From 94c444e71e6a36cfbd3782416200ff20bdd1cea9 Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Mon, 24 Aug 2009 10:26:04 +0200 Subject: Restore QList backward compatibility Add detach3 and append2, leaving the old functions as they were. This ensures that new code will use the optimized version of QList, and old code will just continue calling the old functions. Reviewed-by: Thiago --- src/corelib/tools/qlist.cpp | 51 +++++++++++++++++++++++++++++++++++++++++++++ src/corelib/tools/qlist.h | 8 ++++--- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp index d954160..868bed1 100644 --- a/src/corelib/tools/qlist.cpp +++ b/src/corelib/tools/qlist.cpp @@ -98,12 +98,45 @@ QListData::Data *QListData::detach() * * \internal */ +#if QT_VERSION >= 0x050000 +# error "Remove QListData::detach2(), it is only required for binary compatibility for 4.3.x to 4.5.x" +#endif QListData::Data *QListData::detach2() { Data *x = d; Data* t = static_cast(qMalloc(DataHeaderSize + x->alloc * sizeof(void *))); Q_CHECK_PTR(t); + ::memcpy(x, d, DataHeaderSize + d->alloc * sizeof(void *)); + + t->ref = 1; + t->sharable = true; + t->alloc = x->alloc; + if (!t->alloc) { + t->begin = 0; + t->end = 0; + } else { + t->begin = x->begin; + t->end = x->end; + } + d = t; + + return x; +} + +/*! + * Detaches the QListData by reallocating new memory. + * Returns the old (shared) data, it is up to the caller to deref() and free() + * For the new data node_copy needs to be called. + * + * \internal + */ +QListData::Data *QListData::detach3() +{ + Data *x = d; + Data* t = static_cast(qMalloc(DataHeaderSize + x->alloc * sizeof(void *))); + Q_CHECK_PTR(t); + t->ref = 1; t->sharable = true; t->alloc = x->alloc; @@ -150,6 +183,9 @@ void **QListData::append() } // ensures that enough space is available to append the list +#if QT_VERSION >= 0x050000 +# error "Remove QListData::append(), it is only required for binary compatibility up to 4.5.x" +#endif void **QListData::append(const QListData& l) { Q_ASSERT(d->ref == 1); @@ -158,6 +194,21 @@ void **QListData::append(const QListData& l) if (n) { if (e + n > d->alloc) realloc(grow(e + l.d->end - l.d->begin)); + ::memcpy(d->array + d->end, l.d->array + l.d->begin, n*sizeof(void*)); + d->end += n; + } + return d->array + e; +} + +// ensures that enough space is available to append the list +void **QListData::append2(const QListData& l) +{ + Q_ASSERT(d->ref == 1); + int e = d->end; + int n = l.d->end - l.d->begin; + if (n) { + if (e + n > d->alloc) + realloc(grow(e + l.d->end - l.d->begin)); d->end += n; } return d->array + e; diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index ab6f7bd..331f448 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -72,13 +72,15 @@ struct Q_CORE_EXPORT QListData { enum { DataHeaderSize = sizeof(Data) - sizeof(void *) }; Data *detach(); // remove in 5.0 - Data *detach2(); + Data *detach2(); // remove in 5.0 + Data *detach3(); void realloc(int alloc); static Data shared_null; Data *d; void **erase(void **xi); void **append(); void **append(const QListData &l); + void **append2(const QListData &l); // remove in 5.0 void **prepend(); void **insert(int i); void remove(int i); @@ -593,7 +595,7 @@ template Q_OUTOFLINE_TEMPLATE void QList::detach_helper() { Node *n = reinterpret_cast(p.begin()); - QListData::Data *x = p.detach2(); + QListData::Data *x = p.detach3(); QT_TRY { node_copy(reinterpret_cast(p.begin()), reinterpret_cast(p.end()), n); } QT_CATCH(...) { @@ -693,7 +695,7 @@ template Q_OUTOFLINE_TEMPLATE QList &QList::operator+=(const QList &l) { detach(); - Node *n = reinterpret_cast(p.append(l.p)); + Node *n = reinterpret_cast(p.append2(l.p)); QT_TRY{ node_copy(n, reinterpret_cast(p.end()), reinterpret_cast(l.p.begin())); } QT_CATCH(...) { -- cgit v0.12