Make container move semantics consistent

Make all containers (excepting QVarLengthArray)
- nothrow default-constructible
- nothrow move-constructible
- nothrow move-assignable
- nothrow swappable

[ChangeLog][QtCore] All containers (with the exception of QVarLengthArray,
but including QSharedPointer) are now nothrow_default_constructible,
nothrow_move_constructible, nothrow_move_assignable, and nothrow-swappable.

Change-Id: I12138d262f9f7f600f0e1218137da208c12e7c0a
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Marc Mutz 2015-07-03 13:24:31 +02:00
parent 52812e9a2b
commit f89803e459
8 changed files with 22 additions and 20 deletions

View File

@ -48,7 +48,7 @@ class Q_CORE_EXPORT QBitArray
QByteArray d;
public:
inline QBitArray() {}
inline QBitArray() Q_DECL_NOTHROW {}
explicit QBitArray(int size, bool val = false);
QBitArray(const QBitArray &other) : d(other.d) {}
inline QBitArray &operator=(const QBitArray &other) { d = other.d; return *this; }

View File

@ -935,7 +935,7 @@ template <class Key, class T>
class QMultiHash : public QHash<Key, T>
{
public:
QMultiHash() {}
QMultiHash() Q_DECL_NOTHROW {}
#ifdef Q_COMPILER_INITIALIZER_LISTS
inline QMultiHash(std::initializer_list<std::pair<Key,T> > list)
{
@ -951,7 +951,7 @@ public:
#ifdef Q_COMPILER_RVALUE_REFS
QMultiHash(QHash<Key, T> &&other) Q_DECL_NOTHROW : QHash<Key, T>(std::move(other)) {}
#endif
void swap(QMultiHash &other) { QHash<Key, T>::swap(other); } // prevent QMultiHash<->QHash swaps
void swap(QMultiHash &other) Q_DECL_NOTHROW { QHash<Key, T>::swap(other); } // prevent QMultiHash<->QHash swaps
inline typename QHash<Key, T>::iterator replace(const Key &key, const T &value)
{ return QHash<Key, T>::insert(key, value); }

View File

@ -74,7 +74,7 @@ class QLinkedList
union { QLinkedListData *d; QLinkedListNode<T> *e; };
public:
inline QLinkedList() : d(const_cast<QLinkedListData *>(&QLinkedListData::shared_null)) { }
inline QLinkedList() Q_DECL_NOTHROW : d(const_cast<QLinkedListData *>(&QLinkedListData::shared_null)) { }
inline QLinkedList(const QLinkedList<T> &l) : d(l.d) { d->ref.ref(); if (!d->sharable) detach(); }
#if defined(Q_COMPILER_INITIALIZER_LISTS)
inline QLinkedList(std::initializer_list<T> list)
@ -86,11 +86,12 @@ public:
~QLinkedList();
QLinkedList<T> &operator=(const QLinkedList<T> &);
#ifdef Q_COMPILER_RVALUE_REFS
inline QLinkedList(QLinkedList<T> &&other) : d(other.d) { other.d = const_cast<QLinkedListData *>(&QLinkedListData::shared_null); }
inline QLinkedList<T> &operator=(QLinkedList<T> &&other)
QLinkedList(QLinkedList<T> &&other) Q_DECL_NOTHROW
: d(other.d) { other.d = const_cast<QLinkedListData *>(&QLinkedListData::shared_null); }
QLinkedList<T> &operator=(QLinkedList<T> &&other) Q_DECL_NOTHROW
{ QLinkedList moved(std::move(other)); swap(moved); return *this; }
#endif
inline void swap(QLinkedList<T> &other) { qSwap(d, other.d); }
inline void swap(QLinkedList<T> &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
bool operator==(const QLinkedList<T> &l) const;
inline bool operator!=(const QLinkedList<T> &l) const { return !(*this == l); }

View File

@ -143,11 +143,12 @@ public:
~QList();
QList<T> &operator=(const QList<T> &l);
#ifdef Q_COMPILER_RVALUE_REFS
inline QList(QList<T> &&other) : d(other.d) { other.d = const_cast<QListData::Data *>(&QListData::shared_null); }
inline QList &operator=(QList<T> &&other)
inline QList(QList<T> &&other) Q_DECL_NOTHROW
: d(other.d) { other.d = const_cast<QListData::Data *>(&QListData::shared_null); }
inline QList &operator=(QList<T> &&other) Q_DECL_NOTHROW
{ QList moved(std::move(other)); swap(moved); return *this; }
#endif
inline void swap(QList<T> &other) { qSwap(d, other.d); }
inline void swap(QList<T> &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
#ifdef Q_COMPILER_INITIALIZER_LISTS
inline QList(std::initializer_list<T> args)
: d(const_cast<QListData::Data *>(&QListData::shared_null))

View File

@ -321,7 +321,7 @@ class QMap
QMapData<Key, T> *d;
public:
inline QMap() : d(static_cast<QMapData<Key, T> *>(const_cast<QMapDataBase *>(&QMapDataBase::shared_null))) { }
inline QMap() Q_DECL_NOTHROW : d(static_cast<QMapData<Key, T> *>(const_cast<QMapDataBase *>(&QMapDataBase::shared_null))) { }
#ifdef Q_COMPILER_INITIALIZER_LISTS
inline QMap(std::initializer_list<std::pair<Key,T> > list)
: d(static_cast<QMapData<Key, T> *>(const_cast<QMapDataBase *>(&QMapDataBase::shared_null)))
@ -336,17 +336,17 @@ public:
QMap<Key, T> &operator=(const QMap<Key, T> &other);
#ifdef Q_COMPILER_RVALUE_REFS
inline QMap(QMap<Key, T> &&other)
inline QMap(QMap<Key, T> &&other) Q_DECL_NOTHROW
: d(other.d)
{
other.d = static_cast<QMapData<Key, T> *>(
const_cast<QMapDataBase *>(&QMapDataBase::shared_null));
}
inline QMap<Key, T> &operator=(QMap<Key, T> &&other)
inline QMap<Key, T> &operator=(QMap<Key, T> &&other) Q_DECL_NOTHROW
{ QMap moved(std::move(other)); swap(moved); return *this; }
#endif
inline void swap(QMap<Key, T> &other) { qSwap(d, other.d); }
inline void swap(QMap<Key, T> &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
explicit QMap(const typename std::map<Key, T> &other);
std::map<Key, T> toStdMap() const;
@ -1168,7 +1168,7 @@ template <class Key, class T>
class QMultiMap : public QMap<Key, T>
{
public:
QMultiMap() {}
QMultiMap() Q_DECL_NOTHROW {}
#ifdef Q_COMPILER_INITIALIZER_LISTS
inline QMultiMap(std::initializer_list<std::pair<Key,T> > list)
{
@ -1180,7 +1180,7 @@ public:
#ifdef Q_COMPILER_RVALUE_REFS
QMultiMap(QMap<Key, T> &&other) Q_DECL_NOTHROW : QMap<Key, T>(std::move(other)) {}
#endif
inline void swap(QMultiMap<Key, T> &other) { QMap<Key, T>::swap(other); }
void swap(QMultiMap<Key, T> &other) Q_DECL_NOTHROW { QMap<Key, T>::swap(other); }
inline typename QMap<Key, T>::iterator replace(const Key &key, const T &value)
{ return QMap<Key, T>::insert(key, value); }

View File

@ -44,7 +44,7 @@ class QQueue : public QList<T>
{
public:
// compiler-generated special member functions are fine!
inline void swap(QQueue<T> &other) { QList<T>::swap(other); } // prevent QList<->QQueue swaps
inline void swap(QQueue<T> &other) Q_DECL_NOTHROW { QList<T>::swap(other); } // prevent QList<->QQueue swaps
#ifndef Q_QDOC
// bring in QList::swap(int, int). We cannot say using QList<T>::swap,
// because we don't want to make swap(QList&) available.

View File

@ -48,7 +48,7 @@ class QSet
typedef QHash<T, QHashDummyValue> Hash;
public:
inline QSet() {}
inline QSet() Q_DECL_NOTHROW {}
#ifdef Q_COMPILER_INITIALIZER_LISTS
inline QSet(std::initializer_list<T> list)
{
@ -60,7 +60,7 @@ public:
// compiler-generated copy/move ctor/assignment operators are fine!
// compiler-generated destructor is fine!
inline void swap(QSet<T> &other) { q_hash.swap(other.q_hash); }
inline void swap(QSet<T> &other) Q_DECL_NOTHROW { q_hash.swap(other.q_hash); }
inline bool operator==(const QSet<T> &other) const
{ return q_hash == other.q_hash; }

View File

@ -44,7 +44,7 @@ class QStack : public QVector<T>
{
public:
// compiler-generated special member functions are fine!
inline void swap(QStack<T> &other) { QVector<T>::swap(other); } // prevent QVector<->QStack swaps
inline void swap(QStack<T> &other) Q_DECL_NOTHROW { QVector<T>::swap(other); } // prevent QVector<->QStack swaps
inline void push(const T &t) { QVector<T>::append(t); }
T pop();
T &top();