xref: /llvm-project/libcxx/test/std/iterators/iterator.range/begin-end.container.pass.cpp (revision 000940e2964d27ea2ce29c107198e718f7de3d63)
1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // UNSUPPORTED: c++03
10 
11 // <iterator>
12 //
13 // template <class C> constexpr auto begin(C& c) -> decltype(c.begin());                   // constexpr since C++17
14 // template <class C> constexpr auto begin(const C& c) -> decltype(c.begin());             // constexpr since C++17
15 // template <class C> constexpr auto end(C& c) -> decltype(c.end());                       // constexpr since C++17
16 // template <class C> constexpr auto end(const C& c) -> decltype(c.end());                 // constexpr since C++17
17 //
18 // template <class C> constexpr auto cbegin(const C& c) -> decltype(std::begin(c));        // C++14
19 // template <class C> constexpr auto cend(const C& c) -> decltype(std::end(c));            // C++14
20 // template <class C> constexpr auto rbegin(C& c) -> decltype(c.rbegin());                 // C++14, constexpr since C++17
21 // template <class C> constexpr auto rbegin(const C& c) -> decltype(c.rbegin());           // C++14, constexpr since C++17
22 // template <class C> constexpr auto rend(C& c) -> decltype(c.rend());                     // C++14, constexpr since C++17
23 // template <class C> constexpr auto rend(const C& c) -> decltype(c.rend());               // C++14, constexpr since C++17
24 // template <class C> constexpr auto crbegin(const C& c) -> decltype(std::rbegin(c));      // C++14, constexpr since C++17
25 // template <class C> constexpr auto crend(const C& c) -> decltype(std::rend(c));          // C++14, constexpr since C++17
26 
27 #include <array>
28 #include <cassert>
29 #include <iterator>
30 #include <list>
31 #include <vector>
32 
33 #include "test_macros.h"
34 
35 template <typename C,
36           typename Iterator             = typename C::iterator,
37           typename ConstIterator        = typename C::const_iterator,
38           typename ReverseIterator      = typename C::reverse_iterator,
39           typename ConstReverseIterator = typename C::const_reverse_iterator>
40 TEST_CONSTEXPR_CXX17 bool test() {
41   C c         = {1, 2, 3};
42   const C& cc = c;
43 
44   // std::begin(C& c) / std::end(C& c)
45   {
46     ASSERT_SAME_TYPE(decltype(std::begin(c)), Iterator);
47     assert(std::begin(c) == c.begin());
48 
49     ASSERT_SAME_TYPE(decltype(std::end(c)), Iterator);
50     assert(std::end(c) == c.end());
51   }
52 
53   // std::begin(C const& c) / std::end(C const& c)
54   {
55     ASSERT_SAME_TYPE(decltype(std::begin(cc)), ConstIterator);
56     assert(std::begin(cc) == cc.begin());
57 
58     ASSERT_SAME_TYPE(decltype(std::end(cc)), ConstIterator);
59     assert(std::end(cc) == cc.end());
60   }
61 
62 #if TEST_STD_VER >= 14
63   // std::cbegin(C const&) / std::cend(C const&)
64   {
65     ASSERT_SAME_TYPE(decltype(std::cbegin(cc)), ConstIterator);
66     static_assert(noexcept(std::cbegin(cc)) == noexcept(std::begin(cc)), "");
67     assert(std::cbegin(cc) == std::begin(cc));
68 
69     ASSERT_SAME_TYPE(decltype(std::cend(cc)), ConstIterator);
70     static_assert(noexcept(std::cend(cc)) == noexcept(std::end(cc)), "");
71     assert(std::cend(cc) == std::end(cc));
72 
73     // kind of overkill, but whatever
74     ASSERT_SAME_TYPE(decltype(std::cbegin(c)), ConstIterator);
75     static_assert(noexcept(std::cbegin(c)) == noexcept(std::begin(cc)), "");
76     assert(std::cbegin(c) == std::begin(cc));
77 
78     ASSERT_SAME_TYPE(decltype(std::cend(c)), ConstIterator);
79     static_assert(noexcept(std::cend(c)) == noexcept(std::end(cc)), "");
80     assert(std::cend(c) == std::end(cc));
81   }
82 
83   // std::rbegin(C& c) / std::rend(C& c)
84   {
85     ASSERT_SAME_TYPE(decltype(std::rbegin(c)), ReverseIterator);
86     assert(std::rbegin(c) == c.rbegin());
87 
88     ASSERT_SAME_TYPE(decltype(std::rend(c)), ReverseIterator);
89     assert(std::rend(c) == c.rend());
90   }
91 
92   // std::rbegin(C const&) / std::rend(C const&)
93   {
94     ASSERT_SAME_TYPE(decltype(std::rbegin(cc)), ConstReverseIterator);
95     assert(std::rbegin(cc) == cc.rbegin());
96 
97     ASSERT_SAME_TYPE(decltype(std::rend(cc)), ConstReverseIterator);
98     assert(std::rend(cc) == cc.rend());
99   }
100 
101   // std::crbegin(C const&) / std::crend(C const&)
102   {
103     ASSERT_SAME_TYPE(decltype(std::crbegin(cc)), ConstReverseIterator);
104     assert(std::crbegin(cc) == std::rbegin(cc));
105 
106     ASSERT_SAME_TYPE(decltype(std::crend(cc)), ConstReverseIterator);
107     assert(std::crend(cc) == std::rend(cc));
108 
109     // kind of overkill, but whatever
110     ASSERT_SAME_TYPE(decltype(std::crbegin(c)), ConstReverseIterator);
111     assert(std::crbegin(c) == std::rbegin(cc));
112 
113     ASSERT_SAME_TYPE(decltype(std::crend(c)), ConstReverseIterator);
114     assert(std::crend(c) == std::rend(cc));
115   }
116 #endif // TEST_STD_VER >= 14
117 
118   return true;
119 }
120 
121 int main(int, char**) {
122   test<std::array<int, 3>>();
123   test<std::list<int>>();
124   test<std::vector<int>>();
125 
126 #if TEST_STD_VER >= 17
127   static_assert(test<std::array<int, 3>>());
128 #endif
129 
130   return 0;
131 }
132