1f4a2713aSLionel Sambuc // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
2f4a2713aSLionel Sambuc
3f4a2713aSLionel Sambuc namespace value_range_detail {
4f4a2713aSLionel Sambuc template<typename T>
5f4a2713aSLionel Sambuc class value_range_iter {
6f4a2713aSLionel Sambuc T t;
7f4a2713aSLionel Sambuc public:
value_range_iter(const T & t)8f4a2713aSLionel Sambuc value_range_iter(const T &t) : t(t) {}
operator *() const9f4a2713aSLionel Sambuc T operator*() const { return t; }
operator !=(const value_range_iter & o) const10f4a2713aSLionel Sambuc bool operator!=(const value_range_iter &o) const { return t != o.t; }
operator ++()11f4a2713aSLionel Sambuc value_range_iter &operator++() { ++t; return *this; }
12f4a2713aSLionel Sambuc };
13f4a2713aSLionel Sambuc
14f4a2713aSLionel Sambuc template<typename T>
15f4a2713aSLionel Sambuc struct value_range {
value_rangevalue_range_detail::value_range16f4a2713aSLionel Sambuc value_range(const T &a, const T &b) : begin_(a), end_(b) {}
17f4a2713aSLionel Sambuc value_range_iter<T> begin_, end_;
18f4a2713aSLionel Sambuc };
19f4a2713aSLionel Sambuc
20f4a2713aSLionel Sambuc template<typename T>
begin(const value_range<T> & r)21f4a2713aSLionel Sambuc value_range_iter<T> begin(const value_range<T> &r) { return r.begin_; }
22f4a2713aSLionel Sambuc template<typename T>
end(const value_range<T> & r)23f4a2713aSLionel Sambuc value_range_iter<T> end(const value_range<T> &r) { return r.end_; }
24f4a2713aSLionel Sambuc
25f4a2713aSLionel Sambuc
26f4a2713aSLionel Sambuc struct end_t {};
27f4a2713aSLionel Sambuc
28f4a2713aSLionel Sambuc template<typename T>
29f4a2713aSLionel Sambuc class value_range_step_iter {
30f4a2713aSLionel Sambuc T it, step;
31f4a2713aSLionel Sambuc public:
value_range_step_iter(const T & it,const T & step)32f4a2713aSLionel Sambuc value_range_step_iter(const T &it, const T &step) : it(it), step(step) {}
operator *() const33f4a2713aSLionel Sambuc T operator*() const { return it; }
operator !=(value_range_step_iter end) const34f4a2713aSLionel Sambuc bool operator!=(value_range_step_iter end) const { return it != end.it; }
operator ++()35f4a2713aSLionel Sambuc value_range_step_iter &operator++() { it += step; return *this; }
36f4a2713aSLionel Sambuc };
37f4a2713aSLionel Sambuc
38f4a2713aSLionel Sambuc template<typename T>
39f4a2713aSLionel Sambuc class value_range_step {
40f4a2713aSLionel Sambuc T it, step, end_;
41f4a2713aSLionel Sambuc public:
value_range_step(const T & it,const T & end,const T & step)42f4a2713aSLionel Sambuc value_range_step(const T &it, const T &end, const T &step) :
43f4a2713aSLionel Sambuc it(it), end_(end), step(step) {}
44f4a2713aSLionel Sambuc typedef value_range_step_iter<T> iterator;
begin() const45f4a2713aSLionel Sambuc iterator begin() const { return iterator(it, step); }
end() const46f4a2713aSLionel Sambuc iterator end() const { return iterator(end_, step); }
47f4a2713aSLionel Sambuc };
48f4a2713aSLionel Sambuc }
49f4a2713aSLionel Sambuc
50f4a2713aSLionel Sambuc template<typename T>
range(const T & a,const T & b)51f4a2713aSLionel Sambuc value_range_detail::value_range<T> range(const T &a, const T &b) { return value_range_detail::value_range<T>(a, b); }
52f4a2713aSLionel Sambuc
53f4a2713aSLionel Sambuc template<typename T>
range(const T & a,const T & b,const T & step)54f4a2713aSLionel Sambuc 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); }
55f4a2713aSLionel Sambuc
56f4a2713aSLionel Sambuc
57f4a2713aSLionel Sambuc namespace map_range {
58f4a2713aSLionel Sambuc template<typename T>
59f4a2713aSLionel Sambuc class vector {
60f4a2713aSLionel Sambuc T storage[100];
61f4a2713aSLionel Sambuc decltype(sizeof(char)) size;
62f4a2713aSLionel Sambuc public:
vector()63f4a2713aSLionel Sambuc vector() : size() {}
push_back(T t)64f4a2713aSLionel Sambuc void push_back(T t) { storage[size++] = t; }
begin()65f4a2713aSLionel Sambuc T *begin() { return storage; }
end()66f4a2713aSLionel Sambuc T *end() { return storage + size; }
67f4a2713aSLionel Sambuc };
68f4a2713aSLionel Sambuc
69f4a2713aSLionel Sambuc template<typename T> struct tuple_elem {
70f4a2713aSLionel Sambuc T t;
tuple_elemmap_range::tuple_elem71f4a2713aSLionel Sambuc tuple_elem() {}
tuple_elemmap_range::tuple_elem72f4a2713aSLionel Sambuc tuple_elem(T t) : t(t) {}
73f4a2713aSLionel Sambuc };
74f4a2713aSLionel Sambuc template<typename... A>
75f4a2713aSLionel Sambuc struct tuple : tuple_elem<A>... {
tuplemap_range::tuple76f4a2713aSLionel Sambuc tuple() : tuple_elem<A>()... {}
tuplemap_range::tuple77f4a2713aSLionel Sambuc tuple(A... a) : tuple_elem<A>(a)... {}
getmap_range::tuple78f4a2713aSLionel Sambuc template<typename B> B &get() { return tuple_elem<B>::t; }
79f4a2713aSLionel Sambuc };
80f4a2713aSLionel Sambuc
81f4a2713aSLionel Sambuc template<typename F, typename I>
82f4a2713aSLionel Sambuc class map_iter {
83f4a2713aSLionel Sambuc F f;
84f4a2713aSLionel Sambuc I i;
85f4a2713aSLionel Sambuc public:
map_iter(F f,I i)86f4a2713aSLionel Sambuc map_iter(F f, I i) : f(f), i(i) {}
operator *() const87f4a2713aSLionel Sambuc auto operator*() const -> decltype(f(*i)) { return f(*i); }
operator !=(const map_iter & o) const88f4a2713aSLionel Sambuc bool operator!=(const map_iter &o) const { return i != o.i; }
operator ++()89f4a2713aSLionel Sambuc map_iter &operator++() { ++i; return *this; }
90f4a2713aSLionel Sambuc };
91f4a2713aSLionel Sambuc
92f4a2713aSLionel Sambuc template<typename T>
93f4a2713aSLionel Sambuc struct iter_pair {
94f4a2713aSLionel Sambuc T begin_, end_;
iter_pairmap_range::iter_pair95f4a2713aSLionel Sambuc iter_pair(T begin, T end) : begin_(begin), end_(end) {}
96f4a2713aSLionel Sambuc };
begin(iter_pair<T> p)97f4a2713aSLionel Sambuc template<typename T> T begin(iter_pair<T> p) { return p.begin_; }
end(iter_pair<T> p)98f4a2713aSLionel Sambuc template<typename T> T end(iter_pair<T> p) { return p.end_; }
99f4a2713aSLionel Sambuc
100f4a2713aSLionel Sambuc template<typename...> class mem_fun_impl;
101f4a2713aSLionel Sambuc template<typename R, typename T, typename... A>
102f4a2713aSLionel Sambuc class mem_fun_impl<R (T::*)(A...)> {
103f4a2713aSLionel Sambuc typedef R (T::*F)(A...);
104f4a2713aSLionel Sambuc F f;
105f4a2713aSLionel Sambuc public:
mem_fun_impl(F f)106f4a2713aSLionel Sambuc mem_fun_impl(F f) : f(f) {}
operator ()(T & t,A &&...a) const107f4a2713aSLionel Sambuc R operator()(T &t, A &&...a) const { return (t.*f)(static_cast<A&&>(a)...); }
108f4a2713aSLionel Sambuc };
mem_fun(F f)109f4a2713aSLionel Sambuc template<typename F> mem_fun_impl<F> mem_fun(F f) { return mem_fun_impl<F>(f); }
110f4a2713aSLionel Sambuc
111f4a2713aSLionel Sambuc template<typename F, typename T>
map(const F & f,T & t)112f4a2713aSLionel Sambuc auto map(const F &f, T &t) -> iter_pair<map_iter<F, decltype(t.begin())>> {
113f4a2713aSLionel Sambuc typedef map_iter<F, decltype(t.begin())> iter;
114f4a2713aSLionel Sambuc return iter_pair<iter>(iter(f, t.begin()), iter(f, t.end()));
115f4a2713aSLionel Sambuc }
116f4a2713aSLionel Sambuc }
117f4a2713aSLionel Sambuc
118f4a2713aSLionel Sambuc #define assert(b) if (!(b)) { return 1; }
main()119f4a2713aSLionel Sambuc int main() {
120f4a2713aSLionel Sambuc int total = 0;
121f4a2713aSLionel Sambuc
122f4a2713aSLionel Sambuc for (auto n : range(1, 5)) {
123f4a2713aSLionel Sambuc total += n;
124f4a2713aSLionel Sambuc }
125f4a2713aSLionel Sambuc assert(total == 10);
126f4a2713aSLionel Sambuc
127f4a2713aSLionel Sambuc for (auto n : range(10, 100, 10)) {
128f4a2713aSLionel Sambuc total += n;
129f4a2713aSLionel Sambuc }
130f4a2713aSLionel Sambuc assert(total == 460);
131f4a2713aSLionel Sambuc
132f4a2713aSLionel Sambuc map_range::vector<char> chars;
133f4a2713aSLionel Sambuc chars.push_back('a');
134f4a2713aSLionel Sambuc chars.push_back('b');
135f4a2713aSLionel Sambuc chars.push_back('c');
136f4a2713aSLionel Sambuc for (char c : chars) {
137f4a2713aSLionel Sambuc ++total;
138f4a2713aSLionel Sambuc }
139f4a2713aSLionel Sambuc assert(total == 463);
140f4a2713aSLionel Sambuc
141f4a2713aSLionel Sambuc typedef map_range::tuple<int, double> T;
142f4a2713aSLionel Sambuc map_range::vector<T> pairs;
143f4a2713aSLionel Sambuc pairs.push_back(T(42, 12.9));
144f4a2713aSLionel Sambuc pairs.push_back(T(6, 4.2));
145f4a2713aSLionel Sambuc pairs.push_back(T(9, 1.1));
146f4a2713aSLionel Sambuc for (auto a : map(map_range::mem_fun(&T::get<int>), pairs)) {
147f4a2713aSLionel Sambuc total += a;
148f4a2713aSLionel Sambuc }
149f4a2713aSLionel Sambuc assert(total == 500);
150f4a2713aSLionel Sambuc }
151f4a2713aSLionel Sambuc
152f4a2713aSLionel Sambuc // PR11793
153f4a2713aSLionel Sambuc namespace test2 {
154f4a2713aSLionel Sambuc class A {
155f4a2713aSLionel Sambuc int xs[10]; // expected-note {{implicitly declared private here}}
156f4a2713aSLionel Sambuc };
test(A & a)157f4a2713aSLionel Sambuc void test(A &a) {
158f4a2713aSLionel Sambuc for (int x : a.xs) { } // expected-error {{'xs' is a private member of 'test2::A'}}
159f4a2713aSLionel Sambuc }
160f4a2713aSLionel Sambuc }
161f4a2713aSLionel Sambuc
162f4a2713aSLionel Sambuc namespace test3 {
163f4a2713aSLionel Sambuc // Make sure this doesn't crash
164f4a2713aSLionel Sambuc struct A {};
165f4a2713aSLionel Sambuc struct B { ~B(); operator bool(); };
166f4a2713aSLionel Sambuc struct C { B operator!=(const C&); C& operator++(); int operator*(); };
167f4a2713aSLionel Sambuc C begin(const A&);
168f4a2713aSLionel Sambuc C end(const A&);
f()169f4a2713aSLionel Sambuc template<typename T> void f() { for (auto a : A()) {} }
g()170f4a2713aSLionel Sambuc void g() { f<int>(); }
171f4a2713aSLionel Sambuc }
172f4a2713aSLionel Sambuc
173f4a2713aSLionel Sambuc namespace test4 {
f()174f4a2713aSLionel Sambuc void f() {
175f4a2713aSLionel Sambuc int y;
176f4a2713aSLionel Sambuc
177f4a2713aSLionel Sambuc // Make sure these don't crash. Better diagnostics would be nice.
178f4a2713aSLionel Sambuc for (: {1, 2, 3}) {} // expected-error {{expected expression}} expected-error {{expected ';'}}
179*0a6a1f1dSLionel Sambuc for (1 : {1, 2, 3}) {} // expected-error {{must declare a variable}} expected-warning {{result unused}}
180*0a6a1f1dSLionel Sambuc for (+x : {1, 2, 3}) {} // expected-error {{undeclared identifier}} expected-error {{expected ';'}}
181*0a6a1f1dSLionel Sambuc for (+y : {1, 2, 3}) {} // expected-error {{must declare a variable}} expected-warning {{result unused}}
182f4a2713aSLionel Sambuc }
183f4a2713aSLionel Sambuc }
184f4a2713aSLionel Sambuc
185f4a2713aSLionel Sambuc namespace test5 {
186f4a2713aSLionel Sambuc // Test error-recovery.
f()187f4a2713aSLionel Sambuc void f() {
188f4a2713aSLionel Sambuc for (auto x : undeclared_identifier) // expected-error {{undeclared identifier}}
189f4a2713aSLionel Sambuc for (auto y : x->foo)
190f4a2713aSLionel Sambuc y->bar();
191f4a2713aSLionel Sambuc for (auto x : 123) // expected-error {{no viable 'begin'}}
192f4a2713aSLionel Sambuc x->foo();
193f4a2713aSLionel Sambuc }
194f4a2713aSLionel Sambuc }
195f4a2713aSLionel Sambuc
196f4a2713aSLionel Sambuc namespace test6 {
foo(int arr[])197f4a2713aSLionel Sambuc void foo(int arr[]) { // expected-note {{declared here}}
198f4a2713aSLionel Sambuc for (auto i : arr) { }
199f4a2713aSLionel Sambuc // expected-error@-1 {{cannot build range expression with array function parameter 'arr' since parameter with array type 'int []' is treated as pointer type 'int *'}}
200f4a2713aSLionel Sambuc }
201f4a2713aSLionel Sambuc
202f4a2713aSLionel Sambuc struct vector {
begintest6::vector203f4a2713aSLionel Sambuc int *begin() { return 0; }
endtest6::vector204f4a2713aSLionel Sambuc int *end() { return 0; }
205f4a2713aSLionel Sambuc };
206f4a2713aSLionel Sambuc
foo(vector arr[])207f4a2713aSLionel Sambuc void foo(vector arr[]) { // expected-note {{declared here}}
208f4a2713aSLionel Sambuc // Don't suggest to dereference arr.
209f4a2713aSLionel Sambuc for (auto i : arr) { }
210f4a2713aSLionel Sambuc // expected-error@-1 {{cannot build range expression with array function parameter 'arr' since parameter with array type 'test6::vector []' is treated as pointer type 'test6::vector *'}}
211f4a2713aSLionel Sambuc }
212f4a2713aSLionel Sambuc }
213*0a6a1f1dSLionel Sambuc
214*0a6a1f1dSLionel Sambuc namespace test7 {
f()215*0a6a1f1dSLionel Sambuc void f() {
216*0a6a1f1dSLionel Sambuc int arr[5], b;
217*0a6a1f1dSLionel Sambuc for (a : arr) {} // expected-error {{requires type for loop variable}}
218*0a6a1f1dSLionel Sambuc // FIXME: Give a different error in this case?
219*0a6a1f1dSLionel Sambuc for (b : arr) {} // expected-error {{requires type for loop variable}}
220*0a6a1f1dSLionel Sambuc for (arr : arr) {} // expected-error {{requires type for loop variable}}
221*0a6a1f1dSLionel Sambuc for (c alignas(8) : arr) { // expected-error {{requires type for loop variable}}
222*0a6a1f1dSLionel Sambuc static_assert(alignof(c) == 8, ""); // expected-warning {{extension}}
223*0a6a1f1dSLionel Sambuc }
224*0a6a1f1dSLionel Sambuc // FIXME: The fix-it hint here is not sufficient to fix the error.
225*0a6a1f1dSLionel Sambuc // We fail to diagnose that d is underaligned for its type, because
226*0a6a1f1dSLionel Sambuc // we check the alignment attribute before we perform the auto
227*0a6a1f1dSLionel Sambuc // deduction.
228*0a6a1f1dSLionel Sambuc for (d alignas(1) : arr) {} // expected-error {{requires type for loop variable}}
229*0a6a1f1dSLionel Sambuc for (e [[deprecated]] : arr) { e = 0; } // expected-warning {{deprecated}} expected-note {{here}} expected-error {{requires type for loop variable}}
230*0a6a1f1dSLionel Sambuc }
231*0a6a1f1dSLionel Sambuc }
232*0a6a1f1dSLionel Sambuc
233*0a6a1f1dSLionel Sambuc namespace pr18587 {
234*0a6a1f1dSLionel Sambuc class Arg {};
235*0a6a1f1dSLionel Sambuc struct Cont {
236*0a6a1f1dSLionel Sambuc int *begin();
237*0a6a1f1dSLionel Sambuc int *end();
238*0a6a1f1dSLionel Sambuc };
AddAllArgs(Cont & x)239*0a6a1f1dSLionel Sambuc void AddAllArgs(Cont &x) {
240*0a6a1f1dSLionel Sambuc for (auto Arg: x) {
241*0a6a1f1dSLionel Sambuc }
242*0a6a1f1dSLionel Sambuc }
243*0a6a1f1dSLionel Sambuc }
244