summaryrefslogtreecommitdiffstats
path: root/src/corelib/global/qglobal.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/global/qglobal.h')
-rw-r--r--src/corelib/global/qglobal.h62
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.