#include "detail/tuple_types.hpp" #include #include #include #include namespace { template constexpr auto detect_is_transparent = false; template constexpr auto detect_is_transparent> = true; struct S {}; constexpr auto operator+(S) { return 17; } constexpr auto operator*(S) { return 28; } } // namespace TEST_CASE("unary_plus", "[functional]") { STATIC_REQUIRE(stdx::unary_plus{}(17) == 17); STATIC_REQUIRE(stdx::unary_plus<>{}(17) == 17); } TEST_CASE("unary_plus transparency", "[functional]") { STATIC_REQUIRE(not detect_is_transparent>); STATIC_REQUIRE(detect_is_transparent>); } TEST_CASE("unary_plus calls operator+", "[functional]") { STATIC_REQUIRE(stdx::unary_plus<>{}(S{}) == 17); } TEST_CASE("safe_identity returns unchanged argument", "[functional]") { static_assert(stdx::safe_identity(17) == 17); static_assert(stdx::safe_identity(move_only{17}).value == 17); } TEST_CASE("safe_identity (copy)", "[functional]") { counter::reset(); counter c0{}; [[maybe_unused]] auto c1 = stdx::safe_identity(c0); CHECK(counter::copies == 1); } TEST_CASE("safe_identity (move)", "[functional]") { counter::reset(); counter c0{}; [[maybe_unused]] auto c1 = stdx::safe_identity(std::move(c0)); CHECK(counter::copies == 0); CHECK(counter::moves == 1); } TEST_CASE("safe_identity transparency", "[functional]") { STATIC_REQUIRE(detect_is_transparent); } namespace { template auto declval() -> T; } TEST_CASE("safe_identity value categories", "[functional]") { static_assert( std::is_same_v())), int>); static_assert( std::is_same_v())), int &>); static_assert( std::is_same_v())), int>); } TEST_CASE("safe_identity cvref categories", "[functional]") { static_assert( std::is_same_v())), int const &>); static_assert( std::is_same_v())), int volatile &>); static_assert(std::is_same_v())), int const volatile &>); static_assert( std::is_same_v())), int>); static_assert( std::is_same_v< decltype(stdx::safe_identity(declval())), int>); static_assert(std::is_same_v())), int>); } TEST_CASE("dereference", "[functional]") { int x{28}; CHECK(stdx::dereference{}(&x) == 28); CHECK(stdx::dereference<>{}(&x) == 28); } TEST_CASE("dereference transparency", "[functional]") { STATIC_REQUIRE(not detect_is_transparent>); STATIC_REQUIRE(detect_is_transparent>); } TEST_CASE("dereference calls operator*", "[functional]") { STATIC_REQUIRE(stdx::dereference<>{}(S{}) == 28); }