Skip to content

Commit 0a9e077

Browse files
committed
add syntax sugar for indexed
1 parent 7af2d61 commit 0a9e077

File tree

1 file changed

+82
-0
lines changed

1 file changed

+82
-0
lines changed

source/mir/ndslice/slice.d

+82
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,8 @@ $(TR $(TD A $(B fully defined slice) is an empty sequence
404404
or a sequence composed of $(B indexes) and at least one
405405
$(B interval) with an overall length equal to `N`.)
406406
$(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]`))
407409
)
408410
409411
$(H3 Internal Binary Representation)
@@ -578,6 +580,11 @@ struct Slice(SliceKind kind, size_t[] packs, Iterator)
578580
&& PureIndexLength!Slices < packs[0]
579581
&& allSatisfy!(templateOr!(isIndex, is_Slice), Slices);
580582

583+
enum isIndexedSlice(Slices...) =
584+
Slices.length
585+
&& Slices.length <= packs[0]
586+
&& allSatisfy!(templateOr!isSlice, Slices);
587+
581588
///
582589
public size_t[N] _lengths;
583590
///
@@ -1495,6 +1502,81 @@ struct Slice(SliceKind kind, size_t[] packs, Iterator)
14951502
auto col = slice[0..$, 1];
14961503
}
14971504

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+
14981580
static if (isMutable!(PureThis.DeepElemType))
14991581
{
15001582
private void opIndexOpAssignImplSlice(string op, SliceKind rkind, size_t[] rpacks, RIterator)(Slice!(rkind, rpacks, RIterator) value)

0 commit comments

Comments
 (0)