Get rid of unsharable containers

The support for unsharable containers has been deprecated
since Qt 5.3.0, so let's finally remove support for them.

Change-Id: I9be31f55208ae4750e8020b10b6e4ad7e8fb3e0e
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This commit is contained in:
Lars Knoll 2019-05-10 10:51:14 +02:00
parent 7f70a4afa4
commit d273076b44
17 changed files with 23 additions and 911 deletions

View File

@ -86,15 +86,9 @@
#define QT_CONFIG(feature) (1/QT_FEATURE_##feature == 1)
#define QT_REQUIRE_CONFIG(feature) Q_STATIC_ASSERT_X(QT_FEATURE_##feature == 1, "Required feature " #feature " for file " __FILE__ " not available.")
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
// ### Qt6: FIXME and get rid of unsharable containers
//# define QT_NO_UNSHARABLE_CONTAINERS
# define QT6_VIRTUAL virtual
# define QT6_NOT_VIRTUAL
#else
# define QT6_VIRTUAL
# define QT6_NOT_VIRTUAL virtual
#endif
// ### Clean those up, once all code is adjusted
#define QT6_VIRTUAL virtual
#define QT6_NOT_VIRTUAL
/* These two macros makes it possible to turn the builtin line expander into a
* string literal. */

View File

@ -164,8 +164,6 @@ static const QArrayData qt_array[3] = {
QT_WARNING_POP
static const QArrayData &qt_array_empty = qt_array[0];
static const QArrayData &qt_array_unsharable_empty = qt_array[1];
static inline size_t calculateBlockSize(size_t &capacity, size_t objectSize, size_t headerSize,
uint options)
{
@ -197,13 +195,8 @@ QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment,
&& !(alignment & (alignment - 1)));
// Don't allocate empty headers
if (!(options & RawData) && !capacity) {
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
if (options & Unsharable)
return const_cast<QArrayData *>(&qt_array_unsharable_empty);
#endif
if (!(options & RawData) && !capacity)
return const_cast<QArrayData *>(&qt_array_empty);
}
size_t headerSize = sizeof(QArrayData);
@ -223,11 +216,7 @@ QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment,
quintptr data = (quintptr(header) + sizeof(QArrayData) + alignment - 1)
& ~(alignment - 1);
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
header->ref.atomic.storeRelaxed(bool(!(options & Unsharable)));
#else
header->ref.atomic.storeRelaxed(1);
#endif
header->size = 0;
header->alloc = capacity;
header->capacityReserved = bool(options & CapacityReserved);
@ -260,11 +249,6 @@ void QArrayData::deallocate(QArrayData *data, size_t objectSize,
&& !(alignment & (alignment - 1)));
Q_UNUSED(objectSize) Q_UNUSED(alignment)
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
if (data == &qt_array_unsharable_empty)
return;
#endif
Q_ASSERT_X(data == 0 || !data->ref.isStatic(), "QArrayData::deallocate",
"Static data cannot be deleted");
::free(data);

View File

@ -78,9 +78,6 @@ struct Q_CORE_EXPORT QArrayData
enum AllocationOption {
CapacityReserved = 0x1,
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
Unsharable = 0x2,
#endif
RawData = 0x4,
Grow = 0x8,
@ -265,14 +262,6 @@ struct QTypedArrayData
Q_STATIC_ASSERT(sizeof(QTypedArrayData) == sizeof(QArrayData));
return allocate(/* capacity */ 0);
}
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
static QTypedArrayData *unsharableEmpty()
{
Q_STATIC_ASSERT(sizeof(QTypedArrayData) == sizeof(QArrayData));
return allocate(/* capacity */ 0, Unsharable);
}
#endif
};
template <class T, size_t N>

View File

@ -131,23 +131,6 @@ public:
return (!d->isMutable() || d->ref.isShared());
}
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
void setSharable(bool sharable)
{
if (needsDetach()) {
Data *detached = clone(sharable
? d->detachFlags() & ~QArrayData::Unsharable
: d->detachFlags() | QArrayData::Unsharable);
QArrayDataPointer old(d);
d = detached;
} else {
d->ref.setSharable(sharable);
}
}
bool isSharable() const { return d->isSharable(); }
#endif
void swap(QArrayDataPointer &other) noexcept
{
qSwap(d, other.d);

View File

@ -102,9 +102,6 @@ public:
inline void detach() { if (d->ref.loadRelaxed() != 1) detach_helper(); }
inline bool isDetached() const { return d->ref.loadRelaxed() == 1; }
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
inline void setSharable(bool sharable) { if (!sharable) detach(); d->sharable = sharable; }
#endif
QContiguousCache<T> &operator=(const QContiguousCache<T> &other);
inline QContiguousCache<T> &operator=(QContiguousCache<T> &&other) noexcept

View File

@ -290,9 +290,6 @@ public:
inline void detach() { if (d->ref.isShared()) detach_helper(); }
inline bool isDetached() const { return !d->ref.isShared(); }
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
inline void setSharable(bool sharable) { if (!sharable) detach(); if (d != &QHashData::shared_null) d->sharable = sharable; }
#endif
bool isSharedWith(const QHash &other) const { return d == other.d; }
void clear();

View File

@ -107,9 +107,6 @@ public:
inline void detach()
{ if (d->ref.isShared()) detach_helper2(this->e); }
inline bool isDetached() const { return !d->ref.isShared(); }
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
inline void setSharable(bool sharable) { if (!sharable) detach(); if (d != &QLinkedListData::shared_null) d->sharable = sharable; }
#endif
inline bool isSharedWith(const QLinkedList<T> &other) const { return d == other.d; }
inline bool isEmpty() const { return d->size == 0; }

View File

@ -356,17 +356,6 @@ public:
inline void detach() { if (d->ref.isShared()) detach_helper(); }
inline bool isDetached() const { return !d->ref.isShared(); }
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
inline void setSharable(bool sharable)
{
if (sharable == d->ref.isSharable())
return;
if (!sharable)
detach();
// Don't call on shared_null
d->ref.setSharable(sharable);
}
#endif
inline bool isSharedWith(const QMap<Key, T> &other) const { return d == other.d; }
void clear();

View File

@ -53,10 +53,6 @@ class RefCount
public:
inline bool ref() noexcept {
int count = atomic.loadRelaxed();
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
if (count == 0) // !isSharable
return false;
#endif
if (count != -1) // !isStatic
atomic.ref();
return true;
@ -64,32 +60,11 @@ public:
inline bool deref() noexcept {
int count = atomic.loadRelaxed();
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
if (count == 0) // !isSharable
return false;
#endif
if (count == -1) // isStatic
return true;
return atomic.deref();
}
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
bool setSharable(bool sharable) noexcept
{
Q_ASSERT(!isShared());
if (sharable)
return atomic.testAndSetRelaxed(0, 1);
else
return atomic.testAndSetRelaxed(1, 0);
}
bool isSharable() const noexcept
{
// Sharable === Shared ownership.
return atomic.loadRelaxed() != 0;
}
#endif
bool isStatic() const noexcept
{
// Persistent object, never deleted

View File

@ -86,9 +86,6 @@ public:
inline void detach() { q_hash.detach(); }
inline bool isDetached() const { return q_hash.isDetached(); }
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
inline void setSharable(bool sharable) { q_hash.setSharable(sharable); }
#endif
inline void clear() { q_hash.clear(); }

View File

@ -130,23 +130,6 @@ public:
inline void detach();
inline bool isDetached() const { return !d->ref.isShared(); }
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
inline void setSharable(bool sharable)
{
if (sharable == d->ref.isSharable())
return;
if (!sharable)
detach();
if (d == Data::unsharableEmpty()) {
if (sharable)
d = Data::sharedNull();
} else {
d->ref.setSharable(sharable);
}
Q_ASSERT(d->ref.isSharable() == sharable);
}
#endif
inline bool isSharedWith(const QVector<T> &other) const { return d == other.d; }
@ -426,14 +409,11 @@ inline QVector<T>::QVector(const QVector<T> &v)
template <typename T>
void QVector<T>::detach()
{
if (!isDetached()) {
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
if (!d->alloc)
d = Data::unsharableEmpty();
else
#endif
realloc(int(d->alloc));
}
if (d->ref.isStatic())
return;
if (!isDetached())
realloc(int(d->alloc));
Q_ASSERT(isDetached());
}
@ -442,11 +422,7 @@ void QVector<T>::reserve(int asize)
{
if (asize > int(d->alloc))
realloc(asize);
if (isDetached()
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
&& d != Data::unsharableEmpty()
#endif
)
if (isDetached())
d->capacityReserved = 1;
Q_ASSERT(capacity() >= asize);
}
@ -629,9 +605,6 @@ void QVector<T>::reallocData(const int asize, const int aalloc, QArrayData::Allo
x = Data::allocate(aalloc, options);
Q_CHECK_PTR(x);
// aalloc is bigger then 0 so it is not [un]sharedEmpty
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
Q_ASSERT(x->ref.isSharable() || options.testFlag(QArrayData::Unsharable));
#endif
Q_ASSERT(!x->ref.isStatic());
x->size = asize;
@ -712,9 +685,6 @@ void QVector<T>::reallocData(const int asize, const int aalloc, QArrayData::Allo
Q_ASSERT(d->data());
Q_ASSERT(uint(d->size) <= d->alloc);
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
Q_ASSERT(d != Data::unsharableEmpty());
#endif
Q_ASSERT(aalloc ? d != Data::sharedNull() : d == Data::sharedNull());
Q_ASSERT(d->alloc >= uint(aalloc));
Q_ASSERT(d->size == asize);
@ -733,9 +703,6 @@ void QVector<T>::realloc(int aalloc, QArrayData::AllocationOptions options)
x = Data::allocate(aalloc, options);
Q_CHECK_PTR(x);
// aalloc is bigger then 0 so it is not [un]sharedEmpty
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
Q_ASSERT(x->ref.isSharable() || options.testFlag(QArrayData::Unsharable));
#endif
Q_ASSERT(!x->ref.isStatic());
x->size = d->size;
@ -783,9 +750,6 @@ void QVector<T>::realloc(int aalloc, QArrayData::AllocationOptions options)
Q_ASSERT(d->data());
Q_ASSERT(uint(d->size) <= d->alloc);
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
Q_ASSERT(d != Data::unsharableEmpty());
#endif
Q_ASSERT(d != Data::sharedNull());
Q_ASSERT(d->alloc >= uint(aalloc));
}

View File

@ -88,10 +88,6 @@ public:
bool isStatic() const { return d->ref.isStatic(); }
bool isShared() const { return d->ref.isShared(); }
bool isSharedWith(const SimpleVector &other) const { return d == other.d; }
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
bool isSharable() const { return d->ref.isSharable(); }
void setSharable(bool sharable) { d.setSharable(sharable); }
#endif
size_t size() const { return d->size; }
size_t capacity() const { return d->alloc; }

View File

@ -39,9 +39,6 @@ struct SharedNullVerifier
{
Q_ASSERT(QArrayData::shared_null[0].ref.isStatic());
Q_ASSERT(QArrayData::shared_null[0].ref.isShared());
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
Q_ASSERT(QArrayData::shared_null[0].ref.isSharable());
#endif
}
};
@ -73,8 +70,6 @@ private slots:
void gccBug43247();
void arrayOps();
void arrayOps2();
void setSharable_data();
void setSharable();
void fromRawData_data();
void fromRawData();
void literals();
@ -94,9 +89,6 @@ void tst_QArrayData::referenceCounting()
QCOMPARE(array.ref.atomic.loadRelaxed(), 1);
QVERIFY(!array.ref.isStatic());
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
QVERIFY(array.ref.isSharable());
#endif
QVERIFY(array.ref.ref());
QCOMPARE(array.ref.atomic.loadRelaxed(), 2);
@ -116,27 +108,6 @@ void tst_QArrayData::referenceCounting()
// Now would be a good time to free/release allocated data
}
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
{
// Reference counting initialized to 0 (non-sharable)
QArrayData array = { { Q_BASIC_ATOMIC_INITIALIZER(0) }, 0, 0, 0, 0 };
QCOMPARE(array.ref.atomic.loadRelaxed(), 0);
QVERIFY(!array.ref.isStatic());
QVERIFY(!array.ref.isSharable());
QVERIFY(!array.ref.ref());
// Reference counting fails, data should be copied
QCOMPARE(array.ref.atomic.loadRelaxed(), 0);
QVERIFY(!array.ref.deref());
QCOMPARE(array.ref.atomic.loadRelaxed(), 0);
// Free/release data
}
#endif
{
// Reference counting initialized to -1 (static read-only data)
QArrayData array = { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, 0, 0 };
@ -144,9 +115,6 @@ void tst_QArrayData::referenceCounting()
QCOMPARE(array.ref.atomic.loadRelaxed(), -1);
QVERIFY(array.ref.isStatic());
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
QVERIFY(array.ref.isSharable());
#endif
QVERIFY(array.ref.ref());
QCOMPARE(array.ref.atomic.loadRelaxed(), -1);
@ -171,11 +139,6 @@ void tst_QArrayData::sharedNullEmpty()
QCOMPARE(null->ref.atomic.loadRelaxed(), -1);
QCOMPARE(empty->ref.atomic.loadRelaxed(), -1);
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
QVERIFY(null->ref.isSharable());
QVERIFY(empty->ref.isSharable());
#endif
QVERIFY(null->ref.ref());
QVERIFY(empty->ref.ref());
@ -302,17 +265,6 @@ void tst_QArrayData::simpleVector()
QVERIFY(!v7.isShared());
QVERIFY(!v8.isShared());
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
QVERIFY(v1.isSharable());
QVERIFY(v2.isSharable());
QVERIFY(v3.isSharable());
QVERIFY(v4.isSharable());
QVERIFY(v5.isSharable());
QVERIFY(v6.isSharable());
QVERIFY(v7.isSharable());
QVERIFY(v8.isSharable());
#endif
QVERIFY(v1.isSharedWith(v2));
QVERIFY(v1.isSharedWith(v3));
QVERIFY(v1.isSharedWith(v4));
@ -494,71 +446,6 @@ void tst_QArrayData::simpleVector()
for (int i = 0; i < 120; ++i)
QCOMPARE(v1[i], v8[i % 10]);
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
{
v7.setSharable(true);
QVERIFY(v7.isSharable());
SimpleVector<int> copy1(v7);
QVERIFY(copy1.isSharedWith(v7));
v7.setSharable(false);
QVERIFY(!v7.isSharable());
QVERIFY(!copy1.isSharedWith(v7));
QCOMPARE(v7.size(), copy1.size());
for (size_t i = 0; i < copy1.size(); ++i)
QCOMPARE(v7[i], copy1[i]);
SimpleVector<int> clone(v7);
QVERIFY(!clone.isSharedWith(v7));
QCOMPARE(clone.size(), copy1.size());
for (size_t i = 0; i < copy1.size(); ++i)
QCOMPARE(clone[i], copy1[i]);
v7.setSharable(true);
QVERIFY(v7.isSharable());
SimpleVector<int> copy2(v7);
QVERIFY(copy2.isSharedWith(v7));
}
{
SimpleVector<int> null;
SimpleVector<int> empty(0, 5);
QVERIFY(null.isSharable());
QVERIFY(empty.isSharable());
null.setSharable(true);
empty.setSharable(true);
QVERIFY(null.isSharable());
QVERIFY(empty.isSharable());
QVERIFY(null.isEmpty());
QVERIFY(empty.isEmpty());
null.setSharable(false);
empty.setSharable(false);
QVERIFY(!null.isSharable());
QVERIFY(!empty.isSharable());
QVERIFY(null.isEmpty());
QVERIFY(empty.isEmpty());
null.setSharable(true);
empty.setSharable(true);
QVERIFY(null.isSharable());
QVERIFY(empty.isSharable());
QVERIFY(null.isEmpty());
QVERIFY(empty.isEmpty());
}
#endif
}
Q_DECLARE_METATYPE(SimpleVector<int>)
@ -649,7 +536,6 @@ void tst_QArrayData::allocate_data()
QTest::addColumn<size_t>("alignment");
QTest::addColumn<QArrayData::AllocationOptions>("allocateOptions");
QTest::addColumn<bool>("isCapacityReserved");
QTest::addColumn<bool>("isSharable"); // ### Qt6: remove
QTest::addColumn<const QArrayData *>("commonEmpty");
struct {
@ -665,27 +551,15 @@ void tst_QArrayData::allocate_data()
QArrayData *shared_empty = QArrayData::allocate(0, alignof(QArrayData), 0);
QVERIFY(shared_empty);
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
QArrayData *unsharable_empty = QArrayData::allocate(0, alignof(QArrayData), 0, QArrayData::Unsharable);
QVERIFY(unsharable_empty);
#endif
struct {
char const *description;
QArrayData::AllocationOptions allocateOptions;
bool isCapacityReserved;
bool isSharable;
const QArrayData *commonEmpty;
} options[] = {
{ "Default", QArrayData::Default, false, true, shared_empty },
{ "Reserved", QArrayData::CapacityReserved, true, true, shared_empty },
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
{ "Reserved | Unsharable",
QArrayData::CapacityReserved | QArrayData::Unsharable, true, false,
unsharable_empty },
{ "Unsharable", QArrayData::Unsharable, false, false, unsharable_empty },
#endif
{ "Grow", QArrayData::Grow, false, true, shared_empty }
{ "Default", QArrayData::Default, false, shared_empty },
{ "Reserved", QArrayData::CapacityReserved, true, shared_empty },
{ "Grow", QArrayData::Grow, false, shared_empty }
};
for (size_t i = 0; i < sizeof(types)/sizeof(types[0]); ++i)
@ -696,7 +570,7 @@ void tst_QArrayData::allocate_data()
+ QLatin1String(options[j].description)))
<< types[i].objectSize << types[i].alignment
<< options[j].allocateOptions << options[j].isCapacityReserved
<< options[j].isSharable << options[j].commonEmpty;
<< options[j].commonEmpty;
}
void tst_QArrayData::allocate()
@ -729,10 +603,6 @@ void tst_QArrayData::allocate()
else
QCOMPARE(data->alloc, uint(capacity));
QCOMPARE(data->capacityReserved, uint(isCapacityReserved));
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
QFETCH(bool, isSharable);
QCOMPARE(data->ref.isSharable(), isSharable);
#endif
// Check that the allocated array can be used. Best tested with a
// memory checker, such as valgrind, running.
@ -778,10 +648,6 @@ void tst_QArrayData::reallocate()
else
QCOMPARE(data->alloc, uint(newCapacity));
QCOMPARE(data->capacityReserved, uint(isCapacityReserved));
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
QFETCH(bool, isSharable);
QCOMPARE(data->ref.isSharable(), isSharable);
#endif
for (int i = 0; i < capacity; ++i)
QCOMPARE(static_cast<char *>(data->data())[i], 'A');
@ -1354,136 +1220,6 @@ static inline bool arrayIsFilledWith(const QArrayDataPointer<int> &array,
return true;
}
void tst_QArrayData::setSharable_data()
{
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
QTest::addColumn<QArrayDataPointer<int> >("array");
QTest::addColumn<size_t>("size");
QTest::addColumn<size_t>("capacity");
QTest::addColumn<bool>("isCapacityReserved");
QTest::addColumn<int>("fillValue");
QArrayDataPointer<int> null;
QArrayDataPointer<int> empty; empty.clear();
static QStaticArrayData<int, 10> staticArrayData = {
Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(int, 10),
{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }
};
QArrayDataPointer<int> emptyReserved(QTypedArrayData<int>::allocate(5,
QArrayData::CapacityReserved));
QArrayDataPointer<int> nonEmpty(QTypedArrayData<int>::allocate(5,
QArrayData::Default));
QArrayDataPointer<int> nonEmptyExtraCapacity(
QTypedArrayData<int>::allocate(10, QArrayData::Default));
QArrayDataPointer<int> nonEmptyReserved(QTypedArrayData<int>::allocate(15,
QArrayData::CapacityReserved));
QArrayDataPointer<int> staticArray(
static_cast<QTypedArrayData<int> *>(&staticArrayData.header));
QArrayDataPointer<int> rawData(
QTypedArrayData<int>::fromRawData(staticArrayData.data, 10));
nonEmpty->copyAppend(5, 1);
nonEmptyExtraCapacity->copyAppend(5, 1);
nonEmptyReserved->copyAppend(7, 2);
QTest::newRow("shared-null") << null << size_t(0) << size_t(0) << false << 0;
QTest::newRow("shared-empty") << empty << size_t(0) << size_t(0) << false << 0;
// unsharable-empty implicitly tested in shared-empty
QTest::newRow("empty-reserved") << emptyReserved << size_t(0) << size_t(5) << true << 0;
QTest::newRow("non-empty") << nonEmpty << size_t(5) << size_t(5) << false << 1;
QTest::newRow("non-empty-extra-capacity") << nonEmptyExtraCapacity << size_t(5) << size_t(10) << false << 1;
QTest::newRow("non-empty-reserved") << nonEmptyReserved << size_t(7) << size_t(15) << true << 2;
QTest::newRow("static-array") << staticArray << size_t(10) << size_t(0) << false << 3;
QTest::newRow("raw-data") << rawData << size_t(10) << size_t(0) << false << 3;
#endif
}
void tst_QArrayData::setSharable()
{
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
QFETCH(QArrayDataPointer<int>, array);
QFETCH(size_t, size);
QFETCH(size_t, capacity);
QFETCH(bool, isCapacityReserved);
QFETCH(int, fillValue);
QVERIFY(array->ref.isShared()); // QTest has a copy
QVERIFY(array->ref.isSharable());
QCOMPARE(size_t(array->size), size);
QCOMPARE(size_t(array->alloc), capacity);
QCOMPARE(bool(array->capacityReserved), isCapacityReserved);
QVERIFY(arrayIsFilledWith(array, fillValue, size));
// shared-null becomes shared-empty, may otherwise detach
array.setSharable(true);
QVERIFY(array->ref.isSharable());
QVERIFY(arrayIsFilledWith(array, fillValue, size));
{
QArrayDataPointer<int> copy(array);
QVERIFY(array->ref.isShared());
QVERIFY(array->ref.isSharable());
QCOMPARE(copy.data(), array.data());
}
// Unshare, must detach
array.setSharable(false);
// Immutability (alloc == 0) is lost on detach, as is additional capacity
// if capacityReserved flag is not set.
if ((capacity == 0 && size != 0)
|| (!isCapacityReserved && capacity > size))
capacity = size;
QVERIFY(!array->ref.isShared());
QVERIFY(!array->ref.isSharable());
QCOMPARE(size_t(array->size), size);
QCOMPARE(size_t(array->alloc), capacity);
QCOMPARE(bool(array->capacityReserved), isCapacityReserved);
QVERIFY(arrayIsFilledWith(array, fillValue, size));
{
QArrayDataPointer<int> copy(array);
QVERIFY(!array->ref.isShared());
QVERIFY(!array->ref.isSharable());
// Null/empty is always shared
QCOMPARE(copy->ref.isShared(), !(size || isCapacityReserved));
QVERIFY(copy->ref.isSharable());
QCOMPARE(size_t(copy->size), size);
QCOMPARE(size_t(copy->alloc), capacity);
QCOMPARE(bool(copy->capacityReserved), isCapacityReserved);
QVERIFY(arrayIsFilledWith(copy, fillValue, size));
}
// Make sharable, again
array.setSharable(true);
QCOMPARE(array->ref.isShared(), !(size || isCapacityReserved));
QVERIFY(array->ref.isSharable());
QCOMPARE(size_t(array->size), size);
QCOMPARE(size_t(array->alloc), capacity);
QCOMPARE(bool(array->capacityReserved), isCapacityReserved);
QVERIFY(arrayIsFilledWith(array, fillValue, size));
{
QArrayDataPointer<int> copy(array);
QVERIFY(array->ref.isShared());
QCOMPARE(copy.data(), array.data());
}
QCOMPARE(array->ref.isShared(), !(size || isCapacityReserved));
QVERIFY(array->ref.isSharable());
#endif
}
struct ResetOnDtor
{
ResetOnDtor()
@ -1531,37 +1267,6 @@ void fromRawData_impl()
QCOMPARE(raw.back(), T(11));
QVERIFY((const T *)raw.constBegin() != array);
}
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
{
// Immutable, unsharable
SimpleVector<T> raw = SimpleVector<T>::fromRawData(array,
sizeof(array)/sizeof(array[0]), QArrayData::Unsharable);
QCOMPARE(raw.size(), size_t(11));
QCOMPARE((const T *)raw.constBegin(), array);
QCOMPARE((const T *)raw.constEnd(), (const T *)(array + sizeof(array)/sizeof(array[0])));
SimpleVector<T> copy(raw);
QVERIFY(!copy.isSharedWith(raw));
QVERIFY(!raw.isShared());
QCOMPARE(copy.size(), size_t(11));
for (size_t i = 0; i < 11; ++i) {
QCOMPARE(const_(copy)[i], const_(raw)[i]);
QCOMPARE(const_(copy)[i], T(i + 1));
}
QCOMPARE(raw.size(), size_t(11));
QCOMPARE((const T *)raw.constBegin(), array);
QCOMPARE((const T *)raw.constEnd(), (const T *)(array + sizeof(array)/sizeof(array[0])));
// Detach
QCOMPARE(raw.back(), T(11));
QVERIFY((const T *)raw.constBegin() != array);
}
#endif
}
void tst_QArrayData::fromRawData_data()
@ -1615,10 +1320,6 @@ void tst_QArrayData::literals()
// v.capacity() is unspecified, for now
QVERIFY(v.isStatic());
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
QVERIFY(v.isSharable());
#endif
QCOMPARE((void*)(const char*)(v.constBegin() + v.size()), (void*)(const char*)v.constEnd());
for (int i = 0; i < 10; ++i)
@ -1677,10 +1378,6 @@ void tst_QArrayData::variadicLiterals()
// v.capacity() is unspecified, for now
QVERIFY(v.isStatic());
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
QVERIFY(v.isSharable());
#endif
QCOMPARE((const int *)(v.constBegin() + v.size()), (const int *)v.constEnd());
for (int i = 0; i < 7; ++i)

View File

@ -1372,13 +1372,6 @@ void tst_QHash::noNeedlessRehashes()
void tst_QHash::const_shared_null()
{
QHash<int, QString> hash2;
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
QHash<int, QString> hash1;
hash1.setSharable(false);
QVERIFY(hash1.isDetached());
hash2.setSharable(true);
#endif
QVERIFY(!hash2.isDetached());
}

View File

@ -225,8 +225,6 @@ private slots:
void constSharedNullInt() const;
void constSharedNullMovable() const;
void constSharedNullComplex() const;
void setSharableInt() const;
private:
template<typename T> void length() const;
template<typename T> void first() const;
@ -1048,13 +1046,6 @@ template<typename T>
void tst_QLinkedList::constSharedNull() const
{
QLinkedList<T> list2;
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
QLinkedList<T> list1;
list1.setSharable(false);
QVERIFY(list1.isDetached());
list2.setSharable(true);
#endif
QVERIFY(!list2.isDetached());
}
@ -1077,57 +1068,5 @@ void tst_QLinkedList::constSharedNullComplex() const
QCOMPARE(liveCount, Complex::getLiveCount());
}
void tst_QLinkedList::setSharableInt() const
{
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
QLinkedList<int> orglist;
orglist << 0 << 1 << 2 << 3 << 4 << 5;
int size = 6;
QLinkedList<int> list;
list = orglist;
QVERIFY(!list.isDetached());
list.setSharable(true);
QCOMPARE(list.size(), size);
{
QLinkedList<int> copy(list);
QVERIFY(!copy.isDetached());
QVERIFY(copy.isSharedWith(list));
}
list.setSharable(false);
QVERIFY(list.isDetached() || list.isSharedWith(QLinkedList<int>()));
{
QLinkedList<int> copy(list);
QVERIFY(copy.isDetached() || copy.isSharedWith(QLinkedList<int>()));
QCOMPARE(copy.size(), size);
QCOMPARE(copy, list);
}
list.setSharable(true);
{
QLinkedList<int> copy(list);
QVERIFY(!copy.isDetached());
QVERIFY(copy.isSharedWith(list));
}
QLinkedList<int>::const_iterator it = list.constBegin();
for (int i = 0; i < list.size(); ++i) {
QCOMPARE(int(*it), i);
++it;
}
QCOMPARE(list.size(), size);
#endif
}
QTEST_APPLESS_MAIN(tst_QLinkedList)
#include "tst_qlinkedlist.moc"

View File

@ -68,7 +68,6 @@ private slots:
void const_shared_null();
void equal_range();
void setSharable();
void insert();
void checkMostLeftNode();
@ -1065,13 +1064,6 @@ void tst_QMap::qmultimap_specific()
void tst_QMap::const_shared_null()
{
QMap<int, QString> map2;
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
QMap<int, QString> map1;
map1.setSharable(false);
QVERIFY(map1.isDetached());
map2.setSharable(true);
#endif
QVERIFY(!map2.isDetached());
}
@ -1160,61 +1152,6 @@ const T &const_(const T &t)
return t;
}
void tst_QMap::setSharable()
{
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
QMap<int, QString> map;
map.insert(1, "um");
map.insert(2, "dois");
map.insert(4, "quatro");
map.insert(5, "cinco");
map.setSharable(true);
QCOMPARE(map.size(), 4);
QCOMPARE(const_(map)[4], QString("quatro"));
{
QMap<int, QString> copy(map);
QVERIFY(!map.isDetached());
QVERIFY(copy.isSharedWith(map));
sanityCheckTree(copy, __LINE__);
}
map.setSharable(false);
sanityCheckTree(map, __LINE__);
QVERIFY(map.isDetached());
QCOMPARE(map.size(), 4);
QCOMPARE(const_(map)[4], QString("quatro"));
{
QMap<int, QString> copy(map);
QVERIFY(map.isDetached());
QVERIFY(copy.isDetached());
QCOMPARE(copy.size(), 4);
QCOMPARE(const_(copy)[4], QString("quatro"));
QCOMPARE(map, copy);
sanityCheckTree(map, __LINE__);
sanityCheckTree(copy, __LINE__);
}
map.setSharable(true);
QCOMPARE(map.size(), 4);
QCOMPARE(const_(map)[4], QString("quatro"));
{
QMap<int, QString> copy(map);
QVERIFY(!map.isDetached());
QVERIFY(copy.isSharedWith(map));
}
#endif
}
void tst_QMap::insert()
{
QMap<QString, float> map;

View File

@ -314,15 +314,6 @@ private slots:
void initializeListCustom();
void const_shared_null();
#if 1
// ### Qt6 remove this section
void setSharableInt_data();
void setSharableInt();
void setSharableMovable_data();
void setSharableMovable();
void setSharableCustom_data();
void setSharableCustom();
#endif
void detachInt() const;
void detachMovable() const;
@ -358,8 +349,6 @@ private:
template<typename T> void size() const;
template<typename T> void swap() const;
template<typename T> void initializeList();
template<typename T> void setSharable_data() const;
template<typename T> void setSharable() const;
template<typename T> void detach() const;
template<typename T> void detachThreadSafety() const;
};
@ -467,24 +456,6 @@ void tst_QVector::copyConstructor() const
QVector<T> v2(v1);
QCOMPARE(v1, v2);
}
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
// ### Qt6 remove this section
{
QVector<T> v1;
v1.setSharable(false);
QVector<T> v2(v1);
QVERIFY(!v1.isSharedWith(v2));
QCOMPARE(v1, v2);
}
{
QVector<T> v1;
v1 << value1 << value2 << value3 << value4;
v1.setSharable(false);
QVector<T> v2(v1);
QVERIFY(!v1.isSharedWith(v2));
QCOMPARE(v1, v2);
}
#endif
}
void tst_QVector::copyConstructorInt() const
@ -665,17 +636,6 @@ void tst_QVector::append() const
QVERIFY(v.size() == 3);
QCOMPARE(v.at(v.size() - 1), SimpleValue<T>::at(0));
}
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
// ### Qt6 remove this section
{
QVector<T> v(2);
v.reserve(12);
v.setSharable(false);
v.append(SimpleValue<T>::at(0));
QVERIFY(v.size() == 3);
QCOMPARE(v.last(), SimpleValue<T>::at(0));
}
#endif
{
QVector<int> v;
v << 1 << 2 << 3;
@ -1019,20 +979,9 @@ void tst_QVector::endsWith() const
template<typename T>
void tst_QVector::eraseEmpty() const
{
{
QVector<T> v;
v.erase(v.begin(), v.end());
QCOMPARE(v.size(), 0);
}
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
// ### Qt6 remove this section
{
QVector<T> v;
v.setSharable(false);
v.erase(v.begin(), v.end());
QCOMPARE(v.size(), 0);
}
#endif
QVector<T> v;
v.erase(v.begin(), v.end());
QCOMPARE(v.size(), 0);
}
void tst_QVector::eraseEmptyInt() const
@ -1057,22 +1006,10 @@ void tst_QVector::eraseEmptyCustom() const
template<typename T>
void tst_QVector::eraseEmptyReserved() const
{
{
QVector<T> v;
v.reserve(10);
v.erase(v.begin(), v.end());
QCOMPARE(v.size(), 0);
}
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
// ### Qt6 remove this section
{
QVector<T> v;
v.reserve(10);
v.setSharable(false);
v.erase(v.begin(), v.end());
QCOMPARE(v.size(), 0);
}
#endif
QVector<T> v;
v.reserve(10);
v.erase(v.begin(), v.end());
QCOMPARE(v.size(), 0);
}
void tst_QVector::eraseEmptyReservedInt() const
@ -1179,21 +1116,6 @@ void tst_QVector::erase(bool shared) const
if (shared)
QCOMPARE(SimpleValue<T>::vector(12), *svc.copy);
}
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
// ### Qt6 remove this section
{
QVector<T> v = SimpleValue<T>::vector(10);
SharedVectorChecker<T> svc(v, shared);
v.setSharable(false);
SharedVectorChecker<T> svc2(v, shared);
v.erase(v.begin() + 3);
QCOMPARE(v.size(), 9);
v.erase(v.begin(), v.end() - 1);
QCOMPARE(v.size(), 1);
if (shared)
QCOMPARE(SimpleValue<T>::vector(10), *svc.copy);
}
#endif
}
void tst_QVector::eraseInt() const
@ -1266,18 +1188,6 @@ template<typename T> void tst_QVector::eraseReserved() const
v.erase(v.begin() + 1, v.end() - 1);
QCOMPARE(v.size(), 2);
}
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
// ### Qt6 remove this section
{
QVector<T> v(10);
v.reserve(16);
v.setSharable(false);
v.erase(v.begin() + 3);
QCOMPARE(v.size(), 9);
v.erase(v.begin(), v.end() - 1);
QCOMPARE(v.size(), 1);
}
#endif
}
void tst_QVector::eraseReservedInt() const
@ -2019,33 +1929,6 @@ void tst_QVector::resizePOD_data() const
QTest::newRow("emptyReserved") << emptyReserved << 10;
QTest::newRow("nonEmpty") << nonEmpty << 10;
QTest::newRow("nonEmptyReserved") << nonEmptyReserved << 10;
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
// ### Qt6 remove this section
QVector<int> nullNotShared;
QVector<int> emptyNotShared(0, 5);
QVector<int> emptyReservedNotShared;
QVector<int> nonEmptyNotShared;
QVector<int> nonEmptyReservedNotShared;
emptyReservedNotShared.reserve(10);
nonEmptyReservedNotShared.reserve(15);
nonEmptyNotShared << 0 << 1 << 2 << 3 << 4;
nonEmptyReservedNotShared << 0 << 1 << 2 << 3 << 4 << 5 << 6;
QVERIFY(emptyReservedNotShared.capacity() >= 10);
QVERIFY(nonEmptyReservedNotShared.capacity() >= 15);
emptyNotShared.setSharable(false);
emptyReservedNotShared.setSharable(false);
nonEmptyNotShared.setSharable(false);
nonEmptyReservedNotShared.setSharable(false);
QTest::newRow("nullNotShared") << nullNotShared << 10;
QTest::newRow("emptyNotShared") << emptyNotShared << 10;
QTest::newRow("emptyReservedNotShared") << emptyReservedNotShared << 10;
QTest::newRow("nonEmptyNotShared") << nonEmptyNotShared << 10;
QTest::newRow("nonEmptyReservedNotShared") << nonEmptyReservedNotShared << 10;
#endif
}
void tst_QVector::resizePOD() const
@ -2094,33 +1977,6 @@ void tst_QVector::resizeComplexMovable_data() const
QTest::newRow("emptyReserved") << emptyReserved << 10;
QTest::newRow("nonEmpty") << nonEmpty << 10;
QTest::newRow("nonEmptyReserved") << nonEmptyReserved << 10;
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
// ### Qt6 remove this section
QVector<Movable> nullNotShared;
QVector<Movable> emptyNotShared(0, 'Q');
QVector<Movable> emptyReservedNotShared;
QVector<Movable> nonEmptyNotShared;
QVector<Movable> nonEmptyReservedNotShared;
emptyReservedNotShared.reserve(10);
nonEmptyReservedNotShared.reserve(15);
nonEmptyNotShared << '0' << '1' << '2' << '3' << '4';
nonEmptyReservedNotShared << '0' << '1' << '2' << '3' << '4' << '5' << '6';
QVERIFY(emptyReservedNotShared.capacity() >= 10);
QVERIFY(nonEmptyReservedNotShared.capacity() >= 15);
emptyNotShared.setSharable(false);
emptyReservedNotShared.setSharable(false);
nonEmptyNotShared.setSharable(false);
nonEmptyReservedNotShared.setSharable(false);
QTest::newRow("nullNotShared") << nullNotShared << 10;
QTest::newRow("emptyNotShared") << emptyNotShared << 10;
QTest::newRow("emptyReservedNotShared") << emptyReservedNotShared << 10;
QTest::newRow("nonEmptyNotShared") << nonEmptyNotShared << 10;
QTest::newRow("nonEmptyReservedNotShared") << nonEmptyReservedNotShared << 10;
#endif
}
void tst_QVector::resizeComplexMovable() const
@ -2173,33 +2029,6 @@ void tst_QVector::resizeComplex_data() const
QTest::newRow("emptyReserved") << emptyReserved << 10;
QTest::newRow("nonEmpty") << nonEmpty << 10;
QTest::newRow("nonEmptyReserved") << nonEmptyReserved << 10;
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
// ### Qt6 remove this section
QVector<Custom> nullNotShared;
QVector<Custom> emptyNotShared(0, '0');
QVector<Custom> emptyReservedNotShared;
QVector<Custom> nonEmptyNotShared;
QVector<Custom> nonEmptyReservedNotShared;
emptyReservedNotShared.reserve(10);
nonEmptyReservedNotShared.reserve(15);
nonEmptyNotShared << '0' << '1' << '2' << '3' << '4';
nonEmptyReservedNotShared << '0' << '1' << '2' << '3' << '4' << '5' << '6';
QVERIFY(emptyReservedNotShared.capacity() >= 10);
QVERIFY(nonEmptyReservedNotShared.capacity() >= 15);
emptyNotShared.setSharable(false);
emptyReservedNotShared.setSharable(false);
nonEmptyNotShared.setSharable(false);
nonEmptyReservedNotShared.setSharable(false);
QTest::newRow("nullNotShared") << nullNotShared << 10;
QTest::newRow("emptyNotShared") << emptyNotShared << 10;
QTest::newRow("emptyReservedNotShared") << emptyReservedNotShared << 10;
QTest::newRow("nonEmptyNotShared") << nonEmptyNotShared << 10;
QTest::newRow("nonEmptyReservedNotShared") << nonEmptyReservedNotShared << 10;
#endif
}
void tst_QVector::resizeComplex() const
@ -2636,154 +2465,9 @@ void tst_QVector::initializeListCustom()
void tst_QVector::const_shared_null()
{
QVector<int> v2;
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
// ### Qt6 remove this section
QVector<int> v1;
v1.setSharable(false);
QVERIFY(v1.isDetached());
v2.setSharable(true);
#endif
QVERIFY(!v2.isDetached());
}
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
// ### Qt6 remove this section
template<typename T>
void tst_QVector::setSharable_data() const
{
QTest::addColumn<QVector<T> >("vector");
QTest::addColumn<int>("size");
QTest::addColumn<int>("capacity");
QTest::addColumn<bool>("isCapacityReserved");
QVector<T> null;
QVector<T> empty(0, SimpleValue<T>::at(1));
QVector<T> emptyReserved;
QVector<T> nonEmpty;
QVector<T> nonEmptyReserved;
emptyReserved.reserve(10);
nonEmptyReserved.reserve(15);
nonEmpty << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2) << SimpleValue<T>::at(3) << SimpleValue<T>::at(4);
nonEmptyReserved << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2) << SimpleValue<T>::at(3) << SimpleValue<T>::at(4) << SimpleValue<T>::at(5) << SimpleValue<T>::at(6);
QVERIFY(emptyReserved.capacity() >= 10);
QVERIFY(nonEmptyReserved.capacity() >= 15);
QTest::newRow("null") << null << 0 << 0 << false;
QTest::newRow("empty") << empty << 0 << 0 << false;
QTest::newRow("empty, Reserved") << emptyReserved << 0 << 10 << true;
QTest::newRow("non-empty") << nonEmpty << 5 << 0 << false;
QTest::newRow("non-empty, Reserved") << nonEmptyReserved << 7 << 15 << true;
}
template<typename T>
void tst_QVector::setSharable() const
{
QFETCH(QVector<T>, vector);
QFETCH(int, size);
QFETCH(int, capacity);
QFETCH(bool, isCapacityReserved);
QVERIFY(!vector.isDetached()); // Shared with QTest
vector.setSharable(true);
QCOMPARE(vector.size(), size);
if (isCapacityReserved)
QVERIFY2(vector.capacity() >= capacity,
qPrintable(QString("Capacity is %1, expected at least %2.")
.arg(vector.capacity())
.arg(capacity)));
{
QVector<T> copy(vector);
QVERIFY(!copy.isDetached());
QVERIFY(copy.isSharedWith(vector));
}
vector.setSharable(false);
QVERIFY(vector.isDetached() || vector.isSharedWith(QVector<T>()));
{
QVector<T> copy(vector);
QVERIFY(copy.isDetached() || copy.isEmpty() || copy.isSharedWith(QVector<T>()));
QCOMPARE(copy.size(), size);
if (isCapacityReserved)
QVERIFY2(copy.capacity() >= capacity,
qPrintable(QString("Capacity is %1, expected at least %2.")
.arg(copy.capacity())
.arg(capacity)));
QCOMPARE(copy, vector);
}
vector.setSharable(true);
{
QVector<T> copy(vector);
QVERIFY(!copy.isDetached());
QVERIFY(copy.isSharedWith(vector));
}
for (int i = 0; i < vector.size(); ++i)
QCOMPARE(vector[i], SimpleValue<T>::at(i));
QCOMPARE(vector.size(), size);
if (isCapacityReserved)
QVERIFY2(vector.capacity() >= capacity,
qPrintable(QString("Capacity is %1, expected at least %2.")
.arg(vector.capacity())
.arg(capacity)));
}
#else
template<typename T> void tst_QVector::setSharable_data() const
{
}
template<typename T> void tst_QVector::setSharable() const
{
}
#endif
void tst_QVector::setSharableInt_data()
{
setSharable_data<int>();
}
void tst_QVector::setSharableMovable_data()
{
setSharable_data<Movable>();
}
void tst_QVector::setSharableCustom_data()
{
setSharable_data<Custom>();
}
void tst_QVector::setSharableInt()
{
setSharable<int>();
}
void tst_QVector::setSharableMovable()
{
const int instancesCount = Movable::counter.loadAcquire();
setSharable<Movable>();
QCOMPARE(instancesCount, Movable::counter.loadAcquire());
}
void tst_QVector::setSharableCustom()
{
const int instancesCount = Custom::counter.loadAcquire();
setSharable<Custom>();
QCOMPARE(instancesCount, Custom::counter.loadAcquire());
}
template<typename T>
void tst_QVector::detach() const
{
@ -2791,7 +2475,7 @@ void tst_QVector::detach() const
// detach an empty vector
QVector<T> v;
v.detach();
QVERIFY(v.isDetached());
QVERIFY(!v.isDetached());
QCOMPARE(v.size(), 0);
QCOMPARE(v.capacity(), 0);
}
@ -2801,7 +2485,7 @@ void tst_QVector::detach() const
QVector<T> ref(v);
QVERIFY(!v.isDetached());
v.detach();
QVERIFY(v.isDetached());
QVERIFY(!v.isDetached());
QCOMPARE(v.size(), 0);
QCOMPARE(v.capacity(), 0);
}