dranges.typetuple

This module defines templates on typetuples (complementary, sometimes similar to std. typetuple /std.traits): reversing, rotating, extracting, filtering, unfolding, etc, all on typetuples.

License:
Boost License 1.0.

Authors:
Philippe Sigaud and Simen Kjærås.

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)

template Init (T...)
Alias itself to the .init value of a typetuple. When you have a typetuple (T...) inside a template, you cannot do (T.init), DMD does not accept it. Use Init !T instead.

template SameTuple (T...)
Compares tuples that might contain a mixture of types and values.

Author:
Simen Kjærås.

Usage:
SameTuple!(FirstTuple).As!(SecondTuple);


Example:
static assert(SameTuple!(int, int).As!(int, int));
static assert(SameTuple!(int, "foo").As!(int, "foo"));
static assert(!SameTuple!(int, "foo").As!("foo", int));


template Contained (T...)
Checks if one tuple contains another.

Author:
Simen Kjærås.

Usage:
Contained!(SmallTuple).In!(BigTuple);


Example:
static assert(Contained!(int).In!(float, int));
static assert(!Contained!(int).In!(float, "foo"));
static assert(Contained!(int,"foo").In!(float, int, "foo", "bar"));


template allTuplesSatisfy (alias F,uint tupleLength,T...)
Evaluates to F!(T[0..tupleLength]) && F!(T[tupleLength..2*tupleLength]) && ... && F[T[$-tupleLength..$]].

Author:
Simen Kjærås.

Example:
static assert(allTuplesSatisfy!(Contained!(int).In, 2, int, float, "foo", int));
static assert(!allTuplesSatisfy!(Contained!(int).In, 2, int, float, "foo",string));


template RepeatTuple (uint num,T...)
Repeats a type or typetuple num times.

Author:
Simen Kjærås.

Example:
static assert(SameTuple!(RepeatTuple!(4, int)).As!(int, int, int, int));
static assert(SameTuple!(RepeatTuple!(4, "foo")).As!("foo", "foo", "foo", "foo"));
static assert(SameTuple!(RepeatTuple!(2, int, "foo")).As!(int, "foo", int, "foo"));
static assert(!SameTuple!(RepeatTuple!(2, int)).As!());


template ExtractType (alias array,R...)
Extracts some types from the variadic type tuple R according to the indices given by array (a static array). [0,1,2] means 'the first, second and third types'. The indices can be repeated or omitted and the array can be longer than R ([0,1,2,2,3,0,0,2,3]...). In the latter case, the resulting type tuple will obviously be longer than R.

Examples:
alias TypeTuple!(int,double,string) TT;
alias ExtractType!([0,1],TT) E1;
alias ExtractType!([1,0],TT) E2;
alias ExtractType!([1],TT) E3;
alias ExtractType!([1,0,2,2,0],TT) E4;

assert(is(E1 == TypeTuple!(int,double)));
assert(is(E2 == TypeTuple!(double,int)));
assert(is(E3 == TypeTuple!(double)));
assert(is(E4 == TypeTuple!(double,int,string,string,int)));


Note:
why a static array instead of free parameters like this: ExtractType !(0,2,3,1, TT)? Because the type tuple and the index list are both of variable length, and the tuple can contain any template parameter, including ints. A simplified version working only on pure types tuples could use StaticTakeWhile to get the parameters that are of integral type and then deduce the rest is the type tuple.

template RotateTypes (int n,R...) if (R.length > 0 && n >= 0)
template RotateTypes (int n,R...) if (R.length > 0 && n < 0)
template RotateTypes (int n)
If n>0, it rotate a TypeTuple on the left by n positions (it takes the first n types and puts them at the end). for n== 0, it does nothing (it's the identity template). If n<0, it rotates on the right (takes the last n types and puts them at the beginning).

Example:
alias TypeTuple!(int,double,string) TT;
alias RotateTypes!(1,TT) R1;   // (double, string, int)
alias RotateTypes!(0,TT) R0;   // (int, double, string)
alias RotateTypes!(5,TT) R5;   // (string, int, double)
alias RotateTypes!(-1,TT) R_1; // (string, int, double)
alias RotateTypes!(-5,TT) R_5; // (double, string, int)

assert(is(R1 == TypeTuple!(double,string,int)));
assert(is(R0 == TT));
assert(is(R5 == TypeTuple!(string,int,double))); // equivalent to Rotate!(2,TT)
assert(is(R_1 == TypeTuple!(string,int,double)));
assert(is(R_5 == TypeTuple!(double,string,int))); // equivalent to Rotate!(-2,TT) and also to Rotate!(1,TT)

alias TypeTuple!(int) TT2;
assert(is(RotateTypes!(1,TT2) == TT2)); // one type: unchanged by rotation

alias StaticFilter!(isIntegral, TT2) F; // double is not an integral type -> F is empty
assert(is(RotateTypes!(1,F) == F)); // zero type: also unchanged by rotation.
To Be Documented: curried version: alias RotateTypes !1 R1;

template ReverseTypes (T...)
Takes a type tuple and reverses it.

Example:
alias TypeTuple!(int,double,string) TT;
alias ReverseTypes!TT R;
assert(is(R == TypeTuple!(string,double,int)));

alias TypeTuple!(double) TT2;
assert(is(ReverseTypes!TT2 == TT2)); // one type: unchanged by inversion.

alias StaticFilter!(isIntegral, TT2) F; // double is not an integral type -> F is empty
assert(is(ReverseTypes!F == F)); // no type: unchanged by inversion.


template SwapTypes (size_t i1,size_t i2,R...)
Swap the types at index i1 and index i2 in a TypeTuple.

Example:
alias TypeTuple!(int, double, string, short) Test;

assert(is(SwapTypes!(1,3,Test) == TypeTuple!(int,short,string,double)));
assert(is(SwapTypes!(3,1,Test) == TypeTuple!(int,short,string,double)));

assert(is(SwapTypes!(1,1,Test) == Test));


template SegmentTypes (int n,T...) if (n > 0 && T.length % n == 0)
Cut a typetuple into segments of length n. The segments are std.typecons.Tuples, not type tuples, to avoid auto-flattening. It will not compile if n == 0 or if n do not cut the typetuple in equal parts.

Example:
alias TypeTuple!(int, double, string, int delegate()) Types;
alias SegmentTypes!(2, Types) Segments;
assert(is(Segment == TypeTuple!(Tuple!(int,double), Tuple!(string, int delegate())) ));


template AllEqual (alias a,Rest...)
Is true iff all elements of the variadic list are equal (as tested by ==).

template AllEqual (Types...)
Is true iff all types in the typetuple are equal.

template TypeNuple (T,size_t n)
creates a TypeTuple of n T's, repeated. If n == 0, it becomes the empty TypeTuple: TypeTuple!().
alias TypeNuple!(int, 3) TN3;
assert(is(TN3 == TypeTuple!(int,int,int)));
alias TypeNuple!(int, 1) TN1;
assert(is(TN1 == TypeTuple!(int)));
assert(!is(TN1 == int)); // TypeTuple!int is not an int.


template TypeNuple (alias a,size_t n)
ditto ditto

template Expansion (T : U[n],U,size_t n)
Transforms a static array into a TypeTuple.

Example:
alias Expansion!(int[3]) E; // Gives TypeTuple!(int, int, int).


Note:
int[1] gives TypeTuple!(int), which is not of type int.

template FlattenTuple (T...)
D's typetuple automatically flatten, which is interesting on certain occasions, but not when you're trying to create a deeply nested structure, such as a tree of types. For those occasions, using std.Typecons.Tuple is a possibility. This template is for going back: given a typetuple, possibliy containing nested tuples, it flattens them all and returns a flat typetuple.

Example:
alias TypeTuple!(int, double, string) Flat;
alias TypeTuple!(Tuple!(int,double), string, Tuple!Flat, Tuple!(int, Tuple!int)) Nested;

assert(is(FlattenTuple!Flat == Flat));
assert(is(FlattenTuple!Nested == TypeTuple!(int,double,string,int,double,string,int,int)));


template Interleave (T...)
Usage:
Interleave!(FirstTypeTuple).With!(SecondTypeTuple):
Given T0, T1, T2, ..., Ti and U0, U1, ... Uj, it will interleavs the types and becomes T0, U0, T1, U1, ... If one of the tuples is longer than the other, its tail will be appended.

Example:
alias TypeTuple!(byte,short,int,long,ubyte,ushort,uint,ulong) IntegralTypes;
alias TypeTuple!(float,double,real) FloatTypes;
alias Interleave!IntegralTypes.With!FloatTypes NumericalTypes;

assert(is(NumericalTypes == TypeTuple!(byte,float,short,double,int,real,long,ubyte,ushort,uint,ulong)));


template StaticMap (alias F,T...)
Just an exercice: blind-coding std.traits.staticMap. Aliases itself to the TypeTuple (F!T0, F!T1, ...)

template StaticFilter (alias Pred,T...)
The filter equivalent to StaticMap: alias itself to a TypeTuple containing the types in T that verify the predicate Pred
alias TypeTuple!(int, double, string, long) TT;
assert(is(StaticFilter!(isIntegral, TT) == TypeTuple!(int, long)));
assert(is(StaticFilter!(hasLength2, int[], int[3], int) == TypeTuple!(int[], int[3])));


template StaticReduce (alias F,T...)
Aliases itself to a repeated application of the binary template F on the types of T, like reduce does on ranges.

Example:
template CT(T,T2) {
    alias CommonType!(T,T2) CT;
}

template Tup(T1,T2) {
    alias Tuple!(T1, T2) Tup; // That's std.typecons.Tuple, NOT std.typetuple.TypeTuple
}

alias StaticReduce!(CT, int, double, int, long) SR1; // Equivalent to CommonType!(int,double,int,long)
assert(is(SR1 == double));
alias StaticReduce!(Tup, int, double, int, long) SR2;
assert(is(SR2 == Tuple!(int, Tuple!(double, Tuple!(int, long))))); // Non-flattening tuples


template TypeOf (alias a)
alias itself to the type of alias a.

template MapOnAlias (alias Mapper,alias current,Rest...)
Maps the Mapper template on the alias list.

template ReduceOnAlias (alias Reducer,alias current,Rest...)
Same as StaticReduce, but on an alias list.

template StaticReduce0 (alias F,alias accumulator,T...)
Folds (reduces) the T list, given a reducing template F and an initial accumulator value. F must be a binary template and accumulator a value accepted by F as first parameter.

template StaticScan (alias F,T...)
Gives the TypeTuple resulting from the sucessive applications of F to reduce the T list.

See Also:
dranges.algorithm.scan.

template StaticIterate (size_t times,alias F,T...)
Gives the typetuple (T, F!(T), F!(F!(T)), F!(F!(F!(T))), ...), up to times applications of F.

template StaticIterateOnAlias (size_t times,alias F,alias value)
The same, but on an alias list. Useful for iterating on values: 0,1,2,3...

template StaticUnfold (size_t times,alias F,State...)
Given a template F and a state State, unfolds F times times. Applying F on a type must give a typetuple whose first element is the result and the rest the next state.

See Also:
dranges.algorithm2.unfold, to get some grip on this.

template StaticStride (alias step,T...) if (step > 0)
Given a typetuple T, gives (T[0], T[step], T[2*step], T[3*step],...)

template StaticTakeWhile (alias pred,Types...)
Takes elements in a typetuple as long as the predicate template pred is true for the current element.

Example:
alias TypeTuple!(int, short, byte, double, int, long) Types;
alias StaticTakeWhile!(isIntegral, Types) FirstIntegrals;
asser(is( FirstIntegrals == TypeTuple!(int,short,byte))); // stopped when double was encountered


template StaticDropWhile (alias pred,Types...)
The cousin of StaticTakeWhile. Drops types from a typetuple as long as the predicate is true.

template StaticRotateWhile (alias pred,Types...)
Rotates a typetuple as long as the predicate template pred is true for the first element. If a complete rotation is done (pred gives true for all elements of T), StaticRotateWhile recognizes this and aliases itself to Types instead of cycling forever...

template StaticRange (alias to)
The TypeTuple (0,1,2, ..., to) (to is included)

template StaticRange (alias from,alias to)
The TypeTuple (from, from+1, ..., to) (to is included)

template StaticRange (alias from,alias to,alias step)
The TypeTuple (from, from+step, from+2*step, ... to). to is not necessarily included if step 'jumps' above it.

template SortTypes (alias Pred,Types...)
Sort types in Types, according to predicate Pred. Pred is a binary template that must alias itself to 0 if types are equal, to -1 if T1 < T2 and +1 if T1 > T2. If you do not care for the precise ordering (such as when you just want to verify that two tuples are the same), you can use dranges.templates.CompareTypes as a predicate.

template NthType (size_t n)
Alias itself to the nth field/type in a TypeTuple. Useful for template composition.

template First (T...) if (T.length)
Same as NthType. Alias itself to the first type in a typetuple.

template Second (T...) if (T.length > 1)
Same as NthType. Alias itself to the second type in a typetuple.

template Last (T...) if (T.length)
Alias itself to the last type in a TypeTuple. As the previous template, it's sometimes useful while composing templates.

template Tail (T...) if (T.length)
Alias itself to all types except the first in a TypeTuple.

template Doubler (T...)
Doubles a TypeTuple. ie: from (int, double), makes a (int,double,int,double).

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