28#define _RWSTD_TEST_SRC
45_rw_throw (
const char *file,
int line,
const char *fmt, ...)
53 const char*
what ()
const {
64 size_t bufsize =
sizeof ex.what_;
74static const char*
const
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*)",
85 "widen(const char*, const char*, char_type*)",
86 "narrow(char_type, char)",
87 "narrow(const char_type*, const char_type*, char, char*)"
101_rw_char_masks [256] = {
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
117#define LETTER(m) (PRINT | ALPHA | GRAPH | m)
513# error unknown character set (neither ASCII nor EBCDIC)
552 _rw_throw (__FILE__, __LINE__,
553 "UserCtype<%s>::%s: reached call limit of %zu",
556 RW_ASSERT (!
"logic error: should not reach");
572 _rw_throw (__FILE__, __LINE__,
573 "UserCtype<%s>::%s: invalid character: %{#lc}",
574 ctp.
cname_, _rw_func_names [mf], int (uch));
576 RW_ASSERT (!
"logic error: should not reach");
583_rw_make_mask_vec (
const unsigned *chars,
const unsigned *masks)
595 Mask*
const vec =
new Mask [
size];
597 memset (vec, 0,
size *
sizeof *vec);
599 for (
size_t i = 0; 0 <= chars [
i]; ++
i)
600 vec [
UChar (chars [
i])] = Mask (masks [
i]);
617UserCtype (
const unsigned *chars,
const unsigned *masks,
size_t refs )
618 :
Base (_rw_make_mask_vec (chars, masks),
true, refs),
630 _rw_funcall (*
this, mf_toupper);
634 _rw_check_char (*
this, mf_toupper, uch);
637 if (masks_ [uch] &
LOWER) {
639 return char_type (uch - 32);
641 return char_type (uch + 64);
647 RW_ASSERT (!
"do_toupper() not implemented");
656do_toupper (char_type *lo,
const char_type *hi)
const
658 _rw_funcall (*
this, mf_toupper_range);
661 for ( ; lo < hi; ++lo) {
665 _rw_check_char (*
this, mf_toupper, uch);
667 if (masks_ [uch] &
LOWER) {
669 *lo = char_type (uch - 32);
671 *lo = char_type (uch + 64);
678 RW_ASSERT (!
"do_toupper() not implemented");
689 _rw_funcall (*
this, mf_tolower);
691 _rw_check_char (*
this, mf_toupper,
UChar (ch));
696 return char_type (
UChar (ch + 32));
698 return char_type (
UChar (ch - 64));
704 RW_ASSERT (!
"do_toupper() not implemented");
713do_tolower (char_type *lo,
const char_type *hi)
const
715 _rw_funcall (*
this, mf_tolower_range);
718 for ( ; lo < hi; ++lo) {
722 _rw_check_char (*
this, mf_toupper, uch);
724 if (masks_ [uch] &
UPPER) {
726 *lo = char_type (uch - 32);
728 *lo = char_type (uch + 64);
735 RW_ASSERT (!
"do_toupper() not implemented");
746 _rw_funcall (*
this, mf_widen);
750 _rw_check_char (*
this, mf_toupper, uch);
752 if (narrow_ && wide_) {
753 for (
size_t i = 0; 0 <= narrow_ [
i]; ++
i) {
754 if (uch ==
UChar (narrow_ [
i])) {
758 if (throw_on_invalid_)
772do_widen (
const char *lo,
const char *hi, char_type *dst)
const
774 _rw_funcall (*
this, mf_widen_range);
776 if (narrow_ && wide_) {
777 for ( ; lo < hi; ++lo, ++dst) {
779 const UChar uch = *lo;
781 _rw_check_char (*
this, mf_toupper, uch);
783 for (
size_t i = 0; 0 <= narrow_ [
i]; ++
i) {
784 if (uch ==
UChar (narrow_ [
i])) {
788 if (throw_on_invalid_)
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);
802 for (; lo < hi; ++lo, ++dst) {
806 _rw_check_char (*
this, mf_toupper, uch);
808 *dst = char_type (uch);
817do_narrow (char_type ch,
char dfault)
const
819 _rw_funcall (*
this, mf_narrow);
823 _rw_check_char (*
this, mf_toupper, uch);
825 if (narrow_ && wide_) {
826 for (
size_t i = 0; 0 <= wide_ [
i]; ++
i) {
827 if (uch ==
UChar (wide_ [
i])) {
831 if (throw_on_invalid_)
847do_narrow (
const char_type *lo,
const char_type *hi,
char dflt,
char *dst)
const
849 _rw_funcall (*
this, mf_narrow_range);
851 if (narrow_ && wide_) {
852 for ( ; lo < hi; ++lo, ++dst) {
856 _rw_check_char (*
this, mf_toupper, uch);
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);
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);
872 for (; lo < hi; ++lo, ++dst) {
876 _rw_check_char (*
this, mf_toupper, uch);
878 *dst = char_type (uch);
887#ifndef _RWSTD_NO_WCHAR_T
894 masks_ = _rw_char_masks;
899UserCtype (
const unsigned *chars,
const unsigned *masks,
size_t refs)
905 masks = _rw_char_masks;
914do_is (mask
m, char_type ch)
const
916 _rw_funcall (*
this, mf_is);
918 const size_t uch = size_t (ch);
920 _rw_check_char (*
this, mf_toupper, uch);
922 if (masks_ == _rw_char_masks) {
923 return uch < 256 ? 0 != (masks_ [uch] &
m) :
false;
926 for (
size_t i = 0; 0 <= chars_ [
i]; ++
i)
927 if (chars_ [
i] ==
int (ch))
928 return 0 != (masks_ [
i] &
m);
936do_is (
const char_type *lo,
const char_type *hi, mask *vec)
const
938 _rw_funcall (*
this, mf_is_range);
940 if (masks_ == _rw_char_masks) {
941 for ( ; lo < hi; ++lo, ++vec) {
943 const size_t uch = size_t (*lo);
945 _rw_check_char (*
this, mf_toupper, uch);
947 *vec = mask (uch < 256 ? masks_ [uch] : 0);
951 for ( ; lo < hi; ++lo, ++vec) {
953 _rw_check_char (*
this, mf_toupper,
size_t (*lo));
957 for (
size_t i = 0; 0 <= chars_ [
i]; ++
i) {
958 if (chars_ [
i] ==
int (*lo)) {
959 *vec = mask (masks_ [
i]);
965 if (!
found && throw_on_invalid_)
976do_scan_is (mask
m,
const char_type *lo,
const char_type *hi)
const
978 _rw_funcall (*
this, mf_scan_is);
980 if (masks_ == _rw_char_masks) {
981 for ( ; lo < hi; ++lo) {
982 const size_t uch = size_t (*lo);
984 _rw_check_char (*
this, mf_toupper, uch);
986 if (uch < 256 && masks_ [uch] &
m)
991 for ( ; lo < hi; ++lo) {
993 _rw_check_char (*
this, mf_toupper,
size_t (*lo));
995 for (
size_t i = 0; 0 <= chars_ [
i]; ++
i) {
996 if (chars_ [
i] ==
int (*lo) && masks_ [
i] &
m)
1008do_scan_not (mask
m,
const char_type *lo,
const char_type *hi)
const
1010 _rw_funcall (*
this, mf_scan_not);
1012 if (masks_ == _rw_char_masks) {
1013 for ( ; lo < hi; ++lo) {
1015 const size_t uch = size_t (*lo);
1017 _rw_check_char (*
this, mf_toupper, uch);
1019 if (uch < 256 && 0 == (masks_ [uch] &
m))
1024 for ( ; lo < hi; ++lo) {
1026 _rw_check_char (*
this, mf_toupper,
size_t (*lo));
1028 for (
size_t i = 0; 0 <= chars_ [
i]; ++
i) {
1029 if (chars_ [
i] ==
int (*lo) && 0 == (masks_ [
i] &
m))
1043 _rw_funcall (*
this, mf_toupper);
1045 const size_t uch = size_t (ch);
1047 _rw_check_char (*
this, mf_toupper, uch);
1051 if (uch < 256 && masks_ [uch] &
LOWER) {
1053 return char_type (uch - 32);
1055 return char_type (uch + 64);
1061 RW_ASSERT (!
"do_toupper() not implemented");
1070do_toupper (char_type *lo,
const char_type *hi)
const
1072 _rw_funcall (*
this, mf_toupper_range);
1075 for ( ; lo < hi; ++lo) {
1076 const size_t uch = size_t (*lo);
1078 _rw_check_char (*
this, mf_toupper, uch);
1080 if (uch < 256 && masks_ [uch] &
LOWER) {
1082 *lo = char_type (uch - 32);
1084 *lo = char_type (uch + 64);
1091 RW_ASSERT (!
"do_toupper() not implemented");
1102 _rw_funcall (*
this, mf_tolower);
1104 const size_t uch = size_t (ch);
1106 _rw_check_char (*
this, mf_toupper, uch);
1108 if (masks_ == _rw_char_masks) {
1109 if (uch < 256 && masks_ [uch] &
UPPER) {
1111 return char_type (uch + 32);
1113 return char_type (uch - 64);
1119 RW_ASSERT (!
"do_toupper() not implemented");
1128do_tolower (char_type *lo,
const char_type *hi)
const
1130 _rw_funcall (*
this, mf_tolower_range);
1132 if (masks_ == _rw_char_masks) {
1133 for ( ; lo < hi; ++lo) {
1135 const size_t uch = size_t (*lo);
1137 if (uch < 256 && masks_ [uch] &
UPPER) {
1139 *lo = char_type (uch - 32);
1141 *lo = char_type (uch + 64);
1148 RW_ASSERT (!
"do_toupper() not implemented");
1159 _rw_funcall (*
this, mf_widen);
1163 _rw_check_char (*
this, mf_toupper, uch);
1165 if (narrow_ && wide_) {
1166 for (
size_t i = 0; 0 <= narrow_ [
i]; ++
i) {
1167 if (
int (uch) == narrow_ [
i]) {
1169 return char_type (wide_ [
i]);
1171 if (throw_on_invalid_)
1185do_widen (
const char *lo,
const char *hi, char_type *dst)
const
1187 _rw_funcall (*
this, mf_widen_range);
1189 if (narrow_ && wide_) {
1190 for ( ; lo < hi; ++lo, ++dst) {
1192 const size_t uch = size_t (*lo);
1194 _rw_check_char (*
this, mf_toupper, uch);
1196 for (
size_t i = 0; 0 <= narrow_ [
i]; ++
i) {
1197 if (
int (uch) == narrow_ [
i]) {
1199 *dst = char_type (wide_ [
i]);
1201 if (throw_on_invalid_)
1210 for (; lo < hi; ++lo, ++dst) {
1214 _rw_check_char (*
this, mf_toupper, uch);
1216 *dst = char_type (uch);
1225do_narrow (char_type ch,
char dfault)
const
1227 _rw_funcall (*
this, mf_narrow);
1229 const size_t uch = size_t (ch);
1231 _rw_check_char (*
this, mf_toupper, uch);
1233 if (narrow_ && wide_) {
1234 for (
size_t i = 0; 0 <= wide_ [
i]; ++
i) {
1235 if (
int (uch) == wide_ [
i]) {
1237 return char (wide_ [
i]);
1239 if (throw_on_invalid_)
1255do_narrow (
const char_type *lo,
const char_type *hi,
char dflt,
char *dst)
const
1257 _rw_funcall (*
this, mf_narrow_range);
1259 if (narrow_ && wide_) {
1260 for ( ; lo < hi; ++lo, ++dst) {
1262 const size_t uch = size_t (*lo);
1264 _rw_check_char (*
this, mf_toupper, uch);
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;
1275 for (; lo < hi; ++lo, ++dst) {
1277 const size_t uch = size_t (*lo);
1279 _rw_check_char (*
this, mf_toupper, uch);
1304 masks_ = _rw_char_masks;
1310ctype (
const unsigned *chars,
const unsigned *masks,
size_t refs )
1316 masks = _rw_char_masks;
1324bool ctype<UserChar>::
1325do_is (mask
m, char_type ch)
const
1327 _rw_funcall (*
this, mf_is);
1329 const size_t uch = size_t (ch.c);
1331 _rw_check_char (*
this, mf_toupper, uch);
1333 if (masks_ == _rw_char_masks) {
1334 return uch < 256 ? 0 != (masks_ [uch] &
m) :
false;
1337 for (
size_t i = 0; 0 <= chars_ [
i]; ++
i)
1338 if (chars_ [
i] ==
int (uch))
1339 return 0 != (masks_ [
i] &
m);
1345const ctype<UserChar>::char_type*
1347do_is (
const char_type *lo,
const char_type *hi, mask *vec)
const
1349 _rw_funcall (*
this, mf_is_range);
1351 if (masks_ == _rw_char_masks) {
1352 for ( ; lo < hi; ++lo, ++vec) {
1354 const size_t uch = size_t (lo->c);
1356 _rw_check_char (*
this, mf_toupper, uch);
1358 *vec = mask (uch < 256 ? masks_ [uch] : 0);
1362 for ( ; lo < hi; ++lo, ++vec) {
1364 _rw_check_char (*
this, mf_toupper,
size_t (lo->c));
1368 for (
size_t i = 0; 0 <= chars_ [
i]; ++
i) {
1369 if (chars_ [
i] ==
int (
UChar (lo->c))) {
1370 *vec = mask (masks_ [
i]);
1376 if (!
found && throw_on_invalid_)
1385const ctype<UserChar>::char_type*
1387do_scan_is (mask
m,
const char_type *lo,
const char_type *hi)
const
1389 _rw_funcall (*
this, mf_scan_is);
1391 if (masks_ == _rw_char_masks) {
1392 for ( ; lo < hi; ++lo) {
1393 const size_t uch = size_t (lo->c);
1395 _rw_check_char (*
this, mf_toupper, uch);
1397 if (uch < 256 && masks_ [uch] &
m)
1402 for ( ; lo < hi; ++lo) {
1404 _rw_check_char (*
this, mf_toupper,
size_t (lo->c));
1406 for (
size_t i = 0; 0 <= chars_ [
i]; ++
i) {
1407 if (chars_ [
i] ==
int (
UChar (lo->c)) && masks_ [
i] &
m)
1417const ctype<UserChar>::char_type*
1419do_scan_not (mask
m,
const char_type *lo,
const char_type *hi)
const
1421 _rw_funcall (*
this, mf_scan_not);
1423 if (masks_ == _rw_char_masks) {
1424 for ( ; lo < hi; ++lo) {
1426 const size_t uch = size_t (lo->c);
1428 _rw_check_char (*
this, mf_toupper, uch);
1430 if (uch < 256 && 0 == (masks_ [uch] &
m))
1435 for ( ; lo < hi; ++lo) {
1437 const size_t uch = size_t (lo->c);
1439 _rw_check_char (*
this, mf_toupper, uch);
1441 for (
size_t i = 0; 0 <= chars_ [
i]; ++
i) {
1442 if (chars_ [
i] ==
int (uch) && 0 == (masks_ [
i] &
m))
1452ctype<UserChar>::char_type
1454do_toupper (char_type ch)
const
1456 _rw_funcall (*
this, mf_toupper);
1458 const size_t uch = size_t (ch.c);
1460 _rw_check_char (*
this, mf_toupper, uch);
1464 if (uch < 256 && masks_ [uch] &
LOWER) {
1466 ch.c =
UChar (uch - 32);
1468 ch.c =
UChar (uch + 64);
1474 RW_ASSERT (!
"do_toupper() not implemented");
1481const ctype<UserChar>::char_type*
1483do_toupper (char_type *lo,
const char_type *hi)
const
1485 _rw_funcall (*
this, mf_toupper_range);
1488 for ( ; lo < hi; ++lo) {
1489 const size_t uch = size_t (lo->c);
1491 _rw_check_char (*
this, mf_toupper, uch);
1493 if (uch < 256 && masks_ [uch] &
LOWER) {
1495 lo->c =
UChar (uch - 32);
1497 lo->c =
UChar (uch + 64);
1504 RW_ASSERT (!
"do_toupper() not implemented");
1511ctype<UserChar>::char_type
1513do_tolower (char_type ch)
const
1515 _rw_funcall (*
this, mf_tolower);
1517 const size_t uch = size_t (ch.c);
1519 _rw_check_char (*
this, mf_toupper, uch);
1521 if (masks_ == _rw_char_masks) {
1522 if (uch < 256 && masks_ [uch] &
UPPER) {
1524 ch.c =
UChar (uch + 32);
1526 ch.c =
UChar (uch - 64);
1532 RW_ASSERT (!
"do_toupper() not implemented");
1539const ctype<UserChar>::char_type*
1541do_tolower (char_type *lo,
const char_type *hi)
const
1543 _rw_funcall (*
this, mf_tolower_range);
1545 if (masks_ == _rw_char_masks) {
1546 for ( ; lo < hi; ++lo) {
1548 const size_t uch = size_t (lo->c);
1550 if (uch < 256 && masks_ [uch] &
UPPER) {
1552 lo->c =
UChar (uch - 32);
1554 lo->c =
UChar (uch + 64);
1561 RW_ASSERT (!
"do_toupper() not implemented");
1568ctype<UserChar>::char_type
1570do_widen (
char ch)
const
1572 _rw_funcall (*
this, mf_widen);
1576 _rw_check_char (*
this, mf_toupper, uch);
1578 if (narrow_ && wide_) {
1579 for (
size_t i = 0; 0 <= narrow_ [
i]; ++
i) {
1580 if (
int (uch) == narrow_ [
i]) {
1584 if (throw_on_invalid_)
1598do_widen (
const char *lo,
const char *hi, char_type *dst)
const
1600 _rw_funcall (*
this, mf_widen_range);
1602 if (narrow_ && wide_) {
1603 for ( ; lo < hi; ++lo, ++dst) {
1605 const size_t uch = size_t (*lo);
1607 _rw_check_char (*
this, mf_toupper, uch);
1609 for (
size_t i = 0; 0 <= narrow_ [
i]; ++
i) {
1610 if (
int (uch) == narrow_ [
i]) {
1614 if (throw_on_invalid_)
1623 for (; lo < hi; ++lo, ++dst) {
1627 _rw_check_char (*
this, mf_toupper, uch);
1637char ctype<UserChar>::
1638do_narrow (char_type ch,
char dfault)
const
1640 _rw_funcall (*
this, mf_narrow);
1642 const size_t uch = size_t (ch.c);
1644 _rw_check_char (*
this, mf_toupper, uch);
1646 if (narrow_ && wide_) {
1647 for (
size_t i = 0; 0 <= wide_ [
i]; ++
i) {
1648 if (
int (uch) == wide_ [
i]) {
1650 return char (wide_ [
i]);
1652 if (throw_on_invalid_)
1666const ctype<UserChar>::char_type*
1668do_narrow (
const char_type *lo,
const char_type *hi,
char dflt,
char *dst)
const
1670 _rw_funcall (*
this, mf_narrow_range);
1672 if (narrow_ && wide_) {
1673 for ( ; lo < hi; ++lo, ++dst) {
1675 const size_t uch = size_t (lo->c);
1677 _rw_check_char (*
this, mf_toupper, uch);
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;
1688 for (; lo < hi; ++lo, ++dst) {
1690 const size_t uch = size_t (lo->c);
1692 _rw_check_char (*
this, mf_toupper, uch);
1710 masks_ = _rw_char_masks;
1715UserCtype (
const unsigned *chars,
const unsigned *masks,
size_t refs)
1721 masks = _rw_char_masks;
#define va_start(va, name)
#define _RWSTD_UNUSED(arg)
#define _RWSTD_NAMESPACE(name)
#define _RWSTD_CONST_CAST(T, x)
UserChar make_char(char c, UserChar *)
virtual const char * what() const =0
_RWSTD_SIZE_T n_throws_[n_funs]
_RWSTD_SIZE_T n_calls_[n_funs]
_RWSTD_SIZE_T throw_at_calls_[n_funs]
_RWSTD_SIZE_T n_all_calls_
UserCtypeBase(const char *)
_TEST_EXPORT int rw_vasnprintf(char **, size_t *, const char *, va_list)