@@ -1049,14 +1049,14 @@ struct Slice(SliceKind kind, size_t[] packs, Iterator)
10491049 static if (N == 1 && isMutable! DeepElemType && ! hasAccessByRef)
10501050 {
10511051 // /ditto
1052- auto front (size_t dimension = 0 , T)(T value) @property
1052+ auto ref front (size_t dimension = 0 , T)(auto ref T value) @property
10531053 if (dimension == 0 )
10541054 {
10551055 assert (! empty! dimension);
10561056 static if (__traits(compiles, * _iterator = value))
10571057 return * _iterator = value;
10581058 else
1059- _iterator[0 ] = value;
1059+ return _iterator[0 ] = value;
10601060 }
10611061 }
10621062
@@ -1102,7 +1102,7 @@ struct Slice(SliceKind kind, size_t[] packs, Iterator)
11021102 static if (N == 1 && isMutable! DeepElemType && ! hasAccessByRef)
11031103 {
11041104 // /ditto
1105- auto back (size_t dimension = 0 , T)(T value) @property
1105+ auto ref back (size_t dimension = 0 , T)(auto ref T value) @property
11061106 if (dimension == 0 )
11071107 {
11081108 assert (! empty! dimension);
@@ -1205,6 +1205,92 @@ struct Slice(SliceKind kind, size_t[] packs, Iterator)
12051205 assert (slice.shape == cast (size_t [3 ])[0 , 0 , 0 ]);
12061206 }
12071207
1208+ package (mir) ptrdiff_t lastIndex()() const @property
1209+ {
1210+ static if (kind == Contiguous)
1211+ {
1212+ return elementsCount - 1 ;
1213+ }
1214+ else
1215+ {
1216+ auto strides = strides;
1217+ ptrdiff_t shift = 0 ;
1218+ foreach (i; Iota! (packs[0 ]))
1219+ shift += strides[i] * (_lengths[i] - 1 );
1220+ return shift;
1221+ }
1222+ }
1223+
1224+ static if (packs[0 ] > 1 )
1225+ {
1226+ // / Accesses the first deep element of the slice.
1227+ auto ref first ()() @property
1228+ {
1229+ assert (! anyEmpty);
1230+ static if (packs.length == 1 )
1231+ return * _iterator;
1232+ else
1233+ static if (S)
1234+ return DeepElemType (_lengths[packs[0 ] .. $], _strides[packs[0 ] .. $], _iterator);
1235+ else
1236+ return DeepElemType (_lengths[packs[0 ] .. $], _strides, _iterator);
1237+ }
1238+
1239+ static if (isMutable! DeepElemType && ! hasAccessByRef)
1240+ // /ditto
1241+ auto ref first (T)(auto ref T value) @property
1242+ {
1243+ assert (! anyEmpty);
1244+ static if (__traits(compiles, * _iterator = value))
1245+ return * _iterator = value;
1246+ else
1247+ return _iterator[0 ] = value;
1248+ }
1249+
1250+ // /
1251+ unittest
1252+ {
1253+ import mir.ndslice.topology: iota, universal, canonical;
1254+ auto f = 5 ;
1255+ assert ([2 , 3 ].iota(f).first == f);
1256+ }
1257+
1258+ // / Accesses the last deep element of the slice.
1259+ auto ref last ()() @property
1260+ {
1261+ assert (! anyEmpty);
1262+ import mir.ndslice.topology: retro;
1263+ static if (packs.length == 1 )
1264+ return _iterator[lastIndex];
1265+ else
1266+ static if (S)
1267+ return DeepElemType (_lengths[packs[0 ] .. $], _strides[packs[0 ] .. $], _iterator + lastIndex);
1268+ else
1269+ return DeepElemType (_lengths[packs[0 ] .. $], _strides, _iterator + lastIndex);
1270+ }
1271+
1272+ static if (isMutable! DeepElemType && ! hasAccessByRef)
1273+ // /ditto
1274+ auto ref last (T)(auto ref T value) @property
1275+ {
1276+ assert (! anyEmpty);
1277+ return _iterator[lastIndex] = value;
1278+ }
1279+
1280+ // /
1281+ unittest
1282+ {
1283+ import mir.ndslice.topology: iota;
1284+ auto f = 5 ;
1285+ assert ([2 , 3 ].iota(f).last == f + 2 * 3 - 1 );
1286+ }
1287+ }
1288+ else
1289+ {
1290+ alias first = front;
1291+ alias last = back;
1292+ }
1293+
12081294 /+ +
12091295 Returns: `true` if for any dimension the length equals to `0`, and `false` otherwise.
12101296 +/
@@ -1378,13 +1464,11 @@ struct Slice(SliceKind kind, size_t[] packs, Iterator)
13781464 return _iterator[indexStride(_indexes)];
13791465 else
13801466 {
1381- auto c = _iterator;
1382- c += indexStride(_indexes);
13831467 static if (I == packs[0 ])
13841468 static if (S)
1385- return DeepElemType (_lengths[packs[0 ] .. $], _strides[packs[0 ] .. $], c );
1469+ return DeepElemType (_lengths[packs[0 ] .. $], _strides[packs[0 ] .. $], _iterator + indexStride(_indexes) );
13861470 else
1387- return DeepElemType (_lengths[packs[0 ] .. $], _strides, c );
1471+ return DeepElemType (_lengths[packs[0 ] .. $], _strides, _iterator + indexStride(_indexes) );
13881472 else
13891473 {
13901474 enum size_t diff = packs[0 ] - I;
@@ -1395,9 +1479,9 @@ struct Slice(SliceKind kind, size_t[] packs, Iterator)
13951479 diff ~ packs[1 .. $],
13961480 Iterator);
13971481 static if (S)
1398- return Ret (_lengths[I .. N], _strides[I .. S], c );
1482+ return Ret (_lengths[I .. N], _strides[I .. S], _iterator + indexStride(_indexes) );
13991483 else
1400- return Ret (_lengths[I .. N], _strides, c );
1484+ return Ret (_lengths[I .. N], _strides, _iterator + indexStride(_indexes) );
14011485 }
14021486 }
14031487
0 commit comments