comparison 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
comparison
equal deleted inserted replaced
93:08508eebbb3e 94:61615fa85940
1
2 // Written in the D programming language.
3
4 /**
5 * Templates with which to extract information about
6 * types at compile time.
7 *
8 * Macros:
9 * WIKI = Phobos/StdTraits
10 * Copyright:
11 * Public Domain
12 */
13
14 /*
15 * Authors:
16 * Walter Bright, Digital Mars, www.digitalmars.com
17 * Tomasz Stachowiak (isStaticArray, isExpressionTuple)
18 */
19
1 module std.traits; 20 module std.traits;
2 struct TypeHolder(S, T...) { 21
3 S _ReturnType; 22 /***
4 T _ParameterTypeTuple; 23 * Get the type of the return value from a function,
24 * a pointer to function, or a delegate.
25 * Example:
26 * ---
27 * import std.traits;
28 * int foo();
29 * ReturnType!(foo) x; // x is declared as int
30 * ---
31 */
32 template ReturnType(alias dg)
33 {
34 alias ReturnType!(typeof(dg)) ReturnType;
5 } 35 }
6 TypeHolder!(S, T) *IFTI_gen(S, T...)(S delegate(T) dg) { return null; } 36
7 TypeHolder!(S, T) *IFTI_gen(S, T...)(S function(T) dg) { return null; } 37 /** ditto */
8 template ParameterTypeTuple(T) { 38 template ReturnType(dg)
9 alias typeof(IFTI_gen(T.init)._ParameterTypeTuple) ParameterTypeTuple; 39 {
40 static if (is(dg R == return))
41 alias R ReturnType;
42 else
43 static assert(0, "argument has no return type");
10 } 44 }
11 template ReturnType(T) { 45
12 alias typeof(IFTI_gen(T.init)._ReturnType) ReturnType; 46 /***
47 * Get the types of the paramters to a function,
48 * a pointer to function, or a delegate as a tuple.
49 * Example:
50 * ---
51 * import std.traits;
52 * int foo(int, long);
53 * void bar(ParameterTypeTuple!(foo)); // declares void bar(int, long);
54 * void abc(ParameterTypeTuple!(foo)[1]); // declares void abc(long);
55 * ---
56 */
57 template ParameterTypeTuple(alias dg)
58 {
59 alias ParameterTypeTuple!(typeof(dg)) ParameterTypeTuple;
13 } 60 }
14 template isArray(T) { const bool isArray=false; } 61
15 template isArray(T: T[]) { const bool isArray=true; } 62 /** ditto */
63 template ParameterTypeTuple(dg)
64 {
65 static if (is(dg P == function))
66 alias P ParameterTypeTuple;
67 else static if (is(dg P == delegate))
68 alias ParameterTypeTuple!(P) ParameterTypeTuple;
69 else static if (is(dg P == P*))
70 alias ParameterTypeTuple!(P) ParameterTypeTuple;
71 else
72 static assert(0, "argument has no parameters");
73 }
74
75
76 /***
77 * Get the types of the fields of a struct or class.
78 * This consists of the fields that take up memory space,
79 * excluding the hidden fields like the virtual function
80 * table pointer.
81 */
82
83 template FieldTypeTuple(S)
84 {
85 static if (is(S == struct) || is(S == class))
86 alias typeof(S.tupleof) FieldTypeTuple;
87 else
88 static assert(0, "argument is not struct or class");
89 }
90
91
92 /***
93 * Get a TypeTuple of the base class and base interfaces of
94 * this class or interface.
95 * Example:
96 * ---
97 * import std.traits, std.typetuple, std.stdio;
98 * interface I { }
99 * class A { }
100 * class B : A, I { }
101 *
102 * void main()
103 * {
104 * alias BaseTypeTuple!(B) TL;
105 * writefln(typeid(TL)); // prints: (A,I)
106 * }
107 * ---
108 */
109
110 template BaseTypeTuple(A)
111 {
112 static if (is(A P == super))
113 alias P BaseTypeTuple;
114 else
115 static assert(0, "argument is not a class or interface");
116 }
117
118 unittest
119 {
120 interface I { }
121 class A { }
122 class B : A, I { }
123
124 alias BaseTypeTuple!(B) TL;
125 assert(TL.length == 2);
126 assert(is (TL[0] == A));
127 assert(is (TL[1] == I));
128 }
129
130 /* *******************************************
131 */
132 template isStaticArray_impl(T)
133 {
134 const T inst = void;
135
136 static if (is(typeof(T.length)))
137 {
138 static if (!is(typeof(T) == typeof(T.init)))
139 { // abuses the fact that int[5].init == int
140 static if (is(T == typeof(T[0])[inst.length]))
141 { // sanity check. this check alone isn't enough because dmd complains about dynamic arrays
142 const bool res = true;
143 }
144 else
145 const bool res = false;
146 }
147 else
148 const bool res = false;
149 }
150 else
151 {
152 const bool res = false;
153 }
154 }
155 /**
156 * Detect whether type T is a static array.
157 */
158 template isStaticArray(T)
159 {
160 const bool isStaticArray = isStaticArray_impl!(T).res;
161 }
162
163
164 static assert (isStaticArray!(int[51]));
165 static assert (isStaticArray!(int[][2]));
166 //static assert (isStaticArray!(char[][int][11]));
167 static assert (!isStaticArray!(int[]));
168 //static assert (!isStaticArray!(int[char]));
169 static assert (!isStaticArray!(int[1][]));
170
171 template isArray(T)
172 {
173 const bool isArray=false;
174 }
175 template isArray(T: T[])
176 {
177 const bool isArray=true;
178 }
179
180 /**
181 * Tells whether the tuple T is an expression tuple.
182 */
183 template isExpressionTuple(T ...)
184 {
185 static if (is(void function(T)))
186 const bool isExpressionTuple = false;
187 else
188 const bool isExpressionTuple = true;
189 }