diff --git a/include/stdx/utility.hpp b/include/stdx/utility.hpp index e740ece..8d65bf2 100644 --- a/include/stdx/utility.hpp +++ b/include/stdx/utility.hpp @@ -260,23 +260,25 @@ template constexpr auto is_ct_v = is_ct_v; #if __cplusplus >= 202002L -#define CT_WRAP(X) \ +#define CT_WRAP(...) \ [&](auto f) { \ if constexpr (::stdx::is_ct_v) { \ return f(); \ } else if constexpr (requires { \ - ::stdx::ct<[&]() constexpr { return X; }()>; \ + ::stdx::ct<[&]() constexpr { \ + return __VA_ARGS__; \ + }()>; \ }) { \ - return ::stdx::ct<[&]() constexpr { return X; }()>(); \ + return ::stdx::ct<[&]() constexpr { return __VA_ARGS__; }()>(); \ } else { \ return f(); \ } \ - }([&] { return X; }) + }([&] { return __VA_ARGS__; }) #ifdef __clang__ -#define CX_DETECT(X) \ +#define CX_DETECT(...) \ std::is_empty_v #else namespace stdx { @@ -285,34 +287,34 @@ template constexpr auto cx_detect0() {} constexpr auto cx_detect1(auto) { return 0; } } // namespace v1 } // namespace stdx -#define CX_DETECT(X) \ +#define CX_DETECT(...) \ requires { \ ::stdx::cx_detect0<::stdx::cx_detect1( \ - (X) + ::stdx::cxv_detail::type_val{})>; \ + (__VA_ARGS__) + ::stdx::cxv_detail::type_val{})>; \ } #endif -#define CX_WRAP(X) \ - [&](auto f) { \ +#define CX_WRAP(...) \ + [&]([[maybe_unused]] auto f) { \ STDX_PRAGMA(diagnostic push) \ STDX_PRAGMA(diagnostic ignored "-Wold-style-cast") \ - if constexpr (::stdx::is_cx_value_v< \ - std::invoke_result_t> or \ - std::is_empty_v>) { \ + if constexpr (decltype(::stdx::cxv_detail::is_type< \ + ::stdx::cxv_detail::from_any( \ + __VA_ARGS__)>())::value) { \ + return ::stdx::overload{ \ + ::stdx::cxv_detail::cx_base{}, [&] { \ + return ::stdx::type_identity< \ + decltype(::stdx::cxv_detail::type_of< \ + ::stdx::cxv_detail::from_any( \ + __VA_ARGS__)>())>{}; \ + }}; \ + } else if constexpr (::stdx::is_cx_value_v< \ + std::invoke_result_t> or \ + std::is_empty_v< \ + std::invoke_result_t>) { \ return f(); \ - } else if constexpr (CX_DETECT(X)) { \ - if constexpr (decltype(::stdx::cxv_detail::is_type< \ - ::stdx::cxv_detail::from_any( \ - X)>())::value) { \ - return ::stdx::overload{ \ - ::stdx::cxv_detail::cx_base{}, [&] { \ - return ::stdx::type_identity< \ - decltype(::stdx::cxv_detail::type_of< \ - ::stdx::cxv_detail::from_any(X)>())>{}; \ - }}; \ - } else { \ - return ::stdx::overload{::stdx::cxv_detail::cx_base{}, f}; \ - } \ + } else if constexpr (CX_DETECT(__VA_ARGS__)) { \ + return ::stdx::overload{::stdx::cxv_detail::cx_base{}, f}; \ } else { \ return f(); \ } \ @@ -320,7 +322,7 @@ constexpr auto cx_detect1(auto) { return 0; } }([&] { \ STDX_PRAGMA(diagnostic push) \ STDX_PRAGMA(diagnostic ignored "-Wold-style-cast") \ - return (X) + ::stdx::cxv_detail::type_val{}; \ + return (__VA_ARGS__) + ::stdx::cxv_detail::type_val{}; \ STDX_PRAGMA(diagnostic pop) \ }) diff --git a/test/utility.cpp b/test/utility.cpp index 4042d84..087b07a 100644 --- a/test/utility.cpp +++ b/test/utility.cpp @@ -364,6 +364,13 @@ TEST_CASE("CX_WRAP type argument", "[utility]") { std::is_same_v>); } +TEST_CASE("CX_WRAP empty type argument", "[utility]") { + using X = std::integral_constant; + STATIC_REQUIRE(stdx::is_cx_value_v); + STATIC_REQUIRE( + std::is_same_v>); +} + TEST_CASE("CX_WRAP integral_constant arg", "[utility]") { auto x = std::integral_constant{}; STATIC_REQUIRE(std::is_same_v);