1// Test for range-based for loop with templates
2// and begin/end as member functions
3
4// { dg-do run { target c++11 } }
5
6/* Preliminary declarations */
7namespace pre
8{
9  struct iterator
10  {
11    int x;
12    explicit iterator (int v) :x(v) {}
13    iterator &operator ++() { ++x; return *this; }
14    int operator *() { return x; }
15    bool operator != (const iterator &o) { return x != o.x; }
16  };
17
18  struct container
19  {
20    int min, max;
21    container(int a, int b) :min(a), max(b) {}
22    iterator begin() const
23    {
24        return iterator(min);
25    }
26    iterator end() const
27    {
28        return iterator(max);
29    }
30
31  };
32
33} //namespace pre
34
35using pre::container;
36extern "C" void abort(void);
37
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. */
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. */
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. */
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. */
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. */
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
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