Skip to content

Commit

Permalink
Work around libc++18 std::invoke() bug
Browse files Browse the repository at this point in the history
It seems like std::invoke() in libc++18 (but not previous versions) doesn't like default function parameters in certain contexts.

Reported as llvm/llvm-project#106428
  • Loading branch information
tcbrindle committed Aug 28, 2024
1 parent 5996620 commit 9388588
Showing 1 changed file with 22 additions and 2 deletions.
24 changes: 22 additions & 2 deletions include/flux/op/fold.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,16 @@ struct fold_first_op {
}
};

// Workaround libc++18 invoke() bug: https://github.com/llvm/llvm-project/issues/106428
consteval bool libcpp_fold_invoke_workaround_required()
{
#if defined(_LIBCPP_VERSION)
return _LIBCPP_VERSION >= 180000 && _LIBCPP_VERSION < 190000;
#else
return false;
#endif
}

struct sum_op {
template <sequence Seq>
requires std::default_initializable<value_t<Seq>> &&
Expand All @@ -66,7 +76,12 @@ struct sum_op {
constexpr auto operator()(Seq&& seq) const -> value_t<Seq>
{
if constexpr (num::integral<value_t<Seq>>) {
return fold_op{}(FLUX_FWD(seq), num::add, value_t<Seq>(0));
if constexpr (libcpp_fold_invoke_workaround_required()) {
auto add = []<typename T>(T lhs, T rhs) -> T { return num::add(lhs, rhs); };
return fold_op{}(FLUX_FWD(seq), add, value_t<Seq>(0));
} else {
return fold_op{}(FLUX_FWD(seq), num::add, value_t<Seq>(0));
}
} else {
return fold_op{}(FLUX_FWD(seq), std::plus<>{}, value_t<Seq>(0));
}
Expand All @@ -81,7 +96,12 @@ struct product_op {
constexpr auto operator()(Seq&& seq) const -> value_t<Seq>
{
if constexpr (num::integral<value_t<Seq>>) {
return fold_op{}(FLUX_FWD(seq), num::mul, value_t<Seq>(1));
if constexpr (libcpp_fold_invoke_workaround_required()) {
auto mul = []<typename T>(T lhs, T rhs) -> T { return num::mul(lhs, rhs); };
return fold_op{}(FLUX_FWD(seq), mul, value_t<Seq>(1));
} else {
return fold_op{}(FLUX_FWD(seq), num::mul, value_t<Seq>(1));
}
} else {
return fold_op{}(FLUX_FWD(seq), std::multiplies<>{}, value_t<Seq>(1));
}
Expand Down

0 comments on commit 9388588

Please sign in to comment.