#include #include #include #include TEST_CASE("integral", "[concepts]") { STATIC_REQUIRE(stdx::integral); STATIC_REQUIRE(not stdx::integral); } TEST_CASE("floating_point", "[concepts]") { STATIC_REQUIRE(stdx::floating_point); STATIC_REQUIRE(not stdx::floating_point); } TEST_CASE("signed_integral", "[concepts]") { STATIC_REQUIRE(stdx::signed_integral); STATIC_REQUIRE(not stdx::signed_integral); } TEST_CASE("unsigned_integral", "[concepts]") { STATIC_REQUIRE(stdx::unsigned_integral); STATIC_REQUIRE(not stdx::unsigned_integral); } TEST_CASE("same_as", "[concepts]") { STATIC_REQUIRE(stdx::same_as); STATIC_REQUIRE(not stdx::same_as); } TEST_CASE("same_any", "[concepts]") { STATIC_REQUIRE(stdx::same_any); STATIC_REQUIRE(not stdx::same_any); } TEST_CASE("same_none", "[concepts]") { STATIC_REQUIRE(stdx::same_none); STATIC_REQUIRE(not stdx::same_none); } TEST_CASE("same_as_unqualified", "[concepts]") { STATIC_REQUIRE(stdx::same_as_unqualified); STATIC_REQUIRE(not stdx::same_as_unqualified); STATIC_REQUIRE(stdx::same_as_unqualified); STATIC_REQUIRE(stdx::same_as_unqualified); STATIC_REQUIRE(stdx::same_as_unqualified); STATIC_REQUIRE(stdx::same_as_unqualified); STATIC_REQUIRE(stdx::same_as_unqualified); STATIC_REQUIRE(stdx::same_as_unqualified); STATIC_REQUIRE(stdx::same_as_unqualified); STATIC_REQUIRE(stdx::same_as_unqualified); } TEST_CASE("convertible_to", "[concepts]") { STATIC_REQUIRE(stdx::convertible_to); STATIC_REQUIRE(not stdx::convertible_to); } namespace { struct S {}; } // namespace TEST_CASE("equality_comparable", "[concepts]") { STATIC_REQUIRE(stdx::equality_comparable); STATIC_REQUIRE(not stdx::equality_comparable); } TEST_CASE("totally_ordered", "[concepts]") { STATIC_REQUIRE(stdx::totally_ordered); STATIC_REQUIRE(not stdx::totally_ordered); } namespace { struct A {}; struct B : A {}; struct C : private A {}; } // namespace TEST_CASE("derived_from", "[concepts]") { STATIC_REQUIRE(stdx::derived_from); STATIC_REQUIRE(stdx::derived_from); STATIC_REQUIRE(not stdx::derived_from); STATIC_REQUIRE(not stdx::derived_from); } TEST_CASE("invocable", "[concepts]") { using invocable_no_args = auto (*)()->void; using invocable_int = auto (*)(int)->void; [[maybe_unused]] constexpr auto l_invocable_no_args = [] {}; [[maybe_unused]] constexpr auto l_invocable_int = [](int) {}; STATIC_REQUIRE(not stdx::invocable); STATIC_REQUIRE(stdx::invocable); STATIC_REQUIRE(not stdx::invocable); STATIC_REQUIRE(stdx::invocable); STATIC_REQUIRE(not stdx::invocable); STATIC_REQUIRE(stdx::invocable); STATIC_REQUIRE(not stdx::invocable); STATIC_REQUIRE(stdx::invocable); STATIC_REQUIRE(not stdx::invocable); } TEST_CASE("predicate (negative cases)", "[concepts]") { using not_predicate_no_args = auto (*)()->void; using not_predicate_int = auto (*)(int)->void; [[maybe_unused]] constexpr auto l_not_predicate_no_args = [] {}; [[maybe_unused]] constexpr auto l_not_predicate_int = [](int) {}; STATIC_REQUIRE(not stdx::predicate); STATIC_REQUIRE(not stdx::predicate); STATIC_REQUIRE(not stdx::predicate); STATIC_REQUIRE(not stdx::predicate); } TEST_CASE("predicate (positive cases)", "[concepts]") { using predicate_no_args = auto (*)()->bool; using predicate_int = auto (*)(int)->bool; [[maybe_unused]] constexpr auto l_predicate_no_args = [] { return true; }; [[maybe_unused]] constexpr auto l_predicate_int = [](int) { return true; }; [[maybe_unused]] constexpr auto convert_predicate_no_args = [] { return std::true_type{}; }; [[maybe_unused]] constexpr auto convert_predicate_int = [](int) { return std::true_type{}; }; STATIC_REQUIRE(stdx::predicate); STATIC_REQUIRE(stdx::predicate); STATIC_REQUIRE(stdx::predicate); STATIC_REQUIRE(stdx::predicate); STATIC_REQUIRE(stdx::predicate); STATIC_REQUIRE(stdx::predicate); } namespace { [[maybe_unused]] auto func_no_args() {} [[maybe_unused]] auto func_one_arg(int) {} struct funcobj { auto operator()() {} }; struct generic_funcobj { template auto operator()() {} }; } // namespace TEST_CASE("callable", "[concepts]") { [[maybe_unused]] constexpr auto l_callable_no_args = [] {}; [[maybe_unused]] constexpr auto l_callable_int = [](int) {}; [[maybe_unused]] constexpr auto l_callable_generic = [](auto) {}; STATIC_REQUIRE(not stdx::callable); STATIC_REQUIRE(stdx::callable); STATIC_REQUIRE(stdx::callable); STATIC_REQUIRE(stdx::callable); STATIC_REQUIRE(stdx::callable); STATIC_REQUIRE(stdx::callable); STATIC_REQUIRE(stdx::callable); STATIC_REQUIRE(stdx::callable); } TEST_CASE("models_trait", "[concepts]") { STATIC_REQUIRE(stdx::has_trait); STATIC_REQUIRE(not stdx::has_trait); } namespace { struct non_structural { ~non_structural() {} // nontrivial destructor }; } // namespace TEST_CASE("structural", "[concepts]") { STATIC_REQUIRE(stdx::structural); STATIC_REQUIRE(not stdx::structural); } TEST_CASE("complete", "[concepts]") { struct incomplete; STATIC_REQUIRE(stdx::complete); STATIC_REQUIRE(not stdx::complete); } namespace { template struct unary_t {}; template struct variadic_t {}; } // namespace TEST_CASE("same_template_as", "[concepts]") { STATIC_REQUIRE(stdx::same_template_as, unary_t>); STATIC_REQUIRE(not stdx::same_template_as, variadic_t>); }