Skip to content

Commit

Permalink
Merge pull request #25 from tusooa/patch-4
Browse files Browse the repository at this point in the history
Make sorted and reversed constexpr
  • Loading branch information
arximboldi authored Mar 24, 2021
2 parents c580d6b + d631a7d commit b28a04c
Showing 1 changed file with 68 additions and 19 deletions.
87 changes: 68 additions & 19 deletions zug/transducer/eager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,51 @@ namespace zug {
struct eager_tag
{};

namespace detail {

template <typename Algo, typename StepT>
struct eager_reducing_func_t
{
Algo algo;
StepT step;

template <typename ContainerT>
struct tuple_maker_t
{
eager_reducing_func_t* parent;

constexpr auto operator()() const
{
return std::make_tuple(ContainerT{}, &parent->step, &parent->algo);
}
};

template <typename StateT, typename... ItemT>
constexpr auto operator()(StateT &&s, ItemT&&... is)
{
using container_t =
std::vector<std::decay_t<decltype(tuplify(is...))>>;
auto data = state_data(ZUG_FWD(s), tuple_maker_t<container_t>{this});
std::get<0>(data).push_back(tuplify(ZUG_FWD(is)...));
return wrap_state<eager_tag>(state_unwrap(ZUG_FWD(s)),
std::move(data));
}
};

template <typename Algo>
struct eager_uncomposed_transducer_t
{
Algo algo;

template <typename StepT>
constexpr auto operator()(StepT&& step) const
{
return eager_reducing_func_t<Algo, std::decay_t<StepT>>{algo, step};
};
};

}

/*!
* Transducer that processes the whole sequence with the eager algorithm
* `algo`. `algo` is a function that takes a vector as an argument a returns a
Expand All @@ -33,18 +78,7 @@ struct eager_tag
template <typename Algo>
constexpr auto eager(Algo algo)
{
return comp([=](auto&& step) {
return [=](auto&& s, auto&&... is) mutable {
using container_t =
std::vector<std::decay_t<decltype(tuplify(is...))>>;
auto data = state_data(ZUG_FWD(s), [&] {
return std::make_tuple(container_t{}, &step, &algo);
});
std::get<0>(data).push_back(tuplify(ZUG_FWD(is)...));
return wrap_state<eager_tag>(state_unwrap(ZUG_FWD(s)),
std::move(data));
};
});
return comp(detail::eager_uncomposed_transducer_t<Algo>{algo});
}

template <typename T>
Expand All @@ -57,6 +91,16 @@ decltype(auto) state_wrapper_complete(eager_tag, T&& wrapper)
std::get<0>(state_wrapper_data(std::forward<T>(wrapper)))))));
}

struct sorted_t
{
template <typename RangeT>
decltype(auto) operator()(RangeT&& range) const
{
std::sort(range.begin(), range.end());
return ZUG_FWD(range);
}
};

/*!
* Eager transducer that sorts the input sequence.
* @rst
Expand All @@ -67,10 +111,17 @@ decltype(auto) state_wrapper_complete(eager_tag, T&& wrapper)
* :dedent: 4
* @endrst
*/
auto sorted = eager([](auto&& range) -> decltype(auto) {
std::sort(range.begin(), range.end());
return ZUG_FWD(range);
});
ZUG_INLINE_CONSTEXPR auto sorted = eager(sorted_t{});


struct reversed_t
{
template <typename RangeT>
decltype(auto) operator()(RangeT&& range) const
{
return detail::make_iterator_range(range.rbegin(), range.rend());
}
};

/*!
* Eager transducer that reverses the input sequence.
Expand All @@ -82,8 +133,6 @@ auto sorted = eager([](auto&& range) -> decltype(auto) {
* :dedent: 4
* @endrst
*/
auto reversed = eager([](auto&& range) -> decltype(auto) {
return detail::make_iterator_range(range.rbegin(), range.rend());
});
ZUG_INLINE_CONSTEXPR auto reversed = eager(reversed_t{});

} // namespace zug

0 comments on commit b28a04c

Please sign in to comment.