@@ -45,7 +45,6 @@ Macros:
4545 */
4646module mir.algorithm.iteration ;
4747
48- import mir.primitives;
4948import mir.functional: naryFun;
5049import mir.internal.utility;
5150import mir.math.common: optmath;
@@ -54,6 +53,7 @@ import mir.ndslice.internal;
5453import mir.ndslice.iterator: FieldIterator, RetroIterator;
5554import mir.ndslice.slice;
5655import mir.primitives;
56+ import mir.qualifier;
5757import std.meta ;
5858import std.range.primitives : isInputRange, isBidirectionalRange, isInfinite, isForwardRange, ElementType;
5959import std.traits ;
@@ -567,14 +567,20 @@ template frontOf(size_t N)
567567 }
568568}
569569
570- template allFlattened (size_t N)
571- if (N)
570+ package (mir) template allFlattened(args... )
572571{
573- enum i = N - 1 ;
574- static if (i)
575- enum allFlattened = .allFlattened! i ~ (" slices[" ~ i.stringof ~ " ].flattened, " );
572+ static if (args.length)
573+ {
574+ alias arg = args[0 ];
575+ @optmath @property ls()()
576+ {
577+ import mir.ndslice.topology: flattened;
578+ return flattened (arg);
579+ }
580+ alias allFlattened = AliasSeq! (ls, allFlattened! (args[1 .. $]));
581+ }
576582 else
577- enum allFlattened = " slices[ " ~ i.stringof ~ " ].flattened, " ;
583+ alias allFlattened = AliasSeq ! () ;
578584}
579585
580586private template areAllContiguousSlices (Slices... )
@@ -707,7 +713,7 @@ template reduce(alias fun)
707713 static if (areAllContiguousSlices! Slices)
708714 {
709715 import mir.ndslice.topology: flattened;
710- return mixin ( ` .reduce!fun(seed, ` ~ allFlattened! (Slices.length) ~ ` ) ` );
716+ return .reduce! fun(seed, allFlattened! (allLightScope ! slices) );
711717 }
712718 else
713719 {
@@ -717,7 +723,7 @@ template reduce(alias fun)
717723 alias UT = Unqual! S;
718724 else
719725 alias UT = S;
720- return reduceImpl! (fun, UT , Slices)(seed, slices);
726+ return reduceImpl! (fun, UT , Slices)(seed, allLightScope ! slices);
721727 }
722728 }
723729 else version (Mir_disable_inlining_in_reduce)
@@ -730,7 +736,7 @@ template reduce(alias fun)
730736 static if (areAllContiguousSlices! Slices)
731737 {
732738 import mir.ndslice.topology: flattened;
733- return mixin ( ` .reduce!fun(seed, ` ~ allFlattened! (Slices.length) ~ ` ) ` );
739+ return .reduce! fun(seed, allFlattened! (allLightScope ! slices) );
734740 }
735741 else
736742 {
@@ -740,7 +746,7 @@ template reduce(alias fun)
740746 alias UT = Unqual! S;
741747 else
742748 alias UT = S;
743- return reduceImpl! (nonInlinedNaryFun! fun, UT , Slices)(seed, slices);
749+ return reduceImpl! (nonInlinedNaryFun! fun, UT , Slices)(seed, allLightScope ! slices);
744750 }
745751 }
746752 else
@@ -953,13 +959,13 @@ template each(alias fun)
953959 static if (areAllContiguousSlices! Slices)
954960 {
955961 import mir.ndslice.topology: flattened;
956- mixin ( ` .each!fun(` ~ allFlattened! (Slices.length) ~ ` ); ` );
962+ .each! fun(allFlattened! (allLightScope ! slices) );
957963 }
958964 else
959965 {
960966 if (slices[0 ].anyEmpty)
961967 return ;
962- eachImpl! fun(slices);
968+ eachImpl! fun(allLightScope ! slices);
963969 }
964970 }
965971 else
@@ -1083,7 +1089,7 @@ template eachUploPair(alias fun, bool includeDiagonal = false)
10831089 {
10841090 if (matrix.length) do
10851091 {
1086- eachImpl! fun(matrix.front! 0 , matrix.front! 1 );
1092+ eachImpl! fun(matrix.lightScope. front! 0 , matrix.lightScope .front! 1 );
10871093 matrix.popFront! 1 ;
10881094 matrix.popFront! 0 ;
10891095 // hint for optimizer
@@ -1097,8 +1103,8 @@ template eachUploPair(alias fun, bool includeDiagonal = false)
10971103 {
10981104 assert (! matrix.empty! 0 );
10991105 assert (! matrix.empty! 1 );
1100- auto l = matrix.front! 1 ;
1101- auto u = matrix.front! 0 ;
1106+ auto l = matrix.lightScope. front! 1 ;
1107+ auto u = matrix.lightScope. front! 0 ;
11021108 matrix.popFront! 1 ;
11031109 matrix.popFront! 0 ;
11041110 l.popFront;
@@ -1236,7 +1242,7 @@ template isSymmetric(alias fun = "a == b")
12361242 return false ;
12371243 if (matrix.length) do
12381244 {
1239- if (! allImpl! fun(matrix.front! 0 , matrix.front! 1 ))
1245+ if (! allImpl! fun(matrix.lightScope. front! 0 , matrix.lightScope .front! 1 ))
12401246 {
12411247 return false ;
12421248 }
@@ -1280,7 +1286,7 @@ bool minPosImpl(alias fun, Iterator, size_t N, SliceKind kind)(scope ref size_t[
12801286 }
12811287 else
12821288 {
1283- if (minPosImpl! (fun, Iterator, N - 1 , kind)(backwardIndex[1 .. $], iterator, slice.front))
1289+ if (minPosImpl! (fun, LightScopeOf ! Iterator, N - 1 , kind)(backwardIndex[1 .. $], iterator, lightScope( slice) .front))
12841290 {
12851291 backwardIndex[0 ] = slice.length;
12861292 found = true ;
@@ -1315,7 +1321,7 @@ bool[2] minmaxPosImpl(alias fun, Iterator, size_t N, SliceKind kind)(scope ref s
13151321 }
13161322 else
13171323 {
1318- auto r = minmaxPosImpl! (fun, Iterator, N - 1 , kind)(backwardIndex[1 .. $], iterator, slice.front);
1324+ auto r = minmaxPosImpl! (fun, LightScopeOf ! Iterator, N - 1 , kind)(backwardIndex[1 .. $], iterator, lightScope( slice) .front);
13191325 if (r[0 ])
13201326 {
13211327 backwardIndex[0 ][0 ] = slice.length;
@@ -1365,7 +1371,7 @@ template minmaxPos(alias pred = "a < b")
13651371 size_t [2 ][N] ret;
13661372 auto it = slice._iterator;
13671373 Iterator[2 ] iterator = [it, it];
1368- minmaxPosImpl! (pred, Iterator, N, kind)(ret, iterator, slice);
1374+ minmaxPosImpl! (pred, Iterator, N, kind)(ret, iterator, lightScope( slice) );
13691375 foreach (i; Iota! N)
13701376 {
13711377 pret[0 ]._lengths[i] = ret[i][0 ];
@@ -1443,7 +1449,7 @@ template minmaxIndex(alias pred = "a < b")
14431449 }
14441450 auto it = slice._iterator;
14451451 Iterator[2 ] iterator = [it, it];
1446- minmaxPosImpl! (pred, Iterator, N, kind)(ret, iterator, slice);
1452+ minmaxPosImpl! (pred, LightScopeOf ! Iterator, N, kind)(ret, iterator, lightScope( slice) );
14471453 foreach (i; Iota! N)
14481454 {
14491455 pret[0 ][i] = slice._lengths[i] - ret[i][0 ];
@@ -1503,7 +1509,7 @@ template minPos(alias pred = "a < b")
15031509 typeof (return ) ret = { _iterator : slice._iterator };
15041510 if (! slice.anyEmpty)
15051511 {
1506- minPosImpl! (pred, Iterator, N, kind)(ret._lengths, ret._iterator, slice);
1512+ minPosImpl! (pred, LightScopeOf ! Iterator, N, kind)(ret._lengths, ret._iterator, lightScope( slice) );
15071513 }
15081514 auto strides = slice.strides;
15091515 foreach (i; Iota! (0 , ret.S))
@@ -1575,7 +1581,7 @@ template minIndex(alias pred = "a < b")
15751581 if (! slice.anyEmpty)
15761582 {
15771583 ret = slice.shape;
1578- minPosImpl! (pred, Iterator, N, kind)(ret, slice._iterator, slice);
1584+ minPosImpl! (pred, LightScopeOf ! Iterator, N, kind)(ret, slice._iterator, lightScope( slice) );
15791585 foreach (i; Iota! N)
15801586 ret[i] = slice._lengths[i] - ret[i];
15811587 }
@@ -1727,7 +1733,7 @@ template findIndex(alias pred)
17271733 slices.checkShapesMatch;
17281734 size_t [DimensionCount! (Slices[0 ])] ret = - 1 ;
17291735 auto lengths = slices[0 ].shape;
1730- if (! slices[0 ].anyEmpty && findImpl! pred(ret, slices))
1736+ if (! slices[0 ].anyEmpty && findImpl! pred(ret, allLightScope ! slices))
17311737 foreach (i; Iota! (DimensionCount! (Slices[0 ])))
17321738 ret[i] = lengths[i] - ret[i];
17331739 static if (DimensionCount! (Slices[0 ]) > 1 )
@@ -1824,7 +1830,7 @@ template find(alias pred)
18241830 slices.checkShapesMatch;
18251831 size_t [DimensionCount! (Slices[0 ])] ret;
18261832 if (! slices[0 ].anyEmpty)
1827- findImpl! pred(ret, slices);
1833+ findImpl! pred(ret, allLightScope ! slices);
18281834 static if (DimensionCount! (Slices[0 ]) > 1 )
18291835 return ret;
18301836 else
@@ -1951,7 +1957,7 @@ size_t anyImpl(alias fun, Slices...)(scope Slices slices)
19511957 {
19521958 // pragma(msg, S);
19531959 import mir.ndslice.topology: retro;
1954- return .anyImpl! fun(slices[0 ].retro);
1960+ return .anyImpl! fun(lightScope( slices[0 ]) .retro);
19551961 }
19561962 else
19571963 {
@@ -2003,11 +2009,11 @@ template any(alias pred = "a")
20032009 static if (areAllContiguousSlices! Slices)
20042010 {
20052011 import mir.ndslice.topology: flattened;
2006- return mixin ( ` .any!pred(` ~ allFlattened! (Slices.length) ~ ` ) ` );
2012+ return .any! pred(allFlattened! (allLightScope ! slices) );
20072013 }
20082014 else
20092015 {
2010- return ! slices[0 ].anyEmpty && anyImpl! pred(slices);
2016+ return ! slices[0 ].anyEmpty && anyImpl! pred(allLightScope ! slices);
20112017 }
20122018 }
20132019 else
@@ -2104,14 +2110,14 @@ size_t allImpl(alias fun, Slices...)(scope Slices slices)
21042110{
21052111 static if (__traits(isSame, fun, naryFun! " a" ) && is (S : Slice! (FieldIterator! (BitField! (Field , I))), Field , I))
21062112 {
2107- return BitSliceAccelerator! (Field , I)(slices[0 ]).all;
2113+ return BitSliceAccelerator! (LightScopeOf ! Field , I)(lightScope( slices[0 ]) ).all;
21082114 }
21092115 else
21102116 static if (__traits(isSame, fun, naryFun! " a" ) && is (S : Slice! (RetroIterator! (FieldIterator! (BitField! (Field , I)))), Field , I))
21112117 {
21122118 // pragma(msg, S);
21132119 import mir.ndslice.topology: retro;
2114- return .allImpl! fun(slices[0 ].retro);
2120+ return .allImpl! fun(lightScope( slices[0 ]) .retro);
21152121 }
21162122 else
21172123 {
@@ -2163,11 +2169,11 @@ template all(alias pred = "a")
21632169 static if (areAllContiguousSlices! Slices)
21642170 {
21652171 import mir.ndslice.topology: flattened;
2166- return mixin ( ` .all!pred(` ~ allFlattened! (Slices.length) ~ ` ) ` );
2172+ return .all! pred(allFlattened! (allLightScope ! slices) );
21672173 }
21682174 else
21692175 {
2170- return slices[0 ].anyEmpty || allImpl! pred(slices);
2176+ return slices[0 ].anyEmpty || allImpl! pred(allLightScope ! slices);
21712177 }
21722178 }
21732179 else
@@ -2298,13 +2304,13 @@ template count(alias fun)
22982304 static if (areAllContiguousSlices! Slices)
22992305 {
23002306 import mir.ndslice.topology: flattened;
2301- return mixin ( ` .count!fun(` ~ allFlattened! (Slices.length) ~ ` ) ` );
2307+ return .count! fun(allFlattened! (allLightScope ! slices) );
23022308 }
23032309 else
23042310 {
23052311 if (slices[0 ].anyEmpty)
23062312 return 0 ;
2307- return countImpl! (fun, Slices)( slices);
2313+ return countImpl! (fun)(allLightScope ! slices);
23082314 }
23092315 }
23102316 else
@@ -2421,7 +2427,7 @@ template equal(alias pred = "a == b")
24212427 goto False;
24222428 }
24232429 }
2424- return all! pred(slices);
2430+ return all! pred(allLightScope ! slices);
24252431 False: return false ;
24262432 }
24272433 else
@@ -2461,6 +2467,21 @@ version(mir_test) unittest
24612467 assert (! equal(sl1[0 .. $, 0 .. $ - 1 ], sl1));
24622468}
24632469
2470+ @safe pure nothrow @nogc
2471+ version (mir_test) unittest
2472+ {
2473+ import mir.algorithm.iteration: equal;
2474+ import mir.math.common: approxEqual;
2475+ import mir.ndslice.allocation: rcslice;
2476+ import mir.ndslice.topology: as, iota;
2477+
2478+ auto x = 5. iota.as! double .rcslice;
2479+ auto y = x.rcslice;
2480+
2481+ assert (equal(x, y));
2482+ assert (equal! approxEqual(x, y));
2483+ }
2484+
24642485ptrdiff_t cmpImpl (alias pred, A, B)
24652486 (scope A sl1, scope B sl2)
24662487 if (DimensionCount! A == DimensionCount! B)
@@ -2534,7 +2555,7 @@ template cmp(alias pred = "a < b")
25342555 }
25352556 if (b)
25362557 return 1 ;
2537- return cmpImpl! pred(sl1, sl2);
2558+ return cmpImpl! pred(lightScope( sl1), lightScope( sl2) );
25382559 }
25392560 else
25402561 alias cmp = .cmp! (naryFun! pred);
@@ -2608,7 +2629,7 @@ size_t countImpl(alias fun, Slices...)(scope Slices slices)
26082629 {
26092630 // pragma(msg, S);
26102631 import mir.ndslice.topology: retro;
2611- ret = .countImpl! fun(slices[0 ].retro);
2632+ ret = .countImpl! fun(lightScope( slices[0 ]) .retro);
26122633 }
26132634 else
26142635 do
@@ -2635,7 +2656,7 @@ private template selectBackOf(size_t N, string input)
26352656 {
26362657 enum i = N - 1 ;
26372658 enum selectBackOf = selectBackOf! (i, input) ~
2638- " slices[" ~ i.stringof ~ " ].selectBack!0(" ~ input ~ " ), " ;
2659+ " lightScope( slices[" ~ i.stringof ~ " ]) .selectBack!0(" ~ input ~ " ), " ;
26392660 }
26402661}
26412662
@@ -2647,7 +2668,7 @@ private template frontSelectFrontOf(size_t N, string input)
26472668 {
26482669 enum i = N - 1 ;
26492670 enum frontSelectFrontOf = frontSelectFrontOf! (i, input) ~
2650- " slices[" ~ i.stringof ~ " ].front!0.selectFront!0(" ~ input ~ " ), " ;
2671+ " lightScope( slices[" ~ i.stringof ~ " ]) .front!0.selectFront!0(" ~ input ~ " ), " ;
26512672 }
26522673}
26532674
@@ -3114,7 +3135,7 @@ private template frontSelectBackOf(size_t N, string input)
31143135 {
31153136 enum i = N - 1 ;
31163137 enum frontSelectBackOf = frontSelectBackOf! (i, input) ~
3117- " slices[" ~ i.stringof ~ " ].front.selectBack!0(" ~ input ~ " ), " ;
3138+ " lightScope( slices[" ~ i.stringof ~ " ]) .front.selectBack!0(" ~ input ~ " ), " ;
31183139 }
31193140}
31203141
@@ -3126,7 +3147,7 @@ private template selectFrontOf(size_t N, string input)
31263147 {
31273148 enum i = N - 1 ;
31283149 enum selectFrontOf = selectFrontOf! (i, input) ~
3129- " slices[" ~ i.stringof ~ " ].selectFront!0(" ~ input ~ " ), " ;
3150+ " lightScope( slices[" ~ i.stringof ~ " ]) .selectFront!0(" ~ input ~ " ), " ;
31303151 }
31313152}
31323153
0 commit comments