PageRenderTime 36ms CodeModel.GetById 10ms RepoModel.GetById 1ms app.codeStats 0ms

/src/rt/aApply.d

http://github.com/ldc-developers/druntime
D | 904 lines | 766 code | 94 blank | 44 comment | 265 complexity | 26d2e0e3b3a41e505f88520718918a8b MD5 | raw file
  1. /**
  2. * This code handles decoding UTF strings for foreach loops. There are 6
  3. * combinations of conversions between char, wchar, and dchar, and 2 of each
  4. * of those.
  5. *
  6. * Copyright: Copyright Digital Mars 2004 - 2010.
  7. * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
  8. * Authors: Walter Bright
  9. * Source: $(DRUNTIMESRC rt/_aApply.d)
  10. */
  11. module rt.aApply;
  12. import core.internal.utf : decode, toUTF8;
  13. /**********************************************/
  14. /* 1 argument versions */
  15. // dg is D, but _aApplycd() is C
  16. extern (D) alias int delegate(void *) dg_t;
  17. extern (C) int _aApplycd1(in char[] aa, dg_t dg)
  18. {
  19. int result;
  20. size_t len = aa.length;
  21. debug(apply) printf("_aApplycd1(), len = %d\n", len);
  22. for (size_t i = 0; i < len; )
  23. {
  24. dchar d = aa[i];
  25. if (d & 0x80)
  26. d = decode(aa, i);
  27. else
  28. ++i;
  29. result = dg(cast(void *)&d);
  30. if (result)
  31. break;
  32. }
  33. return result;
  34. }
  35. unittest
  36. {
  37. debug(apply) printf("_aApplycd1.unittest\n");
  38. auto s = "hello"c[];
  39. int i;
  40. foreach (dchar d; s)
  41. {
  42. switch (i)
  43. {
  44. case 0: assert(d == 'h'); break;
  45. case 1: assert(d == 'e'); break;
  46. case 2: assert(d == 'l'); break;
  47. case 3: assert(d == 'l'); break;
  48. case 4: assert(d == 'o'); break;
  49. default: assert(0);
  50. }
  51. i++;
  52. }
  53. assert(i == 5);
  54. s = "a\u1234\U000A0456b";
  55. i = 0;
  56. foreach (dchar d; s)
  57. {
  58. //printf("i = %d, d = %x\n", i, d);
  59. switch (i)
  60. {
  61. case 0: assert(d == 'a'); break;
  62. case 1: assert(d == '\u1234'); break;
  63. case 2: assert(d == '\U000A0456'); break;
  64. case 3: assert(d == 'b'); break;
  65. default: assert(0);
  66. }
  67. i++;
  68. }
  69. assert(i == 4);
  70. }
  71. /*****************************/
  72. extern (C) int _aApplywd1(in wchar[] aa, dg_t dg)
  73. {
  74. int result;
  75. size_t len = aa.length;
  76. debug(apply) printf("_aApplywd1(), len = %d\n", len);
  77. for (size_t i = 0; i < len; )
  78. {
  79. dchar d = aa[i];
  80. if (d >= 0xD800)
  81. d = decode(aa, i);
  82. else
  83. ++i;
  84. result = dg(cast(void *)&d);
  85. if (result)
  86. break;
  87. }
  88. return result;
  89. }
  90. unittest
  91. {
  92. debug(apply) printf("_aApplywd1.unittest\n");
  93. auto s = "hello"w[];
  94. int i;
  95. foreach (dchar d; s)
  96. {
  97. switch (i)
  98. {
  99. case 0: assert(d == 'h'); break;
  100. case 1: assert(d == 'e'); break;
  101. case 2: assert(d == 'l'); break;
  102. case 3: assert(d == 'l'); break;
  103. case 4: assert(d == 'o'); break;
  104. default: assert(0);
  105. }
  106. i++;
  107. }
  108. assert(i == 5);
  109. s = "a\u1234\U000A0456b";
  110. i = 0;
  111. foreach (dchar d; s)
  112. {
  113. //printf("i = %d, d = %x\n", i, d);
  114. switch (i)
  115. {
  116. case 0: assert(d == 'a'); break;
  117. case 1: assert(d == '\u1234'); break;
  118. case 2: assert(d == '\U000A0456'); break;
  119. case 3: assert(d == 'b'); break;
  120. default: assert(0);
  121. }
  122. i++;
  123. }
  124. assert(i == 4);
  125. }
  126. /*****************************/
  127. extern (C) int _aApplycw1(in char[] aa, dg_t dg)
  128. {
  129. int result;
  130. size_t len = aa.length;
  131. debug(apply) printf("_aApplycw1(), len = %d\n", len);
  132. for (size_t i = 0; i < len; )
  133. {
  134. wchar w = aa[i];
  135. if (w & 0x80)
  136. {
  137. dchar d = decode(aa, i);
  138. if (d <= 0xFFFF)
  139. w = cast(wchar) d;
  140. else
  141. {
  142. w = cast(wchar)((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
  143. result = dg(cast(void *)&w);
  144. if (result)
  145. break;
  146. w = cast(wchar)(((d - 0x10000) & 0x3FF) + 0xDC00);
  147. }
  148. }
  149. else
  150. ++i;
  151. result = dg(cast(void *)&w);
  152. if (result)
  153. break;
  154. }
  155. return result;
  156. }
  157. unittest
  158. {
  159. debug(apply) printf("_aApplycw1.unittest\n");
  160. auto s = "hello"c[];
  161. int i;
  162. foreach (wchar d; s)
  163. {
  164. switch (i)
  165. {
  166. case 0: assert(d == 'h'); break;
  167. case 1: assert(d == 'e'); break;
  168. case 2: assert(d == 'l'); break;
  169. case 3: assert(d == 'l'); break;
  170. case 4: assert(d == 'o'); break;
  171. default: assert(0);
  172. }
  173. i++;
  174. }
  175. assert(i == 5);
  176. s = "a\u1234\U000A0456b";
  177. i = 0;
  178. foreach (wchar d; s)
  179. {
  180. //printf("i = %d, d = %x\n", i, d);
  181. switch (i)
  182. {
  183. case 0: assert(d == 'a'); break;
  184. case 1: assert(d == 0x1234); break;
  185. case 2: assert(d == 0xDA41); break;
  186. case 3: assert(d == 0xDC56); break;
  187. case 4: assert(d == 'b'); break;
  188. default: assert(0);
  189. }
  190. i++;
  191. }
  192. assert(i == 5);
  193. }
  194. /*****************************/
  195. extern (C) int _aApplywc1(in wchar[] aa, dg_t dg)
  196. {
  197. int result;
  198. size_t len = aa.length;
  199. debug(apply) printf("_aApplywc1(), len = %d\n", len);
  200. for (size_t i = 0; i < len; )
  201. {
  202. wchar w = aa[i];
  203. if (w & ~0x7F)
  204. {
  205. char[4] buf = void;
  206. dchar d = decode(aa, i);
  207. auto b = toUTF8(buf, d);
  208. foreach (char c2; b)
  209. {
  210. result = dg(cast(void *)&c2);
  211. if (result)
  212. return result;
  213. }
  214. }
  215. else
  216. {
  217. char c = cast(char)w;
  218. ++i;
  219. result = dg(cast(void *)&c);
  220. if (result)
  221. break;
  222. }
  223. }
  224. return result;
  225. }
  226. unittest
  227. {
  228. debug(apply) printf("_aApplywc1.unittest\n");
  229. auto s = "hello"w[];
  230. int i;
  231. foreach (char d; s)
  232. {
  233. switch (i)
  234. {
  235. case 0: assert(d == 'h'); break;
  236. case 1: assert(d == 'e'); break;
  237. case 2: assert(d == 'l'); break;
  238. case 3: assert(d == 'l'); break;
  239. case 4: assert(d == 'o'); break;
  240. default: assert(0);
  241. }
  242. i++;
  243. }
  244. assert(i == 5);
  245. s = "a\u1234\U000A0456b";
  246. i = 0;
  247. foreach (char d; s)
  248. {
  249. //printf("i = %d, d = %x\n", i, d);
  250. switch (i)
  251. {
  252. case 0: assert(d == 'a'); break;
  253. case 1: assert(d == 0xE1); break;
  254. case 2: assert(d == 0x88); break;
  255. case 3: assert(d == 0xB4); break;
  256. case 4: assert(d == 0xF2); break;
  257. case 5: assert(d == 0xA0); break;
  258. case 6: assert(d == 0x91); break;
  259. case 7: assert(d == 0x96); break;
  260. case 8: assert(d == 'b'); break;
  261. default: assert(0);
  262. }
  263. i++;
  264. }
  265. assert(i == 9);
  266. }
  267. /*****************************/
  268. extern (C) int _aApplydc1(in dchar[] aa, dg_t dg)
  269. {
  270. int result;
  271. debug(apply) printf("_aApplydc1(), len = %d\n", aa.length);
  272. foreach (dchar d; aa)
  273. {
  274. if (d & ~0x7F)
  275. {
  276. char[4] buf = void;
  277. auto b = toUTF8(buf, d);
  278. foreach (char c2; b)
  279. {
  280. result = dg(cast(void *)&c2);
  281. if (result)
  282. return result;
  283. }
  284. }
  285. else
  286. {
  287. char c = cast(char)d;
  288. result = dg(cast(void *)&c);
  289. if (result)
  290. break;
  291. }
  292. }
  293. return result;
  294. }
  295. unittest
  296. {
  297. debug(apply) printf("_aApplyRdc1.unittest\n");
  298. auto s = "hello"d[];
  299. int i;
  300. foreach (char d; s)
  301. {
  302. switch (i)
  303. {
  304. case 0: assert(d == 'h'); break;
  305. case 1: assert(d == 'e'); break;
  306. case 2: assert(d == 'l'); break;
  307. case 3: assert(d == 'l'); break;
  308. case 4: assert(d == 'o'); break;
  309. default: assert(0);
  310. }
  311. i++;
  312. }
  313. assert(i == 5);
  314. s = "a\u1234\U000A0456b";
  315. i = 0;
  316. foreach (char d; s)
  317. {
  318. //printf("i = %d, d = %x\n", i, d);
  319. switch (i)
  320. {
  321. case 0: assert(d == 'a'); break;
  322. case 1: assert(d == 0xE1); break;
  323. case 2: assert(d == 0x88); break;
  324. case 3: assert(d == 0xB4); break;
  325. case 4: assert(d == 0xF2); break;
  326. case 5: assert(d == 0xA0); break;
  327. case 6: assert(d == 0x91); break;
  328. case 7: assert(d == 0x96); break;
  329. case 8: assert(d == 'b'); break;
  330. default: assert(0);
  331. }
  332. i++;
  333. }
  334. assert(i == 9);
  335. }
  336. /*****************************/
  337. extern (C) int _aApplydw1(in dchar[] aa, dg_t dg)
  338. {
  339. int result;
  340. debug(apply) printf("_aApplydw1(), len = %d\n", aa.length);
  341. foreach (dchar d; aa)
  342. {
  343. wchar w;
  344. if (d <= 0xFFFF)
  345. w = cast(wchar) d;
  346. else
  347. {
  348. w = cast(wchar)((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
  349. result = dg(cast(void *)&w);
  350. if (result)
  351. break;
  352. w = cast(wchar)(((d - 0x10000) & 0x3FF) + 0xDC00);
  353. }
  354. result = dg(cast(void *)&w);
  355. if (result)
  356. break;
  357. }
  358. return result;
  359. }
  360. unittest
  361. {
  362. debug(apply) printf("_aApplydw1.unittest\n");
  363. auto s = "hello"d[];
  364. int i;
  365. foreach (wchar d; s)
  366. {
  367. switch (i)
  368. {
  369. case 0: assert(d == 'h'); break;
  370. case 1: assert(d == 'e'); break;
  371. case 2: assert(d == 'l'); break;
  372. case 3: assert(d == 'l'); break;
  373. case 4: assert(d == 'o'); break;
  374. default: assert(0);
  375. }
  376. i++;
  377. }
  378. assert(i == 5);
  379. s = "a\u1234\U000A0456b";
  380. i = 0;
  381. foreach (wchar d; s)
  382. {
  383. //printf("i = %d, d = %x\n", i, d);
  384. switch (i)
  385. {
  386. case 0: assert(d == 'a'); break;
  387. case 1: assert(d == 0x1234); break;
  388. case 2: assert(d == 0xDA41); break;
  389. case 3: assert(d == 0xDC56); break;
  390. case 4: assert(d == 'b'); break;
  391. default: assert(0);
  392. }
  393. i++;
  394. }
  395. assert(i == 5);
  396. }
  397. /****************************************************************************/
  398. /* 2 argument versions */
  399. // dg is D, but _aApplycd2() is C
  400. extern (D) alias int delegate(void *, void *) dg2_t;
  401. extern (C) int _aApplycd2(in char[] aa, dg2_t dg)
  402. {
  403. int result;
  404. size_t len = aa.length;
  405. debug(apply) printf("_aApplycd2(), len = %d\n", len);
  406. size_t n;
  407. for (size_t i = 0; i < len; i += n)
  408. {
  409. dchar d = aa[i];
  410. if (d & 0x80)
  411. {
  412. n = i;
  413. d = decode(aa, n);
  414. n -= i;
  415. }
  416. else
  417. n = 1;
  418. result = dg(&i, cast(void *)&d);
  419. if (result)
  420. break;
  421. }
  422. return result;
  423. }
  424. unittest
  425. {
  426. debug(apply) printf("_aApplycd2.unittest\n");
  427. auto s = "hello"c[];
  428. int i;
  429. foreach (k, dchar d; s)
  430. {
  431. //printf("i = %d, k = %d, d = %x\n", i, k, d);
  432. assert(k == i);
  433. switch (i)
  434. {
  435. case 0: assert(d == 'h'); break;
  436. case 1: assert(d == 'e'); break;
  437. case 2: assert(d == 'l'); break;
  438. case 3: assert(d == 'l'); break;
  439. case 4: assert(d == 'o'); break;
  440. default: assert(0);
  441. }
  442. i++;
  443. }
  444. assert(i == 5);
  445. s = "a\u1234\U000A0456b";
  446. i = 0;
  447. foreach (k, dchar d; s)
  448. {
  449. //printf("i = %d, k = %d, d = %x\n", i, k, d);
  450. switch (i)
  451. {
  452. case 0: assert(d == 'a'); assert(k == 0); break;
  453. case 1: assert(d == '\u1234'); assert(k == 1); break;
  454. case 2: assert(d == '\U000A0456'); assert(k == 4); break;
  455. case 3: assert(d == 'b'); assert(k == 8); break;
  456. default: assert(0);
  457. }
  458. i++;
  459. }
  460. assert(i == 4);
  461. }
  462. /*****************************/
  463. extern (C) int _aApplywd2(in wchar[] aa, dg2_t dg)
  464. {
  465. int result;
  466. size_t len = aa.length;
  467. debug(apply) printf("_aApplywd2(), len = %d\n", len);
  468. size_t n;
  469. for (size_t i = 0; i < len; i += n)
  470. {
  471. dchar d = aa[i];
  472. if (d & ~0x7F)
  473. {
  474. n = i;
  475. d = decode(aa, n);
  476. n -= i;
  477. }
  478. else
  479. n = 1;
  480. result = dg(&i, cast(void *)&d);
  481. if (result)
  482. break;
  483. }
  484. return result;
  485. }
  486. unittest
  487. {
  488. debug(apply) printf("_aApplywd2.unittest\n");
  489. auto s = "hello"w[];
  490. int i;
  491. foreach (k, dchar d; s)
  492. {
  493. //printf("i = %d, k = %d, d = %x\n", i, k, d);
  494. assert(k == i);
  495. switch (i)
  496. {
  497. case 0: assert(d == 'h'); break;
  498. case 1: assert(d == 'e'); break;
  499. case 2: assert(d == 'l'); break;
  500. case 3: assert(d == 'l'); break;
  501. case 4: assert(d == 'o'); break;
  502. default: assert(0);
  503. }
  504. i++;
  505. }
  506. assert(i == 5);
  507. s = "a\u1234\U000A0456b";
  508. i = 0;
  509. foreach (k, dchar d; s)
  510. {
  511. //printf("i = %d, k = %d, d = %x\n", i, k, d);
  512. switch (i)
  513. {
  514. case 0: assert(k == 0); assert(d == 'a'); break;
  515. case 1: assert(k == 1); assert(d == '\u1234'); break;
  516. case 2: assert(k == 2); assert(d == '\U000A0456'); break;
  517. case 3: assert(k == 4); assert(d == 'b'); break;
  518. default: assert(0);
  519. }
  520. i++;
  521. }
  522. assert(i == 4);
  523. }
  524. /*****************************/
  525. extern (C) int _aApplycw2(in char[] aa, dg2_t dg)
  526. {
  527. int result;
  528. size_t len = aa.length;
  529. debug(apply) printf("_aApplycw2(), len = %d\n", len);
  530. size_t n;
  531. for (size_t i = 0; i < len; i += n)
  532. {
  533. wchar w = aa[i];
  534. if (w & 0x80)
  535. {
  536. n = i;
  537. dchar d = decode(aa, n);
  538. n -= i;
  539. if (d <= 0xFFFF)
  540. w = cast(wchar) d;
  541. else
  542. {
  543. w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
  544. result = dg(&i, cast(void *)&w);
  545. if (result)
  546. break;
  547. w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);
  548. }
  549. }
  550. else
  551. n = 1;
  552. result = dg(&i, cast(void *)&w);
  553. if (result)
  554. break;
  555. }
  556. return result;
  557. }
  558. unittest
  559. {
  560. debug(apply) printf("_aApplycw2.unittest\n");
  561. auto s = "hello"c[];
  562. int i;
  563. foreach (k, wchar d; s)
  564. {
  565. //printf("i = %d, k = %d, d = %x\n", i, k, d);
  566. assert(k == i);
  567. switch (i)
  568. {
  569. case 0: assert(d == 'h'); break;
  570. case 1: assert(d == 'e'); break;
  571. case 2: assert(d == 'l'); break;
  572. case 3: assert(d == 'l'); break;
  573. case 4: assert(d == 'o'); break;
  574. default: assert(0);
  575. }
  576. i++;
  577. }
  578. assert(i == 5);
  579. s = "a\u1234\U000A0456b";
  580. i = 0;
  581. foreach (k, wchar d; s)
  582. {
  583. //printf("i = %d, k = %d, d = %x\n", i, k, d);
  584. switch (i)
  585. {
  586. case 0: assert(k == 0); assert(d == 'a'); break;
  587. case 1: assert(k == 1); assert(d == 0x1234); break;
  588. case 2: assert(k == 4); assert(d == 0xDA41); break;
  589. case 3: assert(k == 4); assert(d == 0xDC56); break;
  590. case 4: assert(k == 8); assert(d == 'b'); break;
  591. default: assert(0);
  592. }
  593. i++;
  594. }
  595. assert(i == 5);
  596. }
  597. /*****************************/
  598. extern (C) int _aApplywc2(in wchar[] aa, dg2_t dg)
  599. {
  600. int result;
  601. size_t len = aa.length;
  602. debug(apply) printf("_aApplywc2(), len = %d\n", len);
  603. size_t n;
  604. for (size_t i = 0; i < len; i += n)
  605. {
  606. wchar w = aa[i];
  607. if (w & ~0x7F)
  608. {
  609. char[4] buf = void;
  610. n = i;
  611. dchar d = decode(aa, n);
  612. n -= i;
  613. auto b = toUTF8(buf, d);
  614. foreach (char c2; b)
  615. {
  616. result = dg(&i, cast(void *)&c2);
  617. if (result)
  618. return result;
  619. }
  620. }
  621. else
  622. {
  623. char c = cast(char)w;
  624. n = 1;
  625. result = dg(&i, cast(void *)&c);
  626. if (result)
  627. break;
  628. }
  629. }
  630. return result;
  631. }
  632. unittest
  633. {
  634. debug(apply) printf("_aApplywc2.unittest\n");
  635. auto s = "hello"w[];
  636. int i;
  637. foreach (k, char d; s)
  638. {
  639. //printf("i = %d, k = %d, d = %x\n", i, k, d);
  640. assert(k == i);
  641. switch (i)
  642. {
  643. case 0: assert(d == 'h'); break;
  644. case 1: assert(d == 'e'); break;
  645. case 2: assert(d == 'l'); break;
  646. case 3: assert(d == 'l'); break;
  647. case 4: assert(d == 'o'); break;
  648. default: assert(0);
  649. }
  650. i++;
  651. }
  652. assert(i == 5);
  653. s = "a\u1234\U000A0456b";
  654. i = 0;
  655. foreach (k, char d; s)
  656. {
  657. //printf("i = %d, k = %d, d = %x\n", i, k, d);
  658. switch (i)
  659. {
  660. case 0: assert(k == 0); assert(d == 'a'); break;
  661. case 1: assert(k == 1); assert(d == 0xE1); break;
  662. case 2: assert(k == 1); assert(d == 0x88); break;
  663. case 3: assert(k == 1); assert(d == 0xB4); break;
  664. case 4: assert(k == 2); assert(d == 0xF2); break;
  665. case 5: assert(k == 2); assert(d == 0xA0); break;
  666. case 6: assert(k == 2); assert(d == 0x91); break;
  667. case 7: assert(k == 2); assert(d == 0x96); break;
  668. case 8: assert(k == 4); assert(d == 'b'); break;
  669. default: assert(0);
  670. }
  671. i++;
  672. }
  673. assert(i == 9);
  674. }
  675. /*****************************/
  676. extern (C) int _aApplydc2(in dchar[] aa, dg2_t dg)
  677. {
  678. int result;
  679. size_t len = aa.length;
  680. debug(apply) printf("_aApplydc2(), len = %d\n", len);
  681. for (size_t i = 0; i < len; i++)
  682. {
  683. dchar d = aa[i];
  684. if (d & ~0x7F)
  685. {
  686. char[4] buf = void;
  687. auto b = toUTF8(buf, d);
  688. foreach (char c2; b)
  689. {
  690. result = dg(&i, cast(void *)&c2);
  691. if (result)
  692. return result;
  693. }
  694. }
  695. else
  696. {
  697. char c = cast(char)d;
  698. result = dg(&i, cast(void *)&c);
  699. if (result)
  700. break;
  701. }
  702. }
  703. return result;
  704. }
  705. unittest
  706. {
  707. debug(apply) printf("_aApplydc2.unittest\n");
  708. auto s = "hello"d[];
  709. int i;
  710. foreach (k, char d; s)
  711. {
  712. //printf("i = %d, k = %d, d = %x\n", i, k, d);
  713. assert(k == i);
  714. switch (i)
  715. {
  716. case 0: assert(d == 'h'); break;
  717. case 1: assert(d == 'e'); break;
  718. case 2: assert(d == 'l'); break;
  719. case 3: assert(d == 'l'); break;
  720. case 4: assert(d == 'o'); break;
  721. default: assert(0);
  722. }
  723. i++;
  724. }
  725. assert(i == 5);
  726. s = "a\u1234\U000A0456b";
  727. i = 0;
  728. foreach (k, char d; s)
  729. {
  730. //printf("i = %d, k = %d, d = %x\n", i, k, d);
  731. switch (i)
  732. {
  733. case 0: assert(k == 0); assert(d == 'a'); break;
  734. case 1: assert(k == 1); assert(d == 0xE1); break;
  735. case 2: assert(k == 1); assert(d == 0x88); break;
  736. case 3: assert(k == 1); assert(d == 0xB4); break;
  737. case 4: assert(k == 2); assert(d == 0xF2); break;
  738. case 5: assert(k == 2); assert(d == 0xA0); break;
  739. case 6: assert(k == 2); assert(d == 0x91); break;
  740. case 7: assert(k == 2); assert(d == 0x96); break;
  741. case 8: assert(k == 3); assert(d == 'b'); break;
  742. default: assert(0);
  743. }
  744. i++;
  745. }
  746. assert(i == 9);
  747. }
  748. /*****************************/
  749. extern (C) int _aApplydw2(in dchar[] aa, dg2_t dg)
  750. { int result;
  751. debug(apply) printf("_aApplydw2(), len = %d\n", aa.length);
  752. foreach (size_t i, dchar d; aa)
  753. {
  754. wchar w;
  755. auto j = i;
  756. if (d <= 0xFFFF)
  757. w = cast(wchar) d;
  758. else
  759. {
  760. w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
  761. result = dg(&j, cast(void *)&w);
  762. if (result)
  763. break;
  764. w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);
  765. }
  766. result = dg(&j, cast(void *)&w);
  767. if (result)
  768. break;
  769. }
  770. return result;
  771. }
  772. unittest
  773. {
  774. debug(apply) printf("_aApplydw2.unittest\n");
  775. auto s = "hello"d[];
  776. int i;
  777. foreach (k, wchar d; s)
  778. {
  779. //printf("i = %d, k = %d, d = %x\n", i, k, d);
  780. assert(k == i);
  781. switch (i)
  782. {
  783. case 0: assert(d == 'h'); break;
  784. case 1: assert(d == 'e'); break;
  785. case 2: assert(d == 'l'); break;
  786. case 3: assert(d == 'l'); break;
  787. case 4: assert(d == 'o'); break;
  788. default: assert(0);
  789. }
  790. i++;
  791. }
  792. assert(i == 5);
  793. s = "a\u1234\U000A0456b";
  794. i = 0;
  795. foreach (k, wchar d; s)
  796. {
  797. //printf("i = %d, k = %d, d = %x\n", i, k, d);
  798. switch (i)
  799. {
  800. case 0: assert(k == 0); assert(d == 'a'); break;
  801. case 1: assert(k == 1); assert(d == 0x1234); break;
  802. case 2: assert(k == 2); assert(d == 0xDA41); break;
  803. case 3: assert(k == 2); assert(d == 0xDC56); break;
  804. case 4: assert(k == 3); assert(d == 'b'); break;
  805. default: assert(0);
  806. }
  807. i++;
  808. }
  809. assert(i == 5);
  810. }