Header lexy/callback/fold.hpp
Sinks that fold over the items.
Sink lexy::fold
lexy/callback/fold.hpp
namespace 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.hpp
namespace 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.hpp
namespace 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.