@@ -109,7 +109,6 @@ T4=$(TR $(TDNW $(LREF $1)) $(TD $2) $(TD $3) $(TD $4))
109109+/
110110module mir.ndslice.topology ;
111111
112- import std.meta ;
113112
114113import mir.internal.utility;
115114import mir.math.common: optmath;
@@ -121,6 +120,7 @@ import mir.ndslice.slice;
121120import mir.primitives;
122121import mir.qualifier;
123122import mir.utility: min;
123+ import std.meta : AliasSeq, allSatisfy, staticMap, templateOr, Repeat;
124124
125125private immutable choppedExceptionMsg = " bounds passed to chopped are out of sliceable bounds." ;
126126version (D_Exceptions) private immutable choppedException = new Exception (choppedExceptionMsg);
@@ -3928,7 +3928,7 @@ Returns a slice that can be iterated along dimension. Transposes other dimension
39283928Combines $(LREF byDim) and $(LREF evertPack).
39293929
39303930Params:
3931- Dimensions = dimensions to iterate along, length of d, `1 <= d < n`
3931+ SDimensions = dimensions to iterate along, length of d, `1 <= d < n`. Negative dimensions are supported.
39323932Returns:
39333933 `(n-d)`-dimensional slice composed of d-dimensional slices
39343934See_also:
@@ -3938,15 +3938,11 @@ See_also:
39383938 $(LREF ipack),
39393939 $(SUBREF dynamic, transposed).
39403940+/
3941- template alongDim (Dimensions ... )
3942- if (Dimensions .length > 0 )
3941+ template alongDim (SDimensions ... )
3942+ if (SDimensions .length > 0 )
39433943{
3944- import mir.ndslice.internal : isSize_t;
3945- import std.meta : allSatisfy;
3946-
3947- static if (allSatisfy! (isSize_t, Dimensions))
3944+ static if (allSatisfy! (isSizediff_t, SDimensions))
39483945 {
3949- import mir.ndslice.slice : Slice, SliceKind;
39503946 /+ +
39513947 Params:
39523948 slice = input n-dimensional slice, n > d
@@ -3955,30 +3951,15 @@ template alongDim(Dimensions...)
39553951 +/
39563952 @optmath auto alongDim(Iterator, size_t N, SliceKind kind)
39573953 (Slice! (Iterator, N, kind) slice)
3958- if (N > Dimensions .length)
3954+ if (N > SDimensions .length)
39593955 {
3960- import mir.ndslice.topology : ipack;
3961- import mir.ndslice.internal : DimensionsCountCTError;
3962-
3963- mixin DimensionsCountCTError;
3964-
3965- static if (N == 1 )
3966- {
3967- return slice;
3968- }
3969- else
3970- {
3971- import core.lifetime : move;
3972- return slice.move.byDim! Dimensions.evertPack;
3973- }
3956+ import core.lifetime : move;
3957+ return slice.move.byDim! SDimensions.evertPack;
39743958 }
39753959 }
39763960 else
39773961 {
3978- import std.meta : staticMap;
3979- import mir.ndslice.internal : toSize_t;
3980-
3981- alias alongDim = .alongDim! (staticMap! (toSize_t, Dimensions));
3962+ alias alongDim = .alongDim! (staticMap! (toSizediff_t, SDimensions));
39823963 }
39833964}
39843965
@@ -4006,7 +3987,7 @@ version(mir_test) unittest
40063987 // | 4 5 6 7 |
40073988 // | 8 9 10 11 |
40083989 // ------------
4009- auto x = slice.alongDim! 1 ;
3990+ auto x = slice.alongDim! ( - 1 ); // -1 is the last dimension index, the same as 1 for this case.
40103991 static assert (is (typeof (x) == Slice! (SliceIterator! (IotaIterator! sizediff_t ), 1 , Universal)));
40113992
40123993 assert (x.shape == shape3);
@@ -4021,7 +4002,7 @@ version(mir_test) unittest
40214002 // | 2 6 10 |
40224003 // | 3 7 11 |
40234004 // ---------
4024- auto y = slice.alongDim! 0 ;
4005+ auto y = slice.alongDim! 0 ; // alongDim!(-2) is the same for matrices.
40254006 static assert (is (typeof (y) == Slice! (SliceIterator! (IotaIterator! sizediff_t , 1 , Universal))));
40264007
40274008 assert (y.shape == shape4);
@@ -4188,7 +4169,7 @@ Returns a slice that can be iterated by dimension. Transposes dimensions on top
41884169Combines $(SUBREF dynamic, transposed), $(LREF ipack), and SliceKind Selectors.
41894170
41904171Params:
4191- Dimensions = dimensions to perform iteration on, length of d, `1 <= d <= n`
4172+ SDimensions = dimensions to perform iteration on, length of d, `1 <= d <= n`. Negative dimensions are supported.
41924173Returns:
41934174 d-dimensional slice composed of `(n-d)`-dimensional slices
41944175See_also:
@@ -4197,15 +4178,11 @@ See_also:
41974178 $(LREF ipack),
41984179 $(SUBREF dynamic, transposed).
41994180+/
4200- template byDim (Dimensions ... )
4201- if (Dimensions .length > 0 )
4181+ template byDim (SDimensions ... )
4182+ if (SDimensions .length > 0 )
42024183{
4203- import mir.ndslice.internal : isSize_t;
4204- import std.meta : allSatisfy;
4205-
4206- static if (allSatisfy! (isSize_t, Dimensions))
4184+ static if (allSatisfy! (isSizediff_t, SDimensions))
42074185 {
4208- import mir.ndslice.slice : Slice, SliceKind;
42094186 /+ +
42104187 Params:
42114188 slice = input n-dimensional slice, n >= d
@@ -4214,10 +4191,10 @@ template byDim(Dimensions...)
42144191 +/
42154192 @optmath auto byDim(Iterator, size_t N, SliceKind kind)
42164193 (Slice! (Iterator, N, kind) slice)
4217- if (N >= Dimensions .length)
4194+ if (N >= SDimensions .length)
42184195 {
4219- import mir.ndslice.topology : ipack;
4220- import mir.ndslice.internal : DimensionsCountCTError ;
4196+
4197+ alias Dimensions = staticMap ! (ShiftNegativeWith ! N, SDimensions) ;
42214198
42224199 mixin DimensionsCountCTError;
42234200
@@ -4278,10 +4255,7 @@ template byDim(Dimensions...)
42784255 }
42794256 else
42804257 {
4281- import std.meta : staticMap;
4282- import mir.ndslice.internal : toSize_t;
4283-
4284- alias byDim = .byDim! (staticMap! (toSize_t, Dimensions));
4258+ alias byDim = .byDim! (staticMap! (toSizediff_t, SDimensions));
42854259 }
42864260}
42874261
@@ -4309,7 +4283,7 @@ version(mir_test) unittest
43094283 // | 4 5 6 7 |
43104284 // | 8 9 10 11 |
43114285 // ------------
4312- auto x = slice.byDim! 0 ;
4286+ auto x = slice.byDim! 0 ; // byDim!(-2) is the same for matrices.
43134287 static assert (is (typeof (x) == Slice! (SliceIterator! (IotaIterator! sizediff_t ), 1 , Universal)));
43144288
43154289 assert (x.shape == shape3);
@@ -4324,7 +4298,7 @@ version(mir_test) unittest
43244298 // | 2 6 10 |
43254299 // | 3 7 11 |
43264300 // ---------
4327- auto y = slice.byDim! 1 ;
4301+ auto y = slice.byDim! ( - 1 ); // -1 is the last dimension index, the same as 1 for this case.
43284302 static assert (is (typeof (y) == Slice! (SliceIterator! (IotaIterator! sizediff_t , 1 , Universal))));
43294303
43304304 assert (y.shape == shape4);
0 commit comments