meta: Add canFind and isInnerClass

This commit is contained in:
Eugen Wissner 2017-10-04 06:06:26 +02:00
parent e4cd57a615
commit 7e93bcdeeb
2 changed files with 87 additions and 4 deletions

View File

@ -885,8 +885,8 @@ if (Args.length > 0)
* `-1` is returned if $(D_PARAM T) is not found.
*
* Params:
* T = The type to search for.
* L = Type list.
* T = The item to search for.
* L = Symbol sequence.
*
* Returns: The index of the first occurrence of $(D_PARAM T) in $(D_PARAM L).
*/
@ -910,6 +910,37 @@ pure nothrow @safe @nogc unittest
static assert(staticIndexOf!(3, () {}, uint, 5, 3) == 3);
}
/**
* Looks for $(D_PARAM T) in $(D_PARAM L) and returns $(D_KEYWORD true) if it
* could be found and $(D_KEYWORD false) otherwise.
*
* Params:
* T = The item to search for.
* L = Symbol sequence.
*
* Returns: $(D_KEYWORD true) if $(D_PARAM T) can be found in $(D_PARAM L),
* $(D_KEYWORD false) otherwise.
*/
template canFind(T, L...)
{
enum bool canFind = indexOf!(0, AliasSeq!(T, L)) != -1;
}
/// ditto
template canFind(alias T, L...)
{
enum bool canFind = indexOf!(0, AliasSeq!(T, L)) != -1;
}
///
pure nothrow @safe @nogc unittest
{
static assert(!canFind!(int));
static assert(canFind!(int, int));
static assert(canFind!(int, float, double, int, real));
static assert(canFind!(3, () {}, uint, 5, 3));
}
/**
* Combines multiple templates with logical AND. So $(D_PSYMBOL templateAnd)
* evaluates to $(D_INLINECODE Preds[0] && Preds[1] && Preds[2]) and so on.

View File

@ -660,8 +660,12 @@ enum bool isBasicType(T) = isScalarType!T || is(T : void);
///
pure nothrow @safe @nogc unittest
{
struct S;
class C;
static struct S
{
}
class C
{
}
enum E : int
{
i = 0,
@ -2996,3 +3000,51 @@ pure nothrow @safe @nogc unittest
static assert(hasUDA!(a, Attr1));
static assert(!hasUDA!(a, Attr2));
}
/**
* Tests whether $(D_PARAM T) is an inner class, i.e. a class nested inside
* another class.
*
* All inner classes get `outer` propery automatically generated, which points
* to its parent class, though it can be explicitly defined to be something
* different. If $(D_PARAM T) does this, $(D_PSYMBOL isInnerClass)
* evaluates to $(D_KEYWORD false).
*
* Params:
* T = Class to be tested.
*
* Returns $(D_KEYWORD true) if $(D_PARAM T) is an inner class,
* $(D_KEYWORD false) otherwise.
*/
template isInnerClass(T)
{
static if (is(T == class) && is(Alias!(__traits(parent, T)) == class))
{
enum bool isInnerClass = !canFind!("outer", __traits(allMembers, T));
}
else
{
enum bool isInnerClass = false;
}
}
///
pure nothrow @safe @nogc unittest
{
class A
{
}
class O
{
class I
{
}
class Fake
{
bool outer;
}
}
static assert(!isInnerClass!(O));
static assert(isInnerClass!(O.I));
static assert(!isInnerClass!(O.Fake));
}