QList: Introduce constFirst() and constEnd()

Allows to easily prevent detaching in common code like: getList().first()

[ChangeLog][QtCore][QList] Added the convenience constFirst and constLast functions.

Task-number: QTBUG-46026
Change-Id: I51ecb51fe91fc7d993ad35b5c7392f4da88e5f7b
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Sérgio Martins 2015-06-24 14:34:45 +01:00
parent a8a8cdd24b
commit a5306c35d1
3 changed files with 160 additions and 2 deletions

View File

@ -1227,7 +1227,7 @@ void **QListData::erase(void **xi)
not be empty. If the list can be empty, call isEmpty() before
calling this function.
\sa last(), isEmpty()
\sa constFirst(), last(), isEmpty()
*/
/*! \fn const T& QList::first() const
@ -1235,13 +1235,23 @@ void **QListData::erase(void **xi)
\overload
*/
/*! \fn const T& QList::constFirst() const
\since 5.6
Returns a const reference to the first item in the list. The list must
not be empty. If the list can be empty, call isEmpty() before
calling this function.
\sa constLast(), isEmpty(), first()
*/
/*! \fn T& QList::last()
Returns a reference to the last item in the list. The list must
not be empty. If the list can be empty, call isEmpty() before
calling this function.
\sa first(), isEmpty()
\sa constLast(), first(), isEmpty()
*/
/*! \fn const T& QList::last() const
@ -1249,6 +1259,16 @@ void **QListData::erase(void **xi)
\overload
*/
/*! \fn const T& QList::constLast() const
\since 5.6
Returns a reference to the last item in the list. The list must
not be empty. If the list can be empty, call isEmpty() before
calling this function.
\sa constFirst(), isEmpty(), last()
*/
/*! \fn void QList::removeFirst()
Removes the first item in the list. Calling this function is

View File

@ -331,9 +331,11 @@ public:
inline int count() const { return p.size(); }
inline int length() const { return p.size(); } // Same as count()
inline T& first() { Q_ASSERT(!isEmpty()); return *begin(); }
inline const T& constFirst() const { return first(); }
inline const T& first() const { Q_ASSERT(!isEmpty()); return at(0); }
T& last() { Q_ASSERT(!isEmpty()); return *(--end()); }
const T& last() const { Q_ASSERT(!isEmpty()); return at(count() - 1); }
inline const T& constLast() const { return last(); }
inline void removeFirst() { Q_ASSERT(!isEmpty()); erase(begin()); }
inline void removeLast() { Q_ASSERT(!isEmpty()); erase(--end()); }
inline bool startsWith(const T &t) const { return !isEmpty() && first() == t; }

View File

@ -313,6 +313,8 @@ private slots:
void lastOptimal() const;
void lastMovable() const;
void lastComplex() const;
void constFirst() const;
void constLast() const;
void beginOptimal() const;
void beginMovable() const;
void beginComplex() const;
@ -729,6 +731,140 @@ void tst_QList::firstComplex() const
QCOMPARE(liveCount, Complex::getLiveCount());
}
void tst_QList::constFirst() const
{
// Based on tst_QVector::constFirst()
QList<int> list;
list << 69 << 42 << 3;
// test it starts ok
QCOMPARE(list.constFirst(), 69);
QVERIFY(list.isDetached());
QList<int> listCopy = list;
QVERIFY(!list.isDetached());
QVERIFY(!listCopy.isDetached());
QVERIFY(list.isSharedWith(listCopy));
QVERIFY(listCopy.isSharedWith(list));
QCOMPARE(list.constFirst(), 69);
QCOMPARE(listCopy.constFirst(), 69);
QVERIFY(!list.isDetached());
QVERIFY(!listCopy.isDetached());
QVERIFY(list.isSharedWith(listCopy));
QVERIFY(listCopy.isSharedWith(list));
// test removal changes
list.removeAt(0);
QVERIFY(list.isDetached());
QVERIFY(!list.isSharedWith(listCopy));
QCOMPARE(list.constFirst(), 42);
QCOMPARE(listCopy.constFirst(), 69);
listCopy = list;
QVERIFY(!list.isDetached());
QVERIFY(!listCopy.isDetached());
QVERIFY(list.isSharedWith(listCopy));
QVERIFY(listCopy.isSharedWith(list));
QCOMPARE(list.constFirst(), 42);
QCOMPARE(listCopy.constFirst(), 42);
QVERIFY(!list.isDetached());
QVERIFY(!listCopy.isDetached());
QVERIFY(list.isSharedWith(listCopy));
QVERIFY(listCopy.isSharedWith(list));
// test prepend changes
list.prepend(23);
QVERIFY(list.isDetached());
QVERIFY(!list.isSharedWith(listCopy));
QCOMPARE(list.constFirst(), 23);
QCOMPARE(listCopy.constFirst(), 42);
listCopy = list;
QVERIFY(!list.isDetached());
QVERIFY(!listCopy.isDetached());
QVERIFY(list.isSharedWith(listCopy));
QVERIFY(listCopy.isSharedWith(list));
QCOMPARE(list.constFirst(), 23);
QCOMPARE(listCopy.constFirst(), 23);
QVERIFY(!list.isDetached());
QVERIFY(!listCopy.isDetached());
QVERIFY(list.isSharedWith(listCopy));
QVERIFY(listCopy.isSharedWith(list));
}
void tst_QList::constLast() const
{
// Based on tst_QVector::constLast()
QList<int> list;
list << 69 << 42 << 3;
// test it starts ok
QCOMPARE(list.constLast(), 3);
QVERIFY(list.isDetached());
QList<int> listCopy = list;
QVERIFY(!list.isDetached());
QVERIFY(!listCopy.isDetached());
QVERIFY(list.isSharedWith(listCopy));
QVERIFY(listCopy.isSharedWith(list));
QCOMPARE(list.constLast(), 3);
QCOMPARE(listCopy.constLast(), 3);
QVERIFY(!list.isDetached());
QVERIFY(!listCopy.isDetached());
QVERIFY(list.isSharedWith(listCopy));
QVERIFY(listCopy.isSharedWith(list));
// test removal changes
list.removeLast();
QVERIFY(list.isDetached());
QVERIFY(!list.isSharedWith(listCopy));
QCOMPARE(list.constLast(), 42);
QCOMPARE(listCopy.constLast(), 3);
listCopy = list;
QVERIFY(!list.isDetached());
QVERIFY(!listCopy.isDetached());
QVERIFY(list.isSharedWith(listCopy));
QVERIFY(listCopy.isSharedWith(list));
QCOMPARE(list.constLast(), 42);
QCOMPARE(listCopy.constLast(), 42);
QVERIFY(!list.isDetached());
QVERIFY(!listCopy.isDetached());
QVERIFY(list.isSharedWith(listCopy));
QVERIFY(listCopy.isSharedWith(list));
// test prepend changes
list.append(23);
QVERIFY(list.isDetached());
QVERIFY(!list.isSharedWith(listCopy));
QCOMPARE(list.constLast(), 23);
QCOMPARE(listCopy.constLast(), 42);
listCopy = list;
QVERIFY(!list.isDetached());
QVERIFY(!listCopy.isDetached());
QVERIFY(list.isSharedWith(listCopy));
QVERIFY(listCopy.isSharedWith(list));
QCOMPARE(list.constLast(), 23);
QCOMPARE(listCopy.constLast(), 23);
QVERIFY(!list.isDetached());
QVERIFY(!listCopy.isDetached());
QVERIFY(list.isSharedWith(listCopy));
QVERIFY(listCopy.isSharedWith(list));
}
template<typename T>
void tst_QList::last() const
{