State

In the Design section we say how a transducer may extend the state from the reducing function. Not only does this allow it to include feedback in the process, but also to signal to process whether the computation has terminated.

This section describes the abstract interface that comunicates between the state and the reducing process, and also the concrete state wrapping utilities provided for transducer implementors.

state_traits

using state_traits_t = state_traits<std::decay_t<T>>
template <typename T>
decltype(auto) zug::state_complete(T && s)

Convenience function for calling state_traits::complete

template <typename T>
bool zug::state_is_reduced(T &&s)

Convenience function for calling state_traits::is_reduced

template <typename T, typename D>
decltype(auto) zug::state_data(T && s, D && d)

Convenience function for calling state_traits::data

template <typename T>
decltype(auto) zug::state_unwrap(T && s)

Convenience function for calling state_traits::unwrap

template <typename T>
decltype(auto) zug::state_unwrap_all(T && s)

Convenience function for calling state_traits::unwrap_all

template <typename T, typename U>
decltype(auto) zug::state_rewrap(T && s, U && x)

Convenience function for calling state_traits::unwrap_all

template <typename StateT>
struct zug::state_traits

Interface for a type specializing the State concept.

A State is the first parameter of a reducing function, also known as the accumulator. Every type is a model of State, with the following default implementation. However, one might want to specialize the state it for a particular accumulator type, such that transducers can operate with it. A transducer should not make assumptions about the state it receives, instead, it can only wrap it using wrap_state to attach additional data.

For an example of a stateful reducing function, see take.

state_wrapper

template <typename TagT = no_tag, typename StateT, typename DataT = TagT>
auto zug::wrap_state(StateT &&next, DataT &&data = DataT{})

Given a tag TagT and a state next and associated data, returns a state_wrapper instance.

template <typename TagT, typename T>
decltype(auto) zug::state_wrapper_unwrap(TagT, T && s)

Utility function for easy overloading of state_traits::unwrap for state wrappers with a specific tag.

template <typename TagT, typename T>
decltype(auto) zug::state_wrapper_complete(TagT, T && s)

Utility function for easy overloading of state_traits::complete for state wrappers with a specific tag.

template <typename TagT, typename T>
decltype(auto) zug::state_wrapper_unwrap_all(TagT, T && s)

Utility function for easy overloading of state_traits::unwrap_all for state wrappers with a specific tag.

template <typename TagT, typename T, typename U>
decltype(auto) zug::state_wrapper_rewrap(TagT, T && s, U && x)

Utility function for easy overloading of state_traits::rewrap for state wrappers with a specific tag.

template <typename TagT, typename T, typename D>
decltype(auto) zug::state_wrapper_data(TagT tag, T && s, D &&)

Utility function for easy overloading of state_traits::data for state wrappers with a specific tag.

template <typename T>
decltype(auto) zug::state_wrapper_data(T && s)
template <typename TagT, typename T>
decltype(auto) zug::state_wrapper_data(TagT, T && s)
template <typename TagT, typename DataT>
bool zug::state_wrapper_data_is_reduced(TagT, DataT&&)

Utility function that returns whether the DataT associated with a state wrapper with tag TagT is reduced i.e. idempotent. Can be overloaded custom tags.

template <typename TagT, typename T>
bool zug::state_wrapper_is_reduced(TagT tag, T &&s)

Utility function for easy overloading of state_traits::is_reduced for state wrappers with a specific tag. Most of the time you may want to overload state_wrapper_is_reduced instead.

struct zug::no_tag

Default tag for state_wrapper.

template <typename TagT = no_tag, typename StateT = void, typename DataT = void>
struct zug::state_wrapper

A decorator for the accumulator of a reduction.

A transducer must not make any assumptions about the accumulator of the process it is helping to reduce. However, a stateful transducer may use a state_wrapper to attach extra data to the accumulator such that the reducing function object itself can be state-less.

A state wrapper has the following template arguments:

For an example of a stateful reducing function, see take.

Template Parameters
  • TagT: is as tag type used to identify the transducer that is attaching the state. This can useful to specialize the state_traits for a concrete state wrapper.
  • StateT: is the accumulator that is to be wrapped and of which we shall make no assumptions.
  • DataT: is the additional data that the transducer wants to attach to represent its own state.

template <typename StateT, typename DecayedT = std::decay_t<StateT>>
struct zug::is_state_wrapper

Metafunction returning whether StateT is a, or reference to, a state_wrapper instantiation.

template <typename _, typename T, typename S, typename D>
template<>
struct zug::is_state_wrapper<_, state_wrapper<T, S, D>>
template <typename TagT, typename StateT, typename DataT>
template<>
struct zug::state_traits<state_wrapper<TagT, StateT, DataT>>

State traits specialization for state_wrapper. Just forwards to the state_wrapper_* methods, that are easier to specialize for a given tag.

with_state

template <typename StateT, typename UnwrappedFn, typename WrappedFn>
auto zug::with_state(StateT &&st, UnwrappedFn &&fn, WrappedFn &&fn)

Given a value st that represents the state of a reduction, this function generically dispatches to the right function UnwrappedFn or WrappedFn, depending of whether the value is already wrapped or not. This is, during the first iteration of the reduction, UnwrappedFn will be called, from then on, WrappedFnT will be called.

The signatures should be of the form:

  • UnwrappedFn : A -> B
  • WrappedFn : B -> B

This function can dispatch both statically and dynamically in a transparent way. It is thus very useful for writing stateful transducers that can be type erased in a transducer<> object.

maybe_reduced

using maybe_reduced = state_wrapper<maybe_reduced_tag, T, bool>

State wrapper for transducers that may want to signal that the reduction is finished.

bool zug::state_wrapper_data_is_reduced(maybe_reduced_tag, bool is_reduced)
template <typename T>
auto zug::reduced_if(T &&x, bool is_reduced)

Wraps x in a maybe_reduced, where is_reduced contains whether the reduction should actually finish.

template <typename T>
decltype(auto) zug::reduced(T && x)

Wraps x such that the reduction should finish.

template <typename T>
decltype(auto) zug::not_reduced(T && x)

Wraps x such that the reduction should continue.

struct zug::maybe_reduced_tag

Tag for maybe_reduced state wrapper.

any_state

class zug::any_state

Polymorphically holds any value implementing the state_traits. This type is used for the implementation of transducer.