Call a unary function for each element of a range, traversing it along direction.
Any result from the functions is ignored.
The range to get the elements from.
(optional) The direction in which the range is traversed. If it is not given, then the default direction of the range is used.
The function to be called on each element.
Traverse a range and accumulate a value.
fold() is the equivalent of standard C++ accumulate. It is sometimes called reduce. If a range r contains elements a, b, and c, fold (f, s, r), with f a function and s the “state”, computes f (f (f (s, a), b), c). This yields a general form of iteration through a range.
For example, if there is a functor plus that calls operator+, then fold (plus, 0, r) will compute ((0 + a) + b) + c.
The state that is passed in and the return values of the function must be copy-constructible. (They are cached in the function.) The range can be noncopyable. In the default implementation, iteration is implemented with drop(), which will be passed an rvalue Range if that is passed in to fold().
The fold is homogeneous if the range is homogeneous and the function returns the same type as its first parameter. The current version requires that the fold either has finite length or becomes homogeneous at some point, otherwise it will not be able to compute the return type. (The only case for which this could be mended is if there is a limited set of return values that the function cycles between, but this does not seem a great use case.)
With homogeneous range, an obvious implementation is a loop, assigning a new value to the state each time. However, the implementation only uses move-construction and destruction.
The return type is automatically computed. Types are collapsed to some degree (using the “collapse” merge policy), and if multiple types result, the return type becomes a rime::variant. The type resulting from each step of the fold is known: the result type of the function is used exactly. However, for the initial state, no distinction can be made between an rvalue reference and a temporary. For safety, it will always be returned as a temporary, not a reference.
The initial state. This is the first argument to the first invocation of function.
The range to get the elements from.
(optional) The direction in which the range is traversed. If it is not given, then the default direction of the range is used.
The function to be called on each element.
Return a lazy “prefix sum”, i.e. all the intermediate step of an accumulation.
This is often called a “scan”, and seen as a lazy version of fold(). Like fold(), scan() takes a function, a current state, and a range. Like fold(), it applies the function to the state and the first element of the range, then to the result of that and the second element, et cetera. However, fold() performs the whole computation at once; scan() returns the intermediate values lazily.
The state passed in forms the first element of the resulting range. The second element is the result of the function applied to the start state and the range passed in. This forms the next element of the resulting range. This continues until the underlying range is empty; the last element of the range that scan() returns is the result of applying the function to each element of the underlying range. The number of elements in the resulting range is therefore one more than the number of elements in the range that is passed in.
Though the return type of “first” is a reference to the first element, the return type of “chop” has as its first element the value returned by the first function.
The initial state, i.e. the first element. This is saved exactly as qualified.
The underlying range. This will be converted into a view.
(optional) The direction of traversal of both the underlying and the resulting range. If this is not given, the default direction of the underlying range is used.
The function to be applied. This is saved exactly as qualified. Its result type is stored exactly as qualified.
Iterate through a homogeneous range.
Replace a normal for-statement by
RANGE_FOR_EACH (element, range_expression) { ... }
Here, element is the name by which each element can be referred to inside the loop. The type is computed automatically, as the exact type of first (range), including reference-qualification.
range_expression is a range, which can be an expression. The expression is executed exactly once.