Extract Header qforeach.h from qglobal.h
Task-number: QTBUG-99313 Change-Id: Ie89314ca7022e88c1fea957880c5aa4a41640744 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
f0ffe35149
commit
ffcf4f4001
135
src/corelib/global/qforeach.h
Normal file
135
src/corelib/global/qforeach.h
Normal file
@ -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 */
|
@ -3701,7 +3701,7 @@ bool qunsetenv(const char *varName)
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
\macro forever
|
\macro forever
|
||||||
\relates <QtGlobal>
|
\relates <QForeach>
|
||||||
|
|
||||||
This macro is provided for convenience for writing infinite
|
This macro is provided for convenience for writing infinite
|
||||||
loops.
|
loops.
|
||||||
@ -3722,7 +3722,7 @@ bool qunsetenv(const char *varName)
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
\macro Q_FOREVER
|
\macro Q_FOREVER
|
||||||
\relates <QtGlobal>
|
\relates <QForeach>
|
||||||
|
|
||||||
Same as \l{forever}.
|
Same as \l{forever}.
|
||||||
|
|
||||||
@ -3734,7 +3734,7 @@ bool qunsetenv(const char *varName)
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
\macro foreach(variable, container)
|
\macro foreach(variable, container)
|
||||||
\relates <QtGlobal>
|
\relates <QForeach>
|
||||||
|
|
||||||
This macro is used to implement Qt's \c foreach loop. The \a
|
This macro is used to implement Qt's \c foreach loop. The \a
|
||||||
variable parameter is a variable name or variable definition; the
|
variable parameter is a variable name or variable definition; the
|
||||||
@ -3756,7 +3756,7 @@ bool qunsetenv(const char *varName)
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
\macro Q_FOREACH(variable, container)
|
\macro Q_FOREACH(variable, container)
|
||||||
\relates <QtGlobal>
|
\relates <QForeach>
|
||||||
|
|
||||||
Same as foreach(\a variable, \a container).
|
Same as foreach(\a variable, \a container).
|
||||||
|
|
||||||
|
@ -1242,86 +1242,6 @@ constexpr std::underlying_type_t<Enum> qToUnderlying(Enum e) noexcept
|
|||||||
#define Q_IMPLICIT
|
#define Q_IMPLICIT
|
||||||
#endif
|
#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 T> inline T *qGetPtrHelper(T *ptr) noexcept { return ptr; }
|
||||||
template <typename Ptr> inline auto qGetPtrHelper(Ptr &ptr) noexcept -> decltype(ptr.get())
|
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(); }
|
{ 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/qglobalstatic.h>
|
||||||
#include <QtCore/qnumeric.h>
|
#include <QtCore/qnumeric.h>
|
||||||
#include <QtCore/qversiontagging.h>
|
#include <QtCore/qversiontagging.h>
|
||||||
|
#include <QtCore/qforeach.h>
|
||||||
|
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
#endif /* !__ASSEMBLER__ */
|
#endif /* !__ASSEMBLER__ */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user