diff options
| author | Eugen Wissner <belka@caraus.de> | 2017-10-04 06:06:26 +0200 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2017-10-04 06:06:26 +0200 |
| commit | 7e93bcdeeb985e900bfc4f5a0f87fca5d09a3850 (patch) | |
| tree | 9e030e5b7306a5b8edaa6129be7f2b5ec4eb9d35 | |
| parent | e4cd57a61543833c00b3e6a7254962b385db5ef2 (diff) | |
| download | tanya-7e93bcdeeb985e900bfc4f5a0f87fca5d09a3850.tar.gz | |
meta: Add canFind and isInnerClass
| -rw-r--r-- | source/tanya/meta/metafunction.d | 35 | ||||
| -rw-r--r-- | source/tanya/meta/trait.d | 56 |
2 files changed, 87 insertions, 4 deletions
diff --git a/source/tanya/meta/metafunction.d b/source/tanya/meta/metafunction.d index ccaa89e..e126ed3 100644 --- a/source/tanya/meta/metafunction.d +++ b/source/tanya/meta/metafunction.d @@ -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). */ @@ -911,6 +911,37 @@ pure nothrow @safe @nogc unittest } /** + * 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. * diff --git a/source/tanya/meta/trait.d b/source/tanya/meta/trait.d index eb48cb5..bf46fb3 100644 --- a/source/tanya/meta/trait.d +++ b/source/tanya/meta/trait.d @@ -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)); +} |
