// P2718R0 - Wording for P2644R1 Fix for Range-based for Loop // { dg-do run { target c++11 } } #ifndef RANGE_FOR_EXT_TEMPS #define RANGE_FOR_EXT_TEMPS (__cpp_range_based_for >= 202211L) #endif extern "C" void abort (); int a[4]; template int * begin (const T &) { return &a[0]; } template int * end (const T &) { return &a[4]; } struct S { S () { ++s; } S (const S &) { ++s; } ~S () { --s; } static int s; }; int S::s; template struct U { T t; U () { ++u; } U (const U &) { ++u; } ~U () { --u; } const int *begin () const { return ::begin (t); } const int *end () const { return ::end (t); } U &foo () { return *this; } U bar () { return U (); } static int u; }; template int U::u; template U foo () { return U {}; } template T fred (const T &, const T & = T{}, const T & = T{}) { return T {}; } void bar () { int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; if (S::s != 0) abort (); for (auto x : S (), a) { if (S::s != RANGE_FOR_EXT_TEMPS) abort (); } if (S::s != 0) abort (); for (auto x : (void) S (), a) { if (S::s != RANGE_FOR_EXT_TEMPS) abort (); } if (S::s != 0) abort (); for (auto x : static_cast (S ()), a) { if (S::s != RANGE_FOR_EXT_TEMPS) abort (); } if (S::s != 0) abort (); for (auto x : foo ().foo ().bar ().foo ().bar ().foo ().bar ()) { if (S::s != 1 + 3 * RANGE_FOR_EXT_TEMPS) abort (); if (U::u != S::s) abort (); } if (S::s != 0 || U::u != 0) abort (); for (auto x : fred (S {})) { if (S::s != 1 + 3 * RANGE_FOR_EXT_TEMPS) abort (); } if (S::s != 0) abort (); for (auto x : fred (fred (S {}, S {}))) { if (S::s != 1 + 6 * RANGE_FOR_EXT_TEMPS) abort (); } if (S::s != 0) abort (); } template void baz () { int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; if (S::s != 0) abort (); for (auto x : S (), a) { if (S::s != RANGE_FOR_EXT_TEMPS) abort (); } if (S::s != 0) abort (); for (auto x : (void) S (), a) { if (S::s != RANGE_FOR_EXT_TEMPS) abort (); } if (S::s != 0) abort (); for (auto x : static_cast (S ()), a) { if (S::s != RANGE_FOR_EXT_TEMPS) abort (); } if (S::s != 0) abort (); for (auto x : foo ().foo ().bar ().foo ().bar ().foo ().bar ()) { if (S::s != 1 + 3 * RANGE_FOR_EXT_TEMPS) abort (); if (U::u != S::s) abort (); } if (S::s != 0 || U::u != 0) abort (); for (auto x : fred (S {})) { if (S::s != 1 + 3 * RANGE_FOR_EXT_TEMPS) abort (); } if (S::s != 0) abort (); for (auto x : fred (fred (S {}, S {}))) { if (S::s != 1 + 6 * RANGE_FOR_EXT_TEMPS) abort (); } if (S::s != 0) abort (); } template void qux () { int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; if (S::s != 0) abort (); for (auto x : S (), a) { if (S::s != RANGE_FOR_EXT_TEMPS) abort (); } if (S::s != 0) abort (); for (auto x : (void) S (), a) { if (S::s != RANGE_FOR_EXT_TEMPS) abort (); } if (S::s != 0) abort (); for (auto x : static_cast (S ()), a) { if (S::s != RANGE_FOR_EXT_TEMPS) abort (); } if (S::s != 0) abort (); for (auto x : foo ().foo ().bar ().foo ().bar ().foo ().bar ()) { if (S::s != 1 + 3 * RANGE_FOR_EXT_TEMPS) abort (); if (U::u != S::s) abort (); } if (S::s != 0 || U::u != 0) abort (); for (auto x : fred (S {})) { if (S::s != 1 + 3 * RANGE_FOR_EXT_TEMPS) abort (); } if (S::s != 0) abort (); for (auto x : fred (fred (S {}, S {}))) { if (S::s != 1 + 6 * RANGE_FOR_EXT_TEMPS) abort (); } if (S::s != 0) abort (); } int main () { bar (); baz <0> (); qux (); }