00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <bits/std_clocale.h>
00029 #include <bits/std_cstring.h>
00030 #include <bits/std_cassert.h>
00031 #include <bits/std_cctype.h>
00032 #include <bits/std_limits.h>
00033 #include <exception>
00034 #include <bits/std_stdexcept.h>
00035 #include <bits/std_locale.h>
00036 #include <bits/std_istream.h>
00037 #include <bits/std_ostream.h>
00038 #include <bits/std_vector.h>
00039 #include <bits/std_memory.h>
00040 #ifdef _GLIBCPP_USE_WCHAR_T
00041 # include <bits/std_cwctype.h>
00042 #endif
00043
00044 namespace std
00045 {
00046
00047 const locale::category locale::none;
00048 const locale::category locale::ctype;
00049 const locale::category locale::numeric;
00050 const locale::category locale::collate;
00051 const locale::category locale::time;
00052 const locale::category locale::monetary;
00053 const locale::category locale::messages;
00054 const locale::category locale::all;
00055
00056 locale::_Impl* locale::_S_classic;
00057 locale::_Impl* locale::_S_global;
00058 const size_t locale::_S_num_categories;
00059 const size_t locale::_S_num_facets;
00060
00061
00062 locale::id ctype<char>::id;
00063 locale::id codecvt<char, char, mbstate_t>::id;
00064
00065 #ifdef _GLIBCPP_USE_WCHAR_T
00066 locale::id ctype<wchar_t>::id;
00067 locale::id codecvt<wchar_t, char, mbstate_t>::id;
00068 #endif
00069
00070
00071 size_t locale::id::_S_highwater;
00072
00073
00074 const locale::id* const
00075 locale::_Impl::_S_id_ctype[] =
00076 {
00077 &std::ctype<char>::id,
00078 &codecvt<char, char, mbstate_t>::id,
00079 #ifdef _GLIBCPP_USE_WCHAR_T
00080 &std::ctype<wchar_t>::id,
00081 &codecvt<wchar_t, char, mbstate_t>::id,
00082 #endif
00083 0
00084 };
00085
00086 const locale::id* const
00087 locale::_Impl::_S_id_numeric[] =
00088 {
00089 &num_get<char>::id,
00090 &num_put<char>::id,
00091 &numpunct<char>::id,
00092 #ifdef _GLIBCPP_USE_WCHAR_T
00093 &num_get<wchar_t>::id,
00094 &num_put<wchar_t>::id,
00095 &numpunct<wchar_t>::id,
00096 #endif
00097 0
00098 };
00099
00100 const locale::id* const
00101 locale::_Impl::_S_id_collate[] =
00102 {
00103 &std::collate<char>::id,
00104 #ifdef _GLIBCPP_USE_WCHAR_T
00105 &std::collate<wchar_t>::id,
00106 #endif
00107 0
00108 };
00109
00110 const locale::id* const
00111 locale::_Impl::_S_id_time[] =
00112 {
00113 &time_get<char>::id,
00114 &time_put<char>::id,
00115 #ifdef _GLIBCPP_USE_WCHAR_T
00116 &time_get<wchar_t>::id,
00117 &time_put<wchar_t>::id,
00118 #endif
00119 0
00120 };
00121
00122 const locale::id* const
00123 locale::_Impl::_S_id_monetary[] =
00124 {
00125 &money_get<char>::id,
00126 &money_put<char>::id,
00127 &moneypunct<char, false>::id,
00128 &moneypunct<char, true >::id,
00129 #ifdef _GLIBCPP_USE_WCHAR_T
00130 &money_get<wchar_t>::id,
00131 &money_put<wchar_t>::id,
00132 &moneypunct<wchar_t, false>::id,
00133 &moneypunct<wchar_t, true >::id,
00134 #endif
00135 0
00136 };
00137
00138 const locale::id* const
00139 locale::_Impl::_S_id_messages[] =
00140 {
00141 &std::messages<char>::id,
00142 #ifdef _GLIBCPP_USE_WCHAR_T
00143 &std::messages<wchar_t>::id,
00144 #endif
00145 0
00146 };
00147
00148 const locale::id* const* const
00149 locale::_Impl::_S_facet_categories[] =
00150 {
00151
00152 locale::_Impl::_S_id_ctype,
00153 locale::_Impl::_S_id_numeric,
00154 locale::_Impl::_S_id_collate,
00155 locale::_Impl::_S_id_time,
00156 locale::_Impl::_S_id_monetary,
00157 locale::_Impl::_S_id_messages,
00158 0
00159 };
00160
00161
00162
00163 money_base::pattern
00164 money_base::_S_construct_pattern(char __preceeds, char __space, char __posn)
00165 {
00166 pattern __ret;
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 switch (__posn)
00182 {
00183 case 1:
00184
00185 if (__space)
00186 {
00187
00188 if (__preceeds)
00189 {
00190 __ret.field[1] = symbol;
00191 __ret.field[2] = space;
00192 __ret.field[3] = value;
00193 }
00194 else
00195 {
00196 __ret.field[1] = value;
00197 __ret.field[2] = space;
00198 __ret.field[3] = symbol;
00199 }
00200 __ret.field[0] = sign;
00201 }
00202 else
00203 {
00204
00205 if (__preceeds)
00206 {
00207 __ret.field[1] = symbol;
00208 __ret.field[2] = value;
00209 }
00210 else
00211 {
00212 __ret.field[1] = value;
00213 __ret.field[2] = symbol;
00214 }
00215 __ret.field[0] = sign;
00216 __ret.field[3] = none;
00217 }
00218 break;
00219 case 2:
00220
00221 if (__space)
00222 {
00223
00224 if (__preceeds)
00225 {
00226 __ret.field[0] = symbol;
00227 __ret.field[1] = space;
00228 __ret.field[2] = value;
00229 }
00230 else
00231 {
00232 __ret.field[0] = value;
00233 __ret.field[1] = space;
00234 __ret.field[2] = symbol;
00235 }
00236 __ret.field[3] = sign;
00237 }
00238 else
00239 {
00240
00241 if (__preceeds)
00242 {
00243 __ret.field[0] = symbol;
00244 __ret.field[1] = value;
00245 }
00246 else
00247 {
00248 __ret.field[0] = value;
00249 __ret.field[1] = symbol;
00250 }
00251 __ret.field[2] = sign;
00252 __ret.field[3] = none;
00253 }
00254 break;
00255 case 3:
00256
00257 if (__space)
00258 {
00259
00260 if (__preceeds)
00261 {
00262 __ret.field[0] = sign;
00263 __ret.field[1] = symbol;
00264 __ret.field[2] = space;
00265 __ret.field[3] = value;
00266 }
00267 else
00268 {
00269 __ret.field[0] = value;
00270 __ret.field[1] = space;
00271 __ret.field[2] = sign;
00272 __ret.field[3] = symbol;
00273 }
00274 }
00275 else
00276 {
00277
00278 if (__preceeds)
00279 {
00280 __ret.field[0] = sign;
00281 __ret.field[1] = symbol;
00282 __ret.field[2] = value;
00283 }
00284 else
00285 {
00286 __ret.field[0] = value;
00287 __ret.field[1] = sign;
00288 __ret.field[2] = symbol;
00289 }
00290 __ret.field[3] = none;
00291 }
00292 break;
00293 case 4:
00294
00295 if (__space)
00296 {
00297
00298 if (__preceeds)
00299 {
00300 __ret.field[0] = symbol;
00301 __ret.field[1] = sign;
00302 __ret.field[2] = space;
00303 __ret.field[3] = value;
00304 }
00305 else
00306 {
00307 __ret.field[0] = value;
00308 __ret.field[1] = space;
00309 __ret.field[2] = symbol;
00310 __ret.field[3] = sign;
00311 }
00312 }
00313 else
00314 {
00315
00316 if (__preceeds)
00317 {
00318 __ret.field[0] = symbol;
00319 __ret.field[1] = sign;
00320 __ret.field[2] = value;
00321 }
00322 else
00323 {
00324 __ret.field[0] = value;
00325 __ret.field[1] = symbol;
00326 __ret.field[2] = sign;
00327 }
00328 __ret.field[3] = none;
00329 }
00330 break;
00331 default:
00332 ;
00333 }
00334 return __ret;
00335 }
00336
00337 locale::~locale() throw()
00338 { _M_impl->_M_remove_reference(); }
00339
00340 void
00341 locale::_M_coalesce(const locale& __base, const locale& __add,
00342 category __cat)
00343 {
00344 __cat = _S_normalize_category(__cat);
00345 _M_impl = new _Impl(*__base._M_impl, 1);
00346
00347 try
00348 { _M_impl->_M_replace_categories(__add._M_impl, __cat); }
00349 catch (...)
00350 {
00351 _M_impl->_M_remove_reference();
00352 __throw_exception_again;
00353 }
00354 }
00355
00356 locale::locale() throw()
00357 {
00358 _S_initialize();
00359 (_M_impl = _S_global)->_M_add_reference();
00360 }
00361
00362 locale::locale(const locale& __other) throw()
00363 { (_M_impl = __other._M_impl)->_M_add_reference(); }
00364
00365 locale::locale(_Impl* __ip) throw()
00366 : _M_impl(__ip)
00367 { __ip->_M_add_reference(); }
00368
00369 locale::locale(const char* __s)
00370 {
00371 if (__s)
00372 {
00373 if (strcmp(__s, "C") == 0 || strcmp(__s, "POSIX") == 0)
00374 (_M_impl = _S_classic)->_M_add_reference();
00375 else
00376 _M_impl = new _Impl(__s, 1);
00377 }
00378 else
00379 __throw_runtime_error("attempt to create locale from NULL name");
00380 }
00381
00382 locale::locale(const locale& __base, const char* __s, category __cat)
00383 {
00384
00385
00386
00387 locale __add(__s);
00388 _M_coalesce(__base, __add, __cat);
00389 }
00390
00391 locale::locale(const locale& __base, const locale& __add, category __cat)
00392 { _M_coalesce(__base, __add, __cat); }
00393
00394 bool
00395 locale::operator==(const locale& __rhs) const throw()
00396 {
00397 string __name = this->name();
00398 return (_M_impl == __rhs._M_impl
00399 || (__name != "*" && __name == __rhs.name()));
00400 }
00401
00402 const locale&
00403 locale::operator=(const locale& __other) throw()
00404 {
00405 __other._M_impl->_M_add_reference();
00406 _M_impl->_M_remove_reference();
00407 _M_impl = __other._M_impl;
00408 return *this;
00409 }
00410
00411 locale
00412 locale::global(const locale& __other)
00413 {
00414
00415 _S_initialize();
00416 locale __old(_S_global);
00417 __other._M_impl->_M_add_reference();
00418 _S_global->_M_remove_reference();
00419 _S_global = __other._M_impl;
00420 if (_S_global->_M_check_same_name() && _S_global->_M_names[0] != "*")
00421 setlocale(LC_ALL, __other.name().c_str());
00422 return __old;
00423 }
00424
00425 string
00426 locale::name() const
00427 {
00428 string __ret;
00429
00430
00431
00432 const char __separator = '|';
00433
00434 if (_M_impl->_M_check_same_name())
00435 __ret = _M_impl->_M_names[0];
00436 else
00437 {
00438 for (size_t i = 0; i < _S_num_categories; ++i)
00439 __ret += __separator + _M_impl->_M_names[i];
00440 }
00441 return __ret;
00442 }
00443
00444 locale const&
00445 locale::classic()
00446 {
00447 static locale* __classic_locale;
00448
00449 if (!_S_classic)
00450 {
00451 try
00452 {
00453
00454
00455 _S_classic = new _Impl("C", 2);
00456 _S_global = _S_classic;
00457
00458
00459 __classic_locale = new locale(_S_classic);
00460 }
00461 catch(...)
00462 {
00463 delete __classic_locale;
00464 if (_S_classic)
00465 {
00466 _S_classic->_M_remove_reference();
00467 _S_global->_M_remove_reference();
00468 }
00469 _S_classic = _S_global = 0;
00470
00471 __throw_exception_again;
00472 }
00473 }
00474 return *__classic_locale;
00475 }
00476
00477 locale::category
00478 locale::_S_normalize_category(category __cat)
00479 {
00480 int __ret = 0;
00481 if (__cat == none || (__cat & all) && !(__cat & ~all))
00482 __ret = __cat;
00483 else
00484 {
00485
00486 switch (__cat)
00487 {
00488 case LC_COLLATE:
00489 __ret = collate;
00490 break;
00491 case LC_CTYPE:
00492 __ret = ctype;
00493 break;
00494 case LC_MONETARY:
00495 __ret = monetary;
00496 break;
00497 case LC_NUMERIC:
00498 __ret = numeric;
00499 break;
00500 case LC_TIME:
00501 __ret = time;
00502 break;
00503 #ifdef _GLIBCPP_HAVE_LC_MESSAGES
00504 case LC_MESSAGES:
00505 __ret = messages;
00506 break;
00507 #endif
00508 case LC_ALL:
00509 __ret = all;
00510 break;
00511 default:
00512 __throw_runtime_error("bad locale category");
00513 }
00514 }
00515 return __ret;
00516 }
00517
00518 locale::facet::
00519 facet(size_t __refs) throw()
00520 : _M_references(__refs)
00521 { }
00522
00523 void
00524 locale::facet::
00525 _M_add_reference() throw()
00526 { ++_M_references; }
00527
00528 void
00529 locale::facet::
00530 _M_remove_reference() throw()
00531 {
00532 if (_M_references)
00533 --_M_references;
00534 else
00535 {
00536 try
00537 { delete this; }
00538 catch (...)
00539 { }
00540 }
00541 }
00542
00543
00544 const ctype_base::mask ctype_base::space;
00545 const ctype_base::mask ctype_base::print;
00546 const ctype_base::mask ctype_base::cntrl;
00547 const ctype_base::mask ctype_base::upper;
00548 const ctype_base::mask ctype_base::lower;
00549 const ctype_base::mask ctype_base::alpha;
00550 const ctype_base::mask ctype_base::digit;
00551 const ctype_base::mask ctype_base::punct;
00552 const ctype_base::mask ctype_base::xdigit;
00553 const ctype_base::mask ctype_base::alnum;
00554 const ctype_base::mask ctype_base::graph;
00555
00556
00557 #include <bits/ctype_noninline.h>
00558
00559 const size_t ctype<char>::table_size;
00560
00561 ctype<char>::~ctype()
00562 { if (_M_del) delete[] this->table(); }
00563
00564
00565 bool
00566 ctype<char>::do_is(mask, char_type) const
00567 { return false; }
00568
00569 const char*
00570 ctype<char>::do_is(const char_type* __c, const char_type*, mask*) const
00571 { return __c; }
00572
00573 const char*
00574 ctype<char>::do_scan_is(mask, const char_type* __c, const char_type*) const
00575 { return __c; }
00576
00577 const char*
00578 ctype<char>::do_scan_not(mask, const char_type* __c, const char_type*) const
00579 { return __c; }
00580
00581 char
00582 ctype<char>::do_widen(char __c) const
00583 { return __c; }
00584
00585 const char*
00586 ctype<char>::do_widen(const char* __low, const char* __high,
00587 char* __dest) const
00588 {
00589 memcpy(__dest, __low, __high - __low);
00590 return __high;
00591 }
00592
00593 char
00594 ctype<char>::do_narrow(char __c, char ) const
00595 { return __c; }
00596
00597 const char*
00598 ctype<char>::do_narrow(const char* __low, const char* __high,
00599 char , char* __dest) const
00600 {
00601 memcpy(__dest, __low, __high - __low);
00602 return __high;
00603 }
00604
00605 ctype_byname<char>::ctype_byname(const char* , size_t __refs)
00606 : ctype<char>(new mask[table_size], true, __refs)
00607 { }
00608
00609
00610 const money_base::pattern
00611 money_base::_S_default_pattern = {{symbol, sign, none, value}};
00612
00613 template<>
00614 _Format_cache<char>::_Format_cache()
00615 : _M_valid(true),
00616 _M_decimal_point('.'), _M_thousands_sep(','),
00617 _M_truename("true"), _M_falsename("false"), _M_use_grouping(false)
00618 { }
00619
00620 #ifdef _GLIBCPP_USE_WCHAR_T
00621 template<>
00622 _Format_cache<wchar_t>::_Format_cache()
00623 : _M_valid(true),
00624 _M_decimal_point(L'.'), _M_thousands_sep(L','),
00625 _M_truename(L"true"), _M_falsename(L"false"), _M_use_grouping(false)
00626 { }
00627 #endif
00628
00629 template<>
00630 const ctype<char>&
00631 use_facet<ctype<char> >(const locale& __loc)
00632 {
00633 size_t __i = ctype<char>::id._M_index;
00634 const locale::_Impl* __tmp = __loc._M_impl;
00635 return static_cast<const ctype<char>&>(* (*(__tmp->_M_facets))[__i]);
00636 }
00637
00638 #ifdef _GLIBCPP_USE_WCHAR_T
00639 template<>
00640 const ctype<wchar_t>&
00641 use_facet<ctype<wchar_t> >(const locale& __loc)
00642 {
00643 size_t __i = ctype<wchar_t>::id._M_index;
00644 const locale::_Impl* __tmp = __loc._M_impl;
00645 return static_cast<const ctype<wchar_t>&>(* (*(__tmp->_M_facets))[__i]);
00646 }
00647 #endif
00648
00649 template<>
00650 void
00651 num_get<char, istreambuf_iterator<char> >::
00652 _M_extract(istreambuf_iterator<char> __beg,
00653 istreambuf_iterator<char> __end, ios_base& __io,
00654 ios_base::iostate& __err, char* __xtrc, int& __base,
00655 bool __fp) const
00656 {
00657 typedef _Format_cache<char> __cache_type;
00658
00659
00660 __xtrc[0] = '\0';
00661
00662
00663 ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
00664 if (__basefield == ios_base::dec)
00665 __base = 10;
00666 else if (__basefield == ios_base::oct)
00667 __base = 8;
00668 else if (__basefield == ios_base::hex)
00669 __base = 16;
00670 else
00671 __base = 0;
00672
00673
00674 if (__fp)
00675 __base = 10;
00676
00677
00678 __cache_type const* __fmt = __cache_type::_S_get(__io);
00679 bool __valid = __beg != __end;
00680
00681 if (!__valid)
00682 {
00683 __err |= (ios_base::eofbit | ios_base::failbit);
00684 return;
00685 }
00686
00687
00688 string __grp;
00689 int __sep_pos = 0;
00690 int __pos = 0;
00691 const char* __lits = __fmt->_S_literals;
00692 char __c = *__beg;
00693
00694
00695 bool __testsign = false;
00696 if ((__c == __lits[__cache_type::_S_minus])
00697 || (__c == __lits[__cache_type::_S_plus]))
00698 {
00699 __xtrc[__pos++] = __c;
00700 ++__beg;
00701 __testsign = true;
00702
00703 while ((__beg != __end) && (isspace(*__beg)))
00704 ++__beg;
00705
00706
00707 if (__beg == __end)
00708 {
00709 __xtrc[__pos] = '\0';
00710 __err |= (ios_base::eofbit | ios_base::failbit);
00711 return;
00712 }
00713 }
00714
00715 bool __testzero = false;
00716
00717
00718 __c = *__beg;
00719 if (__c == __lits[__cache_type::_S_digits])
00720 {
00721 __testzero = true;
00722 ++__beg;
00723
00724
00725
00726 if (__beg == __end)
00727 {
00728 __xtrc[__pos++] = __c;
00729 __xtrc[__pos] = '\0';
00730 __err |= ios_base::eofbit;
00731 return;
00732 }
00733
00734
00735
00736 if (!__fp && __base != 10 && __base != 8)
00737 {
00738
00739 __c = *__beg;
00740 if ((__c == __lits[__cache_type::_S_x])
00741 || (__c == __lits[__cache_type::_S_X]))
00742 {
00743 ++__beg;
00744 __base = 16;
00745 __testzero = false;
00746 }
00747 else if (__base == 0)
00748 __base = 8;
00749 }
00750
00751
00752 while (__beg != __end)
00753 {
00754 if (*__beg == __lits[__cache_type::_S_digits])
00755 {
00756 ++__beg;
00757 __testzero = true;
00758 }
00759 else
00760 break;
00761 }
00762 }
00763 else if (__base == 0)
00764 __base = 10;
00765
00766
00767
00768
00769 bool __testunits = __testzero;
00770 while (__valid && __beg != __end)
00771 {
00772 __valid = false;
00773 __c = *__beg;
00774 const char* __p = strchr(__fmt->_S_literals, __c);
00775
00776
00777 if (__p && __c)
00778 {
00779
00780 if ((__p >= &__lits[__cache_type::_S_digits]
00781 && __p < &__lits[__cache_type::_S_digits + __base])
00782 || (__p >= &__lits[__cache_type::_S_udigits]
00783 && __p < &__lits[__cache_type::_S_udigits + __base]))
00784 {
00785 __xtrc[__pos++] = __c;
00786 ++__sep_pos;
00787 __valid = true;
00788 __testunits = true;
00789 }
00790 }
00791 else if (__c == __fmt->_M_thousands_sep
00792 && __fmt->_M_use_grouping)
00793 {
00794
00795
00796
00797 if (__sep_pos)
00798 {
00799 __grp += static_cast<char>(__sep_pos);
00800 __sep_pos = 0;
00801 __valid = true;
00802 }
00803 else
00804 __err |= ios_base::failbit;
00805 }
00806 if (__valid)
00807 ++__beg;
00808 }
00809
00810
00811
00812 if (__fmt->_M_use_grouping && !__grp.empty())
00813 {
00814
00815 __grp += static_cast<char>(__sep_pos);
00816
00817
00818
00819
00820
00821 int __i = 0;
00822 int __j = 0;
00823 const int __len = __fmt->_M_grouping.size();
00824 int __n = __grp.size();
00825 bool __test = true;
00826
00827
00828
00829
00830 while (__test && __i < __n - 1)
00831 for (__j = 0; __test && __j < __len && __i < __n - 1; ++__j,++__i)
00832 __test &= __fmt->_M_grouping[__j] == __grp[__n - __i - 1];
00833
00834
00835 __j == __len ? __j = 0 : __j;
00836 __test &= __fmt->_M_grouping[__j] >= __grp[__n - __i - 1];
00837
00838 if (!__test)
00839 {
00840 __err |= ios_base::failbit;
00841 __xtrc[__pos] = '\0';
00842 if (__beg == __end)
00843 __err |= ios_base::eofbit;
00844 return;
00845 }
00846 }
00847
00848
00849 if (__testzero && (__pos == 0 || (__pos == 1 && __testsign)))
00850 __xtrc[__pos++] = __lits[__cache_type::_S_digits];
00851
00852
00853 if (__fp && __beg != __end)
00854 {
00855 __c = *__beg;
00856
00857
00858 bool __testdec = false;
00859
00860 if (__c == __fmt->_M_decimal_point)
00861 {
00862 __xtrc[__pos++] = '.';
00863 ++__beg;
00864
00865
00866 while (__beg != __end)
00867 {
00868 __c = *__beg;
00869 const char* __p = strchr(__fmt->_S_literals, __c);
00870 if ((__p >= &__lits[__cache_type::_S_digits]
00871 && __p < &__lits[__cache_type::_S_digits + __base])
00872 || (__p >= &__lits[__cache_type::_S_udigits]
00873 && __p < &__lits[__cache_type::_S_udigits + __base]))
00874 {
00875 __xtrc[__pos++] = __c;
00876 ++__beg;
00877 __testdec = true;
00878 }
00879 else
00880 break;
00881 }
00882 }
00883 if (!__testunits && !__testdec)
00884 {
00885 __err |= ios_base::failbit;
00886 __xtrc[__pos] = '\0';
00887 if (__beg == __end)
00888 __err |= ios_base::eofbit;
00889 return;
00890 }
00891
00892
00893 if (__beg != __end)
00894 {
00895 __c = *__beg;
00896 if ((__c == __lits[__cache_type::_S_ee])
00897 || (__c == __lits[__cache_type::_S_Ee]))
00898 {
00899 __xtrc[__pos++] = __c;
00900 ++__beg;
00901
00902 if (__beg != __end)
00903 {
00904 __c = *__beg;
00905 if ((__c == __lits[__cache_type::_S_minus])
00906 || (__c == __lits[__cache_type::_S_plus]))
00907 {
00908 __xtrc[__pos++] = __c;
00909 ++__beg;
00910
00911 while ((__beg != __end) && (isspace(*__beg)))
00912 ++__beg;
00913
00914 }
00915 }
00916
00917 if (__beg == __end)
00918 {
00919 __xtrc[__pos] = '\0';
00920 __err |= (ios_base::eofbit | ios_base::failbit);
00921 return;
00922 }
00923 while (__beg != __end)
00924 {
00925 __c = *__beg;
00926 const char* __p = strchr(__fmt->_S_literals, __c);
00927 if ((__p >= &__lits[__cache_type::_S_digits]
00928 && __p < &__lits[__cache_type::_S_digits + __base])
00929 || (__p >= &__lits[__cache_type::_S_udigits]
00930 && __p < &__lits[__cache_type::_S_udigits + __base]))
00931 {
00932 __xtrc[__pos++] = __c;
00933 ++__beg;
00934 }
00935 else
00936 break;
00937 }
00938 }
00939 }
00940
00941 }
00942
00943
00944 __xtrc[__pos] = '\0';
00945 if (__beg == __end)
00946 __err |= ios_base::eofbit;
00947 }
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961 bool
00962 __build_float_format(ios_base& __io, char* __fptr, char __modifier,
00963 streamsize __prec)
00964 {
00965 bool __incl_prec = false;
00966 ios_base::fmtflags __flags = __io.flags();
00967 *__fptr++ = '%';
00968
00969 if (__flags & ios_base::showpos)
00970 *__fptr++ = '+';
00971 if (__flags & ios_base::showpoint)
00972 *__fptr++ = '#';
00973
00974 if (__flags & ios_base::fixed || __prec > 0)
00975 {
00976 *__fptr++ = '.';
00977 *__fptr++ = '*';
00978 __incl_prec = true;
00979 }
00980 if (__modifier)
00981 *__fptr++ = __modifier;
00982 ios_base::fmtflags __fltfield = __flags & ios_base::floatfield;
00983
00984 if (__fltfield == ios_base::fixed)
00985 *__fptr++ = 'f';
00986 else if (__fltfield == ios_base::scientific)
00987 *__fptr++ = (__flags & ios_base::uppercase) ? 'E' : 'e';
00988 else
00989 *__fptr++ = (__flags & ios_base::uppercase) ? 'G' : 'g';
00990 *__fptr = '\0';
00991 return __incl_prec;
00992 }
00993
00994 collate<char>::collate(size_t __refs)
00995 : locale::facet(__refs) { }
00996
00997 collate<char>::~collate() { }
00998
00999 int
01000 collate<char>::do_compare(const char* __lo1, const char* __hi1,
01001 const char* __lo2, const char* __hi2) const
01002 {
01003 for (; __lo1 < __hi1 && __lo2 < __hi2; ++__lo1, ++__lo2)
01004 if (*__lo1 != *__lo2)
01005 return (*__lo1 < *__lo2) ? -1 : 1;
01006 if (__lo1 < __hi1)
01007 return 1;
01008 else if (__lo2 < __hi2)
01009 return -1;
01010 else
01011 return 0;
01012 }
01013
01014 string
01015 collate<char>::
01016 do_transform(const char* __lo, const char* __hi) const
01017 { return string(__lo, __hi - __lo); }
01018
01019 long
01020 collate<char>::
01021 do_hash(const char* __lo, const char* __hi) const
01022 {
01023 unsigned long __val = 0xdeadbeef;
01024 for (; __lo < __hi; ++__lo)
01025 __val = *__lo ^ ((__val << 7) &
01026 (__val >> (numeric_limits<unsigned long>::digits - 1)));
01027 return __val;
01028 }
01029
01030 collate_byname<char>::collate_byname(const char* , size_t __refs)
01031 : collate<char>(__refs) { }
01032
01033 moneypunct_byname<char, false>::moneypunct_byname(const char* ,
01034 size_t __refs)
01035 : moneypunct<char, false>(__refs) { }
01036
01037 moneypunct_byname<char, true>::moneypunct_byname(const char* ,
01038 size_t __refs)
01039 : moneypunct<char, true>(__refs) { }
01040
01041 messages_byname<char>::
01042 messages_byname(const char* , size_t __refs)
01043 : messages<char>(__refs) { }
01044
01045 #ifdef _GLIBCPP_USE_WCHAR_T
01046 ctype<wchar_t>::__wmask_type
01047 ctype<wchar_t>::_M_convert_to_wmask(const mask __m) const
01048 {
01049 __wmask_type __ret;
01050 switch (__m)
01051 {
01052 case space:
01053 __ret = wctype("space");
01054 break;
01055 case print:
01056 __ret = wctype("print");
01057 break;
01058 case cntrl:
01059 __ret = wctype("cntrl");
01060 break;
01061 case upper:
01062 __ret = wctype("upper");
01063 break;
01064 case lower:
01065 __ret = wctype("lower");
01066 break;
01067 case alpha:
01068 __ret = wctype("alpha");
01069 break;
01070 case digit:
01071 __ret = wctype("digit");
01072 break;
01073 case punct:
01074 __ret = wctype("punct");
01075 break;
01076 case xdigit:
01077 __ret = wctype("xdigit");
01078 break;
01079 case alnum:
01080 __ret = wctype("alnum");
01081 break;
01082 case graph:
01083 __ret = wctype("graph");
01084 break;
01085 default:
01086 __ret = 0;
01087 }
01088 return __ret;
01089 };
01090
01091 ctype<wchar_t>::~ctype() { }
01092
01093
01094
01095 ctype<wchar_t>::ctype(size_t __refs) : __ctype_abstract_base<wchar_t>(__refs)
01096 { }
01097
01098 wchar_t
01099 ctype<wchar_t>::do_toupper(wchar_t __c) const
01100 { return towupper(__c); }
01101
01102 const wchar_t*
01103 ctype<wchar_t>::do_toupper(wchar_t* __low, const wchar_t* __high) const
01104 {
01105 while (__low < __high)
01106 {
01107 *__low = towupper(*__low);
01108 ++__low;
01109 }
01110 return __high;
01111 }
01112
01113 wchar_t
01114 ctype<wchar_t>::do_tolower(wchar_t __c) const
01115 { return towlower(__c); }
01116
01117 const wchar_t*
01118 ctype<wchar_t>::do_tolower(wchar_t* __low, const wchar_t* __high) const
01119 {
01120 while (__low < __high)
01121 {
01122 *__low = towlower(*__low);
01123 ++__low;
01124 }
01125 return __high;
01126 }
01127
01128 bool
01129 ctype<wchar_t>::
01130 do_is(mask __m, char_type __c) const
01131 { return static_cast<bool>(iswctype(__c, _M_convert_to_wmask(__m))); }
01132
01133 const wchar_t*
01134 ctype<wchar_t>::
01135 do_is(const wchar_t* __low, const wchar_t* __high, mask* __m) const
01136 {
01137 while (__low < __high && !this->is(*__m, *__low))
01138 ++__low;
01139 return __low;
01140 }
01141
01142 const wchar_t*
01143 ctype<wchar_t>::
01144 do_scan_is(mask __m, const wchar_t* __low, const wchar_t* __high) const
01145 {
01146 while (__low < __high && !this->is(__m, *__low))
01147 ++__low;
01148 return __low;
01149 }
01150
01151 const wchar_t*
01152 ctype<wchar_t>::
01153 do_scan_not(mask __m, const char_type* __low, const char_type* __high) const
01154 {
01155 while (__low < __high && this->is(__m, *__low) != 0)
01156 ++__low;
01157 return __low;
01158 }
01159
01160 wchar_t
01161 ctype<wchar_t>::
01162 do_widen(char __c) const
01163 { return btowc(__c); }
01164
01165 const char*
01166 ctype<wchar_t>::
01167 do_widen(const char* __low, const char* __high, wchar_t* __dest) const
01168 {
01169 mbstate_t __state;
01170 memset(static_cast<void*>(&__state), 0, sizeof(mbstate_t));
01171 mbsrtowcs(__dest, &__low, __high - __low, &__state);
01172 return __high;
01173 }
01174
01175 char
01176 ctype<wchar_t>::
01177 do_narrow(wchar_t __wc, char __dfault) const
01178 {
01179 int __c = wctob(__wc);
01180 return (__c == EOF ? __dfault : static_cast<char>(__c));
01181 }
01182
01183 const wchar_t*
01184 ctype<wchar_t>::
01185 do_narrow(const wchar_t* __low, const wchar_t* __high, char __dfault,
01186 char* __dest) const
01187 {
01188 mbstate_t __state;
01189 memset(static_cast<void*>(&__state), 0, sizeof(mbstate_t));
01190 size_t __len = __high - __low;
01191 size_t __conv = wcsrtombs(__dest, &__low, __len, &__state);
01192 if (__conv == __len)
01193 *__dest = __dfault;
01194 return __high;
01195 }
01196
01197 ctype_byname<wchar_t>::
01198 ctype_byname(const char* , size_t __refs)
01199 : ctype<wchar_t>(__refs) { }
01200
01201 collate<wchar_t>::
01202 collate(size_t __refs): locale::facet(__refs) { }
01203
01204 collate<wchar_t>::
01205 ~collate() { }
01206
01207 int
01208 collate<wchar_t>::
01209 do_compare(const wchar_t* , const wchar_t* ,
01210 const wchar_t* , const wchar_t* ) const
01211 {
01212 return 0;
01213 }
01214
01215 wstring collate<wchar_t>::
01216 do_transform(const wchar_t* , const wchar_t* ) const
01217 {
01218 return wstring();
01219 }
01220
01221 long collate<wchar_t>::
01222 do_hash(const wchar_t* , const wchar_t* ) const
01223 {
01224 return 0;
01225 }
01226
01227 collate_byname<wchar_t>::
01228 collate_byname(const char* , size_t __refs)
01229 : collate<wchar_t> (__refs) { }
01230
01231 messages_byname<wchar_t>::
01232 messages_byname(const char* , size_t __refs)
01233 : messages<wchar_t> (__refs) { }
01234 #endif // _GLIBCPP_USE_WCHAR_T
01235 }
01236