Header lexy/callback.hpp
Callbacks that receive the values produced during parsing and process them.
Callback
lexy/callback.hpp
namespace lexy
{
template <typename T>
concept callback = requires { typename T::return_type; }
template <typename T>
constexpr bool is_callback = callback<T>;
template <typename T, typename ... Args>
concept callback-for = callback<T>
&& requires(const T& cb, Args&&... args) {
{ cb(std::forward<Args>(args)...) }
-> std::same_as<typename T::return_type>;
};
template <typename T, typename ... Args>
constexpr bool is_callback_for = callback-for<T, Args..>;
template <typename T, typename State, typename ... Args>
concept callback-with-state = callback<T>
&& requires(const T& cb, State& state) {
{ cb[state](std::forward<Args>(args)...) }
-> std::same_as<typename T::return_type>;
};
template <typename T, typename State>
constexpr bool is_callback_state
= callback-with-state<T, State, some-arguments...>;
}
A callback is a function object with a return_type
typedef that specifies its return type.
The callback can have multiple overloads of operator()
, but all of them must return the same type.
To be usable in the grammar, a callback must not have any mutable state.
A callback can optionally take a state.
This is an additional parameter that is passed via operator[]
in addition to all the arguments.
During parsing, the callback arguments are the values produced by the rules while the state parameter is the parse state.
Sink
lexy/callback.hpp
namespace lexy
{
template <typename T>
concept sink-callback = requires (T& cb) {
typename T::return_type;
// there exist some args... with:
{ cb(args...) } -> std::same_as<void>;
{ std::move(cb).finish() } -> std::same_as<typename T::return_type>;
};
template <typename T, typename ... Args>
concept sink = requires (const T& s, Args&&... args) {
{ s.sink(std::forward<Args>(args)...) } -> sink-callback;
};
template <typename T, typename... Args>
constexpr bool is_sink = sink<T, Args...>;
template <typename Sink, typename... Args>
using sink_callback = /* return type of .sink(Args...) /;
template <typename T, typename ... Args>
constexpr bool is_sink_callback_for
= / T is a sink callback that can be invoked with Args... */;
}
A sink is an object with a sink()
member function that returns a sink callback, which is a callback that can be invoked multiples times before producing the final value.
The sink()
member function can take arbitrary arguments to construct the sink callback.
This is used to e.g. pass allocator parameters to a container’s constructor.
During parsing, sink()
is passed the parse state, if it accepts it, otherwise it is invoked without arguments.
The sink callback can be invoked with some arguments, and will somehow append them to the result.
Calling finish()
on the sink callback will return the finished result.
Once finish()
has been called, the sink callback is never used again.
During parsing, the sink callback is repeatedly invoked by values produced during a list rule.
Pre-defined callbacks and sinks
Adapters and composition
lexy::callback
Turn an overload set of function objects into a callback.
lexy::mem_fn
Turn a member function/data pointer into a callback.
lexy::operator|
andlexy::operator>>
Combine callbacks and sinks.
lexy::bind
andlexy::bind_sink
Bind parameters and reorder and transform arguments of a callback or sink.
lexy::fold
andlexy::fold_inplace
Fold over all arguments of a sink.
Primitives
lexy::noop
Do nothing.
lexy::constant
Produce a constant value.
lexy::forward
Forward an existing value unchanged.
lexy::construct
andlexy::new_
Construct a new object.
lexy::bit_cast
Constructs a new object by reinterpreting the bits of an existing one.
Rule specific
lexy::as_integer
Produce a (signed) integer value.
lexy::as_string
Produce a string.
lexy::as_list
andlexy::as_collection
Produce a container from all list items.
lexy::as_aggregate
Produce an aggregate by setting the specified members.