94 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++0310 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 > 1159 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#endif66 }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 > 1175 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#endif82 }83 return true;84}85 86int main(int, char**) {87 test();88#if TEST_STD_VER >= 1789 static_assert(test());90#endif91 92 return 0;93}94