Simplify the Q_FOREACH macro when using C++17
This way there is only one for loop, which is more optimizer friendly Change-Id: Iaa02026627d5259c3eea1ff5664e8f22664eef73 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
22788194f9
commit
0330b967f2
@ -1005,6 +1005,15 @@ QForeachContainer<typename std::decay<T>::type> qMakeForeachContainer(T &&t)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
// 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(variable, container) \
|
||||
for (auto _container_ = QtPrivate::qMakeForeachContainer(container); \
|
||||
_container_.i != _container_.e; ++_container_.i) \
|
||||
if (variable = *_container_.i; false) {} else
|
||||
#else
|
||||
// Explanation of the control word:
|
||||
// - it's initialized to 1
|
||||
// - that means both the inner and outer loops start
|
||||
@ -1019,7 +1028,7 @@ 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)
|
||||
|
||||
#endif
|
||||
#endif // QT_NO_FOREACH
|
||||
|
||||
#define Q_FOREVER for(;;)
|
||||
|
@ -2,3 +2,4 @@ CONFIG += testcase
|
||||
TARGET = tst_qglobal
|
||||
QT = core testlib
|
||||
SOURCES = tst_qglobal.cpp qglobal.c
|
||||
contains(QT_CONFIG, c++1z): CONFIG += c++1z
|
||||
|
@ -126,6 +126,46 @@ void tst_QGlobal::for_each()
|
||||
QCOMPARE(i, counter++);
|
||||
}
|
||||
QCOMPARE(counter, list.count());
|
||||
|
||||
// Should also work with an existing variable
|
||||
int local;
|
||||
counter = 0;
|
||||
foreach (local, list) {
|
||||
QCOMPARE(local, counter++);
|
||||
}
|
||||
QCOMPARE(counter, list.count());
|
||||
QCOMPARE(local, counter - 1);
|
||||
|
||||
// Test the macro does not mess if/else conditions
|
||||
counter = 0;
|
||||
if (true)
|
||||
foreach (int i, list)
|
||||
QCOMPARE(i, counter++);
|
||||
else
|
||||
QFAIL("If/Else mismatch");
|
||||
QCOMPARE(counter, list.count());
|
||||
|
||||
counter = 0;
|
||||
if (false)
|
||||
foreach (int i, list)
|
||||
if (i) QFAIL("If/Else mismatch");
|
||||
else QFAIL("If/Else mismatch");
|
||||
else
|
||||
foreach (int i, list)
|
||||
if (false) { }
|
||||
else QCOMPARE(i, counter++);
|
||||
QCOMPARE(counter, list.count());
|
||||
|
||||
// break and continue
|
||||
counter = 0;
|
||||
foreach (int i, list) {
|
||||
if (i == 0)
|
||||
continue;
|
||||
QCOMPARE(i, (counter++) + 1);
|
||||
if (i == 3)
|
||||
break;
|
||||
}
|
||||
QCOMPARE(counter, 3);
|
||||
}
|
||||
|
||||
void tst_QGlobal::qassert()
|
||||
|
Loading…
x
Reference in New Issue
Block a user