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
20struct 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; }
25};
26
27struct ContainerHijacker {
28 int* a_;
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; }
49};
50
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_: 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
86int main(int, char**) {
87 test();
88#if TEST_STD_VER >= 17
89 static_assert(test());
90#endif
91
92 return 0;
93}
94

source code of libcxx/test/std/iterators/iterator.range/begin-end.adl.pass.cpp