A Digitalmars D programozási nyelv

Trait-ek

A Trait-ek egy olyan kiterjesztései a nyelvnek, amik lehetővé teszik, hogy fordítási időben információt nyerhessünk ki kifejezésekből és szimbólumokból.

Trait kifejezés

TraitsExpression:
__traits ( TraitsKeyword , TraitsArguments )

TraitsKeyword:
isAbstractClass
isArithmetic
isAssociativeArray
isFinalClass
isFloating
isIntegral
isScalar
isStaticArray
isUnsigned
isVirtualFunction
isVirtualMethod
isAbstractFunction
isFinalFunction
isStaticFunction
isRef
isOut
isLazy
hasMember
identifier
getMember
getOverloads
getVirtualFunctions
getVirtualMethods
parent
classInstanceSize
allMembers
derivedMembers
isSame
compiles

TraitsArguments:
TraitsArgument
TraitsArgument, TraitsArguments

TraitsArgument:
AssignExpression
Type

isArithmetic

Ha az argumentumai aritmetikai típusúak vagy olyan kifejezések amik típusa aritmetikai, akkor true-t ad vissza, egyébként false-ot. Ha nincs argumentuma, akkor false.

import std.stdio; void main() { int i; writeln(__traits(isArithmetic, int)); writeln(__traits(isArithmetic, i, i+1, int)); writeln(__traits(isArithmetic)); writeln(__traits(isArithmetic, int*)); }

A program kimenete:

true
true
false
false

isFloating

Olyan mint az isArithmetic, csak lebegőpontos típusokhoz.

isIntegral

Olyan mint az isArithmetic, csak egész (integrális) típusokhoz, beleértve a character típust is.

isScalar

Olyan mint az isArithmetic, csak skalár típusokhoz.

isUnsigned

Olyan mint az isArithmetic, csak előjel nélküli típusokhoz.

isStaticArray

Olyan mint az isArithmetic, csak statikus tömb típusokhoz.

isAssociativeArray

Olyan mint az isArithmetic, csak asszociatív tömb típusokhoz.

isAbstractClass

Ha az argumentumai absztrakt osztály típusúak vagy olyan kifejezések, amik típusa absztrakt osztály, akkor true-t ad vissza, egyébként false-ot. Ha nincs argumentuma, akkor false.

import std.stdio; abstract class C { int foo(); } void main() { C c; writeln(__traits(isAbstractClass, C)); writeln(__traits(isAbstractClass, c, C)); writeln(__traits(isAbstractClass)); writeln(__traits(isAbstractClass, int*)); }

A program kimenete:

true
true
false
false

isFinalClass

Olyan mint az isAbstractClass, csak final class típusokhoz.

isVirtualMethod

Egy argumentuma van. Ha az argumentuma virtuális függvény, akkor true-t ad vissza, egyébként false-ot. Ha az argumentum olyan final függvény, ami nem definiál felül semmit, akkor false-ot ad vissza.

import std.stdio; struct S { void bar() { } } class C { void bar() { } } void main() { writeln(__traits(isVirtualMethod, C.bar)); // true writeln(__traits(isVirtualMethod, S.bar)); // false }

isVirtualFunction

Olyan mint az isVirtualMethod, csak a final függvények esetén, amik nem definiálnak felül semmit, true-t ad vissza.

isAbstractFunction

Egy argumentuma van. Ha az argumentuma absztakt függvény, true-t ad vissza, egyébként false-ot.

import std.stdio; struct S { void bar() { } } class C { void bar() { } } class AC { abstract void foo(); } void main() { writeln(__traits(isAbstractFunction, C.bar)); // false writeln(__traits(isAbstractFunction, S.bar)); // false writeln(__traits(isAbstractFunction, AC.foo)); // true }

isFinalFunction

Egy argumentuma van. Ha az argumentuma final függvény, true-t ad vissza, egyébként false-ot.

import std.stdio; struct S { void bar() { } } class C { void bar() { } final void foo(); } final class FC { void foo(); } void main() { writeln(__traits(isFinalFunction, C.bar)); // false writeln(__traits(isFinalFunction, S.bar)); // false writeln(__traits(isFinalFunction, C.foo)); // true writeln(__traits(isFinalFunction, FC.foo)); // true }

isStaticFunction

Egy argumentuma van. Ha az argumentuma statikus függvény, azaz nincsen context mutatója, true-t ad vissza, egyébként false-ot.

isRef, isOut, isLazy

Egy argumentumuk van. Ha az argumentum deklaráció, amennyiben a megfelelő argumentum ref, out vagy lazy akkor true-t adnak vissza, egyébként false-ot.

void fooref(ref int x) { static assert(__traits(isRef, x)); static assert(!__traits(isOut, x)); static assert(!__traits(isLazy, x)); } void fooout(out int x) { static assert(!__traits(isRef, x)); static assert(__traits(isOut, x)); static assert(!__traits(isLazy, x)); } void foolazy(lazy int x) { static assert(!__traits(isRef, x)); static assert(!__traits(isOut, x)); static assert(__traits(isLazy, x)); }

hasMember

Az első argumentuma egy típus, aminek van tagja, vagy egy kifejezés aminek a típusának van tagja. A második argumentuma egy string. Ha ez a string valós tagja az adott típusnak, akkor true-t ad vissza, egyébként false-ot.

import std.stdio; struct S { int m; } void main() { S s; writeln(__traits(hasMember, S, "m")); // true writeln(__traits(hasMember, s, "m")); // true writeln(__traits(hasMember, S, "y")); // false writeln(__traits(hasMember, int, "sizeof")); // true }

identifier

Egy argumentuma van, ami szimbólum. Viszaadja a szimbólum azonosítóját string literálként.

getMember

Két argumentuma van. Az első egy szimbólum, a második egy string. Az eredmény egy kifejezés, ami az első argumentumot és '.'-tal hozzáfűzve a második argumentumot, mint azonosítót tartlamazza.

import std.stdio; struct S { int mx; static int my; } void main() { S s; __traits(getMember, s, "mx") = 1; // ugyanaz, mint s.mx=1; writeln(__traits(getMember, s, "m" ~ "x")); // 1 __traits(getMember, S, "mx") = 1; // hiba, nincs this az S.mx -hoz __traits(getMember, S, "my") = 2; // ok }

getOverloads

Két argumentuma van. Az első egy osztály típus vagy egy osztály típusú kifejezés, a második egy string. A string-nek meg kell egyeznie az osztály egy tagfüggvényének a nevével. Az eredmény egy tuple, ami tartalmazza az összes túlterhelését az adott függvénynek.

import std.stdio; class D { this() { } ~this() { } void foo() { } int foo(int) { return 2; } } void main() { D d = new D(); foreach (t; __traits(getOverloads, D, "foo")) writeln(typeid(typeof(t))); alias typeof(__traits(getOverloads, D, "foo")) b; foreach (t; b) writeln(typeid(t)); auto i = __traits(getOverloads, d, "foo")[1](1); writeln(i); }

A program kimenete:

void()
int()
void()
int()
2

getVirtualMethods

Két argumentuma van. Az első egy osztály típus vagy egy osztály típusú kifejezés, a második egy string. A string-nek meg kell egyeznie az osztály egy tagfüggvényének a nevével. Az eredmény egy tuple, ami tartalmazza a virtuális túlterheléseit az adott függvénynek. Nem tartalmazza a final függvényeket, amik nem definiálnak felül semmit.

import std.stdio; class D { this() { } ~this() { } void foo() { } int foo(int) { return 2; } } void main() { D d = new D(); foreach (t; __traits(getVirtualMethods, D, "foo")) writeln(typeid(typeof(t))); alias typeof(__traits(getVirtualMethods, D, "foo")) b; foreach (t; b) writeln(typeid(t)); auto i = __traits(getVirtualMethods, d, "foo")[1](1); writeln(i); }

A program kimenete:

void()
int()
void()
int()
2

getVirtualFunctions

Olyan mint az getVirtualMethods, csak tartalmazza a final függvényeket is, amik nem definiálnak felül semmit.

parent

Egy argumentuma van, aminek a kiértékelése egy szimbólum kell legyen. A visszatérési értéke az argumentum szimbólum szülőjének a szimbóluma.

classInstanceSize

Egy argumentuma van, ami osztály típus vagy egy osztály típusú kifejezés. Az eredmény típusa size_t, értéke pedig a byte-okban mért mérete az adott osztály egy futás idejű példányának. Ez az osztály statikus típusán alapszik, nem pedig a polimorfikus típusán.

allMembers

Egy argumentuma van, egy típus vagy egy típus kifejezés. Az eredmény egy tuple, ami tartalmazza az összes tagját az adott típusnak, mint string literált. Ha ez a típus, osztály típus, akkor a bázis osztályok tagjai is bele kerünek az eredménybe. Minden tag csak egyszer szerepel, ismétlés nincs. A beépített elemek nem kerülnek az eredménybe

import std.stdio; class D { this() { } ~this() { } void foo() { } int foo(int) { return 0; } } void main() { auto b = [ __traits(allMembers, D) ]; writeln(b); // ["__ctor", "__dtor", "foo", "toString", "toHash", "opCmp", "opEquals", "Monitor", "factory"] }

derivedMembers

Egy argumentuma van, egy típus vagy egy típus kifejezés. Az eredmény egy tuple, ami tartalmazza az összes tagját az adott típusnak, mint string literált. A bázis osztályok tagjai nem kerünek az eredménybe. Minden tag csak egyszer szerepel, ismétlés nincs. A beépített elemek nem kerülnek az eredménybe

import std.stdio; class D { this() { } ~this() { } void foo() { } int foo(int) { return 0; } } void main() { auto b = [ __traits(derivedMembers, D) ]; writeln(b); // // ["__ctor", "__dtor", "foo"] }

isSame

Két argumentuma van, ha azok ugyanazok a szimbólumok, akkor true-t ad vissza, egyébként false-ot

import std.stdio; s truct S { } int foo(); int bar(); void main() { writeln(__traits(isSame, foo, foo)); // true writeln(__traits(isSame, foo, bar)); // false writeln(__traits(isSame, foo, S)); // false writeln(__traits(isSame, S, S)); // true writeln(__traits(isSame, std, S)); // false writeln(__traits(isSame, std, std)); // true }

compiles

True-t ad vissza, ha minden argumentuma lefordul, azaz szemantikusan korrekt. Az argumentumok lehetnek szimbólumok, típusok vagy kifejezések, amik szintaktikusan helyesek. Nem lehetnek az argumentumok deklarációk vagy utasítások.
Használhatóság:

import std.stdio; struct S { static int s1; int s2; } int foo(); int bar(); void main() { writeln(__traits(compiles)); // false writeln(__traits(compiles, foo)); // true writeln(__traits(compiles, foo + 1)); // true writeln(__traits(compiles, &foo + 1)); // false writeln(__traits(compiles, typeof(1))); // true writeln(__traits(compiles, S.s1)); // true writeln(__traits(compiles, S.s3)); // false writeln(__traits(compiles, 1,2,3,int,long,std)); // true writeln(__traits(compiles, 3[1])); // false writeln(__traits(compiles, 1,2,3,int,long,3[1])); // false }