reduce ndslice template bloat part 1

This commit is contained in:
Ilya Yaroshenko 2016-09-30 00:49:02 +02:00
parent 81c09ed1c1
commit c39ec4cd43
4 changed files with 106 additions and 261 deletions

View file

@ -334,42 +334,6 @@ enum indexError(size_t pos, size_t N) =
~ " from the range [0 .." ~ N.stringof ~ ")"
~ " must be less than corresponding length.";
enum indexStrideCode = q{
static if (_indexes.length)
{
size_t stride = _strides[0] * _indexes[0];
assert(_indexes[0] < _lengths[0], indexError!(0, N));
foreach (i; Iota!(1, N)) //static
{
assert(_indexes[i] < _lengths[i], indexError!(i, N));
stride += _strides[i] * _indexes[i];
}
return stride;
}
else
{
return 0;
}
};
enum mathIndexStrideCode = q{
static if (_indexes.length)
{
size_t stride = _strides[0] * _indexes[N - 1];
assert(_indexes[N - 1] < _lengths[0], indexError!(N - 1, N));
foreach_reverse (i; Iota!(0, N - 1)) //static
{
assert(_indexes[i] < _lengths[N - 1 - i], indexError!(i, N));
stride += _strides[N - 1 - i] * _indexes[i];
}
return stride;
}
else
{
return 0;
}
};
enum string tailErrorMessage(
string fun = __FUNCTION__,
string pfun = __PRETTY_FUNCTION__) =

View file

@ -329,7 +329,7 @@ Returns:
n-dimensional slice of the same type
See_also: $(LREF swapped), $(LREF transposed)
+/
Slice!(N, Range) everted(size_t N, Range)(auto ref Slice!(N, Range) slice)
Slice!(N, Range) everted(size_t N, Range)(Slice!(N, Range) slice)
{
mixin _DefineRet;
with (slice)
@ -378,7 +378,7 @@ private enum _transposedCode = q{
}
};
private size_t[N] completeTranspose(size_t N)(in size_t[] dimensions)
private size_t[N] completeTranspose(size_t N)(size_t[] dimensions)
{
assert(dimensions.length <= N);
size_t[N] ctr;
@ -410,7 +410,7 @@ See_also: $(LREF swapped), $(LREF everted)
template transposed(Dimensions...)
if (Dimensions.length)
{
@fmb Slice!(N, Range) transposed(size_t N, Range)(auto ref Slice!(N, Range) slice)
@fmb Slice!(N, Range) transposed(size_t N, Range)(Slice!(N, Range) slice)
{
mixin DimensionsCountCTError;
foreach (i, dimension; Dimensions)
@ -425,22 +425,7 @@ template transposed(Dimensions...)
}
///ditto
Slice!(N, Range) transposed(size_t N, Range)(auto ref Slice!(N, Range) slice, size_t dimension)
in
{
mixin (DimensionRTError);
}
body
{
size_t[1] permutation = void;
permutation[0] = dimension;
immutable perm = completeTranspose!N(permutation);
assert(perm.isPermutation, __PRETTY_FUNCTION__ ~ ": internal error.");
mixin (_transposedCode);
}
///ditto
Slice!(N, Range) transposed(size_t N, Range)(auto ref Slice!(N, Range) slice, in size_t[] dimensions...)
Slice!(N, Range) transposed(size_t N, Range, size_t M)(Slice!(N, Range) slice, size_t[M] dimensions...)
in
{
mixin (DimensionsCountRTError);
@ -458,7 +443,7 @@ body
}
///ditto
Slice!(2, Range) transposed(Range)(auto ref Slice!(2, Range) slice)
Slice!(2, Range) transposed(Range)(Slice!(2, Range) slice)
{
return .transposed!(1, 0)(slice);
}
@ -564,19 +549,7 @@ template reversed(Dimensions...)
}
///ditto
Slice!(N, Range) reversed(size_t N, Range)(Slice!(N, Range) slice, size_t dimension)
in
{
mixin (DimensionRTError);
}
body
{
mixin (_reversedCode);
return slice;
}
///ditto
Slice!(N, Range) reversed(size_t N, Range)(Slice!(N, Range) slice, in size_t[] dimensions...)
Slice!(N, Range) reversed(size_t N, Range, size_t M)(Slice!(N, Range) slice, size_t[M] dimensions...)
in
{
foreach (dimension; dimensions)
@ -584,8 +557,11 @@ in
}
body
{
foreach (dimension; dimensions)
foreach (i; Iota!(0, M))
{
auto dimension = dimensions[i];
mixin (_reversedCode);
}
return slice;
}
@ -904,19 +880,7 @@ template dropOne(Dimensions...)
}
///ditto
Slice!(N, Range) dropOne(size_t N, Range)(Slice!(N, Range) slice, size_t dimension)
in
{
mixin (DimensionRTError);
}
body
{
slice.popFront(dimension);
return slice;
}
///ditto
Slice!(N, Range) dropOne(size_t N, Range)(Slice!(N, Range) slice, in size_t[] dimensions...)
Slice!(N, Range) dropOne(size_t N, Range, size_t M)(Slice!(N, Range) slice, size_t[M] dimensions...)
in
{
foreach (dimension; dimensions)
@ -924,8 +888,11 @@ in
}
body
{
foreach (dimension; dimensions)
foreach (i; Iota!(0, M))
{
auto dimension = dimensions[i];
slice.popFront(dimension);
}
return slice;
}
@ -945,19 +912,7 @@ template dropBackOne(Dimensions...)
}
///ditto
Slice!(N, Range) dropBackOne(size_t N, Range)(Slice!(N, Range) slice, size_t dimension)
in
{
mixin (DimensionRTError);
}
body
{
slice.popBack(dimension);
return slice;
}
///ditto
Slice!(N, Range) dropBackOne(size_t N, Range)(Slice!(N, Range) slice, in size_t[] dimensions...)
Slice!(N, Range) dropBackOne(size_t N, Range, size_t M)(Slice!(N, Range) slice, size_t[M] dimensions...)
in
{
foreach (dimension; dimensions)
@ -965,8 +920,11 @@ in
}
body
{
foreach (dimension; dimensions)
foreach (i; Iota!(0, M))
{
auto dimension = dimensions[i];
slice.popBack(dimension);
}
return slice;
}

View file

@ -75,7 +75,7 @@ Returns:
+/
template pack(K...)
{
@fmb auto pack(size_t N, Range)(auto ref Slice!(N, Range) slice)
@fmb auto pack(size_t N, Range)(Slice!(N, Range) slice)
{
template Template(size_t NInner, Range, R...)
{
@ -174,7 +174,7 @@ Returns:
See_also: $(LREF pack), $(LREF evertPack)
+/
Slice!(N, Range).PureThis unpack(size_t N, Range)(auto ref Slice!(N, Range) slice)
Slice!(N, Range).PureThis unpack(size_t N, Range)(Slice!(N, Range) slice)
{
with (slice) return PureThis(_lengths, _strides, _ptr);
}
@ -200,7 +200,7 @@ Returns:
See_also: $(LREF pack), $(LREF unpack)
+/
SliceFromSeq!(Slice!(N, Range).PureRange, NSeqEvert!(Slice!(N, Range).NSeq))
evertPack(size_t N, Range)(auto ref Slice!(N, Range) slice)
evertPack(size_t N, Range)(Slice!(N, Range) slice)
{
mixin _DefineRet;
static assert(Ret.NSeq.length > 0);
@ -294,7 +294,7 @@ Params:
Returns:
1-dimensional slice composed of diagonal elements
+/
Slice!(1, Range) diagonal(size_t N, Range)(auto ref Slice!(N, Range) slice)
Slice!(1, Range) diagonal(size_t N, Range)(Slice!(N, Range) slice)
{
auto NewN = slice.PureN - N + 1;
mixin _DefineRet;
@ -472,8 +472,7 @@ Params:
Returns:
packed `N`-dimensional slice composed of `N`-dimensional slices
+/
Slice!(N, Slice!(N+1, Range)) blocks(size_t N, Range, Lengths...)(auto ref Slice!(N, Range) slice, Lengths lengths)
if (allSatisfy!(isIndex, Lengths) && Lengths.length == N)
Slice!(N, Slice!(N+1, Range)) blocks(size_t N, Range)(Slice!(N, Range) slice, size_t[N] lengths...)
in
{
foreach (i, length; lengths)
@ -594,8 +593,7 @@ Params:
Returns:
packed `N`-dimensional slice composed of `N`-dimensional slices
+/
Slice!(N, Slice!(N+1, Range)) windows(size_t N, Range, Lengths...)(auto ref Slice!(N, Range) slice, Lengths lengths)
if (allSatisfy!(isIndex, Lengths) && Lengths.length == N)
Slice!(N, Slice!(N+1, Range)) windows(size_t N, Range)(Slice!(N, Range) slice, size_t[N] lengths...)
in
{
foreach (i, length; lengths)
@ -721,11 +719,10 @@ Returns:
Throws:
$(LREF ReshapeException) if the slice cannot be reshaped with the input lengths.
+/
Slice!(Lengths.length, Range)
Slice!(M, Range)
reshape
( size_t N, Range , Lengths... )
(auto ref Slice!(N, Range) slice, Lengths lengths)
if ( allSatisfy!(isIndex, Lengths) && Lengths.length)
(size_t N, Range, size_t M)
(Slice!(N, Range) slice, size_t[M] lengths...)
{
mixin _DefineRet;
foreach (i; Iota!(0, ret.N))
@ -821,14 +818,13 @@ pure unittest
import std.experimental.ndslice.iteration : reversed;
import std.array : array;
auto reshape2(S, L...)(S slice, L lengths)
auto reshape2(S, size_t M)(S slice, size_t[M] lengths...)
{
// Tries to reshape without allocation
try return slice.reshape(lengths);
catch (ReshapeException e)
//allocates the elements and creates a slice
//Note: -1 length is not supported by reshape2
return slice.byElement.array.sliced(lengths);
// Allocates
return slice.slice.reshape(lengths);
}
auto slice =
@ -923,7 +919,7 @@ Params:
Returns:
random access range composed of elements of the `slice`
+/
auto byElement(size_t N, Range)(auto ref Slice!(N, Range) slice)
auto byElement(size_t N, Range)(Slice!(N, Range) slice)
{
with (Slice!(N, Range))
{
@ -1177,7 +1173,7 @@ auto byElement(size_t N, Range)(auto ref Slice!(N, Range) slice)
}
/// ditto
Slice!(1, Range) byElement(size_t N : 1, Range)(auto ref Slice!(N, Range) slice)
Slice!(1, Range) byElement(size_t N : 1, Range)(Slice!(N, Range) slice)
{
return slice;
}
@ -1430,7 +1426,7 @@ Params:
Returns:
forward range composed of all elements of standard simplex of the `slice`
+/
auto byElementInStandardSimplex(size_t N, Range)(auto ref Slice!(N, Range) slice, size_t maxHypercubeLength = size_t.max)
auto byElementInStandardSimplex(size_t N, Range)(Slice!(N, Range) slice, size_t maxHypercubeLength = size_t.max)
{
with (Slice!(N, Range))
{
@ -1518,7 +1514,7 @@ auto byElementInStandardSimplex(size_t N, Range)(auto ref Slice!(N, Range) slice
}
/// ditto
Slice!(1, Range) byElementInStandardSimplex(size_t N : 1, Range)(auto ref Slice!(N, Range) slice, size_t maxHypercubeLength = size_t.max)
Slice!(1, Range) byElementInStandardSimplex(size_t N : 1, Range)(Slice!(N, Range) slice, size_t maxHypercubeLength = size_t.max)
{
if (maxHypercubeLength > slice._lengths[0])
maxHypercubeLength = slice._lengths[0];
@ -1617,14 +1613,7 @@ Returns:
`N`-dimensional slice composed of indexes
See_also: $(LREF IndexSlice), $(LREF iotaSlice)
+/
IndexSlice!(Lengths.length) indexSlice(Lengths...)(Lengths lengths)
if (allSatisfy!(isIndex, Lengths))
{
return .indexSlice!(Lengths.length)([lengths]);
}
///ditto
IndexSlice!N indexSlice(size_t N)(auto ref size_t[N] lengths)
IndexSlice!N indexSlice(size_t N)(size_t[N] lengths...)
{
import std.experimental.ndslice.slice : sliced;
with (typeof(return)) return Range(lengths[1 .. $]).sliced(lengths);
@ -1715,21 +1704,20 @@ Returns:
`N`-dimensional slice composed of indexes
See_also: $(LREF IotaSlice), $(LREF indexSlice)
+/
IotaSlice!(Lengths.length) iotaSlice(Lengths...)(Lengths lengths)
if (allSatisfy!(isIndex, Lengths))
IotaSlice!N iotaSlice(size_t N)(size_t[N] lengths...)
{
return .iotaSlice!(Lengths.length)([lengths]);
return .iotaSlice(lengths, 0);
}
///ditto
IotaSlice!N iotaSlice(size_t N)(auto ref size_t[N] lengths, size_t shift = 0)
IotaSlice!N iotaSlice(size_t N)(size_t[N] lengths, size_t shift)
{
import std.experimental.ndslice.slice : sliced;
return IotaMap!().init.sliced(lengths, shift);
}
///ditto
IotaSlice!N iotaSlice(size_t N)(auto ref size_t[N] lengths, size_t shift, size_t step)
IotaSlice!N iotaSlice(size_t N)(size_t[N] lengths, size_t shift, size_t step)
{
auto iota = iotaSlice(lengths, shift);
foreach (i; Iota!(0, N))
@ -1806,8 +1794,8 @@ Returns:
`n`-dimensional slice composed of identical values, where `n` is dimension count.
See_also: $(REF repeat, std,range)
+/
RepeatSlice!(Lengths.length, T) repeatSlice(T, Lengths...)(T value, Lengths lengths)
if (allSatisfy!(isIndex, Lengths) && !is(T : Slice!(N, Range), size_t N, Range))
RepeatSlice!(M, T) repeatSlice(T, size_t M)(T value, size_t[M] lengths...)
if (!is(T : Slice!(N, Range), size_t N, Range))
{
typeof(return) ret;
foreach (i; Iota!(0, ret.N))
@ -1817,10 +1805,8 @@ RepeatSlice!(Lengths.length, T) repeatSlice(T, Lengths...)(T value, Lengths leng
}
/// ditto
Slice!(Lengths.length, Slice!(N + 1, Range)) repeatSlice(size_t N, Range, Lengths...)(auto ref Slice!(N, Range) slice, Lengths lengths)
if (allSatisfy!(isIndex, Lengths) && Lengths.length)
Slice!(M, Slice!(N + 1, Range)) repeatSlice(size_t N, Range, size_t M)(Slice!(N, Range) slice, size_t[M] lengths...)
{
enum M = Lengths.length;
typeof(return) ret;
ret._ptr = slice._ptr;
foreach (i; Iota!(0, M))
@ -1975,7 +1961,7 @@ template mapSlice(fun...)
{
///
@fmb auto mapSlice(size_t N, Range)
(auto ref Slice!(N, Range) tensor)
(Slice!(N, Range) tensor)
{
// this static if-else block
// may be unified with std.algorithms.iteration.map

View file

@ -49,18 +49,17 @@ Returns:
auto sliced(
Flag!"replaceArrayWithPointer" ra = Yes.replaceArrayWithPointer,
Flag!"allowDownsize" ad = No.allowDownsize,
Range, Lengths...)(Range range, Lengths lengths)
if (!isStaticArray!Range && !isNarrowString!Range
&& allSatisfy!(isIndex, Lengths) && Lengths.length)
Range, size_t N)(Range range, size_t[N] lengths...)
if (!isStaticArray!Range && !isNarrowString!Range && N)
{
return .sliced!(ra, ad, Lengths.length, Range)(range, [lengths]);
return .sliced!(ra, ad)(range, lengths, 0);
}
///ditto
auto sliced(
Flag!"replaceArrayWithPointer" ra = Yes.replaceArrayWithPointer,
Flag!"allowDownsize" ad = No.allowDownsize,
size_t N, Range)(Range range, auto ref in size_t[N] lengths, size_t shift = 0)
size_t N, Range)(Range range, size_t[N] lengths, size_t shift = 0)
if (!isStaticArray!Range && !isNarrowString!Range && N)
in
{
@ -146,13 +145,12 @@ template sliced(Names...)
Flag!`replaceArrayWithPointer` ra = Yes.replaceArrayWithPointer,
Flag!`allowDownsize` ad = No.allowDownsize,
" ~ _Range_Types!Names ~ "
Lengths...)
size_t N)
(" ~ _Range_DeclarationList!Names ~
"Lengths lengths)
if (allSatisfy!(isIndex, Lengths))
"size_t[N] lengths...)
{
alias sliced = .sliced!Names;
return sliced!(ra, ad)(" ~ _Range_Values!Names ~ "[lengths]);
alias sl = .sliced!Names;
return sl!(ra, ad)(" ~ _Range_Values!Names ~ "lengths, 0);
}
auto sliced(
@ -160,7 +158,7 @@ template sliced(Names...)
Flag!`allowDownsize` ad = No.allowDownsize,
size_t N, " ~ _Range_Types!Names ~ ")
(" ~ _Range_DeclarationList!Names ~"
auto ref in size_t[N] lengths,
size_t[N] lengths,
size_t shift = 0)
{
alias RS = AliasSeq!(" ~ _Range_Types!Names ~ ");"
@ -535,20 +533,10 @@ Params:
Returns:
n-dimensional slice
+/
Slice!(Lengths.length, Select!(ra, T*, T[]))
slice(T,
Flag!`replaceArrayWithPointer` ra = Yes.replaceArrayWithPointer,
Lengths...)(Lengths lengths)
if (allSatisfy!(isIndex, Lengths) && Lengths.length)
{
return .slice!(T, ra)([lengths]);
}
/// ditto
Slice!(N, Select!(ra, T*, T[]))
slice(T,
Flag!`replaceArrayWithPointer` ra = Yes.replaceArrayWithPointer,
size_t N)(auto ref in size_t[N] lengths)
size_t N)(size_t[N] lengths...)
{
immutable len = lengthsProduct(lengths);
return new T[len].sliced!ra(lengths);
@ -557,7 +545,7 @@ slice(T,
/// ditto
auto slice(T,
Flag!`replaceArrayWithPointer` ra = Yes.replaceArrayWithPointer,
size_t N)(auto ref in size_t[N] lengths, auto ref T init)
size_t N)(size_t[N] lengths, T init)
{
immutable len = lengthsProduct(lengths);
static if (ra && !hasElaborateAssign!T)
@ -577,7 +565,7 @@ auto slice(T,
/// ditto
auto slice(
Flag!`replaceArrayWithPointer` ra = Yes.replaceArrayWithPointer,
size_t N, Range)(auto ref Slice!(N, Range) slice)
size_t N, Range)(Slice!(N, Range) slice)
{
auto ret = .slice!(Unqual!(slice.DeepElemType), ra)(slice.shape);
ret[] = slice;
@ -620,19 +608,9 @@ Params:
Returns:
uninitialized n-dimensional slice
+/
Slice!(Lengths.length, Select!(ra, T*, T[]))
uninitializedSlice(T,
Flag!`replaceArrayWithPointer` ra = Yes.replaceArrayWithPointer,
Lengths...)(Lengths lengths)
if (allSatisfy!(isIndex, Lengths) && Lengths.length)
{
return .uninitializedSlice!(T, ra)([lengths]);
}
/// ditto
auto uninitializedSlice(T,
Flag!`replaceArrayWithPointer` ra = Yes.replaceArrayWithPointer,
size_t N)(auto ref in size_t[N] lengths)
size_t N)(size_t[N] lengths...)
{
immutable len = lengthsProduct(lengths);
import std.array : uninitializedArray;
@ -662,21 +640,10 @@ Returns:
Note:
`makeSlice` always returns slice with mutable elements
+/
SliceAllocationResult!(Lengths.length, T, ra)
makeSlice(T,
Flag!`replaceArrayWithPointer` ra = Yes.replaceArrayWithPointer,
Allocator,
Lengths...)(auto ref Allocator alloc, Lengths lengths)
if (allSatisfy!(isIndex, Lengths) && Lengths.length)
{
return .makeSlice!(T, ra, Allocator)(alloc, [lengths]);
}
/// ditto
auto makeSlice(
Flag!`replaceArrayWithPointer` ra = Yes.replaceArrayWithPointer,
Allocator,
size_t N, Range)(auto ref Allocator alloc, auto ref Slice!(N, Range) slice)
size_t N, Range)(auto ref Allocator alloc, Slice!(N, Range) slice)
{
alias T = Unqual!(slice.DeepElemType);
return makeSlice!(T, ra)(alloc, slice);
@ -687,7 +654,7 @@ SliceAllocationResult!(N, T, ra)
makeSlice(T,
Flag!`replaceArrayWithPointer` ra = Yes.replaceArrayWithPointer,
Allocator,
size_t N)(auto ref Allocator alloc, auto ref in size_t[N] lengths)
size_t N)(auto ref Allocator alloc, size_t[N] lengths...)
{
import std.experimental.allocator : makeArray;
immutable len = lengthsProduct(lengths);
@ -701,7 +668,7 @@ SliceAllocationResult!(N, T, ra)
makeSlice(T,
Flag!`replaceArrayWithPointer` ra = Yes.replaceArrayWithPointer,
Allocator,
size_t N)(auto ref Allocator alloc, auto ref in size_t[N] lengths, auto ref T init)
size_t N)(auto ref Allocator alloc, size_t[N] lengths, T init)
{
import std.experimental.allocator : makeArray;
immutable len = lengthsProduct(lengths);
@ -715,7 +682,7 @@ SliceAllocationResult!(N, T, ra)
makeSlice(T,
Flag!`replaceArrayWithPointer` ra = Yes.replaceArrayWithPointer,
Allocator,
size_t N, Range)(auto ref Allocator alloc, auto ref Slice!(N, Range) slice)
size_t N, Range)(auto ref Allocator alloc, Slice!(N, Range) slice)
{
import std.experimental.allocator : makeArray;
import std.experimental.ndslice.selection : byElement;
@ -780,22 +747,11 @@ Params:
Returns:
a structure with fields `array` and `slice`
+/
SliceAllocationResult!(Lengths.length, T, ra)
makeUninitializedSlice(T,
Flag!`replaceArrayWithPointer` ra = Yes.replaceArrayWithPointer,
Allocator,
Lengths...)(auto ref Allocator alloc, Lengths lengths)
if (allSatisfy!(isIndex, Lengths) && Lengths.length)
{
return .makeUninitializedSlice!(T, ra, Allocator)(alloc, [lengths]);
}
/// ditto
SliceAllocationResult!(N, T, ra)
makeUninitializedSlice(T,
Flag!`replaceArrayWithPointer` ra = Yes.replaceArrayWithPointer,
Allocator,
size_t N)(auto ref Allocator alloc, auto ref in size_t[N] lengths)
size_t N)(auto ref Allocator alloc, size_t[N] lengths...)
{
immutable len = lengthsProduct(lengths);
auto array = cast(T[]) alloc.allocate(len * T.sizeof);
@ -836,7 +792,7 @@ Params:
Returns:
multidimensional D array
+/
auto ndarray(size_t N, Range)(auto ref Slice!(N, Range) slice)
auto ndarray(size_t N, Range)(Slice!(N, Range) slice)
{
import std.array : array;
static if (N == 1)
@ -1267,25 +1223,42 @@ struct Slice(size_t _N, _Range)
return _strides[dimension] * (_lengths[dimension] - 1);
}
size_t indexStride(Indexes...)(Indexes _indexes) const
if (allSatisfy!(isIndex, Indexes))
size_t indexStride(size_t I)(size_t[I] _indexes...) const
{
mixin(indexStrideCode);
static if (_indexes.length)
{
size_t stride = _strides[0] * _indexes[0];
assert(_indexes[0] < _lengths[0], indexError!(0, N));
foreach (i; Iota!(1, I)) //static
{
assert(_indexes[i] < _lengths[i], indexError!(i, N));
stride += _strides[i] * _indexes[i];
}
return stride;
}
else
{
return 0;
}
}
size_t indexStride(size_t[N] _indexes) const
size_t mathIndexStride(size_t I)(size_t[I] _indexes...) const
{
mixin(indexStrideCode);
static if (_indexes.length)
{
size_t stride = _strides[0] * _indexes[N - 1];
assert(_indexes[N - 1] < _lengths[0], indexError!(N - 1, N));
foreach_reverse (i; Iota!(0, I - 1)) //static
{
assert(_indexes[i] < _lengths[N - 1 - i], indexError!(i, N));
stride += _strides[N - 1 - i] * _indexes[i];
}
size_t mathIndexStride(Indexes...)(Indexes _indexes) const
{
mixin(mathIndexStrideCode);
return stride;
}
size_t mathIndexStride(size_t[N] _indexes) const
else
{
mixin(mathIndexStrideCode);
return 0;
}
}
static if (!hasPtrBehavior!PureRange)
@ -1829,7 +1802,7 @@ struct Slice(size_t _N, _Range)
/++
Overloading `==` and `!=`
+/
bool opEquals(size_t NR, RangeR)(auto ref Slice!(NR, RangeR) rslice)
bool opEquals(size_t NR, RangeR)(Slice!(NR, RangeR) rslice)
if (Slice!(NR, RangeR).PureN == PureN)
{
foreach (i; Iota!(0, PureN))
@ -2088,34 +2061,20 @@ struct Slice(size_t _N, _Range)
/++
$(BOLD Fully defined index)
+/
auto ref opIndex(Repeat!(N, size_t) _indexes)
auto ref opIndex(size_t I)(size_t[I] _indexes...)
if(I && I <= N)
{
static if (PureN == N)
static if (I == PureN)
return _ptr[indexStride(_indexes)];
else
static if (N == I)
return DeepElemType(_lengths[N .. $], _strides[N .. $], _ptr + indexStride(_indexes));
}
///ditto
auto ref opIndex(size_t[N] _indexes)
{
static if (PureN == N)
return _ptr[indexStride(_indexes)];
else
return DeepElemType(_lengths[N .. $], _strides[N .. $], _ptr + indexStride(_indexes));
return Slice!(N - I, Range)(_lengths[I .. $], _strides[I .. $], _ptr + indexStride(_indexes));
}
///ditto
auto ref opCall(Repeat!(N, size_t) _indexes)
{
static if (PureN == N)
return _ptr[mathIndexStride(_indexes)];
else
return DeepElemType(_lengths[N .. $], _strides[N .. $], _ptr + mathIndexStride(_indexes));
}
///ditto
auto ref opCall(size_t[N] _indexes)
auto ref opCall()(size_t[N] _indexes...)
{
static if (PureN == N)
return _ptr[mathIndexStride(_indexes)];
@ -2471,14 +2430,7 @@ struct Slice(size_t _N, _Range)
/++
Assignment of a value (e.g. a number) to a $(B fully defined index).
+/
auto ref opIndexAssign(T)(T value, Repeat!(N, size_t) _indexes)
{
return _ptr[indexStride(_indexes)] = value;
}
static if (PureN == N)
/// ditto
auto ref opIndexAssign(T)(T value, size_t[N] _indexes)
auto ref opIndexAssign(T)(T value, size_t[N] _indexes...)
{
return _ptr[indexStride(_indexes)] = value;
}
@ -2524,14 +2476,7 @@ struct Slice(size_t _N, _Range)
/++
Op Assignment `op=` of a value (e.g. a number) to a $(B fully defined index).
+/
auto ref opIndexOpAssign(string op, T)(T value, Repeat!(N, size_t) _indexes)
{
mixin (`return _ptr[indexStride(_indexes)] ` ~ op ~ `= value;`);
}
static if (PureN == N)
/// ditto
auto ref opIndexOpAssign(string op, T)(T value, size_t[N] _indexes)
auto ref opIndexOpAssign(string op, T)(T value, size_t[N] _indexes...)
{
mixin (`return _ptr[indexStride(_indexes)] ` ~ op ~ `= value;`);
}
@ -2781,15 +2726,7 @@ struct Slice(size_t _N, _Range)
/++
Increment `++` and Decrement `--` operators for a $(B fully defined index).
+/
auto ref opIndexUnary(string op)(Repeat!(N, size_t) _indexes)
if (op == `++` || op == `--`)
{
mixin (`return ` ~ op ~ `_ptr[indexStride(_indexes)];`);
}
static if (PureN == N)
///ditto
auto ref opIndexUnary(string op)(size_t[N] _indexes)
auto ref opIndexUnary(string op)(size_t[N] _indexes...)
if (op == `++` || op == `--`)
{
mixin (`return ` ~ op ~ `_ptr[indexStride(_indexes)];`);