for-range-examples.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
  2. namespace value_range_detail {
  3. template<typename T>
  4. class value_range_iter {
  5. T t;
  6. public:
  7. value_range_iter(const T &t) : t(t) {}
  8. T operator*() const { return t; }
  9. bool operator!=(const value_range_iter &o) const { return t != o.t; }
  10. value_range_iter &operator++() { ++t; return *this; }
  11. };
  12. template<typename T>
  13. struct value_range {
  14. value_range(const T &a, const T &b) : begin_(a), end_(b) {}
  15. value_range_iter<T> begin_, end_;
  16. };
  17. template<typename T>
  18. value_range_iter<T> begin(const value_range<T> &r) { return r.begin_; }
  19. template<typename T>
  20. value_range_iter<T> end(const value_range<T> &r) { return r.end_; }
  21. struct end_t {};
  22. template<typename T>
  23. class value_range_step_iter {
  24. T it, step;
  25. public:
  26. value_range_step_iter(const T &it, const T &step) : it(it), step(step) {}
  27. T operator*() const { return it; }
  28. bool operator!=(value_range_step_iter end) const { return it != end.it; }
  29. value_range_step_iter &operator++() { it += step; return *this; }
  30. };
  31. template<typename T>
  32. class value_range_step {
  33. T it, step, end_;
  34. public:
  35. value_range_step(const T &it, const T &end, const T &step) :
  36. it(it), end_(end), step(step) {}
  37. typedef value_range_step_iter<T> iterator;
  38. iterator begin() const { return iterator(it, step); }
  39. iterator end() const { return iterator(end_, step); }
  40. };
  41. }
  42. template<typename T>
  43. value_range_detail::value_range<T> range(const T &a, const T &b) { return value_range_detail::value_range<T>(a, b); }
  44. template<typename T>
  45. 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); }
  46. namespace map_range {
  47. template<typename T>
  48. class vector {
  49. T storage[100];
  50. decltype(sizeof(char)) size;
  51. public:
  52. vector() : size() {}
  53. void push_back(T t) { storage[size++] = t; }
  54. T *begin() { return storage; }
  55. T *end() { return storage + size; }
  56. };
  57. template<typename T> struct tuple_elem {
  58. T t;
  59. tuple_elem() {}
  60. tuple_elem(T t) : t(t) {}
  61. };
  62. template<typename... A>
  63. struct tuple : tuple_elem<A>... {
  64. tuple() : tuple_elem<A>()... {}
  65. tuple(A... a) : tuple_elem<A>(a)... {}
  66. template<typename B> B &get() { return tuple_elem<B>::t; }
  67. };
  68. template<typename F, typename I>
  69. class map_iter {
  70. F f;
  71. I i;
  72. public:
  73. map_iter(F f, I i) : f(f), i(i) {}
  74. auto operator*() const -> decltype(f(*i)) { return f(*i); }
  75. bool operator!=(const map_iter &o) const { return i != o.i; }
  76. map_iter &operator++() { ++i; return *this; }
  77. };
  78. template<typename T>
  79. struct iter_pair {
  80. T begin_, end_;
  81. iter_pair(T begin, T end) : begin_(begin), end_(end) {}
  82. };
  83. template<typename T> T begin(iter_pair<T> p) { return p.begin_; }
  84. template<typename T> T end(iter_pair<T> p) { return p.end_; }
  85. template<typename...> class mem_fun_impl;
  86. template<typename R, typename T, typename... A>
  87. class mem_fun_impl<R (T::*)(A...)> {
  88. typedef R (T::*F)(A...);
  89. F f;
  90. public:
  91. mem_fun_impl(F f) : f(f) {}
  92. R operator()(T &t, A &&...a) const { return (t.*f)(static_cast<A&&>(a)...); }
  93. };
  94. template<typename F> mem_fun_impl<F> mem_fun(F f) { return mem_fun_impl<F>(f); }
  95. template<typename F, typename T>
  96. auto map(const F &f, T &t) -> iter_pair<map_iter<F, decltype(t.begin())>> {
  97. typedef map_iter<F, decltype(t.begin())> iter;
  98. return iter_pair<iter>(iter(f, t.begin()), iter(f, t.end()));
  99. }
  100. }
  101. #define assert(b) if (!b) { return 1; }
  102. int main() {
  103. int total = 0;
  104. for (auto n : range(1, 5)) {
  105. total += n;
  106. }
  107. assert((total == 10));
  108. for (auto n : range(10, 100, 10)) {
  109. total += n;
  110. }
  111. assert((total == 460));
  112. map_range::vector<char> chars;
  113. chars.push_back('a');
  114. chars.push_back('b');
  115. chars.push_back('c');
  116. for (char c : chars) {
  117. ++total;
  118. }
  119. assert((total == 463));
  120. typedef map_range::tuple<int, double> T;
  121. map_range::vector<T> pairs;
  122. pairs.push_back(T(42, 12.9));
  123. pairs.push_back(T(6, 4.2));
  124. pairs.push_back(T(9, 1.1));
  125. for (auto a : map(map_range::mem_fun(&T::get<int>), pairs)) {
  126. total += a;
  127. }
  128. assert((total == 500));
  129. }
  130. // PR11793
  131. namespace test2 {
  132. class A {
  133. int xs[10]; // expected-note {{implicitly declared private here}}
  134. };
  135. void test(A &a) {
  136. for (int x : a.xs) { } // expected-error {{'xs' is a private member of 'test2::A'}}
  137. }
  138. }
  139. namespace test3 {
  140. // Make sure this doesn't crash
  141. struct A {};
  142. struct B { ~B(); operator bool(); };
  143. struct C { B operator!=(const C&); C& operator++(); int operator*(); };
  144. C begin(const A&);
  145. C end(const A&);
  146. template<typename T> void f() { for (auto a : A()) {} }
  147. void g() { f<int>(); }
  148. }
  149. namespace test4 {
  150. void f() {
  151. int y;
  152. // Make sure these don't crash. Better diagnostics would be nice.
  153. for (: {1, 2, 3}) {} // expected-error {{expected expression}} expected-error {{expected ';'}}
  154. for (x : {1, 2, 3}) {} // expected-error {{undeclared identifier}} expected-error {{expected ';'}}
  155. for (y : {1, 2, 3}) {} // expected-error {{must declare a variable}} expected-warning {{result unused}}
  156. }
  157. }