root/trunk/docsrc/traits.dd

Revision 2040, 11.6 kB (checked in by walter, 2 years ago)

typography

  • Property svn:eol-style set to native
Line 
1 Ddoc
2
3 $(SPEC_S Traits,
4
5     $(P Traits are extensions to the language to enable
6     programs, at compile time, to get at information
7     internal to the compiler. This is also known as
8     compile time reflection.
9     It is done as a special, easily extended syntax (similar
10     to Pragmas) so that new capabilities can be added
11     as required.
12     )
13
14 $(GRAMMAR
15 $(GNAME TraitsExpression):
16     $(B __traits) $(B $(LPAREN)) $(I TraitsKeyword) $(B ,) $(I TraitsArguments) $(B $(RPAREN))
17
18 $(GNAME TraitsKeyword):
19     $(B isAbstractClass)
20     $(B isArithmetic)
21     $(B isAssociativeArray)
22     $(B isFinalClass)
23     $(B isFloating)
24     $(B isIntegral)
25     $(B isScalar)
26     $(B isStaticArray)
27     $(B isUnsigned)
28     $(B isVirtualFunction)
29     $(B isAbstractFunction)
30     $(B isFinalFunction)
31 $(V2      $(GBLINK isStaticFunction)
32 )    $(GBLINK isRef)
33     $(GBLINK isOut)
34     $(GBLINK isLazy)
35     $(B hasMember)
36 $(V2      $(GBLINK identifier)
37 )    $(B getMember)
38 $(V2      $(GBLINK getOverloads)
39 )    $(GBLINK getVirtualFunctions)
40     $(B classInstanceSize)
41     $(GBLINK allMembers)
42     $(GBLINK derivedMembers)
43     $(B isSame)
44     $(B compiles)
45
46 $(GNAME TraitsArguments):
47     $(I TraitsArgument)
48     $(I TraitsArgument) $(B ,) $(I TraitsArguments)
49
50 $(GNAME TraitsArgument):
51     $(I AssignExpression)
52     $(I Type)
53 )
54
55 $(H2 isArithmetic)
56
57     $(P If the arguments are all either types that are arithmetic types,
58     or expressions that are typed as arithmetic types, then $(B true)
59     is returned.
60     Otherwise, $(B false) is returned.
61     If there are no arguments, $(B false) is returned.)
62
63 ---
64 import std.stdio;
65
66 void main()
67 {
68     int i;
69     writefln(__traits(isArithmetic, int));
70     writefln(__traits(isArithmetic, i, i+1, int));
71     writefln(__traits(isArithmetic));
72     writefln(__traits(isArithmetic, int*));
73 }
74 ---
75
76     $(P Prints:)
77
78 $(CONSOLE
79 true
80 true
81 false
82 false
83 )
84
85 $(H2 isFloating)
86
87     $(P Works like $(B isArithmetic), except it's for floating
88     point types (including imaginary and complex types).)
89
90 $(H2 isIntegral)
91
92     $(P Works like $(B isArithmetic), except it's for integral
93     types (including character types).)
94
95 $(H2 isScalar)
96
97     $(P Works like $(B isArithmetic), except it's for scalar
98     types.)
99
100 $(H2 isUnsigned)
101
102     $(P Works like $(B isArithmetic), except it's for unsigned
103     types.)
104
105 $(H2 isStaticArray)
106
107     $(P Works like $(B isArithmetic), except it's for static array
108     types.)
109
110 $(H2 isAssociativeArray)
111
112     $(P Works like $(B isArithmetic), except it's for associative array
113     types.)
114
115 $(H2 isAbstractClass)
116
117     $(P If the arguments are all either types that are abstract classes,
118     or expressions that are typed as abstract classes, then $(B true)
119     is returned.
120     Otherwise, $(B false) is returned.
121     If there are no arguments, $(B false) is returned.)
122
123 ---
124 import std.stdio;
125
126 abstract class C { int foo(); }
127
128 void main()
129 {
130     C c;
131     writefln(__traits(isAbstractClass, C));
132     writefln(__traits(isAbstractClass, c, C));
133     writefln(__traits(isAbstractClass));
134     writefln(__traits(isAbstractClass, int*));
135 }
136 ---
137
138     $(P Prints:)
139
140 $(CONSOLE
141 true
142 true
143 false
144 false
145 )
146
147 $(H2 isFinalClass)
148
149     $(P Works like $(B isAbstractClass), except it's for final
150     classes.)
151
152 $(H2 isVirtualFunction)
153
154     $(P Takes one argument. If that argument is a virtual function,
155     $(B true) is returned, otherwise $(B false).
156     )
157
158 ---
159 import std.stdio;
160
161 struct S
162 {
163   void bar() { }
164 }
165
166 class C
167 {
168   void bar() { }
169 }
170
171 void main()
172 {
173     writefln(__traits(isVirtualFunction, C.bar));  // true
174     writefln(__traits(isVirtualFunction, S.bar));  // false
175 }
176 ---
177
178 $(H2 isAbstractFunction)
179
180     $(P Takes one argument. If that argument is an abstract function,
181     $(B true) is returned, otherwise $(B false).
182     )
183
184 ---
185 import std.stdio;
186
187 struct S
188 {
189   void bar() { }
190 }
191
192 class C
193 {
194   void bar() { }
195 }
196
197 class AC
198 {
199   abstract void foo();
200 }
201
202 void main()
203 {
204     writefln(__traits(isAbstractFunction, C.bar));   // false
205     writefln(__traits(isAbstractFunction, S.bar));   // false
206     writefln(__traits(isAbstractFunction, AC.foo));  // true
207 }
208 ---
209
210 $(H2 isFinalFunction)
211
212     $(P Takes one argument. If that argument is a final function,
213     $(B true) is returned, otherwise $(B false).
214     )
215
216 ---
217 import std.stdio;
218
219 struct S
220 {
221   void bar() { }
222 }
223
224 class C
225 {
226   void bar() { }
227   final void foo();
228 }
229
230 final class FC
231 {
232   void foo();
233 }
234
235 void main()
236 {
237     writefln(__traits(isFinalFunction, C.bar));   // false
238     writefln(__traits(isFinalFunction, S.bar));   // false
239     writefln(__traits(isFinalFunction, C.foo));   // true
240     writefln(__traits(isFinalFunction, FC.foo));  // true
241 }
242 ---
243
244 $(V2
245 $(H2 $(GNAME isStaticFunction))
246
247     $(P Takes one argument. If that argument is a static function,
248     meaning it has no context pointer,
249     $(B true) is returned, otherwise $(B false).
250     )
251 )
252
253 $(H2 $(GNAME isRef), $(GNAME isOut), $(GNAME isLazy))
254
255     $(P Takes one argument. If that argument is a declaration,
256     $(B true) is returned if it is $(D_KEYWORD ref), $(D_KEYWORD out),
257     $(D_KEYWORD lazy), otherwise $(B false).
258     )
259
260 ---
261 void fooref(ref int x)
262 {
263     static assert(__traits(isRef, x));
264     static assert(!__traits(isOut, x));
265     static assert(!__traits(isLazy, x));
266 }
267
268 void fooout(out int x)
269 {
270     static assert(!__traits(isRef, x));
271     static assert(__traits(isOut, x));
272     static assert(!__traits(isLazy, x));
273 }
274
275 void foolazy(lazy int x)
276 {
277     static assert(!__traits(isRef, x));
278     static assert(!__traits(isOut, x));
279     static assert(__traits(isLazy, x));
280 }
281 ---
282
283 $(H2 hasMember)
284
285     $(P The first argument is a type that has members, or
286     is an expression of a type that has members.
287     The second argument is a string.
288     If the string is a valid property of the type,
289     $(B true) is returned, otherwise $(B false).
290     )
291
292 ---
293 import std.stdio;
294
295 struct S
296 {
297     int m;
298 }
299
300 void main()
301 {   S s;
302
303     writefln(__traits(hasMember, S, "m")); // true
304     writefln(__traits(hasMember, s, "m")); // true
305     writefln(__traits(hasMember, S, "y")); // false
306     writefln(__traits(hasMember, int, "sizeof")); // true
307 }
308 ---
309
310 $(V2
311 $(H2 $(GNAME identifier))
312
313     $(P Takes one argument, a symbol. Returns the identifier
314     for that symbol as a string literal.
315     )
316 )
317
318 $(H2 getMember)
319
320     $(P Takes two arguments, the second must be a string.
321     The result is an expression formed from the first
322     argument, followed by a $(SINGLEQUOTE .), followed by the second
323     argument as an identifier.
324     )
325
326 ---
327 import std.stdio;
328
329 struct S
330 {
331     int mx;
332     static int my;
333 }
334
335 void main()
336 { S s;
337
338   __traits(getMember, s, "mx") = 1;  // same as s.mx=1;
339   writefln(__traits(getMember, s, "m" ~ "x")); // 1
340
341   __traits(getMember, S, "mx") = 1;  // error, no this for S.mx
342   __traits(getMember, S, "my") = 2;  // ok
343 }
344 ---
345
346 $(V2
347 $(H2 $(GNAME getOverloads))
348
349     $(P The first argument is a class type or an expression of
350     class type.
351     The second argument is a string that matches the name of
352     one of the functions of that class.
353     The result is an array of all the overloads of that function.
354     )
355
356 ---
357 import std.stdio;
358
359 class D
360 {
361     this() { }
362     ~this() { }
363     void foo() { }
364     int foo(int) { return 2; }
365 }
366
367 void main()
368 {
369     D d = new D();
370
371     foreach (t; __traits(getOverloads, D, "foo"))
372     writefln(typeid(typeof(t)));
373
374     alias typeof(__traits(getOverloads, D, "foo")) b;
375     foreach (t; b)
376     writefln(typeid(t));
377
378     auto i = __traits(getOverloads, d, "foo")[1](1);
379     writefln(i);
380 }
381 ---
382
383     $(P Prints:)
384
385 $(CONSOLE
386 void()
387 int()
388 void()
389 int()
390 2
391 )
392 )
393
394 $(H2 $(GNAME getVirtualFunctions))
395
396     $(P The first argument is a class type or an expression of
397     class type.
398     The second argument is a string that matches the name of
399     one of the functions of that class.
400     The result is an array of the virtual overloads of that function.
401     )
402
403 ---
404 import std.stdio;
405
406 class D
407 {
408     this() { }
409     ~this() { }
410     void foo() { }
411     int foo(int) { return 2; }
412 }
413
414 void main()
415 {
416     D d = new D();
417
418     foreach (t; __traits(getVirtualFunctions, D, "foo"))
419     writefln(typeid(typeof(t)));
420
421     alias typeof(__traits(getVirtualFunctions, D, "foo")) b;
422     foreach (t; b)
423     writefln(typeid(t));
424
425     auto i = __traits(getVirtualFunctions, d, "foo")[1](1);
426     writefln(i);
427 }
428 ---
429
430     $(P Prints:)
431
432 $(CONSOLE
433 void()
434 int()
435 void()
436 int()
437 2
438 )
439
440 $(H2 classInstanceSize)
441
442     $(P Takes a single argument, which must evaluate to either
443     a class type or an expression of class type.
444     The result
445     is of type $(CODE size_t), and the value is the number of
446     bytes in the runtime instance of the class type.
447     It is based on the static type of a class, not the
448     polymorphic type.
449     )
450
451 $(H2 $(GNAME allMembers))
452
453     $(P Takes a single argument, which must evaluate to either
454     a type or an expression of type.
455     $(V1 An array)
456     $(V2 A tuple)
457     of string literals is returned, each of which
458     is the name of a member of that type combined with all
459     of the members of the base classes (if the type is a class).
460     No name is repeated.
461     Builtin properties are not included.
462     )
463
464 ---
465 import std.stdio;
466
467 class D
468 {
469     this() { }
470     ~this() { }
471     void foo() { }
472     int foo(int) { return 0; }
473 }
474
475 void main()
476 {
477     auto a = __traits(allMembers, D);
478     writefln(a);
479 $(V2      // _ctor,_dtor,foo,print,toString,toHash,opCmp,opEquals
480
481     auto b = [ __traits(allMembers, D) ];
482     writefln(b);
483 )    // [_ctor,_dtor,foo,print,toString,toHash,opCmp,opEquals]
484 }
485 ---
486
487     $(P The order in which the strings appear in the result
488     is not defined.)
489
490 $(H2 $(GNAME derivedMembers))
491
492     $(P Takes a single argument, which must evaluate to either
493     a type or an expression of type.
494     $(V1 An array)
495     $(V2 A tuple)
496     of string literals is returned, each of which
497     is the name of a member of that type.
498     No name is repeated.
499     Base class member names are not included.
500     Builtin properties are not included.
501     )
502
503 ---
504 import std.stdio;
505
506 class D
507 {
508     this() { }
509     ~this() { }
510     void foo() { }
511     int foo(int) { return 0; }
512 }
513
514 void main()
515 {
516     auto a = __traits(derivedMembers, D);
517 $(V1      writefln(a);  // [_ctor,_dtor,foo])
518 $(V2      writefln(a);  // _ctor,_dtor,foo)
519 }
520 ---
521
522     $(P The order in which the strings appear in the result
523     is not defined.)
524
525 $(H2 isSame)
526
527     $(P Takes two arguments and returns bool $(B true) if they
528     are the same symbol, $(B false) if not.)
529
530 ---
531 import std.stdio;
532
533 struct S { }
534
535 int foo();
536 int bar();
537
538 void main()
539 {
540     writefln(__traits(isSame, foo, foo)); // true
541     writefln(__traits(isSame, foo, bar)); // false
542     writefln(__traits(isSame, foo, S));   // false
543     writefln(__traits(isSame, S, S));     // true
544     writefln(__traits(isSame, std, S));   // false
545     writefln(__traits(isSame, std, std)); // true
546 }
547 ---
548
549     $(P If the two arguments are expressions made up of literals
550     or enums that evaluate to the same value, true is returned.)
551
552 $(H2 compiles)
553
554     $(P Returns a bool $(B true) if all of the arguments
555     compile (are semantically correct).
556     The arguments can be symbols, types, or expressions that
557     are syntactically correct.
558     The arguments cannot be statements or declarations.
559     )
560
561     $(P If there are no arguments, the result is $(B false).)
562
563 ---
564 import std.stdio;
565
566 struct S
567 {
568     static int s1;
569     int s2;
570 }
571
572 int foo();
573 int bar();
574
575 void main()
576 {
577     writefln(__traits(compiles));                      // false
578     writefln(__traits(compiles, foo));                 // true
579     writefln(__traits(compiles, foo + 1));             // true
580     writefln(__traits(compiles, &foo + 1));            // false
581     writefln(__traits(compiles, typeof(1)));           // true
582     writefln(__traits(compiles, S.s1));                // true
583     writefln(__traits(compiles, S.s3));                // false
584     writefln(__traits(compiles, 1,2,3,int,long,std));  // true
585     writefln(__traits(compiles, 3[1]));                // false
586     writefln(__traits(compiles, 1,2,3,int,long,3[1])); // false
587 }
588 ---
589
590     $(P This is useful for:)
591
592     $(UL
593     $(LI Giving better error messages inside generic code than
594     the sometimes hard to follow compiler ones.)
595     $(LI Doing a finer grained specialization than template
596     partial specialization allows for.)
597     )
598
599 )
600
601 Macros:
602     TITLE=Traits
603     WIKI=Traits
604     GBLINK=$(LINK2 #$0, $(B $0))
605     H2=<h2>$0</h2>
Note: See TracBrowser for help on using the browser.