On Wednesday, 23 March 2016 at 03:17:05 UTC, Hanh wrote:
Thanks for your help everyone.

I agree that the issue is due to the misusage of an InputRange but what is the semantics of 'take' when applied to an InputRange? It seems that calling it invalidates the range; in which case what is the recommended way to get a few bytes and keep on advancing.

Doing *anything* to a range invalidates it (or at least you should expect it to), a range is read-once. Never reuse a range. Some ranges can be saved in order to use a copy of it, but never expect a range to be implicitely reusable.

For instance, to read a ushort, I use
range.read!(ushort)()
Unfortunately, it reads a single value.

For now, I use a loop

foreach (element ; range.enumerate) {
  buffer[i] = range.front;
  range.popFront();
  }

Is there a more idiomatic way to do the same thing?

Two ways, the first one being for reference:

    import std.range: enumerate;
    foreach (element, index ; range.enumerate) {
        buffer[index] = element;
    }

And the other one

In Scala, 'take' consumes bytes from the iterator. So the same code would be
buffer = range.take(N).toArray

Then just do that!

    import std.range, std.array;
    auto buffer = range.take(N).array;

    auto example = iota(0, 200, 5).take(5).array;
    assert(example == [0, 5, 10, 15, 20]);

Reply via email to