diff --git a/README.md b/README.md index ac7e695..8cd5015 100644 --- a/README.md +++ b/README.md @@ -94,9 +94,9 @@ results in the follow build error (snippet): external/llvm_toolchain_llvm/bin/../include/c++/v1/__functional/operations.h:374:37: note: read of non-const variable 'n' is not allowed in a constant expression 374 | return std::forward<_T1>(__t) < std::forward<_T2>(__u); | ^ -./src/detail/predicate.hpp:38:24: note: in call to 'static_cast &>(*this).operator()(0, n)' - 38 | const auto value = static_cast(*this)(std::as_const(args)...); - | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +./src/detail/predicate.hpp:35:18: note: in call to 'static_cast &>(*this).operator()(0, n)' + 35 | auto value = static_cast(*this)(std::as_const(args)...); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ example/ctest_fail.cpp:10:47: note: (skipping 2 calls in backtrace; use -fconstexpr-backtrace-limit=0 to see all) 10 | "read non-const"_ctest = [] { return expect(lt(0, n)); }; | ^ diff --git a/example/ctest_fail.log b/example/ctest_fail.log index 547b538..6459545 100644 --- a/example/ctest_fail.log +++ b/example/ctest_fail.log @@ -10,9 +10,9 @@ external/llvm_toolchain_llvm/bin/../include/c++/v1/__functional/operations.h:374:37: note: read of non-const variable 'n' is not allowed in a constant expression 374 | return std::forward<_T1>(__t) < std::forward<_T2>(__u); | ^ -./src/detail/predicate.hpp:38:24: note: in call to 'static_cast &>(*this).operator()(0, n)' - 38 | const auto value = static_cast(*this)(std::as_const(args)...); - | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +./src/detail/predicate.hpp:35:18: note: in call to 'static_cast &>(*this).operator()(0, n)' + 35 | auto value = static_cast(*this)(std::as_const(args)...); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ example/ctest_fail.cpp:10:47: note: (skipping 2 calls in backtrace; use -fconstexpr-backtrace-limit=0 to see all) 10 | "read non-const"_ctest = [] { return expect(lt(0, n)); }; | ^ diff --git a/src/detail/predicate.hpp b/src/detail/predicate.hpp index 18e791e..0c23f47 100644 --- a/src/detail/predicate.hpp +++ b/src/detail/predicate.hpp @@ -29,15 +29,14 @@ struct predicate : F constexpr predicate(T&& f) : F{std::forward(f)} {} - template < - class... Ts, - class = - std::enable_if_t>> + template constexpr auto operator()(Ts&&... args) const { - const auto value = static_cast(*this)(std::as_const(args)...); + auto value = static_cast(*this)(std::as_const(args)...); + return relation...>{ - std::tuple...>{std::forward(args)...}, value}; + std::tuple...>{std::forward(args)...}, + std::move(value)}; } }; diff --git a/src/test_param.hpp b/src/test_param.hpp index 9b809d0..2bc84fb 100644 --- a/src/test_param.hpp +++ b/src/test_param.hpp @@ -152,21 +152,14 @@ struct param_bound_closure template struct param_bound_static_closure { - template < - std::size_t I, - class P = remove_cvref_t, - std::enable_if_t, bool> = true> - constexpr auto operator[](constant) const - { - return [] { return func(get(params)); }; - } - template < - std::size_t I, - class P = remove_cvref_t, - std::enable_if_t, bool> = true> + template constexpr auto operator[](constant) const { - return [] { return func(params.begin()[I]); }; + if constexpr (is_range_v) { + return [] { return func(params.begin()[I]); }; + } else { + return [] { return func(get(params)); }; + } } }; @@ -246,34 +239,25 @@ class parameterized_test : params_{params}, basename_{basename} {} - template < - class F, - std::enable_if_t< - param_invocable_v and - not(is_static_closure_constructible_v and - has_static_value_v), - bool> = true> + template auto operator=(const F& func) && -> void { - assign_impl( - param_sequence_t{}, - param_bound_closure{func, params_}); - } - template < - class F, - std::enable_if_t< - param_invocable_v and - is_static_closure_constructible_v and - has_static_value_v, - bool> = true> - auto operator=(const F& func) && -> void - { - static const auto f = func; - static constexpr const auto& p = params_type::value; - - assign_impl( - std::make_index_sequence>{}, - param_bound_static_closure{}); + constexpr auto is_constexpr_invocable = + is_static_closure_constructible_v and + has_static_value_v; + + if constexpr (is_constexpr_invocable) { + static const auto f = func; + static constexpr const auto& p = params_type::value; + + assign_impl( + std::make_index_sequence>{}, + param_bound_static_closure{}); + } else { + assign_impl( + param_sequence_t{}, + param_bound_closure{func, params_}); + } } };