From 9388588c858c802f206f86aaa4bbb268e938fe37 Mon Sep 17 00:00:00 2001 From: Tristan Brindle Date: Wed, 28 Aug 2024 19:18:54 +0100 Subject: [PATCH] Work around libc++18 std::invoke() bug It seems like std::invoke() in libc++18 (but not previous versions) doesn't like default function parameters in certain contexts. Reported as https://github.com/llvm/llvm-project/issues/106428 --- include/flux/op/fold.hpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/include/flux/op/fold.hpp b/include/flux/op/fold.hpp index 3d839d63..9f9e6a79 100644 --- a/include/flux/op/fold.hpp +++ b/include/flux/op/fold.hpp @@ -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 requires std::default_initializable> && @@ -66,7 +76,12 @@ struct sum_op { constexpr auto operator()(Seq&& seq) const -> value_t { if constexpr (num::integral>) { - return fold_op{}(FLUX_FWD(seq), num::add, value_t(0)); + if constexpr (libcpp_fold_invoke_workaround_required()) { + auto add = [](T lhs, T rhs) -> T { return num::add(lhs, rhs); }; + return fold_op{}(FLUX_FWD(seq), add, value_t(0)); + } else { + return fold_op{}(FLUX_FWD(seq), num::add, value_t(0)); + } } else { return fold_op{}(FLUX_FWD(seq), std::plus<>{}, value_t(0)); } @@ -81,7 +96,12 @@ struct product_op { constexpr auto operator()(Seq&& seq) const -> value_t { if constexpr (num::integral>) { - return fold_op{}(FLUX_FWD(seq), num::mul, value_t(1)); + if constexpr (libcpp_fold_invoke_workaround_required()) { + auto mul = [](T lhs, T rhs) -> T { return num::mul(lhs, rhs); }; + return fold_op{}(FLUX_FWD(seq), mul, value_t(1)); + } else { + return fold_op{}(FLUX_FWD(seq), num::mul, value_t(1)); + } } else { return fold_op{}(FLUX_FWD(seq), std::multiplies<>{}, value_t(1)); }