1*000940e2SLouis Dionne //===----------------------------------------------------------------------===// 2*000940e2SLouis Dionne // 3*000940e2SLouis Dionne // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*000940e2SLouis Dionne // See https://llvm.org/LICENSE.txt for license information. 5*000940e2SLouis Dionne // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*000940e2SLouis Dionne // 7*000940e2SLouis Dionne //===----------------------------------------------------------------------===// 8*000940e2SLouis Dionne 9*000940e2SLouis Dionne // UNSUPPORTED: c++03 10*000940e2SLouis Dionne 11*000940e2SLouis Dionne // Make sure that std::cbegin(x) effectively calls std::as_const(x).begin(), not x.cbegin(). 12*000940e2SLouis Dionne // 13*000940e2SLouis Dionne // Also make sure that we don't get hijacked by ADL, see https://llvm.org/PR28927. 14*000940e2SLouis Dionne 15*000940e2SLouis Dionne #include <cassert> 16*000940e2SLouis Dionne #include <iterator> 17*000940e2SLouis Dionne 18*000940e2SLouis Dionne #include "test_macros.h" 19*000940e2SLouis Dionne 20*000940e2SLouis Dionne struct ArrayHijacker { begin(ArrayHijacker (&)[3])21*000940e2SLouis Dionne friend constexpr int begin(ArrayHijacker (&)[3]) { return 42; } end(ArrayHijacker (&)[3])22*000940e2SLouis Dionne friend constexpr int end(ArrayHijacker (&)[3]) { return 42; } begin(const ArrayHijacker (&)[3])23*000940e2SLouis Dionne friend constexpr int begin(const ArrayHijacker (&)[3]) { return 42; } end(const ArrayHijacker (&)[3])24*000940e2SLouis Dionne friend constexpr int end(const ArrayHijacker (&)[3]) { return 42; } 25*000940e2SLouis Dionne }; 26*000940e2SLouis Dionne 27*000940e2SLouis Dionne struct ContainerHijacker { 28*000940e2SLouis Dionne int* a_; beginContainerHijacker29*000940e2SLouis Dionne constexpr int* begin() const { return a_; } endContainerHijacker30*000940e2SLouis Dionne constexpr int* end() const { return a_ + 3; } rbeginContainerHijacker31*000940e2SLouis Dionne constexpr int* rbegin() const { return a_; } rendContainerHijacker32*000940e2SLouis Dionne constexpr int* rend() const { return a_ + 3; } begin(ContainerHijacker &)33*000940e2SLouis Dionne friend constexpr int begin(ContainerHijacker&) { return 42; } end(ContainerHijacker &)34*000940e2SLouis Dionne friend constexpr int end(ContainerHijacker&) { return 42; } begin(const ContainerHijacker &)35*000940e2SLouis Dionne friend constexpr int begin(const ContainerHijacker&) { return 42; } end(const ContainerHijacker &)36*000940e2SLouis Dionne friend constexpr int end(const ContainerHijacker&) { return 42; } cbegin(ContainerHijacker &)37*000940e2SLouis Dionne friend constexpr int cbegin(ContainerHijacker&) { return 42; } cend(ContainerHijacker &)38*000940e2SLouis Dionne friend constexpr int cend(ContainerHijacker&) { return 42; } cbegin(const ContainerHijacker &)39*000940e2SLouis Dionne friend constexpr int cbegin(const ContainerHijacker&) { return 42; } cend(const ContainerHijacker &)40*000940e2SLouis Dionne friend constexpr int cend(const ContainerHijacker&) { return 42; } rbegin(ContainerHijacker &)41*000940e2SLouis Dionne friend constexpr int rbegin(ContainerHijacker&) { return 42; } rend(ContainerHijacker &)42*000940e2SLouis Dionne friend constexpr int rend(ContainerHijacker&) { return 42; } rbegin(const ContainerHijacker &)43*000940e2SLouis Dionne friend constexpr int rbegin(const ContainerHijacker&) { return 42; } rend(const ContainerHijacker &)44*000940e2SLouis Dionne friend constexpr int rend(const ContainerHijacker&) { return 42; } crbegin(ContainerHijacker &)45*000940e2SLouis Dionne friend constexpr int crbegin(ContainerHijacker&) { return 42; } crend(ContainerHijacker &)46*000940e2SLouis Dionne friend constexpr int crend(ContainerHijacker&) { return 42; } crbegin(const ContainerHijacker &)47*000940e2SLouis Dionne friend constexpr int crbegin(const ContainerHijacker&) { return 42; } crend(const ContainerHijacker &)48*000940e2SLouis Dionne friend constexpr int crend(const ContainerHijacker&) { return 42; } 49*000940e2SLouis Dionne }; 50*000940e2SLouis Dionne test()51*000940e2SLouis DionneTEST_CONSTEXPR_CXX17 bool test() { 52*000940e2SLouis Dionne { 53*000940e2SLouis Dionne ArrayHijacker a[3] = {}; 54*000940e2SLouis Dionne assert(begin(a) == 42); 55*000940e2SLouis Dionne assert(end(a) == 42); 56*000940e2SLouis Dionne assert(std::begin(a) == a); 57*000940e2SLouis Dionne assert(std::end(a) == a + 3); 58*000940e2SLouis Dionne #if TEST_STD_VER > 11 59*000940e2SLouis Dionne assert(std::cbegin(a) == a); 60*000940e2SLouis Dionne assert(std::cend(a) == a + 3); 61*000940e2SLouis Dionne assert(std::rbegin(a).base() == a + 3); 62*000940e2SLouis Dionne assert(std::rend(a).base() == a); 63*000940e2SLouis Dionne assert(std::crbegin(a).base() == a + 3); 64*000940e2SLouis Dionne assert(std::crend(a).base() == a); 65*000940e2SLouis Dionne #endif 66*000940e2SLouis Dionne } 67*000940e2SLouis Dionne { 68*000940e2SLouis Dionne int a[3] = {}; 69*000940e2SLouis Dionne ContainerHijacker c{a}; 70*000940e2SLouis Dionne assert(begin(c) == 42); 71*000940e2SLouis Dionne assert(end(c) == 42); 72*000940e2SLouis Dionne assert(std::begin(c) == a); 73*000940e2SLouis Dionne assert(std::end(c) == a + 3); 74*000940e2SLouis Dionne #if TEST_STD_VER > 11 75*000940e2SLouis Dionne assert(std::cbegin(c) == a); 76*000940e2SLouis Dionne assert(std::cend(c) == a + 3); 77*000940e2SLouis Dionne assert(std::rbegin(c) == a); 78*000940e2SLouis Dionne assert(std::rend(c) == a + 3); 79*000940e2SLouis Dionne assert(std::crbegin(c) == a); 80*000940e2SLouis Dionne assert(std::crend(c) == a + 3); 81*000940e2SLouis Dionne #endif 82*000940e2SLouis Dionne } 83*000940e2SLouis Dionne return true; 84*000940e2SLouis Dionne } 85*000940e2SLouis Dionne main(int,char **)86*000940e2SLouis Dionneint main(int, char**) { 87*000940e2SLouis Dionne test(); 88*000940e2SLouis Dionne #if TEST_STD_VER >= 17 89*000940e2SLouis Dionne static_assert(test()); 90*000940e2SLouis Dionne #endif 91*000940e2SLouis Dionne 92*000940e2SLouis Dionne return 0; 93*000940e2SLouis Dionne } 94