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 // Make sure that std::cbegin(x) effectively calls std::as_const(x).begin(), not x.cbegin(). 12 // 13 // Also make sure that we don't get hijacked by ADL, see https://llvm.org/PR28927. 14 15 #include <cassert> 16 #include <iterator> 17 18 #include "test_macros.h" 19 20 struct ArrayHijacker { begin(ArrayHijacker (&)[3])21 friend constexpr int begin(ArrayHijacker (&)[3]) { return 42; } end(ArrayHijacker (&)[3])22 friend constexpr int end(ArrayHijacker (&)[3]) { return 42; } begin(const ArrayHijacker (&)[3])23 friend constexpr int begin(const ArrayHijacker (&)[3]) { return 42; } end(const ArrayHijacker (&)[3])24 friend constexpr int end(const ArrayHijacker (&)[3]) { return 42; } 25 }; 26 27 struct ContainerHijacker { 28 int* a_; beginContainerHijacker29 constexpr int* begin() const { return a_; } endContainerHijacker30 constexpr int* end() const { return a_ + 3; } rbeginContainerHijacker31 constexpr int* rbegin() const { return a_; } rendContainerHijacker32 constexpr int* rend() const { return a_ + 3; } begin(ContainerHijacker &)33 friend constexpr int begin(ContainerHijacker&) { return 42; } end(ContainerHijacker &)34 friend constexpr int end(ContainerHijacker&) { return 42; } begin(const ContainerHijacker &)35 friend constexpr int begin(const ContainerHijacker&) { return 42; } end(const ContainerHijacker &)36 friend constexpr int end(const ContainerHijacker&) { return 42; } cbegin(ContainerHijacker &)37 friend constexpr int cbegin(ContainerHijacker&) { return 42; } cend(ContainerHijacker &)38 friend constexpr int cend(ContainerHijacker&) { return 42; } cbegin(const ContainerHijacker &)39 friend constexpr int cbegin(const ContainerHijacker&) { return 42; } cend(const ContainerHijacker &)40 friend constexpr int cend(const ContainerHijacker&) { return 42; } rbegin(ContainerHijacker &)41 friend constexpr int rbegin(ContainerHijacker&) { return 42; } rend(ContainerHijacker &)42 friend constexpr int rend(ContainerHijacker&) { return 42; } rbegin(const ContainerHijacker &)43 friend constexpr int rbegin(const ContainerHijacker&) { return 42; } rend(const ContainerHijacker &)44 friend constexpr int rend(const ContainerHijacker&) { return 42; } crbegin(ContainerHijacker &)45 friend constexpr int crbegin(ContainerHijacker&) { return 42; } crend(ContainerHijacker &)46 friend constexpr int crend(ContainerHijacker&) { return 42; } crbegin(const ContainerHijacker &)47 friend constexpr int crbegin(const ContainerHijacker&) { return 42; } crend(const ContainerHijacker &)48 friend constexpr int crend(const ContainerHijacker&) { return 42; } 49 }; 50 test()51TEST_CONSTEXPR_CXX17 bool test() { 52 { 53 ArrayHijacker a[3] = {}; 54 assert(begin(a) == 42); 55 assert(end(a) == 42); 56 assert(std::begin(a) == a); 57 assert(std::end(a) == a + 3); 58 #if TEST_STD_VER > 11 59 assert(std::cbegin(a) == a); 60 assert(std::cend(a) == a + 3); 61 assert(std::rbegin(a).base() == a + 3); 62 assert(std::rend(a).base() == a); 63 assert(std::crbegin(a).base() == a + 3); 64 assert(std::crend(a).base() == a); 65 #endif 66 } 67 { 68 int a[3] = {}; 69 ContainerHijacker c{a}; 70 assert(begin(c) == 42); 71 assert(end(c) == 42); 72 assert(std::begin(c) == a); 73 assert(std::end(c) == a + 3); 74 #if TEST_STD_VER > 11 75 assert(std::cbegin(c) == a); 76 assert(std::cend(c) == a + 3); 77 assert(std::rbegin(c) == a); 78 assert(std::rend(c) == a + 3); 79 assert(std::crbegin(c) == a); 80 assert(std::crend(c) == a + 3); 81 #endif 82 } 83 return true; 84 } 85 main(int,char **)86int main(int, char**) { 87 test(); 88 #if TEST_STD_VER >= 17 89 static_assert(test()); 90 #endif 91 92 return 0; 93 } 94