Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<const std::less<void> &>(*this).operator()<const int &, const int &>(0, n)'
38 | const auto value = static_cast<const F&>(*this)(std::as_const(args)...);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./src/detail/predicate.hpp:35:18: note: in call to 'static_cast<const std::less<void> &>(*this).operator()<const int &, const int &>(0, n)'
35 | auto value = static_cast<const F&>(*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)); };
| ^
Expand Down
6 changes: 3 additions & 3 deletions example/ctest_fail.log
Original file line number Diff line number Diff line change
Expand Up @@ -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<const std::less<void> &>(*this).operator()<const int &, const int &>(0, n)'
38 | const auto value = static_cast<const F&>(*this)(std::as_const(args)...);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./src/detail/predicate.hpp:35:18: note: in call to 'static_cast<const std::less<void> &>(*this).operator()<const int &, const int &>(0, n)'
35 | auto value = static_cast<const F&>(*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)); };
| ^
Expand Down
11 changes: 5 additions & 6 deletions src/detail/predicate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,14 @@ struct predicate : F
constexpr predicate(T&& f) : F{std::forward<T>(f)}
{}

template <
class... Ts,
class =
std::enable_if_t<std::is_invocable_r_v<bool, const F&, const Ts&...>>>
template <class... Ts>
constexpr auto operator()(Ts&&... args) const
{
const auto value = static_cast<const F&>(*this)(std::as_const(args)...);
auto value = static_cast<const F&>(*this)(std::as_const(args)...);

return relation<predicate, std::decay_t<Ts>...>{
std::tuple<std::decay_t<Ts>...>{std::forward<Ts>(args)...}, value};
std::tuple<std::decay_t<Ts>...>{std::forward<Ts>(args)...},
std::move(value)};
}
};

Expand Down
62 changes: 23 additions & 39 deletions src/test_param.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,21 +152,14 @@ struct param_bound_closure
template <const auto& func, const auto& params>
struct param_bound_static_closure
{
template <
std::size_t I,
class P = remove_cvref_t<decltype(params)>,
std::enable_if_t<not is_range_v<P>, bool> = true>
constexpr auto operator[](constant<I>) const
{
return [] { return func(get<I>(params)); };
}
template <
std::size_t I,
class P = remove_cvref_t<decltype(params)>,
std::enable_if_t<is_range_v<P>, bool> = true>
template <std::size_t I>
constexpr auto operator[](constant<I>) const
{
return [] { return func(params.begin()[I]); };
if constexpr (is_range_v<decltype(params)>) {
return [] { return func(params.begin()[I]); };
} else {
return [] { return func(get<I>(params)); };
}
}
};

Expand Down Expand Up @@ -246,34 +239,25 @@ class parameterized_test
: params_{params}, basename_{basename}
{}

template <
class F,
std::enable_if_t<
param_invocable_v<F, params_type> and
not(is_static_closure_constructible_v<F> and
has_static_value_v<params_type>),
bool> = true>
template <class F>
auto operator=(const F& func) && -> void
{
assign_impl(
param_sequence_t<params_type>{},
param_bound_closure<F, params_type>{func, params_});
}
template <
class F,
std::enable_if_t<
param_invocable_v<F, params_type> and
is_static_closure_constructible_v<F> and
has_static_value_v<params_type>,
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<static_size_v<params_type>>{},
param_bound_static_closure<f, p>{});
constexpr auto is_constexpr_invocable =
is_static_closure_constructible_v<F> and
has_static_value_v<params_type>;

if constexpr (is_constexpr_invocable) {
static const auto f = func;
static constexpr const auto& p = params_type::value;

assign_impl(
std::make_index_sequence<static_size_v<params_type>>{},
param_bound_static_closure<f, p>{});
} else {
assign_impl(
param_sequence_t<params_type>{},
param_bound_closure<F, params_type>{func, params_});
}
}
};

Expand Down