mirror of
https://github.com/dlang/phobos.git
synced 2025-05-04 17:11:26 +03:00
reduce ndslice template bloat part 1
This commit is contained in:
parent
81c09ed1c1
commit
c39ec4cd43
4 changed files with 106 additions and 261 deletions
|
@ -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__) =
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)];`);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue