zoukankan      html  css  js  c++  java
  • D语言基本类型判断 traits.d

    D语言中的基本类型函数都放于 traits.d 文件中,该文件每一句就提示:

    Templates which extract information about types and symbols at compile time

    在编译时提取有关类型和符号的信息的模板。

    也就是说,这里放的模板及模板函数,都是可以用于在编译时提取类型和符号信息的。

    这一部分的函数是可用来进行编译时编程的。D语言中程序分为两个部分,第一部分是编译时执行部分,第二部分是运行时执行部分

    一、符号名称函数  Symbol Name

          1)fullyQualifiedName       取完整路径名

    auto tmp = fullyQualifiedName!(File);
    writeln(tmp);
    //输出 std.stdio.File

          2)moduleName       取模块名

    auto tmp = moduleName!(File);
    writeln(tmp);
    //输出 std.stdio

          3)packageName      取包名

    auto tmp = packageName!(File);
    writeln(tmp);
    //输出std                因为File地包为std

    二、函数类型判断

    1) arity    函数参数的数量

    void foo(){}
    void bar(uint){}
    
    auto pn1 = arity!foo;
    auto pn2 = arity!bar;
    writeln("pn1:",pn1);
    writeln("pn2:",pn2);
    //输出 pn1:0
    //输出 pn2:1

    2) functionAttributes  取函数的属性

    void foo(){}
    real func(real x) pure nothrow @safe{return x;}
    auto v1 = functionAttributes!foo;
    auto v2 = functionAttributes!func  & FunctionAttribute.safe;
    auto v3 = functionAttributes!func  & FunctionAttribute.pure_;
    writeln("v1:",v1);
    writeln("v2:",v2);
    writeln("v3:",v3);
    /*  输出
        v1:system
        v2:safe
        v3:pure_
    */

    3) FunctionTypeOf 函数的类型

    int test(int a) { return 0; }
    auto x = is( FunctionTypeOf!test == typeof(test));
    writeln("v1:",x);
    /*
        输出
        v1:true
    */
    alias F_dglit = FunctionTypeOf!((int a){ return a; });
    auto v1 = is(F_dglit* : int function(int));
    auto v2 = is(F_dglit* : void function(int));
    writeln("v1:",v1);
    writeln("v2:",v2);
    /*
        输出
        v1:true
        v2:false
    */

    4)  isSafe   函数是否为安全类型

    @safe    int add(int a, int b) {return a+b;}
    @trusted int sub(int a, int b) {return a-b;}
    @system  int mul(int a, int b) {return a*b;}
    auto v1 = isSafe!add;
    auto v2 = isSafe!sub;
    auto v3 = isSafe!mul;
    writeln("v1:",v1);
    writeln("v2:",v2);
    writeln("v3:",v3);
    /*
        输出
         v1:true
        v2:true
        v3:false
    */

    5) isUnsafe 函数是否为不安全类型

    6) ParameterDefaults

    7) ParameterIdentifierTuple

    8) ParameterStorageClassTuple

    9) Parameters

    int foo(int a,string b);
    auto v1 = typeid(Parameters!foo);
    writeln("v1:",v1);
    /*
        输出
        v1:(int,immutable(char)[])
    */

    10) ReturnType

    int foo();
    auto v1 = typeid(ReturnType!foo);
    writeln("v1:",v1);
    /*
        输出
        v1:int
    */

    11) SetFunctionAttributes

    12) variadicFunctionStyle

    三、Aggregate Type 迭代器类型工具函数

    1) BaseClassesTuple   取基类类型 class 的

    class C1 { }
    class C2 : C1 { }
    class C3 : C2 { }
    auto v1 = typeid(BaseClassesTuple!Object);
    auto v2 = typeid(BaseClassesTuple!C1);
    auto v3 = typeid(BaseClassesTuple!C2);
    auto v4 = typeid(BaseClassesTuple!C3);
    writeln("v1:",v1);
    writeln("v2:",v2);
    writeln("v3:",v3);
    writeln("v4:",v4);
    /*
    输出
    v1:()
    v2:(object.Object)
    v3:(main.main.C1,object.Object)
    v4:(main.main.C2,main.main.C1,object.Object)
    */

    2) BaseTypeTuple  取类型的基类型  主要是接口

    interface I1 { }
    interface I2 { }
    interface I12 : I1, I2 { }
    auto v1 = typeid(BaseTypeTuple!I1);
    auto v2 = typeid(BaseTypeTuple!I12);
    writeln("v1:",v1);
    writeln("v2:",v2);
    /*
    输出
    v1:()
    v2:(main.main.I1,main.main.I2)
    */

    3) classInstanceAlignment   取类的对齐方式

    class A { byte b; }
    class B { long l; }
    auto v1 = classInstanceAlignment!A;
    auto v2 = classInstanceAlignment!B;
    writeln("v1:",v1);
    writeln("v2:",v2);
    /*
    输出
    v1:4
    v2:8
    */

    4) EnumMembers  取

    enum A { a,b,c }
    auto v1 = EnumMembers!A;
    foreach(i,v;v1)
        writeln(format("v%d:%s",i,v));
    /*
    输出
    v0:a
    v1:b
    v2:c
    */

    5) FieldNameTuple   取字段名集合

    struct S { int x; float y; }
    auto v1 = FieldNameTuple!S;
    foreach(i,v;v1)
        writeln(format("v%d:%s",i,v));
    /*
    输出
    v0:x
    v1:y
    */

    6) Fields    取字段类型

    struct S { int x; float y; }
    auto v1 = typeid(Fields!S);
    writeln("v1:",v1);
    /*
    输出
    v1:(int,float)
    */

    7) hasAliasing

    8) hasElaborateAssign

    9) hasElaborateCopyConstructor

    10) hasElaborateDestructor

    11) hasIndirections

    12) hasMember   是否有成员函数

    struct S {
        int x;
        void f(){}
        void t()(){}
        template T(){}
    }
    static assert(hasMember!(S, "x"));
    static assert(hasMember!(S, "f"));
    static assert(hasMember!(S, "t"));
    static assert(hasMember!(S, "T"));

    13) hasNested

    14) hasUnsharedAliasing

    15) InterfacesTuple   取类型的所有接口类型元组

    interface I1 {}
    interface I2 {}
    class A : I1, I2 { }
    class B : A, I1 { }
    class C : B {}
    alias TL = InterfacesTuple!C;
    foreach(i,item;TL)
        writeln(format("v%d:%s",i,typeid(item)));
    /*
    输出
    v0:main.main.I1
    v1:main.main.I2
    */

    16) isNested

    17) MemberFunctionsTuple    取类型的所有成员函数元组

    18) RepresentationTypeTuple

    19) TemplateArgsOf      取模板的参数

    20) TemplateOf    取类型的模板

    21) TransitiveBaseTypeTuple

    四、Type Conversion   类型转换

    1)  CommonType  公共类型

    alias X = CommonType!(int, long, short);
    alias Y = CommonType!(int, char[], short);
    auto v1 = typeid(X);
    auto v2 = typeid(Y);
    writeln("v1:",v1);
    writeln("v2:",v2);
    /*
    输出
    v1:long
    v2:void
    */

    2)  ImplicitConversionTargets

    3)  CopyTypeQualifiers

    4)  CopyConstness

    5)  isAssignable   类型2转化为类型1时能不能隐式转换

    6)  isCovariantWith

    7)  isImplicitlyConvertible

    五、SomethingTypeOf

    六、Categories of types

    1) isAggregateType     是否为聚合类型

        class C;
        union U;
        struct S;
        interface I;
    
        static assert( isAggregateType!C);
        static assert( isAggregateType!U);
        static assert( isAggregateType!S);
        static assert( isAggregateType!I);
        static assert(!isAggregateType!void);
        static assert(!isAggregateType!string);
        static assert(!isAggregateType!(int[]));
        static assert(!isAggregateType!(C[string]));
        static assert(!isAggregateType!(void delegate(int)));

    2) isArray  是否为数组类型

    3) isAssociativeArray

    4) isAutodecodableString

    5) isBasicType

    6) isBoolean

    7) isBuiltinType

    8) isDynamicArray

    9) isFloatingPoint

    10) isIntegral

    11) isNarrowString

    12) isNumeric

    13) isPointer

    14) isScalarType

    15) isSigned

    16) isSomeChar

    17) isSomeString

    18) isStaticArray

    19) isUnsigned

    七、Type behaviours

    1) isAbstractClass   是否为抽象类

    2) isAbstractFunction  是否为抽象函数

    3) isCallable    是否为函数调用类型

    4) isDelegate  是否为委托类型

    5) isExpressions    是否为表达式类型

    6) isFinalClass  是否为最终类类型

    7) isFinalFunction  是否为最终函数类型

    8) isFunctionPointer  是否为函数指针类型

    9)   isInstanceOf   类型是否为某泛型的实例化类型

    struct Doo(T) { }
    auto v1 = isInstanceOf!(Doo, Doo!int);
    writeln("v1:",v1);
    /*
    输出
    v1:true
    */

    10) isIterable       是否为迭代器类型

    迭代器类型有两种接口:

    1.  实现int opApply(int delegate(ref ItemType) dg)函数

    2.  实现

            @property UserType front();

            void popFront() ;

            bool empty();

        三个函数都可以实现迭代器,实现了迭代器,就可以使用foreach访问了。

    struct OpApply
    {
        int opApply(int delegate(ref uint) dg) { assert(0); }
    }
    
    struct Range
    {
        @property uint front() { assert(0); }
        void popFront() { assert(0); }
        enum bool empty = false;
    }
    
    static assert( isIterable!(uint[]));
    static assert( isIterable!OpApply);
    static assert( isIterable!(uint[string]));
    static assert( isIterable!Range);
    
    static assert(!isIterable!uint);

    11) isMutable   是否为可变类型

    12) isSomeFunction  是否为相当函数类型

    13) isTypeTuple   是否为类型无组

    八、General Types

    1) ForeachType  取迭代的项的类型

    static assert(is(ForeachType!(uint[]) == uint));

    2) KeyType

    alias Hash = int[string];
    static assert(is(KeyType!Hash == string));
    static assert(is(ValueType!Hash == int));

    3) Largest    体积最大的类型

    static assert(is(Largest!(uint, ubyte, ushort, real) == real));
    static assert(is(Largest!(ulong, double) == ulong));
    static assert(is(Largest!(double, ulong) == double));
    static assert(is(Largest!(uint, byte, double, short) == double));

    4) mostNegative

    5) OriginalType   取原始类型

    enum E : real { a }
    enum F : E    { a = E.a }
    alias G = const(F);
    static assert(is(OriginalType!E == real));
    static assert(is(OriginalType!F == real));
    static assert(is(OriginalType!G == const real));

    6) PointerTarget  取指针指向的类型

    7) Signed

    8) Unqual

    9) Unsigned

    10) ValueType   值的类型

    11) SubTypeOf  取子类型

     

    九、Misc  杂项

    1) mangledName  取管理时使用的名称

        mangledName!int == int.mangleof   与mangleof功能一样

    2) Select

    3) select

    十、User-Defined Attributes

    1) hasUDA     变量是否有某个自定义的属性

    enum E;
    struct S;
    struct Named { string name; }
    @("alpha") int a;
    @(E)       int b;
    @E         int c;
    @(S, E)    int d;
    @S         int e;
    @(S, E, "alpha") int f;
    @(100)     int g;
    @Named("abc") int h;
    
    writeln("alpha:",hasUDA!(a, "alpha"));
    writeln("E:",hasUDA!(b, E));
    writeln("S:",hasUDA!(d, S));
    writeln("Named:",hasUDA!(h, Named));
    /*
    输出
    alpha:true
    E:true
    S:true
    Named:true
    */

    2) getUDAs    类型是否有某个自定义的属性

        struct Attr
        {
            string name;
            int value;
        }
    
        @Attr("Answer", 42) int a;
        static assert(getUDAs!(a, Attr)[0].name == "Answer");
        static assert(getUDAs!(a, Attr)[0].value == 42);
    
        @(Attr("Answer", 42), "string", 9999) int b;
        static assert(getUDAs!(b, Attr)[0].name == "Answer");
        static assert(getUDAs!(b, Attr)[0].value == 42);
    
        @Attr("Answer", 42) @Attr("Pi", 3) int c;
        static assert(getUDAs!(c, Attr)[0].name == "Answer");
        static assert(getUDAs!(c, Attr)[0].value == 42);
        static assert(getUDAs!(c, Attr)[1].name == "Pi");
        static assert(getUDAs!(c, Attr)[1].value == 3);
    
        struct AttrT(T)
        {
            string name;
            T value;
        }
    
        @AttrT!uint("Answer", 42) @AttrT!int("Pi", 3) @AttrT int d;
        static assert(getUDAs!(d, AttrT)[0].name == "Answer");
        static assert(getUDAs!(d, AttrT)[0].value == 42);
        static assert(getUDAs!(d, AttrT)[1].name == "Pi");
        static assert(getUDAs!(d, AttrT)[1].value == 3);
        static assert(getUDAs!(d, AttrT!uint)[0].name == "Answer");
        static assert(getUDAs!(d, AttrT!uint)[0].value == 42);
        static assert(getUDAs!(d, AttrT!int)[0].name == "Pi");
        static assert(getUDAs!(d, AttrT!int)[0].value == 3);

    3) getSymbolsByUDA  通过属性名称取符号

        enum Attr;
    
        static struct A
        {
            @Attr int a;
            int b;
            @Attr void doStuff() {}
            void doOtherStuff() {}
            static struct Inner
            {
                // Not found by getSymbolsByUDA
                @Attr int c;
            }
        }
    
        // Finds both variables and functions with the attribute, but
        // doesn't include the variables and functions without it.
        static assert(getSymbolsByUDA!(A, Attr).length == 2);
        // Can access attributes on the symbols returned by getSymbolsByUDA.
        static assert(hasUDA!(getSymbolsByUDA!(A, Attr)[0], Attr));
        static assert(hasUDA!(getSymbolsByUDA!(A, Attr)[1], Attr));
    
        static struct UDA { string name; }
    
        static struct B
        {
            @UDA("X")
            int x;
            @UDA("Y")
            int y;
            @(100)
            int z;
        }
    
        // Finds both UDA attributes.
        static assert(getSymbolsByUDA!(B, UDA).length == 2);
        // Finds one `100` attribute.
        static assert(getSymbolsByUDA!(B, 100).length == 1);
        // Can get the value of the UDA from the return value
        static assert(getUDAs!(getSymbolsByUDA!(B, UDA)[0], UDA)[0].name == "X");
    
        @UDA("A")
        static struct C
        {
            @UDA("B")
            int d;
        }
    
        // Also checks the symbol itself
        static assert(getSymbolsByUDA!(C, UDA).length == 2);
        static assert(getSymbolsByUDA!(C, UDA)[0].stringof == "C");
        static assert(getSymbolsByUDA!(C, UDA)[1].stringof == "d");

    十一、 未列表部分

    1) ParameterIdentifierTuple 参数标识符表

    int foo(int num, string name, int);
    static assert([ParameterIdentifierTuple!foo] == ["num", "name", ""]);

    2) ParameterDefaults 参数的默认值

    int foo(int num, string name = "hello", int[] = [1,2,3]);
    static assert(is(ParameterDefaults!foo[0] == void));
    static assert(   ParameterDefaults!foo[1] == "hello");
    static assert(   ParameterDefaults!foo[2] == [1,2,3]);
  • 相关阅读:
    2020.11.21日记
    Miller-Rabin质数测试
    Deepin配置记录
    shell
    module load
    vma
    DRDI
    Android.mk
    AEE
    阿里云下配置二级域名的解析设置
  • 原文地址:https://www.cnblogs.com/wanhongnan/p/5735213.html
Copyright © 2011-2022 走看看