1//===----------------------------------------------------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// <iterator>
11// template <class C> auto begin(C& c) -> decltype(c.begin());
12// template <class C> auto begin(const C& c) -> decltype(c.begin());
13// template <class C> auto end(C& c) -> decltype(c.end());
14// template <class C> auto end(const C& c) -> decltype(c.end());
15// template <class E> reverse_iterator<const E*> rbegin(initializer_list<E> il);
16// template <class E> reverse_iterator<const E*> rend(initializer_list<E> il);
17
18#include <__config>
19
20#if __cplusplus >= 201103L
21#include <iterator>
22#include <cassert>
23#include <vector>
24#include <array>
25#include <list>
26#include <initializer_list>
27
28template<typename C>
29void test_const_container( const C & c, typename C::value_type val ) {
30    assert ( std::begin(c)   == c.begin());
31    assert (*std::begin(c)   ==  val );
32    assert ( std::begin(c)   != c.end());
33    assert ( std::end(c)     == c.end());
34#if _LIBCPP_STD_VER > 11
35    assert ( std::cbegin(c)  == c.cbegin());
36    assert ( std::cbegin(c)  != c.cend());
37    assert ( std::cend(c)    == c.cend());
38    assert ( std::rbegin(c)  == c.rbegin());
39    assert ( std::rbegin(c)  != c.rend());
40    assert ( std::rend(c)    == c.rend());
41    assert ( std::crbegin(c) == c.crbegin());
42    assert ( std::crbegin(c) != c.crend());
43    assert ( std::crend(c)   == c.crend());
44#endif
45    }
46
47template<typename T>
48void test_const_container( const std::initializer_list<T> & c, T val ) {
49    assert ( std::begin(c)   == c.begin());
50    assert (*std::begin(c)   ==  val );
51    assert ( std::begin(c)   != c.end());
52    assert ( std::end(c)     == c.end());
53#if _LIBCPP_STD_VER > 11
54//  initializer_list doesn't have cbegin/cend/rbegin/rend
55//  but std::cbegin(),etc work (b/c they're general fn templates)
56//     assert ( std::cbegin(c)  == c.cbegin());
57//     assert ( std::cbegin(c)  != c.cend());
58//     assert ( std::cend(c)    == c.cend());
59//     assert ( std::rbegin(c)  == c.rbegin());
60//     assert ( std::rbegin(c)  != c.rend());
61//     assert ( std::rend(c)    == c.rend());
62//     assert ( std::crbegin(c) == c.crbegin());
63//     assert ( std::crbegin(c) != c.crend());
64//     assert ( std::crend(c)   == c.crend());
65#endif
66    }
67
68template<typename C>
69void test_container( C & c, typename C::value_type val ) {
70    assert ( std::begin(c)   == c.begin());
71    assert (*std::begin(c)   ==  val );
72    assert ( std::begin(c)   != c.end());
73    assert ( std::end(c)     == c.end());
74#if _LIBCPP_STD_VER > 11
75    assert ( std::cbegin(c)  == c.cbegin());
76    assert ( std::cbegin(c)  != c.cend());
77    assert ( std::cend(c)    == c.cend());
78    assert ( std::rbegin(c)  == c.rbegin());
79    assert ( std::rbegin(c)  != c.rend());
80    assert ( std::rend(c)    == c.rend());
81    assert ( std::crbegin(c) == c.crbegin());
82    assert ( std::crbegin(c) != c.crend());
83    assert ( std::crend(c)   == c.crend());
84#endif
85    }
86
87template<typename T>
88void test_container( std::initializer_list<T> & c, T val ) {
89    assert ( std::begin(c)   == c.begin());
90    assert (*std::begin(c)   ==  val );
91    assert ( std::begin(c)   != c.end());
92    assert ( std::end(c)     == c.end());
93#if _LIBCPP_STD_VER > 11
94//  initializer_list doesn't have cbegin/cend/rbegin/rend
95//     assert ( std::cbegin(c)  == c.cbegin());
96//     assert ( std::cbegin(c)  != c.cend());
97//     assert ( std::cend(c)    == c.cend());
98//     assert ( std::rbegin(c)  == c.rbegin());
99//     assert ( std::rbegin(c)  != c.rend());
100//     assert ( std::rend(c)    == c.rend());
101//     assert ( std::crbegin(c) == c.crbegin());
102//     assert ( std::crbegin(c) != c.crend());
103//     assert ( std::crend(c)   == c.crend());
104#endif
105    }
106
107template<typename T, size_t Sz>
108void test_const_array( const T (&array)[Sz] ) {
109    assert ( std::begin(array)  == array );
110    assert (*std::begin(array)  ==  array[0] );
111    assert ( std::begin(array)  != std::end(array));
112    assert ( std::end(array)    == array + Sz);
113#if _LIBCPP_STD_VER > 11
114    assert ( std::cbegin(array) == array );
115    assert (*std::cbegin(array) == array[0] );
116    assert ( std::cbegin(array) != std::cend(array));
117    assert ( std::cend(array)   == array + Sz);
118#endif
119    }
120
121int main(){
122    std::vector<int> v; v.push_back(1);
123    std::list<int> l;   l.push_back(2);
124    std::array<int, 1> a; a[0] = 3;
125    std::initializer_list<int> il = { 4 };
126
127    test_container ( v, 1 );
128    test_container ( l, 2 );
129    test_container ( a, 3 );
130    test_container ( il, 4 );
131
132    test_const_container ( v, 1 );
133    test_const_container ( l, 2 );
134    test_const_container ( a, 3 );
135    test_const_container ( il, 4 );
136
137    static constexpr int arrA [] { 1, 2, 3 };
138    test_const_array ( arrA );
139#if _LIBCPP_STD_VER > 11
140    constexpr const int *b = std::cbegin(arrA);
141    constexpr const int *e = std::cend(arrA);
142    static_assert(e - b == 3, "");
143#endif
144}
145
146#else
147int main(){}
148#endif
149