Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-12 09:21:28

0001 // Copyright (C) 2022 The Qt Company Ltd.
0002 // Copyright (C) 2019 Intel Corporation.
0003 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
0004 // Qt-Security score:significant reason:default
0005 
0006 #ifndef QFOREACH_H
0007 #define QFOREACH_H
0008 
0009 #include <QtCore/qtclasshelpermacros.h>
0010 #include <QtCore/qtconfigmacros.h>
0011 #include <QtCore/qtdeprecationmarkers.h>
0012 #include <QtCore/qttypetraits.h>
0013 
0014 QT_BEGIN_NAMESPACE
0015 
0016 #if 0
0017 #pragma qt_class(QForeach)
0018 #pragma qt_sync_stop_processing
0019 #endif
0020 
0021 #ifndef QT_NO_FOREACH
0022 
0023 namespace QtPrivate {
0024 
0025 template <typename T>
0026 class QForeachContainer {
0027     Q_DISABLE_COPY_MOVE(QForeachContainer)
0028 public:
0029     QForeachContainer(const T &t) : c(t), i(std::as_const(c).begin()), e(std::as_const(c).end()) {}
0030     QForeachContainer(T &&t) : c(std::move(t)), i(std::as_const(c).begin()), e(std::as_const(c).end())  {}
0031 
0032     T c;
0033     typename T::const_iterator i, e;
0034 };
0035 
0036 // Containers that have a detach function are considered shared, and are OK in a foreach loop
0037 template <typename T, typename = decltype(std::declval<T>().detach())>
0038 inline void warnIfContainerIsNotShared(int) {}
0039 
0040 #if QT_DEPRECATED_SINCE(6, 0)
0041 // Other containers will copy themselves if used in foreach, this use is deprecated
0042 template <typename T>
0043 QT_DEPRECATED_VERSION_X_6_0("Do not use foreach/Q_FOREACH with containers which are not implicitly shared. "
0044     "Prefer using a range-based for loop with these containers: `for (const auto &it : container)`, "
0045     "keeping in mind that range-based for doesn't copy the container as Q_FOREACH does")
0046 inline void warnIfContainerIsNotShared(...) {}
0047 #endif
0048 
0049 template<typename T>
0050 QForeachContainer<typename std::decay<T>::type> qMakeForeachContainer(T &&t)
0051 {
0052     warnIfContainerIsNotShared<typename std::decay<T>::type>(0);
0053     return QForeachContainer<typename std::decay<T>::type>(std::forward<T>(t));
0054 }
0055 
0056 }
0057 
0058 // Use C++17 if statement with initializer. User's code ends up in a else so
0059 // scoping of different ifs is not broken
0060 #define Q_FOREACH_IMPL(variable, name, container)                                             \
0061     for (auto name = QtPrivate::qMakeForeachContainer(container); name.i != name.e; ++name.i) \
0062         if (variable = *name.i; false) {} else
0063 
0064 #define Q_FOREACH_JOIN(A, B) Q_FOREACH_JOIN_IMPL(A, B)
0065 #define Q_FOREACH_JOIN_IMPL(A, B) A ## B
0066 
0067 #define Q_FOREACH(variable, container) \
0068     Q_FOREACH_IMPL(variable, Q_FOREACH_JOIN(_container_, __LINE__), container)
0069 #endif // QT_NO_FOREACH
0070 
0071 #define Q_FOREVER for(;;)
0072 #ifndef QT_NO_KEYWORDS
0073 # ifndef QT_NO_FOREACH
0074 #  ifndef foreach
0075 #    define foreach Q_FOREACH
0076 #  endif
0077 # endif // QT_NO_FOREACH
0078 #  ifndef forever
0079 #    define forever Q_FOREVER
0080 #  endif
0081 #endif
0082 
0083 QT_END_NAMESPACE
0084 
0085 #endif /* QFOREACH_H */