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 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