1 // Test for range-based for loop with templates 2 3 // { dg-do run { target c++11 } } 4 5 /* Preliminary declarations */ 6 namespace pre 7 { 8 struct iterator 9 { 10 int x; iteratoriterator11 iterator (int v) :x(v) {} 12 iterator &operator ++() { ++x; return *this; } 13 int operator *() { return x; } 14 bool operator != (const iterator &o) { return x != o.x; } 15 }; 16 17 struct container 18 { 19 int min, max; containercontainer20 container(int a, int b) :min(a), max(b) {} 21 }; 22 begin(const container & c)23 iterator begin(const container &c) 24 { 25 return iterator(c.min); 26 } 27 end(const container & c)28 iterator end(const container &c) 29 { 30 return iterator(c.max); 31 } 32 33 } //namespace pre 34 35 using pre::container; 36 extern "C" void abort(void); 37 run_me_just_once()38container run_me_just_once() 39 { 40 static bool run = false; 41 if (run) 42 abort(); 43 run = true; 44 return container(1,2); 45 } 46 47 /* Template with dependent expression. */ test1(const T & r)48template<typename T> int test1(const T &r) 49 { 50 int t = 0; 51 for (int i : r) 52 t += i; 53 return t; 54 } 55 56 /* Template with non-dependent expression and dependent declaration. */ test2(const container & r)57template<typename T> int test2(const container &r) 58 { 59 int t = 0; 60 for (T i : r) 61 t += i; 62 return t; 63 } 64 65 /* Template with non-dependent expression (array) and dependent declaration. */ test2(const int (& r)[4])66template<typename T> int test2(const int (&r)[4]) 67 { 68 int t = 0; 69 for (T i : r) 70 t += i; 71 return t; 72 } 73 74 /* Template with non-dependent expression and auto declaration. */ test3(const container & r)75template<typename T> int test3(const container &r) 76 { 77 int t = 0; 78 for (auto i : r) 79 t += i; 80 return t; 81 } 82 83 /* Template with non-dependent expression (array) and auto declaration. */ test3(const int (& r)[4])84template<typename T> int test3(const int (&r)[4]) 85 { 86 int t = 0; 87 for (auto i : r) 88 t += i; 89 return t; 90 } 91 main()92int main () 93 { 94 container c(1,5); 95 int a[4] = {5,6,7,8}; 96 97 for (auto x : run_me_just_once()) 98 ; 99 100 if (test1 (c) != 10) 101 abort(); 102 if (test1 (a) != 26) 103 abort(); 104 105 if (test2<int> (c) != 10) 106 abort(); 107 if (test2<int> (a) != 26) 108 abort(); 109 110 if (test3<int> (c) != 10) 111 abort(); 112 if (test3<int> (a) != 26) 113 abort(); 114 return 0; 115 } 116