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.

Reply via email to