Alias Flatten

Flattens a list of types to their ElementType or in the case of an AliasPack it's .UnpackDeep

alias Flatten(Values...) = Flatten!(Head.UnpackDeep,Flatten!Tail);

If a type is a range then its ElementType is used

Example

import std.algorithm: filter;
import std.meta: AliasSeq;

alias R1 = typeof([1, 2, 3].filter!"true");
alias R2 = typeof([1.0, 2.0, 3.0]);

static assert(is(Flatten!(int, double) == AliasSeq!(int, double)));
static assert(is(Flatten!(int, R1, R2) == AliasSeq!(int, int, double)));
static assert(is(Flatten!(R1, int) == AliasSeq!(int, int)));

import std.traits: CommonType;
static assert(is(CommonType!(Flatten!(int, R1, R2, float)) == double));

static assert(is(Flatten!(R1, int, AliasPack!(AliasPack!(float, int)), int) == AliasSeq!(int, int, float, int, int)));