Home | History | Annotate | Download | only in iterator.range
      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 // XFAIL: c++98, c++03
     11 
     12 // <iterator>
     13 // template <class C> constexpr auto begin(C& c) -> decltype(c.begin());
     14 // template <class C> constexpr auto begin(const C& c) -> decltype(c.begin());
     15 // template <class C> constexpr auto cbegin(const C& c) -> decltype(std::begin(c)); // C++14
     16 // template <class C> constexpr auto cend(const C& c) -> decltype(std::end(c));     // C++14
     17 // template <class C> constexpr auto end  (C& c) -> decltype(c.end());
     18 // template <class C> constexpr auto end  (const C& c) -> decltype(c.end());
     19 // template <class E> constexpr reverse_iterator<const E*> rbegin(initializer_list<E> il);
     20 // template <class E> constexpr reverse_iterator<const E*> rend  (initializer_list<E> il);
     21 //
     22 // template <class C> auto constexpr rbegin(C& c) -> decltype(c.rbegin());                 // C++14
     23 // template <class C> auto constexpr rbegin(const C& c) -> decltype(c.rbegin());           // C++14
     24 // template <class C> auto constexpr rend(C& c) -> decltype(c.rend());                     // C++14
     25 // template <class C> constexpr auto rend(const C& c) -> decltype(c.rend());               // C++14
     26 // template <class T, size_t N> reverse_iterator<T*> constexpr rbegin(T (&array)[N]);      // C++14
     27 // template <class T, size_t N> reverse_iterator<T*> constexpr rend(T (&array)[N]);        // C++14
     28 // template <class C> constexpr auto crbegin(const C& c) -> decltype(std::rbegin(c));      // C++14
     29 // template <class C> constexpr auto crend(const C& c) -> decltype(std::rend(c));          // C++14
     30 //
     31 //  All of these are constexpr in C++17
     32 
     33 #include "test_macros.h"
     34 
     35 #include <iterator>
     36 #include <cassert>
     37 #include <vector>
     38 #include <array>
     39 #include <list>
     40 #include <initializer_list>
     41 
     42 // std::array is explicitly allowed to be initialized with A a = { init-list };.
     43 // Disable the missing braces warning for this reason.
     44 #include "disable_missing_braces_warning.h"
     45 
     46 template<typename C>
     47 void test_const_container( const C & c, typename C::value_type val ) {
     48     assert ( std::begin(c)   == c.begin());
     49     assert (*std::begin(c)   ==  val );
     50     assert ( std::begin(c)   != c.end());
     51     assert ( std::end(c)     == c.end());
     52 #if TEST_STD_VER > 11
     53     assert ( std::cbegin(c)  == c.cbegin());
     54     assert ( std::cbegin(c)  != c.cend());
     55     assert ( std::cend(c)    == c.cend());
     56     assert ( std::rbegin(c)  == c.rbegin());
     57     assert ( std::rbegin(c)  != c.rend());
     58     assert ( std::rend(c)    == c.rend());
     59     assert ( std::crbegin(c) == c.crbegin());
     60     assert ( std::crbegin(c) != c.crend());
     61     assert ( std::crend(c)   == c.crend());
     62 #endif
     63     }
     64 
     65 template<typename T>
     66 void test_const_container( const std::initializer_list<T> & c, T val ) {
     67     assert ( std::begin(c)   == c.begin());
     68     assert (*std::begin(c)   ==  val );
     69     assert ( std::begin(c)   != c.end());
     70     assert ( std::end(c)     == c.end());
     71 #if TEST_STD_VER > 11
     72 //  initializer_list doesn't have cbegin/cend/rbegin/rend
     73 //  but std::cbegin(),etc work (b/c they're general fn templates)
     74 //     assert ( std::cbegin(c)  == c.cbegin());
     75 //     assert ( std::cbegin(c)  != c.cend());
     76 //     assert ( std::cend(c)    == c.cend());
     77 //     assert ( std::rbegin(c)  == c.rbegin());
     78 //     assert ( std::rbegin(c)  != c.rend());
     79 //     assert ( std::rend(c)    == c.rend());
     80 //     assert ( std::crbegin(c) == c.crbegin());
     81 //     assert ( std::crbegin(c) != c.crend());
     82 //     assert ( std::crend(c)   == c.crend());
     83 #endif
     84     }
     85 
     86 template<typename C>
     87 void test_container( C & c, typename C::value_type val ) {
     88     assert ( std::begin(c)   == c.begin());
     89     assert (*std::begin(c)   ==  val );
     90     assert ( std::begin(c)   != c.end());
     91     assert ( std::end(c)     == c.end());
     92 #if TEST_STD_VER > 11
     93     assert ( std::cbegin(c)  == c.cbegin());
     94     assert ( std::cbegin(c)  != c.cend());
     95     assert ( std::cend(c)    == c.cend());
     96     assert ( std::rbegin(c)  == c.rbegin());
     97     assert ( std::rbegin(c)  != c.rend());
     98     assert ( std::rend(c)    == c.rend());
     99     assert ( std::crbegin(c) == c.crbegin());
    100     assert ( std::crbegin(c) != c.crend());
    101     assert ( std::crend(c)   == c.crend());
    102 #endif
    103     }
    104 
    105 template<typename T>
    106 void test_container( std::initializer_list<T> & c, T val ) {
    107     assert ( std::begin(c)   == c.begin());
    108     assert (*std::begin(c)   ==  val );
    109     assert ( std::begin(c)   != c.end());
    110     assert ( std::end(c)     == c.end());
    111 #if TEST_STD_VER > 11
    112 //  initializer_list doesn't have cbegin/cend/rbegin/rend
    113 //     assert ( std::cbegin(c)  == c.cbegin());
    114 //     assert ( std::cbegin(c)  != c.cend());
    115 //     assert ( std::cend(c)    == c.cend());
    116 //     assert ( std::rbegin(c)  == c.rbegin());
    117 //     assert ( std::rbegin(c)  != c.rend());
    118 //     assert ( std::rend(c)    == c.rend());
    119 //     assert ( std::crbegin(c) == c.crbegin());
    120 //     assert ( std::crbegin(c) != c.crend());
    121 //     assert ( std::crend(c)   == c.crend());
    122 #endif
    123     }
    124 
    125 template<typename T, size_t Sz>
    126 void test_const_array( const T (&array)[Sz] ) {
    127     assert ( std::begin(array)  == array );
    128     assert (*std::begin(array)  ==  array[0] );
    129     assert ( std::begin(array)  != std::end(array));
    130     assert ( std::end(array)    == array + Sz);
    131 #if TEST_STD_VER > 11
    132     assert ( std::cbegin(array) == array );
    133     assert (*std::cbegin(array) == array[0] );
    134     assert ( std::cbegin(array) != std::cend(array));
    135     assert ( std::cend(array)   == array + Sz);
    136 #endif
    137     }
    138 
    139 int main(){
    140     std::vector<int> v; v.push_back(1);
    141     std::list<int> l;   l.push_back(2);
    142     std::array<int, 1> a; a[0] = 3;
    143     std::initializer_list<int> il = { 4 };
    144 
    145     test_container ( v, 1 );
    146     test_container ( l, 2 );
    147     test_container ( a, 3 );
    148     test_container ( il, 4 );
    149 
    150     test_const_container ( v, 1 );
    151     test_const_container ( l, 2 );
    152     test_const_container ( a, 3 );
    153     test_const_container ( il, 4 );
    154 
    155     static constexpr int arrA [] { 1, 2, 3 };
    156     test_const_array ( arrA );
    157 #if TEST_STD_VER > 11
    158     constexpr const int *b = std::cbegin(arrA);
    159     constexpr const int *e = std::cend(arrA);
    160     static_assert(e - b == 3, "");
    161 #endif
    162 
    163 #if TEST_STD_VER > 14
    164     {
    165         typedef std::array<int, 5> C;
    166         constexpr const C c{0,1,2,3,4};
    167 
    168         static_assert ( c.begin()   == std::begin(c), "");
    169         static_assert ( c.cbegin()  == std::cbegin(c), "");
    170         static_assert ( c.end()     == std::end(c), "");
    171         static_assert ( c.cend()    == std::cend(c), "");
    172 
    173         static_assert ( c.rbegin()  == std::rbegin(c), "");
    174         static_assert ( c.crbegin() == std::crbegin(c), "");
    175         static_assert ( c.rend()    == std::rend(c), "");
    176         static_assert ( c.crend()   == std::crend(c), "");
    177 
    178         static_assert ( std::begin(c)   != std::end(c), "");
    179         static_assert ( std::rbegin(c)  != std::rend(c), "");
    180         static_assert ( std::cbegin(c)  != std::cend(c), "");
    181         static_assert ( std::crbegin(c) != std::crend(c), "");
    182 
    183         static_assert ( *c.begin()  == 0, "");
    184         static_assert ( *c.rbegin()  == 4, "");
    185 
    186         static_assert ( *std::begin(c)   == 0, "" );
    187         static_assert ( *std::cbegin(c)  == 0, "" );
    188         static_assert ( *std::rbegin(c)  == 4, "" );
    189         static_assert ( *std::crbegin(c) == 4, "" );
    190     }
    191 
    192     {
    193         static constexpr const int c[] = {0,1,2,3,4};
    194 
    195         static_assert ( *std::begin(c)   == 0, "" );
    196         static_assert ( *std::cbegin(c)  == 0, "" );
    197         static_assert ( *std::rbegin(c)  == 4, "" );
    198         static_assert ( *std::crbegin(c) == 4, "" );
    199     }
    200 #endif
    201 }
    202