std.experimental.ndslice.slice
Source: std/experimental/ndslice/slice.d
- auto
sliced
(Flag!"replaceArrayWithPointer" ra = Yes.replaceArrayWithPointer, Flag!"allowDownsize" ad = No.allowDownsize, Range, size_t N)(Rangerange
, size_t[N]lengths
...)
if (!isStaticArray!Range && !isNarrowString!Range && N);
autosliced
(Flag!"replaceArrayWithPointer" ra = Yes.replaceArrayWithPointer, Flag!"allowDownsize" ad = No.allowDownsize, size_t N, Range)(Rangerange
, size_t[N]lengths
, size_tshift
= 0)
if (!isStaticArray!Range && !isNarrowString!Range && N);
templatesliced
(Names...) if (Names.length && !anySatisfy!(isType, Names) && allSatisfy!(isStringValue, Names))
autosliced
(Flag!"replaceArrayWithPointer" ra = Yes.replaceArrayWithPointer, Flag!"allowDownsize" ad = No.allowDownsize, Range)(Rangerange
)
if (!isStaticArray!Range && !isNarrowString!Range && hasLength!Range); - Creates an n-dimensional slice-shell over a
range
.Parameters:Range range
a random access range
or an array; only index operator auto opIndex(size_t index) is required for ranges. The length of therange
should be equal to the sum ofshift
and the product oflengths
. If ad, the length of therange
should be greater than or equal to the sum ofshift
and the product oflengths
.size_t[N] lengths
list of lengths
for each dimensionsize_t shift
index of the first element of a range
. The firstshift
elements ofrange
are ignored.Names names of elements in a slice tuple. Slice tuple is a slice, which holds single set of lengths
and strides for a number of ranges.ra If yes, the array will be replaced with its pointer to improve performance. Use no for compile time function evaluation. ad If yes, no assert error will be thrown for range
, which has a length and its length is greater then the sum ofshift
and the product oflengths
.Returns:n-dimensional sliceExamples:Creates a slice from an array.auto slice = slice!int(5, 6, 7); assert(slice.length == 5); assert(slice.elementsCount == 5 * 6 * 7); static assert(is(typeof(slice) == Slice!(3, int*)));
Examples:Creates a slice usingshift
parameter.import std.range : iota; auto slice = (5 * 6 * 7 + 9).iota.sliced([5, 6, 7], 9); assert(slice.length == 5); assert(slice.elementsCount == 5 * 6 * 7); assert(slice[0, 0, 0] == 9);
Examples:Creates an 1-dimensional slice over arange
.import std.range : iota; auto slice = 10.iota.sliced; assert(slice.length == 10);
Examples:Vandermonde matrixauto vandermondeMatrix(Slice!(1, double*) x) { auto ret = slice!double(x.length, x.length); foreach (i; 0 .. x.length) foreach (j; 0 .. x.length) ret[i, j] = x[i] ^^ j; return ret; } auto x = [1.0, 2, 3, 4, 5].sliced(5); auto v = vandermondeMatrix(x); assert(v == [[ 1.0, 1, 1, 1, 1], [ 1.0, 2, 4, 8, 16], [ 1.0, 3, 9, 27, 81], [ 1.0, 4, 16, 64, 256], [ 1.0, 5, 25, 125, 625]]);
Examples:Creates a slice composed of named elements, each one of which corresponds to a given argument. See also assumeSameStructure.import std.algorithm.comparison : equal; import std.experimental.ndslice.selection : byElement; import std.range : iota; auto alpha = 12.iota; auto beta = new int[12]; auto m = sliced!("a", "b")(alpha, beta, 4, 3); foreach (r; m) foreach (e; r) e.b = e.a; assert(equal(alpha, beta)); beta[] = 0; foreach (e; m.byElement) e.b = e.a; assert(equal(alpha, beta));
Examples:Random accessrange
primitives for slices over user defined typesstruct MyIota { //`[index]` operator overloading auto opIndex(size_t index) { return index; } } alias S = Slice!(3, MyIota); import std.range.primitives; static assert(hasLength!S); static assert(hasSlicing!S); static assert(isRandomAccessRange!S); auto slice = MyIota().sliced(20, 10); assert(slice[1, 2] == 12); auto sCopy = slice.save; assert(slice[1, 2] == 12);
Examples:Slice tuple and flagsimport std.typecons : Yes, No; static immutable a = [1, 2, 3, 4, 5, 6]; static immutable b = [1.0, 2, 3, 4, 5, 6]; alias namedSliced = sliced!("a", "b"); auto slice = namedSliced!(No.replaceArrayWithPointer, Yes.allowDownsize) (a, b, 2, 3); assert(slice[1, 2].a == slice[1, 2].b);
- template
assumeSameStructure
(Names...) if (Names.length && !anySatisfy!(isType, Names) && allSatisfy!(isStringValue, Names)) - Groups slices into a slice tuple. The slices must have identical structure. Slice tuple is a slice, which holds single set of lengths and strides for a number of ranges.Parameters:
Names names of elements in a slice tuple Returns:n-dimensional sliceSee Also:Examples:import std.algorithm.comparison : equal; import std.experimental.ndslice.selection : byElement, iotaSlice; auto alpha = iotaSlice(4, 3); auto beta = slice!int(4, 3); auto m = assumeSameStructure!("a", "b")(alpha, beta); foreach (r; m) foreach (e; r) e.b = cast(int)e.a; assert(alpha == beta); beta[] = 0; foreach (e; m.byElement) e.b = cast(int)e.a; assert(alpha == beta);
Examples:import std.algorithm.iteration : map, sum, reduce; import std.algorithm.comparison : max; import std.experimental.ndslice.iteration : transposed; import std.typecons : No; /// Returns maximal column average. auto maxAvg(S)(S matrix) { return matrix.transposed.map!sum.reduce!max / matrix.length; } enum matrix = [1, 2, 3, 4].sliced!(No.replaceArrayWithPointer)(2, 2); ///Сompile time function evaluation static assert(maxAvg(matrix) == 3);
Examples:import std.algorithm.iteration : map, sum, reduce; import std.algorithm.comparison : max; import std.experimental.ndslice.iteration : transposed; import std.typecons : No; /// Returns maximal column average. auto maxAvg(S)(S matrix) { return matrix.transposed.map!sum.reduce!max / matrix.length; } enum matrix = [1, 2, 3, 4].sliced!(No.replaceArrayWithPointer)(2, 2); ///Сompile time function evaluation static assert(maxAvg(matrix) == 3);
- Slice!(N, Select!(ra, T*, T[]))
slice
(T, Flag!"replaceArrayWithPointer" ra = Yes.replaceArrayWithPointer, size_t N)(size_t[N]lengths
...);
autoslice
(T, Flag!"replaceArrayWithPointer" ra = Yes.replaceArrayWithPointer, size_t N)(size_t[N]lengths
, Tinit
);
autoslice
(Flag!"replaceArrayWithPointer" ra = Yes.replaceArrayWithPointer, size_t N, Range)(Slice!(N, Range)slice
); - Creates an array and an n-dimensional
slice
over it.Parameters:size_t[N] lengths
list of lengths
for each dimensionSlice!(N, Range) slice
slice
to copy shape and data fromReturns:n-dimensionalslice
Examples:auto tensor = slice!int(5, 6, 7); assert(tensor.length == 5); assert(tensor.elementsCount == 5 * 6 * 7); static assert(is(typeof(tensor) == Slice!(3, int*))); // creates duplicate using `slice` auto dup = tensor.slice; assert(dup == tensor);
Examples:auto tensor = slice([2, 3], 5); assert(tensor.elementsCount == 2 * 3); assert(tensor[1, 1] == 5);
- auto
uninitializedSlice
(T, Flag!"replaceArrayWithPointer" ra = Yes.replaceArrayWithPointer, size_t N)(size_t[N]lengths
...); - Creates an uninitialized array and an n-dimensional slice over it.Parameters:
size_t[N] lengths
list of lengths
for each dimensionslice slice to copy shape and data from Returns:uninitialized n-dimensional sliceExamples:auto tensor = uninitializedSlice!int(5, 6, 7); assert(tensor.length == 5); assert(tensor.elementsCount == 5 * 6 * 7); static assert(is(typeof(tensor) == Slice!(3, int*)));
- auto
makeSlice
(Flag!"replaceArrayWithPointer" ra = Yes.replaceArrayWithPointer, Allocator, size_t N, Range)(auto ref Allocatoralloc
, Slice!(N, Range)slice
);
SliceAllocationResult!(N, T, ra)makeSlice
(T, Flag!"replaceArrayWithPointer" ra = Yes.replaceArrayWithPointer, Allocator, size_t N)(auto ref Allocatoralloc
, size_t[N]lengths
...);
SliceAllocationResult!(N, T, ra)makeSlice
(T, Flag!"replaceArrayWithPointer" ra = Yes.replaceArrayWithPointer, Allocator, size_t N)(auto ref Allocatoralloc
, size_t[N]lengths
, Tinit
);
SliceAllocationResult!(N, T, ra)makeSlice
(T, Flag!"replaceArrayWithPointer" ra = Yes.replaceArrayWithPointer, Allocator, size_t N, Range)(auto ref Allocatoralloc
, Slice!(N, Range)slice
); - Allocates an array through a specified allocator and creates an n-dimensional
slice
over it. See also std.experimental.allocator.Parameters:Allocator alloc
allocator size_t[N] lengths
list of lengths
for each dimensionT init
default value for array initialization Slice!(N, Range) slice
slice
to copy shape and data fromReturns:a structure with fields array andslice
Note:
makeSlice
always returnsslice
with mutable elementsExamples:import std.experimental.allocator; import std.experimental.allocator.mallocator; auto tup = makeSlice!int(Mallocator.instance, 2, 3, 4); assert(tup.array.length == 24); assert(tup.slice.elementsCount == 24); assert(tup.array.ptr == &tup.slice[0, 0, 0]); // makes duplicate using `makeSlice` tup.slice[0, 0, 0] = 3; auto dup = makeSlice(Mallocator.instance, tup.slice); assert(dup.slice == tup.slice); Mallocator.instance.dispose(tup.array); Mallocator.instance.dispose(dup.array);
Examples:Initialization with default valueimport std.experimental.allocator; import std.experimental.allocator.mallocator; auto tup = makeSlice(Mallocator.instance, [2, 3, 4], 10); auto slice = tup.slice; assert(slice[1, 1, 1] == 10); Mallocator.instance.dispose(tup.array);
- SliceAllocationResult!(N, T, ra)
makeUninitializedSlice
(T, Flag!"replaceArrayWithPointer" ra = Yes.replaceArrayWithPointer, Allocator, size_t N)(auto ref Allocatoralloc
, size_t[N]lengths
...); - Allocates an uninitialized array through a specified allocator and creates an n-dimensional slice over it. See also std.experimental.allocator.Parameters:
Allocator alloc
allocator size_t[N] lengths
list of lengths
for each dimensioninit default value for array initialization slice slice to copy shape and data from Returns:a structure with fields array and sliceExamples:import std.experimental.allocator; import std.experimental.allocator.mallocator; auto tup = makeUninitializedSlice!int(Mallocator.instance, 2, 3, 4); assert(tup.array.length == 24); assert(tup.slice.elementsCount == 24); assert(tup.array.ptr == &tup.slice[0, 0, 0]); Mallocator.instance.dispose(tup.array);
- struct
SliceAllocationResult
(size_t N, T, Flag!"replaceArrayWithPointer" ra); - Structure used by makeSlice and makeUninitializedSlice.
- T[]
array
; - Slice!(N, Select!(ra, T*, T[]))
slice
;
- auto
ndarray
(size_t N, Range)(Slice!(N, Range)slice
); - Creates a common n-dimensional array from a
slice
.Parameters:Slice!(N, Range) slice
slice
Returns:multidimensional D arrayExamples:import std.experimental.ndslice.selection : iotaSlice; auto slice = iotaSlice(3, 4); auto m = slice.ndarray; static assert(is(typeof(m) == size_t[][])); assert(m == [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]);
- auto
makeNdarray
(T, Allocator, size_t N, Range)(auto ref Allocatoralloc
, Slice!(N, Range)slice
); - Allocates a common n-dimensional array using data from a
slice
.Parameters:Allocator alloc
allocator (optional) Slice!(N, Range) slice
slice
Returns:multidimensional D arrayExamples:import std.experimental.allocator; import std.experimental.allocator.mallocator; import std.experimental.ndslice.selection : iotaSlice; auto slice = iotaSlice(3, 4); auto m = Mallocator.instance.makeNdarray!long(slice); static assert(is(typeof(m) == long[][])); static immutable ar = [[0L, 1, 2, 3], [4L, 5, 6, 7], [8L, 9, 10, 11]]; assert(m == ar); foreach (ref row; m) Mallocator.instance.dispose(row); Mallocator.instance.dispose(m);
- @property auto
shape
(T)(T[]array
, ref interr
); - Shape of a common n-dimensional
array
.Parameters:T[] array
common n-dimensional array
int err
error flag Returns:staticarray
of dimensions type of size_t[n]Examples:int err; size_t[2] shape = [[1, 2, 3], [4, 5, 6]].shape(err); assert(shape == [2, 3]); assert(err == 0); [[1, 2], [4, 5, 6]].shape(err); assert(err != 0);
Examples:Slice from ndarrayint err; auto array = [[1, 2, 3], [4, 5, 6]]; auto slice = array.shape(err).slice!int; assert(err == 0); slice[] = [[1, 2, 3], [4, 5, 6]]; assert(slice == array);
- template
as
(T) - Convenience function that creates a lazy view, where each element of the original slice is converted to the type T. It uses mapSlice and to composition under the hood.Parameters:
Slice!(N, Range) slice a slice to create a view on. Returns:A lazy slice with elements converted to the type T.Examples:import std.experimental.ndslice.slice : as; import std.experimental.ndslice.selection : diagonal; auto matrix = slice!double([2, 2], 0); auto stringMatrixView = matrix.as!string; assert(stringMatrixView == [["0", "0"], ["0", "0"]]); matrix.diagonal[] = 1; assert(stringMatrixView == [["1", "0"], ["0", "1"]]); /// allocate new slice composed of strings Slice!(2, string*) stringMatrix = stringMatrixView.slice;
- auto
as
(size_t N, Range)(Slice!(N, Range)slice
);
- class
SliceException
: object.Exception; - Base Exception class for std.experimental.ndslice.
- pure nothrow @nogc @safe this(string
msg
, stringfile
= __FILE__, uintline
= cast(uint)1041, Throwablenext
= null);
- template
DeepElementType
(S : Slice!(N, Range), size_t N, Range) - Returns the element type of the Slice type.Examples:
import std.range : iota; static assert(is(DeepElementType!(Slice!(4, const(int)[])) == const(int))); static assert(is(DeepElementType!(Slice!(4, immutable(int)*)) == immutable(int))); static assert(is(DeepElementType!(Slice!(4, typeof(100.iota))) == int)); //packed slice static assert(is(DeepElementType!(Slice!(2, Slice!(5, int*))) == Slice!(4, int*)));
- struct
Structure
(size_t N); - Presents .Slice.structure.
- size_t[N]
lengths
; - sizediff_t[N]
strides
;
- struct
Slice
(size_t _N, _Range) if (_N && _N < 256LU && (!is(Unqual!_Range :Slice
!(N0, Range0), size_t N0, Range0) && (isPointer!_Range || is(typeof(_Range.init[size_t.init]))) || is(_Range ==Slice
!(N1, Range1), size_t N1, Range1))); - Presents an n-dimensional view over a range.
Definitions
In order to change data in a slice using overloaded operators such as =, +=, ++, a syntactic structure of type <slice to change>[<index and interval sequence...>] must be used. It is worth noting that just like for regular arrays, operations a = b and a[] = b have different meanings. In the first case, after the operation is carried out, a simply points at the same data as b does, and the data which a previously pointed at remains unmodified. Here, а and b must be of the same type. In the second case, a points at the same data as before, but the data itself will be changed. In this instance, the number of dimensions of b may be less than the number of dimensions of а; and b can be aSlice
, a regular multidimensional array, or simply a value (e.g. a number). In the following table you will find the definitions you might come across in comments on operator overloading.Definition Examples at N == 3 An interval is a part of a sequence of type i .. j. 2..$-3, 0..4 @@@DEPRECATED_2017-04@@@An index is a part of a sequence of type i. 3, $-1 @@@DEPRECATED_2017-04@@@A partially defined slice is a sequence composed of intervals and indexes with an overall length strictly less than N. [3], [0..$], [3, 3], [0..$,0..3], [0..$,2] @@@DEPRECATED_2017-04@@@A fully defined index is a sequence composed only of indexes with an overall length equal to N. [2,3,1] @@@DEPRECATED_2017-04@@@A fully defined slice is an empty sequence or a sequence composed of indexes and at least one interval with an overall length equal to N. [], [3..$,0..3,0..$-1], [2,0..$,1] @@@DEPRECATED_2017-04@@@Internal Binary Representation
MultidimensionalSlice
is a structure that consists of lengths, strides, and a pointer. For ranges, a shell is used instead of a pointer. This shell contains a shift of the current initial element of a multidimensional slice and the range itself. With the exception of overloaded operators, no functions in this package change or copy data. The operations are only carried out on lengths, strides, and pointers. If a slice is defined over a range, only the shift of the initial element changes instead of the pointer.Internal Representation for Pointers
Type definitionSlice!(N, T*)
SchemaSlice!(N, T*) size_t[N] lengths sizediff_t[N] strides T* ptr
Example: Definitions
import std.experimental.ndslice; auto a = new double[24]; Slice!(3, double*) s = a.sliced(2, 3, 4); Slice!(3, double*) t = s.transposed!(1, 2, 0); Slice!(3, double*) r = t.reversed!1;
Representations________________________ lengths[0] ::= 2 lengths[1] ::= 3 lengths[2] ::= 4 strides[0] ::= 12 strides[1] ::= 4 strides[2] ::= 1 ptr ::= &a[0] t____transposed!(1, 2, 0) lengths[0] ::= 3 lengths[1] ::= 4 lengths[2] ::= 2 strides[0] ::= 4 strides[1] ::= 1 strides[2] ::= 12 ptr ::= &a[0] r______________reversed!1 lengths[0] ::= 2 lengths[1] ::= 3 lengths[2] ::= 4 strides[0] ::= 12 strides[1] ::= -4 strides[2] ::= 1 ptr ::= &a[8] // (old_strides[1] * (lengths[1] - 1)) = 8
Internal Representation for Ranges
Type definitionSlice!(N, Range)
RepresentationSlice!(N, Range) size_t[N] lengths sizediff_t[N] strides PtrShell!T ptr sizediff_t shift Range range
Example: Definitions
import std.experimental.ndslice; import std.range : iota; auto a = iota(24); alias A = typeof(a); Slice!(3, A) s = a.sliced(2, 3, 4); Slice!(3, A) t = s.transposed!(1, 2, 0); Slice!(3, A) r = t.reversed!1;
Representations________________________ lengths[0] ::= 2 lengths[1] ::= 3 lengths[2] ::= 4 strides[0] ::= 12 strides[1] ::= 4 strides[2] ::= 1 shift ::= 0 range ::= a t____transposed!(1, 2, 0) lengths[0] ::= 3 lengths[1] ::= 4 lengths[2] ::= 2 strides[0] ::= 4 strides[1] ::= 1 strides[2] ::= 12 shift ::= 0 range ::= a r______________reversed!1 lengths[0] ::= 2 lengths[1] ::= 3 lengths[2] ::= 4 strides[0] ::= 12 strides[1] ::= -4 strides[2] ::= 1 shift ::= 8 // (old_strides[1] * (lengths[1] - 1)) = 8 range ::= a
Examples:Slicing, indexing, and arithmetic operations.import std.experimental.ndslice.iteration : transposed; import std.experimental.ndslice.selection : iotaSlice; auto tensor = iotaSlice(3, 4, 5).slice; assert(tensor[1, 2] == tensor[1][2]); assert(tensor[1, 2, 3] == tensor[1][2][3]); assert( tensor[0..$, 0..$, 4] == tensor.transposed!2[4]); assert(&tensor[0..$, 0..$, 4][1, 2] is &tensor[1, 2, 4]); tensor[1, 2, 3]++; //`opIndex` returns value by reference. --tensor[1, 2, 3]; //`opUnary` ++tensor[]; tensor[] -= 1; // `opIndexAssing` accepts only fully defined indexes and slices. // Use an additional empty slice `[]`. static assert(!__traits(compiles, tensor[0 .. 2] *= 2)); tensor[0 .. 2][] *= 2; //OK, empty slice tensor[0 .. 2, 3, 0..$] /= 2; //OK, 3 index or slice positions are defined. //fully defined index may be replaced by a static array size_t[3] index = [1, 2, 3]; assert(tensor[index] == tensor[1, 2, 3]);
Examples:Operations with rvalue slices.import std.experimental.ndslice.iteration : transposed, everted; auto tensor = slice!int(3, 4, 5); auto matrix = slice!int(3, 4); auto vector = slice!int(3); foreach (i; 0..3) vector[i] = i; // fills matrix columns matrix.transposed[] = vector; // fills tensor with vector // transposed tensor shape is (4, 5, 3) // vector shape is ( 3) tensor.transposed!(1, 2)[] = vector; // transposed tensor shape is (5, 3, 4) // matrix shape is ( 3, 4) tensor.transposed!2[] += matrix; // transposed tensor shape is (5, 4, 3) // transposed matrix shape is ( 4, 3) tensor.everted[] ^= matrix.transposed; // XOR
Examples:Creating a slice from text. See also std.format.import std.algorithm, std.conv, std.exception, std.format, std.functional, std.string, std.range; Slice!(2, int*) toMatrix(string str) { string[][] data = str.lineSplitter.filter!(not!empty).map!split.array; size_t rows = data .length.enforce("empty input"); size_t columns = data[0].length.enforce("empty first row"); data.each!(a => enforce(a.length == columns, "rows have different lengths")); auto slice = slice!int(rows, columns); foreach (i, line; data) foreach (j, num; line) slice[i, j] = num.to!int; return slice; } auto input = "\r1 2 3\r\n 4 5 6\n"; auto matrix = toMatrix(input); assert(matrix == [[1, 2, 3], [4, 5, 6]]); // back to text auto text2 = format("%(%(%s %)\n%)\n", matrix); assert(text2 == "1 2 3\n4 5 6\n");
- size_t[PureN]
_lengths
; - Direct access to the lengths. Use for ndslice plugins only.
- sizediff_t[PureN]
_strides
; - Direct access to the strides. Use for ndslice plugins only.
- SlicePtr!PureRange
_ptr
; - Direct access to the pointer. Use for ndslice plugins only.
- this(in size_t[PureN]
lengths
, in sizediff_t[PureN]strides
, PureRangerange
); - This constructor should be used only for integration with other languages or libraries such as Julia and numpy.Parameters:
size_t[PureN] lengths
lengths
sizediff_t[PureN] strides
strides
PureRange range
range
or pointer to iterate onExamples:Creates a 2-dimentional slice with customstrides
.import std.experimental.ndslice.selection : byElement; import std.algorithm.comparison : equal; import std.range : only; uint[8] array = [1, 2, 3, 4, 5, 6, 7, 8]; auto slice = Slice!(2, uint*)([2, 2], [4, 1], array.ptr); assert(&slice[0, 0] == &array[0]); assert(&slice[0, 1] == &array[1]); assert(&slice[1, 0] == &array[4]); assert(&slice[1, 1] == &array[5]); assert(slice.byElement.equal(only(1, 2, 5, 6))); array[2] = 42; assert(slice.byElement.equal(only(1, 2, 5, 6))); array[1] = 99; assert(slice.byElement.equal(only(1, 99, 5, 6)));
- const pure nothrow @nogc ref @trusted ConstThis
toConst
(); - Implicit cast to const slices in case of underlaying range is a pointer.
- @property auto
ptr
(); - Returns:Pointer to the first element of a slice if slice is defined as Slice!(N, T*) or plain structure with two fields shift and range otherwise. In second case the expression range[shift] refers to the first element. For slices with named elements the type of a return value has the same behavior like a pointer.
Note:
ptr
is defined only for non-packed slices.Attention:
ptr
refers to the first element in the memory representation if and only if all strides are positive. - const @property size_t[N]
shape
(); - Returns:static array of lengthsSee Also:Examples:Regular slice
import std.experimental.ndslice.selection : iotaSlice; assert(iotaSlice(3, 4, 5) .shape == cast(size_t[3])[3, 4, 5]);
Examples:Packed sliceimport std.experimental.ndslice.selection : pack, iotaSlice; assert(iotaSlice(3, 4, 5, 6, 7) .pack!2 .shape == cast(size_t[3])[3, 4, 5]);
- const @property Structure!N
structure
(); - Returns:static array of lengths and static array of stridesSee Also:Examples:Regular slice
import std.experimental.ndslice.selection : iotaSlice; assert(iotaSlice(3, 4, 5) .structure == Structure!3([3, 4, 5], [20, 5, 1]));
Examples:Modified regular sliceimport std.experimental.ndslice.selection : pack, iotaSlice; import std.experimental.ndslice.iteration : reversed, strided, transposed; assert(iotaSlice(3, 4, 50) .reversed!2 //makes stride negative .strided!2(6) //multiplies stride by 6 and changes corresponding length .transposed!2 //brings dimension `2` to the first position .structure == Structure!3([9, 3, 4], [-6, 200, 50]));
Examples:Packed sliceimport std.experimental.ndslice.selection : pack, iotaSlice; assert(iotaSlice(3, 4, 5, 6, 7) .pack!2 .structure == Structure!3([3, 4, 5], [20 * 42, 5 * 42, 1 * 42]));
- @property auto
save
(); - Forward range primitive.Examples:Forward range
import std.experimental.ndslice.selection : iotaSlice; auto slice = iotaSlice(2, 3).save;
Examples:Pointer type.//slice type is `Slice!(2, int*)` auto slice = slice!int(2, 3).save;
- const @property size_t
length
(size_t dimension = 0)()
if (dimension < N); - Multidimensional
length
property.Returns:length
of the corresponding dimensionSee Also:Examples:import std.experimental.ndslice.selection : iotaSlice; auto slice = iotaSlice(3, 4, 5); assert(slice.length == 3); assert(slice.length!0 == 3); assert(slice.length!1 == 4); assert(slice.length!2 == 5);
- const @property sizediff_t
stride
(size_t dimension = 0)()
if (dimension < N); - Multidimensional
stride
property.Returns:stride
of the corresponding dimensionSee Also:Examples:Regular sliceimport std.experimental.ndslice.selection : iotaSlice; auto slice = iotaSlice(3, 4, 5); assert(slice.stride == 20); assert(slice.stride!0 == 20); assert(slice.stride!1 == 5); assert(slice.stride!2 == 1);
Examples:Modified regular sliceimport std.experimental.ndslice.iteration : reversed, strided, swapped; import std.experimental.ndslice.selection : iotaSlice; assert(iotaSlice(3, 4, 50) .reversed!2 //makes stride negative .strided!2(6) //multiplies stride by 6 and changes the corresponding length .swapped!(1, 2) //swaps dimensions `1` and `2` .stride!1 == -6);
- const @property bool
empty
(size_t dimension = 0)()
if (dimension < N);
@property ref autofront
(size_t dimension = 0)()
if (dimension < N);
@property autofront
(size_t dimension = 0, T)(Tvalue
)
if (dimension == 0);
@property ref autoback
(size_t dimension = 0)()
if (dimension < N);
@property autoback
(size_t dimension = 0, T)(Tvalue
)
if (dimension == 0);
voidpopFront
(size_t dimension = 0)()
if (dimension < N);
voidpopBack
(size_t dimension = 0)()
if (dimension < N);
voidpopFrontExactly
(size_t dimension = 0)(size_tn
)
if (dimension < N);
voidpopBackExactly
(size_t dimension = 0)(size_tn
)
if (dimension < N);
voidpopFrontN
(size_t dimension = 0)(size_tn
)
if (dimension < N);
voidpopBackN
(size_t dimension = 0)(size_tn
)
if (dimension < N); - Multidimensional input range primitive.Examples:
import std.range.primitives; import std.experimental.ndslice.selection : iotaSlice; auto slice = iotaSlice(10, 20, 30); static assert(isRandomAccessRange!(typeof(slice))); static assert(hasSlicing!(typeof(slice))); static assert(hasLength!(typeof(slice))); assert(slice.shape == cast(size_t[3])[10, 20, 30]); slice.popFront; slice.popFront!1; slice.popBackExactly!2(4); assert(slice.shape == cast(size_t[3])[9, 19, 26]); auto matrix = slice.front!1; assert(matrix.shape == cast(size_t[2])[9, 26]); auto column = matrix.back!1; assert(column.shape == cast(size_t[1])[9]); slice.popFrontExactly!1(slice.length!1); assert(slice.empty == false); assert(slice.empty!1 == true); assert(slice.empty!2 == false); assert(slice.shape == cast(size_t[3])[9, 0, 26]); assert(slice.back.front!1.empty); slice.popFrontN!0(40); slice.popFrontN!2(40); assert(slice.shape == cast(size_t[3])[0, 0, 0]);
- const bool
anyEmpty
(); - Returns:true if for any dimension the length equals to 0, and false otherwise.Examples:
import std.experimental.ndslice.selection : iotaSlice; auto s = iotaSlice(2, 3); assert(!s.anyEmpty); s.popFrontExactly!1(3); assert(s.anyEmpty);
- ref auto
backward
(size_t[N]index
); - Convenience function for
backward
indexing.Returns:this[$-index
[0], $-index
[1], ..., $-index
[N-1]]Examples:import std.experimental.ndslice.selection : iotaSlice; auto s = iotaSlice(2, 3); assert(s[$ - 1, $ - 2] == s.backward([1, 2]));
- const size_t
elementsCount
(); - Returns:Total number of elements in a sliceExamples:Regular slice
import std.experimental.ndslice.selection : iotaSlice; assert(iotaSlice(3, 4, 5).elementsCount == 60);
Examples:Packed sliceimport std.experimental.ndslice.selection : pack, evertPack, iotaSlice; auto slice = iotaSlice(3, 4, 5, 6, 7, 8); auto p = slice.pack!2; assert(p.elementsCount == 360); assert(p[0, 0, 0, 0].elementsCount == 56); assert(p.evertPack.elementsCount == 56);
- bool
opEquals
(size_t NR, RangeR)(Slice!(NR, RangeR)rslice
)
if (Slice!(NR, RangeR).PureN == PureN);
boolopEquals
(T)(T[]rarrary
); - Overloading == and !=Examples:
auto a = [1, 2, 3, 4].sliced(2, 2); assert(a != [1, 2, 3, 4, 5, 6].sliced(2, 3)); assert(a != [[1, 2, 3], [4, 5, 6]]); assert(a == [1, 2, 3, 4].sliced(2, 2)); assert(a == [[1, 2], [3, 4]]); assert(a != [9, 2, 3, 4].sliced(2, 2)); assert(a != [[9, 2], [3, 4]]);
- const @safe size_t
toHash
(); - Computes hash value using MurmurHash3 algorithms without the finalization step. Built-in associative arrays have the finalization step.Returns:Hash value type of size_t.See Also:Examples:
import std.experimental.ndslice.selection : iotaSlice; const sl = iotaSlice(3, 7); size_t hash = sl.toHash;
Examples:import std.experimental.ndslice.iteration : allReversed; import std.experimental.ndslice.selection : iotaSlice; // hash is the same for allocated data and for generated data auto a = iotaSlice(3, 7); auto b = iotaSlice(3, 7).slice; assert(a.toHash == b.toHash); assert(typeid(typeof(a)).getHash(&a) == typeid(typeof(b)).getHash(&b)); // hash does not depend on strides a = iotaSlice(3, 7).allReversed; b = iotaSlice(3, 7).allReversed.slice; assert(a.toHash == b.toHash); assert(typeid(typeof(a)).getHash(&a) == typeid(typeof(b)).getHash(&b));
- const @trusted auto
toMurmurHash3
(uint size, uint opt = size_t.sizeof == 8 ? 64 : 32)(); - Computes hash value using MurmurHash3 algorithms without the finalization step.Returns:Hash value type of MurmurHash3!(size, opt).get().See Also:
- ref auto
opIndex
(size_t I)(size_t[I]_indexes
...)
if (I && I <= N);
ref autoopCall
()(size_t[N]_indexes
...); -
Examples:
auto slice = slice!int(5, 2); auto q = &slice[3, 1]; // D & C order auto p = &slice(1, 3); // Math & Fortran order assert(p is q); *q = 4; assert(slice[3, 1] == 4); // D & C order assert(slice(1, 3) == 4); // Math & Fortran order size_t[2] indexP = [1, 3]; size_t[2] indexQ = [3, 1]; assert(slice[indexQ] == 4); // D & C order assert(slice(indexP) == 4); // Math & Fortran order
- auto
opIndex
(Slices...)(Slicesslices
)
if (isPureSlice!Slices); -
Examples:
auto slice = slice!int(5, 3); /// Fully defined slice assert(slice[] == slice); auto sublice = slice[0..$-2, 1..$]; /// Partially defined slice auto row = slice[3]; auto col = slice[0..$, 1];
- void
opIndexAssign
(size_t RN, RRange, Slices...)(Slice!(RN, RRange)value
, Slicesslices
)
if (isFullPureSlice!Slices && RN <= ReturnType!(opIndex!Slices).N); - Assignment of a
value
of Slice type to a fully defined slice.Optimization: SIMD instructions may be used if both
slices
have the last stride equals to 1.Examples:auto a = slice!int(2, 3); auto b = [1, 2, 3, 4].sliced(2, 2); a[0..$, 0..$-1] = b; assert(a == [[1, 2, 0], [3, 4, 0]]); // fills both rows with b[0] a[0..$, 0..$-1] = b[0]; assert(a == [[1, 2, 0], [1, 2, 0]]); a[1, 0..$-1] = b[1]; assert(a[1] == [3, 4, 0]); a[1, 0..$-1][] = b[0]; assert(a[1] == [1, 2, 0]);
Examples:Left slice is packedimport std.experimental.ndslice.selection : blocks, iotaSlice; auto a = slice!size_t(4, 4); a.blocks(2, 2)[] = iotaSlice(2, 2); assert(a == [[0, 0, 1, 1], [0, 0, 1, 1], [2, 2, 3, 3], [2, 2, 3, 3]]);
Examples:Bothslices
are packedimport std.experimental.ndslice.selection : blocks, iotaSlice, pack; auto a = slice!size_t(4, 4); a.blocks(2, 2)[] = iotaSlice(2, 2, 2).pack!1; assert(a == [[0, 1, 2, 3], [0, 1, 2, 3], [4, 5, 6, 7], [4, 5, 6, 7]]);
- void
opIndexAssign
(T, Slices...)(T[]value
, Slicesslices
)
if (isFullPureSlice!Slices && !isDynamicArray!DeepElemType && DynamicArrayDimensionsCount!(T[]) <= ReturnType!(opIndex!Slices).N); - Assignment of a regular multidimensional array to a fully defined slice.
Optimization: SIMD instructions may be used if the slice has the last stride equals to 1.
Examples:auto a = slice!int(2, 3); auto b = [[1, 2], [3, 4]]; a[] = [[1, 2, 3], [4, 5, 6]]; assert(a == [[1, 2, 3], [4, 5, 6]]); a[0..$, 0..$-1] = [[1, 2], [3, 4]]; assert(a == [[1, 2, 3], [3, 4, 6]]); a[0..$, 0..$-1] = [1, 2]; assert(a == [[1, 2, 3], [1, 2, 6]]); a[1, 0..$-1] = [3, 4]; assert(a[1] == [3, 4, 6]); a[1, 0..$-1][] = [3, 4]; assert(a[1] == [3, 4, 6]);
Examples:Packedslices
import std.experimental.ndslice.selection : blocks; auto a = slice!int(4, 4); a.blocks(2, 2)[] = [[0, 1], [2, 3]]; assert(a == [[0, 0, 1, 1], [0, 0, 1, 1], [2, 2, 3, 3], [2, 2, 3, 3]]);
- void
opIndexAssign
(T, Slices...)(Tvalue
, Slicesslices
)
if (isFullPureSlice!Slices && (!isDynamicArray!T || isDynamicArray!DeepElemType) && !is(T : Slice!(RN, RRange), size_t RN, RRange)); - Assignment of a
value
(e.g. a number) to a fully defined slice.Optimization: SIMD instructions may be used if the slice has the last stride equals to 1.
Examples:auto a = slice!int(2, 3); a[] = 9; assert(a == [[9, 9, 9], [9, 9, 9]]); a[0..$, 0..$-1] = 1; assert(a == [[1, 1, 9], [1, 1, 9]]); a[0..$, 0..$-1] = 2; assert(a == [[2, 2, 9], [2, 2, 9]]); a[1, 0..$-1] = 3; assert(a[1] == [3, 3, 9]); a[1, 0..$-1] = 4; assert(a[1] == [4, 4, 9]); a[1, 0..$-1][] = 5; assert(a[1] == [5, 5, 9]);
Examples:Packedslices
have the same behavior.import std.experimental.ndslice.selection : pack; auto a = slice!int(2, 3).pack!1; a[] = 9; assert(a == [[9, 9, 9], [9, 9, 9]]);
- ref auto
opIndexAssign
(T)(Tvalue
, size_t[N]_indexes
...); - Assignment of a
value
(e.g. a number) to a fully defined index.Examples:auto a = slice!int(2, 3); a[1, 2] = 3; assert(a[1, 2] == 3);
- ref auto
opIndexOpAssign
(string op, T)(Tvalue
, size_t[N]_indexes
...); - Op Assignment op= of a
value
(e.g. a number) to a fully defined index.Examples:auto a = slice!int(2, 3); a[1, 2] += 3; assert(a[1, 2] == 3);
- void
opIndexOpAssign
(string op, size_t RN, RRange, Slices...)(Slice!(RN, RRange)value
, Slicesslices
)
if (isFullPureSlice!Slices && RN <= ReturnType!(opIndex!Slices).N); - Op Assignment op= of a
value
of Slice type to a fully defined slice.Optimization: SIMD instructions may be used if both
slices
have the last stride equals to 1.Examples:auto a = slice!int(2, 3); auto b = [1, 2, 3, 4].sliced(2, 2); a[0..$, 0..$-1] += b; assert(a == [[1, 2, 0], [3, 4, 0]]); a[0..$, 0..$-1] += b[0]; assert(a == [[2, 4, 0], [4, 6, 0]]); a[1, 0..$-1] += b[1]; assert(a[1] == [7, 10, 0]); a[1, 0..$-1][] += b[0]; assert(a[1] == [8, 12, 0]);
Examples:Left slice is packedimport std.experimental.ndslice.selection : blocks, iotaSlice; auto a = slice!size_t(4, 4); a.blocks(2, 2)[] += iotaSlice(2, 2); assert(a == [[0, 0, 1, 1], [0, 0, 1, 1], [2, 2, 3, 3], [2, 2, 3, 3]]);
Examples:Bothslices
are packedimport std.experimental.ndslice.selection : blocks, iotaSlice, pack; auto a = slice!size_t(4, 4); a.blocks(2, 2)[] += iotaSlice(2, 2, 2).pack!1; assert(a == [[0, 1, 2, 3], [0, 1, 2, 3], [4, 5, 6, 7], [4, 5, 6, 7]]);
- void
opIndexOpAssign
(string op, T, Slices...)(T[]value
, Slicesslices
)
if (isFullPureSlice!Slices && !isDynamicArray!DeepElemType && DynamicArrayDimensionsCount!(T[]) <= ReturnType!(opIndex!Slices).N); - Op Assignment op= of a regular multidimensional array to a fully defined slice.
Optimization: SIMD instructions may be used if the slice has the last stride equals to 1.
Examples:auto a = slice!int(2, 3); a[0..$, 0..$-1] += [[1, 2], [3, 4]]; assert(a == [[1, 2, 0], [3, 4, 0]]); a[0..$, 0..$-1] += [1, 2]; assert(a == [[2, 4, 0], [4, 6, 0]]); a[1, 0..$-1] += [3, 4]; assert(a[1] == [7, 10, 0]); a[1, 0..$-1][] += [1, 2]; assert(a[1] == [8, 12, 0]);
Examples:Packedslices
import std.experimental.ndslice.selection : blocks; auto a = slice!int(4, 4); a.blocks(2, 2)[] += [[0, 1], [2, 3]]; assert(a == [[0, 0, 1, 1], [0, 0, 1, 1], [2, 2, 3, 3], [2, 2, 3, 3]]);
Examples:Packedslices
have the same behavior.import std.experimental.ndslice.selection : pack; auto a = slice!int(2, 3).pack!1; a[] += 9; assert(a == [[9, 9, 9], [9, 9, 9]]);
- void
opIndexOpAssign
(string op, T, Slices...)(Tvalue
, Slicesslices
)
if (isFullPureSlice!Slices && (!isDynamicArray!T || isDynamicArray!DeepElemType) && !is(T : Slice!(RN, RRange), size_t RN, RRange)); - Op Assignment op= of a
value
(e.g. a number) to a fully defined slice.Optimization: SIMD instructions may be used if the slice has the last stride equals to 1.
Examples:auto a = slice!int(2, 3); a[] += 1; assert(a == [[1, 1, 1], [1, 1, 1]]); a[0..$, 0..$-1] += 2; assert(a == [[3, 3, 1], [3, 3, 1]]); a[1, 0..$-1] += 3; assert(a[1] == [6, 6, 1]);
- ref auto
opIndexUnary
(string op)(size_t[N]_indexes
...); - Increment ++ and Decrement -- operators for a fully defined index.Examples:
auto a = slice!int(2, 3); ++a[1, 2]; assert(a[1, 2] == 1);
- void
opIndexUnary
(string op, Slices...)(Slicesslices
)
if (isFullPureSlice!Slices && (op == "++" || op == "--")); - Increment ++ and Decrement -- operators for a fully defined slice.Examples:
auto a = slice!int(2, 3); ++a[]; assert(a == [[1, 1, 1], [1, 1, 1]]); --a[1, 0..$-1]; assert(a[1] == [0, 0, 1]);