1 /**
2 * An implementation of Timon Gehr's X template
3 *
4 * License:
5 * This Source Code Form is subject to the terms of
6 * the Mozilla Public License, v. 2.0. If a copy of
7 * the MPL was not distributed with this file, You
8 * can obtain one at http://mozilla.org/MPL/2.0/.
9 *
10 * Authors:
11 * Vladimir Panteleev <ae@cy.md>
12 */
13
14 module ae.utils.meta.x;
15
16 // Based on idea from Timon Gehr.
17 // http://forum.dlang.org/post/jdiu5s$13bo$1@digitalmars.com
18
19 /// Pre-processes a D code mixin, allowing
20 /// interpolation using @(...) sequences.
21 template X(string x)
22 {
23 enum X = xImpl(x);
24 }
25
26 private string xImpl(string x)
27 {
28 string r;
29
30 for (size_t i=0; i<x.length; i++)
31 if (x[i]=='@' && x[i+1]=='(')
32 {
33 auto j = i+2;
34 for (int nest=1; nest; j++)
35 nest += x[j] == '(' ? +1 : x[j] == ')' ? -1 : 0;
36
37 r ~= `"~(` ~ x[i+2..j-1] ~ `)~"`;
38 i = j-1;
39 }
40 else
41 {
42 if (x[i]=='"' || x[i]=='\\')
43 r ~= "\\";
44 r ~= x[i];
45 }
46 return `"` ~ r ~ `"`;
47 }
48
49 ///
50 debug(ae_unittest) unittest
51 {
52 enum VAR = "aoeu";
53 int aoeu;
54
55 string INSTALL_MEANING_OF_LIFE(string TARGET)
56 {
57 return mixin(X!q{
58 @(TARGET) = 42;
59 });
60 }
61
62 mixin(INSTALL_MEANING_OF_LIFE(VAR));
63 assert(aoeu == 42);
64 }
65