@@ -40,6 +40,99 @@ alias fuse(Dimensions...) = fuseImpl!(false, void, Dimensions);
40
40
// / ditto
41
41
alias rcfuse (Dimensions... ) = fuseImpl! (true , void , Dimensions);
42
42
43
+ // /
44
+ @safe pure nothrow version(mir_test) unittest
45
+ {
46
+ import mir.ndslice.fuse;
47
+ import mir.ndslice.slice : Contiguous, Slice;
48
+ import mir.ndslice.topology: iota;
49
+ import mir.rc.array: RCI ;
50
+
51
+ enum ror = [
52
+ [0 , 1 , 2 , 3 ],
53
+ [4 , 5 , 6 , 7 ],
54
+ [8 , 9 ,10 ,11 ]];
55
+
56
+ // 0 1 2 3
57
+ // 4 5 6 7
58
+ // 8 9 10 11
59
+ auto matrix = ror.fuse;
60
+
61
+ auto rcmatrix = ror.rcfuse; // nogc version
62
+
63
+ assert (matrix == [3 , 4 ].iota);
64
+ assert (rcmatrix == [3 , 4 ].iota);
65
+ static assert (ror.fuse == [3 , 4 ].iota); // CTFE-able
66
+
67
+ // matrix is contiguos
68
+ static assert (is (typeof (matrix) == Slice! (int * , 2 )));
69
+ static assert (is (typeof (rcmatrix) == Slice! (RCI ! int , 2 )));
70
+ }
71
+
72
+ // / Transposed
73
+ @safe pure nothrow version(mir_test) unittest
74
+ {
75
+ import mir.ndslice.fuse;
76
+ import mir.ndslice.topology: iota;
77
+ import mir.ndslice.dynamic: transposed;
78
+ import mir.ndslice.slice : Contiguous, Slice;
79
+
80
+ enum ror = [
81
+ [0 , 1 , 2 , 3 ],
82
+ [4 , 5 , 6 , 7 ],
83
+ [8 , 9 ,10 ,11 ]];
84
+
85
+ // 0 4 8
86
+ // 1 5 9
87
+ // 2 6 10
88
+ // 3 7 11
89
+
90
+ // `!1` brings dimensions under index 1 to the front (0 index).
91
+ auto matrix = ror.fuse! 1 ;
92
+
93
+ assert (matrix == [3 , 4 ].iota.transposed! 1 );
94
+ // TODO: CTFE
95
+ // static assert(ror.fuse!1 == [3, 4].iota.transposed!1); // CTFE-able
96
+ // matrix is contiguos
97
+ static assert (is (typeof (matrix) == Slice! (int * , 2 )));
98
+ }
99
+
100
+
101
+ // / 3D
102
+ @safe pure nothrow version(mir_test) unittest
103
+ {
104
+ import mir.ndslice.fuse;
105
+ import mir.ndslice.topology: iota;
106
+ import mir.ndslice.dynamic: transposed;
107
+
108
+ auto ror =
109
+ [[[ 0 , 1 , 2 , 3 ],
110
+ [ 4 , 5 , 6 , 7 ]],
111
+ [[ 8 , 9 ,10 ,11 ],
112
+ [12 ,13 ,14 ,15 ]]];
113
+
114
+ auto nd = [2 , 2 , 4 ].iota;
115
+
116
+ assert (ror.fuse == nd);
117
+ assert (ror.fuse! 2 == nd.transposed! 2 );
118
+ assert (ror.fuse! (1 , 2 ) == nd.transposed! (1 , 2 ));
119
+ assert (ror.fuse! (2 , 1 ) == nd.transposed! (2 , 1 ));
120
+ }
121
+
122
+ // / Work with RC Arrays of RC Arrays
123
+ @safe pure nothrow version(mir_test) unittest
124
+ {
125
+ import mir.ndslice.fuse;
126
+ import mir.ndslice.slice;
127
+ import mir.ndslice.topology: map;
128
+ import mir.rc.array;
129
+
130
+ Slice! (const (double )* , 2 ) conv(RCArray! (const RCArray! (const double )) a)
131
+ {
132
+ return a[].map! " a[]" .fuse;
133
+ }
134
+ }
135
+
43
136
/+ +
44
137
Fuses ndrange `r` into GC-allocated ($(LREF fuseAs)) or RC-allocated ($(LREF rcfuseAs)) ndslice.
45
138
Can be used to join rows or columns into a matrix.
@@ -54,6 +147,35 @@ alias fuseAs(T, Dimensions...) = fuseImpl!(false, T, Dimensions);
54
147
// / ditto
55
148
alias rcfuseAs (T, Dimensions... ) = fuseImpl! (true , T, Dimensions);
56
149
150
+ // /
151
+ @safe pure nothrow version(mir_test) unittest
152
+ {
153
+ import mir.ndslice.fuse;
154
+ import mir.ndslice.slice : Contiguous, Slice;
155
+ import mir.ndslice.topology: iota;
156
+ import mir.rc.array: RCI ;
157
+
158
+ enum ror = [
159
+ [0 , 1 , 2 , 3 ],
160
+ [4 , 5 , 6 , 7 ],
161
+ [8 , 9 ,10 ,11 ]];
162
+
163
+ // 0 1 2 3
164
+ // 4 5 6 7
165
+ // 8 9 10 11
166
+ auto matrix = ror.fuseAs! double ;
167
+
168
+ auto rcmatrix = ror.rcfuseAs! double ; // nogc version
169
+
170
+ assert (matrix == [3 , 4 ].iota);
171
+ assert (rcmatrix == [3 , 4 ].iota);
172
+ static assert (ror.fuseAs! double == [3 , 4 ].iota); // CTFE-able
173
+
174
+ // matrix is contiguos
175
+ static assert (is (typeof (matrix) == Slice! (double * , 2 )));
176
+ static assert (is (typeof (rcmatrix) == Slice! (RCI ! double , 2 )));
177
+ }
178
+
57
179
// /
58
180
template fuseImpl (bool RC , T_ , Dimensions... )
59
181
{
@@ -157,99 +279,6 @@ template fuseImpl(bool RC, T_, Dimensions...)
157
279
alias fuseImpl = .fuseImpl! (RC , T_ , staticMap! (toSize_t, Dimensions));
158
280
}
159
281
160
- // /
161
- @safe pure nothrow version(mir_test) unittest
162
- {
163
- import mir.ndslice.fuse;
164
- import mir.ndslice.slice : Contiguous, Slice;
165
- import mir.ndslice.topology: iota;
166
- import mir.rc.array: RCI ;
167
-
168
- enum ror = [
169
- [0 , 1 , 2 , 3 ],
170
- [4 , 5 , 6 , 7 ],
171
- [8 , 9 ,10 ,11 ]];
172
-
173
- // 0 1 2 3
174
- // 4 5 6 7
175
- // 8 9 10 11
176
- auto matrix = ror.fuse;
177
-
178
- auto rcmatrix = ror.rcfuse; // nogc version
179
-
180
- assert (matrix == [3 , 4 ].iota);
181
- assert (rcmatrix == [3 , 4 ].iota);
182
- static assert (ror.fuse == [3 , 4 ].iota); // CTFE-able
183
-
184
- // matrix is contiguos
185
- static assert (is (typeof (matrix) == Slice! (int * , 2 )));
186
- static assert (is (typeof (rcmatrix) == Slice! (RCI ! int , 2 )));
187
- }
188
-
189
- // / Transposed
190
- @safe pure nothrow version(mir_test) unittest
191
- {
192
- import mir.ndslice.fuse;
193
- import mir.ndslice.topology: iota;
194
- import mir.ndslice.dynamic: transposed;
195
- import mir.ndslice.slice : Contiguous, Slice;
196
-
197
- enum ror = [
198
- [0 , 1 , 2 , 3 ],
199
- [4 , 5 , 6 , 7 ],
200
- [8 , 9 ,10 ,11 ]];
201
-
202
- // 0 4 8
203
- // 1 5 9
204
- // 2 6 10
205
- // 3 7 11
206
-
207
- // `!1` brings dimensions under index 1 to the front (0 index).
208
- auto matrix = ror.fuse! 1 ;
209
-
210
- assert (matrix == [3 , 4 ].iota.transposed! 1 );
211
- // TODO: CTFE
212
- // static assert(ror.fuse!1 == [3, 4].iota.transposed!1); // CTFE-able
213
- // matrix is contiguos
214
- static assert (is (typeof (matrix) == Slice! (int * , 2 )));
215
- }
216
-
217
-
218
- // / 3D
219
- @safe pure nothrow version(mir_test) unittest
220
- {
221
- import mir.ndslice.fuse;
222
- import mir.ndslice.topology: iota;
223
- import mir.ndslice.dynamic: transposed;
224
-
225
- auto ror =
226
- [[[ 0 , 1 , 2 , 3 ],
227
- [ 4 , 5 , 6 , 7 ]],
228
- [[ 8 , 9 ,10 ,11 ],
229
- [12 ,13 ,14 ,15 ]]];
230
-
231
- auto nd = [2 , 2 , 4 ].iota;
232
-
233
- assert (ror.fuse == nd);
234
- assert (ror.fuse! 2 == nd.transposed! 2 );
235
- assert (ror.fuse! (1 , 2 ) == nd.transposed! (1 , 2 ));
236
- assert (ror.fuse! (2 , 1 ) == nd.transposed! (2 , 1 ));
237
- }
238
-
239
- // / Work with RC Arrays of RC Arrays
240
- @safe pure nothrow version(mir_test) unittest
241
- {
242
- import mir.ndslice.fuse;
243
- import mir.ndslice.slice;
244
- import mir.ndslice.topology: map;
245
- import mir.rc.array;
246
-
247
- Slice! (const (double )* , 2 ) conv(RCArray! (const RCArray! (const double )) a)
248
- {
249
- return a[].map! " a[]" .fuse;
250
- }
251
- }
252
-
253
282
private template fuseDimensionCount (R)
254
283
{
255
284
static if (is (typeof (R.init.shape) : size_t [N], size_t N) && (isDynamicArray! R || __traits(hasMember, R, " front" )))
@@ -279,7 +308,9 @@ size_t[fuseDimensionCount!Range] fuseShape(Range)(Range r)
279
308
typeof (return ) ret;
280
309
ret[0 .. N] = r.shape;
281
310
if (! ret[0 .. N].anyEmptyShape)
311
+ {
282
312
ret[N .. $] = fuseShape(mixin (" r" ~ " .front" .repeat(N).fuseCells.field));
313
+ }
283
314
return ret;
284
315
}
285
316
}
0 commit comments