mirror of
https://github.com/dlang/phobos.git
synced 2025-04-29 22:50:38 +03:00
257 lines
6.3 KiB
D
257 lines
6.3 KiB
D
|
|
// Written in the D programming language.
|
|
|
|
/**
|
|
* Templates with which to manipulate type tuples (also known as type lists).
|
|
*
|
|
* Some operations on type tuples 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
|
|
* list that is a slice of the old one.
|
|
*
|
|
* References:
|
|
* Based on ideas in Table 3.1 from
|
|
* $(LINK2 http://www.amazon.com/exec/obidos/ASIN/0201704315/ref=ase_classicempire/102-2957199-2585768,
|
|
* Modern C++ Design),
|
|
* Andrei Alexandrescu (Addison-Wesley Professional, 2001)
|
|
* Source: $(PHOBOSSRC std/_typetuple.d)
|
|
* Macros:
|
|
* WIKI = Phobos/StdTypeTuple
|
|
* Copyright:
|
|
* Public Domain
|
|
*/
|
|
|
|
/* Author:
|
|
* Walter Bright, Digital Mars, www.digitalmars.com
|
|
*/
|
|
|
|
module std.typetuple;
|
|
|
|
/**
|
|
* Creates a typetuple out of a sequence of zero or more types.
|
|
* Example:
|
|
* ---
|
|
* import std.typetuple;
|
|
* alias TypeTuple!(int, double) TL;
|
|
*
|
|
* int foo(TL td) // same as int foo(int, double);
|
|
* {
|
|
* return td[0] + cast(int)td[1];
|
|
* }
|
|
* ---
|
|
*
|
|
* Example:
|
|
* ---
|
|
* TypeTuple!(TL, char)
|
|
* // is equivalent to:
|
|
* TypeTuple!(int, double, char)
|
|
* ---
|
|
*/
|
|
template TypeTuple(TList...)
|
|
{
|
|
alias TList TypeTuple;
|
|
}
|
|
|
|
/**
|
|
* Returns the index of the first occurrence of type T in the
|
|
* sequence of zero or more types TList.
|
|
* If not found, -1 is returned.
|
|
* Example:
|
|
* ---
|
|
* import std.typetuple;
|
|
* import std.stdio;
|
|
*
|
|
* void foo()
|
|
* {
|
|
* writefln("The index of long is ",
|
|
* IndexOf!(long, TypeTuple!(int, long, double)));
|
|
* // prints: The index of long is 1
|
|
* }
|
|
* ---
|
|
*/
|
|
template IndexOf(T, TList...)
|
|
{
|
|
static if (TList.length == 0)
|
|
const int IndexOf = -1;
|
|
else static if (is(T == TList[0]))
|
|
const int IndexOf = 0;
|
|
else
|
|
const int IndexOf =
|
|
(IndexOf!(T, TList[1 .. length]) == -1)
|
|
? -1
|
|
: 1 + IndexOf!(T, TList[1 .. length]);
|
|
}
|
|
|
|
/**
|
|
* Returns a typetuple created from TList with the first occurrence,
|
|
* if any, of T removed.
|
|
* Example:
|
|
* ---
|
|
* Erase!(long, int, long, double, char)
|
|
* // is the same as:
|
|
* TypeTuple!(int, double, char)
|
|
* ---
|
|
*/
|
|
template Erase(T, TList...)
|
|
{
|
|
static if (TList.length == 0)
|
|
alias TList Erase;
|
|
else static if (is(T == TList[0]))
|
|
alias TList[1 .. length] Erase;
|
|
else
|
|
alias TypeTuple!(TList[0], Erase!(T, TList[1 .. length])) Erase;
|
|
}
|
|
|
|
/**
|
|
* Returns a typetuple created from TList with the all occurrences,
|
|
* if any, of T removed.
|
|
* Example:
|
|
* ---
|
|
* alias TypeTuple!(int, long, long, int) TL;
|
|
*
|
|
* EraseAll!(long, TL)
|
|
* // is the same as:
|
|
* TypeTuple!(int, int)
|
|
* ---
|
|
*/
|
|
template EraseAll(T, TList...)
|
|
{
|
|
static if (TList.length == 0)
|
|
alias TList EraseAll;
|
|
else static if (is(T == TList[0]))
|
|
alias EraseAll!(T, TList[1 .. length]) EraseAll;
|
|
else
|
|
alias TypeTuple!(TList[0], EraseAll!(T, TList[1 .. length])) EraseAll;
|
|
}
|
|
|
|
/**
|
|
* Returns a typetuple created from TList with the all duplicate
|
|
* types removed.
|
|
* Example:
|
|
* ---
|
|
* alias TypeTuple!(int, long, long, int, float) TL;
|
|
*
|
|
* NoDuplicates!(TL)
|
|
* // is the same as:
|
|
* TypeTuple!(int, long, float)
|
|
* ---
|
|
*/
|
|
template NoDuplicates(TList...)
|
|
{
|
|
static if (TList.length == 0)
|
|
alias TList NoDuplicates;
|
|
else
|
|
alias TypeTuple!(TList[0], NoDuplicates!(EraseAll!(TList[0], TList[1 .. length]))) NoDuplicates;
|
|
}
|
|
|
|
/**
|
|
* Returns a typetuple created from TList with the first occurrence
|
|
* of type T, if found, replaced with type U.
|
|
* Example:
|
|
* ---
|
|
* alias TypeTuple!(int, long, long, int, float) TL;
|
|
*
|
|
* Replace!(long, char, TL)
|
|
* // is the same as:
|
|
* TypeTuple!(int, char, long, int, float)
|
|
* ---
|
|
*/
|
|
template Replace(T, U, TList...)
|
|
{
|
|
static if (TList.length == 0)
|
|
alias TList Replace;
|
|
else static if (is(T == TList[0]))
|
|
alias TypeTuple!(U, TList[1 .. length]) Replace;
|
|
else
|
|
alias TypeTuple!(TList[0], Replace!(T, U, TList[1 .. length])) Replace;
|
|
}
|
|
|
|
/**
|
|
* Returns a typetuple created from TList with all occurrences
|
|
* of type T, if found, replaced with type U.
|
|
* Example:
|
|
* ---
|
|
* alias TypeTuple!(int, long, long, int, float) TL;
|
|
*
|
|
* ReplaceAll!(long, char, TL)
|
|
* // is the same as:
|
|
* TypeTuple!(int, char, char, int, float)
|
|
* ---
|
|
*/
|
|
template ReplaceAll(T, U, TList...)
|
|
{
|
|
static if (TList.length == 0)
|
|
alias TList ReplaceAll;
|
|
else static if (is(T == TList[0]))
|
|
alias TypeTuple!(U, ReplaceAll!(T, U, TList[1 .. length])) ReplaceAll;
|
|
else
|
|
alias TypeTuple!(TList[0], ReplaceAll!(T, U, TList[1 .. length])) ReplaceAll;
|
|
}
|
|
|
|
/**
|
|
* Returns a typetuple created from TList with the order reversed.
|
|
* Example:
|
|
* ---
|
|
* alias TypeTuple!(int, long, long, int, float) TL;
|
|
*
|
|
* Reverse!(TL)
|
|
* // is the same as:
|
|
* TypeTuple!(float, int, long, long, int)
|
|
* ---
|
|
*/
|
|
template Reverse(TList...)
|
|
{
|
|
static if (TList.length == 0)
|
|
alias TList Reverse;
|
|
else
|
|
alias TypeTuple!(Reverse!(TList[1 .. length]), TList[0]) Reverse;
|
|
}
|
|
|
|
/**
|
|
* Returns the type from TList that is the most derived from type T.
|
|
* If none are found, T is returned.
|
|
* Example:
|
|
* ---
|
|
* class A { }
|
|
* class B : A { }
|
|
* class C : B { }
|
|
* alias TypeTuple!(A, C, B) TL;
|
|
*
|
|
* MostDerived!(Object, TL) x; // x is declared as type C
|
|
* ---
|
|
*/
|
|
template MostDerived(T, TList...)
|
|
{
|
|
static if (TList.length == 0)
|
|
alias T MostDerived;
|
|
else static if (is(TList[0] : T))
|
|
alias MostDerived!(TList[0], TList[1 .. length]) MostDerived;
|
|
else
|
|
alias MostDerived!(T, TList[1 .. length]) MostDerived;
|
|
}
|
|
|
|
/**
|
|
* Returns the typetuple TList with the types sorted so that the most
|
|
* derived types come first.
|
|
* Example:
|
|
* ---
|
|
* class A { }
|
|
* class B : A { }
|
|
* class C : B { }
|
|
* alias TypeTuple!(A, C, B) TL;
|
|
*
|
|
* DerivedToFront!(TL)
|
|
* // is the same as:
|
|
* TypeTuple!(C, B, A)
|
|
* ---
|
|
*/
|
|
template DerivedToFront(TList...)
|
|
{
|
|
static if (TList.length == 0)
|
|
alias TList DerivedToFront;
|
|
else
|
|
alias TypeTuple!(MostDerived!(TList[0], TList[1 .. length]),
|
|
DerivedToFront!(ReplaceAll!(MostDerived!(TList[0], TList[1 .. length]),
|
|
TList[0],
|
|
TList[1 .. length]))) DerivedToFront;
|
|
}
|