meta: Add canFind and isInnerClass
This commit is contained in:
parent
e4cd57a615
commit
7e93bcdeeb
@ -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.
|
||||
|
@ -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));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user