Mercurial > projects > ldc
diff lphobos/std/traits.d @ 94:61615fa85940 trunk
[svn r98] Added support for std.c.stdlib.alloca via pragma(LLVM_internal, "alloca").
Added support for array .sort and .reverse properties.
Fixed some bugs with pointer arithmetic.
Disabled some DMD AST optimizations that was messing things up, destroying valuable information.
Added a KDevelop project file, this is what I use for coding LLVMDC now :)
Other minor stuff.
author | lindquist |
---|---|
date | Mon, 12 Nov 2007 06:32:46 +0100 |
parents | 42bf2eb2973b |
children | 373489eeaf90 |
line wrap: on
line diff
--- a/lphobos/std/traits.d Thu Nov 08 19:21:05 2007 +0100 +++ b/lphobos/std/traits.d Mon Nov 12 06:32:46 2007 +0100 @@ -1,15 +1,189 @@ + +// Written in the D programming language. + +/** + * Templates with which to extract information about + * types at compile time. + * + * Macros: + * WIKI = Phobos/StdTraits + * Copyright: + * Public Domain + */ + +/* + * Authors: + * Walter Bright, Digital Mars, www.digitalmars.com + * Tomasz Stachowiak (isStaticArray, isExpressionTuple) + */ + module std.traits; -struct TypeHolder(S, T...) { - S _ReturnType; - T _ParameterTypeTuple; + +/*** + * Get the type of the return value from a function, + * a pointer to function, or a delegate. + * Example: + * --- + * import std.traits; + * int foo(); + * ReturnType!(foo) x; // x is declared as int + * --- + */ +template ReturnType(alias dg) +{ + alias ReturnType!(typeof(dg)) ReturnType; +} + +/** ditto */ +template ReturnType(dg) +{ + static if (is(dg R == return)) + alias R ReturnType; + else + static assert(0, "argument has no return type"); +} + +/*** + * Get the types of the paramters to a function, + * a pointer to function, or a delegate as a tuple. + * Example: + * --- + * import std.traits; + * int foo(int, long); + * void bar(ParameterTypeTuple!(foo)); // declares void bar(int, long); + * void abc(ParameterTypeTuple!(foo)[1]); // declares void abc(long); + * --- + */ +template ParameterTypeTuple(alias dg) +{ + alias ParameterTypeTuple!(typeof(dg)) ParameterTypeTuple; +} + +/** ditto */ +template ParameterTypeTuple(dg) +{ + static if (is(dg P == function)) + alias P ParameterTypeTuple; + else static if (is(dg P == delegate)) + alias ParameterTypeTuple!(P) ParameterTypeTuple; + else static if (is(dg P == P*)) + alias ParameterTypeTuple!(P) ParameterTypeTuple; + else + static assert(0, "argument has no parameters"); +} + + +/*** + * Get the types of the fields of a struct or class. + * This consists of the fields that take up memory space, + * excluding the hidden fields like the virtual function + * table pointer. + */ + +template FieldTypeTuple(S) +{ + static if (is(S == struct) || is(S == class)) + alias typeof(S.tupleof) FieldTypeTuple; + else + static assert(0, "argument is not struct or class"); } -TypeHolder!(S, T) *IFTI_gen(S, T...)(S delegate(T) dg) { return null; } -TypeHolder!(S, T) *IFTI_gen(S, T...)(S function(T) dg) { return null; } -template ParameterTypeTuple(T) { - alias typeof(IFTI_gen(T.init)._ParameterTypeTuple) ParameterTypeTuple; + + +/*** + * Get a TypeTuple of the base class and base interfaces of + * this class or interface. + * Example: + * --- + * import std.traits, std.typetuple, std.stdio; + * interface I { } + * class A { } + * class B : A, I { } + * + * void main() + * { + * alias BaseTypeTuple!(B) TL; + * writefln(typeid(TL)); // prints: (A,I) + * } + * --- + */ + +template BaseTypeTuple(A) +{ + static if (is(A P == super)) + alias P BaseTypeTuple; + else + static assert(0, "argument is not a class or interface"); +} + +unittest +{ + interface I { } + class A { } + class B : A, I { } + + alias BaseTypeTuple!(B) TL; + assert(TL.length == 2); + assert(is (TL[0] == A)); + assert(is (TL[1] == I)); } -template ReturnType(T) { - alias typeof(IFTI_gen(T.init)._ReturnType) ReturnType; + +/* ******************************************* + */ +template isStaticArray_impl(T) +{ + const T inst = void; + + static if (is(typeof(T.length))) + { + static if (!is(typeof(T) == typeof(T.init))) + { // abuses the fact that int[5].init == int + static if (is(T == typeof(T[0])[inst.length])) + { // sanity check. this check alone isn't enough because dmd complains about dynamic arrays + const bool res = true; + } + else + const bool res = false; + } + else + const bool res = false; + } + else + { + const bool res = false; + } } -template isArray(T) { const bool isArray=false; } -template isArray(T: T[]) { const bool isArray=true; } +/** + * Detect whether type T is a static array. + */ +template isStaticArray(T) +{ + const bool isStaticArray = isStaticArray_impl!(T).res; +} + + +static assert (isStaticArray!(int[51])); +static assert (isStaticArray!(int[][2])); +//static assert (isStaticArray!(char[][int][11])); +static assert (!isStaticArray!(int[])); +//static assert (!isStaticArray!(int[char])); +static assert (!isStaticArray!(int[1][])); + +template isArray(T) +{ + const bool isArray=false; +} +template isArray(T: T[]) +{ + const bool isArray=true; +} + +/** + * Tells whether the tuple T is an expression tuple. + */ +template isExpressionTuple(T ...) +{ + static if (is(void function(T))) + const bool isExpressionTuple = false; + else + const bool isExpressionTuple = true; +}