@@ -404,6 +404,8 @@ $(TR $(TD A $(B fully defined slice) is an empty sequence
404
404
or a sequence composed of $(B indexes) and at least one
405
405
$(B interval) with an overall length equal to `N`.)
406
406
$(STD `[]`, `[3..$,0..3,0..$-1]`, `[2,0..$,1]`))
407
+ $(TR $(TD An $(B indexed slice) is syntax sugar for $(SUBREF indexed, topology) and $(SUBREF cartesian, topology).
408
+ $(STD `[anNdslice]`, `[anNdsliceForCartesian0, anNdsliceForCartesian1]`))
407
409
)
408
410
409
411
$(H3 Internal Binary Representation)
@@ -578,6 +580,11 @@ struct Slice(SliceKind kind, size_t[] packs, Iterator)
578
580
&& PureIndexLength! Slices < packs[0 ]
579
581
&& allSatisfy! (templateOr! (isIndex, is_Slice), Slices);
580
582
583
+ enum isIndexedSlice (Slices... ) =
584
+ Slices.length
585
+ && Slices.length <= packs[0 ]
586
+ && allSatisfy! (templateOr! isSlice, Slices);
587
+
581
588
// /
582
589
public size_t [N] _lengths;
583
590
// /
@@ -1495,6 +1502,81 @@ struct Slice(SliceKind kind, size_t[] packs, Iterator)
1495
1502
auto col = slice[0 .. $, 1 ];
1496
1503
}
1497
1504
1505
+ /+ +
1506
+ $(BOLD Indexed slice.)
1507
+ +/
1508
+ auto opIndex (Slices... )(Slices slices)
1509
+ if (isIndexedSlice! Slices)
1510
+ {
1511
+ import mir.ndslice.topology: indexed, cartesian, map;
1512
+ static if (Slices.length == 1 )
1513
+ alias index = slices[0 ];
1514
+ else
1515
+ auto index = slices.cartesian;
1516
+ return this .indexed(index);
1517
+ }
1518
+
1519
+ // /
1520
+ pure nothrow unittest
1521
+ {
1522
+ import mir.ndslice.allocation: slice;
1523
+ auto sli = slice! int (4 , 3 );
1524
+ auto idx = slice! (size_t [2 ])(3 );
1525
+ idx[] = [
1526
+ cast (size_t [2 ])[0 , 2 ],
1527
+ cast (size_t [2 ])[3 , 1 ],
1528
+ cast (size_t [2 ])[2 , 0 ]];
1529
+
1530
+ // equivalent to:
1531
+ // import mir.ndslice.topology: indexed;
1532
+ // sli.indexed(indx)[] = 1;
1533
+ sli[idx][] = 1 ;
1534
+
1535
+ assert (sli == [
1536
+ [0 , 0 , 1 ],
1537
+ [0 , 0 , 0 ],
1538
+ [1 , 0 , 0 ],
1539
+ [0 , 1 , 0 ],
1540
+ ]);
1541
+
1542
+ foreach (row; sli[[1 , 3 ].sliced])
1543
+ row[] += 2 ;
1544
+
1545
+ assert (sli == [
1546
+ [0 , 0 , 1 ],
1547
+ [2 , 2 , 2 ], // <-- += 2
1548
+ [1 , 0 , 0 ],
1549
+ [2 , 3 , 2 ], // <-- += 2
1550
+ ]);
1551
+ }
1552
+
1553
+ // /
1554
+ pure nothrow unittest
1555
+ {
1556
+ import mir.ndslice.topology: iota;
1557
+ import mir.ndslice.allocation: slice;
1558
+ auto sli = slice! int (5 , 6 );
1559
+
1560
+ // equivalent to
1561
+ // import mir.ndslice.topology: indexed, cartesian;
1562
+ // auto a = [0, sli.length!0 / 2, sli.length!0 - 1].sliced;
1563
+ // auto b = [0, sli.length!1 / 2, sli.length!1 - 1].sliced;
1564
+ // auto c = cartesian(a, b);
1565
+ // auto minor = sli.indexed(c);
1566
+ auto minor = sli[[0 , $ / 2 , $ - 1 ].sliced, [0 , $ / 2 , $ - 1 ].sliced];
1567
+
1568
+ minor[] = iota([3 , 3 ], 1 );
1569
+
1570
+ assert (sli == [
1571
+ // ↓ ↓ ↓︎
1572
+ [1 , 0 , 0 , 2 , 0 , 3 ], // <---
1573
+ [0 , 0 , 0 , 0 , 0 , 0 ],
1574
+ [4 , 0 , 0 , 5 , 0 , 6 ], // <---
1575
+ [0 , 0 , 0 , 0 , 0 , 0 ],
1576
+ [7 , 0 , 0 , 8 , 0 , 9 ], // <---
1577
+ ]);
1578
+ }
1579
+
1498
1580
static if (isMutable! (PureThis.DeepElemType))
1499
1581
{
1500
1582
private void opIndexOpAssignImplSlice (string op, SliceKind rkind, size_t [] rpacks, RIterator)(Slice! (rkind, rpacks, RIterator) value)
0 commit comments