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 reverse 127*80865c01SMichael Kruse for (Reporter c{"init-stmt"}; auto &&v : Reporter("range")) 128*80865c01SMichael Kruse printf("v=%d\n", v); 129*80865c01SMichael Kruse printf("done\n"); 130*80865c01SMichael Kruse return EXIT_SUCCESS; 131*80865c01SMichael Kruse } 132*80865c01SMichael Kruse 133*80865c01SMichael Kruse #endif /* HEADER */ 134*80865c01SMichael Kruse 135*80865c01SMichael Kruse // CHECK: do 136*80865c01SMichael Kruse // CHECK-NEXT: [init-stmt] ctor 137*80865c01SMichael Kruse // CHECK-NEXT: [range] ctor 138*80865c01SMichael Kruse // CHECK-NEXT: [range] end() 139*80865c01SMichael Kruse // CHECK-NEXT: [range] begin() 140*80865c01SMichael Kruse // CHECK-NEXT: [range] begin() 141*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator distance: 3 142*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 2 143*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 144*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 2 145*80865c01SMichael Kruse // CHECK-NEXT: v=2 146*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 147*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 1 148*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 149*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 1 150*80865c01SMichael Kruse // CHECK-NEXT: v=1 151*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 152*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 0 153*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 154*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 0 155*80865c01SMichael Kruse // CHECK-NEXT: v=0 156*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 157*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 158*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 159*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 160*80865c01SMichael Kruse // CHECK-NEXT: [range] dtor 161*80865c01SMichael Kruse // CHECK-NEXT: [init-stmt] dtor 162*80865c01SMichael Kruse // CHECK-NEXT: done 163