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