Split up "gfortran.dg/goacc/loop-2.f95"
[official-gcc.git] / libphobos / libdruntime / rt / switch_.d
blob73ad6365aa05cbc4292c5c7efeffe4633c4d20ba
1 /**
2 * Contains support code for switch blocks using string constants.
4 * Copyright: Copyright Digital Mars 2004 - 2010.
5 * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 * Authors: Walter Bright, Sean Kelly
7 */
9 /* Copyright Digital Mars 2004 - 2010.
10 * Distributed under the Boost Software License, Version 1.0.
11 * (See accompanying file LICENSE or copy at
12 * http://www.boost.org/LICENSE_1_0.txt)
14 module rt.switch_;
16 private import core.stdc.string;
18 /******************************************************
19 * Support for switch statements switching on strings.
20 * Input:
21 * table[] sorted array of strings generated by compiler
22 * ca string to look up in table
23 * Output:
24 * result index of match in table[]
25 * -1 if not in table
28 extern (C):
30 int _d_switch_string(char[][] table, char[] ca)
33 //printf("in _d_switch_string()\n");
34 assert(table.length >= 0);
35 assert(ca.length >= 0);
37 // Make sure table[] is sorted correctly
38 for (size_t j = 1u; j < table.length; j++)
40 auto len1 = table[j - 1].length;
41 auto len2 = table[j].length;
43 assert(len1 <= len2);
44 if (len1 == len2)
46 int ci;
48 ci = memcmp(table[j - 1].ptr, table[j].ptr, len1);
49 assert(ci < 0); // ci==0 means a duplicate
53 out (result)
55 int cj;
57 //printf("out _d_switch_string()\n");
58 if (result == -1)
60 // Not found
61 for (auto i = 0u; i < table.length; i++)
63 if (table[i].length == ca.length)
64 { cj = memcmp(table[i].ptr, ca.ptr, ca.length);
65 assert(cj != 0);
69 else
71 assert(0 <= result && cast(size_t)result < table.length);
72 for (auto i = 0u; 1; i++)
74 assert(i < table.length);
75 if (table[i].length == ca.length)
77 cj = memcmp(table[i].ptr, ca.ptr, ca.length);
78 if (cj == 0)
80 assert(i == result);
81 break;
87 body
89 //printf("body _d_switch_string(%.*s)\n", ca.length, ca.ptr);
90 size_t low = 0;
91 size_t high = table.length;
93 version (none)
95 // Print table
96 printf("ca[] = '%s'\n", ca.length, ca.ptr);
97 for (auto i = 0; i < high; i++)
99 auto pca = table[i];
100 printf("table[%d] = %d, '%.*s'\n", i, pca.length, pca.length, pca.ptr);
103 if (high &&
104 ca.length >= table[0].length &&
105 ca.length <= table[high - 1].length)
107 // Looking for 0 length string, which would only be at the beginning
108 if (ca.length == 0)
109 return 0;
111 char c1 = ca[0];
113 // Do binary search
114 while (low < high)
116 auto mid = (low + high) >> 1;
117 auto pca = table[mid];
118 auto c = cast(sizediff_t)(ca.length - pca.length);
119 if (c == 0)
121 c = cast(ubyte)c1 - cast(ubyte)pca[0];
122 if (c == 0)
124 c = memcmp(ca.ptr, pca.ptr, ca.length);
125 if (c == 0)
126 { //printf("found %d\n", mid);
127 return cast(int)mid;
131 if (c < 0)
133 high = mid;
135 else
137 low = mid + 1;
142 //printf("not found\n");
143 return -1; // not found
146 unittest
148 switch (cast(char []) "c")
150 case "coo":
151 default:
152 break;
155 int bug5381(string s)
157 switch (s)
159 case "unittest": return 1;
160 case "D_Version2": return 2;
161 case "none": return 3;
162 case "all": return 4;
163 default: return 5;
166 int rc = bug5381("none");
167 assert(rc == 3);
170 /**********************************
171 * Same thing, but for wide chars.
174 int _d_switch_ustring(wchar[][] table, wchar[] ca)
177 //printf("in _d_switch_ustring()\n");
178 assert(table.length >= 0);
179 assert(ca.length >= 0);
181 // Make sure table[] is sorted correctly
182 for (size_t j = 1u; j < table.length; j++)
184 auto len1 = table[j - 1].length;
185 auto len2 = table[j].length;
187 assert(len1 <= len2);
188 if (len1 == len2)
190 int c;
192 c = memcmp(table[j - 1].ptr, table[j].ptr, len1 * wchar.sizeof);
193 assert(c < 0); // c==0 means a duplicate
197 out (result)
199 int c;
201 //printf("out _d_switch_ustring()\n");
202 if (result == -1)
204 // Not found
205 for (auto i = 0u; i < table.length; i++)
207 if (table[i].length == ca.length)
208 { c = memcmp(table[i].ptr, ca.ptr, ca.length * wchar.sizeof);
209 assert(c != 0);
213 else
215 assert(0 <= result && cast(size_t)result < table.length);
216 for (auto i = 0u; 1; i++)
218 assert(i < table.length);
219 if (table[i].length == ca.length)
221 c = memcmp(table[i].ptr, ca.ptr, ca.length * wchar.sizeof);
222 if (c == 0)
224 assert(i == result);
225 break;
231 body
233 //printf("body _d_switch_ustring()\n");
234 size_t low = 0;
235 auto high = table.length;
237 version (none)
239 // Print table
240 wprintf("ca[] = '%.*s'\n", ca.length, ca.ptr);
241 for (auto i = 0; i < high; i++)
243 auto pca = table[i];
244 wprintf("table[%d] = %d, '%.*s'\n", i, pca.length, pca.length, pca.ptr);
248 // Do binary search
249 while (low < high)
251 auto mid = (low + high) >> 1;
252 auto pca = table[mid];
253 auto c = cast(sizediff_t)(ca.length - pca.length);
254 if (c == 0)
256 c = memcmp(ca.ptr, pca.ptr, ca.length * wchar.sizeof);
257 if (c == 0)
258 { //printf("found %d\n", mid);
259 return cast(int)mid;
262 if (c < 0)
264 high = mid;
266 else
268 low = mid + 1;
271 //printf("not found\n");
272 return -1; // not found
276 unittest
278 switch (cast(wchar []) "c")
280 case "coo":
281 default:
282 break;
285 int bug5381(wstring ws)
287 switch (ws)
289 case "unittest": return 1;
290 case "D_Version2": return 2;
291 case "none": return 3;
292 case "all": return 4;
293 default: return 5;
296 int rc = bug5381("none"w);
297 assert(rc == 3);
300 /**********************************
301 * Same thing, but for wide chars.
304 int _d_switch_dstring(dchar[][] table, dchar[] ca)
307 //printf("in _d_switch_dstring()\n");
308 assert(table.length >= 0);
309 assert(ca.length >= 0);
311 // Make sure table[] is sorted correctly
312 for (auto j = 1u; j < table.length; j++)
314 auto len1 = table[j - 1].length;
315 auto len2 = table[j].length;
317 assert(len1 <= len2);
318 if (len1 == len2)
320 auto c = memcmp(table[j - 1].ptr, table[j].ptr, len1 * dchar.sizeof);
321 assert(c < 0); // c==0 means a duplicate
325 out (result)
327 //printf("out _d_switch_dstring()\n");
328 if (result == -1)
330 // Not found
331 for (auto i = 0u; i < table.length; i++)
333 if (table[i].length == ca.length)
334 { auto c = memcmp(table[i].ptr, ca.ptr, ca.length * dchar.sizeof);
335 assert(c != 0);
339 else
341 assert(0 <= result && cast(size_t)result < table.length);
342 for (auto i = 0u; 1; i++)
344 assert(i < table.length);
345 if (table[i].length == ca.length)
347 auto c = memcmp(table[i].ptr, ca.ptr, ca.length * dchar.sizeof);
348 if (c == 0)
350 assert(i == result);
351 break;
357 body
359 //printf("body _d_switch_dstring()\n");
360 size_t low = 0;
361 auto high = table.length;
363 version (none)
365 // Print table
366 wprintf("ca[] = '%.*s'\n", ca.length, ca.ptr);
367 for (auto i = 0; i < high; i++)
369 auto pca = table[i];
370 wprintf("table[%d] = %d, '%.*s'\n", i, pca.length, pca.length, pca.ptr);
374 // Do binary search
375 while (low < high)
377 auto mid = (low + high) >> 1;
378 auto pca = table[mid];
379 auto c = cast(sizediff_t)(ca.length - pca.length);
380 if (c == 0)
382 c = memcmp(ca.ptr, pca.ptr, ca.length * dchar.sizeof);
383 if (c == 0)
384 { //printf("found %d\n", mid);
385 return cast(int)mid;
388 if (c < 0)
390 high = mid;
392 else
394 low = mid + 1;
397 //printf("not found\n");
398 return -1; // not found
402 unittest
404 switch (cast(dchar []) "c")
406 case "coo":
407 default:
408 break;
411 int bug5381(dstring ds)
413 switch (ds)
415 case "unittest": return 1;
416 case "D_Version2": return 2;
417 case "none": return 3;
418 case "all": return 4;
419 default: return 5;
422 int rc = bug5381("none"d);
423 assert(rc == 3);