diff options
Diffstat (limited to 'src/corelib/global/qglobal.h')
-rw-r--r-- | src/corelib/global/qglobal.h | 62 |
1 files changed, 46 insertions, 16 deletions
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index b4245ac8f6..9ac29acd16 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -44,6 +44,7 @@ #ifdef __cplusplus # include <type_traits> # include <cstddef> +# include <utility> #endif #include <stddef.h> @@ -915,19 +916,57 @@ QT_WARNING_DISABLE_MSVC(4530) /* C++ exception handler used, but unwind semantic # endif #endif +namespace QtPrivate { +template <typename T> struct QAddConst { typedef const T Type; }; +} + +// this adds const to non-const objects (like std::as_const) +template <typename T> +Q_DECL_CONSTEXPR typename QtPrivate::QAddConst<T>::Type &qAsConst(T &t) Q_DECL_NOTHROW { return t; } +// prevent rvalue arguments: +template <typename T> +void qAsConst(const T &&) Q_DECL_EQ_DELETE; + #ifndef QT_NO_FOREACH +namespace QtPrivate { + template <typename T> 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()) {} - const T c; + 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)) + { + } + + 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; }; +template<typename T> +QForeachContainer<typename std::decay<T>::type> qMakeForeachContainer(T &&t) +{ + return QForeachContainer<typename std::decay<T>::type>(std::forward<T>(t)); +} + +} // Explanation of the control word: // - it's initialized to 1 // - that means both the inner and outer loops start @@ -938,7 +977,7 @@ public: // - if there was a break inside the inner loop, it will exit with control still // set to 1; in that case, the outer loop will invert it to 0 and will exit too #define Q_FOREACH(variable, container) \ -for (QForeachContainer<typename std::remove_reference<decltype(container)>::type> _container_((container)); \ +for (auto _container_ = QtPrivate::qMakeForeachContainer(container); \ _container_.control && _container_.i != _container_.e; \ ++_container_.i, _container_.control ^= 1) \ for (variable = *_container_.i; _container_.control; _container_.control = 0) @@ -966,8 +1005,8 @@ template <typename Wrapper> static inline typename Wrapper::pointer qGetPtrHelpe friend class Class##Private; #define Q_DECLARE_PRIVATE_D(Dptr, Class) \ - inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(Dptr); } \ - inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private *>(Dptr); } \ + inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(qGetPtrHelper(Dptr)); } \ + inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private *>(qGetPtrHelper(Dptr)); } \ friend class Class##Private; #define Q_DECLARE_PUBLIC(Class) \ @@ -1105,17 +1144,8 @@ template <typename T> struct QEnableIf<true, T> { typedef T Type; }; template <bool B, typename T, typename F> struct QConditional { typedef T Type; }; template <typename T, typename F> struct QConditional<false, T, F> { typedef F Type; }; - -template <typename T> struct QAddConst { typedef const T Type; }; } -// this adds const to non-const objects (like std::as_const) -template <typename T> -Q_DECL_CONSTEXPR typename QtPrivate::QAddConst<T>::Type &qAsConst(T &t) Q_DECL_NOTHROW { return t; } -// prevent rvalue arguments: -template <typename T> -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. |