Mercurial > projects > ldc
annotate lphobos/internal/switch.d @ 837:331a176c1f4f
Removed error on naked, not fully complete, but I'll be doing more work on it during this Christmas, and some things do work.
Fixed taking delegate of final class method. see mini/delegate3.d.
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Tue, 09 Dec 2008 14:07:30 +0100 |
parents | 373489eeaf90 |
children |
rev | line source |
---|---|
122 | 1 /* |
2 * Copyright (C) 2004-2007 by Digital Mars, www.digitalmars.com | |
3 * Written by Walter Bright | |
4 * | |
5 * This software is provided 'as-is', without any express or implied | |
6 * warranty. In no event will the authors be held liable for any damages | |
7 * arising from the use of this software. | |
8 * | |
9 * Permission is granted to anyone to use this software for any purpose, | |
10 * including commercial applications, and to alter it and redistribute it | |
11 * freely, in both source and binary form, subject to the following | |
12 * restrictions: | |
13 * | |
14 * o The origin of this software must not be misrepresented; you must not | |
15 * claim that you wrote the original software. If you use this software | |
16 * in a product, an acknowledgment in the product documentation would be | |
17 * appreciated but is not required. | |
18 * o Altered source versions must be plainly marked as such, and must not | |
19 * be misrepresented as being the original software. | |
20 * o This notice may not be removed or altered from any source | |
21 * distribution. | |
22 */ | |
23 | |
24 | |
25 import std.c.stdio; | |
26 import std.c.string; | |
27 import std.string; | |
28 | |
29 /****************************************************** | |
30 * Support for switch statements switching on strings. | |
31 * Input: | |
32 * table[] sorted array of strings generated by compiler | |
33 * ca string to look up in table | |
34 * Output: | |
35 * result index of match in table[] | |
36 * -1 if not in table | |
37 */ | |
38 | |
39 extern (C): | |
40 | |
41 int _d_switch_string(char[][] table, char[] ca) | |
42 in | |
43 { | |
44 //printf("in _d_switch_string()\n"); | |
45 assert(table.length >= 0); | |
46 assert(ca.length >= 0); | |
47 | |
48 // Make sure table[] is sorted correctly | |
49 int j; | |
50 | |
51 for (j = 1; j < table.length; j++) | |
52 { | |
53 int len1 = table[j - 1].length; | |
54 int len2 = table[j].length; | |
55 | |
56 assert(len1 <= len2); | |
57 if (len1 == len2) | |
58 { | |
59 int ci; | |
60 | |
61 ci = memcmp(table[j - 1].ptr, table[j].ptr, len1); | |
62 assert(ci < 0); // ci==0 means a duplicate | |
63 } | |
64 } | |
65 } | |
66 out (result) | |
67 { | |
68 int i; | |
69 int cj; | |
70 | |
71 //printf("out _d_switch_string()\n"); | |
72 if (result == -1) | |
73 { | |
74 // Not found | |
75 for (i = 0; i < table.length; i++) | |
76 { | |
77 if (table[i].length == ca.length) | |
78 { cj = memcmp(table[i].ptr, ca.ptr, ca.length); | |
79 assert(cj != 0); | |
80 } | |
81 } | |
82 } | |
83 else | |
84 { | |
85 assert(0 <= result && result < table.length); | |
86 for (i = 0; 1; i++) | |
87 { | |
88 assert(i < table.length); | |
89 if (table[i].length == ca.length) | |
90 { | |
91 cj = memcmp(table[i].ptr, ca.ptr, ca.length); | |
92 if (cj == 0) | |
93 { | |
94 assert(i == result); | |
95 break; | |
96 } | |
97 } | |
98 } | |
99 } | |
100 } | |
101 body | |
102 { | |
103 //printf("body _d_switch_string(%.*s)\n", ca); | |
104 int low; | |
105 int high; | |
106 int mid; | |
107 int c; | |
108 char[] pca; | |
109 | |
110 low = 0; | |
111 high = table.length; | |
112 | |
113 version (none) | |
114 { | |
115 // Print table | |
116 printf("ca[] = '%s'\n", cast(char *)ca); | |
117 for (mid = 0; mid < high; mid++) | |
118 { | |
119 pca = table[mid]; | |
120 printf("table[%d] = %d, '%.*s'\n", mid, pca.length, pca); | |
121 } | |
122 } | |
123 if (high && | |
124 ca.length >= table[0].length && | |
125 ca.length <= table[high - 1].length) | |
126 { | |
127 // Looking for 0 length string, which would only be at the beginning | |
128 if (ca.length == 0) | |
129 return 0; | |
130 | |
131 char c1 = ca[0]; | |
132 | |
133 // Do binary search | |
134 while (low < high) | |
135 { | |
136 mid = (low + high) >> 1; | |
137 pca = table[mid]; | |
138 c = ca.length - pca.length; | |
139 if (c == 0) | |
140 { | |
141 c = cast(ubyte)c1 - cast(ubyte)pca[0]; | |
142 if (c == 0) | |
143 { | |
144 c = memcmp(ca.ptr, pca.ptr, ca.length); | |
145 if (c == 0) | |
146 { //printf("found %d\n", mid); | |
147 return mid; | |
148 } | |
149 } | |
150 } | |
151 if (c < 0) | |
152 { | |
153 high = mid; | |
154 } | |
155 else | |
156 { | |
157 low = mid + 1; | |
158 } | |
159 } | |
160 } | |
161 | |
162 //printf("not found\n"); | |
163 return -1; // not found | |
164 } | |
165 | |
166 unittest | |
167 { | |
168 switch (cast(char []) "c") | |
169 { | |
170 case "coo": | |
171 default: | |
172 break; | |
173 } | |
174 } | |
175 | |
176 /********************************** | |
177 * Same thing, but for wide chars. | |
178 */ | |
179 | |
180 int _d_switch_ustring(wchar[][] table, wchar[] ca) | |
181 in | |
182 { | |
183 //printf("in _d_switch_ustring()\n"); | |
184 assert(table.length >= 0); | |
185 assert(ca.length >= 0); | |
186 | |
187 // Make sure table[] is sorted correctly | |
188 int j; | |
189 | |
190 for (j = 1; j < table.length; j++) | |
191 { | |
192 int len1 = table[j - 1].length; | |
193 int len2 = table[j].length; | |
194 | |
195 assert(len1 <= len2); | |
196 if (len1 == len2) | |
197 { | |
198 int c; | |
199 | |
200 c = memcmp(table[j - 1].ptr, table[j].ptr, len1 * wchar.sizeof); | |
201 assert(c < 0); // c==0 means a duplicate | |
202 } | |
203 } | |
204 } | |
205 out (result) | |
206 { | |
207 int i; | |
208 int c; | |
209 | |
210 //printf("out _d_switch_string()\n"); | |
211 if (result == -1) | |
212 { | |
213 // Not found | |
214 for (i = 0; i < table.length; i++) | |
215 { | |
216 if (table[i].length == ca.length) | |
217 { c = memcmp(table[i].ptr, ca.ptr, ca.length * wchar.sizeof); | |
218 assert(c != 0); | |
219 } | |
220 } | |
221 } | |
222 else | |
223 { | |
224 assert(0 <= result && result < table.length); | |
225 for (i = 0; 1; i++) | |
226 { | |
227 assert(i < table.length); | |
228 if (table[i].length == ca.length) | |
229 { | |
230 c = memcmp(table[i].ptr, ca.ptr, ca.length * wchar.sizeof); | |
231 if (c == 0) | |
232 { | |
233 assert(i == result); | |
234 break; | |
235 } | |
236 } | |
237 } | |
238 } | |
239 } | |
240 body | |
241 { | |
242 //printf("body _d_switch_ustring()\n"); | |
243 int low; | |
244 int high; | |
245 int mid; | |
246 int c; | |
247 wchar[] pca; | |
248 | |
249 low = 0; | |
250 high = table.length; | |
251 | |
252 /* | |
253 // Print table | |
254 wprintf("ca[] = '%.*s'\n", ca); | |
255 for (mid = 0; mid < high; mid++) | |
256 { | |
257 pca = table[mid]; | |
258 wprintf("table[%d] = %d, '%.*s'\n", mid, pca.length, pca); | |
259 } | |
260 */ | |
261 | |
262 // Do binary search | |
263 while (low < high) | |
264 { | |
265 mid = (low + high) >> 1; | |
266 pca = table[mid]; | |
267 c = ca.length - pca.length; | |
268 if (c == 0) | |
269 { | |
270 c = memcmp(ca.ptr, pca.ptr, ca.length * wchar.sizeof); | |
271 if (c == 0) | |
272 { //printf("found %d\n", mid); | |
273 return mid; | |
274 } | |
275 } | |
276 if (c < 0) | |
277 { | |
278 high = mid; | |
279 } | |
280 else | |
281 { | |
282 low = mid + 1; | |
283 } | |
284 } | |
285 //printf("not found\n"); | |
286 return -1; // not found | |
287 } | |
288 | |
289 | |
290 unittest | |
291 { | |
292 switch (cast(wchar []) "c") | |
293 { | |
294 case "coo": | |
295 default: | |
296 break; | |
297 } | |
298 } | |
299 | |
300 | |
301 /********************************** | |
302 * Same thing, but for wide chars. | |
303 */ | |
304 | |
305 int _d_switch_dstring(dchar[][] table, dchar[] ca) | |
306 in | |
307 { | |
308 //printf("in _d_switch_dstring()\n"); | |
309 assert(table.length >= 0); | |
310 assert(ca.length >= 0); | |
311 | |
312 // Make sure table[] is sorted correctly | |
313 int j; | |
314 | |
315 for (j = 1; j < table.length; j++) | |
316 { | |
317 int len1 = table[j - 1].length; | |
318 int len2 = table[j].length; | |
319 | |
320 assert(len1 <= len2); | |
321 if (len1 == len2) | |
322 { | |
323 int c; | |
324 | |
325 c = memcmp(table[j - 1].ptr, table[j].ptr, len1 * dchar.sizeof); | |
326 assert(c < 0); // c==0 means a duplicate | |
327 } | |
328 } | |
329 } | |
330 out (result) | |
331 { | |
332 int i; | |
333 int c; | |
334 | |
335 //printf("out _d_switch_string()\n"); | |
336 if (result == -1) | |
337 { | |
338 // Not found | |
339 for (i = 0; i < table.length; i++) | |
340 { | |
341 if (table[i].length == ca.length) | |
342 { c = memcmp(table[i].ptr, ca.ptr, ca.length * dchar.sizeof); | |
343 assert(c != 0); | |
344 } | |
345 } | |
346 } | |
347 else | |
348 { | |
349 assert(0 <= result && result < table.length); | |
350 for (i = 0; 1; i++) | |
351 { | |
352 assert(i < table.length); | |
353 if (table[i].length == ca.length) | |
354 { | |
355 c = memcmp(table[i].ptr, ca.ptr, ca.length * dchar.sizeof); | |
356 if (c == 0) | |
357 { | |
358 assert(i == result); | |
359 break; | |
360 } | |
361 } | |
362 } | |
363 } | |
364 } | |
365 body | |
366 { | |
367 //printf("body _d_switch_ustring()\n"); | |
368 int low; | |
369 int high; | |
370 int mid; | |
371 int c; | |
372 dchar[] pca; | |
373 | |
374 low = 0; | |
375 high = table.length; | |
376 | |
377 /* | |
378 // Print table | |
379 wprintf("ca[] = '%.*s'\n", ca); | |
380 for (mid = 0; mid < high; mid++) | |
381 { | |
382 pca = table[mid]; | |
383 wprintf("table[%d] = %d, '%.*s'\n", mid, pca.length, pca); | |
384 } | |
385 */ | |
386 | |
387 // Do binary search | |
388 while (low < high) | |
389 { | |
390 mid = (low + high) >> 1; | |
391 pca = table[mid]; | |
392 c = ca.length - pca.length; | |
393 if (c == 0) | |
394 { | |
395 c = memcmp(ca.ptr, pca.ptr, ca.length * dchar.sizeof); | |
396 if (c == 0) | |
397 { //printf("found %d\n", mid); | |
398 return mid; | |
399 } | |
400 } | |
401 if (c < 0) | |
402 { | |
403 high = mid; | |
404 } | |
405 else | |
406 { | |
407 low = mid + 1; | |
408 } | |
409 } | |
410 //printf("not found\n"); | |
411 return -1; // not found | |
412 } | |
413 | |
414 | |
415 unittest | |
416 { | |
417 switch (cast(dchar []) "c") | |
418 { | |
419 case "coo": | |
420 default: | |
421 break; | |
422 } | |
423 } | |
424 | |
473
373489eeaf90
Applied downs' lphobos update
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
122
diff
changeset
|
425 void _d_switch_error(string fn, int line) |
373489eeaf90
Applied downs' lphobos update
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
122
diff
changeset
|
426 { |
373489eeaf90
Applied downs' lphobos update
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
122
diff
changeset
|
427 throw new Exception(fn~toString(line)~": switch missing default"); |
373489eeaf90
Applied downs' lphobos update
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
122
diff
changeset
|
428 } |