Re: how do I implement opSlice for retro range?

2021-05-14 Thread Jack via Digitalmars-d-learn
On Friday, 14 May 2021 at 14:14:03 UTC, Steven Schveighoffer 
wrote:

On 5/13/21 11:49 PM, Jack wrote:

[...]


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


much easier, I'll be just using the one from std.range. Thanks!


Re: how do I implement opSlice for retro range?

2021-05-14 Thread Jack via Digitalmars-d-learn

On Friday, 14 May 2021 at 10:00:44 UTC, Christian Köstlin wrote:

On 2021-05-14 05:49, Jack wrote:

[...]

arr.retro()[0..2] already works.

see https://run.dlang.io/is/U8u3br


oh, how i silly of i didn't notice that before


Re: how do I implement opSlice for retro range?

2021-05-14 Thread Steven Schveighoffer via Digitalmars-d-learn

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


Re: how do I implement opSlice for retro range?

2021-05-14 Thread Christian Köstlin via Digitalmars-d-learn

On 2021-05-14 05:49, 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)
     {
    ???
     }
     }
}
```



arr.retro()[0..2] already works.

see https://run.dlang.io/is/U8u3br



Re: how do I implement opSlice for retro range?

2021-05-13 Thread Jack via Digitalmars-d-learn

sorry, in this code i mean b must be [5, 4]



```d
auto arr = [1, 2, 3, 4, 5];
auto a = new A!int(arr);
auto b = a.retro[0 .. 2]; //5,4
```






how do I implement opSlice for retro range?

2021-05-13 Thread Jack via Digitalmars-d-learn
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)
{
   ???
}
}
}
```