@@ -23,10 +23,6 @@ import mir.qualifier;
2323import std.meta ;
2424import std.traits ;
2525
26- import mir.math.common: optmath;
27-
28- @optmath:
29-
3026/+ +
3127Fuses ndrange `r` into GC-allocated ($(LREF fuse)) or RC-allocated ($(LREF rcfuse)) ndslice.
3228Can be used to join rows or columns into a matrix.
@@ -41,7 +37,7 @@ alias fuse(Dimensions...) = fuseImpl!(false, void, Dimensions);
4137alias rcfuse (Dimensions... ) = fuseImpl! (true , void , Dimensions);
4238
4339// /
44- @safe pure nothrow version(mir_test) unittest
40+ @safe pure version(mir_test) unittest
4541{
4642 import mir.ndslice.fuse;
4743 import mir.ndslice.slice : Contiguous, Slice;
@@ -70,7 +66,7 @@ alias rcfuse(Dimensions...) = fuseImpl!(true, void, Dimensions);
7066}
7167
7268// / Transposed
73- @safe pure nothrow version(mir_test) unittest
69+ @safe pure version(mir_test) unittest
7470{
7571 import mir.ndslice.fuse;
7672 import mir.ndslice.topology: iota;
@@ -99,7 +95,7 @@ alias rcfuse(Dimensions...) = fuseImpl!(true, void, Dimensions);
9995
10096
10197// / 3D
102- @safe pure nothrow version(mir_test) unittest
98+ @safe pure version(mir_test) unittest
10399{
104100 import mir.ndslice.fuse;
105101 import mir.ndslice.topology: iota;
@@ -120,7 +116,7 @@ alias rcfuse(Dimensions...) = fuseImpl!(true, void, Dimensions);
120116}
121117
122118// / Work with RC Arrays of RC Arrays
123- @safe pure nothrow version(mir_test) unittest
119+ @safe pure version(mir_test) unittest
124120{
125121 import mir.ndslice.fuse;
126122 import mir.ndslice.slice;
@@ -148,7 +144,7 @@ alias fuseAs(T, Dimensions...) = fuseImpl!(false, T, Dimensions);
148144alias rcfuseAs (T, Dimensions... ) = fuseImpl! (true , T, Dimensions);
149145
150146// /
151- @safe pure nothrow version(mir_test) unittest
147+ @safe pure version(mir_test) unittest
152148{
153149 import mir.ndslice.fuse;
154150 import mir.ndslice.slice : Contiguous, Slice;
@@ -185,7 +181,7 @@ template fuseImpl(bool RC, T_, Dimensions...)
185181 Params:
186182 r = parallelotope (ndrange) with length/shape and input range primitives.
187183 +/
188- @optmath auto fuseImpl(NDRange)(NDRange r)
184+ auto fuseImpl (NDRange)(NDRange r)
189185 if (hasShape! NDRange)
190186 {
191187 import mir.conv: emplaceRef;
@@ -290,6 +286,11 @@ private template fuseDimensionCount(R)
290286 enum size_t fuseDimensionCount = 0 ;
291287}
292288
289+ private static immutable shapeExceptionMsg = " fuseShape Exception: elements have different shapes/lengths" ;
290+
291+ version (D_Exceptions)
292+ static immutable shapeException = new Exception (shapeExceptionMsg);
293+
293294/+
294295TODO docs
295296+/
@@ -298,7 +299,9 @@ size_t[fuseDimensionCount!Range] fuseShape(Range)(Range r)
298299{
299300 // auto outerShape = r.shape;
300301 enum N = r.shape.length;
301- static if (N == typeof (return ).length)
302+ enum RN = typeof (return ).length;
303+ enum M = RN - N;
304+ static if (M == 0 )
302305 {
303306 return r.shape;
304307 }
@@ -310,6 +313,14 @@ size_t[fuseDimensionCount!Range] fuseShape(Range)(Range r)
310313 if (! ret[0 .. N].anyEmptyShape)
311314 {
312315 ret[N .. $] = fuseShape(mixin (" r" ~ " .front" .repeat(N).fuseCells.field));
316+ import mir.algorithm.iteration: all;
317+ if (! all! ((a) => cast (size_t [M]) ret[N .. $] == .fuseShape(a))(r))
318+ {
319+ version (D_Exceptions)
320+ throw shapeException;
321+ else
322+ assert (0 , shapeExceptionMsg);
323+ }
313324 }
314325 return ret;
315326 }
@@ -358,7 +369,7 @@ auto fuseCells(S)(S cells)
358369}
359370
360371// / 1D
361- @safe pure nothrow version(mir_test) unittest
372+ @safe pure version(mir_test) unittest
362373{
363374 import mir.ndslice.topology: iota;
364375 enum ar = [[0 , 1 ], [], [2 , 3 , 4 , 5 ], [6 ], [7 , 8 , 9 ]];
@@ -367,7 +378,7 @@ auto fuseCells(S)(S cells)
367378}
368379
369380// / 2D
370- @safe pure nothrow version(mir_test) unittest
381+ @safe pure version(mir_test) unittest
371382{
372383 import mir.ndslice.topology: iota;
373384 import mir.ndslice.chunks;
0 commit comments