1*80865c01SMichael Kruse // RUN: %libomp-cxx20-compile-and-run | FileCheck %s --match-full-lines 2*80865c01SMichael Kruse 3*80865c01SMichael Kruse #ifndef HEADER 4*80865c01SMichael Kruse #define HEADER 5*80865c01SMichael Kruse 6*80865c01SMichael Kruse #include <cstdlib> 7*80865c01SMichael Kruse #include <cstdarg> 8*80865c01SMichael Kruse #include <cstdio> 9*80865c01SMichael Kruse #include <vector> 10*80865c01SMichael Kruse 11*80865c01SMichael Kruse struct Reporter { 12*80865c01SMichael Kruse const char *name; 13*80865c01SMichael Kruse 14*80865c01SMichael Kruse Reporter(const char *name) : name(name) { print("ctor"); } 15*80865c01SMichael Kruse 16*80865c01SMichael Kruse Reporter() : name("<anon>") { print("ctor"); } 17*80865c01SMichael Kruse 18*80865c01SMichael Kruse Reporter(const Reporter &that) : name(that.name) { print("copy ctor"); } 19*80865c01SMichael Kruse 20*80865c01SMichael Kruse Reporter(Reporter &&that) : name(that.name) { print("move ctor"); } 21*80865c01SMichael Kruse 22*80865c01SMichael Kruse ~Reporter() { print("dtor"); } 23*80865c01SMichael Kruse 24*80865c01SMichael Kruse const Reporter &operator=(const Reporter &that) { 25*80865c01SMichael Kruse print("copy assign"); 26*80865c01SMichael Kruse this->name = that.name; 27*80865c01SMichael Kruse return *this; 28*80865c01SMichael Kruse } 29*80865c01SMichael Kruse 30*80865c01SMichael Kruse const Reporter &operator=(Reporter &&that) { 31*80865c01SMichael Kruse print("move assign"); 32*80865c01SMichael Kruse this->name = that.name; 33*80865c01SMichael Kruse return *this; 34*80865c01SMichael Kruse } 35*80865c01SMichael Kruse 36*80865c01SMichael Kruse struct Iterator { 37*80865c01SMichael Kruse const Reporter *owner; 38*80865c01SMichael Kruse int pos; 39*80865c01SMichael Kruse 40*80865c01SMichael Kruse Iterator(const Reporter *owner, int pos) : owner(owner), pos(pos) {} 41*80865c01SMichael Kruse 42*80865c01SMichael Kruse Iterator(const Iterator &that) : owner(that.owner), pos(that.pos) { 43*80865c01SMichael Kruse owner->print("iterator copy ctor"); 44*80865c01SMichael Kruse } 45*80865c01SMichael Kruse 46*80865c01SMichael Kruse Iterator(Iterator &&that) : owner(that.owner), pos(that.pos) { 47*80865c01SMichael Kruse owner->print("iterator move ctor"); 48*80865c01SMichael Kruse } 49*80865c01SMichael Kruse 50*80865c01SMichael Kruse ~Iterator() { owner->print("iterator dtor"); } 51*80865c01SMichael Kruse 52*80865c01SMichael Kruse const Iterator &operator=(const Iterator &that) { 53*80865c01SMichael Kruse owner->print("iterator copy assign"); 54*80865c01SMichael Kruse this->owner = that.owner; 55*80865c01SMichael Kruse this->pos = that.pos; 56*80865c01SMichael Kruse return *this; 57*80865c01SMichael Kruse } 58*80865c01SMichael Kruse 59*80865c01SMichael Kruse const Iterator &operator=(Iterator &&that) { 60*80865c01SMichael Kruse owner->print("iterator move assign"); 61*80865c01SMichael Kruse this->owner = that.owner; 62*80865c01SMichael Kruse this->pos = that.pos; 63*80865c01SMichael Kruse return *this; 64*80865c01SMichael Kruse } 65*80865c01SMichael Kruse 66*80865c01SMichael Kruse bool operator==(const Iterator &that) const { 67*80865c01SMichael Kruse owner->print("iterator %d == %d", 2 - this->pos, 2 - that.pos); 68*80865c01SMichael Kruse return this->pos == that.pos; 69*80865c01SMichael Kruse } 70*80865c01SMichael Kruse 71*80865c01SMichael Kruse Iterator &operator++() { 72*80865c01SMichael Kruse owner->print("iterator prefix ++"); 73*80865c01SMichael Kruse pos -= 1; 74*80865c01SMichael Kruse return *this; 75*80865c01SMichael Kruse } 76*80865c01SMichael Kruse 77*80865c01SMichael Kruse Iterator operator++(int) { 78*80865c01SMichael Kruse owner->print("iterator postfix ++"); 79*80865c01SMichael Kruse auto result = *this; 80*80865c01SMichael Kruse pos -= 1; 81*80865c01SMichael Kruse return result; 82*80865c01SMichael Kruse } 83*80865c01SMichael Kruse 84*80865c01SMichael Kruse int operator*() const { 85*80865c01SMichael Kruse int result = 2 - pos; 86*80865c01SMichael Kruse owner->print("iterator deref: %i", result); 87*80865c01SMichael Kruse return result; 88*80865c01SMichael Kruse } 89*80865c01SMichael Kruse 90*80865c01SMichael Kruse size_t operator-(const Iterator &that) const { 91*80865c01SMichael Kruse int result = (2 - this->pos) - (2 - that.pos); 92*80865c01SMichael Kruse owner->print("iterator distance: %d", result); 93*80865c01SMichael Kruse return result; 94*80865c01SMichael Kruse } 95*80865c01SMichael Kruse 96*80865c01SMichael Kruse Iterator operator+(int steps) const { 97*80865c01SMichael Kruse owner->print("iterator advance: %i += %i", 2 - this->pos, steps); 98*80865c01SMichael Kruse return Iterator(owner, pos - steps); 99*80865c01SMichael Kruse } 100*80865c01SMichael Kruse 101*80865c01SMichael Kruse void print(const char *msg) const { owner->print(msg); } 102*80865c01SMichael Kruse }; 103*80865c01SMichael Kruse 104*80865c01SMichael Kruse Iterator begin() const { 105*80865c01SMichael Kruse print("begin()"); 106*80865c01SMichael Kruse return Iterator(this, 2); 107*80865c01SMichael Kruse } 108*80865c01SMichael Kruse 109*80865c01SMichael Kruse Iterator end() const { 110*80865c01SMichael Kruse print("end()"); 111*80865c01SMichael Kruse return Iterator(this, -1); 112*80865c01SMichael Kruse } 113*80865c01SMichael Kruse 114*80865c01SMichael Kruse void print(const char *msg, ...) const { 115*80865c01SMichael Kruse va_list args; 116*80865c01SMichael Kruse va_start(args, msg); 117*80865c01SMichael Kruse printf("[%s] ", name); 118*80865c01SMichael Kruse vprintf(msg, args); 119*80865c01SMichael Kruse printf("\n"); 120*80865c01SMichael Kruse va_end(args); 121*80865c01SMichael Kruse } 122*80865c01SMichael Kruse }; 123*80865c01SMichael Kruse 124*80865c01SMichael Kruse int main() { 125*80865c01SMichael Kruse printf("do\n"); 126*80865c01SMichael Kruse #pragma omp parallel for collapse(3) num_threads(1) 127*80865c01SMichael Kruse for (int i = 0; i < 3; ++i) 128*80865c01SMichael Kruse #pragma omp reverse 129*80865c01SMichael Kruse for (Reporter c{"init-stmt"}; auto &&v : Reporter("range")) 130*80865c01SMichael Kruse for (int k = 0; k < 3; ++k) 131*80865c01SMichael Kruse printf("i=%d j=%d k=%d\n", i, v, k); 132*80865c01SMichael Kruse printf("done\n"); 133*80865c01SMichael Kruse return EXIT_SUCCESS; 134*80865c01SMichael Kruse } 135*80865c01SMichael Kruse 136*80865c01SMichael Kruse #endif /* HEADER */ 137*80865c01SMichael Kruse 138*80865c01SMichael Kruse // CHECK: do 139*80865c01SMichael Kruse // CHECK-NEXT: [init-stmt] ctor 140*80865c01SMichael Kruse // CHECK-NEXT: [range] ctor 141*80865c01SMichael Kruse // CHECK-NEXT: [range] end() 142*80865c01SMichael Kruse // CHECK-NEXT: [range] begin() 143*80865c01SMichael Kruse // CHECK-NEXT: [range] begin() 144*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator distance: 3 145*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 2 146*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 147*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 2 148*80865c01SMichael Kruse // CHECK-NEXT: i=0 j=2 k=0 149*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 150*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 2 151*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 152*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 2 153*80865c01SMichael Kruse // CHECK-NEXT: i=0 j=2 k=1 154*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 155*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 2 156*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 157*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 2 158*80865c01SMichael Kruse // CHECK-NEXT: i=0 j=2 k=2 159*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 160*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 1 161*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 162*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 1 163*80865c01SMichael Kruse // CHECK-NEXT: i=0 j=1 k=0 164*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 165*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 1 166*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 167*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 1 168*80865c01SMichael Kruse // CHECK-NEXT: i=0 j=1 k=1 169*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 170*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 1 171*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 172*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 1 173*80865c01SMichael Kruse // CHECK-NEXT: i=0 j=1 k=2 174*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 175*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 0 176*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 177*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 0 178*80865c01SMichael Kruse // CHECK-NEXT: i=0 j=0 k=0 179*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 180*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 0 181*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 182*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 0 183*80865c01SMichael Kruse // CHECK-NEXT: i=0 j=0 k=1 184*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 185*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 0 186*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 187*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 0 188*80865c01SMichael Kruse // CHECK-NEXT: i=0 j=0 k=2 189*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 190*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 2 191*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 192*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 2 193*80865c01SMichael Kruse // CHECK-NEXT: i=1 j=2 k=0 194*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 195*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 2 196*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 197*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 2 198*80865c01SMichael Kruse // CHECK-NEXT: i=1 j=2 k=1 199*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 200*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 2 201*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 202*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 2 203*80865c01SMichael Kruse // CHECK-NEXT: i=1 j=2 k=2 204*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 205*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 1 206*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 207*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 1 208*80865c01SMichael Kruse // CHECK-NEXT: i=1 j=1 k=0 209*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 210*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 1 211*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 212*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 1 213*80865c01SMichael Kruse // CHECK-NEXT: i=1 j=1 k=1 214*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 215*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 1 216*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 217*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 1 218*80865c01SMichael Kruse // CHECK-NEXT: i=1 j=1 k=2 219*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 220*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 0 221*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 222*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 0 223*80865c01SMichael Kruse // CHECK-NEXT: i=1 j=0 k=0 224*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 225*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 0 226*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 227*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 0 228*80865c01SMichael Kruse // CHECK-NEXT: i=1 j=0 k=1 229*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 230*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 0 231*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 232*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 0 233*80865c01SMichael Kruse // CHECK-NEXT: i=1 j=0 k=2 234*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 235*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 2 236*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 237*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 2 238*80865c01SMichael Kruse // CHECK-NEXT: i=2 j=2 k=0 239*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 240*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 2 241*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 242*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 2 243*80865c01SMichael Kruse // CHECK-NEXT: i=2 j=2 k=1 244*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 245*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 2 246*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 247*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 2 248*80865c01SMichael Kruse // CHECK-NEXT: i=2 j=2 k=2 249*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 250*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 1 251*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 252*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 1 253*80865c01SMichael Kruse // CHECK-NEXT: i=2 j=1 k=0 254*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 255*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 1 256*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 257*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 1 258*80865c01SMichael Kruse // CHECK-NEXT: i=2 j=1 k=1 259*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 260*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 1 261*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 262*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 1 263*80865c01SMichael Kruse // CHECK-NEXT: i=2 j=1 k=2 264*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 265*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 0 266*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 267*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 0 268*80865c01SMichael Kruse // CHECK-NEXT: i=2 j=0 k=0 269*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 270*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 0 271*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 272*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 0 273*80865c01SMichael Kruse // CHECK-NEXT: i=2 j=0 k=1 274*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 275*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 0 276*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 277*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 0 278*80865c01SMichael Kruse // CHECK-NEXT: i=2 j=0 k=2 279*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 280*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 281*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 282*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 283*80865c01SMichael Kruse // CHECK-NEXT: [range] dtor 284*80865c01SMichael Kruse // CHECK-NEXT: [init-stmt] dtor 285*80865c01SMichael Kruse // CHECK-NEXT: done 286