A function
import mir.ndslice.allocation: slice; import mir.ndslice.topology: iota; //| 1 2 3 | //| 4 5 6 | //| 7 8 9 | auto m = iota([3, 3], 1).slice; m.eachLower!"a = 0"; assert(m == [ [1, 2, 3], [0, 5, 6], [0, 0, 9]]);
Swap two slices
import mir.utility : swap; import mir.ndslice.allocation : slice; import mir.ndslice.topology : as, iota; //| 0 1 2 | //| 3 4 5 | //| 6 7 8 | auto a = iota([3, 3]).as!double.slice; //| 10 11 12 | //| 13 14 15 | //| 16 17 18 | auto b = iota([3, 3], 10).as!double.slice; eachLower!swap(a, b); assert(a == [ [ 0, 1, 2], [13, 4, 5], [16, 17, 8]]); assert(b == [ [10, 11, 12], [ 3, 14, 15], [ 6, 7, 18]]);
Swap two zipped slices
import mir.utility : swap; import mir.ndslice.allocation : slice; import mir.ndslice.topology : as, zip, iota; //| 0 1 2 | //| 3 4 5 | //| 6 7 8 | auto a = iota([3, 3]).as!double.slice; //| 10 11 12 | //| 13 14 15 | //| 16 17 18 | auto b = iota([3, 3], 10).as!double.slice; auto z = zip(a, b); z.eachLower!(z => swap(z.a, z.b)); assert(a == [ [ 0, 1, 2], [13, 4, 5], [16, 17, 8]]); assert(b == [ [10, 11, 12], [ 3, 14, 15], [ 6, 7, 18]]);
This is functionally similar to each.
The call eachLower!(fun)(slice1, ..., sliceN) evaluates fun on the lower triangle in slice1, ..., sliceN respectively.
eachLower allows iterating multiple slices in the lockstep.