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, c++11, c++14, c++17
10
11// <compare>, <iterator>, <ranges>
12
13// ADL should be performed. Ordinary unqualified lookup should not be performed.
14
15namespace ns {
16struct StructWithGlobalFunctions {};
17} // namespace ns
18
19struct ConvertibleToCmpType;
20ConvertibleToCmpType strong_order(const ns::StructWithGlobalFunctions&, const ns::StructWithGlobalFunctions&);
21ConvertibleToCmpType weak_order(const ns::StructWithGlobalFunctions&, const ns::StructWithGlobalFunctions&);
22ConvertibleToCmpType partial_order(const ns::StructWithGlobalFunctions&, const ns::StructWithGlobalFunctions&);
23
24int&& iter_move(const ns::StructWithGlobalFunctions&);
25void iter_swap(const ns::StructWithGlobalFunctions&, const ns::StructWithGlobalFunctions&);
26
27int* begin(const ns::StructWithGlobalFunctions&);
28int* end(const ns::StructWithGlobalFunctions&);
29int* rbegin(const ns::StructWithGlobalFunctions&);
30int* rend(const ns::StructWithGlobalFunctions&);
31unsigned int size(const ns::StructWithGlobalFunctions&);
32
33#include <compare>
34#include <ranges>
35#include <type_traits>
36
37struct ConvertibleToCmpType {
38 operator std::strong_ordering() const;
39 operator std::weak_ordering() const;
40 operator std::partial_ordering() const;
41};
42
43struct StructWithHiddenFriends {
44 friend ConvertibleToCmpType strong_order(const StructWithHiddenFriends&, const StructWithHiddenFriends&);
45 friend ConvertibleToCmpType weak_order(const StructWithHiddenFriends&, const StructWithHiddenFriends&);
46 friend ConvertibleToCmpType partial_order(const StructWithHiddenFriends&, const StructWithHiddenFriends&);
47
48 friend int&& iter_move(const StructWithHiddenFriends&);
49 friend void iter_swap(const StructWithHiddenFriends&, const StructWithHiddenFriends&);
50
51 friend int* begin(const StructWithHiddenFriends&);
52 friend int* end(const StructWithHiddenFriends&);
53 friend int* rbegin(const StructWithHiddenFriends&);
54 friend int* rend(const StructWithHiddenFriends&);
55 friend unsigned int size(const StructWithHiddenFriends&);
56};
57
58// [cmp.alg] ADL should be performed.
59static_assert(std::is_invocable_v<decltype(std::strong_order), StructWithHiddenFriends&, StructWithHiddenFriends&>);
60static_assert(std::is_invocable_v<decltype(std::weak_order), StructWithHiddenFriends&, StructWithHiddenFriends&>);
61static_assert(std::is_invocable_v<decltype(std::partial_order), StructWithHiddenFriends&, StructWithHiddenFriends&>);
62
63// [cmp.alg] Ordinary unqualified lookup should not be performed.
64static_assert(
65 !std::is_invocable_v<decltype(std::strong_order), ns::StructWithGlobalFunctions&, ns::StructWithGlobalFunctions&>);
66static_assert(
67 !std::is_invocable_v<decltype(std::weak_order), ns::StructWithGlobalFunctions&, ns::StructWithGlobalFunctions&>);
68static_assert(
69 !std::is_invocable_v<decltype(std::partial_order), ns::StructWithGlobalFunctions&, ns::StructWithGlobalFunctions&>);
70
71// [iterator.cust] ADL should be performed.
72static_assert(std::is_invocable_v<decltype(std::ranges::iter_move), StructWithHiddenFriends&>);
73static_assert(
74 std::is_invocable_v<decltype(std::ranges::iter_swap), StructWithHiddenFriends&, StructWithHiddenFriends&>);
75
76// [iterator.cust] Ordinary unqualified lookup should not be performed.
77static_assert(!std::is_invocable_v<decltype(std::ranges::iter_move), ns::StructWithGlobalFunctions&>);
78static_assert(!std::is_invocable_v<decltype(std::ranges::iter_swap),
79 ns::StructWithGlobalFunctions&,
80 ns::StructWithGlobalFunctions&>);
81
82// [range.access] ADL should be performed.
83static_assert(std::is_invocable_v<decltype(std::ranges::begin), StructWithHiddenFriends&>);
84static_assert(std::is_invocable_v<decltype(std::ranges::cbegin), StructWithHiddenFriends&>);
85static_assert(std::is_invocable_v<decltype(std::ranges::end), StructWithHiddenFriends&>);
86static_assert(std::is_invocable_v<decltype(std::ranges::cend), StructWithHiddenFriends&>);
87static_assert(std::is_invocable_v<decltype(std::ranges::rbegin), StructWithHiddenFriends&>);
88static_assert(std::is_invocable_v<decltype(std::ranges::crbegin), StructWithHiddenFriends&>);
89static_assert(std::is_invocable_v<decltype(std::ranges::rend), StructWithHiddenFriends&>);
90static_assert(std::is_invocable_v<decltype(std::ranges::crend), StructWithHiddenFriends&>);
91static_assert(std::is_invocable_v<decltype(std::ranges::size), StructWithHiddenFriends&>);
92
93// [range.access] Ordinary unqualified lookup should not be performed.
94static_assert(!std::is_invocable_v<decltype(std::ranges::begin), ns::StructWithGlobalFunctions&>);
95static_assert(!std::is_invocable_v<decltype(std::ranges::cbegin), ns::StructWithGlobalFunctions&>);
96static_assert(!std::is_invocable_v<decltype(std::ranges::end), ns::StructWithGlobalFunctions&>);
97static_assert(!std::is_invocable_v<decltype(std::ranges::cend), ns::StructWithGlobalFunctions&>);
98static_assert(!std::is_invocable_v<decltype(std::ranges::rbegin), ns::StructWithGlobalFunctions&>);
99static_assert(!std::is_invocable_v<decltype(std::ranges::crbegin), ns::StructWithGlobalFunctions&>);
100static_assert(!std::is_invocable_v<decltype(std::ranges::rend), ns::StructWithGlobalFunctions&>);
101static_assert(!std::is_invocable_v<decltype(std::ranges::crend), ns::StructWithGlobalFunctions&>);
102static_assert(!std::is_invocable_v<decltype(std::ranges::size), ns::StructWithGlobalFunctions&>);
103

source code of libcxx/test/std/ranges/robust_against_poison_pills.compile.pass.cpp