dranges.rangeofranges
This module contains functions creating or acting upon range of ranges (of whatever rank): mapping them, transforming
a linear range into a range of ranges, zipping them, creating them by tensorial product, etc.
License:
Boost License 1.0.
Authors:
Philippe Sigaud
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- struct
Transpose
(R) if (isRangeOfRanges!(R) && hasLength!(R) && hasLength!(ElementType!(R)));
UnWrap!("Transpose",R)
transpose
(R)(R ror);
Transpose!(R)
transpose
(R)(R ror);
- Takes a range of ranges and transposes it. If it's applied a second time, transpose detects this
and gives back the original range. It's a thin wrapper around R: it acts by ref on the subjacent
range.
Example:
int[][] mat = [[0,1,2,3], [4,5,6,7], [8,9,10,11]];
// transpose(mat) is [[0, 4, 8] [1, 5, 9] [2, 6, 10] [3, 7, 11]]
assert(asString(transpose(transpose(mat))) == asString(mat));
auto t = transpose(mat);
t[2] = [0,0,0][]; // opIndexAssign
// t is [[0, 4, 8] [1, 5, 9] [0, 0, 0] [3, 7, 11]]
auto t2 = transpose(t);
assert(asString(t2, " ") == "[0, 1, 0, 3] [4, 5, 0, 7] [8, 9, 0, 11]");
TODO:
Compare to std.range.transverse, look at std.range.transposed.
- Cycle!(Cycle!(ElementType!(R))[])
torus
(R)(R rangeofranges);
- Takes a range of ranges and wraps it around itself to make it a
torus
:
each subrange becomes a cycle and the global range is also a cycle. It's an infinite
range whose elements are also all infinite.
If the initial range offers random access, individual elements of a
torus
can be reached
by two applications of opIndex (see in the example below).
Example:
int[][] r1 = [[0,1,2],[3,4,5]];
auto toroid = torus(r1);
// toroid is (more or less) :
// ......
// ... 0 1 2 0 1 2 0 1 2 0 1 2 ...
// ... 3 4 5 3 4 5 3 4 5 3 4 5 ...
// ... 0 1 2 0 1 2 0 1 2 0 1 2 ...
// ... 3 4 5 3 4 5 3 4 5 3 4 5 ...
// ... 0 1 2 0 1 2 0 1 2 0 1 2 ...
// ... 3 4 5 3 4 5 3 4 5 3 4 5 ...
// ......
assert(isInfinite!(typeof(toroid))); // a torus is an infinite range (necklace-like in this direction)
foreach(line; take(10, toroid)) assert(isInfinite!(typeof(line))); // each element is infinite (a cycle)
assert(equal(take(10, toroid.front), [0,1,2,0,1,2,0,1,2,0][]));
toroid.popFront; // pops the first line
assert(equal(take(10, toroid.front), [3,4,5,3,4,5,3,4,5,3][]));
assert(equal(take(10, map!"a.front"(toroid)), [3,0,3,0,3,0,3,0,3,0][])); // the front of each element is a cycle
assert(equal(take(10, map!"a[1]"(toroid)), [4,1,4,1,4,1,4,1,4,1][])); // second 'column'
assert(toroid[1][2] == 2); // Elements are accessible with a twofold application of opIndex. second 'line', third 'column' -> '2'
assert(toroid[1][2] == toroid[1 + 2][2 +3]); // Periodic with a period of 2 in a direction, 3 in the other.
TODO:
maybe add an opIndex(i,j) operation, to get
torus
[1,2] instead of
torus
[1][2].
TODO:
some kind of slicing, to extract a rectangular section from the
torus
. Maybe with a syntax like
torus
[[1,2],[3,4]]
- typeof(unaryFun!(fun)(E.init))
depthMap
(alias fun, int downToRank = 0, E)(E elem);
Map!(unaryFun!(
depthMap
!(fun,downToRank,ElementType!(R))),R)
depthMap
(alias fun, int downToRank = 0, R)(R range);
- Maps fun at depth downToRank inside a range of ranges.
- RecursiveMapType!(fun,downToRank,R)
recursiveMap
(alias fun, int downToRank = 1, R)(R range);
- Maps fun from the bottow (down to rank downToRank) up, calling fun at each level on the result of the previous (innermost) level.
- NTake!(R,Indices)
nTake
(R, Indices...)(R range, Indices indices);
- A n-dimensional generalization of take: given a range of ranges of rank k and n<k indices n0, n1, n2, ... , nn, it
will lazily take the first n0 elements of the range, the first n1 elements for each range inside the first, and so on.
It's a 'hypercubic' take, if you want.
So, given a rank-3 range (a range of ranges of ranges) of length 3*4*5,
nTake
(range, 2, 10, 2) will produce
a rank-3 range of length 2*4*2.
You can give it less indices than the rank of the range: it will left untouched the innermost ranges. So, given the previous
3*4*5 rank-3 range,
nTake
(range, 2,2) will produce a rank-3 range of dimension 2*2*5 and
nTake
(range, 2)
is the same than take(range,2) (and returns a rank-3 2*4*5 range).
- NDrop!(R,Indices)
nDrop
(R, Indices...)(R range, Indices indices);
- The same, for drop.
- NTake!(NDrop!(R,Indices[__dollar / 2 .. __dollar]),Indices[0 .. __dollar / 2])
nSlice
(R, Indices...)(R range, Indices indices);
- TMapType!(fun,R1,R2)
recursiveBiMap
(alias fun, R1, R2)(R1 r1, R2 r2);
TMapType!(
recursiveBiMap
!(fun,R1,ElementType!(R2)),Repeat!(R1),R2)
recursiveBiMap
(alias fun, R1, R2)(R1 r1, R2 r2);
TMapType!(
recursiveBiMap
!(fun,ElementType!(R1),R2),R1,Repeat!(R2))
recursiveBiMap
(alias fun, R1, R2)(R1 r1, R2 r2);
TMapType!(
recursiveBiMap
!(fun,ElementType!(R1),ElementType!(R2)),R1,R2)
recursiveBiMap
(alias fun, R1, R2)(R1 r1, R2 r2);
- maps two range of ranges together.
- TensorProduct!(tuple,TypeNuple!(R,n))
power
(size_t n, R)(R range);
-
power
of a range: a range multiplied (by tensorial product) by itself n times. Generates a range of ranges, of rank n from a range of rank 1 (flat).
- struct
TensorProduct
(alias fun = tuple,R...) if (R.length && isForwardRange!(R[__dollar - 1]));
TensorProduct!(fun,R)
tensorProduct
(alias fun = tuple, R...)(R ranges);
- The product of n ranges, creating a rank-n range of ranges at the same time.
- struct
RecursiveIndex
(R...) if (R.length && isForwardRange!(R[__dollar - 1]));
- RecursiveIndex!(R)
recursiveIndex
(R)(R range);
- Indexes a range of ranges (of whatever rank): each element is transformed into a tuple(#,#,#, value), the numbers being
the 0-based coordinates. It's a n-dim generalization of indexed.
- size_t
rlength
(R)(R r);
- gives the complete length of a range of ranges.
- struct
AsRangeOfRanges
(R) if (isForwardRange!(R));
AsRangeOfRanges!(R)
asRangeOfRanges
(R)(R r, int n);
- NDRangeType!(R,Indices)
asNDimRange
(R, Indices...)(R r, Indices indices);
- ElementType!(R)
nthElement
(R)(R range, size_t n);
- Returns the
nthElement
of each subrange in a range of range. A transversal slice, if you will.
|