diff --git a/include/continuable/continuable-base.hpp b/include/continuable/continuable-base.hpp index 538afe0..db3063f 100644 --- a/include/continuable/continuable-base.hpp +++ b/include/continuable/continuable-base.hpp @@ -677,8 +677,8 @@ template auto when_all(Continuables&&... continuables) { static_assert(sizeof...(continuables) >= 2, "Requires at least 2 continuables!"); - return detail::traits::fold(detail::traits::and_folding(), - std::forward(continuables)...); + return CONTINUABLE_FOLD_EXPRESSION( + &&, std::forward(continuables)...); } /// Connects the given continuables with an *any* logic. @@ -693,8 +693,8 @@ template auto when_any(Continuables&&... continuables) { static_assert(sizeof...(continuables) >= 2, "Requires at least 2 continuables!"); - return detail::traits::fold(detail::traits::or_folding(), - std::forward(continuables)...); + return CONTINUABLE_FOLD_EXPRESSION( + ||, std::forward(continuables)...); } /// Connects the given continuables with a *seq* logic. @@ -709,8 +709,8 @@ template auto when_seq(Continuables&&... continuables) { static_assert(sizeof...(continuables) >= 2, "Requires at least 2 continuables!"); - return detail::traits::fold(detail::traits::seq_folding(), - std::forward(continuables)...); + return CONTINUABLE_FOLD_EXPRESSION( + >>, std::forward(continuables)...); } } // namespace cti diff --git a/include/continuable/detail/features.hpp b/include/continuable/detail/features.hpp index 29b2acd..32208f3 100644 --- a/include/continuable/detail/features.hpp +++ b/include/continuable/detail/features.hpp @@ -47,7 +47,9 @@ #endif #endif // CONTINUABLE_WITH_NO_EXCEPTIONS +/// TODO Enable this #undef CONTINUABLE_HAS_CXX17_CONSTEXPR_IF +/// TODO Enable this #undef CONTINUABLE_HAS_CXX17_FOLD_EXPRESSION #endif // CONTINUABLE_DETAIL_FEATURES_HPP_INCLUDED__ diff --git a/include/continuable/detail/traits.hpp b/include/continuable/detail/traits.hpp index 8ac134b..6c164f5 100644 --- a/include/continuable/detail/traits.hpp +++ b/include/continuable/detail/traits.hpp @@ -401,41 +401,6 @@ constexpr auto merge(identity /*left*/, std::forward(rest)...); } -/// Combines the given arguments with the given folding function -template -constexpr auto fold(F&& /*folder*/, First&& first) { - return std::forward(first); -} -/// Combines the given arguments with the given folding function -template -auto fold(F&& folder, First&& first, Second&& second, Rest&&... rest) { - auto res = folder(std::forward(first), std::forward(second)); - return fold(std::forward(folder), std::move(res), - std::forward(rest)...); -} - -/// Returns a folding function using operator `&&`. -inline auto and_folding() noexcept { - return [](auto&& left, auto&& right) { - return std::forward(left) && - std::forward(right); - }; -} -/// Returns a folding function using operator `||`. -inline auto or_folding() noexcept { - return [](auto&& left, auto&& right) { - return std::forward(left) || - std::forward(right); - }; -} -/// Returns a folding function using operator `>>`. -inline auto seq_folding() noexcept { - return [](auto&& left, auto&& right) { - return std::forward(left) >> - std::forward(right); - }; -} - /// Deduces to a std::false_type template using fail = std::integral_constant::value>; @@ -443,7 +408,4 @@ using fail = std::integral_constant::value>; } // namespace detail } // namespace cti -#define CONTINUABLE_CONSTEXPR_IF(EXPR, TRUE_BRANCH, FALSE_BRANCH) -#define CONTINUABLE_FOLD_EXPRESSION(OPERATOR, SEQUENCE) - #endif // CONTINUABLE_DETAIL_TRAITS_HPP_INCLUDED__ diff --git a/include/continuable/detail/util.hpp b/include/continuable/detail/util.hpp index dbf8357..2a7a66f 100644 --- a/include/continuable/detail/util.hpp +++ b/include/continuable/detail/util.hpp @@ -260,8 +260,44 @@ private: *(volatile int*)0 = 0; #endif } + +/// Exposes functionality to emulate later standard features +namespace emulation { +#ifndef CONTINUABLE_HAS_CXX17_FOLD_EXPRESSION +/// Combines the given arguments with the given folding function +template +constexpr auto fold(F&& /*folder*/, First&& first) { + return std::forward(first); +} +/// Combines the given arguments with the given folding function +template +auto fold(F&& folder, First&& first, Second&& second, Rest&&... rest) { + auto res = folder(std::forward(first), std::forward(second)); + return fold(std::forward(folder), std::move(res), + std::forward(rest)...); +} +#endif // CONTINUABLE_HAS_CXX17_FOLD_EXPRESSION +} // namespace emulation } // namespace util } // namespace detail } // namespace cti +#ifdef CONTINUABLE_CONSTEXPR_IF +#define CONTINUABLE_CONSTEXPR_IF(EXPR, TRUE_BRANCH, FALSE_BRANCH) +#else +#define CONTINUABLE_CONSTEXPR_IF(EXPR, TRUE_BRANCH, FALSE_BRANCH) +#endif // CONTINUABLE_CONSTEXPR_IF + +#ifdef CONTINUABLE_HAS_CXX17_FOLD_EXPRESSION +#define CONTINUABLE_FOLD_EXPRESSION(OP, PACK) (... OP PACK) +#else +#define CONTINUABLE_FOLD_EXPRESSION(OP, PACK) \ + cti::detail::util::emulation::fold( \ + [](auto&& left, auto&& right) { \ + return std::forward(left) \ + OP std::forward(right); \ + }, \ + PACK); +#endif // CONTINUABLE_HAS_CXX17_FOLD_EXPRESSION + #endif // CONTINUABLE_DETAIL_UTIL_HPP_INCLUDED__ diff --git a/test/unit-test/test-continuable-regression.cpp b/test/unit-test/test-continuable-regression.cpp index a801ab3..8c29d7b 100644 --- a/test/unit-test/test-continuable-regression.cpp +++ b/test/unit-test/test-continuable-regression.cpp @@ -39,7 +39,7 @@ TEST(regression_tests, are_multiple_args_mergeable) { std::make_tuple(1, 2, 3, 4)); auto count = traits::unpack(tp2, [](auto... args) { - return traits::fold(std::plus{}, args...); + return CONTINUABLE_FOLD_EXPRESSION(+, args...); }); EXPECT_EQ(count, 20); }