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