1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
11 // Make sure that std::cbegin(x) effectively calls std::as_const(x).begin(), not x.cbegin().
13 // Also make sure that we don't get hijacked by ADL, see https://llvm.org/PR28927.
18 #include "test_macros.h"
20 struct ArrayHijacker
{
21 friend constexpr int begin(ArrayHijacker (&)[3]) { return 42; }
22 friend constexpr int end(ArrayHijacker (&)[3]) { return 42; }
23 friend constexpr int begin(const ArrayHijacker (&)[3]) { return 42; }
24 friend constexpr int end(const ArrayHijacker (&)[3]) { return 42; }
27 struct ContainerHijacker
{
29 constexpr int* begin() const { return a_
; }
30 constexpr int* end() const { return a_
+ 3; }
31 constexpr int* rbegin() const { return a_
; }
32 constexpr int* rend() const { return a_
+ 3; }
33 friend constexpr int begin(ContainerHijacker
&) { return 42; }
34 friend constexpr int end(ContainerHijacker
&) { return 42; }
35 friend constexpr int begin(const ContainerHijacker
&) { return 42; }
36 friend constexpr int end(const ContainerHijacker
&) { return 42; }
37 friend constexpr int cbegin(ContainerHijacker
&) { return 42; }
38 friend constexpr int cend(ContainerHijacker
&) { return 42; }
39 friend constexpr int cbegin(const ContainerHijacker
&) { return 42; }
40 friend constexpr int cend(const ContainerHijacker
&) { return 42; }
41 friend constexpr int rbegin(ContainerHijacker
&) { return 42; }
42 friend constexpr int rend(ContainerHijacker
&) { return 42; }
43 friend constexpr int rbegin(const ContainerHijacker
&) { return 42; }
44 friend constexpr int rend(const ContainerHijacker
&) { return 42; }
45 friend constexpr int crbegin(ContainerHijacker
&) { return 42; }
46 friend constexpr int crend(ContainerHijacker
&) { return 42; }
47 friend constexpr int crbegin(const ContainerHijacker
&) { return 42; }
48 friend constexpr int crend(const ContainerHijacker
&) { return 42; }
51 TEST_CONSTEXPR_CXX17
bool test() {
53 ArrayHijacker a
[3] = {};
54 assert(begin(a
) == 42);
56 assert(std::begin(a
) == a
);
57 assert(std::end(a
) == a
+ 3);
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
);
69 ContainerHijacker c
{a
};
70 assert(begin(c
) == 42);
72 assert(std::begin(c
) == a
);
73 assert(std::end(c
) == a
+ 3);
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);
86 int main(int, char**) {
88 #if TEST_STD_VER >= 17
89 static_assert(test());