123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 | // Copyright (C) 2022 The Qt Company Ltd.// Copyright (C) 2019 Intel Corporation.// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only#ifndef QFOREACH_H#define QFOREACH_H#include <QtCore/qtclasshelpermacros.h>#include <QtCore/qtconfigmacros.h>#include <QtCore/qtdeprecationmarkers.h>#include <QtCore/qttypetraits.h> QT_BEGIN_NAMESPACE #if 0#pragma qt_class(QForeach)#pragma qt_sync_stop_processing#endif#ifndef QT_NO_FOREACHnamespace QtPrivate {template<typename T>class QForeachContainer {Q_DISABLE_COPY_MOVE(QForeachContainer)public:QForeachContainer(const T &t) :c(t),i(std::as_const(c).begin()),e(std::as_const(c).end()) {}QForeachContainer(T &&t) :c(std::move(t)),i(std::as_const(c).begin()),e(std::as_const(c).end()) {} T c; typename T::const_iterator i, e;};// Containers that have a detach function are considered shared, and are OK in a foreach looptemplate<typename T, typename =decltype(std::declval<T>().detach())>inlinevoidwarnIfContainerIsNotShared(int) {}#if QT_DEPRECATED_SINCE(6, 0)// Other containers will copy themselves if used in foreach, this use is deprecatedtemplate<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")inlinevoidwarnIfContainerIsNotShared(...) {}#endiftemplate<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 */
|