diff --git a/libcxx/include/concepts b/libcxx/include/concepts --- a/libcxx/include/concepts +++ b/libcxx/include/concepts @@ -398,7 +398,25 @@ template concept regular_invocable = invocable<_Fn, _Args...>; -#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) +// [concept.predicate] +template +concept predicate = + regular_invocable<_Fn, _Args...> && __boolean_testable>; + +// [concept.relation] +template +concept relation = + predicate<_Rp, _Tp, _Tp> && predicate<_Rp, _Up, _Up> && + predicate<_Rp, _Tp, _Up> && predicate<_Rp, _Up, _Tp>; + +// [concept.equiv] +template +concept equivalence_relation = relation<_Rp, _Tp, _Up>; + +// [concept.strictweakorder] +template +concept strict_weak_order = relation<_Rp, _Tp, _Up>; +#endif //_LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/test/std/concepts/concepts.callable/concepts.equiv/equivalence_relation.pass.cpp b/libcxx/test/std/concepts/concepts.callable/concepts.equiv/equivalence_relation.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/concepts/concepts.callable/concepts.equiv/equivalence_relation.pass.cpp @@ -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 +// concept equivalence_relation; + +#include + +static_assert(std::equivalence_relation); +static_assert(std::equivalence_relation); +static_assert(std::equivalence_relation); + +static_assert(!std::equivalence_relation); +static_assert(!std::equivalence_relation); +static_assert(!std::equivalence_relation); + +static_assert( + !std::equivalence_relation); +static_assert(!std::equivalence_relation); + +struct S1 {}; +static_assert(!std::equivalence_relation); + +struct S2 {}; + +struct P1 { + bool operator()(S1, S1) const; +}; +static_assert(std::equivalence_relation); + +struct P2 { + bool operator()(S1, S1) const; + bool operator()(S1, S2) const; +}; +static_assert(!std::equivalence_relation); + +struct P3 { + bool operator()(S1, S1) const; + bool operator()(S1, S2) const; + bool operator()(S2, S1) const; +}; +static_assert(!std::equivalence_relation); + +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::equivalence_relation); + +int main(int, char**) { return 0; } diff --git a/libcxx/test/std/concepts/concepts.callable/concepts.equiv/equivalence_relation.subsumption.pass.cpp b/libcxx/test/std/concepts/concepts.callable/concepts.equiv/equivalence_relation.subsumption.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/concepts/concepts.callable/concepts.equiv/equivalence_relation.subsumption.pass.cpp @@ -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 +// concept equivalence_relation; + +#include + +// clang-format off +template +requires std::relation +[[nodiscard]] constexpr bool check_subsumption() { return false; } + +template +requires std::equivalence_relation && true +[[nodiscard]] constexpr bool check_subsumption() { return true; } +// clang-format on + +static_assert(check_subsumption()); + +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()); + +int main(int, char**) { return 0; } diff --git a/libcxx/test/std/concepts/concepts.callable/concepts.predicate/predicate.pass.cpp b/libcxx/test/std/concepts/concepts.callable/concepts.predicate/predicate.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/concepts/concepts.callable/concepts.predicate/predicate.pass.cpp @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// concept predicate; + +#include + +static_assert(std::predicate); +static_assert(std::predicate); +static_assert(std::predicate); + +static_assert(!std::predicate); +static_assert(!std::predicate); +static_assert(!std::predicate); + +struct S {}; + +static_assert(!std::predicate); +static_assert(!std::predicate); +static_assert(std::predicate); +static_assert(std::predicate); +static_assert(!std::predicate); + +static_assert(!std::predicate); +static_assert(!std::predicate); +static_assert(!std::predicate); +static_assert(std::predicate); + +struct Predicate { + bool operator()(int, double, char); +}; +static_assert(std::predicate); +static_assert(std::predicate); + +int main(int, char**) { return 0; } diff --git a/libcxx/test/std/concepts/concepts.callable/concepts.predicate/predicate.subsumption.pass.cpp b/libcxx/test/std/concepts/concepts.callable/concepts.predicate/predicate.subsumption.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/concepts/concepts.callable/concepts.predicate/predicate.subsumption.pass.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// concept predicate; + +#include + +[[nodiscard]] constexpr bool check_subsumption(std::regular_invocable auto) { + return false; +} + +// clang-format off +template +requires std::predicate && true +[[nodiscard]] constexpr bool check_subsumption(F) +{ + return true; +} +// clang-format on + +static_assert(!check_subsumption([] {})); +static_assert(check_subsumption([] { return true; })); +static_assert(check_subsumption([] { return std::true_type(); })); +static_assert(check_subsumption([]() -> int* { return nullptr; })); + +struct boolean { + operator bool() const noexcept; +}; +static_assert(check_subsumption([] { return boolean(); })); + +struct explicit_bool { + explicit operator bool() const noexcept; +}; +static_assert(!check_subsumption([] { return explicit_bool(); })); + +int main(int, char**) { return 0; } diff --git a/libcxx/test/std/concepts/concepts.callable/concepts.relation/relation.pass.cpp b/libcxx/test/std/concepts/concepts.callable/concepts.relation/relation.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/concepts/concepts.callable/concepts.relation/relation.pass.cpp @@ -0,0 +1,59 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// concept relation; + +#include + +static_assert(std::relation); +static_assert(std::relation); +static_assert(std::relation); + +static_assert(!std::relation); +static_assert(!std::relation); +static_assert(!std::relation); + +static_assert(!std::relation); +static_assert(!std::relation); + +struct S1 {}; +static_assert(!std::relation); + +struct S2 {}; + +struct P1 { + bool operator()(S1, S1) const; +}; +static_assert(std::relation); + +struct P2 { + bool operator()(S1, S1) const; + bool operator()(S1, S2) const; +}; +static_assert(!std::relation); + +struct P3 { + bool operator()(S1, S1) const; + bool operator()(S1, S2) const; + bool operator()(S2, S1) const; +}; +static_assert(!std::relation); + +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::relation); + +int main(int, char**) { return 0; } diff --git a/libcxx/test/std/concepts/concepts.callable/concepts.relation/relation.subsumption.pass.cpp b/libcxx/test/std/concepts/concepts.callable/concepts.relation/relation.subsumption.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/concepts/concepts.callable/concepts.relation/relation.subsumption.pass.cpp @@ -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 +// concept relation; + +#include + +// clang-format off +template +requires std::predicate && std::predicate && + std::predicate && std::predicate +[[nodiscard]] constexpr bool check_subsumption() { return false; } + +template +requires std::relation && true +[[nodiscard]] constexpr bool check_subsumption() { return true; } +// clang-format on + +static_assert(check_subsumption()); + +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()); + +int main(int, char**) { return 0; } diff --git a/libcxx/test/std/concepts/concepts.callable/concepts.strictweakorder/strict_weak_order.pass.cpp b/libcxx/test/std/concepts/concepts.callable/concepts.strictweakorder/strict_weak_order.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/concepts/concepts.callable/concepts.strictweakorder/strict_weak_order.pass.cpp @@ -0,0 +1,59 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// concept strict_weak_order; + +#include + +static_assert(std::strict_weak_order); +static_assert(std::strict_weak_order); +static_assert(std::strict_weak_order); + +static_assert(!std::strict_weak_order); +static_assert(!std::strict_weak_order); +static_assert(!std::strict_weak_order); + +static_assert(!std::strict_weak_order); +static_assert(!std::strict_weak_order); + +struct S1 {}; +static_assert(!std::strict_weak_order); + +struct S2 {}; + +struct P1 { + bool operator()(S1, S1) const; +}; +static_assert(std::strict_weak_order); + +struct P2 { + bool operator()(S1, S1) const; + bool operator()(S1, S2) const; +}; +static_assert(!std::strict_weak_order); + +struct P3 { + bool operator()(S1, S1) const; + bool operator()(S1, S2) const; + bool operator()(S2, S1) const; +}; +static_assert(!std::strict_weak_order); + +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); + +int main(int, char**) { return 0; } diff --git a/libcxx/test/std/concepts/concepts.callable/concepts.strictweakorder/strict_weak_order.subsumption.pass.cpp b/libcxx/test/std/concepts/concepts.callable/concepts.strictweakorder/strict_weak_order.subsumption.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/concepts/concepts.callable/concepts.strictweakorder/strict_weak_order.subsumption.pass.cpp @@ -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 +// concept strict_weak_order; + +#include + +// clang-format off +template +requires std::relation +[[nodiscard]] constexpr bool check_subsumption() { return false; } + +template +requires std::strict_weak_order && true +[[nodiscard]] constexpr bool check_subsumption() { return true; } +// clang-format on + +static_assert(check_subsumption()); + +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()); + +int main(int, char**) { return 0; }