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