xref: /llvm-project/libcxx/test/std/iterators/iterator.range/begin-end.adl.pass.cpp (revision 000940e2964d27ea2ce29c107198e718f7de3d63)
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()51 TEST_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 **)86 int main(int, char**) {
87   test();
88 #if TEST_STD_VER >= 17
89   static_assert(test());
90 #endif
91 
92   return 0;
93 }
94