| // XFAIL: msvc |
| // Fails on windows due to issue #129023 |
| // RUN: %libomp-cxx20-compile-and-run | FileCheck %s --match-full-lines |
| |
| #ifndef HEADER |
| #define HEADER |
| |
| #include <cstdlib> |
| #include <cstdarg> |
| #include <cstdio> |
| #include <vector> |
| |
| struct Reporter { |
| const char *name; |
| |
| Reporter(const char *name) : name(name) { print("ctor"); } |
| |
| Reporter() : name("<anon>") { print("ctor"); } |
| |
| Reporter(const Reporter &that) : name(that.name) { print("copy ctor"); } |
| |
| Reporter(Reporter &&that) : name(that.name) { print("move ctor"); } |
| |
| ~Reporter() { print("dtor"); } |
| |
| const Reporter &operator=(const Reporter &that) { |
| print("copy assign"); |
| this->name = that.name; |
| return *this; |
| } |
| |
| const Reporter &operator=(Reporter &&that) { |
| print("move assign"); |
| this->name = that.name; |
| return *this; |
| } |
| |
| struct Iterator { |
| const Reporter *owner; |
| int pos; |
| |
| Iterator(const Reporter *owner, int pos) : owner(owner), pos(pos) {} |
| |
| Iterator(const Iterator &that) : owner(that.owner), pos(that.pos) { |
| owner->print("iterator copy ctor"); |
| } |
| |
| Iterator(Iterator &&that) : owner(that.owner), pos(that.pos) { |
| owner->print("iterator move ctor"); |
| } |
| |
| ~Iterator() { owner->print("iterator dtor"); } |
| |
| const Iterator &operator=(const Iterator &that) { |
| owner->print("iterator copy assign"); |
| this->owner = that.owner; |
| this->pos = that.pos; |
| return *this; |
| } |
| |
| const Iterator &operator=(Iterator &&that) { |
| owner->print("iterator move assign"); |
| this->owner = that.owner; |
| this->pos = that.pos; |
| return *this; |
| } |
| |
| bool operator==(const Iterator &that) const { |
| owner->print("iterator %d == %d", 2 - this->pos, 2 - that.pos); |
| return this->pos == that.pos; |
| } |
| |
| bool operator!=(const Iterator &that) const { |
| owner->print("iterator %d != %d", 2 - this->pos, 2 - that.pos); |
| return this->pos == that.pos; |
| } |
| |
| Iterator &operator++() { |
| owner->print("iterator prefix ++"); |
| pos -= 1; |
| return *this; |
| } |
| |
| Iterator operator++(int) { |
| owner->print("iterator postfix ++"); |
| auto result = *this; |
| pos -= 1; |
| return result; |
| } |
| |
| int operator*() const { |
| int result = 2 - pos; |
| owner->print("iterator deref: %i", result); |
| return result; |
| } |
| |
| size_t operator-(const Iterator &that) const { |
| int result = (2 - this->pos) - (2 - that.pos); |
| owner->print("iterator distance: %d", result); |
| return result; |
| } |
| |
| Iterator operator+(int steps) const { |
| owner->print("iterator advance: %i += %i", 2 - this->pos, steps); |
| return Iterator(owner, pos - steps); |
| } |
| }; |
| |
| Iterator begin() const { |
| print("begin()"); |
| return Iterator(this, 2); |
| } |
| |
| Iterator end() const { |
| print("end()"); |
| return Iterator(this, -1); |
| } |
| |
| void print(const char *msg, ...) const { |
| va_list args; |
| va_start(args, msg); |
| printf("[%s] ", name); |
| vprintf(msg, args); |
| printf("\n"); |
| va_end(args); |
| } |
| }; |
| |
| int main() { |
| printf("do\n"); |
| Reporter A("A"), B("B"); |
| #pragma omp interchange |
| for (auto it = A.begin(); it != A.end(); ++it) |
| for (auto jt = B.begin(); jt != B.end(); ++jt) |
| printf("i=%d j=%d\n", *it, *jt); |
| printf("done\n"); |
| return EXIT_SUCCESS; |
| } |
| |
| #endif /* HEADER */ |
| |
| // CHECK: do |
| // CHECK-NEXT: [A] ctor |
| // CHECK-NEXT: [B] ctor |
| // CHECK-NEXT: [A] begin() |
| // CHECK-NEXT: [A] begin() |
| // CHECK-NEXT: [A] end() |
| // CHECK-NEXT: [A] iterator distance: 3 |
| // CHECK-NEXT: [B] begin() |
| // CHECK-NEXT: [B] begin() |
| // CHECK-NEXT: [B] end() |
| // CHECK-NEXT: [B] iterator distance: 3 |
| // CHECK-NEXT: [B] iterator advance: 0 += 0 |
| // CHECK-NEXT: [B] iterator move assign |
| // CHECK-NEXT: [A] iterator advance: 0 += 0 |
| // CHECK-NEXT: [A] iterator move assign |
| // CHECK-NEXT: [A] iterator deref: 0 |
| // CHECK-NEXT: [B] iterator deref: 0 |
| // CHECK-NEXT: i=0 j=0 |
| // CHECK-NEXT: [A] iterator dtor |
| // CHECK-NEXT: [A] iterator advance: 0 += 1 |
| // CHECK-NEXT: [A] iterator move assign |
| // CHECK-NEXT: [A] iterator deref: 1 |
| // CHECK-NEXT: [B] iterator deref: 0 |
| // CHECK-NEXT: i=1 j=0 |
| // CHECK-NEXT: [A] iterator dtor |
| // CHECK-NEXT: [A] iterator advance: 0 += 2 |
| // CHECK-NEXT: [A] iterator move assign |
| // CHECK-NEXT: [A] iterator deref: 2 |
| // CHECK-NEXT: [B] iterator deref: 0 |
| // CHECK-NEXT: i=2 j=0 |
| // CHECK-NEXT: [A] iterator dtor |
| // CHECK-NEXT: [B] iterator dtor |
| // CHECK-NEXT: [B] iterator advance: 0 += 1 |
| // CHECK-NEXT: [B] iterator move assign |
| // CHECK-NEXT: [A] iterator advance: 0 += 0 |
| // CHECK-NEXT: [A] iterator move assign |
| // CHECK-NEXT: [A] iterator deref: 0 |
| // CHECK-NEXT: [B] iterator deref: 1 |
| // CHECK-NEXT: i=0 j=1 |
| // CHECK-NEXT: [A] iterator dtor |
| // CHECK-NEXT: [A] iterator advance: 0 += 1 |
| // CHECK-NEXT: [A] iterator move assign |
| // CHECK-NEXT: [A] iterator deref: 1 |
| // CHECK-NEXT: [B] iterator deref: 1 |
| // CHECK-NEXT: i=1 j=1 |
| // CHECK-NEXT: [A] iterator dtor |
| // CHECK-NEXT: [A] iterator advance: 0 += 2 |
| // CHECK-NEXT: [A] iterator move assign |
| // CHECK-NEXT: [A] iterator deref: 2 |
| // CHECK-NEXT: [B] iterator deref: 1 |
| // CHECK-NEXT: i=2 j=1 |
| // CHECK-NEXT: [A] iterator dtor |
| // CHECK-NEXT: [B] iterator dtor |
| // CHECK-NEXT: [B] iterator advance: 0 += 2 |
| // CHECK-NEXT: [B] iterator move assign |
| // CHECK-NEXT: [A] iterator advance: 0 += 0 |
| // CHECK-NEXT: [A] iterator move assign |
| // CHECK-NEXT: [A] iterator deref: 0 |
| // CHECK-NEXT: [B] iterator deref: 2 |
| // CHECK-NEXT: i=0 j=2 |
| // CHECK-NEXT: [A] iterator dtor |
| // CHECK-NEXT: [A] iterator advance: 0 += 1 |
| // CHECK-NEXT: [A] iterator move assign |
| // CHECK-NEXT: [A] iterator deref: 1 |
| // CHECK-NEXT: [B] iterator deref: 2 |
| // CHECK-NEXT: i=1 j=2 |
| // CHECK-NEXT: [A] iterator dtor |
| // CHECK-NEXT: [A] iterator advance: 0 += 2 |
| // CHECK-NEXT: [A] iterator move assign |
| // CHECK-NEXT: [A] iterator deref: 2 |
| // CHECK-NEXT: [B] iterator deref: 2 |
| // CHECK-NEXT: i=2 j=2 |
| // CHECK-NEXT: [A] iterator dtor |
| // CHECK-NEXT: [B] iterator dtor |
| // CHECK-NEXT: [B] iterator dtor |
| // CHECK-NEXT: [B] iterator dtor |
| // CHECK-NEXT: [A] iterator dtor |
| // CHECK-NEXT: [A] iterator dtor |
| // CHECK-NEXT: done |
| // CHECK-NEXT: [B] iterator dtor |
| // CHECK-NEXT: [A] iterator dtor |
| // CHECK-NEXT: [B] dtor |
| // CHECK-NEXT: [A] dtor |