Thanks for the insights everyone, it really helped!

I actually discovered that it wasn't working because one of the parsing functions used `std.range.take` and, since I was giving it a slice, `take` decided to save the fwdrange instead of mutating it. I realised the `take` call was 100% useless, so I removed it and it works perfectly now, and refactored to be more idiomatic :)

On Wednesday, 15 November 2017 at 21:02:35 UTC, Jonathan M Davis wrote:
If you specifically want a function to accept a range and mutate it without returning it, then it should take its argument by ref. Having it take auto ref is actually quite odd, since that means that the behavior can depend on whether an lvalue or rvalue is passed in.

I was under the impression that templated parameters needed `auto ref` to work as `ref` properly. Good to know that's not true.

On Wednesday, 15 November 2017 at 21:11:16 UTC, Steven Schveighoffer wrote:
I'd model your functions after the std.conv.parse functions:

https://dlang.org/phobos/std_conv.html#parse

This always takes the range by reference, and takes the type to parse via a template parameter (more idiomatic D to have parse!int than parseInt).

Yes, that is much more idiomatic than what I was going for. I've been writing some Java, so I guess it got to my head :)

On Wednesday, 15 November 2017 at 21:14:04 UTC, Ali Çehreli wrote:
That should work:

import std.range;

T read(T, Range)(auto ref Range range) if (isInputRange!Range) {
   range.popFront();
   return 42;
}

unittest {
   ubyte[] slice = [ 1, 2 ];
   read!int(slice);
   assert(slice == [2]);
}

void main() {
}

That is exactly what I was looking for, thanks!

Reply via email to