QList: overload data_ptr() for rvalue

Amends 343cc50c224655ba8da5cc02d263a9b70f10d529. Marc suggested
adding an rvalue overload for data_ptr().

Return by rvalue as the new overload empties `this`; also
`std::optional::value() &&` returns by rvalue so it's more idiomatic.

Change-Id: I4e2f2cdee2420059465b0592b84c8ade3444e88b
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Ahmad Samir 2025-01-08 21:18:34 +02:00
parent 0e2067334d
commit 0e68115324
3 changed files with 33 additions and 6 deletions

View File

@ -107,8 +107,10 @@ public:
using rvalue_ref = T &&; using rvalue_ref = T &&;
#endif #endif
DataPointer &data_ptr() { return d; } DataPointer &data_ptr() & { return d; }
const DataPointer &data_ptr() const { return d; } const DataPointer &data_ptr() const & { return d; }
DataPointer &&data_ptr() && { return std::move(d); }
// No current use-case for a `const &&` overload
class const_iterator; class const_iterator;
class iterator { class iterator {

View File

@ -1640,8 +1640,9 @@
*/ */
/*! /*!
\fn template <typename T> QList<T>::DataPointer &QList<T>::data_ptr(); \fn template <typename T> QList<T>::DataPointer &QList<T>::data_ptr() &;
\fn template <typename T> const QList<T>::DataPointer &QList<T>::data_ptr() const; \fn template <typename T> const QList<T>::DataPointer &QList<T>::data_ptr() const &;
\fn template <typename T> QList<T>::DataPointer QList<T>::data_ptr() &&;
\internal \internal
\since 6.10 \since 6.10

View File

@ -265,6 +265,7 @@ private slots:
void countCustom() const { count<Custom>(); } void countCustom() const { count<Custom>(); }
void cpp17ctad() const; void cpp17ctad() const;
void data() const; void data() const;
void reinterpreted() const;
void emptyInt() const { empty<int>(); } void emptyInt() const { empty<int>(); }
void emptyMovable() const { empty<Movable>(); } void emptyMovable() const { empty<Movable>(); }
void emptyCustom() const { empty<Custom>(); } void emptyCustom() const { empty<Custom>(); }
@ -776,7 +777,7 @@ void tst_QList::assignEmpty() const
using T = int; using T = int;
QList<T> list; QList<T> list;
QList<T> ref1 = list; QList<T> ref1 = list;
QVERIFY(list.d.needsDetach()); QVERIFY(list.data_ptr().needsDetach());
list.assign(list.begin(), list.begin()); list.assign(list.begin(), list.begin());
#if !defined Q_OS_QNX // QNX has problems with the empty istream_iterator #if !defined Q_OS_QNX // QNX has problems with the empty istream_iterator
@ -784,7 +785,7 @@ void tst_QList::assignEmpty() const
list.squeeze(); list.squeeze();
QCOMPARE_EQ(list.capacity(), 0); QCOMPARE_EQ(list.capacity(), 0);
ref1 = list; ref1 = list;
QVERIFY(list.d.needsDetach()); QVERIFY(list.data_ptr().needsDetach());
list.assign(empty, empty); list.assign(empty, empty);
#endif #endif
} }
@ -1340,6 +1341,29 @@ void tst_QList::data() const
QVERIFY(!constVec.isDetached()); // const data() does not detach() QVERIFY(!constVec.isDetached()); // const data() does not detach()
} }
void tst_QList::reinterpreted() const
{
const QList<char16_t> expected = {char16_t(42), char16_t(43), char16_t(44)};
{
QList<ushort> t = {42, 43, 44};
const auto size = t.size();
QList<char16_t> x = std::move(t.data_ptr()).reinterpreted<char16_t>();
QVERIFY(t.data_ptr().isNull());
QCOMPARE(x.size(), size);
QCOMPARE_EQ(x, expected);
}
{
QList<ushort> t = {42, 43, 44};
const auto size = t.size();
QList<char16_t> x = std::move(t).data_ptr().reinterpreted<char16_t>();
QVERIFY(t.data_ptr().isNull());
QCOMPARE(x.size(), size);
QCOMPARE_EQ(x, expected);
}
}
template<typename T> template<typename T>
void tst_QList::empty() const void tst_QList::empty() const
{ {