31#if 3 == __GNUG__ && 3 > __GNUC_MINOR__ \
32 || 3 == __GNUC_MINOR__ && 1 >__GNUC_PATCHLEVEL__
36# ifndef _RWSTD_NO_EXTERN_TEMPLATE
37# define _RWSTD_NO_EXTERN_TEMPLATE
49#ifndef _RWSTD_NO_WCHAR_H
64#if _RWSTD_MB_LEN_MAX < 8
65# define _RWSTD_MB_MAX 8
67# define _RWSTD_MB_MAX _RWSTD_MB_LEN_MAX
71#if defined (_RWSTD_NO_WCSCOLL) && !defined (_RWSTD_NO_WCSCOLL_IN_LIBC)
76int wcscoll (
const wchar_t*,
const wchar_t*)
_LIBC_THROWS ();
78# undef _RWSTD_NO_WCSCOLL
85#ifdef _RWSTD_NO_WCSXFRM
86# ifndef _RWSTD_NO_WCSXFRM_IN_LIBC
91_RWSTD_SIZE_T wcsxfrm (
wchar_t*,
const wchar_t*, _RWSTD_SIZE_T)
_LIBC_THROWS ();
93# define _RWSTD_WCSXFRM wcsxfrm
94# undef _RWSTD_NO_WCSXFRM
99# define _RWSTD_WCSXFRM _RW::__rw_wcsxfrm
102# define _RWSTD_WCSXFRM wcsxfrm
106#if defined (_RWSTD_NO_WCSTOMBS) && !defined (_RWSTD_NO_WCSTOMBS_IN_LIBC)
112wcstombs (
char*,
const wchar_t*, _RWSTD_SIZE_T)
_LIBC_THROWS ();
114# undef _RWSTD_NO_WCSTOMBS
133int __rw_get_cat (
int);
136#ifndef _RWSTD_NO_WCHAR_T
139__rw_append_weight (
const _RW::__rw_collate_t *impl,
140 const unsigned *weights,
144 for (
int i = 0;
i < impl->longest_weight; ++
i, ++weights) {
146 const unsigned int wt = *weights;
150 if (wt && wt != _RWSTD_UINT_MAX) {
161__rw_append_weight (
const _RW::__rw_collate_t *impl,
162 const unsigned int *weights,
166 for (
int i = 0;
i < impl->longest_weight; ++
i, ++weights) {
168 unsigned wt = *weights;
173 if (wt && wt != _RWSTD_UINT_MAX) {
175 while (_RWSTD_CHAR_MAX < wt) {
176 out += char (_RWSTD_CHAR_MAX);
177 wt -= _RWSTD_CHAR_MAX;
188template <
class _STR_T>
190__rw_process_offsets (_RW::__rw_collate_t *impl,
191 const unsigned **
start,
192 const unsigned **
end,
198 for (
unsigned int pass = 0;
pass < impl->num_weights;
pass++) {
200 unsigned int shift_value = (impl->num_weights - (
pass + 1)) * 2;
202 const unsigned int** cur_start =
start;
203 const unsigned int** cur_end =
start;
205 if (*cur_start == *
end)
213 unsigned int cur_ord = (**cur_end >> shift_value) & 0x00000003;
214 while (cur_end !=
end && ((**cur_end >> shift_value)
215 & 0x00000003) == cur_ord) {
219 const unsigned int**
cur;
223 for (
cur = cur_start;
cur < cur_end;
cur++) {
224 const unsigned int* weightp = *
cur;
225 weightp = weightp + 1 +
pass * impl->longest_weight;
229 _RW::__rw_append_weight (impl, weightp,
out);
235 for (
cur = cur_end - 1;
cur >= cur_start;
cur --) {
236 const unsigned int* weightp = *
cur;
237 weightp = weightp + 1 +
pass * impl->longest_weight;
241 _RW::__rw_append_weight (impl, weightp,
out);
249 for (
cur = cur_start;
cur < cur_end;
cur++) {
250 const unsigned int* weightp = *
cur;
251 weightp = weightp + 1 +
pass * impl->longest_weight;
257 typedef typename _STR_T::value_type
CharT;
260 _STD::numeric_limits<CharT>::max ();
267 _RW::__rw_append_weight (impl, weightp,
out);
274 for (
cur = cur_end - 1;
cur >= cur_start;
cur --) {
275 const unsigned int* weightp = *
cur;
276 weightp = weightp + 1 +
pass * impl->longest_weight;
279 typedef typename _STR_T::value_type
CharT;
282 _STD::numeric_limits<CharT>::max ();
289 _RW::__rw_append_weight (impl, weightp,
out);
295 typedef typename _STR_T::value_type
CharT;
299 }
while (cur_end !=
end);
303#ifndef _RWSTD_NO_WCHAR_T
306__rw_get_w_ce_offset (
const __rw_collate_t *impl,
307 const wchar_t** cur_char,
314 if (impl->largest_ce > 1) {
316 unsigned int cur_tab = 0;
320 const unsigned int* tab;
321 while (*cur_char <
end) {
324 const _RWSTD_SIZE_T nbytes =
325 _RW::__rw_itoutf8 (**cur_char, utf8_enc);
327 for (_RWSTD_SIZE_T
i = 0;
i < nbytes;
i++) {
329 const unsigned c1 = impl->get_first_char_in_w_ce_tab (cur_tab);
330 const unsigned c2 = impl->get_last_char_in_w_ce_tab (cur_tab);
335 tab = impl->get_w_ce_tab (cur_tab);
337 const unsigned int next_off = tab [
UChar (utf8_enc [
i]) -
c1];
338 if (next_off == _RWSTD_UINT_MAX) {
342 if (next_off & 0x80000000) {
343 cur_tab = next_off &~ 0x80000000;
357__rw_get_wchar_offset (
const __rw_collate_t *impl,
358 const wchar_t** cur_char,
363 unsigned cur_tab = 0;
366 while (*cur_char <
end) {
368 const _RWSTD_SIZE_T nbytes =
369 _RW::__rw_itoutf8 (**cur_char, utf8_enc);
371 for (_RWSTD_SIZE_T
i = 0;
i < nbytes;
i++) {
372 const unsigned c1 = impl->get_first_char_in_w_tab (cur_tab);
376 const unsigned*
const tab = impl->get_w_tab (cur_tab);
378 const unsigned int next_off = tab [
UChar (utf8_enc [
i]) -
c1];
379 if (next_off == _RWSTD_UINT_MAX) {
383 if (next_off & 0x80000000) {
384 cur_tab = next_off &~ 0x80000000;
399__rw_get_n_ce_offset (
const __rw_collate_t *impl,
400 const char **cur_char,
403 if (impl->largest_ce > 1) {
404 unsigned int cur_tab = 0;
405 const unsigned int* tab;
407 while (*cur_char <
end ) {
408 const unsigned c1 = impl->get_first_char_in_n_ce_tab (cur_tab);
409 const unsigned c2 = impl->get_last_char_in_n_ce_tab (cur_tab);
413 tab = impl->get_n_ce_tab (cur_tab);
415 unsigned int next_off = tab [
UChar (**cur_char) -
c1];
416 if (next_off == _RWSTD_UINT_MAX) {
420 if (next_off & 0x80000000) {
422 cur_tab = next_off &~ 0x80000000;
434__rw_get_char_offset (
const __rw_collate_t *impl,
435 const char** cur_char,
438 unsigned int cur_tab = 0;
440 while (*cur_char <
end) {
441 unsigned c1 = impl->get_first_char_in_n_tab (cur_tab);
445 const unsigned int* tab = impl->get_n_tab (cur_tab);
446 c1 = impl->get_first_char_in_n_tab (cur_tab);
448 unsigned int next_off = tab [
UChar (**cur_char) -
c1];
449 if (next_off == _RWSTD_UINT_MAX) {
453 if (next_off & 0x80000000) {
455 cur_tab = next_off &~ 0x80000000;
469__rw_is_invalid (
const unsigned int* first_tab,
const char *from)
471 return 0 != (__rw_mbtowco (first_tab, from, 0) & 0x80000000);
479__rw_strnxfrm (
const char *src, _RWSTD_SIZE_T
nchars)
486 _RWSTD_SIZE_T bufsize =
sizeof buf;
494 const char*
const last = (
const char*)memchr (src,
'\0',
nchars);
505 pbuf =
new char [
nchars + 1];
509 memcpy (psrc, src,
nchars);
522 src += (
last - src) + 1;
528 char just_in_case_buf [8];
529 const _RWSTD_SIZE_T dst_size = strxfrm (just_in_case_buf, psrc, 0);
532 if (0 == (dst_size << 1))
533 return _STD::string ();
535 _RWSTD_SIZE_T res_size =
res.size ();
541 res.resize (res_size + dst_size + 1);
550 _RWSTD_SIZE_T xfrm_size =
551 strxfrm (&
res [0] + res_size, psrc, dst_size + 1);
553#if defined _MSC_VER && _MSC_VER < 1400
557 xfrm_size = strlen (&
res [0] + res_size);
564 res_size += xfrm_size + (
last && !*psrc && !xfrm_size);
567 res.resize (res_size);
583#ifndef _RWSTD_NO_WCHAR_T
585# ifdef _RWSTD_NO_WCSXFRM
591__rw_wcsxfrm (
wchar_t *dst,
const wchar_t *src, _RWSTD_SIZE_T dstsize)
599# ifndef _RWSTD_NO_WCSTOMBS
608 const _RWSTD_SIZE_T needbytes =
611 char narrow_buf [256];
613 sizeof narrow_buf < needbytes ?
new char [needbytes + 1] : narrow_buf;
617 const _RWSTD_SIZE_T nmbchars = wcstombs (nbuf, src, needbytes);
619 if (_RWSTD_SIZE_MAX == nmbchars)
625 char xfrm_buf [
sizeof narrow_buf * 8];
626 const _RWSTD_SIZE_T xbufsize =
sizeof xfrm_buf;
627 const _RWSTD_SIZE_T xbufneed = needbytes * 8;
632 xbufsize < xbufneed ?
new char [xbufneed + 1] : xfrm_buf;
636 result = strxfrm (xbuf, nbuf, xbufneed);
638 if (_RWSTD_SIZE_MAX !=
result && dstsize) {
646 for (_RWSTD_SIZE_T
i = 0;
i != dstsize; ++
i)
647 dst [
i] =
wchar_t (
UChar (xbuf [
i]));
651 if (xbuf != xfrm_buf)
656 if (nbuf != narrow_buf)
669 return _RWSTD_SIZE_MAX;
682__rw_wcsnxfrm (
const wchar_t *src, _RWSTD_SIZE_T
nchars)
689 _RWSTD_SIZE_T bufsize =
sizeof buf /
sizeof *
buf;
694 typedef _STD::char_traits<wchar_t>
Traits;
696 const wchar_t*
const last = Traits::find (src,
nchars,
L'\0');
707 pbuf =
new wchar_t [
nchars + 1];
711 memcpy (psrc, src,
nchars *
sizeof *psrc);
724 src += (
last - src) + 1;
730 wchar_t just_in_case_buf [8];
732 const _RWSTD_SIZE_T dst_size =
736 if (_RWSTD_SIZE_MAX == dst_size)
737 return _STD::wstring ();
739 _RWSTD_SIZE_T res_size =
res.size ();
745 res.resize (res_size + dst_size + 1);
754 _RWSTD_SIZE_T xfrm_size =
757# if defined _MSC_VER && _MSC_VER < 1400
761 xfrm_size = Traits::length (&
res [0] + res_size);
768 res_size += xfrm_size + (
last && !*psrc && !xfrm_size);
771 res.resize (res_size);
789template <
class _CharT>
790long __rw_hash (
const _CharT *lo,
const _CharT *hi)
_THROWS (())
796 const int long_bits = _RWSTD_CHAR_BIT * int (
sizeof (
long));
797 const int one_eighth = long_bits / 8;
798 const int three_fourths = long_bits * 3 / 4;
800 const long hi_bits = ~0
L << (long_bits - one_eighth);
804 for ( ; lo != hi; ++lo) {
805 typedef _STD::char_traits<_CharT> _Traits;
807 res = (
res << one_eighth) + _Traits::to_int_type (*lo);
809 const long tmp =
res & hi_bits;
811 res = (
res ^ (
tmp >> three_fourths)) & ~hi_bits;
817#ifndef _RWSTD_NO_INSTANTIATE
818# ifndef _RWSTD_NO_EXPLICIT_FUNC_INSTANTIATION
825template long __rw_hash (
const char*,
const char*)
_THROWS(());
827# ifndef _RWSTD_NO_WCHAR_T
829template long __rw_hash (
const wchar_t*,
const wchar_t*)
_THROWS(());
843_RW::__rw_facet_id collate<char>::id;
856do_compare (
const char_type *__lo1,
const char_type *__hi1,
857 const char_type *__lo2,
const char_type *__hi2)
const
861 const _RWSTD_SIZE_T __len1 = __hi1 - __lo1;
862 const _RWSTD_SIZE_T __len2 = __hi2 - __lo2;
864 const int cmp = memcmp (__lo1, __lo2, __len1 < __len2 ? __len1 : __len2);
867 return cmp < 0 ? -1 : 1;
869 return __len1 < __len2 ? -1 : __len2 < __len1 ? +1 : 0;
873collate<char>::string_type collate<char>::
874do_transform (
const char_type *__lo,
const char_type *__hi)
const
879 return string_type (__lo,
size_t (__hi - __lo));
884do_hash (
const char_type *__lo,
const char_type *__hi)
const
889 const string_type __str = do_transform (__lo, __hi);
891 __lo = __str.data ();
892 __hi = __lo + __str.length ();
894 const long res = _RW::__rw_hash (__lo, __hi);
902 collate_byname<char>::
909int collate_byname<char>::
910do_compare (
const char* low1,
const char* high1,
911 const char* low2,
const char* high2)
const
913 const string_type
s1 = do_transform (low1, high1);
914 const string_type
s2 = do_transform (low2, high2);
919 const int cmp =
s1.compare (
s2);
922 return cmp < 0 ? -1 :
cmp ? 1 : 0;
926collate_byname<char>::string_type
927collate_byname<char>::
928do_transform (
const char* low,
const char* high)
const
932 const int ccvt_cat = _RW::__rw_get_cat ((_C_wcodecvt_byname + 1) / 2);
934 _RW::__rw_collate_t*
const impl =
938 if (!impl || (this->_C_opts & this->_C_use_libc)) {
941 const _RW::__rw_setlocale clocale (_C_name, _RWSTD_LC_COLLATE);
943 return _RW::__rw_strnxfrm (low, high - low);
950 _RW::__rw_pod_array<const unsigned int*, 1024> indexes;
954 const char* tmp_lo = low;
956 for (; tmp_lo < high; tmp_lo++) {
957 const char* tmp_lo2 = tmp_lo;
958 int ret = _RW::__rw_get_n_ce_offset (impl, &tmp_lo2, high);
962 ret = _RW::__rw_get_char_offset (impl, &tmp_lo2, high);
970 if (impl->undefined_optimization) {
974 const _RW::__rw_codecvt_t *
cvt =
976 _RW::__rw_get_facet_data (
977 ccvt_cat,
size, _C_name,
978 impl->codeset_name ()));
980 if (_RW::__rw_is_invalid (
cvt->n_to_w_tab(), tmp_lo2))
983 const unsigned int *pwt =
984 impl->get_weight (impl->undefined_weight_idx);
985 indexes.append (&pwt, 1);
991 const unsigned int *pwt = impl->get_weight (ret);
992 indexes.append (&pwt, 1);
998 const unsigned int *pwt = impl->get_weight (ret);
999 indexes.append (&pwt, 1);
1005 _RW::__rw_process_offsets (impl, indexes.data (),
1006 indexes.data () + indexes.size (),
out);
1012#ifndef _RWSTD_NO_WCHAR_T
1014_RW::__rw_facet_id collate<wchar_t>::id;
1026int collate<wchar_t>::
1027do_compare (
const char_type *__lo1,
const char_type *__hi1,
1028 const char_type *__lo2,
const char_type *__hi2)
const
1032 const _RWSTD_SIZE_T __len1 = __hi1 - __lo1;
1033 const _RWSTD_SIZE_T __len2 = __hi2 - __lo2;
1035#ifndef _RWSTD_NO_WMEMCMP
1037 const int cmp = wmemcmp (__lo1, __lo2, __len1 < __len2 ? __len1 : __len2);
1040 return cmp < 0 ? -1 : 1;
1044 for (_RWSTD_SIZE_T __len = __len1 < __len2 ? __len1 : __len2;
1045 __len--; ++__lo1, ++__lo2) {
1047 typedef string_type::traits_type _Traits;
1048 typedef _Traits::int_type _Int;
1051 const _Int __i1 = _Traits::to_int_type (*__lo1);
1052 const _Int __i2 = _Traits::to_int_type (*__lo2);
1055 if (!_Traits::eq_int_type (__i1, __i2))
1056 return __i1 < __i2 ? -1 : 1;
1061 return __len1 < __len2 ? -1 : __len2 < __len1 ? +1 : 0;
1065collate<wchar_t>::string_type collate<wchar_t>::
1066do_transform (
const char_type *__lo,
const char_type *__hi)
const
1071 return string_type (__lo,
size_t (__hi - __lo));
1075long collate<wchar_t>::
1076do_hash (
const char_type *__lo,
const char_type *__hi)
const
1081 const string_type __str = do_transform (__lo, __hi);
1083 __lo = __str.data ();
1084 __hi = __lo + __str.length ();
1086 const long res = _RW::__rw_hash (__lo, __hi);
1094 collate_byname<wchar_t>::
1101int collate_byname<wchar_t>::
1102do_compare (
const wchar_t* low1,
const wchar_t* high1,
1103 const wchar_t* low2,
const wchar_t* high2)
const
1105 if (this->_C_opts & this->_C_use_libstd) {
1106 const string_type
s1 = do_transform (low1, high1);
1107 const string_type
s2 = do_transform (low2, high2);
1110 return s1.compare (
s2);
1113#ifndef _RWSTD_NO_WCSCOLL
1117 _RW::__rw_setlocale clocale (this->_C_name, _RWSTD_LC_COLLATE);
1119 const _RWSTD_SIZE_T len1 = high1 - low1;
1120 const _RWSTD_SIZE_T len2 = high2 - low2;
1121 const _RWSTD_SIZE_T
len = len1 + len2;
1124 wchar_t local_buffer [256];
1125 const _RWSTD_SIZE_T bufsize =
sizeof local_buffer /
sizeof *local_buffer;
1128 wchar_t*
const wbuf =
1129 len + 2 >= bufsize ?
new wchar_t [
len + 2] : local_buffer;
1132 char_traits<wchar_t>::copy (wbuf, low1, len1);
1136 char_traits<wchar_t>::copy (wbuf + len1 + 1, low2, len2);
1137 wbuf [len1 + 1 + len2] =
'\0';
1140 const int result = wcscoll (wbuf, wbuf + len1 + 1);
1143 if (wbuf != local_buffer)
1151 const string_type
s1 = do_transform (low1, high1);
1152 const string_type
s2 = do_transform (low2, high2);
1154 return s1.compare (
s2);
1161collate_byname<wchar_t>::string_type
1162collate_byname<wchar_t>::
1163do_transform (
const wchar_t* low,
const wchar_t* high)
const
1165 const int ccvt_cat = _RW::__rw_get_cat ((_C_wcodecvt_byname + 1) / 2);
1167 _RW::__rw_collate_t *impl =
1169 const _RW::__rw_collate_t*, _C_data ()));
1171 if (!impl || (this->_C_opts & this->_C_use_libc)) {
1174 const _RW::__rw_setlocale clocale (_C_name, _RWSTD_LC_COLLATE);
1176 return _RW::__rw_wcsnxfrm (low, high - low);
1182 _RW::__rw_pod_array<const unsigned int*, 1024> indexes;
1186 for (
const wchar_t* tmp_lo =low; tmp_lo < high; tmp_lo++) {
1187 const wchar_t* tmp_lo2 = tmp_lo;
1188 int ret = _RW::__rw_get_w_ce_offset (impl, &tmp_lo2, high);
1191 ret = _RW::__rw_get_wchar_offset (impl, &tmp_lo2, high);
1199 if (impl->undefined_optimization) {
1201 const _RW::__rw_codecvt_t *
cvt =
1203 _RW::__rw_get_facet_data (
1204 ccvt_cat,
size, _C_name,
1205 impl->codeset_name ()));
1209 const _RWSTD_SIZE_T nbytes =
1210 _RW::__rw_itoutf8 (*tmp_lo2,
tmp);
1212 tmp [nbytes] =
'\0';
1214 if (_RW::__rw_is_invalid (
cvt->w_to_n_tab (),
tmp))
1217 const unsigned int *pwt =
1218 impl->get_weight (impl->undefined_weight_idx);
1219 indexes.append (&pwt, 1);
1224 const unsigned int *pwt = impl->get_weight (ret);
1225 indexes.append (&pwt, 1);
1231 const unsigned int *pwt = impl->get_weight (ret);
1232 indexes.append (&pwt, 1);
1238 _RW::__rw_process_offsets (impl, indexes.data (),
1239 indexes.data () + indexes.size (),
out);
#define _RWSTD_UNUSED(arg)
#define _RWSTD_STATIC_CAST(T, x)
#define _RWSTD_NAMESPACE(name)
#define _RWSTD_ASSERT(ignore)
#define _RWSTD_CONST_CAST(T, x)