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 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14, c++17
11 // <compare>, <iterator>, <ranges>
13 // ADL should be performed. Ordinary unqualified lookup should not be performed.
16 struct StructWithGlobalFunctions
{};
19 struct ConvertibleToCmpType
;
20 ConvertibleToCmpType
strong_order(const ns::StructWithGlobalFunctions
&, const ns::StructWithGlobalFunctions
&);
21 ConvertibleToCmpType
weak_order(const ns::StructWithGlobalFunctions
&, const ns::StructWithGlobalFunctions
&);
22 ConvertibleToCmpType
partial_order(const ns::StructWithGlobalFunctions
&, const ns::StructWithGlobalFunctions
&);
24 int&& iter_move(const ns::StructWithGlobalFunctions
&);
25 void iter_swap(const ns::StructWithGlobalFunctions
&, const ns::StructWithGlobalFunctions
&);
27 int* begin(const ns::StructWithGlobalFunctions
&);
28 int* end(const ns::StructWithGlobalFunctions
&);
29 int* rbegin(const ns::StructWithGlobalFunctions
&);
30 int* rend(const ns::StructWithGlobalFunctions
&);
31 unsigned int size(const ns::StructWithGlobalFunctions
&);
35 #include <type_traits>
37 struct ConvertibleToCmpType
{
38 operator std::strong_ordering() const;
39 operator std::weak_ordering() const;
40 operator std::partial_ordering() const;
43 struct 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
&);
48 friend int&& iter_move(const StructWithHiddenFriends
&);
49 friend void iter_swap(const StructWithHiddenFriends
&, const StructWithHiddenFriends
&);
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
&);
58 // [cmp.alg] ADL should be performed.
59 static_assert(std::is_invocable_v
<decltype(std::strong_order
), StructWithHiddenFriends
&, StructWithHiddenFriends
&>);
60 static_assert(std::is_invocable_v
<decltype(std::weak_order
), StructWithHiddenFriends
&, StructWithHiddenFriends
&>);
61 static_assert(std::is_invocable_v
<decltype(std::partial_order
), StructWithHiddenFriends
&, StructWithHiddenFriends
&>);
63 // [cmp.alg] Ordinary unqualified lookup should not be performed.
65 !std::is_invocable_v
<decltype(std::strong_order
), ns::StructWithGlobalFunctions
&, ns::StructWithGlobalFunctions
&>);
67 !std::is_invocable_v
<decltype(std::weak_order
), ns::StructWithGlobalFunctions
&, ns::StructWithGlobalFunctions
&>);
69 !std::is_invocable_v
<decltype(std::partial_order
), ns::StructWithGlobalFunctions
&, ns::StructWithGlobalFunctions
&>);
71 // [iterator.cust] ADL should be performed.
72 static_assert(std::is_invocable_v
<decltype(std::ranges::iter_move
), StructWithHiddenFriends
&>);
74 std::is_invocable_v
<decltype(std::ranges::iter_swap
), StructWithHiddenFriends
&, StructWithHiddenFriends
&>);
76 // [iterator.cust] Ordinary unqualified lookup should not be performed.
77 static_assert(!std::is_invocable_v
<decltype(std::ranges::iter_move
), ns::StructWithGlobalFunctions
&>);
78 static_assert(!std::is_invocable_v
<decltype(std::ranges::iter_swap
),
79 ns::StructWithGlobalFunctions
&,
80 ns::StructWithGlobalFunctions
&>);
82 // [range.access] ADL should be performed.
83 static_assert(std::is_invocable_v
<decltype(std::ranges::begin
), StructWithHiddenFriends
&>);
84 static_assert(std::is_invocable_v
<decltype(std::ranges::cbegin
), StructWithHiddenFriends
&>);
85 static_assert(std::is_invocable_v
<decltype(std::ranges::end
), StructWithHiddenFriends
&>);
86 static_assert(std::is_invocable_v
<decltype(std::ranges::cend
), StructWithHiddenFriends
&>);
87 static_assert(std::is_invocable_v
<decltype(std::ranges::rbegin
), StructWithHiddenFriends
&>);
88 static_assert(std::is_invocable_v
<decltype(std::ranges::crbegin
), StructWithHiddenFriends
&>);
89 static_assert(std::is_invocable_v
<decltype(std::ranges::rend
), StructWithHiddenFriends
&>);
90 static_assert(std::is_invocable_v
<decltype(std::ranges::crend
), StructWithHiddenFriends
&>);
91 static_assert(std::is_invocable_v
<decltype(std::ranges::size
), StructWithHiddenFriends
&>);
93 // [range.access] Ordinary unqualified lookup should not be performed.
94 static_assert(!std::is_invocable_v
<decltype(std::ranges::begin
), ns::StructWithGlobalFunctions
&>);
95 static_assert(!std::is_invocable_v
<decltype(std::ranges::cbegin
), ns::StructWithGlobalFunctions
&>);
96 static_assert(!std::is_invocable_v
<decltype(std::ranges::end
), ns::StructWithGlobalFunctions
&>);
97 static_assert(!std::is_invocable_v
<decltype(std::ranges::cend
), ns::StructWithGlobalFunctions
&>);
98 static_assert(!std::is_invocable_v
<decltype(std::ranges::rbegin
), ns::StructWithGlobalFunctions
&>);
99 static_assert(!std::is_invocable_v
<decltype(std::ranges::crbegin
), ns::StructWithGlobalFunctions
&>);
100 static_assert(!std::is_invocable_v
<decltype(std::ranges::rend
), ns::StructWithGlobalFunctions
&>);
101 static_assert(!std::is_invocable_v
<decltype(std::ranges::crend
), ns::StructWithGlobalFunctions
&>);
102 static_assert(!std::is_invocable_v
<decltype(std::ranges::size
), ns::StructWithGlobalFunctions
&>);