[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / clang / test / SemaCXX / for-range-examples.cpp
blob1bbf042f0aa6c22a46a6efe7fcba2d29b9f7b470
1 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
3 namespace value_range_detail {
4 template<typename T>
5 class value_range_iter {
6 T t;
7 public:
8 value_range_iter(const T &t) : t(t) {}
9 T operator*() const { return t; }
10 bool operator!=(const value_range_iter &o) const { return t != o.t; }
11 value_range_iter &operator++() { ++t; return *this; }
14 template<typename T>
15 struct value_range {
16 value_range(const T &a, const T &b) : begin_(a), end_(b) {}
17 value_range_iter<T> begin_, end_;
20 template<typename T>
21 value_range_iter<T> begin(const value_range<T> &r) { return r.begin_; }
22 template<typename T>
23 value_range_iter<T> end(const value_range<T> &r) { return r.end_; }
26 struct end_t {};
28 template<typename T>
29 class value_range_step_iter {
30 T it, step;
31 public:
32 value_range_step_iter(const T &it, const T &step) : it(it), step(step) {}
33 T operator*() const { return it; }
34 bool operator!=(value_range_step_iter end) const { return it != end.it; }
35 value_range_step_iter &operator++() { it += step; return *this; }
38 template<typename T>
39 class value_range_step {
40 T it, step, end_;
41 public:
42 value_range_step(const T &it, const T &end, const T &step) :
43 it(it), end_(end), step(step) {}
44 typedef value_range_step_iter<T> iterator;
45 iterator begin() const { return iterator(it, step); }
46 iterator end() const { return iterator(end_, step); }
50 template<typename T>
51 value_range_detail::value_range<T> range(const T &a, const T &b) { return value_range_detail::value_range<T>(a, b); }
53 template<typename T>
54 value_range_detail::value_range_step<T> range(const T &a, const T &b, const T &step) { return value_range_detail::value_range_step<T>(a, b, step); }
57 namespace map_range {
58 template<typename T>
59 class vector {
60 T storage[100];
61 decltype(sizeof(char)) size;
62 public:
63 vector() : size() {}
64 void push_back(T t) { storage[size++] = t; }
65 T *begin() { return storage; }
66 T *end() { return storage + size; }
69 template<typename T> struct tuple_elem {
70 T t;
71 tuple_elem() {}
72 tuple_elem(T t) : t(t) {}
74 template<typename... A>
75 struct tuple : tuple_elem<A>... {
76 tuple() : tuple_elem<A>()... {}
77 tuple(A... a) : tuple_elem<A>(a)... {}
78 template<typename B> B &get() { return tuple_elem<B>::t; }
81 template<typename F, typename I>
82 class map_iter {
83 F f;
84 I i;
85 public:
86 map_iter(F f, I i) : f(f), i(i) {}
87 auto operator*() const -> decltype(f(*i)) { return f(*i); }
88 bool operator!=(const map_iter &o) const { return i != o.i; }
89 map_iter &operator++() { ++i; return *this; }
92 template<typename T>
93 struct iter_pair {
94 T begin_, end_;
95 iter_pair(T begin, T end) : begin_(begin), end_(end) {}
97 template<typename T> T begin(iter_pair<T> p) { return p.begin_; }
98 template<typename T> T end(iter_pair<T> p) { return p.end_; }
100 template<typename...> class mem_fun_impl;
101 template<typename R, typename T, typename... A>
102 class mem_fun_impl<R (T::*)(A...)> {
103 typedef R (T::*F)(A...);
104 F f;
105 public:
106 mem_fun_impl(F f) : f(f) {}
107 R operator()(T &t, A &&...a) const { return (t.*f)(static_cast<A&&>(a)...); }
109 template<typename F> mem_fun_impl<F> mem_fun(F f) { return mem_fun_impl<F>(f); }
111 template<typename F, typename T>
112 auto map(const F &f, T &t) -> iter_pair<map_iter<F, decltype(t.begin())>> {
113 typedef map_iter<F, decltype(t.begin())> iter;
114 return iter_pair<iter>(iter(f, t.begin()), iter(f, t.end()));
118 #define assert(b) if (!(b)) { return 1; }
119 int main() {
120 int total = 0;
122 for (auto n : range(1, 5)) {
123 total += n;
125 assert(total == 10);
127 for (auto n : range(10, 100, 10)) {
128 total += n;
130 assert(total == 460);
132 map_range::vector<char> chars;
133 chars.push_back('a');
134 chars.push_back('b');
135 chars.push_back('c');
136 for (char c : chars) {
137 ++total;
139 assert(total == 463);
141 typedef map_range::tuple<int, double> T;
142 map_range::vector<T> pairs;
143 pairs.push_back(T(42, 12.9));
144 pairs.push_back(T(6, 4.2));
145 pairs.push_back(T(9, 1.1));
146 for (auto a : map(map_range::mem_fun(&T::get<int>), pairs)) {
147 total += a;
149 assert(total == 500);
152 // PR11793
153 namespace test2 {
154 class A {
155 int xs[10]; // expected-note {{implicitly declared private here}}
157 void test(A &a) {
158 for (int x : a.xs) { } // expected-error {{'xs' is a private member of 'test2::A'}}
162 namespace test3 {
163 // Make sure this doesn't crash
164 struct A {};
165 struct B { ~B(); operator bool(); };
166 struct C { B operator!=(const C&); C& operator++(); int operator*(); };
167 C begin(const A&);
168 C end(const A&);
169 template<typename T> void f() { for (auto a : A()) {} }
170 void g() { f<int>(); }
173 namespace test4 {
174 void f() {
175 int y;
177 // Make sure these don't crash. Better diagnostics would be nice.
178 for (: {1, 2, 3}) {} // expected-error {{expected expression}} expected-error {{expected ';'}}
179 for (1 : {1, 2, 3}) {} // expected-error {{must declare a variable}}
180 for (+x : {1, 2, 3}) {} // expected-error {{undeclared identifier}} expected-error {{expected ';'}}
181 for (+y : {1, 2, 3}) {} // expected-error {{must declare a variable}}
185 namespace test5 {
186 // Test error-recovery.
187 void f() {
188 for (auto x : undeclared_identifier) // expected-error {{undeclared identifier}}
189 for (auto y : x->foo)
190 y->bar();
191 for (auto x : 123) // expected-error {{no viable 'begin'}}
192 x->foo();
196 namespace test6 {
197 void foo(int arr[]) { // expected-note {{declared here}}
198 for (auto i : arr) { }
199 // expected-error@-1 {{cannot build range expression with array function parameter 'arr' since parameter with array type 'int[]' is treated as pointer type 'int *'}}
202 struct vector {
203 int *begin() { return 0; }
204 int *end() { return 0; }
207 void foo(vector arr[]) { // expected-note {{declared here}}
208 // Don't suggest to dereference arr.
209 for (auto i : arr) { }
210 // expected-error@-1 {{cannot build range expression with array function parameter 'arr' since parameter with array type 'vector[]' is treated as pointer type 'vector *'}}
214 namespace test7 {
215 void f() {
216 int arr[5], b;
217 for (a : arr) {} // expected-error {{requires type for loop variable}}
218 // FIXME: Give a different error in this case?
219 for (b : arr) {} // expected-error {{requires type for loop variable}}
220 for (arr : arr) {} // expected-error {{requires type for loop variable}}
221 for (c alignas(8) : arr) { // expected-error {{requires type for loop variable}}
222 static_assert(alignof(c) == 8, ""); // expected-warning {{extension}}
224 for (d alignas(1) : arr) {} // expected-error {{requested alignment is less than minimum}} expected-error {{requires type for loop variable}}
225 for (e [[deprecated]] : arr) { e = 0; } // expected-warning {{deprecated}} expected-note {{here}} expected-error {{requires type for loop variable}}
229 namespace pr18587 {
230 class Arg {};
231 struct Cont {
232 int *begin();
233 int *end();
235 void AddAllArgs(Cont &x) {
236 for (auto Arg: x) {
241 namespace PR32933 {
242 // https://bugs.llvm.org/show_bug.cgi?id=32933
243 void foo ()
245 int b = 1, a[b];
246 a[0] = 0;
247 [&] { for (int c : a) 0; } (); // expected-warning {{expression result unused}}
251 int foo(int b) {
252 int varr[b][(b+=8)];
253 b = 15;
254 [&] {
255 int i = 0;
256 for (auto &c : varr)
258 c[0] = ++b;
260 [&] {
261 int i = 0;
262 for (auto &c : varr) {
263 int j = 0;
264 for(auto &c2 : c) {
265 ++j;
267 ++i;
269 }();
270 }();
271 return b;