Skip to content

Commit

Permalink
Merge pull request #3507 from MartinNowak/AliasSeq
Browse files Browse the repository at this point in the history
Rename Arguments to AliasSeq
  • Loading branch information
dnadlinger committed Jul 23, 2015
2 parents cc7b0ff + 70c8969 commit 7281178
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 67 deletions.
130 changes: 63 additions & 67 deletions std/meta.d
Expand Up @@ -3,9 +3,9 @@
/**
* Templates to manipulate template argument lists (also known as type lists).
*
* Some operations on type tuples are built in to the language,
* Some operations on alias sequences are built in to the language,
* such as TL[$(I n)] which gets the $(I n)th type from the
* type tuple. TL[$(I lwr) .. $(I upr)] returns a new type
* alias sequence. TL[$(I lwr) .. $(I upr)] returns a new type
* list that is a slice of the old one.
*
* Several templates in this module use or operate on eponymous templates that
Expand All @@ -31,18 +31,19 @@
module std.meta;

/**
* Creates a tuple out of a sequence of zero or more template arguments.
* Creates a sequence of zero or more aliases. This is most commonly
* used as template parameters or arguments.
*/
template Arguments(TList...)
template AliasSeq(TList...)
{
alias Arguments = TList;
alias AliasSeq = TList;
}

///
unittest
{
import std.typetuple;
alias TL = Arguments!(int, double);
import std.meta;
alias TL = AliasSeq!(int, double);

int foo(TL td) // same as int foo(int, double);
{
Expand All @@ -53,17 +54,12 @@ unittest
///
unittest
{
alias TL = Arguments!(int, double);
alias TL = AliasSeq!(int, double);

alias Types = Arguments!(TL, char);
static assert(is(Types == Arguments!(int, double, char)));
alias Types = AliasSeq!(TL, char);
static assert(is(Types == AliasSeq!(int, double, char)));
}

/**
* Alternate name for $(LREF Arguments) for legacy compatibility.
*/
alias TypeTuple = Arguments;

/**
* Returns the index of the first occurrence of type T in the
* sequence of zero or more types TList.
Expand All @@ -88,7 +84,7 @@ unittest
void foo()
{
writefln("The index of long is %s",
staticIndexOf!(long, TypeTuple!(int, long, double)));
staticIndexOf!(long, AliasSeq!(int, long, double)));
// prints: The index of long is 1
}
}
Expand Down Expand Up @@ -164,9 +160,9 @@ template Erase(alias T, TList...)
///
unittest
{
alias Types = TypeTuple!(int, long, double, char);
alias Types = AliasSeq!(int, long, double, char);
alias TL = Erase!(long, Types);
static assert(is(TL == TypeTuple!(int, double, char)));
static assert(is(TL == AliasSeq!(int, double, char)));
}

// [internal]
Expand All @@ -184,11 +180,11 @@ private template GenericErase(args...)
static if (isSame!(e, head))
alias result = tail;
else
alias result = TypeTuple!(head, GenericErase!(e, tail).result);
alias result = AliasSeq!(head, GenericErase!(e, tail).result);
}
else
{
alias result = TypeTuple!();
alias result = AliasSeq!();
}
}

Expand Down Expand Up @@ -222,10 +218,10 @@ template EraseAll(alias T, TList...)
///
unittest
{
alias Types = TypeTuple!(int, long, long, int);
alias Types = AliasSeq!(int, long, long, int);

alias TL = EraseAll!(long, Types);
static assert(is(TL == TypeTuple!(int, int)));
static assert(is(TL == AliasSeq!(int, int)));
}

// [internal]
Expand All @@ -244,11 +240,11 @@ private template GenericEraseAll(args...)
static if (isSame!(e, head))
alias result = next;
else
alias result = TypeTuple!(head, next);
alias result = AliasSeq!(head, next);
}
else
{
alias result = TypeTuple!();
alias result = AliasSeq!();
}
}

Expand All @@ -274,16 +270,16 @@ template NoDuplicates(TList...)
alias NoDuplicates = TList;
else
alias NoDuplicates =
TypeTuple!(TList[0], NoDuplicates!(EraseAll!(TList[0], TList[1 .. $])));
AliasSeq!(TList[0], NoDuplicates!(EraseAll!(TList[0], TList[1 .. $])));
}

///
unittest
{
alias Types = TypeTuple!(int, long, long, int, float);
alias Types = AliasSeq!(int, long, long, int, float);

alias TL = NoDuplicates!(Types);
static assert(is(TL == TypeTuple!(int, long, float)));
static assert(is(TL == AliasSeq!(int, long, float)));
}

unittest
Expand Down Expand Up @@ -325,10 +321,10 @@ template Replace(alias T, alias U, TList...)
///
unittest
{
alias Types = TypeTuple!(int, long, long, int, float);
alias Types = AliasSeq!(int, long, long, int, float);

alias TL = Replace!(long, char, Types);
static assert(is(TL == TypeTuple!(int, char, long, int, float)));
static assert(is(TL == AliasSeq!(int, char, long, int, float)));
}

// [internal]
Expand All @@ -345,14 +341,14 @@ private template GenericReplace(args...)
alias tail = tuple[1 .. $];

static if (isSame!(from, head))
alias result = TypeTuple!(to, tail);
alias result = AliasSeq!(to, tail);
else
alias result = TypeTuple!(head,
alias result = AliasSeq!(head,
GenericReplace!(from, to, tail).result);
}
else
{
alias result = TypeTuple!();
alias result = AliasSeq!();
}
}

Expand Down Expand Up @@ -405,10 +401,10 @@ template ReplaceAll(alias T, alias U, TList...)
///
unittest
{
alias Types = TypeTuple!(int, long, long, int, float);
alias Types = AliasSeq!(int, long, long, int, float);

alias TL = ReplaceAll!(long, char, Types);
static assert(is(TL == TypeTuple!(int, char, char, int, float)));
static assert(is(TL == AliasSeq!(int, char, char, int, float)));
}

// [internal]
Expand All @@ -426,13 +422,13 @@ private template GenericReplaceAll(args...)
alias next = GenericReplaceAll!(from, to, tail).result;

static if (isSame!(from, head))
alias result = TypeTuple!(to, next);
alias result = AliasSeq!(to, next);
else
alias result = TypeTuple!(head, next);
alias result = AliasSeq!(head, next);
}
else
{
alias result = TypeTuple!();
alias result = AliasSeq!();
}
}

Expand Down Expand Up @@ -467,7 +463,7 @@ template Reverse(TList...)
else
{
alias Reverse =
TypeTuple!(
AliasSeq!(
Reverse!(TList[$/2 .. $ ]),
Reverse!(TList[ 0 .. $/2]));
}
Expand All @@ -476,10 +472,10 @@ template Reverse(TList...)
///
unittest
{
alias Types = TypeTuple!(int, long, long, int, float);
alias Types = AliasSeq!(int, long, long, int, float);

alias TL = Reverse!(Types);
static assert(is(TL == TypeTuple!(float, int, long, long, int)));
static assert(is(TL == AliasSeq!(float, int, long, long, int)));
}

/**
Expand All @@ -502,7 +498,7 @@ unittest
class A { }
class B : A { }
class C : B { }
alias Types = TypeTuple!(A, C, B);
alias Types = AliasSeq!(A, C, B);

MostDerived!(Object, Types) x; // x is declared as type C
static assert(is(typeof(x) == C));
Expand All @@ -518,7 +514,7 @@ template DerivedToFront(TList...)
alias DerivedToFront = TList;
else
alias DerivedToFront =
TypeTuple!(MostDerived!(TList[0], TList[1 .. $]),
AliasSeq!(MostDerived!(TList[0], TList[1 .. $]),
DerivedToFront!(ReplaceAll!(MostDerived!(TList[0], TList[1 .. $]),
TList[0],
TList[1 .. $])));
Expand All @@ -530,29 +526,29 @@ unittest
class A { }
class B : A { }
class C : B { }
alias Types = TypeTuple!(A, C, B);
alias Types = AliasSeq!(A, C, B);

alias TL = DerivedToFront!(Types);
static assert(is(TL == TypeTuple!(C, B, A)));
static assert(is(TL == AliasSeq!(C, B, A)));
}

/**
Evaluates to $(D TypeTuple!(F!(T[0]), F!(T[1]), ..., F!(T[$ - 1]))).
Evaluates to $(D AliasSeq!(F!(T[0]), F!(T[1]), ..., F!(T[$ - 1]))).
*/
template staticMap(alias F, T...)
{
static if (T.length == 0)
{
alias staticMap = TypeTuple!();
alias staticMap = AliasSeq!();
}
else static if (T.length == 1)
{
alias staticMap = TypeTuple!(F!(T[0]));
alias staticMap = AliasSeq!(F!(T[0]));
}
else
{
alias staticMap =
TypeTuple!(
AliasSeq!(
staticMap!(F, T[ 0 .. $/2]),
staticMap!(F, T[$/2 .. $ ]));
}
Expand All @@ -563,7 +559,7 @@ unittest
{
import std.traits : Unqual;
alias TL = staticMap!(Unqual, int, const int, immutable int);
static assert(is(TL == TypeTuple!(int, int, int)));
static assert(is(TL == AliasSeq!(int, int, int)));
}

unittest
Expand All @@ -576,10 +572,10 @@ unittest

// single
alias Single = staticMap!(Unqual, const int);
static assert(is(Single == TypeTuple!int));
static assert(is(Single == AliasSeq!int));

alias T = staticMap!(Unqual, int, const int, immutable int);
static assert(is(T == TypeTuple!(int, int, int)));
static assert(is(T == AliasSeq!(int, int, int)));
}

/**
Expand Down Expand Up @@ -652,26 +648,26 @@ unittest


/**
* Filters a $(D TypeTuple) using a template predicate. Returns a
* $(D TypeTuple) of the elements which satisfy the predicate.
* Filters an $(D AliasSeq) using a template predicate. Returns a
* $(D AliasSeq) of the elements which satisfy the predicate.
*/
template Filter(alias pred, TList...)
{
static if (TList.length == 0)
{
alias Filter = TypeTuple!();
alias Filter = AliasSeq!();
}
else static if (TList.length == 1)
{
static if (pred!(TList[0]))
alias Filter = TypeTuple!(TList[0]);
alias Filter = AliasSeq!(TList[0]);
else
alias Filter = TypeTuple!();
alias Filter = AliasSeq!();
}
else
{
alias Filter =
TypeTuple!(
AliasSeq!(
Filter!(pred, TList[ 0 .. $/2]),
Filter!(pred, TList[$/2 .. $ ]));
}
Expand All @@ -682,21 +678,21 @@ unittest
{
import std.traits : isNarrowString, isUnsigned;

alias Types1 = TypeTuple!(string, wstring, dchar[], char[], dstring, int);
alias Types1 = AliasSeq!(string, wstring, dchar[], char[], dstring, int);
alias TL1 = Filter!(isNarrowString, Types1);
static assert(is(TL1 == TypeTuple!(string, wstring, char[])));
static assert(is(TL1 == AliasSeq!(string, wstring, char[])));

alias Types2 = TypeTuple!(int, byte, ubyte, dstring, dchar, uint, ulong);
alias Types2 = AliasSeq!(int, byte, ubyte, dstring, dchar, uint, ulong);
alias TL2 = Filter!(isUnsigned, Types2);
static assert(is(TL2 == TypeTuple!(ubyte, uint, ulong)));
static assert(is(TL2 == AliasSeq!(ubyte, uint, ulong)));
}

unittest
{
import std.traits : isPointer;

static assert(is(Filter!(isPointer, int, void*, char[], int*) == TypeTuple!(void*, int*)));
static assert(is(Filter!isPointer == TypeTuple!()));
static assert(is(Filter!(isPointer, int, void*, char[], int*) == AliasSeq!(void*, int*)));
static assert(is(Filter!isPointer == AliasSeq!()));
}


Expand Down Expand Up @@ -740,7 +736,7 @@ unittest

unittest
{
foreach (T; TypeTuple!(int, staticMap, 42))
foreach (T; AliasSeq!(int, staticMap, 42))
{
static assert(!Instantiate!(templateNot!testAlways, T));
static assert(Instantiate!(templateNot!testNever, T));
Expand Down Expand Up @@ -791,7 +787,7 @@ unittest

unittest
{
foreach (T; TypeTuple!(int, staticMap, 42))
foreach (T; AliasSeq!(int, staticMap, 42))
{
static assert( Instantiate!(templateAnd!(), T));
static assert( Instantiate!(templateAnd!(testAlways), T));
Expand Down Expand Up @@ -849,7 +845,7 @@ unittest

unittest
{
foreach (T; TypeTuple!(int, staticMap, 42))
foreach (T; AliasSeq!(int, staticMap, 42))
{
static assert( Instantiate!(templateOr!(testAlways), T));
static assert( Instantiate!(templateOr!(testAlways, testAlways), T));
Expand Down Expand Up @@ -1022,7 +1018,7 @@ unittest
* Instantiates the given template with the given list of parameters.
*
* Used to work around syntactic limitations of D with regard to instantiating
* a template from a type tuple (e.g. T[0]!(...) is not valid) or a template
* a template from an alias sequence (e.g. T[0]!(...) is not valid) or a template
* returning another template (e.g. Foo!(Bar)!(Baz) is not allowed).
*/
// TODO: Consider publicly exposing this, maybe even if only for better
Expand Down

0 comments on commit 7281178

Please sign in to comment.