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 F, class... Args> 12 // concept equivalence_relation; 13 14 #include <concepts> 15 16 struct S1 {}; 17 struct S2 {}; 18 19 struct R { 20 bool operator()(S1, S1) const; 21 bool operator()(S1, S2) const; 22 bool operator()(S2, S1) const; 23 bool operator()(S2, S2) const; 24 }; 25 26 // clang-format off 27 template<class F, class T, class U> 28 requires std::relation<F, T, U> 29 constexpr bool check_equivalence_relation_subsumes_relation() { 30 return false; 31 } 32 33 template<class F, class T, class U> 34 requires std::equivalence_relation<F, T, U> && true 35 constexpr bool check_equivalence_relation_subsumes_relation() { 36 return true; 37 } 38 // clang-format on 39 40 static_assert(check_equivalence_relation_subsumes_relation<int (*)(int, int), 41 int, int>()); 42 static_assert(check_equivalence_relation_subsumes_relation<int (*)(int, double), 43 int, double>()); 44 static_assert(check_equivalence_relation_subsumes_relation<R, S1, S1>()); 45 static_assert(check_equivalence_relation_subsumes_relation<R, S1, S2>()); 46 47 // clang-format off 48 template<class F, class T, class U> 49 requires std::relation<F, T, U> && true 50 constexpr bool check_relation_subsumes_equivalence_relation() { 51 return true; 52 } 53 54 template<class F, class T, class U> 55 requires std::equivalence_relation<F, T, U> 56 constexpr bool check_relation_subsumes_equivalence_relation() { 57 return false; 58 } 59 // clang-format on 60 61 static_assert(check_relation_subsumes_equivalence_relation<int (*)(int, int), 62 int, int>()); 63 static_assert(check_relation_subsumes_equivalence_relation<int (*)(int, double), 64 int, double>()); 65 static_assert(check_relation_subsumes_equivalence_relation<R, S1, S1>()); 66 static_assert(check_relation_subsumes_equivalence_relation<R, S1, S2>()); 67 68 // clang-format off 69 template<class F, class T, class U> 70 requires std::equivalence_relation<F, T, T> && std::equivalence_relation<F, U, U> 71 constexpr bool check_equivalence_relation_subsumes_itself() { 72 return false; 73 } 74 75 template<class F, class T, class U> 76 requires std::equivalence_relation<F, T, U> 77 constexpr bool check_equivalence_relation_subsumes_itself() { 78 return true; 79 } 80 // clang-format on 81 82 static_assert( 83 check_equivalence_relation_subsumes_itself<int (*)(int, int), int, int>()); 84 static_assert(check_equivalence_relation_subsumes_itself<R, S1, S1>()); 85