Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
ctype.cpp
Go to the documentation of this file.
1
27// expand _TEST_EXPORT macros
28#define _RWSTD_TEST_SRC
29
30#include <rw_ctype.h>
31
32#include <stdarg.h> // for va_arg(), va_list
33#include <string.h> // for memset()
34
35
37typedef unsigned char UChar;
38
39
41rw_vasnprintf (char**, size_t*, const char*, va_list);
42
43
44static void
45_rw_throw (const char *file, int line, const char *fmt, ...)
46{
47 _RWSTD_UNUSED (file);
49
51 char what_ [256];
52
53 /* virtual */ const char* what () const {
54 return what_;
55 }
56 };
57
58 Exception ex;
59
60 va_list va;
61 va_start (va, fmt);
62
63 char *buf = ex.what_;
64 size_t bufsize = sizeof ex.what_;
65 rw_vasnprintf (&buf, &bufsize, fmt, va);
66
67 va_end (va);
68
69 throw ex;
70}
71
72
74static const char* const
75_rw_func_names[] = {
76 "is(mask, char_type)",
77 "is(const char_type*, const char_type*, mask*)",
78 "scan_is(mask, const char_type*, const char_type*)",
79 "scan_not(mask, const char_type*, const char_type*)",
80 "to_upper(char_type)",
81 "to_upper(char_type*, const char_type*)",
82 "to_lower(char_type)",
83 "to_lower(char_type*, const char_type*)",
84 "widen(char)",
85 "widen(const char*, const char*, char_type*)",
86 "narrow(char_type, char)",
87 "narrow(const char_type*, const char_type*, char, char*)"
88};
89
90
94{
95 // no-op
96}
97
98
100static const unsigned
101_rw_char_masks [256] = {
102
103#define ALPHA std::ctype_base::alpha
104#define ALNUM std::ctype_base::alnum
105#define CNTRL std::ctype_base::cntrl
106#define DIGIT std::ctype_base::digit
107#define GRAPH std::ctype_base::graph
108#define LOWER std::ctype_base::lower
109#define PRINT std::ctype_base::print
110#define PUNCT std::ctype_base::punct
111#define SPACE std::ctype_base::space
112#define UPPER std::ctype_base::upper
113#define XDIGIT std::ctype_base::xdigit
114
115
116#undef LETTER
117#define LETTER(m) (PRINT | ALPHA | GRAPH | m)
118
119#if 'A' == 0x41 // ASCII
120
121 /* 0x00 NUL */ CNTRL,
122 /* 0x01 SOH */ CNTRL,
123 /* 0x02 STX */ CNTRL,
124 /* 0x03 ETX */ CNTRL,
125 /* 0x04 EOT */ CNTRL,
126 /* 0x05 ENQ */ CNTRL,
127 /* 0x06 ACK */ CNTRL,
128 /* '\a' BEL */ CNTRL,
129 /* 0x08 BS */ CNTRL,
130 /* '\t' TAB */ SPACE | CNTRL,
131 /* '\n' LF */ SPACE | CNTRL,
132 /* 0x0b VT */ SPACE | CNTRL,
133 /* '\f' FF */ SPACE | CNTRL,
134 /* '\r' CR */ SPACE | CNTRL,
135 /* 0x0e SO */ CNTRL,
136 /* 0x0f SI */ CNTRL,
137 /* 0x10 DLE */ CNTRL,
138 /* 0x11 DC1 */ CNTRL,
139 /* 0x12 DC2 */ CNTRL,
140 /* 0x13 DC3 */ CNTRL,
141 /* 0x14 DC4 */ CNTRL,
142 /* 0x15 NAK */ CNTRL,
143 /* 0x16 SYN */ CNTRL,
144 /* 0x17 ETB */ CNTRL,
145 /* 0x18 CAN */ CNTRL,
146 /* 0x19 EM */ CNTRL,
147 /* 0x1a SUB */ CNTRL,
148 /* 0x1b ESC */ CNTRL,
149 /* 0x1c FS */ CNTRL,
150 /* 0x1d GS */ CNTRL,
151 /* 0x1e RS */ CNTRL,
152 /* 0x1f US */ CNTRL,
153 /* ' ' */ SPACE | PRINT,
154 /* '!' */ PRINT | PUNCT | GRAPH,
155 /* '"' */ PRINT | PUNCT | GRAPH,
156 /* '#' */ PRINT | PUNCT | GRAPH,
157 /* '$' */ PRINT | PUNCT | GRAPH,
158 /* '%' */ PRINT | PUNCT | GRAPH,
159 /* '&' */ PRINT | PUNCT | GRAPH,
160 /* '\'' */ PRINT | PUNCT | GRAPH,
161 /* '(' */ PRINT | PUNCT | GRAPH,
162 /* ')' */ PRINT | PUNCT | GRAPH,
163 /* '*' */ PRINT | PUNCT | GRAPH,
164 /* '+' */ PRINT | PUNCT | GRAPH,
165 /* ',' */ PRINT | PUNCT | GRAPH,
166 /* '-' */ PRINT | PUNCT | GRAPH,
167 /* '.' */ PRINT | PUNCT | GRAPH,
168 /* '/' */ PRINT | PUNCT | GRAPH,
169 /* '0' */ PRINT | DIGIT | GRAPH | XDIGIT,
170 /* '1' */ PRINT | DIGIT | GRAPH | XDIGIT,
171 /* '2' */ PRINT | DIGIT | GRAPH | XDIGIT,
172 /* '3' */ PRINT | DIGIT | GRAPH | XDIGIT,
173 /* '4' */ PRINT | DIGIT | GRAPH | XDIGIT,
174 /* '5' */ PRINT | DIGIT | GRAPH | XDIGIT,
175 /* '6' */ PRINT | DIGIT | GRAPH | XDIGIT,
176 /* '7' */ PRINT | DIGIT | GRAPH | XDIGIT,
177 /* '8' */ PRINT | DIGIT | GRAPH | XDIGIT,
178 /* '9' */ PRINT | DIGIT | GRAPH | XDIGIT,
179 /* ':' */ PRINT | PUNCT | GRAPH,
180 /* ';' */ PRINT | PUNCT | GRAPH,
181 /* '<' */ PRINT | PUNCT | GRAPH,
182 /* '=' */ PRINT | PUNCT | GRAPH,
183 /* '>' */ PRINT | PUNCT | GRAPH,
184 /* '?' */ PRINT | PUNCT | GRAPH,
185 /* '@' */ PRINT | PUNCT | GRAPH,
186
187 /* 'A' */ LETTER (UPPER | XDIGIT),
188 /* 'B' */ LETTER (UPPER | XDIGIT),
189 /* 'C' */ LETTER (UPPER | XDIGIT),
190 /* 'D' */ LETTER (UPPER | XDIGIT),
191 /* 'E' */ LETTER (UPPER | XDIGIT),
192 /* 'F' */ LETTER (UPPER | XDIGIT),
193 /* 'G' */ LETTER (UPPER),
194 /* 'H' */ LETTER (UPPER),
195 /* 'I' */ LETTER (UPPER),
196 /* 'J' */ LETTER (UPPER),
197 /* 'K' */ LETTER (UPPER),
198 /* 'L' */ LETTER (UPPER),
199 /* 'M' */ LETTER (UPPER),
200 /* 'N' */ LETTER (UPPER),
201 /* 'O' */ LETTER (UPPER),
202 /* 'P' */ LETTER (UPPER),
203 /* 'Q' */ LETTER (UPPER),
204 /* 'R' */ LETTER (UPPER),
205 /* 'S' */ LETTER (UPPER),
206 /* 'T' */ LETTER (UPPER),
207 /* 'U' */ LETTER (UPPER),
208 /* 'V' */ LETTER (UPPER),
209 /* 'W' */ LETTER (UPPER),
210 /* 'X' */ LETTER (UPPER),
211 /* 'Y' */ LETTER (UPPER),
212 /* 'Z' */ LETTER (UPPER),
213
214 /* '[' */ PRINT | PUNCT | GRAPH,
215 /* '\\' */ PRINT | PUNCT | GRAPH,
216 /* ']' */ PRINT | PUNCT | GRAPH,
217 /* '^' */ PRINT | PUNCT | GRAPH,
218 /* '_' */ PRINT | PUNCT | GRAPH,
219 /* '`' */ PRINT | PUNCT | GRAPH,
220
221 /* 'a' */ LETTER (LOWER | XDIGIT),
222 /* 'b' */ LETTER (LOWER | XDIGIT),
223 /* 'c' */ LETTER (LOWER | XDIGIT),
224 /* 'd' */ LETTER (LOWER | XDIGIT),
225 /* 'e' */ LETTER (LOWER | XDIGIT),
226 /* 'f' */ LETTER (LOWER | XDIGIT),
227 /* 'g' */ LETTER (LOWER),
228 /* 'h' */ LETTER (LOWER),
229 /* 'i' */ LETTER (LOWER),
230 /* 'j' */ LETTER (LOWER),
231 /* 'k' */ LETTER (LOWER),
232 /* 'l' */ LETTER (LOWER),
233 /* 'm' */ LETTER (LOWER),
234 /* 'n' */ LETTER (LOWER),
235 /* 'o' */ LETTER (LOWER),
236 /* 'p' */ LETTER (LOWER),
237 /* 'q' */ LETTER (LOWER),
238 /* 'r' */ LETTER (LOWER),
239 /* 's' */ LETTER (LOWER),
240 /* 't' */ LETTER (LOWER),
241 /* 'u' */ LETTER (LOWER),
242 /* 'v' */ LETTER (LOWER),
243 /* 'w' */ LETTER (LOWER),
244 /* 'x' */ LETTER (LOWER),
245 /* 'y' */ LETTER (LOWER),
246 /* 'z' */ LETTER (LOWER),
247
248 /* '{' */ PRINT | PUNCT | GRAPH,
249 /* '|' */ PRINT | PUNCT | GRAPH,
250 /* '}' */ PRINT | PUNCT | GRAPH,
251 /* '~' */ PRINT | PUNCT | GRAPH,
252 /* 0x7f DEL */ CNTRL
253
254#elif 'A' == 0xc1 // EBCDIC
255
256 /* NUL */ CNTRL,
257 /* SOH */ CNTRL,
258 /* STX */ CNTRL,
259 /* ETX */ CNTRL,
260 /* PF */ CNTRL,
261 /* HT */ CNTRL,
262 /* LC */ CNTRL,
263 /* DEL */ CNTRL,
264 /* */ 0,
265 /* */ 0,
266 /* SMM */ CNTRL,
267 /* VT */ SPACE | CNTRL,
268 /* FF */ SPACE | CNTRL,
269 /* CR */ SPACE | CNTRL,
270 /* SO */ CNTRL,
271 /* SI */ CNTRL,
272 /* DLE */ CNTRL,
273 /* DC1 */ CNTRL,
274 /* DC2 */ CNTRL,
275 /* TM */ CNTRL,
276 /* RES */ CNTRL,
277 /* NL */ CNTRL,
278 /* BS */ CNTRL,
279 /* IL */ CNTRL,
280 /* CAN */ CNTRL,
281 /* EM */ CNTRL,
282 /* CC */ CNTRL,
283 /* CU1 */ CNTRL,
284 /* IFS */ CNTRL,
285 /* IGS */ CNTRL,
286 /* IRS */ CNTRL,
287 /* IUS */ CNTRL,
288 /* DS */ CNTRL,
289 /* SOS */ CNTRL,
290 /* FS */ CNTRL,
291 /* */ 0,
292 /* BYP */ CNTRL,
293 /* LF */ SPACE | CNTRL,
294 /* ETB */ CNTRL,
295 /* ESC */ CNTRL,
296 /* */ 0,
297 /* */ 0,
298 /* SM */ CNTRL,
299 /* CU2 */ CNTRL,
300 /* */ 0,
301 /* ENQ */ CNTRL,
302 /* ACK */ CNTRL,
303 /* BEL */ CNTRL,
304 /* */ 0,
305 /* */ 0,
306 /* SYN */ CNTRL,
307 /* */ 0,
308 /* PN */ CNTRL,
309 /* RS */ CNTRL,
310 /* UC */ CNTRL,
311 /* EOT */ CNTRL,
312 /* */ 0,
313 /* */ 0,
314 /* */ 0,
315 /* CU3 */ CNTRL,
316 /* DC4 */ CNTRL,
317 /* NAK */ CNTRL,
318 /* */ 0,
319 /* SUB */ CNTRL,
320 /* ' ' */ SPACE | PRINT,
321 /* */ 0,
322 /* */ 0,
323 /* */ 0,
324 /* */ 0,
325 /* */ 0,
326 /* */ 0,
327 /* */ 0,
328 /* */ 0,
329 /* */ 0,
330 /* ct. */ PRINT | PUNCT | GRAPH,
331 /* '.' */ PRINT | PUNCT | GRAPH,
332 /* '<' */ PRINT | PUNCT | GRAPH,
333 /* '(' */ PRINT | PUNCT | GRAPH,
334 /* '+' */ PRINT | PUNCT | GRAPH,
335 /* '|' */ PRINT | PUNCT | GRAPH,
336 /* '&' */ PRINT | PUNCT | GRAPH,
337 /* */ 0,
338 /* */ 0,
339 /* */ 0,
340 /* */ 0,
341 /* */ 0,
342 /* */ 0,
343 /* */ 0,
344 /* */ 0,
345 /* */ 0,
346 /* '!' */ PRINT | PUNCT | GRAPH,
347 /* '$' */ PRINT | PUNCT | GRAPH,
348 /* '*' */ PRINT | PUNCT | GRAPH,
349 /* ')' */ PRINT | PUNCT | GRAPH,
350 /* ';' */ PRINT | PUNCT | GRAPH,
351 /* '~' */ PRINT | PUNCT | GRAPH,
352 /* '-' */ PRINT | PUNCT | GRAPH,
353 /* '/' */ PRINT | PUNCT | GRAPH,
354 /* */ 0,
355 /* */ 0,
356 /* */ 0,
357 /* */ 0,
358 /* */ 0,
359 /* */ 0,
360 /* */ 0,
361 /* */ 0,
362 /* */ 0,
363 /* ',' */ PRINT | PUNCT | GRAPH,
364 /* '%' */ PRINT | PUNCT | GRAPH,
365 /* '_' */ PRINT | PUNCT | GRAPH,
366 /* '>' */ PRINT | PUNCT | GRAPH,
367 /* '?' */ PRINT | PUNCT | GRAPH,
368 /* */ 0,
369 /* */ 0,
370 /* */ 0,
371 /* */ 0,
372 /* */ 0,
373 /* */ 0,
374 /* */ 0,
375 /* */ 0,
376 /* */ 0,
377 /* */ 0,
378 /* ':' */ PRINT | PUNCT | GRAPH,
379 /* '#' */ PRINT | PUNCT | GRAPH,
380 /* '@' */ PRINT | PUNCT | GRAPH,
381 /* ''' */ PRINT | PUNCT | GRAPH,
382 /* '=' */ PRINT | PUNCT | GRAPH,
383 /* '"' */ PRINT | PUNCT | GRAPH,
384 /* */ 0,
385 /* 'a' */ LETTER (LOWER | XDIGIT),
386 /* 'b' */ LETTER (LOWER | XDIGIT),
387 /* 'c' */ LETTER (LOWER | XDIGIT),
388 /* 'd' */ LETTER (LOWER | XDIGIT),
389 /* 'e' */ LETTER (LOWER | XDIGIT),
390 /* 'f' */ LETTER (LOWER | XDIGIT),
391 /* 'g' */ LETTER (LOWER),
392 /* 'h' */ LETTER (LOWER),
393 /* 'i' */ LETTER (LOWER),
394 /* */ 0,
395 /* */ 0,
396 /* */ 0,
397 /* */ 0,
398 /* */ 0,
399 /* */ 0,
400 /* */ 0,
401 /* 'j' */ LETTER (LOWER),
402 /* 'k' */ LETTER (LOWER),
403 /* 'l' */ LETTER (LOWER),
404 /* 'm' */ LETTER (LOWER),
405 /* 'n' */ LETTER (LOWER),
406 /* 'o' */ LETTER (LOWER),
407 /* 'p' */ LETTER (LOWER),
408 /* 'q' */ LETTER (LOWER),
409 /* 'r' */ LETTER (LOWER),
410 /* */ 0,
411 /* */ 0,
412 /* */ 0,
413 /* */ 0,
414 /* */ 0,
415 /* */ 0,
416 /* */ 0,
417 /* */ 0,
418 /* 's' */ LETTER (LOWER),
419 /* 't' */ LETTER (LOWER),
420 /* 'u' */ LETTER (LOWER),
421 /* 'v' */ LETTER (LOWER),
422 /* 'w' */ LETTER (LOWER),
423 /* 'x' */ LETTER (LOWER),
424 /* 'y' */ LETTER (LOWER),
425 /* 'z' */ LETTER (LOWER),
426 /* */ 0,
427 /* */ 0,
428 /* */ 0,
429 /* */ 0,
430 /* */ 0,
431 /* */ 0,
432 /* */ 0,
433 /* */ 0,
434 /* */ 0,
435 /* */ 0,
436 /* */ 0,
437 /* */ 0,
438 /* */ 0,
439 /* */ 0,
440 /* */ 0,
441 /* '`' */ 0,
442 /* */ 0,
443 /* */ 0,
444 /* */ 0,
445 /* */ 0,
446 /* */ 0,
447 /* */ 0,
448 /* 'A' */ LETTER (UPPER | XDIGIT),
449 /* 'B' */ LETTER (UPPER | XDIGIT),
450 /* 'C' */ LETTER (UPPER | XDIGIT),
451 /* 'D' */ LETTER (UPPER | XDIGIT),
452 /* 'E' */ LETTER (UPPER | XDIGIT),
453 /* 'F' */ LETTER (UPPER | XDIGIT),
454 /* 'G' */ LETTER (UPPER),
455 /* 'H' */ LETTER (UPPER),
456 /* 'I' */ LETTER (UPPER),
457 /* */ 0,
458 /* */ 0,
459 /* */ 0,
460 /* */ 0,
461 /* */ 0,
462 /* */ 0,
463 /* */ 0,
464 /* 'J' */ LETTER (UPPER),
465 /* 'K' */ LETTER (UPPER),
466 /* 'L' */ LETTER (UPPER),
467 /* 'M' */ LETTER (UPPER),
468 /* 'N' */ LETTER (UPPER),
469 /* 'O' */ LETTER (UPPER),
470 /* 'P' */ LETTER (UPPER),
471 /* 'Q' */ LETTER (UPPER),
472 /* 'R' */ LETTER (UPPER),
473 /* */ 0,
474 /* */ 0,
475 /* */ 0,
476 /* */ 0,
477 /* */ 0,
478 /* */ 0,
479 /* */ 0,
480 /* */ 0,
481 /* 'S' */ LETTER (UPPER),
482 /* 'T' */ LETTER (UPPER),
483 /* 'U' */ LETTER (UPPER),
484 /* 'V' */ LETTER (UPPER),
485 /* 'W' */ LETTER (UPPER),
486 /* 'X' */ LETTER (UPPER),
487 /* 'Y' */ LETTER (UPPER),
488 /* 'Z' */ LETTER (UPPER),
489 /* */ 0,
490 /* */ 0,
491 /* */ 0,
492 /* */ 0,
493 /* */ 0,
494 /* */ 0,
495 /* '0' */ PRINT | DIGIT | GRAPH | XDIGIT,
496 /* '1' */ PRINT | DIGIT | GRAPH | XDIGIT,
497 /* '2' */ PRINT | DIGIT | GRAPH | XDIGIT,
498 /* '3' */ PRINT | DIGIT | GRAPH | XDIGIT,
499 /* '4' */ PRINT | DIGIT | GRAPH | XDIGIT,
500 /* '5' */ PRINT | DIGIT | GRAPH | XDIGIT,
501 /* '6' */ PRINT | DIGIT | GRAPH | XDIGIT,
502 /* '7' */ PRINT | DIGIT | GRAPH | XDIGIT,
503 /* '8' */ PRINT | DIGIT | GRAPH | XDIGIT,
504 /* '9' */ PRINT | DIGIT | GRAPH | XDIGIT,
505 /* */ 0,
506 /* */ 0,
507 /* */ 0,
508 /* */ 0,
509 /* */ 0,
510 /* */ 0
511
512#else // 'A' != 0x41 && 'A' != 0xc1
513# error unknown character set (neither ASCII nor EBCDIC)
514#endif // ASCII or EBCDIC
515
516};
517
518
520UserCtypeBase (const char *cname)
521 : cname_ (cname), masks_ (_rw_char_masks), chars_ (0),
522 upper_ (0), lower_ (0), narrow_ (0), wide_ (0),
523 n_all_calls_ (0),
525{
526 memset (n_calls_, 0, sizeof n_calls_);
527 memset (n_throws_, 0, sizeof n_throws_);
528 memset (throw_at_calls_, 0, sizeof throw_at_calls_);
529}
530
531
533// records a call to the object's member function fun and
534// throws an exception if the number of calls to the member
535// function reaches the limit specified by throw_at_calls_
536static void
537_rw_funcall (const UserCtypeBase &ctp,
539{
540 UserCtypeBase* const pctp = _RWSTD_CONST_CAST (UserCtypeBase*, &ctp);
541
542 // increment the number of calls regardless of success
543 ++pctp->n_all_calls_;
544 ++pctp->n_calls_ [mf];
545
546 // check the number of calls and throw an exception
547 // if the specified limit has been reached
548 if (ctp.n_calls_ [mf] == ctp.throw_at_calls_ [mf]) {
549 // increment the exception counter for this function
550 ++pctp->n_throws_ [mf];
551
552 _rw_throw (__FILE__, __LINE__,
553 "UserCtype<%s>::%s: reached call limit of %zu",
554 ctp.cname_, _rw_func_names [mf], ctp.throw_at_calls_);
555
556 RW_ASSERT (!"logic error: should not reach");
557 }
558}
559
560
562static void
563_rw_check_char (const UserCtypeBase &ctp,
565 size_t uch)
566{
567 if (0 <= ctp.throw_char_ && size_t (ctp.throw_char_) == uch) {
568
569 UserCtypeBase* const pctp = _RWSTD_CONST_CAST (UserCtypeBase*, &ctp);
570 ++pctp->n_throws_ [mf];
571
572 _rw_throw (__FILE__, __LINE__,
573 "UserCtype<%s>::%s: invalid character: %{#lc}",
574 ctp.cname_, _rw_func_names [mf], int (uch));
575
576 RW_ASSERT (!"logic error: should not reach");
577 }
578}
579
580
583_rw_make_mask_vec (const unsigned *chars, const unsigned *masks)
584{
585 if (0 == chars) {
586 RW_ASSERT (0 == masks);
587 return 0;
588 }
589
590 RW_ASSERT (0 != masks);
591
592 typedef UserCtype<char>::mask Mask;
593
594 const size_t size = UserCtype<char>::table_size;
595 Mask* const vec = new Mask [size];
596
597 memset (vec, 0, size * sizeof *vec);
598
599 for (size_t i = 0; 0 <= chars [i]; ++i)
600 vec [UChar (chars [i])] = Mask (masks [i]);
601
602 return vec;
603}
604
605
607UserCtype (size_t refs /* = 0 */)
608 : Base (0, false, refs),
609 UserCtypeBase ("char")
610{
611 chars_ = 0;
612 masks_ = _rw_char_masks;
613}
614
615
617UserCtype (const unsigned *chars, const unsigned *masks, size_t refs /* = 0 */)
618 : Base (_rw_make_mask_vec (chars, masks), true, refs),
619 UserCtypeBase ("char")
620{
621 chars_ = chars;
622 masks_ = masks;
623}
624
625
628do_toupper (char_type ch) const
629{
630 _rw_funcall (*this, mf_toupper);
631
632 const UChar uch = UChar (ch);
633
634 _rw_check_char (*this, mf_toupper, uch);
635
636 if (0 == upper_) {
637 if (masks_ [uch] & LOWER) {
638#if 'A' == 0x41 // ASCII
639 return char_type (uch - 32);
640#else // EBCDIC
641 return char_type (uch + 64);
642#endif
643 }
644 }
645 else {
646 // FIXME: implement this
647 RW_ASSERT (!"do_toupper() not implemented");
648 }
649
650 return ch;
651}
652
653
656do_toupper (char_type *lo, const char_type *hi) const
657{
658 _rw_funcall (*this, mf_toupper_range);
659
660 if (0 == upper_) {
661 for ( ; lo < hi; ++lo) {
662
663 const UChar uch = UChar (*lo);
664
665 _rw_check_char (*this, mf_toupper, uch);
666
667 if (masks_ [uch] & LOWER) {
668#if 'A' == 0x41 // ASCII
669 *lo = char_type (uch - 32);
670#else // EBCDIC
671 *lo = char_type (uch + 64);
672#endif
673 }
674 }
675 }
676 else {
677 // FIXME: implement this
678 RW_ASSERT (!"do_toupper() not implemented");
679 }
680
681 return lo;
682}
683
684
687do_tolower (char_type ch) const
688{
689 _rw_funcall (*this, mf_tolower);
690
691 _rw_check_char (*this, mf_toupper, UChar (ch));
692
693 if (0 == chars_) {
694 if (masks_ [UChar (ch)] & UPPER) {
695#if 'A' == 0x41 // ASCII
696 return char_type (UChar (ch + 32));
697#else // EBCDIC
698 return char_type (UChar (ch - 64));
699#endif
700 }
701 }
702 else {
703 // FIXME: implement this
704 RW_ASSERT (!"do_toupper() not implemented");
705 }
706
707 return ch;
708}
709
710
713do_tolower (char_type *lo, const char_type *hi) const
714{
715 _rw_funcall (*this, mf_tolower_range);
716
717 if (0 == chars_) {
718 for ( ; lo < hi; ++lo) {
719
720 const UChar uch = UChar (*lo);
721
722 _rw_check_char (*this, mf_toupper, uch);
723
724 if (masks_ [uch] & UPPER) {
725#if 'A' == 0x41 // ASCII
726 *lo = char_type (uch - 32);
727#else // EBCDIC
728 *lo = char_type (uch + 64);
729#endif
730 }
731 }
732 }
733 else {
734 // FIXME: implement this
735 RW_ASSERT (!"do_toupper() not implemented");
736 }
737
738 return lo;
739}
740
741
744do_widen (char ch) const
745{
746 _rw_funcall (*this, mf_widen);
747
748 const UChar uch = UChar (ch);
749
750 _rw_check_char (*this, mf_toupper, uch);
751
752 if (narrow_ && wide_) {
753 for (size_t i = 0; 0 <= narrow_ [i]; ++i) {
754 if (uch == UChar (narrow_ [i])) {
755 if (0 <= wide_ [i])
756 return UChar (wide_ [i]);
757
758 if (throw_on_invalid_)
759 throw;
760
761 break;
762 }
763 }
764 }
765
766 return ch;
767}
768
769
770const char*
772do_widen (const char *lo, const char *hi, char_type *dst) const
773{
774 _rw_funcall (*this, mf_widen_range);
775
776 if (narrow_ && wide_) {
777 for ( ; lo < hi; ++lo, ++dst) {
778
779 const UChar uch = *lo;
780
781 _rw_check_char (*this, mf_toupper, uch);
782
783 for (size_t i = 0; 0 <= narrow_ [i]; ++i) {
784 if (uch == UChar (narrow_ [i])) {
785 if (0 <= wide_ [i])
786 *dst = UChar (wide_ [i]);
787
788 if (throw_on_invalid_)
789 throw;
790
791 break;
792 }
793 }
794 }
795 }
796 else if (throw_char_ < 0 || int (_RWSTD_UCHAR_MAX) < throw_char_) {
797 const size_t nelems = size_t (hi - lo);
798 memcpy (dst, lo, nelems);
799 lo += nelems;
800 }
801 else {
802 for (; lo < hi; ++lo, ++dst) {
803
804 const UChar uch = UChar (*lo);
805
806 _rw_check_char (*this, mf_toupper, uch);
807
808 *dst = char_type (uch);
809 }
810 }
811
812 return lo;
813}
814
815
817do_narrow (char_type ch, char dfault) const
818{
819 _rw_funcall (*this, mf_narrow);
820
821 const UChar uch = UChar (ch);
822
823 _rw_check_char (*this, mf_toupper, uch);
824
825 if (narrow_ && wide_) {
826 for (size_t i = 0; 0 <= wide_ [i]; ++i) {
827 if (uch == UChar (wide_ [i])) {
828 if (0 <= wide_ [i])
829 return UChar (wide_ [i]);
830
831 if (throw_on_invalid_)
832 throw;
833
834 break;
835 }
836 }
837
838 return dfault;
839 }
840
841 return ch;
842}
843
844
847do_narrow (const char_type *lo, const char_type *hi, char dflt, char *dst) const
848{
849 _rw_funcall (*this, mf_narrow_range);
850
851 if (narrow_ && wide_) {
852 for ( ; lo < hi; ++lo, ++dst) {
853
854 const UChar uch = UChar (*lo);
855
856 _rw_check_char (*this, mf_toupper, uch);
857
858 for (size_t i = 0; 0 <= wide_ [i]; ++i) {
859 if (uch == UChar (wide_ [i])) {
860 *dst = 0 <= narrow_ [i] ? UChar (wide_ [i]) : UChar (dflt);
861 break;
862 }
863 }
864 }
865 }
866 else if (throw_char_ < 0 || int (_RWSTD_UCHAR_MAX) < throw_char_) {
867 const size_t nelems = size_t (hi - lo);
868 memcpy (dst, lo, nelems);
869 lo += nelems;
870 }
871 else {
872 for (; lo < hi; ++lo, ++dst) {
873
874 const UChar uch = UChar (*lo);
875
876 _rw_check_char (*this, mf_toupper, uch);
877
878 *dst = char_type (uch);
879 }
880 }
881
882 return lo;
883}
884
885
887#ifndef _RWSTD_NO_WCHAR_T
888
890UserCtype (size_t refs /* = 0 */)
891 : Base (refs), UserCtypeBase ("wchar_t")
892{
893 chars_ = 0;
894 masks_ = _rw_char_masks;
895}
896
897
899UserCtype (const unsigned *chars, const unsigned *masks, size_t refs)
900 : Base (refs), UserCtypeBase ("wchar_t")
901{
902 if (0 == masks) {
903 // when masks is null so must chars
904 RW_ASSERT (0 == chars);
905 masks = _rw_char_masks;
906 }
907
908 chars_ = chars;
909 masks_ = masks;
910}
911
912
914do_is (mask m, char_type ch) const
915{
916 _rw_funcall (*this, mf_is);
917
918 const size_t uch = size_t (ch);
919
920 _rw_check_char (*this, mf_toupper, uch);
921
922 if (masks_ == _rw_char_masks) {
923 return uch < 256 ? 0 != (masks_ [uch] & m) : false;
924 }
925
926 for (size_t i = 0; 0 <= chars_ [i]; ++i)
927 if (chars_ [i] == int (ch))
928 return 0 != (masks_ [i] & m);
929
930 return false;
931}
932
933
936do_is (const char_type *lo, const char_type *hi, mask *vec) const
937{
938 _rw_funcall (*this, mf_is_range);
939
940 if (masks_ == _rw_char_masks) {
941 for ( ; lo < hi; ++lo, ++vec) {
942
943 const size_t uch = size_t (*lo);
944
945 _rw_check_char (*this, mf_toupper, uch);
946
947 *vec = mask (uch < 256 ? masks_ [uch] : 0);
948 }
949 }
950 else {
951 for ( ; lo < hi; ++lo, ++vec) {
952
953 _rw_check_char (*this, mf_toupper, size_t (*lo));
954
955 bool found = false;
956
957 for (size_t i = 0; 0 <= chars_ [i]; ++i) {
958 if (chars_ [i] == int (*lo)) {
959 *vec = mask (masks_ [i]);
960 found = true;
961 break;
962 }
963 }
964
965 if (!found && throw_on_invalid_)
966 throw;
967 }
968 }
969
970 return lo;
971}
972
973
976do_scan_is (mask m, const char_type *lo, const char_type *hi) const
977{
978 _rw_funcall (*this, mf_scan_is);
979
980 if (masks_ == _rw_char_masks) {
981 for ( ; lo < hi; ++lo) {
982 const size_t uch = size_t (*lo);
983
984 _rw_check_char (*this, mf_toupper, uch);
985
986 if (uch < 256 && masks_ [uch] & m)
987 break;
988 }
989 }
990 else {
991 for ( ; lo < hi; ++lo) {
992
993 _rw_check_char (*this, mf_toupper, size_t (*lo));
994
995 for (size_t i = 0; 0 <= chars_ [i]; ++i) {
996 if (chars_ [i] == int (*lo) && masks_ [i] & m)
997 return lo;
998 }
999 }
1000 }
1001
1002 return lo;
1003}
1004
1005
1008do_scan_not (mask m, const char_type *lo, const char_type *hi) const
1009{
1010 _rw_funcall (*this, mf_scan_not);
1011
1012 if (masks_ == _rw_char_masks) {
1013 for ( ; lo < hi; ++lo) {
1014
1015 const size_t uch = size_t (*lo);
1016
1017 _rw_check_char (*this, mf_toupper, uch);
1018
1019 if (uch < 256 && 0 == (masks_ [uch] & m))
1020 break;
1021 }
1022 }
1023 else {
1024 for ( ; lo < hi; ++lo) {
1025
1026 _rw_check_char (*this, mf_toupper, size_t (*lo));
1027
1028 for (size_t i = 0; 0 <= chars_ [i]; ++i) {
1029 if (chars_ [i] == int (*lo) && 0 == (masks_ [i] & m))
1030 return lo;
1031 }
1032 }
1033 }
1034
1035 return lo;
1036}
1037
1038
1041do_toupper (char_type ch) const
1042{
1043 _rw_funcall (*this, mf_toupper);
1044
1045 const size_t uch = size_t (ch);
1046
1047 _rw_check_char (*this, mf_toupper, uch);
1048
1049 if (0 == upper_) {
1050
1051 if (uch < 256 && masks_ [uch] & LOWER) {
1052#if 'A' == 0x41 // ASCII
1053 return char_type (uch - 32);
1054#else // EBCDIC
1055 return char_type (uch + 64);
1056#endif
1057 }
1058 }
1059 else {
1060 // FIXME: implement this
1061 RW_ASSERT (!"do_toupper() not implemented");
1062 }
1063
1064 return ch;
1065}
1066
1067
1070do_toupper (char_type *lo, const char_type *hi) const
1071{
1072 _rw_funcall (*this, mf_toupper_range);
1073
1074 if (0 == upper_) {
1075 for ( ; lo < hi; ++lo) {
1076 const size_t uch = size_t (*lo);
1077
1078 _rw_check_char (*this, mf_toupper, uch);
1079
1080 if (uch < 256 && masks_ [uch] & LOWER) {
1081#if 'A' == 0x41 // ASCII
1082 *lo = char_type (uch - 32);
1083#else // EBCDIC
1084 *lo = char_type (uch + 64);
1085#endif
1086 }
1087 }
1088 }
1089 else {
1090 // FIXME: implement this
1091 RW_ASSERT (!"do_toupper() not implemented");
1092 }
1093
1094 return lo;
1095}
1096
1097
1100do_tolower (char_type ch) const
1101{
1102 _rw_funcall (*this, mf_tolower);
1103
1104 const size_t uch = size_t (ch);
1105
1106 _rw_check_char (*this, mf_toupper, uch);
1107
1108 if (masks_ == _rw_char_masks) {
1109 if (uch < 256 && masks_ [uch] & UPPER) {
1110#if 'A' == 0x41 // ASCII
1111 return char_type (uch + 32);
1112#else // EBCDIC
1113 return char_type (uch - 64);
1114#endif
1115 }
1116 }
1117 else {
1118 // FIXME: implement this
1119 RW_ASSERT (!"do_toupper() not implemented");
1120 }
1121
1122 return ch;
1123}
1124
1125
1128do_tolower (char_type *lo, const char_type *hi) const
1129{
1130 _rw_funcall (*this, mf_tolower_range);
1131
1132 if (masks_ == _rw_char_masks) {
1133 for ( ; lo < hi; ++lo) {
1134
1135 const size_t uch = size_t (*lo);
1136
1137 if (uch < 256 && masks_ [uch] & UPPER) {
1138#if 'A' == 0x41 // ASCII
1139 *lo = char_type (uch - 32);
1140#else // EBCDIC
1141 *lo = char_type (uch + 64);
1142#endif
1143 }
1144 }
1145 }
1146 else {
1147 // FIXME: implement this
1148 RW_ASSERT (!"do_toupper() not implemented");
1149 }
1150
1151 return lo;
1152}
1153
1154
1157do_widen (char ch) const
1158{
1159 _rw_funcall (*this, mf_widen);
1160
1161 const UChar uch = UChar (ch);
1162
1163 _rw_check_char (*this, mf_toupper, uch);
1164
1165 if (narrow_ && wide_) {
1166 for (size_t i = 0; 0 <= narrow_ [i]; ++i) {
1167 if (int (uch) == narrow_ [i]) {
1168 if (0 <= wide_ [i])
1169 return char_type (wide_ [i]);
1170
1171 if (throw_on_invalid_)
1172 throw;
1173
1174 break;
1175 }
1176 }
1177 }
1178
1179 return ch;
1180}
1181
1182
1183const char*
1185do_widen (const char *lo, const char *hi, char_type *dst) const
1186{
1187 _rw_funcall (*this, mf_widen_range);
1188
1189 if (narrow_ && wide_) {
1190 for ( ; lo < hi; ++lo, ++dst) {
1191
1192 const size_t uch = size_t (*lo);
1193
1194 _rw_check_char (*this, mf_toupper, uch);
1195
1196 for (size_t i = 0; 0 <= narrow_ [i]; ++i) {
1197 if (int (uch) == narrow_ [i]) {
1198 if (0 <= wide_ [i])
1199 *dst = char_type (wide_ [i]);
1200
1201 if (throw_on_invalid_)
1202 throw;
1203
1204 break;
1205 }
1206 }
1207 }
1208 }
1209 else {
1210 for (; lo < hi; ++lo, ++dst) {
1211
1212 const UChar uch = UChar (*lo);
1213
1214 _rw_check_char (*this, mf_toupper, uch);
1215
1216 *dst = char_type (uch);
1217 }
1218 }
1219
1220 return lo;
1221}
1222
1223
1225do_narrow (char_type ch, char dfault) const
1226{
1227 _rw_funcall (*this, mf_narrow);
1228
1229 const size_t uch = size_t (ch);
1230
1231 _rw_check_char (*this, mf_toupper, uch);
1232
1233 if (narrow_ && wide_) {
1234 for (size_t i = 0; 0 <= wide_ [i]; ++i) {
1235 if (int (uch) == wide_ [i]) {
1236 if (0 <= wide_ [i])
1237 return char (wide_ [i]);
1238
1239 if (throw_on_invalid_)
1240 throw;
1241
1242 break;
1243 }
1244 }
1245
1246 return dfault;
1247 }
1248
1249 return char (uch);
1250}
1251
1252
1255do_narrow (const char_type *lo, const char_type *hi, char dflt, char *dst) const
1256{
1257 _rw_funcall (*this, mf_narrow_range);
1258
1259 if (narrow_ && wide_) {
1260 for ( ; lo < hi; ++lo, ++dst) {
1261
1262 const size_t uch = size_t (*lo);
1263
1264 _rw_check_char (*this, mf_toupper, uch);
1265
1266 for (size_t i = 0; 0 <= wide_ [i]; ++i) {
1267 if (int (uch) == wide_ [i]) {
1268 *dst = 0 <= narrow_ [i] ? char (wide_ [i]) : dflt;
1269 break;
1270 }
1271 }
1272 }
1273 }
1274 else {
1275 for (; lo < hi; ++lo, ++dst) {
1276
1277 const size_t uch = size_t (*lo);
1278
1279 _rw_check_char (*this, mf_toupper, uch);
1280
1281 *dst = char (uch);
1282 }
1283 }
1284
1285 return lo;
1286}
1287
1288#endif // _RWSTD_NO_WCHAR_T
1289
1290
1293
1294
1295std::locale::id
1296ctype<UserChar>::
1297id;
1298
1299
1300ctype<UserChar>::
1301ctype (size_t refs /* = 0 */)
1302 : Base (refs), UserCtypeBase ("UserChar")
1303{
1304 masks_ = _rw_char_masks;
1305 chars_ = 0;
1306}
1307
1308
1309ctype<UserChar>::
1310ctype (const unsigned *chars, const unsigned *masks, size_t refs /* = 0 */)
1311 : Base (refs), UserCtypeBase ("UserChar")
1312{
1313 if (0 == masks) {
1314 // when masks is null so must chars
1315 RW_ASSERT (0 == chars);
1316 masks = _rw_char_masks;
1317 }
1318
1319 chars_ = chars;
1320 masks_ = masks;
1321}
1322
1323
1324bool ctype<UserChar>::
1325do_is (mask m, char_type ch) const
1326{
1327 _rw_funcall (*this, mf_is);
1328
1329 const size_t uch = size_t (ch.c);
1330
1331 _rw_check_char (*this, mf_toupper, uch);
1332
1333 if (masks_ == _rw_char_masks) {
1334 return uch < 256 ? 0 != (masks_ [uch] & m) : false;
1335 }
1336
1337 for (size_t i = 0; 0 <= chars_ [i]; ++i)
1338 if (chars_ [i] == int (uch))
1339 return 0 != (masks_ [i] & m);
1340
1341 return false;
1342}
1343
1344
1345const ctype<UserChar>::char_type*
1346ctype<UserChar>::
1347do_is (const char_type *lo, const char_type *hi, mask *vec) const
1348{
1349 _rw_funcall (*this, mf_is_range);
1350
1351 if (masks_ == _rw_char_masks) {
1352 for ( ; lo < hi; ++lo, ++vec) {
1353
1354 const size_t uch = size_t (lo->c);
1355
1356 _rw_check_char (*this, mf_toupper, uch);
1357
1358 *vec = mask (uch < 256 ? masks_ [uch] : 0);
1359 }
1360 }
1361 else {
1362 for ( ; lo < hi; ++lo, ++vec) {
1363
1364 _rw_check_char (*this, mf_toupper, size_t (lo->c));
1365
1366 bool found = false;
1367
1368 for (size_t i = 0; 0 <= chars_ [i]; ++i) {
1369 if (chars_ [i] == int (UChar (lo->c))) {
1370 *vec = mask (masks_ [i]);
1371 found = true;
1372 break;
1373 }
1374 }
1375
1376 if (!found && throw_on_invalid_)
1377 throw;
1378 }
1379 }
1380
1381 return lo;
1382}
1383
1384
1385const ctype<UserChar>::char_type*
1386ctype<UserChar>::
1387do_scan_is (mask m, const char_type *lo, const char_type *hi) const
1388{
1389 _rw_funcall (*this, mf_scan_is);
1390
1391 if (masks_ == _rw_char_masks) {
1392 for ( ; lo < hi; ++lo) {
1393 const size_t uch = size_t (lo->c);
1394
1395 _rw_check_char (*this, mf_toupper, uch);
1396
1397 if (uch < 256 && masks_ [uch] & m)
1398 break;
1399 }
1400 }
1401 else {
1402 for ( ; lo < hi; ++lo) {
1403
1404 _rw_check_char (*this, mf_toupper, size_t (lo->c));
1405
1406 for (size_t i = 0; 0 <= chars_ [i]; ++i) {
1407 if (chars_ [i] == int (UChar (lo->c)) && masks_ [i] & m)
1408 return lo;
1409 }
1410 }
1411 }
1412
1413 return lo;
1414}
1415
1416
1417const ctype<UserChar>::char_type*
1418ctype<UserChar>::
1419do_scan_not (mask m, const char_type *lo, const char_type *hi) const
1420{
1421 _rw_funcall (*this, mf_scan_not);
1422
1423 if (masks_ == _rw_char_masks) {
1424 for ( ; lo < hi; ++lo) {
1425
1426 const size_t uch = size_t (lo->c);
1427
1428 _rw_check_char (*this, mf_toupper, uch);
1429
1430 if (uch < 256 && 0 == (masks_ [uch] & m))
1431 break;
1432 }
1433 }
1434 else {
1435 for ( ; lo < hi; ++lo) {
1436
1437 const size_t uch = size_t (lo->c);
1438
1439 _rw_check_char (*this, mf_toupper, uch);
1440
1441 for (size_t i = 0; 0 <= chars_ [i]; ++i) {
1442 if (chars_ [i] == int (uch) && 0 == (masks_ [i] & m))
1443 return lo;
1444 }
1445 }
1446 }
1447
1448 return lo;
1449}
1450
1451
1452ctype<UserChar>::char_type
1453ctype<UserChar>::
1454do_toupper (char_type ch) const
1455{
1456 _rw_funcall (*this, mf_toupper);
1457
1458 const size_t uch = size_t (ch.c);
1459
1460 _rw_check_char (*this, mf_toupper, uch);
1461
1462 if (0 == upper_) {
1463
1464 if (uch < 256 && masks_ [uch] & LOWER) {
1465#if 'A' == 0x41 // ASCII
1466 ch.c = UChar (uch - 32);
1467#else // EBCDIC
1468 ch.c = UChar (uch + 64);
1469#endif
1470 }
1471 }
1472 else {
1473 // FIXME: implement this
1474 RW_ASSERT (!"do_toupper() not implemented");
1475 }
1476
1477 return ch;
1478}
1479
1480
1481const ctype<UserChar>::char_type*
1482ctype<UserChar>::
1483do_toupper (char_type *lo, const char_type *hi) const
1484{
1485 _rw_funcall (*this, mf_toupper_range);
1486
1487 if (0 == upper_) {
1488 for ( ; lo < hi; ++lo) {
1489 const size_t uch = size_t (lo->c);
1490
1491 _rw_check_char (*this, mf_toupper, uch);
1492
1493 if (uch < 256 && masks_ [uch] & LOWER) {
1494#if 'A' == 0x41 // ASCII
1495 lo->c = UChar (uch - 32);
1496#else // EBCDIC
1497 lo->c = UChar (uch + 64);
1498#endif
1499 }
1500 }
1501 }
1502 else {
1503 // FIXME: implement this
1504 RW_ASSERT (!"do_toupper() not implemented");
1505 }
1506
1507 return lo;
1508}
1509
1510
1511ctype<UserChar>::char_type
1512ctype<UserChar>::
1513do_tolower (char_type ch) const
1514{
1515 _rw_funcall (*this, mf_tolower);
1516
1517 const size_t uch = size_t (ch.c);
1518
1519 _rw_check_char (*this, mf_toupper, uch);
1520
1521 if (masks_ == _rw_char_masks) {
1522 if (uch < 256 && masks_ [uch] & UPPER) {
1523#if 'A' == 0x41 // ASCII
1524 ch.c = UChar (uch + 32);
1525#else // EBCDIC
1526 ch.c = UChar (uch - 64);
1527#endif
1528 }
1529 }
1530 else {
1531 // FIXME: implement this
1532 RW_ASSERT (!"do_toupper() not implemented");
1533 }
1534
1535 return ch;
1536}
1537
1538
1539const ctype<UserChar>::char_type*
1540ctype<UserChar>::
1541do_tolower (char_type *lo, const char_type *hi) const
1542{
1543 _rw_funcall (*this, mf_tolower_range);
1544
1545 if (masks_ == _rw_char_masks) {
1546 for ( ; lo < hi; ++lo) {
1547
1548 const size_t uch = size_t (lo->c);
1549
1550 if (uch < 256 && masks_ [uch] & UPPER) {
1551#if 'A' == 0x41 // ASCII
1552 lo->c = UChar (uch - 32);
1553#else // EBCDIC
1554 lo->c = UChar (uch + 64);
1555#endif
1556 }
1557 }
1558 }
1559 else {
1560 // FIXME: implement this
1561 RW_ASSERT (!"do_toupper() not implemented");
1562 }
1563
1564 return lo;
1565}
1566
1567
1568ctype<UserChar>::char_type
1569ctype<UserChar>::
1570do_widen (char ch) const
1571{
1572 _rw_funcall (*this, mf_widen);
1573
1574 const UChar uch = UChar (ch);
1575
1576 _rw_check_char (*this, mf_toupper, uch);
1577
1578 if (narrow_ && wide_) {
1579 for (size_t i = 0; 0 <= narrow_ [i]; ++i) {
1580 if (int (uch) == narrow_ [i]) {
1581 if (0 <= wide_ [i])
1582 return make_char (char (wide_ [i]), (UserChar*)0);
1583
1584 if (throw_on_invalid_)
1585 throw;
1586
1587 break;
1588 }
1589 }
1590 }
1591
1592 return make_char (ch, (UserChar*)0);
1593}
1594
1595
1596const char*
1597ctype<UserChar>::
1598do_widen (const char *lo, const char *hi, char_type *dst) const
1599{
1600 _rw_funcall (*this, mf_widen_range);
1601
1602 if (narrow_ && wide_) {
1603 for ( ; lo < hi; ++lo, ++dst) {
1604
1605 const size_t uch = size_t (*lo);
1606
1607 _rw_check_char (*this, mf_toupper, uch);
1608
1609 for (size_t i = 0; 0 <= narrow_ [i]; ++i) {
1610 if (int (uch) == narrow_ [i]) {
1611 if (0 <= wide_ [i])
1612 *dst = make_char (char (wide_ [i]), (UserChar*)0);
1613
1614 if (throw_on_invalid_)
1615 throw;
1616
1617 break;
1618 }
1619 }
1620 }
1621 }
1622 else {
1623 for (; lo < hi; ++lo, ++dst) {
1624
1625 const UChar uch = UChar (*lo);
1626
1627 _rw_check_char (*this, mf_toupper, uch);
1628
1629 *dst = make_char (*lo, (UserChar*)0);
1630 }
1631 }
1632
1633 return lo;
1634}
1635
1636
1637char ctype<UserChar>::
1638do_narrow (char_type ch, char dfault) const
1639{
1640 _rw_funcall (*this, mf_narrow);
1641
1642 const size_t uch = size_t (ch.c);
1643
1644 _rw_check_char (*this, mf_toupper, uch);
1645
1646 if (narrow_ && wide_) {
1647 for (size_t i = 0; 0 <= wide_ [i]; ++i) {
1648 if (int (uch) == wide_ [i]) {
1649 if (0 <= wide_ [i])
1650 return char (wide_ [i]);
1651
1652 if (throw_on_invalid_)
1653 throw;
1654
1655 break;
1656 }
1657 }
1658
1659 return dfault;
1660 }
1661
1662 return char (uch);
1663}
1664
1665
1666const ctype<UserChar>::char_type*
1667ctype<UserChar>::
1668do_narrow (const char_type *lo, const char_type *hi, char dflt, char *dst) const
1669{
1670 _rw_funcall (*this, mf_narrow_range);
1671
1672 if (narrow_ && wide_) {
1673 for ( ; lo < hi; ++lo, ++dst) {
1674
1675 const size_t uch = size_t (lo->c);
1676
1677 _rw_check_char (*this, mf_toupper, uch);
1678
1679 for (size_t i = 0; 0 <= wide_ [i]; ++i) {
1680 if (int (uch) == wide_ [i]) {
1681 *dst = 0 <= narrow_ [i] ? char (wide_ [i]) : dflt;
1682 break;
1683 }
1684 }
1685 }
1686 }
1687 else {
1688 for (; lo < hi; ++lo, ++dst) {
1689
1690 const size_t uch = size_t (lo->c);
1691
1692 _rw_check_char (*this, mf_toupper, uch);
1693
1694 *dst = char (uch);
1695 }
1696 }
1697
1698 return lo;
1699}
1700
1701} // namespace std
1702
1703
1706UserCtype (size_t refs /* = 0 */)
1707 : Base (refs)
1708{
1709 chars_ = 0;
1710 masks_ = _rw_char_masks;
1711}
1712
1713
1715UserCtype (const unsigned *chars, const unsigned *masks, size_t refs)
1716 : Base (refs)
1717{
1718 if (0 == masks) {
1719 // when masks is null so must chars
1720 RW_ASSERT (0 == chars);
1721 masks = _rw_char_masks;
1722 }
1723
1724 chars_ = chars;
1725 masks_ = masks;
1726}
#define m
Definition 17.names.cpp:129
#define i
Definition 17.names.cpp:126
#define found
Definition 17.names.cpp:470
#define line
Definition 17.names.cpp:490
#define buf
Definition 17.names.cpp:452
#define SPACE
#define DIGIT
#define PRINT
#define CNTRL
#define PUNCT
#define XDIGIT
#define GRAPH
#define LOWER
#define UPPER
#define va_end(ignore)
#define va_start(va, name)
#define _RWSTD_UNUSED(arg)
Definition _defs.h:972
#define _RWSTD_NAMESPACE(name)
Definition _defs.h:567
#define _RWSTD_CONST_CAST(T, x)
Definition _defs.h:536
Definition json.h:5363
UserChar make_char(char c, UserChar *)
Definition rw_char.h:74
#define _TEST_EXPORT
Definition rw_testdefs.h:55
#define RW_ASSERT(expr)
unsigned char UChar
Definition collate.cpp:122
#define LETTER(m)
#define true
Definition stdbool.h:25
#define false
Definition stdbool.h:26
virtual const char * what() const =0
int throw_char_
Definition rw_ctype.h:94
const unsigned * chars_
Definition rw_ctype.h:66
_RWSTD_SIZE_T n_throws_[n_funs]
Definition rw_ctype.h:86
_RWSTD_SIZE_T n_calls_[n_funs]
Definition rw_ctype.h:82
const unsigned * upper_
Definition rw_ctype.h:69
_RWSTD_SIZE_T throw_at_calls_[n_funs]
Definition rw_ctype.h:90
_RWSTD_SIZE_T n_all_calls_
Definition rw_ctype.h:78
const char *const cname_
Definition rw_ctype.h:61
const unsigned * masks_
Definition rw_ctype.h:65
UserCtypeBase(const char *)
Definition ctype.cpp:520
const unsigned * lower_
Definition rw_ctype.h:70
const unsigned * narrow_
Definition rw_ctype.h:73
bool throw_on_invalid_
Definition rw_ctype.h:98
const unsigned * wide_
Definition rw_ctype.h:74
unsigned char UChar
Definition ctype.cpp:37
#define LOWER
#define UPPER
_TEST_EXPORT int rw_vasnprintf(char **, size_t *, const char *, va_list)
Definition printf.cpp:946