digitalmars.D.learn - how do I implement opSlice for retro range?
- Jack (48/48) May 13 2021 How can I implement ranges in the retro range? I'd like to do
- Jack (1/6) May 13 2021
- =?UTF-8?Q?Christian_K=c3=b6stlin?= (3/64) May 14 2021 arr.retro()[0..2] already works.
- Jack (2/6) May 14 2021 oh, how i silly of i didn't notice that before
- Steven Schveighoffer (21/82) May 14 2021 Just slice the `a`, appropriately. You have to translate the indexes
- Jack (3/26) May 14 2021 much easier, I'll be just using the one from std.range. Thanks!
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) { ??? } } } ```
May 13 2021
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 ```
May 13 2021
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
May 14 2021
On Friday, 14 May 2021 at 10:00:44 UTC, Christian Köstlin wrote:On 2021-05-14 05:49, Jack wrote:oh, how i silly of i didn't notice that before[...]arr.retro()[0..2] already works. see https://run.dlang.io/is/U8u3br
May 14 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
May 14 2021
On Friday, 14 May 2021 at 14:14:03 UTC, Steven Schveighoffer wrote:On 5/13/21 11:49 PM, Jack wrote:much easier, I'll be just using the one from std.range. Thanks![...]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
May 14 2021