On Monday, 27 April 2020 at 05:06:21 UTC, anon wrote:
To implement your option A you could simply use
std.range.enumerate.
Would something like this work?
import std.algorithm.iteration : map;
import std.algorithm.searching : until;
import std.range : tee;
size_t bytesConsumed;
auto result = input.map!(a => a.yourTransformation )
.until!(stringTerminator)
.tee!(a => bytesConsumed++);
// bytesConsumed is automatically updated as result is consumed
That's interesting. Wouldn't work quite like, but something
similar would, but I don't think it quite achieves what I want.
One thing that's missing is that the initial input is simply a
string, there's nothing to map over at that point. There is
however a transformation step that transforms the string into a
sequence of slices. Then there's a transformation on those
slices. That would be a step prior to the 'map' step. Also, in my
case 'map' cannot be used, because each slice may produce
multiple outputs.
The specifics are minor details, not really so important. The
implementation can take a form along the lines described.
However, structuring like this exposes the details of these steps
to all callers. That is, all callers would have to write the code
above.
My goal is encapsulate the steps into a single range all callers
can use. That is, encapsulate something like the steps you have
above in a standalone range that takes the input string as an
argument, produces all the output elements, and preserves the
bytesConsumed in a way the caller can access it.