1 // RUN: %libomp-cxx20-compile-and-run | FileCheck %s --match-full-lines 2 3 #ifndef HEADER 4 #define HEADER 5 6 #include <cstdlib> 7 #include <cstdarg> 8 #include <cstdio> 9 #include <vector> 10 11 struct Reporter { 12 const char *name; 13 14 Reporter(const char *name) : name(name) { print("ctor"); } 15 16 Reporter() : name("<anon>") { print("ctor"); } 17 18 Reporter(const Reporter &that) : name(that.name) { print("copy ctor"); } 19 20 Reporter(Reporter &&that) : name(that.name) { print("move ctor"); } 21 22 ~Reporter() { print("dtor"); } 23 24 const Reporter &operator=(const Reporter &that) { 25 print("copy assign"); 26 this->name = that.name; 27 return *this; 28 } 29 30 const Reporter &operator=(Reporter &&that) { 31 print("move assign"); 32 this->name = that.name; 33 return *this; 34 } 35 36 struct Iterator { 37 const Reporter *owner; 38 int pos; 39 40 Iterator(const Reporter *owner, int pos) : owner(owner), pos(pos) {} 41 42 Iterator(const Iterator &that) : owner(that.owner), pos(that.pos) { 43 owner->print("iterator copy ctor"); 44 } 45 46 Iterator(Iterator &&that) : owner(that.owner), pos(that.pos) { 47 owner->print("iterator move ctor"); 48 } 49 50 ~Iterator() { owner->print("iterator dtor"); } 51 52 const Iterator &operator=(const Iterator &that) { 53 owner->print("iterator copy assign"); 54 this->owner = that.owner; 55 this->pos = that.pos; 56 return *this; 57 } 58 59 const Iterator &operator=(Iterator &&that) { 60 owner->print("iterator move assign"); 61 this->owner = that.owner; 62 this->pos = that.pos; 63 return *this; 64 } 65 66 bool operator==(const Iterator &that) const { 67 owner->print("iterator %d == %d", 2 - this->pos, 2 - that.pos); 68 return this->pos == that.pos; 69 } 70 71 Iterator &operator++() { 72 owner->print("iterator prefix ++"); 73 pos -= 1; 74 return *this; 75 } 76 77 Iterator operator++(int) { 78 owner->print("iterator postfix ++"); 79 auto result = *this; 80 pos -= 1; 81 return result; 82 } 83 84 int operator*() const { 85 int result = 2 - pos; 86 owner->print("iterator deref: %i", result); 87 return result; 88 } 89 90 size_t operator-(const Iterator &that) const { 91 int result = (2 - this->pos) - (2 - that.pos); 92 owner->print("iterator distance: %d", result); 93 return result; 94 } 95 96 Iterator operator+(int steps) const { 97 owner->print("iterator advance: %i += %i", 2 - this->pos, steps); 98 return Iterator(owner, pos - steps); 99 } 100 101 void print(const char *msg) const { owner->print(msg); } 102 }; 103 104 Iterator begin() const { 105 print("begin()"); 106 return Iterator(this, 2); 107 } 108 109 Iterator end() const { 110 print("end()"); 111 return Iterator(this, -1); 112 } 113 114 void print(const char *msg, ...) const { 115 va_list args; 116 va_start(args, msg); 117 printf("[%s] ", name); 118 vprintf(msg, args); 119 printf("\n"); 120 va_end(args); 121 } 122 }; 123 124 int main() { 125 printf("do\n"); 126 #pragma omp reverse 127 for (Reporter c{"init-stmt"}; auto &&v : Reporter("range")) 128 printf("v=%d\n", v); 129 printf("done\n"); 130 return EXIT_SUCCESS; 131 } 132 133 #endif /* HEADER */ 134 135 // CHECK: do 136 // CHECK-NEXT: [init-stmt] ctor 137 // CHECK-NEXT: [range] ctor 138 // CHECK-NEXT: [range] end() 139 // CHECK-NEXT: [range] begin() 140 // CHECK-NEXT: [range] begin() 141 // CHECK-NEXT: [range] iterator distance: 3 142 // CHECK-NEXT: [range] iterator advance: 0 += 2 143 // CHECK-NEXT: [range] iterator move assign 144 // CHECK-NEXT: [range] iterator deref: 2 145 // CHECK-NEXT: v=2 146 // CHECK-NEXT: [range] iterator dtor 147 // CHECK-NEXT: [range] iterator advance: 0 += 1 148 // CHECK-NEXT: [range] iterator move assign 149 // CHECK-NEXT: [range] iterator deref: 1 150 // CHECK-NEXT: v=1 151 // CHECK-NEXT: [range] iterator dtor 152 // CHECK-NEXT: [range] iterator advance: 0 += 0 153 // CHECK-NEXT: [range] iterator move assign 154 // CHECK-NEXT: [range] iterator deref: 0 155 // CHECK-NEXT: v=0 156 // CHECK-NEXT: [range] iterator dtor 157 // CHECK-NEXT: [range] iterator dtor 158 // CHECK-NEXT: [range] iterator dtor 159 // CHECK-NEXT: [range] iterator dtor 160 // CHECK-NEXT: [range] dtor 161 // CHECK-NEXT: [init-stmt] dtor 162 // CHECK-NEXT: done 163