// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 

namespace value_range_detail {
  template<typename T>
  class value_range_iter {
    T t;
  public:
    value_range_iter(const T &t) : t(t) {}
    T operator*() const { return t; }
    bool operator!=(const value_range_iter &o) const { return t != o.t; }
    value_range_iter &operator++() { ++t; return *this; }
  };

  template<typename T>
  struct value_range {
    value_range(const T &a, const T &b) : begin_(a), end_(b) {}
    value_range_iter<T> begin_, end_;
  };

  template<typename T>
  value_range_iter<T> begin(const value_range<T> &r) { return r.begin_; }
  template<typename T>
  value_range_iter<T> end(const value_range<T> &r) { return r.end_; }


  struct end_t {};

  template<typename T>
  class value_range_step_iter {
    T it, step;
  public:
    value_range_step_iter(const T &it, const T &step) : it(it), step(step) {}
    T operator*() const { return it; }
    bool operator!=(value_range_step_iter end) const { return it != end.it; }
    value_range_step_iter &operator++() { it += step; return *this; }
  };

  template<typename T>
  class value_range_step {
    T it, step, end_;
  public:
    value_range_step(const T &it, const T &end, const T &step) :
      it(it), end_(end), step(step) {}
    typedef value_range_step_iter<T> iterator;
    iterator begin() const { return iterator(it, step); }
    iterator end() const { return iterator(end_, step); }
  };
}

template<typename T>
value_range_detail::value_range<T> range(const T &a, const T &b) { return value_range_detail::value_range<T>(a, b); }

template<typename T>
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); }


namespace map_range {
  template<typename T>
  class vector {
    T storage[100];
    decltype(sizeof(char)) size;
  public:
    vector() : size() {}
    void push_back(T t) { storage[size++] = t; }
    T *begin() { return storage; }
    T *end() { return storage + size; }
  };

  template<typename T> struct tuple_elem {
    T t;
    tuple_elem() {}
    tuple_elem(T t) : t(t) {}
  };
  template<typename... A>
  struct tuple : tuple_elem<A>... {
    tuple() : tuple_elem<A>()... {}
    tuple(A... a) : tuple_elem<A>(a)... {}
    template<typename B> B &get() { return tuple_elem<B>::t; }
  };

  template<typename F, typename I>
  class map_iter {
    F f;
    I i;
  public:
    map_iter(F f, I i) : f(f), i(i) {}
    auto operator*() const -> decltype(f(*i)) { return f(*i); }
    bool operator!=(const map_iter &o) const { return i != o.i; }
    map_iter &operator++() { ++i; return *this; }
  };

  template<typename T>
  struct iter_pair {
    T begin_, end_;
    iter_pair(T begin, T end) : begin_(begin), end_(end) {}
  };
  template<typename T> T begin(iter_pair<T> p) { return p.begin_; }
  template<typename T> T end(iter_pair<T> p) { return p.end_; }

  template<typename...> class mem_fun_impl;
  template<typename R, typename T, typename... A>
  class mem_fun_impl<R (T::*)(A...)> {
    typedef R (T::*F)(A...);
    F f;
  public:
    mem_fun_impl(F f) : f(f) {}
    R operator()(T &t, A &&...a) const { return (t.*f)(static_cast<A&&>(a)...); }
  };
  template<typename F> mem_fun_impl<F> mem_fun(F f) { return mem_fun_impl<F>(f); }

  template<typename F, typename T>
  auto map(const F &f, T &t) -> iter_pair<map_iter<F, decltype(t.begin())>> {
    typedef map_iter<F, decltype(t.begin())> iter;
    return iter_pair<iter>(iter(f, t.begin()), iter(f, t.end()));
  }
}

#define assert(b) if (!(b)) { return 1; }
int main() {
  int total = 0;

  for (auto n : range(1, 5)) {
    total += n;
  }
  assert(total == 10);

  for (auto n : range(10, 100, 10)) {
    total += n;
  }
  assert(total == 460);

  map_range::vector<char> chars;
  chars.push_back('a');
  chars.push_back('b');
  chars.push_back('c');
  for (char c : chars) {
    ++total;
  }
  assert(total == 463);

  typedef map_range::tuple<int, double> T;
  map_range::vector<T> pairs;
  pairs.push_back(T(42, 12.9));
  pairs.push_back(T(6, 4.2));
  pairs.push_back(T(9, 1.1));
  for (auto a : map(map_range::mem_fun(&T::get<int>), pairs)) {
    total += a;
  }
  assert(total == 500);
}

// PR11793
namespace test2 {
  class A {
    int xs[10]; // expected-note {{implicitly declared private here}}
  };
  void test(A &a) {
    for (int x : a.xs) { } // expected-error {{'xs' is a private member of 'test2::A'}}
  }
}

namespace test3 {
  // Make sure this doesn't crash
  struct A {};
  struct B { ~B(); operator bool(); };
  struct C { B operator!=(const C&); C& operator++(); int operator*(); };
  C begin(const A&);
  C end(const A&);
  template<typename T> void f() { for (auto a : A()) {} }
  void g() { f<int>(); }
}

namespace test4 {
  void f() {
    int y;

    // Make sure these don't crash. Better diagnostics would be nice.
    for (: {1, 2, 3}) {} // expected-error {{expected expression}} expected-error {{expected ';'}}
    for (x : {1, 2, 3}) {} // expected-error {{undeclared identifier}} expected-error {{expected ';'}}
    for (y : {1, 2, 3}) {} // expected-error {{must declare a variable}} expected-warning {{result unused}}
  }
}

namespace test5 {
  // Test error-recovery.
  void f() {
    for (auto x : undeclared_identifier) // expected-error {{undeclared identifier}}
      for (auto y : x->foo)
        y->bar();
    for (auto x : 123) // expected-error {{no viable 'begin'}}
      x->foo();
  }
}

namespace test6 {
  void foo(int arr[]) {  // expected-note {{declared here}}
    for (auto i : arr) { }
      // expected-error@-1 {{cannot build range expression with array function parameter 'arr' since parameter with array type 'int []' is treated as pointer type 'int *'}}
  }

  struct vector {
    int *begin() { return 0; }
    int *end() { return 0; }
  };

  void foo(vector arr[]) {  // expected-note {{declared here}}
    // Don't suggest to dereference arr.
    for (auto i : arr) { }
      // 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 *'}}
  }
}
