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

Reply via email to