Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: libcpp-no-concepts

// template<class F, class... Args>
// concept relation;

#include <concepts>

// clang-format off
template<class F, class T, class U>
requires std::predicate<F, T, T> && std::predicate<F, T, U> &&
std::predicate<F, U, T> && std::predicate<F, U, U>
[[nodiscard]] constexpr bool check_subsumption() { return false; }

template<class F, class T, class U>
requires std::relation<F, T, U> && true
[[nodiscard]] constexpr bool check_subsumption() { return true; }
// clang-format on

static_assert(check_subsumption<int (*)(int, double), int, double>());

struct S1 {};
struct S2 {};

struct R {
bool operator()(S1, S1) const;
bool operator()(S1, S2) const;
bool operator()(S2, S1) const;
bool operator()(S2, S2) const;
};
static_assert(check_subsumption<R, S1, S2>());

int main(int, char**) { return 0; }
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: libcpp-no-concepts

// template<class F, class... Args>
// concept strict_weak_order;

#include <concepts>

static_assert(std::strict_weak_order<bool(int, int), int, int>);
static_assert(std::strict_weak_order<bool(int, int), double, double>);
static_assert(std::strict_weak_order<bool(int, double), double, double>);

static_assert(!std::strict_weak_order<bool (*)(), int, double>);
static_assert(!std::strict_weak_order<bool (*)(int), int, double>);
static_assert(!std::strict_weak_order<bool (*)(double), int, double>);

static_assert(!std::strict_weak_order<bool(double, double*), double, double*>);
static_assert(!std::strict_weak_order<bool(int&, int&), double&, double&>);

struct S1 {};
static_assert(std::strict_weak_order<bool (S1::*)(S1*), S1*, S1*>);
static_assert(std::strict_weak_order<bool (S1::*)(S1&), S1&, S1&>);

struct S2 {};

struct P1 {
bool operator()(S1, S1) const;
};
static_assert(std::strict_weak_order<P1, S1, S1>);

struct P2 {
bool operator()(S1, S1) const;
bool operator()(S1, S2) const;
};
static_assert(!std::strict_weak_order<P2, S1, S2>);

struct P3 {
bool operator()(S1, S1) const;
bool operator()(S1, S2) const;
bool operator()(S2, S1) const;
};
static_assert(!std::strict_weak_order<P3, S1, S2>);

struct P4 {
bool operator()(S1, S1) const;
bool operator()(S1, S2) const;
bool operator()(S2, S1) const;
bool operator()(S2, S2) const;
};
static_assert(std::strict_weak_order<P4, S1, S2>);

int main(int, char**) { return 0; }
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: libcpp-no-concepts

// template<class F, class... Args>
// concept strict_weak_order;

#include <concepts>

// clang-format off
template<class F, class T, class U>
requires std::relation<F, T, U>
[[nodiscard]] constexpr bool check_subsumption() { return false; }

template<class F, class T, class U>
requires std::strict_weak_order<F, T, U> && true
[[nodiscard]] constexpr bool check_subsumption() { return true; }
// clang-format on

static_assert(check_subsumption<int (*)(int, double), int, double>());

struct S1 {};
struct S2 {};

struct R {
bool operator()(S1, S1) const;
bool operator()(S1, S2) const;
bool operator()(S2, S1) const;
bool operator()(S2, S2) const;
};
static_assert(check_subsumption<R, S1, S2>());

int main(int, char**) { return 0; }
Original file line number Diff line number Diff line change
Expand Up @@ -42,32 +42,20 @@

#elif TEST_STD_VER == 20

# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_concepts
# error "__cpp_lib_concepts should be defined in c++20"
# endif
# if __cpp_lib_concepts != 202002L
# error "__cpp_lib_concepts should have the value 202002L in c++20"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_concepts
# error "__cpp_lib_concepts should not be defined because it is unimplemented in libc++!"
# endif
# ifndef __cpp_lib_concepts
# error "__cpp_lib_concepts should be defined in c++20"
# endif
# if __cpp_lib_concepts != 202002L
# error "__cpp_lib_concepts should have the value 202002L in c++20"
# endif

#elif TEST_STD_VER > 20

# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_concepts
# error "__cpp_lib_concepts should be defined in c++2b"
# endif
# if __cpp_lib_concepts != 202002L
# error "__cpp_lib_concepts should have the value 202002L in c++2b"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_concepts
# error "__cpp_lib_concepts should not be defined because it is unimplemented in libc++!"
# endif
# ifndef __cpp_lib_concepts
# error "__cpp_lib_concepts should be defined in c++2b"
# endif
# if __cpp_lib_concepts != 202002L
# error "__cpp_lib_concepts should have the value 202002L in c++2b"
# endif

#endif // TEST_STD_VER > 20
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2389,17 +2389,11 @@
# error "__cpp_lib_complex_udls should have the value 201309L in c++20"
# endif

# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_concepts
# error "__cpp_lib_concepts should be defined in c++20"
# endif
# if __cpp_lib_concepts != 202002L
# error "__cpp_lib_concepts should have the value 202002L in c++20"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_concepts
# error "__cpp_lib_concepts should not be defined because it is unimplemented in libc++!"
# endif
# ifndef __cpp_lib_concepts
# error "__cpp_lib_concepts should be defined in c++20"
# endif
# if __cpp_lib_concepts != 202002L
# error "__cpp_lib_concepts should have the value 202002L in c++20"
# endif

# ifndef __cpp_lib_constexpr_algorithms
Expand Down Expand Up @@ -3576,17 +3570,11 @@
# error "__cpp_lib_complex_udls should have the value 201309L in c++2b"
# endif

# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_concepts
# error "__cpp_lib_concepts should be defined in c++2b"
# endif
# if __cpp_lib_concepts != 202002L
# error "__cpp_lib_concepts should have the value 202002L in c++2b"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_concepts
# error "__cpp_lib_concepts should not be defined because it is unimplemented in libc++!"
# endif
# ifndef __cpp_lib_concepts
# error "__cpp_lib_concepts should be defined in c++2b"
# endif
# if __cpp_lib_concepts != 202002L
# error "__cpp_lib_concepts should have the value 202002L in c++2b"
# endif

# ifndef __cpp_lib_constexpr_algorithms
Expand Down
1 change: 0 additions & 1 deletion libcxx/utils/generate_feature_test_macro_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,6 @@ def add_version_header(tc):
"name": "__cpp_lib_concepts",
"values": { "c++20": 202002 },
"headers": ["concepts"],
"unimplemented": True,
}, {
"name": "__cpp_lib_constexpr_algorithms",
"values": { "c++20": 201806 },
Expand Down