Function std.range.tee
Implements a "tee" style pipe, wrapping an input range so that elements of the
range can be passed to a provided function or OutputRange
as they are
iterated over. This is useful for printing out intermediate values in a long
chain of range code, performing some operation with side-effects on each call
to front
or popFront
, or diverting the elements of a range into an
auxiliary OutputRange
.
auto auto tee(Flag!("pipeOnPop") pipeOnPop = Yes .pipeOnPop, R1, R2)
(
R1 inputRange,
R2 outputRange
)
if (isInputRange!R1 && isOutputRange!(R2, ElementType!R1));
auto auto tee(alias fun, Flag!("pipeOnPop") pipeOnPop = Yes .pipeOnPop, R1)
(
R1 inputRange
)
if (is(typeof(fun) == void) || isSomeFunction!fun);
It is important to note that as the resultant range is evaluated lazily,
in the case of the version of tee
that takes a function, the function
will not actually be executed until the range is "walked" using functions
that evaluate ranges, such as array
or
fold
.
Parameters
Name | Description |
---|---|
pipeOnPop | If Yes , simply iterating the range without ever
calling front is enough to have tee mirror elements to outputRange (or,
respectively, fun ). Note that each popFront() call will mirror the
old front value, not the new one. This means that the last value will
not be forwarded if the range isn't iterated until empty. If
No , only elements for which front does get called will be
also sent to outputRange /fun . If front is called twice for the same
element, it will still be sent only once. If this caching is undesired,
consider using map instead. |
inputRange | The input range being passed through. |
outputRange | This range will receive elements of inputRange progressively
as iteration proceeds. |
fun | This function will be called with elements of inputRange
progressively as iteration proceeds. |
Returns
An input range that offers the elements of inputRange
. Regardless of
whether inputRange
is a more powerful range (forward, bidirectional etc),
the result is always an input range. Reading this causes inputRange
to be
iterated and returns its elements in turn. In addition, the same elements
will be passed to outputRange
or fun
as well.
See Also
Example
import std .algorithm .comparison : equal;
import std .algorithm .iteration : filter, map;
// Sum values while copying
int[] values = [1, 4, 9, 16, 25];
int sum = 0;
auto newValues = values .tee!(a => sum += a) .array;
assert(equal(newValues, values));
writeln(sum); // 1 + 4 + 9 + 16 + 25
// Count values that pass the first filter
int count = 0;
auto newValues4 = values .filter!(a => a < 10)
.tee!(a => count++)
.map!(a => a + 1)
.filter!(a => a < 10);
//Fine, equal also evaluates any lazy ranges passed to it.
//count is not 3 until equal evaluates newValues4
assert(equal(newValues4, [2, 5]));
writeln(count); // 3
Authors
Andrei Alexandrescu, David Simcha, Jonathan M Davis, and Jack Stouffer. Credit for some of the ideas in building this module goes to Leonardo Maffi.