Mercurial > projects > dil
comparison trunk/src/util/metastrings.d @ 629:d050e211402b
Moved files in src/std/ to src/util/.
author | Aziz K?ksal <aziz.koeksal@gmail.com> |
---|---|
date | Fri, 11 Jan 2008 20:03:46 +0100 |
parents | trunk/src/std/metastrings.d@33b566df6af4 |
children | b091e8b0ef5c |
comparison
equal
deleted
inserted
replaced
628:08681b93c3b3 | 629:d050e211402b |
---|---|
1 | |
2 // Written in the D programming language. | |
3 | |
4 /** | |
5 * Templates with which to do compile time manipulation of strings. | |
6 * | |
7 * Macros: | |
8 * WIKI = Phobos/StdMetastrings | |
9 * Copyright: | |
10 * Public Domain | |
11 */ | |
12 | |
13 /* | |
14 * Authors: | |
15 * Walter Bright, Digital Mars, www.digitalmars.com | |
16 * Don Clugston | |
17 */ | |
18 | |
19 /* | |
20 Note: this is not the original file! | |
21 Modified by Aziz Köksal: | |
22 Only changed some types from string to char[] | |
23 */ | |
24 | |
25 module util.metastrings; | |
26 | |
27 /** | |
28 * Formats constants into a string at compile time. | |
29 * Analogous to std.string.format(). | |
30 * Parameters: | |
31 * A = tuple of constants, which can be strings, | |
32 * characters, or integral values. | |
33 * Formats: | |
34 * The formats supported are %s for strings, and %% | |
35 * for the % character. | |
36 * Example: | |
37 * --- | |
38 import std.metastrings; | |
39 import std.stdio; | |
40 | |
41 void main() | |
42 { | |
43 string s = Format!("Arg %s = %s", "foo", 27); | |
44 writefln(s); // "Arg foo = 27" | |
45 } | |
46 * --- | |
47 */ | |
48 | |
49 template Format(A...) | |
50 { | |
51 static if (A.length == 0) | |
52 const char[] Format = ""; | |
53 else static if (is(typeof(A[0]) : char[])) | |
54 const char[] Format = FormatString!(A[0], A[1..$]); | |
55 //const char[] Format = FormatString!(A[0]); | |
56 else | |
57 const char[] Format = ToString!(A[0]) ~ Format!(A[1..$]); | |
58 } | |
59 | |
60 template FormatString(char[] F, A...) | |
61 { | |
62 static if (F.length == 0) | |
63 const char[] FormatString = Format!(A); | |
64 else static if (F.length == 1) | |
65 const char[] FormatString = F[0] ~ Format!(A); | |
66 else static if (F[0..2] == "%s") | |
67 const char[] FormatString = ToString!(A[0]) ~ FormatString!(F[2..$],A[1..$]); | |
68 else static if (F[0..2] == "%%") | |
69 const char[] FormatString = "%" ~ FormatString!(F[2..$],A); | |
70 else static if (F[0] == '%') | |
71 static assert(0, "unrecognized format %" ~ F[1]); | |
72 else | |
73 const char[] FormatString = F[0] ~ FormatString!(F[1..$],A); | |
74 } | |
75 | |
76 /** | |
77 * Convert constant argument to a string. | |
78 */ | |
79 | |
80 template ToString(ulong U) | |
81 { | |
82 static if (U < 10) | |
83 const char[] ToString = "" ~ cast(char)(U + '0'); | |
84 else | |
85 const char[] ToString = ToString!(U / 10) ~ ToString!(U % 10); | |
86 } | |
87 | |
88 /// ditto | |
89 template ToString(long I) | |
90 { | |
91 static if (I < 0) | |
92 const char[] ToString = "-" ~ ToString!(cast(ulong)(-I)); | |
93 else | |
94 const char[] ToString = ToString!(cast(ulong)I); | |
95 } | |
96 | |
97 static assert(ToString!(0x100000000) == "4294967296"); | |
98 | |
99 /// ditto | |
100 template ToString(uint U) | |
101 { | |
102 const char[] ToString = ToString!(cast(ulong)U); | |
103 } | |
104 | |
105 /// ditto | |
106 template ToString(int I) | |
107 { | |
108 const char[] ToString = ToString!(cast(long)I); | |
109 } | |
110 | |
111 /// ditto | |
112 template ToString(ushort U) | |
113 { | |
114 const char[] ToString = ToString!(cast(ulong)U); | |
115 } | |
116 | |
117 /// ditto | |
118 template ToString(short I) | |
119 { | |
120 const char[] ToString = ToString!(cast(long)I); | |
121 } | |
122 | |
123 /// ditto | |
124 template ToString(ubyte U) | |
125 { | |
126 const char[] ToString = ToString!(cast(ulong)U); | |
127 } | |
128 | |
129 /// ditto | |
130 template ToString(byte I) | |
131 { | |
132 const char[] ToString = ToString!(cast(long)I); | |
133 } | |
134 | |
135 /// ditto | |
136 template ToString(bool B) | |
137 { | |
138 const char[] ToString = B ? "true" : "false"; | |
139 } | |
140 | |
141 /// ditto | |
142 template ToString(char[] S) | |
143 { | |
144 const char[] ToString = S; | |
145 } | |
146 | |
147 /// ditto | |
148 template ToString(char C) | |
149 { | |
150 const char[] ToString = "" ~ C; | |
151 } | |
152 | |
153 unittest | |
154 { | |
155 char[] s = Format!("hel%slo", "world", -138, 'c', true); | |
156 assert(s == "helworldlo-138ctrue"); | |
157 } | |
158 | |
159 | |
160 /******** | |
161 * Parse unsigned integer literal from the start of string s. | |
162 * returns: | |
163 * .value = the integer literal as a string, | |
164 * .rest = the string following the integer literal | |
165 * Otherwise: | |
166 * .value = null, | |
167 * .rest = s | |
168 */ | |
169 | |
170 template ParseUinteger(char[] s) | |
171 { | |
172 static if (s.length == 0) | |
173 { const char[] value = ""; | |
174 const char[] rest = ""; | |
175 } | |
176 else static if (s[0] >= '0' && s[0] <= '9') | |
177 { const char[] value = s[0] ~ ParseUinteger!(s[1..$]).value; | |
178 const char[] rest = ParseUinteger!(s[1..$]).rest; | |
179 } | |
180 else | |
181 { const char[] value = ""; | |
182 const char[] rest = s; | |
183 } | |
184 } | |
185 | |
186 /******** | |
187 * Parse integer literal optionally preceded by '-' | |
188 * from the start of string s. | |
189 * returns: | |
190 * .value = the integer literal as a string, | |
191 * .rest = the string following the integer literal | |
192 * Otherwise: | |
193 * .value = null, | |
194 * .rest = s | |
195 */ | |
196 | |
197 template ParseInteger(char[] s) | |
198 { | |
199 static if (s.length == 0) | |
200 { const char[] value = ""; | |
201 const char[] rest = ""; | |
202 } | |
203 else static if (s[0] >= '0' && s[0] <= '9') | |
204 { const char[] value = s[0] ~ ParseUinteger!(s[1..$]).value; | |
205 const char[] rest = ParseUinteger!(s[1..$]).rest; | |
206 } | |
207 else static if (s.length >= 2 && | |
208 s[0] == '-' && s[1] >= '0' && s[1] <= '9') | |
209 { const char[] value = s[0..2] ~ ParseUinteger!(s[2..$]).value; | |
210 const char[] rest = ParseUinteger!(s[2..$]).rest; | |
211 } | |
212 else | |
213 { const char[] value = ""; | |
214 const char[] rest = s; | |
215 } | |
216 } | |
217 | |
218 unittest | |
219 { | |
220 assert(ParseUinteger!("1234abc").value == "1234"); | |
221 assert(ParseUinteger!("1234abc").rest == "abc"); | |
222 assert(ParseInteger!("-1234abc").value == "-1234"); | |
223 assert(ParseInteger!("-1234abc").rest == "abc"); | |
224 } | |
225 |