1+ #include " detail/tuple_types.hpp"
2+
13#include < stdx/functional.hpp>
24
35#include < catch2/catch_test_macros.hpp>
46
57#include < type_traits>
8+ #include < utility>
69
710namespace {
811template <typename T, typename = void >
@@ -28,3 +31,80 @@ TEST_CASE("unary_plus transparency", "[functional]") {
2831TEST_CASE (" unary_plus calls operator+" , " [functional]" ) {
2932 STATIC_REQUIRE (stdx::unary_plus<>{}(S{}) == 17 );
3033}
34+
35+ TEST_CASE (" safe_identity returns unchanged argument" , " [functional]" ) {
36+ static_assert (stdx::safe_identity (17 ) == 17 );
37+ static_assert (stdx::safe_identity (move_only{17 }).value == 17 );
38+ }
39+
40+ TEST_CASE (" safe_identity (copy)" , " [functional]" ) {
41+ counter::reset ();
42+ counter c0{};
43+ [[maybe_unused]] auto c1 = stdx::safe_identity (c0);
44+ CHECK (counter::copies == 1 );
45+ }
46+
47+ TEST_CASE (" safe_identity (move)" , " [functional]" ) {
48+ counter::reset ();
49+ counter c0{};
50+ [[maybe_unused]] auto c1 = stdx::safe_identity (std::move (c0));
51+ CHECK (counter::copies == 0 );
52+ CHECK (counter::moves == 1 );
53+ }
54+
55+ TEST_CASE (" safe_identity transparency" , " [functional]" ) {
56+ STATIC_REQUIRE (detect_is_transparent<stdx::safe_identity_t >);
57+ }
58+
59+ namespace {
60+ template <typename T> auto declval () -> T;
61+ }
62+
63+ TEST_CASE (" safe_identity value categories" , " [functional]" ) {
64+ static_assert (
65+ std::is_same_v<decltype (stdx::safe_identity (declval<int >())), int >);
66+ static_assert (
67+ std::is_same_v<decltype (stdx::safe_identity (declval<int &>())), int &>);
68+ static_assert (
69+ std::is_same_v<decltype (stdx::safe_identity (declval<int &&>())), int >);
70+ }
71+
72+ TEST_CASE (" safe_identity cvref categories" , " [functional]" ) {
73+ static_assert (
74+ std::is_same_v<decltype (stdx::safe_identity (declval<int const &>())),
75+ int const &>);
76+ static_assert (
77+ std::is_same_v<decltype (stdx::safe_identity (declval<int volatile &>())),
78+ int volatile &>);
79+ static_assert (std::is_same_v<decltype (stdx::safe_identity (
80+ declval<int const volatile &>())),
81+ int const volatile &>);
82+ static_assert (
83+ std::is_same_v<decltype (stdx::safe_identity (declval<int const &&>())),
84+ int >);
85+ static_assert (
86+ std::is_same_v<
87+ decltype (stdx::safe_identity (declval<int volatile &&>())), int >);
88+ static_assert (std::is_same_v<decltype (stdx::safe_identity (
89+ declval<int const volatile &&>())),
90+ int >);
91+ }
92+
93+ #if __cplusplus >= 202002L
94+ namespace {
95+ auto f () -> int { return 42 ; }
96+ } // namespace
97+
98+ TEST_CASE (" safe_identity vs std::identity" , " [functional]" ) {
99+ int x{};
100+
101+ decltype (auto ) r1 = std::identity{}(x);
102+ static_assert (std::is_same_v<decltype (r1), int &>);
103+ decltype (auto ) r2 = std::identity{}(f ());
104+ static_assert (std::is_same_v<decltype (r2), int &&>);
105+ decltype (auto ) r3 = stdx::safe_identity (x);
106+ static_assert (std::is_same_v<decltype (r3), int &>);
107+ decltype (auto ) r4 = stdx::safe_identity (f ());
108+ static_assert (std::is_same_v<decltype (r4), int >);
109+ }
110+ #endif
0 commit comments