Header lexy/callback/fold.hpp
Sinks that fold over the items.
Sink lexy::fold
lexy/callback/fold.hppnamespace lexy
{
template <typename T, typename Arg = T, typename ... Op>
constexpr sink<> auto fold(Arg&& init, Op&& ... op);
}Sink that folds over all arguments.
When sink() is called, creates a T result by constructing it from T(init), if that is well-formed, and invoking init() otherwise.
Every time the sink callback is invoked, folds the arguments via result = std::invoke(make-overloaded(op…), std::move(result), args…).
The final value of result is returned by finish().
struct production
{
static constexpr auto whitespace = dsl::ascii::space;
static constexpr auto rule = [] {
// An item is a point (x, y)
auto integer = dsl::integer<int>;
auto item = dsl::parenthesized(dsl::twice(integer, dsl::sep(dsl::comma)));
return dsl::list(item, dsl::sep(dsl::comma));
}();
// Sum the x components of the points.
static constexpr auto value
= lexy::fold<int>(0, [](int current, int x, int) { return current + x; });
};Note | Usually with fold algorithms, op is a binary function.
As the operator() of the sink callback can take arbitrary arguments, this is not necessarily the case here.
The first argument will always be the current result, all other arguments are received from the sink callback. |
Tip | Use lexy::callback to use fold as a callback. |
Sink lexy::fold_inplace
lexy/callback/fold.hppnamespace lexy
{
template <typename T, typename Arg = T, typename ... Op>
constexpr sink<> auto fold_inplace(Arg&& init, Op&& ... op);
}Sink that folds over all arguments, modifying the current value.
When sink() is called, creates a T result by constructing it from T(init), if that is well-formed, and invoking init() otherwise.
Every time the sink callback is invoked, folds the arguments via std::invoke(make-overloaded(op…), result, args…),
expecting that op modifies result to the new value.
The final value of result is returned by finish().
struct production
{
static constexpr auto whitespace = dsl::ascii::space;
static constexpr auto rule = [] {
auto integer = dsl::integer<int>;
return dsl::list(integer, dsl::sep(dsl::comma));
}();
// Construct a `std::deque` in reverse order.
static constexpr auto value
= lexy::fold_inplace<std::deque<int>>(std::initializer_list<int>{},
[](auto& deque, int i) { deque.push_front(i); });
};Note | lexy::fold accepts operator+, lexy::fold_inplace accepts operator+=. |
Sink lexy::count
lexy/callback/fold.hppnamespace lexy
{
constexpr sink<> auto count =
= fold_inplace<std::size_t>(0, [](std::size_t& result, auto&&...) { ++result; });
}Counts the number of invocation of the sink callback.
It is entirely equivalent to the lexy::fold_inplace call specified above.