@@ -2124,9 +2124,9 @@ auto stride(T)(T withAsSlice, ptrdiff_t factor)
2124
2124
/+ +
2125
2125
Reverses order of iteration for all dimensions.
2126
2126
Params:
2127
- slice = Unpacked slice.
2127
+ slice = slice, range, or array .
2128
2128
Returns:
2129
- Slice with reversed order of iteration for all dimensions.
2129
+ Slice/range with reversed order of iteration for all dimensions.
2130
2130
See_also: $(SUBREF dynamic, reversed), $(SUBREF dynamic, allReversed).
2131
2131
+/
2132
2132
auto retro
@@ -2184,6 +2184,80 @@ auto retro(T)(T withAsSlice)
2184
2184
return retro (withAsSlice.asSlice);
2185
2185
}
2186
2186
2187
+
2188
+ // / ditto
2189
+ auto retro (Range )(Range r)
2190
+ if (! hasAsSlice! Range && ! isSlice! Range && ! is (Range : T[], T))
2191
+ {
2192
+ import std.traits : Unqual;
2193
+
2194
+ static if (is (Unqual! Range == Range ))
2195
+ {
2196
+ import core.lifetime : move;
2197
+ static if (is (Range : RetroRange! R, R))
2198
+ {
2199
+ return move (r._source);
2200
+ }
2201
+ else
2202
+ {
2203
+ return RetroRange! Range (move(r));
2204
+ }
2205
+ }
2206
+ else
2207
+ {
2208
+ return .retro! (Unqual! Range )(r);
2209
+ }
2210
+ }
2211
+
2212
+ // / ditto
2213
+ struct RetroRange (Range )
2214
+ {
2215
+ import mir.primitives: hasLength;
2216
+
2217
+ // /
2218
+ Range _source;
2219
+
2220
+ private enum hasAccessByRef = __traits(compiles, &_source.front);
2221
+
2222
+ @property
2223
+ {
2224
+ bool empty ()() const { return _source.empty; }
2225
+ static if (hasLength! Range )
2226
+ auto length ()() const { return _source.length; }
2227
+ auto ref front ()() { return _source.back; }
2228
+ auto ref back ()() { return _source.front; }
2229
+ static if (__traits(hasMember, Range , " save" ))
2230
+ auto save ()() { return RetroRange(_source.save); }
2231
+ alias opDollar = length;
2232
+
2233
+ static if (! hasAccessByRef)
2234
+ {
2235
+ import std.traits : ForeachType;
2236
+
2237
+ void front ()(ForeachType! R val)
2238
+ {
2239
+ import mir.functional: forward;
2240
+ _source.back = forward! val;
2241
+ }
2242
+
2243
+ void back ()(ForeachType! R val)
2244
+ {
2245
+ import mir.functional: forward;
2246
+ _source.front = forward! val;
2247
+ }
2248
+ }
2249
+ }
2250
+
2251
+ void popFront ()() { _source.popBack(); }
2252
+ void popBack ()() { _source.popFront(); }
2253
+
2254
+ static if (is (typeof (_source.moveBack())))
2255
+ auto moveFront ()() { return _source.moveBack(); }
2256
+
2257
+ static if (is (typeof (_source.moveFront())))
2258
+ auto moveBack ()() { return _source.moveFront(); }
2259
+ }
2260
+
2187
2261
// /
2188
2262
@safe pure nothrow @nogc version(mir_test) unittest
2189
2263
{
@@ -2198,6 +2272,16 @@ auto retro(T)(T withAsSlice)
2198
2272
static assert (is (typeof (slice.universal.retro) == typeof (slice.universal)));
2199
2273
}
2200
2274
2275
+ // / Ranges
2276
+ @safe pure nothrow @nogc version(mir_test) unittest
2277
+ {
2278
+ import mir.algorithm.iteration: equal;
2279
+ import std.range : std_iota = iota;
2280
+
2281
+ assert (std_iota(4 ).retro.equal(iota(4 ).retro));
2282
+ static assert (is (typeof (std_iota(4 ).retro.retro) == typeof (std_iota(4 ))));
2283
+ }
2284
+
2201
2285
/+ +
2202
2286
Bitwise slice over an integral slice.
2203
2287
Params:
@@ -3308,6 +3392,20 @@ template as(T)
3308
3392
{
3309
3393
return as (withAsSlice.asSlice);
3310
3394
}
3395
+
3396
+ // / ditto
3397
+ auto as (Range )(Range r)
3398
+ if (! hasAsSlice! Range && ! isSlice! Range && ! is (Range : T[], T))
3399
+ {
3400
+ static if (is (ForeachType! Range == T))
3401
+ return r;
3402
+ else
3403
+ {
3404
+ import core.lifetime : move;
3405
+ import mir.conv: to;
3406
+ return map! (to! T)(r.move);
3407
+ }
3408
+ }
3311
3409
}
3312
3410
3313
3411
// /
@@ -3341,6 +3439,13 @@ template as(T)
3341
3439
Slice! (const (double )* , 2 ) const_matrix = matrix.as! (const double );
3342
3440
}
3343
3441
3442
+ // / Ranges
3443
+ @safe pure nothrow version(mir_test) unittest
3444
+ {
3445
+ import mir.algorithm.iteration: filter, equal;
3446
+ assert (5. iota.filter! " a % 2" .as! double .map! " a / 2" .equal([0.5 , 1.5 ]));
3447
+ }
3448
+
3344
3449
/+ +
3345
3450
Takes a field `source` and a slice `indexes`, and creates a view of source as if its elements were reordered according to indexes.
3346
3451
`indexes` may include only a subset of the elements of `source` and may also repeat elements.
0 commit comments