| |
| Posted by Christian Köstlin in reply to JG | PermalinkReply |
|
Christian Köstlin
| On 2022-06-15 19:36, JG wrote:
> On Wednesday, 15 June 2022 at 17:30:31 UTC, JG wrote:
> On Wednesday, 15 June 2022 at 13:52:24 UTC, Christian Köstlin wrote:
> the naive version would look like
auto next(Range)(Range r) {
r.popFront;
return r.front;
}
But looking at a mature library e.g. https://github.com/submada/btl/blob/9cc599fd8495215d346ccd62d6e9f1f7ac140937/source/btl/vector/package.d#L229 is looks like there should be tons of annotations/attributes on it.
Kind regards,
Christian
I not sure of your use case. But you need to check if the range is empty before and after calling popFront (and decide what to if it is). Also unless you want the original range passed in mutated you should call save (assuming you have a forward range) before calling your next or you need to modify next so it calls save.
This is what I would write for next (which should only be called after
checking if the range is empty).
It produces a range whose front points at the next element.
auto next(Range)(Range r) {
auto ret = r.save;
ret.popFront;
return ret;
}
Thanks for the explanation!
I actually want to mutate the original range and I know, that there are at least 2 elements in my range.
e.g. the program
import std.stdio;
import std.range;
auto next(Range)(Range r) {
r.popFront;
return r.front;
}
int main(string[] args) {
auto i = iota(10);
writeln(i.next);
writeln(i.next);
return 0;
}
prints:
1
1
whereas
import std.stdio;
import std.range;
auto next(Range)(ref Range r) {
r.popFront;
return r.front;
}
int main(string[] args) {
auto i = iota(10);
writeln(i.next);
writeln(i.next);
return 0;
}
prints
1
2
which is what I would want. So it depends if the Range is a value or reference type ...
|