@@ -28,24 +28,29 @@ import mir.math.common: optmath;
2828@optmath:
2929
3030/+ +
31- Fuses ndrange `r` into GC-allocated ndslice. Can be used to join rows or columns into a matrix.
31+ Fuses ndrange `r` into GC-allocated (`fuse`) or RC-allocated (`rcfuse`) ndslice. Can be used to join rows or columns into a matrix.
3232
3333Params:
3434 Dimensions = (optional) indexes of dimensions to be brought to the first position
3535Returns:
3636 ndslice
3737+/
38- template fuse (Dimensions... )
38+ // /
39+ alias fuse (Dimensions... ) = fuseImpl! (false , Dimensions);
40+ // /
41+ alias rcfuse (Dimensions... ) = fuseImpl! (true , Dimensions);
42+ // / ditto
43+ template fuseImpl (bool RC , Dimensions... )
3944{
4045 import mir.ndslice.internal: isSize_t, toSize_t;
4146 static if (! allSatisfy! (isSize_t, Dimensions))
42- alias fuse = .fuse ! ( staticMap! (toSize_t, Dimensions));
47+ alias fuseImpl = .fuseImpl ! ( RC , staticMap! (toSize_t, Dimensions));
4348 else
4449 /+ +
4550 Params:
4651 r = parallelotope (ndrange) with length/shape and input range primitives.
4752 +/
48- @optmath Slice ! (FuseElementType ! NDRange * , fuseDimensionCount ! NDRange) fuse (NDRange)(NDRange r)
53+ @optmath auto fuseImpl (NDRange)(NDRange r)
4954 if (hasShape! NDRange)
5055 {
5156 import mir.conv: emplaceRef;
@@ -54,8 +59,17 @@ template fuse(Dimensions...)
5459 auto shape = fuseShape(r);
5560 alias T = FuseElementType! NDRange;
5661 alias UT = Unqual! T;
57- alias R = typeof (return );
58- Slice! (UT * , fuseDimensionCount! NDRange) ret;
62+ static if (RC )
63+ {
64+ import mir.rc.array: RCI ;
65+ alias R = Slice! (RCI ! T, fuseDimensionCount! NDRange);
66+ Slice! (RCI ! UT , fuseDimensionCount! NDRange) ret;
67+ }
68+ else
69+ {
70+ alias R = Slice! (T* , fuseDimensionCount! NDRange);
71+ Slice! (UT * , fuseDimensionCount! NDRange) ret;
72+ }
5973 static if (Dimensions.length)
6074 {
6175 import mir.ndslice.topology: iota;
@@ -72,40 +86,66 @@ template fuse(Dimensions...)
7286 return ar;
7387 }(perm)
7488 );
75- if (__ctfe )
89+ static if (RC )
7690 {
77- ret = shapep.slice ! UT ;
78- ret.transposed! InverseDimensions.each! " a = b " (r);
91+ ret = shapep.uninitRcslice ! UT ;
92+ ret.lightScope. transposed! InverseDimensions.each! (emplaceRef ! T) (r);
7993 }
8094 else
8195 {
82- ret = shapep.uninitSlice! UT ;
83- ret.transposed! InverseDimensions.each! (emplaceRef! T)(r);
96+ if (__ctfe)
97+ {
98+ ret = shapep.slice! UT ;
99+ ret.transposed! InverseDimensions.each! " a = b" (r);
100+ }
101+ else
102+ {
103+ ret = shapep.uninitSlice! UT ;
104+ ret.transposed! InverseDimensions.each! (emplaceRef! T)(r);
105+ }
106+
84107 }
85108 }
86109 else
87110 {
88- if (__ctfe )
111+ static if (RC )
89112 {
90- ret = shape.slice ! UT ;
91- ret.each! " a = b " (r);
113+ ret = shape.uninitRCslice ! UT ;
114+ ret.lightScope. each! (emplaceRef ! T) (r);
92115 }
93116 else
94117 {
95- ret = shape.uninitSlice! UT ;
96- ret.each! (emplaceRef! T)(r);
118+ if (__ctfe)
119+ {
120+ ret = shape.slice! UT ;
121+ ret.each! " a = b" (r);
122+ }
123+ else
124+ {
125+ ret = shape.uninitSlice! UT ;
126+ ret.each! (emplaceRef! T)(r);
127+ }
97128 }
98129 }
99- return R (ret._structure, (() @trusted => cast (T* )ret._iterator)());
130+ static if (RC )
131+ {
132+ import core.lifetime : move;
133+ return move (* (() @trusted => cast (R* )&ret)());
134+ }
135+ else
136+ {
137+ return * (() @trusted => cast (R* )&ret)();
138+ }
100139 }
101140}
102141
103142// /
104- unittest
143+ @safe pure nothrow version(mir_test) unittest
105144{
106145 import mir.ndslice.fuse;
107- import mir.ndslice.topology: iota;
108146 import mir.ndslice.slice : Contiguous, Slice;
147+ import mir.ndslice.topology: iota;
148+ import mir.rc.array: RCI ;
109149
110150 enum ror = [
111151 [0 , 1 , 2 , 3 ],
@@ -117,14 +157,19 @@ unittest
117157 // 8 9 10 11
118158 auto matrix = ror.fuse;
119159
160+ auto rcmatrix = ror.rcfuse; // nogc version
161+
120162 assert (matrix == [3 , 4 ].iota);
163+ assert (rcmatrix == [3 , 4 ].iota);
121164 static assert (ror.fuse == [3 , 4 ].iota); // CTFE-able
165+
122166 // matrix is contiguos
123167 static assert (is (typeof (matrix) == Slice! (int * , 2 )));
168+ static assert (is (typeof (rcmatrix) == Slice! (RCI ! int , 2 )));
124169}
125170
126171// / Transposed
127- unittest
172+ @safe pure nothrow version(mir_test) unittest
128173{
129174 import mir.ndslice.fuse;
130175 import mir.ndslice.topology: iota;
@@ -153,7 +198,7 @@ unittest
153198
154199
155200// / 3D
156- unittest
201+ @safe pure nothrow version(mir_test) unittest
157202{
158203 import mir.ndslice.fuse;
159204 import mir.ndslice.topology: iota;
@@ -174,7 +219,7 @@ unittest
174219}
175220
176221// / Work with RC Arrays of RC Arrays
177- unittest
222+ @safe pure nothrow version(mir_test) unittest
178223{
179224 import mir.ndslice.fuse;
180225 import mir.ndslice.slice;
0 commit comments