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), int, int>()); 41 static_assert(check_equivalence_relation_subsumes_relation<int (*)(int, double), int, double>()); 42 static_assert(check_equivalence_relation_subsumes_relation<R, S1, S1>()); 43 static_assert(check_equivalence_relation_subsumes_relation<R, S1, S2>()); 44 45 // clang-format off 46 template<class F, class T, class U> 47 requires std::relation<F, T, U> && true 48 constexpr bool check_relation_subsumes_equivalence_relation() { 49 return true; 50 } 51 52 template<class F, class T, class U> 53 requires std::equivalence_relation<F, T, U> 54 constexpr bool check_relation_subsumes_equivalence_relation() { 55 return false; 56 } 57 // clang-format on 58 59 static_assert(check_relation_subsumes_equivalence_relation<int (*)(int, int), int, int>()); 60 static_assert(check_relation_subsumes_equivalence_relation<int (*)(int, double), int, double>()); 61 static_assert(check_relation_subsumes_equivalence_relation<R, S1, S1>()); 62 static_assert(check_relation_subsumes_equivalence_relation<R, S1, S2>()); 63 64 // clang-format off 65 template<class F, class T, class U> 66 requires std::equivalence_relation<F, T, T> && std::equivalence_relation<F, U, U> 67 constexpr bool check_equivalence_relation_subsumes_itself() { 68 return false; 69 } 70 71 template<class F, class T, class U> 72 requires std::equivalence_relation<F, T, U> 73 constexpr bool check_equivalence_relation_subsumes_itself() { 74 return true; 75 } 76 // clang-format on 77 78 static_assert( 79 check_equivalence_relation_subsumes_itself<int (*)(int, int), int, int>()); 80 static_assert(check_equivalence_relation_subsumes_itself<R, S1, S1>()); 81