On 5/13/21 11:49 PM, Jack wrote:
How can I implement ranges in the retro range? I'd like to do this
without allocate a new array with .array from std.array, can I do that?
use like this:
```d
auto arr = [1, 2, 3, 4, 5];
auto a = new A!int(arr);
auto b = a.retro[0 .. 2]; // 4, 5
```
the class:
```d
class A(T)
{
private T[] arr;
this(T[] a)
{
arr = a;
}
auto opIndex() nothrow
{
return Range(arr);
}
auto retro() { return RangeRetro(arr); }
protected static struct Range
{
T[] a;
T front() { return a[0]; }
T back() { return a[$ - 1]; }
void popFront() { a = a[1 .. $]; }
bool empty() { return a.length == 0; }
}
protected static struct RangeRetro
{
import std.range : popFront;
import std.range : popBack;
T[] a;
T front() { return a[$ - 1]; }
T back() { return a[0]; }
void popBack() { a.popFront(); }
void popFront() { a.popBack(); }
bool empty() { return a.length == 0; }
auto opSlice(size_t start, size_t end)
{
???
}
}
}
```
Just slice the `a`, appropriately. You have to translate the indexes
back into the original array.
```d
auto opSlice(size_t start, size_t end)
{
return typeof(this)(a[$ - end .. $ - start]);
}
```
You should also define `length`, `save`, `opIndex`, and `opDollar` so
that it fits in the range hierarchy as a proper random-access range.
But I question whether you shouldn't just use `std.range.retro`
directly? It does all this for you:
```d
// inside A
auto retro() {
import std.range : retro;
return arr.retro;
}
```
-Steve