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 // template <class C> constexpr auto begin(C& c) -> decltype(c.begin()); 13 // template <class C> constexpr auto begin(const C& c) -> decltype(c.begin()); 14 // template <class C> constexpr auto cbegin(const C& c) -> decltype(std::begin(c)); // C++14 15 // template <class C> constexpr auto cend(const C& c) -> decltype(std::end(c)); // C++14 16 // template <class C> constexpr auto end (C& c) -> decltype(c.end()); 17 // template <class C> constexpr auto end (const C& c) -> decltype(c.end()); 18 // template <class E> constexpr reverse_iterator<const E*> rbegin(initializer_list<E> il); 19 // template <class E> constexpr reverse_iterator<const E*> rend (initializer_list<E> il); 20 // 21 // template <class C> auto constexpr rbegin(C& c) -> decltype(c.rbegin()); // C++14 22 // template <class C> auto constexpr rbegin(const C& c) -> decltype(c.rbegin()); // C++14 23 // template <class C> auto constexpr rend(C& c) -> decltype(c.rend()); // C++14 24 // template <class C> constexpr auto rend(const C& c) -> decltype(c.rend()); // C++14 25 // template <class T, size_t N> reverse_iterator<T*> constexpr rbegin(T (&array)[N]); // C++14 26 // template <class T, size_t N> reverse_iterator<T*> constexpr rend(T (&array)[N]); // C++14 27 // template <class C> constexpr auto crbegin(const C& c) -> decltype(std::rbegin(c)); // C++14 28 // template <class C> constexpr auto crend(const C& c) -> decltype(std::rend(c)); // C++14 29 // 30 // All of these are constexpr in C++17 31 32 #include <array> 33 #include <cassert> 34 #include <initializer_list> 35 #include <iterator> 36 #include <list> 37 #include <vector> 38 39 #include "test_macros.h" 40 41 // Throughout this test, we consistently compare against c.begin() instead of c.cbegin() 42 // because some STL types (e.g. initializer_list) don't syntactically support il.cbegin(). 43 // Note that std::cbegin(x) effectively calls std::as_const(x).begin(), not x.cbegin(); 44 // see the ContainerHijacker test case below. 45 46 TEST_CONSTEXPR_CXX14 bool test_arrays_and_initializer_lists_forward() 47 { 48 { 49 int a[] = {1, 2, 3}; 50 ASSERT_SAME_TYPE(decltype(std::begin(a)), int*); 51 ASSERT_SAME_TYPE(decltype(std::end(a)), int*); 52 assert(std::begin(a) == a); 53 assert(std::end(a) == a + 3); 54 #if TEST_STD_VER > 11 55 ASSERT_SAME_TYPE(decltype(std::cbegin(a)), const int*); 56 ASSERT_SAME_TYPE(decltype(std::cend(a)), const int*); 57 assert(std::cbegin(a) == a); 58 assert(std::cend(a) == a + 3); 59 #endif 60 61 const auto& ca = a; 62 ASSERT_SAME_TYPE(decltype(std::begin(ca)), const int*); 63 ASSERT_SAME_TYPE(decltype(std::end(ca)), const int*); 64 assert(std::begin(ca) == a); 65 assert(std::end(ca) == a + 3); 66 #if TEST_STD_VER > 11 67 ASSERT_SAME_TYPE(decltype(std::cbegin(ca)), const int*); 68 ASSERT_SAME_TYPE(decltype(std::cend(ca)), const int*); 69 assert(std::cbegin(ca) == a); 70 assert(std::cend(ca) == a + 3); 71 #endif 72 } 73 { 74 std::initializer_list<int> il = {1, 2, 3}; 75 ASSERT_SAME_TYPE(decltype(std::begin(il)), const int*); 76 ASSERT_SAME_TYPE(decltype(std::end(il)), const int*); 77 assert(std::begin(il) == il.begin()); 78 assert(std::end(il) == il.end()); 79 #if TEST_STD_VER > 11 80 ASSERT_SAME_TYPE(decltype(std::cbegin(il)), const int*); 81 ASSERT_SAME_TYPE(decltype(std::cend(il)), const int*); 82 assert(std::cbegin(il) == il.begin()); 83 assert(std::cend(il) == il.end()); 84 #endif 85 86 const auto& cil = il; 87 ASSERT_SAME_TYPE(decltype(std::begin(cil)), const int*); 88 ASSERT_SAME_TYPE(decltype(std::end(cil)), const int*); 89 assert(std::begin(cil) == il.begin()); 90 assert(std::end(cil) == il.end()); 91 #if TEST_STD_VER > 11 92 ASSERT_SAME_TYPE(decltype(std::cbegin(cil)), const int*); 93 ASSERT_SAME_TYPE(decltype(std::cend(cil)), const int*); 94 assert(std::cbegin(cil) == il.begin()); 95 assert(std::cend(cil) == il.end()); 96 #endif 97 } 98 return true; 99 } 100 101 #if TEST_STD_VER > 11 102 TEST_CONSTEXPR_CXX17 bool test_arrays_and_initializer_lists_backward() 103 { 104 { 105 int a[] = {1, 2, 3}; 106 ASSERT_SAME_TYPE(decltype(std::rbegin(a)), std::reverse_iterator<int*>); 107 ASSERT_SAME_TYPE(decltype(std::rend(a)), std::reverse_iterator<int*>); 108 assert(std::rbegin(a).base() == a + 3); 109 assert(std::rend(a).base() == a); 110 ASSERT_SAME_TYPE(decltype(std::crbegin(a)), std::reverse_iterator<const int*>); 111 ASSERT_SAME_TYPE(decltype(std::crend(a)), std::reverse_iterator<const int*>); 112 assert(std::crbegin(a).base() == a + 3); 113 assert(std::crend(a).base() == a); 114 115 const auto& ca = a; 116 ASSERT_SAME_TYPE(decltype(std::rbegin(ca)), std::reverse_iterator<const int*>); 117 ASSERT_SAME_TYPE(decltype(std::rend(ca)), std::reverse_iterator<const int*>); 118 assert(std::rbegin(ca).base() == a + 3); 119 assert(std::rend(ca).base() == a); 120 ASSERT_SAME_TYPE(decltype(std::crbegin(ca)), std::reverse_iterator<const int*>); 121 ASSERT_SAME_TYPE(decltype(std::crend(ca)), std::reverse_iterator<const int*>); 122 assert(std::crbegin(ca).base() == a + 3); 123 assert(std::crend(ca).base() == a); 124 } 125 { 126 std::initializer_list<int> il = {1, 2, 3}; 127 ASSERT_SAME_TYPE(decltype(std::rbegin(il)), std::reverse_iterator<const int*>); 128 ASSERT_SAME_TYPE(decltype(std::rend(il)), std::reverse_iterator<const int*>); 129 assert(std::rbegin(il).base() == il.end()); 130 assert(std::rend(il).base() == il.begin()); 131 ASSERT_SAME_TYPE(decltype(std::crbegin(il)), std::reverse_iterator<const int*>); 132 ASSERT_SAME_TYPE(decltype(std::crend(il)), std::reverse_iterator<const int*>); 133 assert(std::crbegin(il).base() == il.end()); 134 assert(std::crend(il).base() == il.begin()); 135 136 const auto& cil = il; 137 ASSERT_SAME_TYPE(decltype(std::rbegin(cil)), std::reverse_iterator<const int*>); 138 ASSERT_SAME_TYPE(decltype(std::rend(cil)), std::reverse_iterator<const int*>); 139 assert(std::rbegin(cil).base() == il.end()); 140 assert(std::rend(cil).base() == il.begin()); 141 ASSERT_SAME_TYPE(decltype(std::crbegin(cil)), std::reverse_iterator<const int*>); 142 ASSERT_SAME_TYPE(decltype(std::crend(cil)), std::reverse_iterator<const int*>); 143 assert(std::crbegin(cil).base() == il.end()); 144 assert(std::crend(cil).base() == il.begin()); 145 } 146 return true; 147 } 148 #endif 149 150 template<typename C> 151 TEST_CONSTEXPR_CXX14 bool test_container() { 152 C c = {1, 2, 3}; 153 ASSERT_SAME_TYPE(decltype(std::begin(c)), typename C::iterator); 154 ASSERT_SAME_TYPE(decltype(std::end(c)), typename C::iterator); 155 assert(std::begin(c) == c.begin()); 156 assert(std::end(c) == c.end()); 157 #if TEST_STD_VER > 11 158 ASSERT_SAME_TYPE(decltype(std::cbegin(c)), typename C::const_iterator); 159 ASSERT_SAME_TYPE(decltype(std::cend(c)), typename C::const_iterator); 160 assert(std::cbegin(c) == c.begin()); 161 assert(std::cend(c) == c.end()); 162 ASSERT_SAME_TYPE(decltype(std::rbegin(c)), typename C::reverse_iterator); 163 ASSERT_SAME_TYPE(decltype(std::rend(c)), typename C::reverse_iterator); 164 assert(std::rbegin(c).base() == c.end()); 165 assert(std::rend(c).base() == c.begin()); 166 ASSERT_SAME_TYPE(decltype(std::crbegin(c)), typename C::const_reverse_iterator); 167 ASSERT_SAME_TYPE(decltype(std::crend(c)), typename C::const_reverse_iterator); 168 assert(std::crbegin(c).base() == c.end()); 169 assert(std::crend(c).base() == c.begin()); 170 #endif 171 172 const C& cc = c; 173 ASSERT_SAME_TYPE(decltype(std::begin(cc)), typename C::const_iterator); 174 ASSERT_SAME_TYPE(decltype(std::end(cc)), typename C::const_iterator); 175 assert(std::begin(cc) == c.begin()); 176 assert(std::end(cc) == c.end()); 177 #if TEST_STD_VER > 11 178 ASSERT_SAME_TYPE(decltype(std::cbegin(cc)), typename C::const_iterator); 179 ASSERT_SAME_TYPE(decltype(std::cend(cc)), typename C::const_iterator); 180 assert(std::cbegin(cc) == c.begin()); 181 assert(std::cend(cc) == c.end()); 182 ASSERT_SAME_TYPE(decltype(std::rbegin(cc)), typename C::const_reverse_iterator); 183 ASSERT_SAME_TYPE(decltype(std::rend(cc)), typename C::const_reverse_iterator); 184 assert(std::rbegin(cc).base() == c.end()); 185 assert(std::rend(cc).base() == c.begin()); 186 ASSERT_SAME_TYPE(decltype(std::crbegin(cc)), typename C::const_reverse_iterator); 187 ASSERT_SAME_TYPE(decltype(std::crend(cc)), typename C::const_reverse_iterator); 188 assert(std::crbegin(cc).base() == c.end()); 189 assert(std::crend(cc).base() == c.begin()); 190 #endif 191 192 return true; 193 } 194 195 struct ArrayHijacker { 196 friend constexpr int begin(ArrayHijacker(&)[3]) { return 42; } 197 friend constexpr int end(ArrayHijacker(&)[3]) { return 42; } 198 friend constexpr int begin(const ArrayHijacker(&)[3]) { return 42; } 199 friend constexpr int end(const ArrayHijacker(&)[3]) { return 42; } 200 }; 201 202 struct ContainerHijacker { 203 int *a_; 204 constexpr int *begin() const { return a_; } 205 constexpr int *end() const { return a_ + 3; } 206 constexpr int *rbegin() const { return a_; } 207 constexpr int *rend() const { return a_ + 3; } 208 friend constexpr int begin(ContainerHijacker&) { return 42; } 209 friend constexpr int end(ContainerHijacker&) { return 42; } 210 friend constexpr int begin(const ContainerHijacker&) { return 42; } 211 friend constexpr int end(const ContainerHijacker&) { return 42; } 212 friend constexpr int cbegin(ContainerHijacker&) { return 42; } 213 friend constexpr int cend(ContainerHijacker&) { return 42; } 214 friend constexpr int cbegin(const ContainerHijacker&) { return 42; } 215 friend constexpr int cend(const ContainerHijacker&) { return 42; } 216 friend constexpr int rbegin(ContainerHijacker&) { return 42; } 217 friend constexpr int rend(ContainerHijacker&) { return 42; } 218 friend constexpr int rbegin(const ContainerHijacker&) { return 42; } 219 friend constexpr int rend(const ContainerHijacker&) { return 42; } 220 friend constexpr int crbegin(ContainerHijacker&) { return 42; } 221 friend constexpr int crend(ContainerHijacker&) { return 42; } 222 friend constexpr int crbegin(const ContainerHijacker&) { return 42; } 223 friend constexpr int crend(const ContainerHijacker&) { return 42; } 224 }; 225 226 TEST_CONSTEXPR_CXX17 bool test_adl_proofing() { 227 // https://llvm.org/PR28927 228 { 229 ArrayHijacker a[3] = {}; 230 assert(begin(a) == 42); 231 assert(end(a) == 42); 232 assert(std::begin(a) == a); 233 assert(std::end(a) == a + 3); 234 #if TEST_STD_VER > 11 235 assert(std::cbegin(a) == a); 236 assert(std::cend(a) == a + 3); 237 assert(std::rbegin(a).base() == a + 3); 238 assert(std::rend(a).base() == a); 239 assert(std::crbegin(a).base() == a + 3); 240 assert(std::crend(a).base() == a); 241 #endif 242 } 243 { 244 int a[3] = {}; 245 ContainerHijacker c{a}; 246 assert(begin(c) == 42); 247 assert(end(c) == 42); 248 assert(std::begin(c) == a); 249 assert(std::end(c) == a + 3); 250 #if TEST_STD_VER > 11 251 assert(std::cbegin(c) == a); 252 assert(std::cend(c) == a + 3); 253 assert(std::rbegin(c) == a); 254 assert(std::rend(c) == a + 3); 255 assert(std::crbegin(c) == a); 256 assert(std::crend(c) == a + 3); 257 #endif 258 } 259 return true; 260 } 261 262 int main(int, char**) { 263 test_arrays_and_initializer_lists_forward(); 264 #if TEST_STD_VER > 11 265 test_arrays_and_initializer_lists_backward(); 266 #endif 267 test_container<std::array<int, 3>>(); 268 test_container<std::list<int>>(); 269 test_container<std::vector<int>>(); 270 test_adl_proofing(); 271 272 #if TEST_STD_VER > 11 273 static_assert(test_arrays_and_initializer_lists_forward(), ""); 274 #endif 275 #if TEST_STD_VER > 14 276 static_assert(test_arrays_and_initializer_lists_backward()); 277 static_assert(test_container<std::array<int, 3>>()); 278 static_assert(test_adl_proofing()); 279 #endif 280 281 return 0; 282 } 283