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// template<class I1, class I2, class R, class P1, class P2>
12// concept indirectly_comparable;
13
14#include <functional>
15#include <iterator>
16#include <type_traits>
17
18#include "test_macros.h"
19
20struct Deref {
21 int operator()(int*) const;
22};
23
24static_assert(!std::indirectly_comparable<int, int, std::less<int>>); // not dereferenceable
25static_assert(!std::indirectly_comparable<int*, int*, int>); // not a predicate
26static_assert( std::indirectly_comparable<int*, int*, std::less<int>>);
27static_assert(!std::indirectly_comparable<int**, int*, std::less<int>>);
28static_assert( std::indirectly_comparable<int**, int*, std::less<int>, Deref>);
29static_assert(!std::indirectly_comparable<int**, int*, std::less<int>, Deref, Deref>);
30static_assert(!std::indirectly_comparable<int**, int*, std::less<int>, std::identity, Deref>);
31static_assert( std::indirectly_comparable<int*, int**, std::less<int>, std::identity, Deref>);
32
33template<class F>
34 requires std::indirectly_comparable<int*, char*, F>
35 && true // This true is an additional atomic constraint as a tie breaker
36constexpr bool subsumes(F) { return true; }
37
38template<class F>
39 requires std::indirect_binary_predicate<F, std::projected<int*, std::identity>, std::projected<char*, std::identity>>
40void subsumes(F);
41
42template<class F>
43 requires std::indirect_binary_predicate<F, std::projected<int*, std::identity>, std::projected<char*, std::identity>>
44 && true // This true is an additional atomic constraint as a tie breaker
45constexpr bool is_subsumed(F) { return true; }
46
47template<class F>
48 requires std::indirectly_comparable<int*, char*, F>
49void is_subsumed(F);
50
51static_assert(subsumes(std::less<int>()));
52static_assert(is_subsumed(std::less<int>()));
53
54// Test ADL-proofing (P2538R1)
55#if TEST_STD_VER >= 26 || defined(_LIBCPP_VERSION)
56struct Incomplete;
57template<class T> struct Holder { T t; };
58static_assert(std::indirectly_comparable<Holder<Incomplete>**, Holder<Incomplete>**, std::less<Holder<Incomplete>*>>);
59static_assert(!std::indirectly_comparable<Holder<Incomplete>**, Holder<Incomplete>**, Holder<Incomplete>*>);
60#endif
61

source code of libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_comparable.compile.pass.cpp