diff options
author | Marc Mutz <marc.mutz@qt.io> | 2021-12-23 18:12:59 +0100 |
---|---|---|
committer | Marc Mutz <marc.mutz@qt.io> | 2021-12-30 17:45:08 +0000 |
commit | ffcf4f400102aa3626bcf1dda6f8a703553f59f7 (patch) | |
tree | a4f7839ee4f24f5dfa63bd9afd970bb6658df36f /src/corelib/global | |
parent | f0ffe351492a7d8e9fac8a8e060b906b4b8a733a (diff) |
Extract Header qforeach.h from qglobal.h
Task-number: QTBUG-99313
Change-Id: Ie89314ca7022e88c1fea957880c5aa4a41640744
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/global')
-rw-r--r-- | src/corelib/global/qforeach.h | 135 | ||||
-rw-r--r-- | src/corelib/global/qglobal.cpp | 8 | ||||
-rw-r--r-- | src/corelib/global/qglobal.h | 81 |
3 files changed, 140 insertions, 84 deletions
diff --git a/src/corelib/global/qforeach.h b/src/corelib/global/qforeach.h new file mode 100644 index 0000000000..2b6b9f7cee --- /dev/null +++ b/src/corelib/global/qforeach.h @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Copyright (C) 2019 Intel Corporation. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QFOREACH_H +#define QFOREACH_H + +#include <QtCore/qglobal.h> + +QT_BEGIN_NAMESPACE + +#if 0 +#pragma qt_class(QForeach) +#pragma qt_sync_stop_processing +#endif + +#ifndef QT_NO_FOREACH + +namespace QtPrivate { + +template <typename T> +class QForeachContainer { + Q_DISABLE_COPY(QForeachContainer) +public: + 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; +}; + +// Containers that have a detach function are considered shared, and are OK in a foreach loop +template <typename T, typename = decltype(std::declval<T>().detach())> +inline void warnIfContainerIsNotShared(int) {} + +#if QT_DEPRECATED_SINCE(6, 0) +// Other containers will copy themselves if used in foreach, this use is deprecated +template <typename T> +QT_DEPRECATED_VERSION_X_6_0("Do not use foreach/Q_FOREACH with containers which are not implicitly shared. " + "Prefer using a range-based for loop with these containers: `for (const auto &it : container)`, " + "keeping in mind that range-based for doesn't copy the container as Q_FOREACH does") +inline void warnIfContainerIsNotShared(...) {} +#endif + +template<typename T> +QForeachContainer<typename std::decay<T>::type> qMakeForeachContainer(T &&t) +{ + warnIfContainerIsNotShared<typename std::decay<T>::type>(0); + return QForeachContainer<typename std::decay<T>::type>(std::forward<T>(t)); +} + +} + +// Use C++17 if statement with initializer. User's code ends up in a else so +// scoping of different ifs is not broken +#define Q_FOREACH_IMPL(variable, name, container) \ + for (auto name = QtPrivate::qMakeForeachContainer(container); name.i != name.e; ++name.i) \ + if (variable = *name.i; false) {} else + +#define Q_FOREACH_JOIN(A, B) Q_FOREACH_JOIN_IMPL(A, B) +#define Q_FOREACH_JOIN_IMPL(A, B) A ## B + +#define Q_FOREACH(variable, container) \ + Q_FOREACH_IMPL(variable, Q_FOREACH_JOIN(_container_, __LINE__), container) +#endif // QT_NO_FOREACH + +#define Q_FOREVER for(;;) +#ifndef QT_NO_KEYWORDS +# ifndef QT_NO_FOREACH +# ifndef foreach +# define foreach Q_FOREACH +# endif +# endif // QT_NO_FOREACH +# ifndef forever +# define forever Q_FOREVER +# endif +#endif + +QT_END_NAMESPACE + +#endif /* QFOREACH_H */ diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index befc007868..a9c44d3237 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -3701,7 +3701,7 @@ bool qunsetenv(const char *varName) /*! \macro forever - \relates <QtGlobal> + \relates <QForeach> This macro is provided for convenience for writing infinite loops. @@ -3722,7 +3722,7 @@ bool qunsetenv(const char *varName) /*! \macro Q_FOREVER - \relates <QtGlobal> + \relates <QForeach> Same as \l{forever}. @@ -3734,7 +3734,7 @@ bool qunsetenv(const char *varName) /*! \macro foreach(variable, container) - \relates <QtGlobal> + \relates <QForeach> This macro is used to implement Qt's \c foreach loop. The \a variable parameter is a variable name or variable definition; the @@ -3756,7 +3756,7 @@ bool qunsetenv(const char *varName) /*! \macro Q_FOREACH(variable, container) - \relates <QtGlobal> + \relates <QForeach> Same as foreach(\a variable, \a container). diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index e44929b379..d686bbdb8a 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1242,86 +1242,6 @@ constexpr std::underlying_type_t<Enum> qToUnderlying(Enum e) noexcept #define Q_IMPLICIT #endif -#ifndef QT_NO_FOREACH - -namespace QtPrivate { - -template <typename T> -class QForeachContainer { - Q_DISABLE_COPY(QForeachContainer) -public: - 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; -}; - -// Containers that have a detach function are considered shared, and are OK in a foreach loop -template <typename T, typename = decltype(std::declval<T>().detach())> -inline void warnIfContainerIsNotShared(int) {} - -#if QT_DEPRECATED_SINCE(6, 0) -// Other containers will copy themselves if used in foreach, this use is deprecated -template <typename T> -QT_DEPRECATED_VERSION_X_6_0("Do not use foreach/Q_FOREACH with containers which are not implicitly shared. " - "Prefer using a range-based for loop with these containers: `for (const auto &it : container)`, " - "keeping in mind that range-based for doesn't copy the container as Q_FOREACH does") -inline void warnIfContainerIsNotShared(...) {} -#endif - -template<typename T> -QForeachContainer<typename std::decay<T>::type> qMakeForeachContainer(T &&t) -{ - warnIfContainerIsNotShared<typename std::decay<T>::type>(0); - return QForeachContainer<typename std::decay<T>::type>(std::forward<T>(t)); -} - -} - -// Use C++17 if statement with initializer. User's code ends up in a else so -// scoping of different ifs is not broken -#define Q_FOREACH_IMPL(variable, name, container) \ - for (auto name = QtPrivate::qMakeForeachContainer(container); name.i != name.e; ++name.i) \ - if (variable = *name.i; false) {} else - -#define Q_FOREACH_JOIN(A, B) Q_FOREACH_JOIN_IMPL(A, B) -#define Q_FOREACH_JOIN_IMPL(A, B) A ## B - -#define Q_FOREACH(variable, container) \ - Q_FOREACH_IMPL(variable, Q_FOREACH_JOIN(_container_, __LINE__), container) -#endif // QT_NO_FOREACH - -#define Q_FOREVER for(;;) -#ifndef QT_NO_KEYWORDS -# ifndef QT_NO_FOREACH -# ifndef foreach -# define foreach Q_FOREACH -# endif -# endif // QT_NO_FOREACH -# ifndef forever -# define forever Q_FOREVER -# endif -#endif - template <typename T> inline T *qGetPtrHelper(T *ptr) noexcept { return ptr; } template <typename Ptr> inline auto qGetPtrHelper(Ptr &ptr) noexcept -> decltype(ptr.get()) { static_assert(noexcept(ptr.get()), "Smart d pointers for Q_DECLARE_PRIVATE must have noexcept get()"); return ptr.get(); } @@ -1485,6 +1405,7 @@ QT_END_NAMESPACE #include <QtCore/qglobalstatic.h> #include <QtCore/qnumeric.h> #include <QtCore/qversiontagging.h> +#include <QtCore/qforeach.h> #endif /* __cplusplus */ #endif /* !__ASSEMBLER__ */ |