Various stuff for working with generic tuples.
A replacement for std.typetuple.
The following symbols from std.typetuple are publicly imported:
Category | Functions |
---|---|
Searching | anyTuple allTuple |
Creation | RetroTuple StrideTuple ChainTuple RoundRobinTuple RadialTuple RepeatTuple ZipTuple iotaTuple IndexedTuple ChunksTuple |
Comparison | cmpTuple equalTuple |
Iteration | FilterTuple groupTuple JoinTuple MapTuple ReduceTuple UniqTuple |
Creates a generic tuple out of a sequence of zero or more types, expressions, or aliases.
alias MyTemplate(T) = T[]; alias MyTuple = GenericTuple!(int, 5, "a string", MyTemplate); MyTuple[0] myVar = MyTuple[1]; // same as `int myVar = 5;` auto str = MyTuple[2]; // same as `auto str = "a string";` alias Template = MyTuple[3]; static assert(is(Template!int == int[]));
Creates a packed generic tuple out of a sequence of zero or more types, expressions, or aliases.
Packed version doesn't alias itself to its content, i.e. it doesn't auto-unpack.
alias MyPackedTuple = PackedGenericTuple!(long, 3); MyPackedTuple.Tuple[0] myVar = MyPackedTuple.Tuple[1]; // same as `long myVar = 3;` alias MyTemplate(alias packed) = packed.Tuple[0][]; // It is passed as a single template alias parameter: static assert(is(MyTemplate!MyPackedTuple == long[]));
Use this member of to access its content as a generic tuple.
Use this member of to access its content as a typetuple. Defined if Args is a typetuple.
Use this member of to access its content as an expression tuple. Defined if Args is an expression tuple.
Convenient equality check template. Same as equalTuple.
Convenient comparison template. Same as cmpTuple.
Creates a typetuple out of a sequence of zero or more types. Same as GenericTuple, except it contains only types.
alias IntDouble = TypeTuple!(int, double); int foo(IntDouble args) // same as `int foo(int, double)` { return args[0] + cast(int) args[1]; } alias IntDoubleChar = TypeTuple!(int, double, char); static assert(is(TypeTuple!(IntDouble, char) == IntDoubleChar)); static assert(is(IntDoubleChar[0 .. 2] == IntDouble)); version(none) alias BadTypeTuple = TypeTuple!(int, 5); // error: not a type tuple
Creates a packed typetuple out of a sequence of zero or more types. Same as PackedGenericTuple, except it contains only types.
Creates an expression tuple out of a sequence of zero or more expressions. Same as GenericTuple, except it contains only expressions.
alias expressions = expressionTuple!(5, 'c', "str"); typeof(expressions[0]) myVar = expressions[1]; // same as `int myVar = 5;` auto str = expressions[2]; // same as `auto str = "a string";` void foo(out typeof(expressions[0 .. 2]) args) // same as `int foo(out int, out char)` { args[0] = expressions[0] * 2; // same as `5 * 2` args[1] = expressions[1] + 1; // same as `'c' + 1` } void main() { int i; char c; foo(i, c); assert(i == 10 && c == 'd'); } version(none) alias badExpressionTuple = expressionTuple!(int, 5); // error: not an expression tuple
Creates a packed expression tuple out of a sequence of zero or more expressions. Same as PackedGenericTuple, except it contains only expressions.
Creates a generic tuple comprised of elemetns of A in reverse order.
Applying RetroTuple twice to the same generic tuple equals to the original generic tuple.
static assert(is(RetroTuple!(int, bool, long) == TypeTuple!(long, bool, int))); static assert(PackedGenericTuple!(RetroTuple!(1, bool, "x")).equals!("x", bool, 1));
Creates a generic tuple comprised of elemetns of A taken with stride n.
Applying StrideTuple twice to the same generic tuple equals to applying StrideTuple with a step that is the product of the two applications.
static assert(is(StrideTuple!(2, ubyte, byte, uint, int, ulong, long) == TypeTuple!(ubyte, uint, ulong))); static assert(StrideTuple!(3, iota) == expressionTuple!(1, 4, 7, 10));
Creates a generic tuple comprised of all elemetns of packed generic tuples packedTuples in sequence.
alias chain = ChainTuple!(packedExpressionTuple!(1, 2, 3), packedExpressionTuple!(4, 5)); static assert(chain == expressionTuple!(1, 2, 3, 4, 5));
Creates a generic tuple comprised of all elemetns of packed generic tuples packedTuples in an order by analogy with Round-robin scheduling.
alias roundRobin = RoundRobinTuple!(packedExpressionTuple!(1, 2, 3), packedExpressionTuple!(10, 20, 30, 40)); static assert(roundRobin == expressionTuple!(1, 10, 2, 20, 3, 30, 40));
Creates a generic tuple comprised of all elemetns of A which are teken starting from a given point and progressively extending left and right from that point. If RadialTupleMiddle is used or startingIndex is -1 it is assumed that no initial point is given and iteration starts from the middle of A.
static assert(RadialTuple!(-1, 1, 2, 3, 4, 5) == expressionTuple!(3, 4, 2, 5, 1)); static assert(RadialTuple!( 1, 1, 2, 3, 4, 5) == expressionTuple!(2, 3, 1, 4, 5));
Repeats A n times.
static assert(is(RepeatTuple!(2, int) == TypeTuple!(int, int))); static assert(RepeatTuple!(4, 5) == expressionTuple!(5, 5, 5, 5));
Creates a generic tuple comprised of packed generic tuples comprised of elemetns of packed generic tuples packedTuples taken in lockstep.
If stoppingPolicy is StoppingPolicy.longest and a tuple is finished in a lockstep iteration then empty will be taken.
alias packed1 = packedExpressionTuple!(1, 2, 3); alias packed2 = PackedTypeTuple!(short, int, long); alias zip = ZipTuple!(packed1, packed2); static assert(zip[0].equals!(1, short)); static assert(zip[1].equals!(2, int)); static assert(zip[2].equals!(3, long))
Returns expression tuple with elements going through the numbers begin, begin + step, begin + 2 * step, ..., up to and excluding end. The two-arguments version has step = 1. The one-argument version also has begin = 0. If begin < end && step < 0 or begin > end && step > 0 or begin == end, then an empty tuple is returned.
int res; foreach(i; iotaTuple!5) // same as res += foo!1(); res += foo!3(); static if(i & 1) res += foo!i();
Creates a generic tuple comprised of elemetns of packed generic tuple packedSourceTuple reordered according to packed expression tuple packedIndicesTuple. packedIndicesTuple may include only a subset of the elements of packedSourceTuple and may also repeat elements.
alias indexed = IndexedTuple!(PackedTypeTuple!(short, int, long, double), packedExpressionTuple!(1, 0, 2, 2)); static assert(is(indexed == TypeTuple!(int, short, long, long)));
Creates a generic tuple comprised of packed generic tuples comprised of fixed-sized chunks of size chunkSize of A.
If A.length is not evenly divisible by chunkSize, the last packed generic tuple will contain fewer than chunkSize elements.
alias chunks = ChunksTuple!(4, 1, 2, 3, 4, 5, 6, byte, short, int, long); static assert(chunks[0].equals!(1, 2, 3, 4)); static assert(chunks[1].equals!(5, 6, byte, short)); static assert(chunks[2].equals!(int, long));
Performs three-way lexicographical comparison on two packed generic tuples according to predicate pred.
Iterating packedTuple1 and packedTuple2 in lockstep, cmpTuple compares each element A1 of packedTuple1 with the corresponding element A2 in packedTuple2. If Inst!(binaryPred!pred, A1, A2), cmp returns a negative value. If Inst!(binaryPred!pred, A2, A1), cmp returns a positive value. If one of the tuples has been finished, cmp returns a negative value if packedTuple1 has fewer elements than packedTuple2, a positive value if packedTuple1 has more elements than packedTuple2, and 0 if the tuples have the same number of elements.
static assert(cmpTuple!(packedExpressionTuple!0, packedExpressionTuple!0) == 0); static assert(cmpTuple!(packedExpressionTuple!"a", packedExpressionTuple!"ab") < 0); static assert(cmpTuple!(`T.sizeof < U.sizeof`, PackedTypeTuple!int, PackedTypeTuple!long) < 0);
Detect whether two packed generic tuples packedTuple1 and packedTuple2 elements are equal according to binary predicate pred.
isSame is used if no predicacte specified.
static assert( equalTuple!(packedExpressionTuple!(0, 1), packedExpressionTuple!(iotaTuple!2))); static assert( equalTuple!(PackedGenericTuple!(int, "a"), PackedGenericTuple!(int, "a"))); static assert( equalTuple!(`true`, packedExpressionTuple!1, PackedTypeTuple!int)); static assert(!equalTuple!(`true`, packedExpressionTuple!1, packedExpressionTuple!()));
Creates a generic tuple comprised of elemetns of A for which a unary predicate pred is true.
import std.traits; static assert(is(FilterTuple!(isNumeric, int, void, immutable short, char) == TypeTuple!(int, immutable short))); static assert(is(FilterTuple!(`__traits(isUnsigned, T)`, int, size_t, void, ushort, char) == TypeTuple!(size_t, ushort, char)));
Similarly to UniqTuple, creates a generic tuple comprised of packed generic tuples comprised of unique consecutive elemetns of A and counts of equivalent elements seen.
Equivalence of elements is assessed by using a binary predicate pred.
alias tuple = GenericTuple!(1, 2, 2, 2, "x", "x", int, 1, 1); alias group = groupTuple!(isSame, tuple); static assert(group.length == 5); static assert(group[0].equals!(1, 1)); static assert(group[1].equals!(2, 3)); static assert(group[2].equals!("x", 2)); static assert(group[3].equals!(int, 1)); static assert(group[4].equals!(1, 2)); alias group2 = groupTuple!(notTemplate!isSame, tuple); static assert(group2.length == 3); static assert(group2[0].equals!(1, 7)); static assert(group2[1].equals!(1, 1)); static assert(group2[2].equals!(1, 1));
Creates a generic tuple comprised of packed generic tuples packedTuples generic tuples joined together using packed generic tuple packedSeparatorTuple as a separator.
alias sep = packedExpressionTuple!"+"; alias part1 = PackedTypeTuple!(void, int); alias part2 = packedExpressionTuple!0; static assert(PackedGenericTuple!(JoinTuple!(sep, part1, part2)).equals!(void, int, "+", 0));
Creates a generic tuple comprised of results of applying unary template Func to elemetns of A consecutively.
alias squares = MapTuple!(`a * a`, iotaTuple!4); static assert(squares == expressionTuple!(0, 1, 4, 9)); static assert(is(MapTuple!(`T[]`, int, long) == TypeTuple!(int[], long[])));
The instantiation of ReduceTuple!(Func, init, A) first lets result be init. Then, for each element x in A sequentially, it lets result be Inst!(BinaryTemplate!Func, result, x). Finally, result is returned.
static assert(ReduceTuple!(`a + U.sizeof`, 0, bool, short, int) == 1 + 2 + 4); static assert(is(ReduceTuple!(`Select!(T.sizeof > U.sizeof, T, U)`, void, bool, long, int) == long));
Creates a generic tuple comprised of unique consecutive elemetns of A.
Equivalence of elements is assessed by using a binary predicate pred.
alias expr = expressionTuple!(1, 2, 2, 2, 3, 3, 4, 1, 1); static assert(UniqTuple!(`a == b`, expr) == expressionTuple!(1, 2, 3, 4, 1)); static assert(UniqTuple!(`a != b`, expr) == expressionTuple!(1, 1, 1));
Detect whether a generic tuple A contains an element satisfying the predicate pred.
static assert(!anyTuple!(`true`)); static assert( anyTuple!(`isIntegral!T`, float, int)); static assert(!anyTuple!(`a < 2`, 2, 3));
Detect whether all elements of a generic tuple A satisfy the predicate pred.
Returns true for an empty tuple.
static assert( allTuple!(`false`)); static assert( allTuple!(`isIntegral!T`, byte, int)); static assert(!allTuple!("a & 1", 1, 2, 3));