comparison druntime/src/compiler/ldc/aApplyR.d @ 759:d3eb054172f9

Added copy of druntime from DMD 2.020 modified for LDC.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Tue, 11 Nov 2008 01:52:37 +0100
parents
children
comparison
equal deleted inserted replaced
758:f04dde6e882c 759:d3eb054172f9
1
2 /**
3 * Part of the D programming language runtime library.
4 */
5
6 /*
7 * Copyright (C) 2004-2006 by Digital Mars, www.digitalmars.com
8 * Written by Walter Bright
9 *
10 * This software is provided 'as-is', without any express or implied
11 * warranty. In no event will the authors be held liable for any damages
12 * arising from the use of this software.
13 *
14 * Permission is granted to anyone to use this software for any purpose,
15 * including commercial applications, and to alter it and redistribute it
16 * freely, in both source and binary form, subject to the following
17 * restrictions:
18 *
19 * o The origin of this software must not be misrepresented; you must not
20 * claim that you wrote the original software. If you use this software
21 * in a product, an acknowledgment in the product documentation would be
22 * appreciated but is not required.
23 * o Altered source versions must be plainly marked as such, and must not
24 * be misrepresented as being the original software.
25 * o This notice may not be removed or altered from any source
26 * distribution.
27 */
28
29 /*
30 * Modified by Sean Kelly <sean@f4.ca> for use with Tango.
31 */
32
33 /* This code handles decoding UTF strings for foreach_reverse loops.
34 * There are 6 combinations of conversions between char, wchar,
35 * and dchar, and 2 of each of those.
36 */
37
38 private import util.utf;
39
40 /**********************************************/
41 /* 1 argument versions */
42
43 // dg is D, but _aApplyRcd() is C
44 extern (D) typedef int delegate(void *) dg_t;
45
46 extern (C) int _aApplyRcd1(in char[] aa, dg_t dg)
47 { int result;
48
49 debug(apply) printf("_aApplyRcd1(), len = %d\n", aa.length);
50 for (size_t i = aa.length; i != 0; )
51 { dchar d;
52
53 i--;
54 d = aa[i];
55 if (d & 0x80)
56 { char c = cast(char)d;
57 uint j;
58 uint m = 0x3F;
59 d = 0;
60 while ((c & 0xC0) != 0xC0)
61 { if (i == 0)
62 onUnicodeError("Invalid UTF-8 sequence", 0);
63 i--;
64 d |= (c & 0x3F) << j;
65 j += 6;
66 m >>= 1;
67 c = aa[i];
68 }
69 d |= (c & m) << j;
70 }
71 result = dg(cast(void *)&d);
72 if (result)
73 break;
74 }
75 return result;
76 }
77
78 unittest
79 {
80 debug(apply) printf("_aApplyRcd1.unittest\n");
81
82 char[] s = "hello"c;
83 int i;
84
85 foreach_reverse(dchar d; s)
86 {
87 switch (i)
88 {
89 case 0: assert(d == 'o'); break;
90 case 1: assert(d == 'l'); break;
91 case 2: assert(d == 'l'); break;
92 case 3: assert(d == 'e'); break;
93 case 4: assert(d == 'h'); break;
94 default: assert(0);
95 }
96 i++;
97 }
98 assert(i == 5);
99
100 s = "a\u1234\U00100456b";
101 i = 0;
102 foreach_reverse(dchar d; s)
103 {
104 //printf("i = %d, d = %x\n", i, d);
105 switch (i)
106 {
107 case 0: assert(d == 'b'); break;
108 case 1: assert(d == '\U00100456'); break;
109 case 2: assert(d == '\u1234'); break;
110 case 3: assert(d == 'a'); break;
111 default: assert(0);
112 }
113 i++;
114 }
115 assert(i == 4);
116 }
117
118 /*****************************/
119
120 extern (C) int _aApplyRwd1(in wchar[] aa, dg_t dg)
121 { int result;
122
123 debug(apply) printf("_aApplyRwd1(), len = %d\n", aa.length);
124 for (size_t i = aa.length; i != 0; )
125 { dchar d;
126
127 i--;
128 d = aa[i];
129 if (d >= 0xDC00 && d <= 0xDFFF)
130 { if (i == 0)
131 onUnicodeError("Invalid UTF-16 sequence", 0);
132 i--;
133 d = ((aa[i] - 0xD7C0) << 10) + (d - 0xDC00);
134 }
135 result = dg(cast(void *)&d);
136 if (result)
137 break;
138 }
139 return result;
140 }
141
142 unittest
143 {
144 debug(apply) printf("_aApplyRwd1.unittest\n");
145
146 wchar[] s = "hello"w;
147 int i;
148
149 foreach_reverse(dchar d; s)
150 {
151 switch (i)
152 {
153 case 0: assert(d == 'o'); break;
154 case 1: assert(d == 'l'); break;
155 case 2: assert(d == 'l'); break;
156 case 3: assert(d == 'e'); break;
157 case 4: assert(d == 'h'); break;
158 default: assert(0);
159 }
160 i++;
161 }
162 assert(i == 5);
163
164 s = "a\u1234\U00100456b";
165 i = 0;
166 foreach_reverse(dchar d; s)
167 {
168 //printf("i = %d, d = %x\n", i, d);
169 switch (i)
170 {
171 case 0: assert(d == 'b'); break;
172 case 1: assert(d == '\U00100456'); break;
173 case 2: assert(d == '\u1234'); break;
174 case 3: assert(d == 'a'); break;
175 default: assert(0);
176 }
177 i++;
178 }
179 assert(i == 4);
180 }
181
182 /*****************************/
183
184 extern (C) int _aApplyRcw1(in char[] aa, dg_t dg)
185 { int result;
186
187 debug(apply) printf("_aApplyRcw1(), len = %d\n", aa.length);
188 for (size_t i = aa.length; i != 0; )
189 { dchar d;
190 wchar w;
191
192 i--;
193 w = aa[i];
194 if (w & 0x80)
195 { char c = cast(char)w;
196 uint j;
197 uint m = 0x3F;
198 d = 0;
199 while ((c & 0xC0) != 0xC0)
200 { if (i == 0)
201 onUnicodeError("Invalid UTF-8 sequence", 0);
202 i--;
203 d |= (c & 0x3F) << j;
204 j += 6;
205 m >>= 1;
206 c = aa[i];
207 }
208 d |= (c & m) << j;
209
210 if (d <= 0xFFFF)
211 w = cast(wchar) d;
212 else
213 {
214 w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
215 result = dg(cast(void *)&w);
216 if (result)
217 break;
218 w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);
219 }
220 }
221 result = dg(cast(void *)&w);
222 if (result)
223 break;
224 }
225 return result;
226 }
227
228 unittest
229 {
230 debug(apply) printf("_aApplyRcw1.unittest\n");
231
232 char[] s = "hello"c;
233 int i;
234
235 foreach_reverse(wchar d; s)
236 {
237 switch (i)
238 {
239 case 0: assert(d == 'o'); break;
240 case 1: assert(d == 'l'); break;
241 case 2: assert(d == 'l'); break;
242 case 3: assert(d == 'e'); break;
243 case 4: assert(d == 'h'); break;
244 default: assert(0);
245 }
246 i++;
247 }
248 assert(i == 5);
249
250 s = "a\u1234\U00100456b";
251 i = 0;
252 foreach_reverse(wchar d; s)
253 {
254 //printf("i = %d, d = %x\n", i, d);
255 switch (i)
256 {
257 case 0: assert(d == 'b'); break;
258 case 1: assert(d == 0xDBC1); break;
259 case 2: assert(d == 0xDC56); break;
260 case 3: assert(d == 0x1234); break;
261 case 4: assert(d == 'a'); break;
262 default: assert(0);
263 }
264 i++;
265 }
266 assert(i == 5);
267 }
268
269 /*****************************/
270
271 extern (C) int _aApplyRwc1(in wchar[] aa, dg_t dg)
272 { int result;
273
274 debug(apply) printf("_aApplyRwc1(), len = %d\n", aa.length);
275 for (size_t i = aa.length; i != 0; )
276 { dchar d;
277 char c;
278
279 i--;
280 d = aa[i];
281 if (d >= 0xDC00 && d <= 0xDFFF)
282 { if (i == 0)
283 onUnicodeError("Invalid UTF-16 sequence", 0);
284 i--;
285 d = ((aa[i] - 0xD7C0) << 10) + (d - 0xDC00);
286 }
287
288 if (d & ~0x7F)
289 {
290 char[4] buf;
291
292 auto b = toUTF8(buf, d);
293 foreach (char c2; b)
294 {
295 result = dg(cast(void *)&c2);
296 if (result)
297 return result;
298 }
299 continue;
300 }
301 c = cast(char)d;
302 result = dg(cast(void *)&c);
303 if (result)
304 break;
305 }
306 return result;
307 }
308
309 unittest
310 {
311 debug(apply) printf("_aApplyRwc1.unittest\n");
312
313 wchar[] s = "hello"w;
314 int i;
315
316 foreach_reverse(char d; s)
317 {
318 switch (i)
319 {
320 case 0: assert(d == 'o'); break;
321 case 1: assert(d == 'l'); break;
322 case 2: assert(d == 'l'); break;
323 case 3: assert(d == 'e'); break;
324 case 4: assert(d == 'h'); break;
325 default: assert(0);
326 }
327 i++;
328 }
329 assert(i == 5);
330
331 s = "a\u1234\U00100456b";
332 i = 0;
333 foreach_reverse(char d; s)
334 {
335 //printf("i = %d, d = %x\n", i, d);
336 switch (i)
337 {
338 case 0: assert(d == 'b'); break;
339 case 1: assert(d == 0xF4); break;
340 case 2: assert(d == 0x80); break;
341 case 3: assert(d == 0x91); break;
342 case 4: assert(d == 0x96); break;
343 case 5: assert(d == 0xE1); break;
344 case 6: assert(d == 0x88); break;
345 case 7: assert(d == 0xB4); break;
346 case 8: assert(d == 'a'); break;
347 default: assert(0);
348 }
349 i++;
350 }
351 assert(i == 9);
352 }
353
354 /*****************************/
355
356 extern (C) int _aApplyRdc1(in dchar[] aa, dg_t dg)
357 { int result;
358
359 debug(apply) printf("_aApplyRdc1(), len = %d\n", aa.length);
360 for (size_t i = aa.length; i != 0;)
361 { dchar d = aa[--i];
362 char c;
363
364 if (d & ~0x7F)
365 {
366 char[4] buf;
367
368 auto b = toUTF8(buf, d);
369 foreach (char c2; b)
370 {
371 result = dg(cast(void *)&c2);
372 if (result)
373 return result;
374 }
375 continue;
376 }
377 else
378 {
379 c = cast(char)d;
380 }
381 result = dg(cast(void *)&c);
382 if (result)
383 break;
384 }
385 return result;
386 }
387
388 unittest
389 {
390 debug(apply) printf("_aApplyRdc1.unittest\n");
391
392 dchar[] s = "hello"d;
393 int i;
394
395 foreach_reverse(char d; s)
396 {
397 switch (i)
398 {
399 case 0: assert(d == 'o'); break;
400 case 1: assert(d == 'l'); break;
401 case 2: assert(d == 'l'); break;
402 case 3: assert(d == 'e'); break;
403 case 4: assert(d == 'h'); break;
404 default: assert(0);
405 }
406 i++;
407 }
408 assert(i == 5);
409
410 s = "a\u1234\U00100456b";
411 i = 0;
412 foreach_reverse(char d; s)
413 {
414 //printf("i = %d, d = %x\n", i, d);
415 switch (i)
416 {
417 case 0: assert(d == 'b'); break;
418 case 1: assert(d == 0xF4); break;
419 case 2: assert(d == 0x80); break;
420 case 3: assert(d == 0x91); break;
421 case 4: assert(d == 0x96); break;
422 case 5: assert(d == 0xE1); break;
423 case 6: assert(d == 0x88); break;
424 case 7: assert(d == 0xB4); break;
425 case 8: assert(d == 'a'); break;
426 default: assert(0);
427 }
428 i++;
429 }
430 assert(i == 9);
431 }
432
433 /*****************************/
434
435 extern (C) int _aApplyRdw1(in dchar[] aa, dg_t dg)
436 { int result;
437
438 debug(apply) printf("_aApplyRdw1(), len = %d\n", aa.length);
439 for (size_t i = aa.length; i != 0; )
440 { dchar d = aa[--i];
441 wchar w;
442
443 if (d <= 0xFFFF)
444 w = cast(wchar) d;
445 else
446 {
447 w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
448 result = dg(cast(void *)&w);
449 if (result)
450 break;
451 w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);
452 }
453 result = dg(cast(void *)&w);
454 if (result)
455 break;
456 }
457 return result;
458 }
459
460 unittest
461 {
462 debug(apply) printf("_aApplyRdw1.unittest\n");
463
464 dchar[] s = "hello"d;
465 int i;
466
467 foreach_reverse(wchar d; s)
468 {
469 switch (i)
470 {
471 case 0: assert(d == 'o'); break;
472 case 1: assert(d == 'l'); break;
473 case 2: assert(d == 'l'); break;
474 case 3: assert(d == 'e'); break;
475 case 4: assert(d == 'h'); break;
476 default: assert(0);
477 }
478 i++;
479 }
480 assert(i == 5);
481
482 s = "a\u1234\U00100456b";
483 i = 0;
484 foreach_reverse(wchar d; s)
485 {
486 //printf("i = %d, d = %x\n", i, d);
487 switch (i)
488 {
489 case 0: assert(d == 'b'); break;
490 case 1: assert(d == 0xDBC1); break;
491 case 2: assert(d == 0xDC56); break;
492 case 3: assert(d == 0x1234); break;
493 case 4: assert(d == 'a'); break;
494 default: assert(0);
495 }
496 i++;
497 }
498 assert(i == 5);
499 }
500
501
502 /****************************************************************************/
503 /* 2 argument versions */
504
505 // dg is D, but _aApplyRcd2() is C
506 extern (D) typedef int delegate(void *, void *) dg2_t;
507
508 extern (C) int _aApplyRcd2(in char[] aa, dg2_t dg)
509 { int result;
510 size_t i;
511 size_t len = aa.length;
512
513 debug(apply) printf("_aApplyRcd2(), len = %d\n", len);
514 for (i = len; i != 0; )
515 { dchar d;
516
517 i--;
518 d = aa[i];
519 if (d & 0x80)
520 { char c = cast(char)d;
521 uint j;
522 uint m = 0x3F;
523 d = 0;
524 while ((c & 0xC0) != 0xC0)
525 { if (i == 0)
526 onUnicodeError("Invalid UTF-8 sequence", 0);
527 i--;
528 d |= (c & 0x3F) << j;
529 j += 6;
530 m >>= 1;
531 c = aa[i];
532 }
533 d |= (c & m) << j;
534 }
535 result = dg(&i, cast(void *)&d);
536 if (result)
537 break;
538 }
539 return result;
540 }
541
542 unittest
543 {
544 debug(apply) printf("_aApplyRcd2.unittest\n");
545
546 char[] s = "hello"c;
547 int i;
548
549 foreach_reverse(k, dchar d; s)
550 {
551 assert(k == 4 - i);
552 switch (i)
553 {
554 case 0: assert(d == 'o'); break;
555 case 1: assert(d == 'l'); break;
556 case 2: assert(d == 'l'); break;
557 case 3: assert(d == 'e'); break;
558 case 4: assert(d == 'h'); break;
559 default: assert(0);
560 }
561 i++;
562 }
563 assert(i == 5);
564
565 s = "a\u1234\U00100456b";
566 i = 0;
567 foreach_reverse(k, dchar d; s)
568 {
569 //printf("i = %d, k = %d, d = %x\n", i, k, d);
570 switch (i)
571 {
572 case 0: assert(d == 'b'); assert(k == 8); break;
573 case 1: assert(d == '\U00100456'); assert(k == 4); break;
574 case 2: assert(d == '\u1234'); assert(k == 1); break;
575 case 3: assert(d == 'a'); assert(k == 0); break;
576 default: assert(0);
577 }
578 i++;
579 }
580 assert(i == 4);
581 }
582
583 /*****************************/
584
585 extern (C) int _aApplyRwd2(in wchar[] aa, dg2_t dg)
586 { int result;
587
588 debug(apply) printf("_aApplyRwd2(), len = %d\n", aa.length);
589 for (size_t i = aa.length; i != 0; )
590 { dchar d;
591
592 i--;
593 d = aa[i];
594 if (d >= 0xDC00 && d <= 0xDFFF)
595 { if (i == 0)
596 onUnicodeError("Invalid UTF-16 sequence", 0);
597 i--;
598 d = ((aa[i] - 0xD7C0) << 10) + (d - 0xDC00);
599 }
600 result = dg(&i, cast(void *)&d);
601 if (result)
602 break;
603 }
604 return result;
605 }
606
607 unittest
608 {
609 debug(apply) printf("_aApplyRwd2.unittest\n");
610
611 wchar[] s = "hello"w;
612 int i;
613
614 foreach_reverse(k, dchar d; s)
615 {
616 //printf("i = %d, k = %d, d = %x\n", i, k, d);
617 assert(k == 4 - i);
618 switch (i)
619 {
620 case 0: assert(d == 'o'); break;
621 case 1: assert(d == 'l'); break;
622 case 2: assert(d == 'l'); break;
623 case 3: assert(d == 'e'); break;
624 case 4: assert(d == 'h'); break;
625 default: assert(0);
626 }
627 i++;
628 }
629 assert(i == 5);
630
631 s = "a\u1234\U00100456b";
632 i = 0;
633 foreach_reverse(k, dchar d; s)
634 {
635 //printf("i = %d, k = %d, d = %x\n", i, k, d);
636 switch (i)
637 {
638 case 0: assert(k == 4); assert(d == 'b'); break;
639 case 1: assert(k == 2); assert(d == '\U00100456'); break;
640 case 2: assert(k == 1); assert(d == '\u1234'); break;
641 case 3: assert(k == 0); assert(d == 'a'); break;
642 default: assert(0);
643 }
644 i++;
645 }
646 assert(i == 4);
647 }
648
649 /*****************************/
650
651 extern (C) int _aApplyRcw2(in char[] aa, dg2_t dg)
652 { int result;
653
654 debug(apply) printf("_aApplyRcw2(), len = %d\n", aa.length);
655 for (size_t i = aa.length; i != 0; )
656 { dchar d;
657 wchar w;
658
659 i--;
660 w = aa[i];
661 if (w & 0x80)
662 { char c = cast(char)w;
663 uint j;
664 uint m = 0x3F;
665 d = 0;
666 while ((c & 0xC0) != 0xC0)
667 { if (i == 0)
668 onUnicodeError("Invalid UTF-8 sequence", 0);
669 i--;
670 d |= (c & 0x3F) << j;
671 j += 6;
672 m >>= 1;
673 c = aa[i];
674 }
675 d |= (c & m) << j;
676
677 if (d <= 0xFFFF)
678 w = cast(wchar) d;
679 else
680 {
681 w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
682 result = dg(&i, cast(void *)&w);
683 if (result)
684 break;
685 w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);
686 }
687 }
688 result = dg(&i, cast(void *)&w);
689 if (result)
690 break;
691 }
692 return result;
693 }
694
695 unittest
696 {
697 debug(apply) printf("_aApplyRcw2.unittest\n");
698
699 char[] s = "hello"c;
700 int i;
701
702 foreach_reverse(k, wchar d; s)
703 {
704 //printf("i = %d, k = %d, d = %x\n", i, k, d);
705 assert(k == 4 - i);
706 switch (i)
707 {
708 case 0: assert(d == 'o'); break;
709 case 1: assert(d == 'l'); break;
710 case 2: assert(d == 'l'); break;
711 case 3: assert(d == 'e'); break;
712 case 4: assert(d == 'h'); break;
713 default: assert(0);
714 }
715 i++;
716 }
717 assert(i == 5);
718
719 s = "a\u1234\U00100456b";
720 i = 0;
721 foreach_reverse(k, wchar d; s)
722 {
723 //printf("i = %d, k = %d, d = %x\n", i, k, d);
724 switch (i)
725 {
726 case 0: assert(k == 8); assert(d == 'b'); break;
727 case 1: assert(k == 4); assert(d == 0xDBC1); break;
728 case 2: assert(k == 4); assert(d == 0xDC56); break;
729 case 3: assert(k == 1); assert(d == 0x1234); break;
730 case 4: assert(k == 0); assert(d == 'a'); break;
731 default: assert(0);
732 }
733 i++;
734 }
735 assert(i == 5);
736 }
737
738 /*****************************/
739
740 extern (C) int _aApplyRwc2(in wchar[] aa, dg2_t dg)
741 { int result;
742
743 debug(apply) printf("_aApplyRwc2(), len = %d\n", aa.length);
744 for (size_t i = aa.length; i != 0; )
745 { dchar d;
746 char c;
747
748 i--;
749 d = aa[i];
750 if (d >= 0xDC00 && d <= 0xDFFF)
751 { if (i == 0)
752 onUnicodeError("Invalid UTF-16 sequence", 0);
753 i--;
754 d = ((aa[i] - 0xD7C0) << 10) + (d - 0xDC00);
755 }
756
757 if (d & ~0x7F)
758 {
759 char[4] buf;
760
761 auto b = toUTF8(buf, d);
762 foreach (char c2; b)
763 {
764 result = dg(&i, cast(void *)&c2);
765 if (result)
766 return result;
767 }
768 continue;
769 }
770 c = cast(char)d;
771 result = dg(&i, cast(void *)&c);
772 if (result)
773 break;
774 }
775 return result;
776 }
777
778 unittest
779 {
780 debug(apply) printf("_aApplyRwc2.unittest\n");
781
782 wchar[] s = "hello"w;
783 int i;
784
785 foreach_reverse(k, char d; s)
786 {
787 //printf("i = %d, k = %d, d = %x\n", i, k, d);
788 assert(k == 4 - i);
789 switch (i)
790 {
791 case 0: assert(d == 'o'); break;
792 case 1: assert(d == 'l'); break;
793 case 2: assert(d == 'l'); break;
794 case 3: assert(d == 'e'); break;
795 case 4: assert(d == 'h'); break;
796 default: assert(0);
797 }
798 i++;
799 }
800 assert(i == 5);
801
802 s = "a\u1234\U00100456b";
803 i = 0;
804 foreach_reverse(k, char d; s)
805 {
806 //printf("i = %d, k = %d, d = %x\n", i, k, d);
807 switch (i)
808 {
809 case 0: assert(k == 4); assert(d == 'b'); break;
810 case 1: assert(k == 2); assert(d == 0xF4); break;
811 case 2: assert(k == 2); assert(d == 0x80); break;
812 case 3: assert(k == 2); assert(d == 0x91); break;
813 case 4: assert(k == 2); assert(d == 0x96); break;
814 case 5: assert(k == 1); assert(d == 0xE1); break;
815 case 6: assert(k == 1); assert(d == 0x88); break;
816 case 7: assert(k == 1); assert(d == 0xB4); break;
817 case 8: assert(k == 0); assert(d == 'a'); break;
818 default: assert(0);
819 }
820 i++;
821 }
822 assert(i == 9);
823 }
824
825 /*****************************/
826
827 extern (C) int _aApplyRdc2(in dchar[] aa, dg2_t dg)
828 { int result;
829
830 debug(apply) printf("_aApplyRdc2(), len = %d\n", aa.length);
831 for (size_t i = aa.length; i != 0; )
832 { dchar d = aa[--i];
833 char c;
834
835 if (d & ~0x7F)
836 {
837 char[4] buf;
838
839 auto b = toUTF8(buf, d);
840 foreach (char c2; b)
841 {
842 result = dg(&i, cast(void *)&c2);
843 if (result)
844 return result;
845 }
846 continue;
847 }
848 else
849 { c = cast(char)d;
850 }
851 result = dg(&i, cast(void *)&c);
852 if (result)
853 break;
854 }
855 return result;
856 }
857
858 unittest
859 {
860 debug(apply) printf("_aApplyRdc2.unittest\n");
861
862 dchar[] s = "hello"d;
863 int i;
864
865 foreach_reverse(k, char d; s)
866 {
867 //printf("i = %d, k = %d, d = %x\n", i, k, d);
868 assert(k == 4 - i);
869 switch (i)
870 {
871 case 0: assert(d == 'o'); break;
872 case 1: assert(d == 'l'); break;
873 case 2: assert(d == 'l'); break;
874 case 3: assert(d == 'e'); break;
875 case 4: assert(d == 'h'); break;
876 default: assert(0);
877 }
878 i++;
879 }
880 assert(i == 5);
881
882 s = "a\u1234\U00100456b";
883 i = 0;
884 foreach_reverse(k, char d; s)
885 {
886 //printf("i = %d, k = %d, d = %x\n", i, k, d);
887 switch (i)
888 {
889 case 0: assert(k == 3); assert(d == 'b'); break;
890 case 1: assert(k == 2); assert(d == 0xF4); break;
891 case 2: assert(k == 2); assert(d == 0x80); break;
892 case 3: assert(k == 2); assert(d == 0x91); break;
893 case 4: assert(k == 2); assert(d == 0x96); break;
894 case 5: assert(k == 1); assert(d == 0xE1); break;
895 case 6: assert(k == 1); assert(d == 0x88); break;
896 case 7: assert(k == 1); assert(d == 0xB4); break;
897 case 8: assert(k == 0); assert(d == 'a'); break;
898 default: assert(0);
899 }
900 i++;
901 }
902 assert(i == 9);
903 }
904
905 /*****************************/
906
907 extern (C) int _aApplyRdw2(in dchar[] aa, dg2_t dg)
908 { int result;
909
910 debug(apply) printf("_aApplyRdw2(), len = %d\n", aa.length);
911 for (size_t i = aa.length; i != 0; )
912 { dchar d = aa[--i];
913 wchar w;
914
915 if (d <= 0xFFFF)
916 w = cast(wchar) d;
917 else
918 {
919 w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
920 result = dg(&i, cast(void *)&w);
921 if (result)
922 break;
923 w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);
924 }
925 result = dg(&i, cast(void *)&w);
926 if (result)
927 break;
928 }
929 return result;
930 }
931
932 unittest
933 {
934 debug(apply) printf("_aApplyRdw2.unittest\n");
935
936 dchar[] s = "hello"d;
937 int i;
938
939 foreach_reverse(k, wchar d; s)
940 {
941 //printf("i = %d, k = %d, d = %x\n", i, k, d);
942 assert(k == 4 - i);
943 switch (i)
944 {
945 case 0: assert(d == 'o'); break;
946 case 1: assert(d == 'l'); break;
947 case 2: assert(d == 'l'); break;
948 case 3: assert(d == 'e'); break;
949 case 4: assert(d == 'h'); break;
950 default: assert(0);
951 }
952 i++;
953 }
954 assert(i == 5);
955
956 s = "a\u1234\U00100456b";
957 i = 0;
958 foreach_reverse(k, wchar d; s)
959 {
960 //printf("i = %d, k = %d, d = %x\n", i, k, d);
961 switch (i)
962 {
963 case 0: assert(k == 3); assert(d == 'b'); break;
964 case 1: assert(k == 2); assert(d == 0xDBC1); break;
965 case 2: assert(k == 2); assert(d == 0xDC56); break;
966 case 3: assert(k == 1); assert(d == 0x1234); break;
967 case 4: assert(k == 0); assert(d == 'a'); break;
968 default: assert(0);
969 }
970 i++;
971 }
972 assert(i == 5);
973 }
974
975