xref: /llvm-project/libcxx/test/std/iterators/iterator.range/begin-end.adl.pass.cpp (revision 000940e2964d27ea2ce29c107198e718f7de3d63)
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 Dionne TEST_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 Dionne int 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