From 16889ef3b02f107f76860c41ef056665e31c8b7f Mon Sep 17 00:00:00 2001 From: sha512sum Date: Thu, 18 Jul 2024 17:03:23 +0000 Subject: [PATCH] Fix kSeq, add default for f in LeftFold, add example for LeftFold --- examples/src/left_fold.cpp | 2 ++ include/utempl/utils.hpp | 54 +++++++++++++++++++------------------- 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/examples/src/left_fold.cpp b/examples/src/left_fold.cpp index ee67be3..f14030e 100644 --- a/examples/src/left_fold.cpp +++ b/examples/src/left_fold.cpp @@ -5,5 +5,7 @@ auto main() -> int { utempl::GetIndexesTuple<4>(), utempl::kWrapper, [](utempl::Wrapper, auto) -> utempl::Wrapper { return {}; }); + static_assert(std::is_same_v(4)>>); + static_assert(std::is_same_v(4)>&>); }; diff --git a/include/utempl/utils.hpp b/include/utempl/utils.hpp index 392a7ca..b43bf92 100644 --- a/include/utempl/utils.hpp +++ b/include/utempl/utils.hpp @@ -9,6 +9,9 @@ namespace utempl { +template +using ForwardType = decltype(std::forward(std::declval())); + template struct Wrapper { static constexpr auto kValue = Value; @@ -26,13 +29,22 @@ struct Wrapper { template inline constexpr Wrapper kWrapper; +template + requires std::same_as || requires { T{}; } +constexpr auto kDefaultCreator = [] { + return T{}; +}; + +template <> +constexpr auto kDefaultCreator = [] {}; + namespace impl { template struct kSeq { template - friend constexpr auto operator|(F&& f, const kSeq&) { - return [&](std::index_sequence) { + friend constexpr auto operator|(F&& f, const kSeq&) -> decltype(auto) { + return [&](std::index_sequence) -> decltype(auto) { return std::forward(f)(kWrapper...); }(std::make_index_sequence()); }; @@ -430,9 +442,8 @@ struct LeftFold { T data; F f; template - constexpr auto operator|(LeftFold&& other) { - using R = decltype(f(std::move(this->data), std::move(other.data))); - return LeftFold{.data = f(std::move(this->data), std::move(other.data)), .f = this->f}; + constexpr auto operator|(LeftFold&& other) -> LeftFold, F> { + return {.data = std::forward(this->f)(std::forward(this->data), std::forward(other.data)), .f = std::forward(this->f)}; }; }; @@ -447,9 +458,7 @@ template struct LeftFoldIsOk { static constexpr bool value = true; template - consteval auto operator|(LeftFoldIsOk&& other) -> LeftFoldIsOk> - requires Function - { + consteval auto operator|(LeftFoldIsOk&& other) -> LeftFoldIsOk> { return {}; }; consteval auto operator|(auto&&) -> LeftFoldIgnorer { @@ -464,24 +473,24 @@ concept LeftFoldConcept = decltype(Unpack(std::declval(), [] F> -constexpr auto LeftFold(Tuple&& tuple, T&& init, F&& f) { - return Unpack(std::forward(tuple), [&](Ts&&... args) { - return (impl::LeftFold, F>{.data = std::forward(init), .f = std::forward(f)} | ... | - impl::LeftFold>{.data = std::forward(args)}) +template F = decltype(kDefaultCreator)&> +constexpr auto LeftFold(Tuple&& tuple, T&& init, F&& f = kDefaultCreator) -> decltype(auto) { + return Unpack(std::forward(tuple), [&](Ts&&... args) -> decltype(auto) { + return (impl::LeftFold, ForwardType>{.data = std::forward(init), .f = std::forward(f)} | ... | + impl::LeftFold>{.data = std::forward(args)}) .data; }); }; template F> -constexpr auto Reduce(Tuple&& tuple, T&& init, F&& f) { +constexpr auto Reduce(Tuple&& tuple, T&& init, F&& f) -> decltype(auto) { return LeftFold(std::forward(tuple), std::forward(init), std::forward(f)); }; template -constexpr auto Reduce(T&& init, F&& f) { - return [init = std::forward(init), f = std::forward(f)](Tuple&& tuple) - requires impl::LeftFoldConcept +constexpr auto Reduce(T&& init, F&& f) -> decltype(auto) { + return [init = std::forward(init), f = std::forward(f)](Tuple&& tuple) -> decltype(auto) + requires impl::LeftFoldConcept { return Reduce(std::forward(tuple), std::move(init), std::move(f)); }; @@ -506,7 +515,7 @@ inline constexpr auto TupleCat(Tuples&&... tuples) }; template -inline constexpr auto Unpack(Tuples&&... tuples, F&& f) { +inline constexpr auto Unpack(Tuples&&... tuples, F&& f) -> decltype(Unpack(TupleCat(std::forward(tuples)...), std::forward(f))) { return Unpack(TupleCat(std::forward(tuples)...), std::forward(f)); }; @@ -680,15 +689,6 @@ constexpr auto Enumerate(Tuple&& tuple) { }); }; -template - requires std::same_as || requires { T{}; } -constexpr auto kDefaultCreator = [] { - return T{}; -}; - -template <> -constexpr auto kDefaultCreator = [] {}; - namespace impl { template