D mode

x
 
1
/* D demo code // copied from phobos/sd/metastrings.d */
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
10
Copyright: Copyright Digital Mars 2007 - 2009.
11
License:   <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
12
Authors:   $(WEB digitalmars.com, Walter Bright),
13
           Don Clugston
14
Source:    $(PHOBOSSRC std/_metastrings.d)
15
*/
16
/*
17
         Copyright Digital Mars 2007 - 2009.
18
Distributed under the Boost Software License, Version 1.0.
19
   (See accompanying file LICENSE_1_0.txt or copy at
20
         http://www.boost.org/LICENSE_1_0.txt)
21
 */
22
module std.metastrings;
23
24
/**
25
Formats constants into a string at compile time.  Analogous to $(XREF
26
string,format).
27
28
Parameters:
29
30
A = tuple of constants, which can be strings, characters, or integral
31
    values.
32
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
        enum Format = "";
53
    else static if (is(typeof(A[0]) : const(char)[]))
54
        enum Format = FormatString!(A[0], A[1..$]);
55
    else
56
        enum Format = toStringNow!(A[0]) ~ Format!(A[1..$]);
57
}
58
59
template FormatString(const(char)[] F, A...)
60
{
61
    static if (F.length == 0)
62
        enum FormatString = Format!(A);
63
    else static if (F.length == 1)
64
        enum FormatString = F[0] ~ Format!(A);
65
    else static if (F[0..2] == "%s")
66
        enum FormatString
67
            = toStringNow!(A[0]) ~ FormatString!(F[2..$],A[1..$]);
68
    else static if (F[0..2] == "%%")
69
        enum FormatString = "%" ~ FormatString!(F[2..$],A);
70
    else
71
    {
72
        static assert(F[0] != '%', "unrecognized format %" ~ F[1]);
73
        enum FormatString = F[0] ~ FormatString!(F[1..$],A);
74
    }
75
}
76
77
unittest
78
{
79
    auto s = Format!("hel%slo", "world", -138, 'c', true);
80
    assert(s == "helworldlo-138ctrue", "[" ~ s ~ "]");
81
}
82
83
/**
84
 * Convert constant argument to a string.
85
 */
86
87
template toStringNow(ulong v)
88
{
89
    static if (v < 10)
90
        enum toStringNow = "" ~ cast(char)(v + '0');
91
    else
92
        enum toStringNow = toStringNow!(v / 10) ~ toStringNow!(v % 10);
93
}
94
95
unittest
96
{
97
    static assert(toStringNow!(1uL << 62) == "4611686018427387904");
98
}
99
100
/// ditto
101
template toStringNow(long v)
102
{
103
    static if (v < 0)
104
        enum toStringNow = "-" ~ toStringNow!(cast(ulong) -v);
105
    else
106
        enum toStringNow = toStringNow!(cast(ulong) v);
107
}
108
109
unittest
110
{
111
    static assert(toStringNow!(0x100000000) == "4294967296");
112
    static assert(toStringNow!(-138L) == "-138");
113
}
114
115
/// ditto
116
template toStringNow(uint U)
117
{
118
    enum toStringNow = toStringNow!(cast(ulong)U);
119
}
120
121
/// ditto
122
template toStringNow(int I)
123
{
124
    enum toStringNow = toStringNow!(cast(long)I);
125
}
126
127
/// ditto
128
template toStringNow(bool B)
129
{
130
    enum toStringNow = B ? "true" : "false";
131
}
132
133
/// ditto
134
template toStringNow(string S)
135
{
136
    enum toStringNow = S;
137
}
138
139
/// ditto
140
template toStringNow(char C)
141
{
142
    enum toStringNow = "" ~ C;
143
}
144
145
146
/********
147
 * Parse unsigned integer literal from the start of string s.
148
 * returns:
149
 *    .value = the integer literal as a string,
150
 *    .rest = the string following the integer literal
151
 * Otherwise:
152
 *    .value = null,
153
 *    .rest = s
154
 */
155
156
template parseUinteger(const(char)[] s)
157
{
158
    static if (s.length == 0)
159
    {
160
        enum value = "";
161
        enum rest = "";
162
    }
163
    else static if (s[0] >= '0' && s[0] <= '9')
164
    {
165
        enum value = s[0] ~ parseUinteger!(s[1..$]).value;
166
        enum rest = parseUinteger!(s[1..$]).rest;
167
    }
168
    else
169
    {
170
        enum value = "";
171
        enum rest = s;
172
    }
173
}
174
175
/********
176
Parse integer literal optionally preceded by $(D '-') from the start
177
of string $(D s).
178
179
Returns:
180
   .value = the integer literal as a string,
181
   .rest = the string following the integer literal
182
183
Otherwise:
184
   .value = null,
185
   .rest = s
186
*/
187
188
template parseInteger(const(char)[] s)
189
{
190
    static if (s.length == 0)
191
    {
192
        enum value = "";
193
        enum rest = "";
194
    }
195
    else static if (s[0] >= '0' && s[0] <= '9')
196
    {
197
        enum value = s[0] ~ parseUinteger!(s[1..$]).value;
198
        enum rest = parseUinteger!(s[1..$]).rest;
199
    }
200
    else static if (s.length >= 2 &&
201
            s[0] == '-' && s[1] >= '0' && s[1] <= '9')
202
    {
203
        enum value = s[0..2] ~ parseUinteger!(s[2..$]).value;
204
        enum rest = parseUinteger!(s[2..$]).rest;
205
    }
206
    else
207
    {
208
        enum value = "";
209
        enum rest = s;
210
    }
211
}
212
213
unittest
214
{
215
    assert(parseUinteger!("1234abc").value == "1234");
216
    assert(parseUinteger!("1234abc").rest == "abc");
217
    assert(parseInteger!("-1234abc").value == "-1234");
218
    assert(parseInteger!("-1234abc").rest == "abc");
219
}
220
221
/**
222
Deprecated aliases held for backward compatibility.
223
*/
224
deprecated alias toStringNow ToString;
225
/// Ditto
226
deprecated alias parseUinteger ParseUinteger;
227
/// Ditto
228
deprecated alias parseUinteger ParseInteger;
229
230

Simple mode that handle D-Syntax (DLang Homepage).

MIME types defined: text/x-d .