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 15 namespace ns { 16 struct StructWithGlobalFunctions {}; 17 } // namespace ns 18 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&); 23 24 int&& iter_move(const ns::StructWithGlobalFunctions&); 25 void iter_swap(const ns::StructWithGlobalFunctions&, const ns::StructWithGlobalFunctions&); 26 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&); 32 33 #include <compare> 34 #include <ranges> 35 #include <type_traits> 36 37 struct ConvertibleToCmpType { 38 operator std::strong_ordering() const; 39 operator std::weak_ordering() const; 40 operator std::partial_ordering() const; 41 }; 42 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&); 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. 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&>); 62 63 // [cmp.alg] Ordinary unqualified lookup should not be performed. 64 static_assert( 65 !std::is_invocable_v<decltype(std::strong_order), ns::StructWithGlobalFunctions&, ns::StructWithGlobalFunctions&>); 66 static_assert( 67 !std::is_invocable_v<decltype(std::weak_order), ns::StructWithGlobalFunctions&, ns::StructWithGlobalFunctions&>); 68 static_assert( 69 !std::is_invocable_v<decltype(std::partial_order), ns::StructWithGlobalFunctions&, ns::StructWithGlobalFunctions&>); 70 71 // [iterator.cust] ADL should be performed. 72 static_assert(std::is_invocable_v<decltype(std::ranges::iter_move), StructWithHiddenFriends&>); 73 static_assert( 74 std::is_invocable_v<decltype(std::ranges::iter_swap), StructWithHiddenFriends&, StructWithHiddenFriends&>); 75 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&>); 81 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&>); 92 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&>); 103