From a35a01aaa2aa4d3ba8d3c619ec2d18fcc4a6ad2f Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Wed, 9 Nov 2016 17:40:14 +0100 Subject: QForeachContainer: make it a move-only type Honor the rule of five. Copy assignment was already disabled. Disable also copy construction, but re-enable the move special member functions. This requires making the container non-const; to avoid detaches and keep compatibility with containers that only have begin/end (but not cbegin/cend), use qAsConst. This requires moving qAsConst definition a bit up in the file. Change-Id: I19cd74437cf69baceada9483920a21e96d7b1727 Reviewed-by: Thiago Macieira --- src/corelib/global/qglobal.h | 48 +++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 127e1e7e13..a020be7fb2 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -917,25 +917,46 @@ QT_WARNING_DISABLE_MSVC(4530) /* C++ exception handler used, but unwind semantic # endif #endif +namespace QtPrivate { +template struct QAddConst { typedef const T Type; }; +} + +// this adds const to non-const objects (like std::as_const) +template +Q_DECL_CONSTEXPR typename QtPrivate::QAddConst::Type &qAsConst(T &t) Q_DECL_NOTHROW { return t; } +// prevent rvalue arguments: +template +void qAsConst(const T &&) Q_DECL_EQ_DELETE; + #ifndef QT_NO_FOREACH namespace QtPrivate { template class QForeachContainer { - QForeachContainer &operator=(const QForeachContainer &) Q_DECL_EQ_DELETE; + Q_DISABLE_COPY(QForeachContainer) public: - QForeachContainer(const T &t) : c(t), i(c.begin()), e(c.end()) {} - QForeachContainer(T &&t) : c(std::move(t)), i(c.begin()), e(c.end()) {} - QForeachContainer(const QForeachContainer &other) - : c(other.c), - i(c.begin()), - e(c.end()), - control(other.control) + QForeachContainer(const T &t) : c(t), i(qAsConst(c).begin()), e(qAsConst(c).end()) {} + QForeachContainer(T &&t) : c(std::move(t)), i(qAsConst(c).begin()), e(qAsConst(c).end()) {} + + QForeachContainer(QForeachContainer &&other) + : c(std::move(other.c)), + i(qAsConst(c).begin()), + e(qAsConst(c).end()), + control(std::move(other.control)) { } - const T c; + QForeachContainer &operator=(QForeachContainer &&other) + { + c = std::move(other.c); + i = qAsConst(c).begin(); + e = qAsConst(c).end(); + control = std::move(other.control); + return *this; + } + + T c; typename T::const_iterator i, e; int control = 1; }; @@ -1124,17 +1145,8 @@ template struct QEnableIf { typedef T Type; }; template struct QConditional { typedef T Type; }; template struct QConditional { typedef F Type; }; - -template struct QAddConst { typedef const T Type; }; } -// this adds const to non-const objects (like std::as_const) -template -Q_DECL_CONSTEXPR typename QtPrivate::QAddConst::Type &qAsConst(T &t) Q_DECL_NOTHROW { return t; } -// prevent rvalue arguments: -template -void qAsConst(const T &&) Q_DECL_EQ_DELETE; - QT_END_NAMESPACE // We need to keep QTypeInfo, QSysInfo, QFlags, qDebug & family in qglobal.h for compatibility with Qt 4. -- cgit v1.2.3