[Issue 5351] Add template mixin for Range Primitives using random access
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Mon Oct 30 20:16:55 UTC 2017
https://issues.dlang.org/show_bug.cgi?id=5351
Simen Kjaeraas <simen.kjaras at gmail.com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |simen.kjaras at gmail.com
--- Comment #3 from Simen Kjaeraas <simen.kjaras at gmail.com> ---
The implementation above will fail for this simple case:
MyRange!int a = [1,2,3];
a.popFront();
assert(a[0] == a.front);
It could be made to work for ranges that support slicing, and assignment from
the slice to the range:
void popFront() {
this = this[1..$];
}
front and empty are then trivial calls to this[0] and length == 0,
respectively.
One option that only requires opIndex and length would use a wrapper struct.
This solution would leave MyRange as a non-range, though - only its sliced
result would be a range:
struct MyRange(T) {
T[] arr;
T opIndex(size_t idx) {
return arr[idx];
}
@property
size_t length() {
return arr.length;
}
mixin rangeFuncs!();
}
template rangeFuncs() {
auto opSlice() {
alias TT = typeof(this);
struct Result {
size_t _index;
TT* _range;
auto front() {
return (*_range)[_index];
}
@property
bool empty() {
return _index == _range.length;
}
void popFront() {
_index++;
}
auto opIndex(size_t idx) {
return (*_range)[_index + idx];
}
}
Result result;
result._range = &this;
return result;
}
}
unittest {
import std.range.primitives : isInputRange;
import std.algorithm.comparison : equal;
auto a = MyRange!int([1,2,3,4]);
static assert(!isInputRange!(typeof(a)));
static assert(isInputRange!(typeof(a[])));
assert(a[].equal([1,2,3,4]));
}
In conclusion, opIndex + length is insufficient functionality to turn something
into a range.
--
More information about the Digitalmars-d-bugs
mailing list