From 2db590a88f67cfa344b4d93b54029d379df7092e Mon Sep 17 00:00:00 2001 From: nickpdemarco Date: Fri, 23 Feb 2024 13:10:16 -0500 Subject: [PATCH 1/2] Attempt 1: move declval into decltype only, take args in result_type_helper --- test/initial_draft.cpp | 41 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/test/initial_draft.cpp b/test/initial_draft.cpp index c7eb283..f38cec3 100644 --- a/test/initial_draft.cpp +++ b/test/initial_draft.cpp @@ -13,6 +13,8 @@ #include #include +#define STLAB_FWD(x) std::forward(x) + /* If exception inside of a segment _apply_ function throws an exception then the exception must be @@ -92,6 +94,16 @@ class segment { } }; +namespace detail { + +/// Apply a recursive lambda to each element in the tuple-like Segments. +template +constexpr auto fold_over(Fold fold, Segments&& segments) { + return std::apply([fold](auto&&... links) { return fold(fold, STLAB_FWD(links)...); }, STLAB_FWD(segments)); +} + +} // namespace detail + template using segment_result_type = decltype(std::declval().result_type_helper(std::declval()...)); @@ -100,32 +112,16 @@ using segment_result_type = simplify this code by handing the multi-argument case earlier (somehow). */ -#define STLAB_FWD(x) std::forward(x) - template class chain { Tail _tail; segment _head; - /// Apply a recursive lambda to each element in _tail, followed by _head. - template - auto fold_over(F fold) && { - return std::apply([fold](auto&&... links) { return fold(fold, STLAB_FWD(links)...); }, - std::tuple_cat(std::move(_tail), std::tuple(std::move(_head)))); - } - - template - static consteval auto static_fold_over(F fold) { - return std::apply([fold](auto&&... links) { return fold(fold, STLAB_FWD(links)...); }, - std::tuple_cat(std::declval(), - std::tuple(std::declval>()))); - } - /// Return a lambda with the signature of /// head( tail( tail<1>( tail<0>( auto&& args... ) ) ) ) /// for computing the result type of this chain. - static consteval auto result_type_helper() { - return static_fold_over([](auto fold, auto&& first, auto&&... rest) { + static consteval auto result_type_helper(Tail&& tail, segment&& head) { + return detail::fold_over([](auto fold, auto&& first, auto&&... rest) { if constexpr (sizeof...(rest) == 0) { return [_segment = STLAB_FWD(first)](auto&&... args) mutable { return std::move(_segment).result_type_helper(STLAB_FWD(args)...); @@ -136,12 +132,12 @@ class chain { return std::move(_segment).result_type_helper(STLAB_FWD(args)...); }; } - }); + }, std::tuple_cat(std::move(tail), std::tuple{std::move(head)})); } template auto expand(const R& receiver) && { - return std::move(*this).fold_over([receiver](auto fold, auto&& first, auto&&... rest) { + return detail::fold_over([receiver](auto fold, auto&& first, auto&&... rest) { if constexpr (sizeof...(rest) == 0) { return [receiver, _segment = STLAB_FWD(first).append(receiver)](auto&&... args) mutable { @@ -153,12 +149,13 @@ class chain { return std::move(_segment).invoke(receiver, STLAB_FWD(args)...); }; } - }); + }, std::tuple_cat(std::move(_tail), std::tuple{std::move(_head)})); } public: template - using result_type = decltype(result_type_helper()(std::declval()...)); + using result_type = + decltype(result_type_helper(std::declval(), std::declval>())(std::declval()...)); explicit chain(Tail&& tail, segment&& head) : _tail{std::move(tail)}, _head{std::move(head)} {} From dd7a22cf5ea522cb4cd65adcec3d4afedfbcfc1a Mon Sep 17 00:00:00 2001 From: Clang Robot Date: Fri, 23 Feb 2024 18:11:18 +0000 Subject: [PATCH 2/2] :art: Committing clang-format changes --- test/initial_draft.cpp | 61 +++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/test/initial_draft.cpp b/test/initial_draft.cpp index f38cec3..339ea8a 100644 --- a/test/initial_draft.cpp +++ b/test/initial_draft.cpp @@ -99,7 +99,8 @@ namespace detail { /// Apply a recursive lambda to each element in the tuple-like Segments. template constexpr auto fold_over(Fold fold, Segments&& segments) { - return std::apply([fold](auto&&... links) { return fold(fold, STLAB_FWD(links)...); }, STLAB_FWD(segments)); + return std::apply([fold](auto&&... links) { return fold(fold, STLAB_FWD(links)...); }, + STLAB_FWD(segments)); } } // namespace detail @@ -121,41 +122,45 @@ class chain { /// head( tail( tail<1>( tail<0>( auto&& args... ) ) ) ) /// for computing the result type of this chain. static consteval auto result_type_helper(Tail&& tail, segment&& head) { - return detail::fold_over([](auto fold, auto&& first, auto&&... rest) { - if constexpr (sizeof...(rest) == 0) { - return [_segment = STLAB_FWD(first)](auto&&... args) mutable { - return std::move(_segment).result_type_helper(STLAB_FWD(args)...); - }; - } else { - return [_segment = STLAB_FWD(first).append(fold(fold, STLAB_FWD(rest)...))]( - auto&&... args) mutable { - return std::move(_segment).result_type_helper(STLAB_FWD(args)...); - }; - } - }, std::tuple_cat(std::move(tail), std::tuple{std::move(head)})); + return detail::fold_over( + [](auto fold, auto&& first, auto&&... rest) { + if constexpr (sizeof...(rest) == 0) { + return [_segment = STLAB_FWD(first)](auto&&... args) mutable { + return std::move(_segment).result_type_helper(STLAB_FWD(args)...); + }; + } else { + return [_segment = STLAB_FWD(first).append(fold(fold, STLAB_FWD(rest)...))]( + auto&&... args) mutable { + return std::move(_segment).result_type_helper(STLAB_FWD(args)...); + }; + } + }, + std::tuple_cat(std::move(tail), std::tuple{std::move(head)})); } template auto expand(const R& receiver) && { - return detail::fold_over([receiver](auto fold, auto&& first, auto&&... rest) { - if constexpr (sizeof...(rest) == 0) { - return [receiver, - _segment = STLAB_FWD(first).append(receiver)](auto&&... args) mutable { - return std::move(_segment).invoke(receiver, STLAB_FWD(args)...); - }; - } else { - return [receiver, _segment = STLAB_FWD(first).append( - fold(fold, STLAB_FWD(rest)...))](auto&&... args) mutable { - return std::move(_segment).invoke(receiver, STLAB_FWD(args)...); - }; - } - }, std::tuple_cat(std::move(_tail), std::tuple{std::move(_head)})); + return detail::fold_over( + [receiver](auto fold, auto&& first, auto&&... rest) { + if constexpr (sizeof...(rest) == 0) { + return [receiver, + _segment = STLAB_FWD(first).append(receiver)](auto&&... args) mutable { + return std::move(_segment).invoke(receiver, STLAB_FWD(args)...); + }; + } else { + return [receiver, _segment = STLAB_FWD(first).append( + fold(fold, STLAB_FWD(rest)...))](auto&&... args) mutable { + return std::move(_segment).invoke(receiver, STLAB_FWD(args)...); + }; + } + }, + std::tuple_cat(std::move(_tail), std::tuple{std::move(_head)})); } public: template - using result_type = - decltype(result_type_helper(std::declval(), std::declval>())(std::declval()...)); + using result_type = decltype(result_type_helper( + std::declval(), std::declval>())(std::declval()...)); explicit chain(Tail&& tail, segment&& head) : _tail{std::move(tail)}, _head{std::move(head)} {}