how do I implement opSlice for retro range?
Steven Schveighoffer
schveiguy at gmail.com
Fri May 14 14:14:03 UTC 2021
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
More information about the Digitalmars-d-learn
mailing list