196dbdd75SChristopher Di Bella //===----------------------------------------------------------------------===//
296dbdd75SChristopher Di Bella //
396dbdd75SChristopher Di Bella // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
496dbdd75SChristopher Di Bella // See https://llvm.org/LICENSE.txt for license information.
596dbdd75SChristopher Di Bella // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
696dbdd75SChristopher Di Bella //
796dbdd75SChristopher Di Bella //===----------------------------------------------------------------------===//
896dbdd75SChristopher Di Bella 
996dbdd75SChristopher Di Bella // UNSUPPORTED: c++03, c++11, c++14, c++17
1096dbdd75SChristopher Di Bella 
1196dbdd75SChristopher Di Bella // template<class F, class... Args>
1296dbdd75SChristopher Di Bella // concept relation;
1396dbdd75SChristopher Di Bella 
1496dbdd75SChristopher Di Bella #include <concepts>
1596dbdd75SChristopher Di Bella 
1696dbdd75SChristopher Di Bella struct S1 {};
1796dbdd75SChristopher Di Bella struct S2 {};
1896dbdd75SChristopher Di Bella 
1996dbdd75SChristopher Di Bella struct R {
2096dbdd75SChristopher Di Bella   bool operator()(S1, S1) const;
2196dbdd75SChristopher Di Bella   bool operator()(S1, S2) const;
2296dbdd75SChristopher Di Bella   bool operator()(S2, S1) const;
2396dbdd75SChristopher Di Bella   bool operator()(S2, S2) const;
2496dbdd75SChristopher Di Bella };
2596dbdd75SChristopher Di Bella 
2696dbdd75SChristopher Di Bella // clang-format off
2796dbdd75SChristopher Di Bella template<class F, class T, class U>
2896dbdd75SChristopher Di Bella requires std::predicate<F, T, T> && std::predicate<F, T, U> &&
2996dbdd75SChristopher Di Bella          std::predicate<F, U, T> && std::predicate<F, U, U>
check_relation_subsumes_predicate()30*88b73a98SLouis Dionne constexpr bool check_relation_subsumes_predicate() {
3196dbdd75SChristopher Di Bella   return false;
3296dbdd75SChristopher Di Bella }
3396dbdd75SChristopher Di Bella 
3496dbdd75SChristopher Di Bella template<class F, class T, class U>
3596dbdd75SChristopher Di Bella requires std::relation<F, T, U> && true
check_relation_subsumes_predicate()36*88b73a98SLouis Dionne constexpr bool check_relation_subsumes_predicate() {
3796dbdd75SChristopher Di Bella   return true;
3896dbdd75SChristopher Di Bella }
3996dbdd75SChristopher Di Bella // clang-format on
4096dbdd75SChristopher Di Bella 
4196dbdd75SChristopher Di Bella static_assert(
4296dbdd75SChristopher Di Bella     check_relation_subsumes_predicate<int (*)(int, double), int, int>());
4396dbdd75SChristopher Di Bella static_assert(
4496dbdd75SChristopher Di Bella     check_relation_subsumes_predicate<int (*)(int, double), int, double>());
4596dbdd75SChristopher Di Bella static_assert(check_relation_subsumes_predicate<R, S1, S1>());
4696dbdd75SChristopher Di Bella static_assert(check_relation_subsumes_predicate<R, S1, S2>());
4796dbdd75SChristopher Di Bella 
4896dbdd75SChristopher Di Bella // clang-format off
4996dbdd75SChristopher Di Bella template<class F, class T, class U>
5096dbdd75SChristopher Di Bella requires std::relation<F, T, T> && std::relation<F, U, U>
check_relation_subsumes_itself()51*88b73a98SLouis Dionne constexpr bool check_relation_subsumes_itself() {
5296dbdd75SChristopher Di Bella   return false;
5396dbdd75SChristopher Di Bella }
5496dbdd75SChristopher Di Bella 
5596dbdd75SChristopher Di Bella template<class F, class T, class U>
5696dbdd75SChristopher Di Bella requires std::relation<F, T, U>
check_relation_subsumes_itself()57*88b73a98SLouis Dionne constexpr bool check_relation_subsumes_itself() {
5896dbdd75SChristopher Di Bella   return true;
5996dbdd75SChristopher Di Bella }
6096dbdd75SChristopher Di Bella // clang-format on
6196dbdd75SChristopher Di Bella 
6296dbdd75SChristopher Di Bella static_assert(check_relation_subsumes_itself<int (*)(int, double), int, int>());
6396dbdd75SChristopher Di Bella static_assert(check_relation_subsumes_itself<R, S1, S1>());
64