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 bool operator!=(const Iterator &that) const { 72*80865c01SMichael Kruse owner->print("iterator %d != %d", 2 - this->pos, 2 - that.pos); 73*80865c01SMichael Kruse return this->pos != that.pos; 74*80865c01SMichael Kruse } 75*80865c01SMichael Kruse 76*80865c01SMichael Kruse Iterator &operator++() { 77*80865c01SMichael Kruse owner->print("iterator prefix ++"); 78*80865c01SMichael Kruse pos -= 1; 79*80865c01SMichael Kruse return *this; 80*80865c01SMichael Kruse } 81*80865c01SMichael Kruse 82*80865c01SMichael Kruse Iterator operator++(int) { 83*80865c01SMichael Kruse owner->print("iterator postfix ++"); 84*80865c01SMichael Kruse auto result = *this; 85*80865c01SMichael Kruse pos -= 1; 86*80865c01SMichael Kruse return result; 87*80865c01SMichael Kruse } 88*80865c01SMichael Kruse 89*80865c01SMichael Kruse int operator*() const { 90*80865c01SMichael Kruse int result = 2 - pos; 91*80865c01SMichael Kruse owner->print("iterator deref: %i", result); 92*80865c01SMichael Kruse return result; 93*80865c01SMichael Kruse } 94*80865c01SMichael Kruse 95*80865c01SMichael Kruse size_t operator-(const Iterator &that) const { 96*80865c01SMichael Kruse int result = (2 - this->pos) - (2 - that.pos); 97*80865c01SMichael Kruse owner->print("iterator distance: %d", result); 98*80865c01SMichael Kruse return result; 99*80865c01SMichael Kruse } 100*80865c01SMichael Kruse 101*80865c01SMichael Kruse Iterator operator+(int steps) const { 102*80865c01SMichael Kruse owner->print("iterator advance: %i += %i", 2 - this->pos, steps); 103*80865c01SMichael Kruse return Iterator(owner, pos - steps); 104*80865c01SMichael Kruse } 105*80865c01SMichael Kruse }; 106*80865c01SMichael Kruse 107*80865c01SMichael Kruse Iterator begin() const { 108*80865c01SMichael Kruse print("begin()"); 109*80865c01SMichael Kruse return Iterator(this, 2); 110*80865c01SMichael Kruse } 111*80865c01SMichael Kruse 112*80865c01SMichael Kruse Iterator end() const { 113*80865c01SMichael Kruse print("end()"); 114*80865c01SMichael Kruse return Iterator(this, -1); 115*80865c01SMichael Kruse } 116*80865c01SMichael Kruse 117*80865c01SMichael Kruse void print(const char *msg, ...) const { 118*80865c01SMichael Kruse va_list args; 119*80865c01SMichael Kruse va_start(args, msg); 120*80865c01SMichael Kruse printf("[%s] ", name); 121*80865c01SMichael Kruse vprintf(msg, args); 122*80865c01SMichael Kruse printf("\n"); 123*80865c01SMichael Kruse va_end(args); 124*80865c01SMichael Kruse } 125*80865c01SMichael Kruse }; 126*80865c01SMichael Kruse 127*80865c01SMichael Kruse int main() { 128*80865c01SMichael Kruse printf("do\n"); 129*80865c01SMichael Kruse Reporter range("range"); 130*80865c01SMichael Kruse #pragma omp reverse 131*80865c01SMichael Kruse for (auto it = range.begin(); it != range.end(); ++it) 132*80865c01SMichael Kruse printf("v=%d\n", *it); 133*80865c01SMichael Kruse printf("done\n"); 134*80865c01SMichael Kruse return EXIT_SUCCESS; 135*80865c01SMichael Kruse } 136*80865c01SMichael Kruse 137*80865c01SMichael Kruse #endif /* HEADER */ 138*80865c01SMichael Kruse 139*80865c01SMichael Kruse // CHECK: do 140*80865c01SMichael Kruse // CHECK-NEXT: [range] ctor 141*80865c01SMichael Kruse // CHECK-NEXT: [range] begin() 142*80865c01SMichael Kruse // CHECK-NEXT: [range] begin() 143*80865c01SMichael Kruse // CHECK-NEXT: [range] end() 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: v=2 149*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 150*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 1 151*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 152*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 1 153*80865c01SMichael Kruse // CHECK-NEXT: v=1 154*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 155*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator advance: 0 += 0 156*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator move assign 157*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator deref: 0 158*80865c01SMichael Kruse // CHECK-NEXT: v=0 159*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 160*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 161*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 162*80865c01SMichael Kruse // CHECK-NEXT: done 163*80865c01SMichael Kruse // CHECK-NEXT: [range] iterator dtor 164*80865c01SMichael Kruse // CHECK-NEXT: [range] dtor 165