-
Notifications
You must be signed in to change notification settings - Fork 27
/
D-templates-tutorial.html
7269 lines (6526 loc) · 529 KB
/
D-templates-tutorial.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<h1 id="introduction">Introduction</h1>
<p>Templates are a central feature of D, giving you powerful compile-time code generation abilities that'll make your code cleaner, more flexible and even more efficient. They are used everywhere in <a href="http://www.dlang.org/phobos/">Phobos</a> --- D standard library --- and therefore any D user should know about them. But, based on C++ templates as they are, D templates can be a bit daunting at first. The <a href="http://www.dlang.org">D Programming Language</a> website's <a href="http://www.dlang.org/template.html">documentation</a> is a good start, though its description of templates is spread among many different files and (as it's a language reference) its material doesn't so much <em>teach</em> you how to use templates as <em>show</em> you their syntax and semantics.</p>
<p>This document aims to be a kind of tutorial on D templates, to show the beginning D coder what can be achieved with them. When I was using C++, I remember <em>never</em> using templates for more than <em>containers-of-T</em> stuff, and considered Boost-level<a href="#fn1" class="footnoteRef" id="fnref1"><sup>1</sup></a> metaprogramming the kind of code I could never understand, never mind produce. Well, D's sane syntax for templates and nifty features such as <code class="sourceCode d"><span class="kw">static</span> <span class="kw">if</span></code>, <code class="sourceCode d"><span class="kw">alias</span></code> or tuples cured me of that impression. I hope this document will help you, too.</p>
<h2 id="whats-in-this-document">What's in This Document</h2>
<p><a href="#basics">The first part</a> deals with the very basics: how to declare and instantiate a template, the standard `building blocks' you'll use in almost all your templates, along with <a href="#function-templates">function</a>, <a href="#struct-templates">struct</a> and <a href="#class-templates">class</a> templates. Throughout the text, examples will present applications of these concepts.</p>
<p><a href="#some-more-advanced-considerations">The second part</a> is about more advanced topics a D template user will probably use, but not on a daily basis, like <a href="#constraints">template constraints</a>, <a href="#mixin-templates">mixin templates</a> or <a href="#operator-overloading">operator overloading</a>.</p>
<p><a href="#around-templates">The third part</a> presents other metaprogramming tools: <a href="#string-mixins">string mixins</a>, <a href="#compile-time-function-evaluation">compile-time function evaluation</a>, and <a href="#traits">__traits</a>. These are seen from a template-y point of view: how they can interact with templates and what you can build with them in conjunction with templates.</p>
<p><a href="#examples">The fourth part</a> presents more developed examples of what can be done with templates, based on real needs I had at some time and that could be fulfilled with templates.</p>
<p>Finally, an appendix on the <a href="#the-is-expression">ubiquitous is expression</a> and another giving <a href="#resources-and-further-reading">resources</a> and further reading advice complete this document.</p>
<h2 id="conventions">Conventions</h2>
<p>To make this document more easily readable, I'll use standard coding books conventions, by highlighting parts of the text. Mainly, in this doc:</p>
<ul>
<li>D keywords will be marked like this: <code class="sourceCode d"><span class="dt">int</span></code>, <code class="sourceCode d"><span class="kw">static</span> <span class="kw">if</span></code>, <code class="sourceCode d">__traits</code> (these will be colored or not, depending on what was used to generate the document).</li>
<li>Symbols and names used in code samples and cited in the text will be written like this: <code>myFunc</code>, <code>flatten</code>.</li>
<li>internal links will be like <a href="#introduction">this</a>.</li>
<li>external links will be like <a href="http://www.dlang.org">this</a>.</li>
<li>Syntax-highlighted code samples are shown like this:</li>
</ul>
<table class="sourceCode d numberLines"><tr class="sourceCode"><td class="lineNumbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="sourceCode"><pre><code class="sourceCode d"><span class="co">/**</span>
<span class="co"> * This is a doc comment.</span>
<span class="co"> */</span>
<span class="kw">module</span> intro;
<span class="kw">import</span> std.stdio;
<span class="dt">void</span> main()
{
<span class="dt">int</span> times = <span class="dv">10</span>;
<span class="co">// This is a comment</span>
<span class="kw">foreach</span>(i; <span class="dv">0</span>..times)
writeln(<span class="st">"Hello, Word!"</span>);
}</code></pre></td></tr></table>
<p>Numbered lines will be used only when necessary.</p>
<p>I will sometimes make a little explanatory detour, discussing a small piece of info too small to be in its own section but of interest to the reader nonetheless. These will be marked so:</p>
<blockquote>
<p><strong>Semi-Literate Programming.</strong> Most code samples presented in this document will compile with a reasonably recent D compiler. In the <code>utils</code> directory, there is a small D script called <code>codesamples.d</code> that extracts code samples from the mardkdown files.</p>
</blockquote>
<blockquote>
<p>Samples with a <code class="sourceCode d"><span class="kw">module</span> name;</code> declaration will be extracted, a file called <code>name.d</code> will be created and compiled (possibly with a stub <code class="sourceCode d">main()</code> if none exists). The previous code sample creates a file called <code>intro.d</code> and so on. The compilation results are put in a file called <code>result.txt</code>. Samples that depend on other samples just import them (yeah for D modularity, no need for specific mark-up to weave code together). Samples with a name ending in <code>_error</code> will <em>not</em> compile, as expected: they are there to show errors, mistakes and gotchas. Anonymous samples are not extracted: I use them to show small snippets not intended to stand by themselves, or just to show D-ish pseudocode.</p>
</blockquote>
<blockquote>
<p>All in all, you can see this entire document as a gigantic D package, describing hundreds of small modules.</p>
</blockquote>
<p>Finally, some sections in this doc are not finished yet. The sections I consider unfinished will contain this:</p>
<blockquote>
<p><strong>Unfinished.</strong> Hey, now I've added a Thanks section. But as long as I'm adding new parts in the document, new appendices, and new section, this intro will not be finished.</p>
</blockquote>
<p>I probably forgot some 'unfinished' tags, do not hesitate to tell me so.</p>
<h2 id="how-to-get-this-document">How to Get This Document</h2>
<p>This document is just a markdown file <a href="http://github.com/PhilippeSigaud/D-templates-tutorial">hosted on Github</a>. Don't hesitate to fork it or (even better for me) to make pull requests! For those of you reading this on paper, the address is:</p>
<p><a href="https://github.com/PhilippeSigaud/D-templates-tutorial">https://github.com/PhilippeSigaud/D-templates-tutorial</a></p>
<h2 id="thanks">Thanks</h2>
<p>As soon as I publicly released this document, D community members gave me help, suggestions, corrections, and code samples. This is cool to see a D network emerge and people participating in common projects. The following people helped me:</p>
<p>Craig Dillabaugh, Andrej Mitrovic, Justin Whear, Zachary Lund, Jacob Carlborg, Timon Gehr, Simen Kjaeras, Andrei Alexandrescu, Bjorn Lietz-Spendig.</p>
<p>Thanks guys!</p>
<h1 id="basics">Basics</h1>
<h2 id="why-templates">Why Templates?</h2>
<p>Here you are, reading a book-size document on D templates. But why should you be interested in templates? Let say you have this wonderful tree struct:</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> basicTree1;
<span class="kw">struct</span> Tree {
<span class="dt">int</span> value;
Tree[] children;
<span class="dt">size_t</span> size() {
<span class="dt">size_t</span> s = <span class="dv">1</span>;
<span class="kw">foreach</span>(child; children)
s += child.size();
<span class="kw">return</span> s;
}
<span class="dt">bool</span> isLeaf() @property {
<span class="kw">return</span> children.<span class="dt">length</span> == <span class="dv">0</span>;
}
}</code></pre>
<p>Which is used like this:</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> usingBasicTree1;
<span class="kw">import</span> basicTree1;
<span class="dt">void</span> main()
{
<span class="kw">auto</span> tree = Tree(<span class="dv">0</span>, [Tree(<span class="dv">1</span>), Tree(<span class="dv">2</span>, [Tree(<span class="dv">3</span>), Tree(<span class="dv">4</span>), Tree(<span class="dv">5</span>)])]);
<span class="kw">assert</span>(!tree.isLeaf);
<span class="kw">assert</span>(tree.size() == <span class="dv">6</span>);
}</code></pre>
<p>All is well and good, this is a nice basic <code class="sourceCode d"><span class="dt">int</span></code>-holding n-ary tree. But what if, after some time, you need a <code class="sourceCode d"><span class="dt">float</span></code>-holding one? No problem, this can be coded easily, with a bit of copy-pasting. First, we change <code>Tree</code> to <code>IntTree</code> and then create a <code>FloatTree</code> node:</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> basicTree2;
<span class="kw">struct</span> IntTree {
<span class="dt">int</span> value;
IntTree[] children;
<span class="dt">size_t</span> size() {
<span class="dt">size_t</span> s = <span class="dv">1</span>;
<span class="kw">foreach</span>(child; children)
s += child.size();
<span class="kw">return</span> s;
}
<span class="dt">bool</span> isLeaf() @property {
<span class="kw">return</span> children.<span class="dt">length</span> == <span class="dv">0</span>;
}
}
<span class="kw">struct</span> FloatTree {
<span class="dt">float</span> value;
FloatTree[] children;
<span class="dt">size_t</span> size() {
<span class="dt">size_t</span> s = <span class="dv">1</span>;
<span class="kw">foreach</span>(child; children)
s += child.size();
<span class="kw">return</span> s;
}
<span class="dt">bool</span> isLeaf() @property {
<span class="kw">return</span> children.<span class="dt">length</span> == <span class="dv">0</span>;
}
}</code></pre>
<p>But that's a lot of code duplication: the only changes are the types of <code>value</code> and <code>children</code>, which become a <code class="sourceCode d"><span class="dt">float</span></code> and <code>FloatTree</code> instead of an <code class="sourceCode d"><span class="dt">int</span></code> and <code>IntTree</code>. What a waste! And what if we need another tree, for example holding functions (a tree of callbacks, say)? There must be a better way.</p>
<p>Let's observe the previous code. What we need here is a way to produce code by generating different tree types, injecting the type for <code>value</code> as user-defined input. It's a bit like a function: pushing parameters and getting a result. Let's imagine some code with a placeholder, let's call it <code>Type</code>, to represent the type of <code>value</code>.</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">struct</span> Tree {
Type value;
Tree[] children;
<span class="dt">size_t</span> size() {
<span class="dt">size_t</span> s = <span class="dv">1</span>;
<span class="kw">foreach</span>(child; children)
s += child.size();
<span class="kw">return</span> s;
}
<span class="dt">bool</span> isLeaf() @property {
<span class="kw">return</span> children.<span class="dt">length</span> == <span class="dv">0</span>;
}
}</code></pre>
<p>But here <code>Type</code> is a symbol introduced without warning in the struct scope. If you try to compile that code, the compiler will rightfully complain and ask you 'where does <code>Type</code> come from?'. With functions, parameters are introduced in a parameter list(!) that will push them into the following scope, the function body. That's what we want here. We should tell the compiler that <code>Type</code> is our placeholder, to be provided latter on. Let's continue with our imaginary syntax here:</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> genericTree;
<span class="kw">struct</span> Tree(Type) {
Type value;
Tree[] children;
<span class="dt">size_t</span> size() {
<span class="dt">size_t</span> s = <span class="dv">1</span>;
<span class="kw">foreach</span>(child; children)
s += child.size();
<span class="kw">return</span> s;
}
<span class="dt">bool</span> isLeaf() @property {
<span class="kw">return</span> children.<span class="dt">length</span> == <span class="dv">0</span>;
}
}</code></pre>
<p>See how I introduced <code>Type</code> in a (one-element) parameter list, right after <code>Tree</code>? Ideally, this is what a struct definition abstracted on the type of <code>value</code> should look like, right? A sort of... recipe to be used to generate the <code>Tree</code> we need.</p>
<p>Look no further, the previous definition is standard D for a struct template! You can compile it and use it to your heart content (see the next chapters to do that).</p>
<p>That's the essence of templates: writing some code, seeing way to abstract it on certain items (types, symbols, numbers, the possibility are numerous) and defining such a generic recipe, for further perusal.</p>
<h2 id="what-is-a-template">What is a Template?</h2>
<p>In the next chapters, you'll see how to define <a href="#function-templates">function</a>, <a href="#struct-templates">struct</a> and <a href="#class-templates">class</a> templates. The nifty syntax demonstrated just before is a special case for these constructs. It's a simplified version of the full template declaration syntax, which we will see in the next section.</p>
<p>But before that, I'd like to introduce what a template <em>really</em> is, because this definition is the most fundamental of the whole document. As I said, a template is a way to define a blueprint to generate some code, be it a class definition, a function or... what? What could be the most abstract unit of code?</p>
<p>Let us say you have a wonderful piece of code, full of function definitions, structs and their methods, new symbols, and so on. This piece of code offer a few entry points for further parameterization: some types, some symbols could be abstracted away and put into a template parameter list.</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="co">// Could be parameterized on Type, as seen before</span>
<span class="kw">struct</span> Tree { ... }
<span class="co">// Could be parameterized on the Tree type also</span>
<span class="co">// And maybe on f?</span>
Tree mapOnTree(Tree input, Tree <span class="kw">delegate</span>(Tree) f) { ... }
<span class="dt">void</span> printTree(Tree input) { ... }
<span class="co">// What about defining a different TreeArray for all possible Trees?</span>
<span class="kw">alias</span> TreeArray = Tree[];</code></pre>
<p>But where is the basic unit to hold this code? Well, a code block of course, or a <em>scope</em>. Ideally, we would like a way to group all the previous declaration into one unit, with the same parameter list:</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="co">// scope?</span>
(Type)
{
<span class="kw">struct</span> Tree { <span class="co">/* using Type here */</span>}
Tree mapOnTree(Tree input, Tree <span class="kw">delegate</span>(Tree) f) { <span class="co">/* here also */</span> }
<span class="dt">void</span> printTree(Tree input) { <span class="co">/* the same */</span> }
<span class="kw">alias</span> TreeArray = Tree[]; <span class="co">// You get it</span>
}</code></pre>
<p>Since we will need to 'call' it to produce some code (a bit like you'd call a function), this code block needs a name. And then, we just need to tell the compiler: 'here, this is a blueprint'. The D keyword for that is (you got it) <code class="sourceCode d"><span class="kw">template</span></code>:</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">template</span> MyDefs(Type)
{
<span class="kw">struct</span> Tree {...}
Tree mapOnTree(Tree input, Tree <span class="kw">delegate</span>(Tree) f) {...}
<span class="dt">void</span> printTree(Tree input) {...}
<span class="kw">alias</span> TreeArray = Tree[];
}</code></pre>
<p>Here you are. This is what a template is, at its core: a named, parameterized, code block, ready to be instantiated just for you.</p>
<h2 id="template-declarations">Template Declarations</h2>
<p>Here is the syntax for a template declaration:</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">template</span> templateName(list, of, parameters)
{
<span class="co">// Some syntactically correct declarations here</span>
<span class="co">// The arguments are accessible inside the template scope.</span>
}</code></pre>
<p><code>templateName</code> is your usual D identifier and the list of parameters is a comma-separated list of zero or more template parameters. These can be:</p>
<dl>
<dt>Types (<code>identifier</code>)</dt>
<dd><p>An <code>identifier</code> alone by itself is considered a type name. The common D style is to use identifiers beginning with a capital letter (<code>Range</code>, <code>Rest</code>), as for any user-defined types. Many D templates use the C++ tradition of one-capital-letter names for types, starting from <code>T</code> (<code>U</code>, <code>V</code>, ...). Do not feel constrained by this, use what makes your templates most easy to understand.</p>
</dd>
<dt>Aliases (<code class="sourceCode d"><span class="kw">alias</span> identifier</code>)</dt>
<dd><p>You declare them with <code class="sourceCode d"><span class="kw">alias</span> identifier</code>. They will capture not types but <em>symbols</em>: variable names, class <em>names</em>, even other template names. They will also accept many compile-time literals: strings, arrays, function literals, ... Mostly, if you need a widely-accepting template, use an <code>alias</code> parameter. Note that they will <em>not</em> accept built-in types as arguments, however, since <code>int</code> is not a valid identifier in D (it's a keyword).</p>
</dd>
<dt>Literal values (<code>typeName identifier</code>)</dt>
<dd><p>They are all declared like this: <code>typeName identifier</code>. Literal values can be integral values (<code class="sourceCode d"><span class="dt">int</span></code>, <code class="sourceCode d"><span class="dt">ulong</span></code>, ...), <code class="sourceCode d"><span class="kw">enum</span></code>-based, strings, <code class="sourceCode d">chars</code>, floating-point values or boolean values. Any expression that can be evaluated at compile-time is OK. For example : <code class="sourceCode d"><span class="dt">int</span> depth</code> or <code class="sourceCode d"><span class="dt">string</span> name</code>.</p>
</dd>
<dt>Template parameters tuples (<code>identifier...</code>)</dt>
<dd><p>The syntax is <code>identifier...</code> (yes, three dots) and the tuple must be the last parameter of a template. Template parameters tuples will capture under one identifier <em>an entire list of template parameters</em> (types, names, literals, ...). These tuples will store any template argument you will throw at them. If no argument is passed, you will just get an empty, zero-length, tuple. Really, as they can deal with types as well as symbols, these tuples are a bit of a mongrel type but they are wonderfully powerful and easy to use, as you will see in section <a href="#template-tuple-parameters">Tuples</a>.</p>
</dd>
</dl>
<p>Of those, types and aliases are the most common, while floating point values are fairly rare: their use as arguments for compile-time calculations have been superseded by D's Compile-Time Function Evaluation, aka <a href="#ctfe">CTFE</a>. You'll see different uses of these parameters in this document.</p>
<p>Note that pointers, arrays, objects (instantiated classes), structs or functions are not part of this list. But as I said, alias parameters allow you to capture and use array, class, function or struct <em>names</em> and then access their capacities.</p>
<blockquote>
<p><strong>Aliases, Symbols and Names.</strong> There is big difference between built-in types like <code class="sourceCode d"><span class="dt">int</span></code> or <code class="sourceCode d"><span class="dt">double</span>[<span class="dv">3</span>]</code> and user-defined types. A user-defined type, say a class called <code>MyClass</code>, is a type name. So, it's <em>both</em> a type (the class <code>MyClass</code>, accepted by type templates arguments) and a name, a symbol (<code>MyClass</code>, accepted by <code>alias</code> template parameters). On the other hand, <code class="sourceCode d"><span class="dt">int</span></code>, being a D keyword is not a symbol nor a name. It's just a type. You cannot pass it to an alias template parameter.</p>
</blockquote>
<p>The template body can contain any standard D declarations: variable, function, class, interface, other templates, alias declarations,... The only exception I can think of is declaring a <code>module</code>, as this is done at the top-level scope.</p>
<blockquote>
<p><strong>Syntax and Semantics.</strong> Code inside a <code class="sourceCode d"><span class="kw">template</span></code> declaration only has to be syntactically correct D code (that is: code that looks like D code). The semantics are not checked until instantiation. That means you can code happily, writing templates upon templates and the compiler won't bat an eye if you do not exercise your templates by instantiating them.</p>
</blockquote>
<p>Inside the template body, the parameters are all accessible as placeholders for the future arguments. Also, the template's own name refers to its current instantiation when the code is generated. This is mostly used in <a href="#struct-templates">struct templates</a> and <a href="#class-templates">class templates</a>.</p>
<p>Here are some template declaration examples:</p>
<table class="sourceCode d numberLines"><tr class="sourceCode"><td class="lineNumbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
</pre></td><td class="sourceCode"><pre><code class="sourceCode d"><span class="kw">module</span> declaration;
<span class="kw">template</span> ArrayOf(T) <span class="co">// T is a type</span>
{
<span class="kw">alias</span> ArrayType = T[];
<span class="kw">alias</span> ElementType = T;
}
<span class="kw">template</span> Transformer(From, To) <span class="co">// From and To are types, too</span>
{
To transform(From from)
{
<span class="kw">import</span> std.conv;
<span class="kw">return</span> to!(To)(from);
}
<span class="kw">class</span> Modificator
{
From f;
To t;
<span class="kw">this</span>(From f) { <span class="co">/*...*/</span> }
}
}
<span class="kw">template</span> nameOf(<span class="kw">alias</span> a)
{
<span class="kw">enum</span> <span class="dt">string</span> name = a.<span class="dt">stringof</span>; <span class="co">// enum: manifest constant</span>
<span class="co">// determined at compile-time.</span>
<span class="co">// See below.</span>
}
<span class="kw">template</span> ComplicatedOne(T, <span class="dt">string</span> s, <span class="kw">alias</span> a, <span class="dt">bool</span> b, <span class="dt">int</span> i)
{ <span class="co">/* some code using T, s, a, b and i */</span> }
<span class="kw">template</span> Minimalist() {} <span class="co">// Zero-parameter template declaration.</span>
<span class="kw">template</span> OneOrMore(FirstType, Rest...) <span class="co">// Rest is a tuple.</span>
{ <span class="co">/*...*/</span> }
<span class="kw">template</span> ZeroOrMore(Types...) <span class="co">// Types is a tuple.</span>
{ <span class="co">/*...*/</span> }
<span class="kw">template</span> Multiple(T) { <span class="co">/*...*/</span> } <span class="co">// One arg version.</span>
<span class="kw">template</span> Multiple(T,U) { <span class="co">/*...*/</span> } <span class="co">// Two args,</span>
<span class="kw">template</span> Multiple(T,U,V) { <span class="co">/*...*/</span> } <span class="co">// and three.</span></code></pre></td></tr></table>
<p>The full syntax for template declarations is slightly more complex, I'll introduce more of it in the next sections. You'll see for example type restrictions in section <a href="#templates-specializations">Templates Specializations</a>, default values in section <a href="#default-values">Default Values</a>, instantiation constraints in <a href="#constraints">Template Constraints</a>, and more on tuples in section <a href="#template-tuple-parameters">tuples</a>.</p>
<p>There is a limitation that's interesting to keep in mind: templates can be declared in almost any scope, except inside a (regular) function.</p>
<blockquote>
<p><strong>enum.</strong> In the previous code, see line 27? It defines a <code class="sourceCode d"><span class="dt">string</span></code> called <code>name</code> as a member of <code>nameOf</code>. The <code class="sourceCode d"><span class="kw">enum</span></code> placed right before means <code>name</code> is a compile-time constant. You can see it as a kind of storage class, in the line of <code class="sourceCode d"><span class="kw">immutable</span></code> or <code class="sourceCode d"><span class="kw">const</span></code>, one that means the value is totally defined and fixed at runtime. You'll see numerous examples of <code class="sourceCode d"><span class="kw">enum</span></code> in this document.</p>
</blockquote>
<h2 id="instantiating-a-template">Instantiating a Template</h2>
<h3 id="syntax">Syntax</h3>
<p>To instantiate a template, use the following syntax:</p>
<pre class="sourceCode d"><code class="sourceCode d">templateName!(list, of, arguments)</code></pre>
<p>Note the exclamation point (<code>!</code>) before the comma-separated argument list. That's what differentiate template arguments lists from standard (funtion) argument lists. If both are present (for function templates), we will use:</p>
<pre><code>templateName!(template, argument, list)(runtime, agument, list)</code></pre>
<p>There is a small trick to get a shorter instantiation syntax: if the argument list contains only one argument with a length of one token, you can drop the parenthesis, like this:</p>
<pre class="sourceCode d"><code class="sourceCode d">templateName!argument</code></pre>
<p>So, these are all valid template instantiations:</p>
<pre class="sourceCode d"><code class="sourceCode d">Template!(<span class="dt">int</span>)
Template!<span class="dt">int</span>
Template!(<span class="st">"string arg"</span>)
Template!<span class="st">"string arg"</span>
map!(foo)(range); <span class="co">// foo is a symbol, capture by an alias.</span>
<span class="co">// range is a runtime argument.</span>
map!foo(range); <span class="co">// ditto</span>
<span class="co">// But:</span>
Multiple!(<span class="dt">int</span>, <span class="dt">double</span>)
<span class="co">// And not:</span>
<span class="co">// Multiple!int, double //??</span></code></pre>
<h3 id="templates-as-template-arguments">Templates as Template Arguments</h3>
<p>Arguments can themselves be the result of another template instantiation. If a template returns a type upon instantiation, it's perfectly OK to use it inside another template argument list. In this document you'll regularly see Matrioshka calls like this: <code>firstTemp!(secondTempl!(Arguments), OtherArguments)</code>.</p>
<h3 id="selecting-among-declarations">Selecting among Declarations</h3>
<p>The compiler will have a look at the declarations (if more than one template was declared with the called name) and select the one with the correct number of arguments and the correct types to instantiate. If more than one template can be instantiated, it will complain and stop there (though, have a look on <a href="#templates-specializations">template specializations</a> and <a href="#constraints">template constraints</a>.</p>
<h3 id="effect-of-instantiation">Effect of Instantiation</h3>
<p>When you instantiate a template, the global effect is that a new named scope (code block) is created at the template declaration scope. The name of this new scope is the template name with its argument list: <code>templateName!(args)</code>. Inside this block, the parameters are now 'replaced' with the corresponding arguments (storage classes get applied, variables are initialized, ...). Here's what possible instantiations of the previous templates might look like:</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> instantiation;
<span class="kw">import</span> declaration;
<span class="dt">void</span> main()
{
ArrayOf!(<span class="dt">int</span>).ArrayType myArray;
<span class="co">// From is an alias for the type double</span>
<span class="co">// To for the type int</span>
<span class="kw">alias</span> transfo = Transformer!(<span class="dt">double</span>,<span class="dt">int</span>);
<span class="kw">struct</span> MyStruct { <span class="co">/*...*/</span> }
<span class="co">// "MyStruct" is a identifier -> captured by alias</span>
<span class="kw">auto</span> name = nameOf!(MyStruct).name;
<span class="kw">alias</span> complicatedExample =
ComplicatedOne!( <span class="dt">int</span>[] <span class="co">// a type</span>
, <span class="st">"Hello"</span> <span class="co">// a string literal</span>
, ArrayOf <span class="co">// a name</span>
, <span class="kw">true</span> <span class="co">// a boolean literal</span>
, <span class="dv">1</span>+<span class="dv">2</span> <span class="co">// calculated to be the integral '3'.</span>
);
<span class="kw">alias</span> min1 = Minimalist!(); <span class="co">// No argument</span>
<span class="co">// FirstType is 'int'</span>
<span class="co">// Rest is 'double,string,"abc"'</span>
<span class="kw">alias</span> oneOrMore =
OneOrMore!( <span class="dt">int</span>
, <span class="dt">double</span>, <span class="dt">string</span>, <span class="st">"abc"</span>
);
<span class="co">// Types is a 1-element tuple: (int)</span>
<span class="kw">alias</span> zero1 = ZeroOrMore!(<span class="dt">int</span>);
<span class="co">// Types is (int,double,string)</span>
<span class="kw">alias</span> zero2 = ZeroOrMore!(<span class="dt">int</span>,<span class="dt">double</span>,<span class="dt">string</span>);
<span class="co">// Types is the empty tuple: ()</span>
<span class="kw">alias</span> zero3 = ZeroOrMore!();
<span class="co">// Selects the one-arg version</span>
<span class="kw">alias</span> mult1 = Multiple!(<span class="dt">int</span>);
<span class="co">// The three args version.</span>
<span class="kw">alias</span> mult2 = Multiple!(<span class="dt">int</span>,<span class="dt">double</span>,<span class="dt">string</span>);
<span class="co">// Error! No 0-arg version</span>
<span class="co">//alias mult3 = Multiple!();</span>
}</code></pre>
<p>Outside the scope (that is, where you put the template instantiation in your own code), the internal declarations are accessible by fully qualifying them:</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> internaldeclarations1;
<span class="kw">import</span> declaration;
<span class="co">// ArrayType is accessible (it's int[])</span>
<span class="co">// array is a completly standard dynamic array of ints.</span>
ArrayOf!(<span class="dt">int</span>).ArrayType array;
ArrayOf!(<span class="dt">int</span>).ElementType element; <span class="co">// the same, element is an int.</span>
<span class="dt">void</span> main()
{
<span class="co">// the transform function is accessible. Instantiated like this,</span>
<span class="co">// it's a function from double to string.</span>
<span class="kw">auto</span> s = Transformer!(<span class="dt">double</span>,<span class="dt">string</span>).transform(<span class="fl">3.14159</span>);
<span class="kw">assert</span>(<span class="kw">is</span>(<span class="dt">typeof</span>(s) == <span class="dt">string</span>)); <span class="co">// s is a string</span>
}</code></pre>
<p>Obviously, using templates like this, with their full name, is a pain. The nifty D <code class="sourceCode d"><span class="kw">alias</span></code> declaration is your friend:</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> internaldeclarations2;
<span class="kw">import</span> declaration;
<span class="kw">alias</span> DtoS = Transformer!(<span class="dt">double</span>, <span class="dt">string</span>);
<span class="dt">void</span> main()
{
<span class="kw">auto</span> s = DtoS.transform(<span class="fl">3.14159</span>);
<span class="kw">auto</span> m = <span class="kw">new</span> DtoS.Modificator(<span class="fl">1.618</span>); <span class="co">// DtoS.Modificator is a class</span>
<span class="co">// storing a double and a string.</span>
}</code></pre>
<p>You must keep in mind that instantiating a template means generating code. Using different arguments at different places in your code will instantiate <em>as many differently named scopes</em>. This is a major difference with <em>generics</em> in languages like Java or C#, where generic code is created only once and type erasure is used to link all this together. On the other hand, instantiating the same template, with the same arguments, will create only one piece of code.</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> differentinstantiations;
<span class="kw">import</span> declaration;
<span class="kw">alias</span> StoD = Transformer!(<span class="dt">string</span>,<span class="dt">double</span>);
<span class="kw">alias</span> DtoS = Transformer!(<span class="dt">double</span>,<span class="dt">string</span>);
<span class="kw">alias</span> StoI = Transformer!(<span class="dt">string</span>,<span class="dt">int</span>);
<span class="co">// Now we can use three different functions and three different classes.</span></code></pre>
<blockquote>
<p><strong>void.</strong> Note that <code class="sourceCode d"><span class="dt">void</span></code> is a valid D type and, as such, a possible template argument for a type parameter. Take care: many templates make no sense when <code class="sourceCode d"><span class="dt">void</span></code> is used as a type. In the following sections and in the appendix, you'll see ways to restrict arguments to only certain types.</p>
</blockquote>
<h2 id="template-building-blocks">Template Building Blocks</h2>
<p>Up to now, templates may not seem that interesting to you, even with a simple declaration and instantiation syntax. But wait! D introduced a few nifty tricks that both simplify and greatly expand template uses. This section will introduce you to your future best friends, the foundations on which your templates will be built.</p>
<h3 id="the-eponymous-trick">The Eponymous Trick</h3>
<p>If a template declares a symbol with the same name (greek: <em>epo-nymous</em>) as the enclosing template, that symbol is assumed to be referred to when the template is instantiated. This one is pretty good to clean your code:</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> pair;
<span class="kw">template</span> pair(T)
{
<span class="co">// template 'pair' declares only a 'pair' member</span>
T[] pair(T t) { <span class="kw">return</span> [t,t];}
}
<span class="kw">auto</span> array = pair!(<span class="dt">int</span>)(<span class="dv">1</span>); <span class="co">// no need to do pair!(int).pair(1)</span></code></pre>
<p>or:</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> nameof1;
<span class="kw">template</span> nameOf(<span class="kw">alias</span> name)
{
<span class="kw">enum</span> <span class="dt">string</span> nameOf = name.<span class="dt">stringof</span>;
}
<span class="kw">struct</span> Example { <span class="dt">int</span> i;}
<span class="dt">void</span> main()
{
Example example;
<span class="kw">auto</span> s1 = nameOf!(Example);
<span class="kw">auto</span> s2 = nameOf!(example);
<span class="kw">assert</span>(s1 == <span class="st">"Example"</span>);
<span class="kw">assert</span>(s2 == <span class="st">"example"</span>);
}</code></pre>
<p>There used to be a limitation in that the eponymous trick worked <em>only</em> if you defined one (and only one) symbol. Even if the other symbols were private, they would break the eponymous substitution. This was changed recently (Fall 2012) and now, we can do:</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> record;
<span class="kw">template</span> Record(T, U, V)
{
<span class="kw">import</span> std.typecons: Tuple, tuple;
<span class="co">// The real work is done here</span>
<span class="co">// Use as many symbols as you need.</span>
<span class="kw">alias</span> Tuple!(T,U) Pair;
<span class="kw">alias</span> Pair[V] AssocArray;
<span class="kw">alias</span> AssocArray[] Record;
}</code></pre>
<p>Note that in this case, the eponymous member is an alias, whereas it was a function or a manifest constant (an <code class="sourceCode d"><span class="kw">enum</span></code>) in previous examples. As was already said, any member with the same name will do.</p>
<p>And then, to use <code>Record</code>:</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> using_record;
<span class="kw">import</span> record;
Record!(<span class="dt">int</span>,<span class="dt">string</span>,<span class="dt">double</span>[]) recordslist;
<span class="co">/* ... */</span></code></pre>
<p>Although, in this case, the eponymous member hides the other members: <code>Pair</code> and <code>AssocArray</code> cannot be accessed any more. That seems logical, since if you use the eponymous trick, it's to provide a simplified interface to your users.</p>
<h3 id="inner-alias">Inner alias</h3>
<p>A common use for templates is to do some type magic: deducing types, assembling them in new way, etc. Types are not first-class entities in D (there is no <code>type</code> type), but they can easily be manipulated as any other symbol, by aliasing them. So, when a template has to expose a type, it's done by aliasing it to a new name.</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> allarrays;
<span class="kw">template</span> AllArraysOf(T)
{
<span class="kw">alias</span> T Element;
<span class="kw">alias</span> T* PointerTo;
<span class="kw">alias</span> T[] DynamicArray;
<span class="kw">alias</span> T[<span class="dv">1</span>] StaticArray;
<span class="kw">alias</span> T[T] AssociativeArray;
}</code></pre>
<blockquote>
<p><strong>Exposing Template Parameters.</strong> Though they are part of a template's name, its parameters are <em>not</em> directly accessible externally. Keep in mind that a template name is just a scope name. Once it's instantiated, all the <code>T</code>s and <code>U</code>s and such do not exist anymore. If you need them externally, expose them through a template member, as is done with <code>AllArraysOf.Element</code>. You will find other examples of this in section <a href="#struct-templates">Struct Templates</a> and section <a href="#class-templates">Class Templates</a>.</p>
</blockquote>
<h3 id="static-if"><code>static if</code></h3>
<h4 id="syntax-1">Syntax</h4>
<p>The <code class="sourceCode d"><span class="kw">static</span> <span class="kw">if</span></code> construct<a href="#fn2" class="footnoteRef" id="fnref2"><sup>2</sup></a> lets you decide between two code paths at compile time. It's not specific to templates (you can use it in other parts of your code), but it's incredibly useful to have your templates adapt themselves to the arguments. That way, using compile-time-calculated predicates based on the template arguments, you'll generate different code and customize the template to your need.</p>
<p>The syntax is:</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">static</span> <span class="kw">if</span> (compileTimeExpression)
{
<span class="co">/* Code created if compileTimeExpression is evaluated to true */</span>
}
<span class="kw">else</span> <span class="co">/* optional */</span>
{
<span class="co">/* Code created if it's false */</span>
}</code></pre>
<p>Something really important here is a bit of compiler magic: once the code path is selected, the resulting code is instantiated in the template body, but without the curly braces. Otherwise that would create a local scope, hiding what's happening inside and would drastically limit the power of <code class="sourceCode d"><span class="kw">static</span> <span class="kw">if</span></code>. So the curly braces are there only to group the statements together.</p>
<p>If there is only one statement, you can get rid of the braces entirely, something you'll see frequently in D code. For example, suppose you need a template that 'returns' <code class="sourceCode d"><span class="kw">true</span></code> if the passed type is a dynamic array and <code class="sourceCode d"><span class="kw">false</span></code> otherwise (this kind of predicate template is developed a bit more in section [predicates]).</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> isdynamicarray;
<span class="kw">template</span> isDynamicArray(T)
{
<span class="kw">static</span> <span class="kw">if</span> (<span class="kw">is</span>(T t == U[], U))
<span class="kw">enum</span> isDynamicArray = <span class="kw">true</span>;
<span class="kw">else</span>
<span class="kw">enum</span> isDynamicArray = <span class="kw">false</span>;
}</code></pre>
<p>As you can see, with no curly braces after <code class="sourceCode d"><span class="kw">static</span> <span class="kw">if</span></code> and the eponymous trick (<code>isDynamicArray</code> is a symbol defined by the template and its type is automatically deduced by the compiler), results in a very clean syntax. The <code class="sourceCode d"><span class="kw">is</span>()</code> expression part is a way to get compile-time introspection which goes hand in hand with <code class="sourceCode d"><span class="kw">static</span> <span class="kw">if</span></code>. There is a crash course on it at the end of this document (see [appendix-isExpression]).</p>
<h4 id="optional-code">Optional Code</h4>
<p>A common use of <code class="sourceCode d"><span class="kw">static</span> <span class="kw">if</span></code> is to enable or disable code: a single <code class="sourceCode d"><span class="kw">static</span> <span class="kw">if</span></code> without an <code class="sourceCode d"><span class="kw">else</span></code> clause will generate code only when the condition is true. You can find many examples of this idiom in <a href="http://dlang.org/phobos/std_range.html">std.range</a> where higher-level ranges (ranges wrapping other ranges) will activate some functionality if and only if the wrapped range can support it, like this:</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="co">/* We are inside a MyRange templated struct, wrapping a R. */</span>
R innerRange;
<span class="co">/* Code that exists in all instantiations of MyRange */</span>
(...)
<span class="co">/* optional code */</span>
<span class="kw">static</span> <span class="kw">if</span> (hasLength!R) <span class="co">// does innerRange have a .length() method?</span>
<span class="kw">auto</span> length() <span class="co">// Then MyRange has one also.</span>
{
<span class="kw">return</span> innerRange.<span class="dt">length</span>;
}
<span class="kw">static</span> <span class="kw">if</span> (isInfinite!R) <span class="co">// Is innerRange an infinite range?</span>
<span class="kw">enum</span> <span class="dt">bool</span> empty = <span class="kw">false</span>; <span class="co">// Then MyRange is also infinite.</span>
<span class="co">// And so on...</span></code></pre>
<h4 id="nested-static-ifs">Nested <code>static if</code>s</h4>
<p><code class="sourceCode d"><span class="kw">static</span> <span class="kw">if</span></code>'s can be nested: just put another <code class="sourceCode d"><span class="kw">static</span> <span class="kw">if</span></code> after <code class="sourceCode d"><span class="kw">else</span></code>. Here is a template selecting an alias:</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> selector;
<span class="kw">import</span> std.traits: isIntegral, isFloatingPoint;
<span class="kw">template</span> selector(T, <span class="kw">alias</span> intFoo, <span class="kw">alias</span> floatFoo, <span class="kw">alias</span> defaultFoo)
{
<span class="kw">static</span> <span class="kw">if</span> (isIntegral!T)
<span class="kw">alias</span> intFoo selector;
<span class="kw">else</span> <span class="kw">static</span> <span class="kw">if</span> (isFloatingPoint!T)
<span class="kw">alias</span> floatFoo selector;
<span class="kw">else</span> <span class="co">// default case</span>
<span class="kw">alias</span> defaultFoo selector;
}</code></pre>
<p>If you need a sort of <code>static switch</code> construct, see section [examples-staticswitch].</p>
<h4 id="recursion-with-static-if">Recursion with <code>static if</code></h4>
<h5 id="rank">Rank:</h5>
<p>Now, let's use <code class="sourceCode d"><span class="kw">static</span> <span class="kw">if</span></code> for something a bit more complicated than just dispatching between code paths: recursion. What if you know you will receive n-dimensional arrays (simple arrays, arrays of arrays, arrays of arrays of arrays, ...), and want to use the fastest, super-optimized numerical function for the 1-dim array, another one for 2D arrays and yet another one for higher-level arrays? Abstracting this away, we need a template doing some introspection on types, that will return 0 for an element (anything that's not an array), 1 for a 1-dim array (<code>T[]</code>, for some <code class="sourceCode d">T</code>), 2 for a 2-dim array (<code>T[][]</code>), and so on. Mathematicians call this the <em>rank</em> of an array, so we will use that. The definition is perfectly recursive:</p>
<table class="sourceCode d numberLines"><tr class="sourceCode"><td class="lineNumbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="sourceCode"><pre><code class="sourceCode d"><span class="kw">module</span> rank1;
<span class="kw">template</span> rank(T)
{
<span class="kw">static</span> <span class="kw">if</span> (<span class="kw">is</span>(T t == U[], U)) <span class="co">// is T an array of U, for some type U?</span>
<span class="kw">enum</span> <span class="dt">size_t</span> rank = <span class="dv">1</span> + rank!(U); <span class="co">// then let's recurse down.</span>
<span class="kw">else</span>
<span class="kw">enum</span> <span class="dt">size_t</span> rank = <span class="dv">0</span>; <span class="co">// Base case, ending the recursion.</span>
}</code></pre></td></tr></table>
<p>Lines 5 and 6 are the most interesting: with some <code class="sourceCode d"><span class="kw">is</span></code> magic, <code class="sourceCode d">U</code> has been deduced by the compiler and is accessible inside the <code class="sourceCode d"><span class="kw">static</span> <span class="kw">if</span></code> branch. We use it to peel one level of <code>[]</code> off the type and recurse downward, using <code class="sourceCode d">U</code> as a new type for instantiating <code class="sourceCode d">rank</code>. Either <code class="sourceCode d">U</code> is itself an array (in which case the recursion will continue) or it will hit the base case and stop there. Since the template defines a member named like itself, the result is directly accessible: any instantiation of <code>rank</code> will be a value of type <code class="sourceCode d"><span class="dt">size_t</span></code>.</p>
<p>Let's use it:</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> using_rank1;
<span class="kw">import</span> rank1;
<span class="kw">static</span> <span class="kw">assert</span>(rank!(<span class="dt">int</span>) == <span class="dv">0</span>);
<span class="kw">static</span> <span class="kw">assert</span>(rank!(<span class="dt">int</span>[]) == <span class="dv">1</span>);
<span class="kw">static</span> <span class="kw">assert</span>(rank!(<span class="dt">int</span>[][]) == <span class="dv">2</span>);
<span class="kw">static</span> <span class="kw">assert</span>(rank!(<span class="dt">int</span>[][][]) == <span class="dv">3</span>);
<span class="co">/* It will work for any type, obviously */</span>
<span class="kw">struct</span> S {}
<span class="kw">static</span> <span class="kw">assert</span>(rank!(S) == <span class="dv">0</span>);
<span class="kw">static</span> <span class="kw">assert</span>(rank!(S[])== <span class="dv">1</span>);
<span class="kw">static</span> <span class="kw">assert</span>(rank!(S*) == <span class="dv">0</span>);</code></pre>
<blockquote>
<p><strong>static assert.</strong> Putting <code class="sourceCode d"><span class="kw">static</span></code> before an <code class="sourceCode d"><span class="kw">assert</span></code> forces the <code class="sourceCode d"><span class="kw">assert</span></code> execution at compile-time. Using an <code class="sourceCode d"><span class="kw">is</span></code> expression as the test clause gives assertion on types. One common use of <code class="sourceCode d"><span class="kw">static</span> <span class="kw">assert</span></code> is to stop the compilation, for example if we ever get in a bad code path, by using <code class="sourceCode d"><span class="kw">static</span> <span class="kw">assert</span>(<span class="kw">false</span>, someString)</code> (or <code class="sourceCode d"><span class="kw">static</span> <span class="kw">assert</span>(<span class="dv">0</span>, someString)</code>). The string is then emitted as a compiler error message.</p>
</blockquote>
<h5 id="rank-for-ranges">Rank for Ranges:</h5>
<p>D has an interesting sequence concept called a <em>range</em>. The <a href="http://dlang.org/phobos/index.html">Phobos</a> standard library comes with predefined testing templates in <a href="http://dlang.org/phobos/std_range.html">std.range</a>. Why not extend <code class="sourceCode d">rank</code> to have it deal with ranges and see if something is a range of ranges or more? A type can be tested to be a range with <code class="sourceCode d">isInputRange</code> and its element type is obtained by applying <code class="sourceCode d">ElementType</code> to the range type. Both templates are found in <a href="http://dlang.org/phobos/std_range.html">std.range</a>. Also, since arrays are included in the range concept, we can entirely ditch the array part and use only ranges. Here is a slightly modified version of <code class="sourceCode d">rank</code>:</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> rank2;
<span class="kw">import</span> std.range;
<span class="kw">template</span> rank(T)
{
<span class="kw">static</span> <span class="kw">if</span> (isInputRange!T) <span class="co">// is T a range?</span>
<span class="kw">enum</span> <span class="dt">size_t</span> rank = <span class="dv">1</span> + rank!(ElementType!T); <span class="co">// if yes, recurse</span>
<span class="kw">else</span>
<span class="kw">enum</span> <span class="dt">size_t</span> rank = <span class="dv">0</span>; <span class="co">// base case, stop there</span>
}
<span class="kw">unittest</span>
{
<span class="kw">auto</span> c = cycle([[<span class="dv">0</span>,<span class="dv">1</span>],[<span class="dv">2</span>,<span class="dv">3</span>]]); <span class="co">// == [[0,1],[2,3],[0,1],[2,3],[0,1]...</span>
<span class="kw">assert</span>(rank!(<span class="dt">typeof</span>(c)) == <span class="dv">2</span>); <span class="co">// range of ranges</span>
}</code></pre>
<h5 id="base-element-type">Base Element Type:</h5>
<p>With <code class="sourceCode d">rank</code>, we now have a way to get the number of <code>[]</code>'s in an array type (<code>T[][][]</code>) or the level of nesting in a range of ranges. The complementary query would be to get the base element type, <code class="sourceCode d">T</code>, from any array of arrays ... of <code class="sourceCode d">T</code> or the equivalent for a range. Here it is:</p>
<table class="sourceCode d numberLines"><tr class="sourceCode"><td class="lineNumbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="sourceCode"><pre><code class="sourceCode d"><span class="kw">module</span> baseelementtype;
<span class="kw">import</span> std.range;
<span class="kw">import</span> rank2;
<span class="kw">template</span> BaseElementType(T)
{
<span class="kw">static</span> <span class="kw">if</span> (rank!T == <span class="dv">0</span>) <span class="co">// not a range</span>
<span class="kw">static</span> <span class="kw">assert</span>(<span class="dv">0</span>, T.<span class="dt">stringof</span> ~ <span class="st">" is not a range."</span>);
<span class="kw">else</span> <span class="kw">static</span> <span class="kw">if</span> (rank!T == <span class="dv">1</span>) <span class="co">// simple range</span>
<span class="kw">alias</span> ElementType!T BaseElementType;
<span class="kw">else</span> <span class="co">// at least range of ranges</span>
<span class="kw">alias</span> BaseElementType!(ElementType!(T)) BaseElementType;
}</code></pre></td></tr></table>
<p>Line 8 is an example of <code>static assert</code> stopping compilation if we ever get into a bad code path. Line 12 is an example of a Matrioshka call: a template using another template's call as its parameter.</p>
<h5 id="generating-arrays">Generating Arrays:</h5>
<p>Now, what about becoming more generative by inverting the process? Given a type <code class="sourceCode d">T</code> and a rank <code class="sourceCode d">r</code> (a <code class="sourceCode d"><span class="dt">size_t</span></code>), we want to obtain <code>T[][]...[]</code>, with <code class="sourceCode d">r</code> levels of <code>[]</code>'s. A rank of 0 means producing <code class="sourceCode d">T</code> as the result type.</p>
<table class="sourceCode d numberLines"><tr class="sourceCode"><td class="lineNumbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="sourceCode"><pre><code class="sourceCode d"><span class="kw">module</span> ndim;
<span class="kw">template</span> NDimArray(T, <span class="dt">size_t</span> r)
{
<span class="kw">static</span> <span class="kw">if</span> (r == <span class="dv">0</span>)
<span class="kw">alias</span> T NDimArray;
<span class="kw">else</span>
<span class="kw">alias</span> NDimArray!(T, r-<span class="dv">1</span>)[] NDimArray;
}</code></pre></td></tr></table>
<p>Here, recursion is done on line 8: we instantiate <code class="sourceCode d">NDimArray!(T,r-<span class="dv">1</span>)</code>, which is a type, then create an array of them by putting <code>[]</code> at the end and expose it through an alias. This is also a nice example of using an integral value, <code>r</code>, as a template parameter.</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> using_ndim;
<span class="kw">import</span> ndim;
<span class="kw">alias</span> NDimArray!(<span class="dt">double</span>, <span class="dv">8</span>) Level8;
<span class="kw">static</span> <span class="kw">assert</span>(<span class="kw">is</span>(Level8 == <span class="dt">double</span>[][][][][][][][]));
<span class="kw">static</span> <span class="kw">assert</span>(<span class="kw">is</span>(NDimArray!(<span class="dt">double</span>, <span class="dv">0</span>) == <span class="dt">double</span>));</code></pre>
<h5 id="repeated-composition">Repeated composition:</h5>
<p>As a last example, we will use an alias template parameter in conjunction with some <code class="sourceCode d"><span class="kw">static</span> <span class="kw">if</span></code> recursion to define a template that creates the 'exponentiation' of a function, aka its repeated composition. Here is what I mean by this:</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> using_power;
<span class="kw">import</span> repeatedcomposition;
<span class="co">// standard function</span>
<span class="dt">string</span> foo(<span class="dt">string</span> s) { <span class="kw">return</span> s ~ s;}
<span class="co">// function templates. You'll see them soon.</span>
Arr[] makeArray(Arr)(Arr array) { <span class="kw">return</span> [array,array];}
<span class="dt">void</span> main()
{
<span class="co">// power!(foo, n) is a function.</span>
<span class="kw">assert</span>(power!(foo, <span class="dv">0</span>)(<span class="st">"a"</span>) == <span class="st">"a"</span>); <span class="co">// identity function</span>
<span class="kw">assert</span>(power!(foo, <span class="dv">1</span>)(<span class="st">"a"</span>) == foo(<span class="st">"a"</span>)); <span class="co">// "aa"</span>
<span class="kw">assert</span>(power!(foo, <span class="dv">2</span>)(<span class="st">"a"</span>) == foo(foo(<span class="st">"a"</span>))); <span class="co">// "aaaa"</span>
<span class="kw">assert</span>(power!(foo, <span class="dv">3</span>)(<span class="st">"a"</span>) == foo(foo(foo(<span class="st">"a"</span>)))); <span class="co">// "aaaaaaaa"</span>
<span class="co">// It's even better with function templates:</span>
<span class="kw">assert</span>(power!(makeArray, <span class="dv">0</span>)(<span class="dv">1</span>) == <span class="dv">1</span>);
<span class="kw">assert</span>(power!(makeArray, <span class="dv">1</span>)(<span class="dv">1</span>) == [<span class="dv">1</span>,<span class="dv">1</span>]);
<span class="kw">assert</span>(power!(makeArray, <span class="dv">2</span>)(<span class="dv">1</span>) == [[<span class="dv">1</span>,<span class="dv">1</span>],[<span class="dv">1</span>,<span class="dv">1</span>]]);
<span class="kw">assert</span>(power!(makeArray, <span class="dv">3</span>)(<span class="dv">1</span>) == [[[<span class="dv">1</span>,<span class="dv">1</span>],[<span class="dv">1</span>,<span class="dv">1</span>]],[[<span class="dv">1</span>,<span class="dv">1</span>],[<span class="dv">1</span>,<span class="dv">1</span>]]]);
}</code></pre>
<p>First, this is a template that 'returns' (becomes, rather) a function. It's easy to do with the eponymous trick: just define inside the template a function with the same name. Secondly, it's clearly recursive in its definition, with two base cases: if the exponent is zero, then we shall produce the identity function and if the exponent is one, we shall just return the input function itself. That being said, <code class="sourceCode d">power</code> writes itself:</p>
<table class="sourceCode d numberLines"><tr class="sourceCode"><td class="lineNumbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="sourceCode"><pre><code class="sourceCode d"><span class="kw">module</span> repeatedcomposition;
<span class="kw">template</span> power(<span class="kw">alias</span> fun, <span class="dt">uint</span> exponent)
{
<span class="kw">static</span> <span class="kw">if</span> (exponent == <span class="dv">0</span>) <span class="co">// degenerate case -> id function</span>
<span class="kw">auto</span> power(Args)(Args args) { <span class="kw">return</span> args; }
<span class="kw">else</span> <span class="kw">static</span> <span class="kw">if</span> (exponent == <span class="dv">1</span>) <span class="co">// end-of-recursion case -> fun</span>
<span class="kw">alias</span> fun power;
<span class="kw">else</span>
<span class="kw">auto</span> power(Args...)(Args args)
{
<span class="kw">return</span> .power!(fun, exponent-<span class="dv">1</span>)(fun(args));
}
}</code></pre></td></tr></table>
<blockquote>
<p><strong>.power</strong> If you are wondering what's with the <code>.power</code> syntax on line 12, it's because by defining an eponymous template, we hide the parent template's name. So inside <code>power(Args...)</code>, <code>power</code> refers to <code>power(Args...)</code> and not <code class="sourceCode d">power(<span class="kw">alias</span> fun, <span class="dt">uint</span> exponent)</code>. Here we want a new <code class="sourceCode d">power</code> to be generated so we call on the global <code class="sourceCode d">power</code> template with the 'global scope' operator (<code>.</code>).</p>
</blockquote>
<p>In all three branches of <code class="sourceCode d"><span class="kw">static</span> <span class="kw">if</span></code>, <code class="sourceCode d">power</code> exposes a <code class="sourceCode d">power</code> member, activating the eponymous template trick and allowing for an easy use by the client. Note that this template will work not only for unary (one argument) functions but also for n-args functions <a href="#fn3" class="footnoteRef" id="fnref3"><sup>3</sup></a>, for delegates and for structs or classes that define the <code>()</code>(ie, <code class="sourceCode d">opCall</code>) operator and for function templates... <a href="#fn4" class="footnoteRef" id="fnref4"><sup>4</sup></a></p>
<p>Now, are you beginning to see the power of templates?</p>
<blockquote>
<p><strong>Curried Templates?</strong> No, I do not mean making them spicy, but separating the template's arguments, so as to call them in different places in your code. For <code class="sourceCode d">power</code>, that could mean doing <code class="sourceCode d"><span class="kw">alias</span> power!<span class="dv">2</span> square;</code> somewhere and then using <code>square!fun1</code>, <code>square!fun2</code> at your leisure: the <code class="sourceCode d">exponent</code> parameter and the <code class="sourceCode d">fun</code> alias are separated. In fact, <code class="sourceCode d">power</code> is already partially curried: <code class="sourceCode d">fun</code> and <code class="sourceCode d">exponent</code> are separated from <code class="sourceCode d">Args</code>. For more on this, see section <a href="#templates-in-templates">Templates In Templates</a>. Given a template <code class="sourceCode d">temp</code>, writing a <code class="sourceCode d">curry</code> template that automatically generates the code for a curried version of <code class="sourceCode d">temp</code> is <em>also</em> possible, but outside the scope of this document.</p>
</blockquote>
<h4 id="templates-specializations">Templates Specializations</h4>
<p>Up to now, when we write a <code class="sourceCode d">T</code> in a template parameter list, there is no constraint on the type that <code class="sourceCode d">T</code> can become during instantiation. Template specialization is a small 'subsyntax', restricting templates instantiations to a subset of all possible types and directing the compiler into instantiating a particular version of a template instead of another. If you've read [appendix-isexpression] on the <code class="sourceCode d"><span class="kw">is</span>()</code> expression, you already know how to write them. If you didn't, please do it now, as it's really the same syntax. These specializations are a direct inheritance from C++ templates, up to the way they are written and they existed in D from the very beginning, long before <code class="sourceCode d"><span class="kw">static</span> <span class="kw">if</span></code> or templates constraints were added.</p>
<p>The specializations are added in the template parameter list, the <code>(T, U, V)</code> part of the template definition. <code>Type : OtherType</code> restricts <code class="sourceCode d">Type</code> to be implicitly convertible into <code>OtherType</code>.</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> specialization1;
<span class="kw">template</span> ElementType(T : U[], U) <span class="co">// can only be instantiated with arrays</span>
{
<span class="kw">alias</span> U ElementType;
}
<span class="kw">template</span> ElementType(T : U[n], U, <span class="dt">size_t</span> n) <span class="co">// only with static arrays</span>
{
<span class="kw">alias</span> U ElementType;
}
<span class="kw">class</span> Array { <span class="kw">alias</span> <span class="dt">int</span> ElementType;}
<span class="kw">template</span> ElementType(T : Array)
{
<span class="kw">alias</span> Array.ElementType ElementType;
}</code></pre>
<p>Now, the idea may seem strange to you: if you know you want to restrict <code class="sourceCode d">Type</code> to be <code class="sourceCode d">AnotherType</code>, why make it a template parameter? It's because of templates specializations' main use: you can write different implementations of a template (with the same name, obviously), and when asked to instantiate one of them, the compiler will automatically decide which one to use, taking the 'most adapted' to the provided arguments. 'Most adapted' obeys some complicated rules you can find on the D Programming Language website, but they act in a natural way most of the time. The neat thing is that you can define the most general template <em>and</em> some specialization. The specialized ones will be chosen when it's possible.</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> specialization2;
<span class="kw">template</span> InnerType(T : U*, U) <span class="co">// Specialization for pointers</span>
{
<span class="kw">alias</span> U InnerType;
}
<span class="kw">template</span> InnerType(T : U[], U) <span class="co">// Specialization for dyn. arrays</span>
{ <span class="co">/*...*/</span> }
<span class="kw">template</span> InnerType(T) <span class="co">// Standard, default case</span>
{ <span class="co">/*...*/</span> }
<span class="dt">void</span> main()
{
<span class="dt">int</span>* p;
<span class="dt">int</span> i;
<span class="kw">alias</span> InnerType!(<span class="dt">typeof</span>(p)) Pointer; <span class="co">// pointer spec. selected</span>
<span class="kw">alias</span> InnerType!(<span class="dt">typeof</span>(i)) Default; <span class="co">// standard template selected</span>
}</code></pre>
<p>This idiom is frequently used in C++, where there is no (built-in) <code class="sourceCode d"><span class="kw">static</span> <span class="kw">if</span></code> construct or template constraints. Oldish D templates used it a lot, too, but since other ways have been around for some years, recent D code seems to be more constraint-oriented: have a look at heavily templated Phobos modules, for example <a href="http://dlang.org/phobos/std_algorithm.html">std.algorithm</a> or <a href="http://dlang.org/phobos/std_range.html">std.range</a>.</p>
<blockquote>
<p><strong>Specializations or static if or Templates Constraints?</strong> Yes indeed. Let's defer this discussion for when we have seen all three subsystems.</p>
</blockquote>
<h3 id="default-values">Default Values</h3>
<p>Like functions parameters, templates parameters can have default values. The syntax is the same: <code>Param = defaultValue</code>. The default can be anything that makes sense with respect to the parameter kind: a type, a literal value, a symbol or another template parameter.</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> def;
<span class="kw">template</span> Default(T = <span class="dt">int</span>, <span class="dt">bool</span> flag = <span class="kw">false</span>)
{
<span class="kw">static</span> <span class="kw">if</span> (flag)
<span class="kw">alias</span> T Default;
<span class="kw">else</span>
<span class="kw">alias</span> <span class="dt">void</span> Default;
}
<span class="kw">alias</span> Default!(<span class="dt">double</span>) D1; <span class="co">// Instantiate Default!(double, false)</span>
<span class="kw">alias</span> Default!(<span class="dt">double</span>, <span class="kw">true</span>) D2; <span class="co">// Instantiate Default!(double, true) (Doh!)</span>
<span class="kw">alias</span> Default!() D3; <span class="co">// Instantiate Default!(int, false)</span></code></pre>
<p>In contrast to function parameters, thanks to <a href="#templates-specializations">Templates Specializations</a> or <a href="#ifti">IFTI</a>, some template parameters can be automatically deduced by the compiler. So, default template parameters are not required to be the final parameters in the list:</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> deduced;
<span class="kw">import</span> std.typecons: Tuple;
<span class="kw">template</span> Deduced(T : U[], V = T, U)
{
<span class="kw">alias</span> Tuple!(T,U,V) Deduced;
}
<span class="kw">alias</span> Deduced!(<span class="dt">int</span>[], <span class="dt">double</span>) D1; <span class="co">// U deduced to be int. Force V to be a double.</span>
<span class="kw">alias</span> Deduced!(<span class="dt">int</span>[]) D2; <span class="co">// U deduced to be int. V is int, too.</span></code></pre>
<blockquote>
<p><strong>Specialization and Default Value?</strong> Yes you can. Put the specialization first, then the default value. Like this: <code>(T : U[] = int[], U)</code>. It's not commonly used, though.</p>
</blockquote>
<p>As for functions, well-chosen defaults can greatly simplify standard calls. See for example <a href="http://dlang.org/phobos/std_algorithm.html#sort">std.algorithm.sort</a>. It's parameterized on a predicate and a swapping strategy, but both are adapted to what most people need when sorting. That way, most client uses of the template will be short and clean, but customization to their own need is still possible.</p>
<blockquote>
<p><strong>TODO</strong> Maybe something on template dummy parameters, like those used by <a href="http://dlang.org/phobos/std_traits.html#ReturnType">std.traits.ReturnType</a>. Things like <code class="sourceCode d">dummy == <span class="dt">void</span></code>.</p>
</blockquote>
<h2 id="function-templates">Function Templates</h2>
<h3 id="syntax-2">Syntax</h3>
<p>If you come from languages with generics, maybe you thought D templates were all about parameterized classes and functions and didn't see any interest in the previous sections (acting on types?). Fear not, you can also do type-generic functions and such in D, with the added generative power of templates.</p>
<p>As we have seen in <a href="#the-eponymous-trick">The Eponymous Trick</a>, if you define a function inside a template and use the template's own name, you can call it easily:</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> function_declaration1;
<span class="kw">import</span> std.conv : to;
<span class="co">// declaration:</span>
<span class="kw">template</span> myFunc(T, <span class="dt">int</span> n)
{
<span class="kw">auto</span> myFunc(T t) { <span class="kw">return</span> to!<span class="dt">int</span>(t) * n;}
}
<span class="dt">void</span> main()
{
<span class="co">// call:</span>
<span class="kw">auto</span> result = myFunc!(<span class="dt">double</span>,<span class="dv">3</span>)(<span class="fl">3.1415</span>);
<span class="kw">assert</span>(result == to!<span class="dt">int</span>(<span class="fl">3.1415</span>)*<span class="dv">3</span>);
}</code></pre>
<p>Well, the full story is even better. First, D has a simple way to declare a function template: just put a template parameter list before the argument list:</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> function_declaration2;
<span class="kw">import</span> std.conv:to;
<span class="dt">string</span> concatenate(A,B)(A a, B b)
{
<span class="kw">return</span> to!<span class="dt">string</span>(a) ~ to!<span class="dt">string</span>(b);
}
Arg select(<span class="dt">string</span> how = <span class="st">"max"</span>, Arg)(Arg arg0, Arg arg1)
{
<span class="kw">static</span> <span class="kw">if</span> (how == <span class="st">"max"</span>)
<span class="kw">return</span> (arg0 < arg1) ? arg1 : arg0;
<span class="kw">else</span> <span class="kw">static</span> <span class="kw">if</span> (how == <span class="st">"min"</span>)
<span class="kw">return</span> (arg0 < arg1) ? arg0 : arg1;
<span class="kw">else</span>
<span class="kw">static</span> <span class="kw">assert</span>(<span class="dv">0</span>,
<span class="st">"select: string 'how' must be either \"max\" or \"min\"."</span>);
}</code></pre>
<p>Nice and clean, uh? Notice how the return type can be templated too, using <code class="sourceCode d">Arg</code> as a return type in <code class="sourceCode d">select</code>.</p>
<h3 id="auto-return">auto return</h3>
<p>Since you can select among code paths, the function return type can vary widely, depending on the template parameters you passed it. Use <code class="sourceCode d"><span class="kw">auto</span></code> to simplify your code:</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> morph;
<span class="co">// What morph will return will heavily depend on T and U</span>
<span class="kw">auto</span> morph(<span class="kw">alias</span> f, T, U)(U arg)
{
<span class="kw">static</span> <span class="kw">if</span> (<span class="kw">is</span>(T == <span class="kw">class</span>))
<span class="kw">return</span> <span class="kw">new</span> T(f(arg));
<span class="kw">else</span> <span class="kw">static</span> <span class="kw">if</span> (<span class="kw">is</span>(T == <span class="kw">struct</span>))
<span class="kw">return</span> T(f(arg));
<span class="kw">else</span>
<span class="kw">return</span>; <span class="co">// void-returning function.</span>
}</code></pre>
<blockquote>
<p><strong>auto ref.</strong> A function template can have an <code>auto ref</code> return type. That means that for templates where the returned values are lvalues, the template will get the <code class="sourceCode d"><span class="kw">ref</span></code>ed version. And the non-<code class="sourceCode d"><span class="kw">ref</span></code> version if not. I should add some examples for that behaviour.</p>
</blockquote>
<h3 id="ifti">IFTI</h3>
<p>Even better is Implicit Function Template Instantiation (IFTI), which means that the compiler will generally be able to automatically determine a template's parameters by studying the function arguments. If some template arguments are pure compile-time parameters, just provide them directly:</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> ifti;
<span class="kw">import</span> function_declaration2;
<span class="kw">struct</span> Foo {}
<span class="dt">void</span> main()
{
<span class="dt">string</span> res1 = concatenate(<span class="dv">1</span>, <span class="fl">3.14</span>); <span class="co">// A is int and B is double</span>
<span class="dt">string</span> res2 = concatenate(<span class="st">"abc"</span>, Foo()); <span class="co">// A is string, B is Foo</span>
<span class="kw">auto</span> res3 = select(<span class="dv">3</span>,<span class="dv">4</span>); <span class="co">// how is "max", Arg is int.</span>
<span class="kw">auto</span> res4 = select!<span class="st">"min"</span>(<span class="fl">3.1416</span>, <span class="fl">2.718</span>); <span class="co">// how is "min", Arg is double.</span>
}</code></pre>
<p>As you can see, this results in very simple calling code. So we can both declare function templates and call them with a very clean syntax. The same can be done with structs or classes and such, as you will see in the next sections. In fact, the syntax is so clean that, if you are like me, you may forget from time to time that you are <em>not</em> manipulating a function (or a struct, etc.): you are manipulating a template, a parameterized piece of code.</p>
<blockquote>
<p><strong>A Mantra.</strong> <code class="sourceCode d">XXX</code> templates are not <code class="sourceCode d">XXX</code>s, they are templates. With <code class="sourceCode d">XXX</code> being any of (function, struct, class, interface, union). Templates are parameterized scopes and scopes are not first-class in D: they have no type, they cannot be assigned to a variable, they cannot be returned from functions. That means, for example, that you <em>cannot</em> return function templates, you cannot inherit from class templates and so on. Of course, <em>instantiated</em> templates are perfect examples of functions, classes, and such. Those you can inherit, return...</p>
</blockquote>
<p>We may encounter <strong>The Mantra</strong> again in this tutorial.</p>
<h3 id="example-flattening-arrays-and-ranges">Example: Flattening Arrays and Ranges</h3>
<p>Let's use what we have just seen in a concrete way. In D, you can manipulate 2D and 3D arrays, but sometimes need to process them linearly. As of this writing, neither <a href="http://dlang.org/phobos/std_algorithm.html">std.algorithm</a> nor <a href="http://dlang.org/phobos/std_range.html">std.range</a> provide a <code class="sourceCode d">flatten</code> function. Beginning with simple arrays, here is what we want:</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> using_flatten1;
<span class="kw">import</span> flatten1;
<span class="dt">void</span> main()
{
<span class="kw">assert</span>( flatten([[<span class="dv">0</span>,<span class="dv">1</span>],[<span class="dv">2</span>,<span class="dv">3</span>],[<span class="dv">4</span>]]) == [<span class="dv">0</span>,<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span>] );
<span class="kw">assert</span>( flatten([[<span class="dv">0</span>,<span class="dv">1</span>]]) == [<span class="dv">0</span>,<span class="dv">1</span>] );
<span class="kw">assert</span>( flatten([<span class="dv">0</span>,<span class="dv">1</span>]) == [<span class="dv">0</span>,<span class="dv">1</span>] );
<span class="kw">assert</span>( flatten(<span class="dv">0</span>) == <span class="dv">0</span> );
<span class="kw">assert</span>( flatten([[[<span class="dv">0</span>,<span class="dv">1</span>],[]], [[<span class="dv">2</span>]], [[<span class="dv">3</span>], [<span class="dv">4</span>,<span class="dv">5</span>]], [[]], [[<span class="dv">6</span>,<span class="dv">7</span>,<span class="dv">8</span>]]])
== [<span class="dv">0</span>,<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span>,<span class="dv">5</span>,<span class="dv">6</span>,<span class="dv">7</span>,<span class="dv">8</span>] );
}</code></pre>
<p>So, studying the examples, we want a simple array (rank == 1) or a non-array (rank == 0) to be unaffected by <code class="sourceCode d">flatten</code>: it just returns them. For arrays of rank 2 or higher, it collapses the elements down to a rank-1 array. It's classically recursive: we will apply <code class="sourceCode d">flatten</code> on all sub-arrays with <a href="http://dlang.org/phobos/std_algorithm.html#map">std.algorithm.map</a> and concatenate the elements with <a href="http://dlang.org/phobos/std_algorithm.html#reduce">std.algorithm.reduce</a>:</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> flatten1;
<span class="kw">import</span> std.algorithm;
<span class="kw">import</span> rank2;
<span class="kw">auto</span> flatten(Arr)(Arr array)
{
<span class="kw">static</span> <span class="kw">if</span> (rank!Arr <= <span class="dv">1</span>)
<span class="kw">return</span> array;
<span class="kw">else</span>
{
<span class="kw">auto</span> children = map!(.flatten)(array);
<span class="kw">return</span> reduce!<span class="st">"a~b"</span>(children); <span class="co">// concatenate the children</span>
}
}</code></pre>
<p>We make good use of D <code class="sourceCode d"><span class="kw">auto</span></code> return parameter for functions there. In fact, a single call to <code class="sourceCode d">flatten</code> will create one instance per level, all with a different return type.</p>
<p>Note that <code class="sourceCode d">flatten</code> works perfectly on ranges too, but is not lazy: it eagerly concatenates all the elements down to the very last one in the innermost range. Ranges being lazy, a good <code class="sourceCode d">flatten</code> implementation for them should itself be a range that delivers the elements one by one, calculating the next one only when asked to (and thus, would work on infinite or very long ranges too, which the previous simple implementation cannot do). Implementing this means creating a <a href="#struct-templates">struct template</a> with a <a href="#factory-functions">factory function</a>. You will find this as an example <a href="#example-a-concat-flatten-range">here</a>.</p>
<p>From our current <code class="sourceCode d">flatten</code>, it's an interesting exercise to add another parameter: the number of levels you want to flatten. Only the first three levels or last two innermost, for example. Just add an integral template parameter that gets incremented (or decremented) when you recurse and is another stopping case for the recursion. Positive levels could mean the outermost levels, while a negative argument would act on the innermost ones. A possible use would look like this:</p>
<pre class="sourceCode d"><code class="sourceCode d">flatten!<span class="dv">1</span>([[[<span class="dv">0</span>,<span class="dv">1</span>],[]], [[<span class="dv">2</span>]], [[<span class="dv">3</span>], [<span class="dv">4</span>,<span class="dv">5</span>]], [[]], [[<span class="dv">6</span>,<span class="dv">7</span>,<span class="dv">8</span>]]]);
<span class="co">// == [[[0,1],[],[2],[3], [4,5],[],[6,7,8]]</span>
flatten!<span class="dv">2</span>([[[<span class="dv">0</span>,<span class="dv">1</span>],[]], [[<span class="dv">2</span>]], [[<span class="dv">3</span>], [<span class="dv">4</span>,<span class="dv">5</span>]], [[]], [[<span class="dv">6</span>,<span class="dv">7</span>,<span class="dv">8</span>]]]);
<span class="co">// == [0,1,2,3,4,5,6,7,8]</span>
flatten!<span class="dv">0</span>([[[<span class="dv">0</span>,<span class="dv">1</span>],[]], [[<span class="dv">2</span>]], [[<span class="dv">3</span>], [<span class="dv">4</span>,<span class="dv">5</span>]], [[]], [[<span class="dv">6</span>,<span class="dv">7</span>,<span class="dv">8</span>]]]);
<span class="co">// ==[[[0,1],[]], [[2]], [[3], [4,5]], [[]], [[6,7,8]]]</span>
flatten!(-<span class="dv">1</span>)([[[<span class="dv">0</span>,<span class="dv">1</span>],[]], [[<span class="dv">2</span>]], [[<span class="dv">3</span>], [<span class="dv">4</span>,<span class="dv">5</span>]], [[]], [[<span class="dv">6</span>,<span class="dv">7</span>,<span class="dv">8</span>]]]);
<span class="co">// ==[[[0,1]], [[2]], [[3,4,5]], [[]], [[6,7,8]]]</span></code></pre>
<h3 id="anonymous-function-templates">Anonymous Function Templates</h3>
<p>In D, you can define anonymous functions (delegates even, that is: closures):</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> anonymous_function1;
<span class="kw">auto</span> adder(<span class="dt">int</span> a)
{
<span class="kw">return</span> (<span class="dt">int</span> b) { <span class="kw">return</span> a+b;};
}
<span class="kw">unittest</span>
{
<span class="kw">auto</span> add1 = adder(<span class="dv">1</span>); <span class="co">// add1 is an int delegate(int)</span>
<span class="kw">assert</span>(add1(<span class="dv">2</span>) == <span class="dv">3</span>);
}</code></pre>
<p>In the previous code, <code class="sourceCode d">adder</code> returns an anonymous delegate. Could <code class="sourceCode d">adder</code> be templated? Ha! Remember <strong>The Mantra</strong>: function templates are templates and cannot be returned. For this particular problem, there are two possible solutions. Either you do not need any new type and just use <code class="sourceCode d">T</code>:</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> anonymous_function2;
<span class="kw">auto</span> adder(T)(T a)
{
<span class="kw">return</span> (T b) { <span class="kw">return</span> a+b;};
}
<span class="kw">unittest</span>
{
<span class="kw">auto</span> add1f = adder(<span class="fl">1.0</span>); <span class="co">// add1f is an float delegate(float)</span>
<span class="kw">assert</span>(add1f(<span class="fl">2.0</span>) == <span class="fl">3.0</span>);
<span class="kw">import</span> std.bigint;
<span class="co">// addBigOne accepts a BigInt and returns a BigInt</span>
<span class="kw">auto</span> addBigOne = adder(BigInt(<span class="st">"1000000000000000"</span>));
<span class="kw">assert</span>(addBigOne(BigInt(<span class="st">"1"</span>)) == BigInt(<span class="st">"1000000000000001"</span>));
<span class="co">// But:</span>
<span class="co">// auto error = add1(3.14); // Error! Waiting for an int, getting a double.</span>
}</code></pre>
<p>In the previous example, the returned anonymous delegate is <em>not</em> templated. It just happens to use <code class="sourceCode d">T</code>, which is perfectly defined once instantiation is done. If you really need to return something that can be called with any type, use an inner struct (see the section on <a href="#inner-structs">inner structs</a>).</p>
<p>Now, it may come as a surprise to you that D <em>does</em> have anonymous function templates. The syntax is a purified version of anonymous functions:</p>
<pre class="sourceCode d"><code class="sourceCode d">(a,b) { <span class="kw">return</span> a+b;}</code></pre>
<p>Yes, the previous skeleton of a function is an anonymous template. But, remember The Mantra: you cannot return them. And due to (to my eyes) a bug in <code class="sourceCode d"><span class="kw">alias</span></code> grammar, you cannot alias them to a symbol:</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">alias</span> (a){ <span class="kw">return</span> a;} Id; <span class="co">// Error</span></code></pre>
<p>So what good are they? You can use them with template alias parameters, when these stand for functions and function templates:</p>
<pre class="sourceCode d"><code class="sourceCode d"><span class="kw">module</span> calltwice;
<span class="kw">template</span> callTwice(<span class="kw">alias</span> fun)
{
<span class="kw">auto</span> callTwice(T)(T t)
{
<span class="kw">return</span> fun(fun(t));
}
}