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.

Page was generated with on Fri Nov 12 11:55:11 2010