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* __lo, const char* __hi, char* __dest) const
00587 {
00588 memcpy(__dest, __lo, __hi - __lo);
00589 return __hi;
00590 }
00591
00592 char
00593 ctype<char>::do_narrow(char __c, char ) const
00594 { return __c; }
00595
00596 const char*
00597 ctype<char>::do_narrow(const char* __lo, const char* __hi,
00598 char , char* __dest) const
00599 {
00600 memcpy(__dest, __lo, __hi - __lo);
00601 return __hi;
00602 }
00603
00604 template<>
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
00650
00651
00652
00653
00654
00655 template<>
00656 void
00657 num_get<char, istreambuf_iterator<char> >::
00658 _M_extract(istreambuf_iterator<char> __beg,
00659 istreambuf_iterator<char> __end, ios_base& __io,
00660 ios_base::iostate& __err, char* __xtrc, int& __base,
00661 bool __fp) const
00662 {
00663 typedef _Format_cache<char> __cache_type;
00664
00665
00666 __xtrc[0] = '\0';
00667
00668
00669 ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
00670 if (__basefield == ios_base::dec)
00671 __base = 10;
00672 else if (__basefield == ios_base::oct)
00673 __base = 8;
00674 else if (__basefield == ios_base::hex)
00675 __base = 16;
00676 else
00677 __base = 0;
00678
00679
00680 if (__fp)
00681 __base = 10;
00682
00683
00684 __cache_type const* __fmt = __cache_type::_S_get(__io);
00685
00686
00687 if (__beg == __end)
00688 {
00689 __err |= (ios_base::eofbit | ios_base::failbit);
00690 return;
00691 }
00692
00693
00694 string __grp;
00695 int __sep_pos = 0;
00696 int __pos = 0;
00697 const char* __lits = __fmt->_S_literals;
00698 char __c = *__beg;
00699
00700
00701 bool __testsign = false;
00702 if ((__c == __lits[__cache_type::_S_minus])
00703 || (__c == __lits[__cache_type::_S_plus]))
00704 {
00705 __testsign = true;
00706 __xtrc[__pos++] = __c;
00707 ++__beg;
00708 __c = * __beg;
00709
00710
00711 while ((__beg != __end) && (isspace(__c)))
00712 {
00713 ++__beg;
00714 __c = *__beg;
00715 }
00716
00717
00718 if (__beg == __end)
00719 {
00720 __xtrc[__pos] = '\0';
00721 __err |= (ios_base::eofbit | ios_base::failbit);
00722 return;
00723 }
00724 }
00725
00726
00727 bool __testzero = false;
00728 if (__c == __lits[__cache_type::_S_digits])
00729 {
00730 __testzero = true;
00731 ++__beg;
00732 __c = *__beg;
00733
00734
00735
00736 if (__beg == __end)
00737 {
00738 __xtrc[__pos++] = __lits[__cache_type::_S_digits];
00739 __xtrc[__pos] = '\0';
00740 __err |= ios_base::eofbit;
00741 return;
00742 }
00743
00744
00745
00746 if (!__fp && __base != 10 && __base != 8)
00747 {
00748
00749 if ((__c == __lits[__cache_type::_S_x])
00750 || (__c == __lits[__cache_type::_S_X]))
00751 {
00752 ++__beg;
00753 __c = *__beg;
00754 __base = 16;
00755 __testzero = false;
00756 }
00757 else if (__base == 0)
00758 __base = 8;
00759 }
00760
00761
00762 while (__beg != __end)
00763 {
00764 if (__c == __lits[__cache_type::_S_digits])
00765 {
00766 ++__beg;
00767 __c = *__beg;
00768 __testzero = true;
00769 }
00770 else
00771 break;
00772 }
00773 }
00774 else if (__base == 0)
00775 __base = 10;
00776
00777
00778
00779
00780 bool __testunits = __testzero;
00781 while (__beg != __end)
00782 {
00783 const char* __p = strchr(__lits, __c);
00784
00785
00786 if (__p && __c
00787 &&((__p >= &__lits[__cache_type::_S_digits]
00788 && __p < &__lits[__cache_type::_S_digits + __base])
00789 || (__p >= &__lits[__cache_type::_S_udigits]
00790 && __p < &__lits[__cache_type::_S_udigits + __base])))
00791 {
00792
00793 __xtrc[__pos++] = __c;
00794 if (__pos == _M_extract_buffer_length)
00795 {
00796
00797
00798 __xtrc[_M_extract_buffer_length-1] = '\0';
00799 __err |= ios_base::failbit;
00800 return;
00801 }
00802 ++__sep_pos;
00803 __testunits = true;
00804 ++__beg;
00805 __c = *__beg;
00806 }
00807 else if (__c == __fmt->_M_thousands_sep && __fmt->_M_use_grouping)
00808 {
00809
00810
00811
00812 if (__sep_pos)
00813 {
00814 __grp += static_cast<char>(__sep_pos);
00815 __sep_pos = 0;
00816 ++__beg;
00817 __c = *__beg;
00818 }
00819 else
00820 {
00821 __err |= ios_base::failbit;
00822 break;
00823 }
00824 }
00825 else
00826
00827 break;
00828 }
00829
00830
00831
00832 if (__fmt->_M_use_grouping && !__grp.empty())
00833 {
00834
00835 __grp += static_cast<char>(__sep_pos);
00836
00837
00838
00839
00840
00841 int __i = 0;
00842 int __j = 0;
00843 const int __len = __fmt->_M_grouping.size();
00844 int __n = __grp.size();
00845 bool __test = true;
00846
00847
00848
00849
00850 while (__test && __i < __n - 1)
00851 for (__j = 0; __test && __j < __len && __i < __n - 1; ++__j,++__i)
00852 __test &= __fmt->_M_grouping[__j] == __grp[__n - __i - 1];
00853
00854
00855 __j == __len ? __j = 0 : __j;
00856 __test &= __fmt->_M_grouping[__j] >= __grp[__n - __i - 1];
00857
00858 if (!__test)
00859 {
00860 __err |= ios_base::failbit;
00861 __xtrc[__pos] = '\0';
00862 if (__beg == __end)
00863 __err |= ios_base::eofbit;
00864 return;
00865 }
00866 }
00867
00868
00869 if (__testzero && (__pos == 0 || (__pos == 1 && __testsign)))
00870 __xtrc[__pos++] = __lits[__cache_type::_S_digits];
00871
00872
00873 if (__fp && __beg != __end)
00874 {
00875
00876
00877 bool __testdec = false;
00878
00879 if (__c == __fmt->_M_decimal_point)
00880 {
00881 __xtrc[__pos++] = '.';
00882 if (__pos == _M_extract_buffer_length)
00883 {
00884
00885
00886 __xtrc[_M_extract_buffer_length-1] = '\0';
00887 __err |= ios_base::failbit;
00888 return;
00889 }
00890 ++__beg;
00891 __c = *__beg;
00892
00893
00894
00895 while (__beg != __end)
00896 {
00897 const char* __p = strchr(__lits, __c);
00898 if ((__p >= &__lits[__cache_type::_S_digits]
00899 && __p < &__lits[__cache_type::_S_digits + __base])
00900 || (__p >= &__lits[__cache_type::_S_udigits]
00901 && __p < &__lits[__cache_type::_S_udigits + __base]))
00902 {
00903 __xtrc[__pos++] = __c;
00904 if (__pos == _M_extract_buffer_length)
00905 {
00906
00907
00908 __xtrc[_M_extract_buffer_length-1] = '\0';
00909 __err |= ios_base::failbit;
00910 return;
00911 }
00912 ++__beg;
00913 __c = *__beg;
00914 __testdec = true;
00915 }
00916 else
00917 break;
00918 }
00919 }
00920 if (!__testunits && !__testdec)
00921 {
00922 __err |= ios_base::failbit;
00923 __xtrc[__pos] = '\0';
00924 if (__beg == __end)
00925 __err |= ios_base::eofbit;
00926 return;
00927 }
00928
00929
00930 if (__beg != __end)
00931 {
00932 if ((__c == __lits[__cache_type::_S_ee])
00933 || (__c == __lits[__cache_type::_S_Ee]))
00934 {
00935 __xtrc[__pos++] = __c;
00936 if (__pos == _M_extract_buffer_length)
00937 {
00938
00939
00940 __xtrc[_M_extract_buffer_length-1] = '\0';
00941 __err |= ios_base::failbit;
00942 return;
00943 }
00944 ++__beg;
00945 __c = *__beg;
00946
00947
00948 if (__beg != __end)
00949 {
00950 if ((__c == __lits[__cache_type::_S_minus])
00951 || (__c == __lits[__cache_type::_S_plus]))
00952 {
00953 __xtrc[__pos++] = __c;
00954 if (__pos == _M_extract_buffer_length)
00955 {
00956
00957
00958 __xtrc[_M_extract_buffer_length-1] = '\0';
00959 __err |= ios_base::failbit;
00960 return;
00961 }
00962 ++__beg;
00963 __c = *__beg;
00964
00965 while ((__beg != __end) && (isspace(__c)))
00966 {
00967 ++__beg;
00968 __c = *__beg;
00969 }
00970 }
00971 }
00972
00973 if (__beg == __end)
00974 {
00975 __xtrc[__pos] = '\0';
00976 __err |= (ios_base::eofbit | ios_base::failbit);
00977 return;
00978 }
00979 while (__beg != __end)
00980 {
00981 const char* __p = strchr(__lits, __c);
00982 if ((__p >= &__lits[__cache_type::_S_digits]
00983 && __p < &__lits[__cache_type::_S_digits + __base])
00984 || (__p >= &__lits[__cache_type::_S_udigits]
00985 && __p < &__lits[__cache_type::_S_udigits + __base]))
00986 {
00987 __xtrc[__pos++] = __c;
00988 if (__pos == _M_extract_buffer_length)
00989 {
00990
00991
00992 __xtrc[_M_extract_buffer_length-1] = '\0';
00993 __err |= ios_base::failbit;
00994 return;
00995 }
00996 ++__beg;
00997 __c = *__beg;
00998 }
00999 else
01000 break;
01001 }
01002 }
01003 }
01004
01005 }
01006
01007
01008 __xtrc[__pos] = '\0';
01009 if (__beg == __end)
01010 __err |= ios_base::eofbit;
01011 }
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025 bool
01026 __build_float_format(ios_base& __io, char* __fptr, char __modifier,
01027 streamsize __prec)
01028 {
01029 bool __incl_prec = false;
01030 ios_base::fmtflags __flags = __io.flags();
01031 *__fptr++ = '%';
01032
01033 if (__flags & ios_base::showpos)
01034 *__fptr++ = '+';
01035 if (__flags & ios_base::showpoint)
01036 *__fptr++ = '#';
01037
01038 if (__flags & ios_base::fixed || __prec > 0)
01039 {
01040 *__fptr++ = '.';
01041 *__fptr++ = '*';
01042 __incl_prec = true;
01043 }
01044 if (__modifier)
01045 *__fptr++ = __modifier;
01046 ios_base::fmtflags __fltfield = __flags & ios_base::floatfield;
01047
01048 if (__fltfield == ios_base::fixed)
01049 *__fptr++ = 'f';
01050 else if (__fltfield == ios_base::scientific)
01051 *__fptr++ = (__flags & ios_base::uppercase) ? 'E' : 'e';
01052 else
01053 *__fptr++ = (__flags & ios_base::uppercase) ? 'G' : 'g';
01054 *__fptr = '\0';
01055 return __incl_prec;
01056 }
01057
01058 template <>
01059 collate<char>::collate(size_t __refs)
01060 : locale::facet(__refs) { }
01061
01062 template<>
01063 collate<char>::~collate() { }
01064
01065 template<>
01066 int
01067 collate<char>::do_compare(const char* __lo1, const char* __hi1,
01068 const char* __lo2, const char* __hi2) const
01069 {
01070 for (; __lo1 < __hi1 && __lo2 < __hi2; ++__lo1, ++__lo2)
01071 if (*__lo1 != *__lo2)
01072 return (*__lo1 < *__lo2) ? -1 : 1;
01073 if (__lo1 < __hi1)
01074 return 1;
01075 else if (__lo2 < __hi2)
01076 return -1;
01077 else
01078 return 0;
01079 }
01080
01081 template<>
01082 string
01083 collate<char>::
01084 do_transform(const char* __lo, const char* __hi) const
01085 { return string(__lo, __hi - __lo); }
01086
01087 template<>
01088 long
01089 collate<char>::
01090 do_hash(const char* __lo, const char* __hi) const
01091 {
01092 unsigned long __val = 0xdeadbeef;
01093 for (; __lo < __hi; ++__lo)
01094 __val = *__lo ^ ((__val << 7) &
01095 (__val >> (numeric_limits<unsigned long>::digits - 1)));
01096 return __val;
01097 }
01098
01099 template<>
01100 collate_byname<char>::collate_byname(const char* , size_t __refs)
01101 : collate<char>(__refs) { }
01102
01103 template<>
01104 moneypunct_byname<char, false>::moneypunct_byname(const char* ,
01105 size_t __refs)
01106 : moneypunct<char, false>(__refs) { }
01107
01108 template<>
01109 moneypunct_byname<char, true>::moneypunct_byname(const char* ,
01110 size_t __refs)
01111 : moneypunct<char, true>(__refs) { }
01112
01113 template<>
01114 messages_byname<char>::
01115 messages_byname(const char* , size_t __refs)
01116 : messages<char>(__refs) { }
01117
01118 #ifdef _GLIBCPP_USE_WCHAR_T
01119 ctype<wchar_t>::__wmask_type
01120 ctype<wchar_t>::_M_convert_to_wmask(const mask __m) const
01121 {
01122 __wmask_type __ret;
01123 switch (__m)
01124 {
01125 case space:
01126 __ret = wctype("space");
01127 break;
01128 case print:
01129 __ret = wctype("print");
01130 break;
01131 case cntrl:
01132 __ret = wctype("cntrl");
01133 break;
01134 case upper:
01135 __ret = wctype("upper");
01136 break;
01137 case lower:
01138 __ret = wctype("lower");
01139 break;
01140 case alpha:
01141 __ret = wctype("alpha");
01142 break;
01143 case digit:
01144 __ret = wctype("digit");
01145 break;
01146 case punct:
01147 __ret = wctype("punct");
01148 break;
01149 case xdigit:
01150 __ret = wctype("xdigit");
01151 break;
01152 case alnum:
01153 __ret = wctype("alnum");
01154 break;
01155 case graph:
01156 __ret = wctype("graph");
01157 break;
01158 default:
01159 __ret = 0;
01160 }
01161 return __ret;
01162 };
01163
01164 ctype<wchar_t>::~ctype() { }
01165
01166
01167
01168 ctype<wchar_t>::ctype(size_t __refs) : __ctype_abstract_base<wchar_t>(__refs)
01169 { }
01170
01171 wchar_t
01172 ctype<wchar_t>::do_toupper(wchar_t __c) const
01173 { return towupper(__c); }
01174
01175 const wchar_t*
01176 ctype<wchar_t>::do_toupper(wchar_t* __lo, const wchar_t* __hi) const
01177 {
01178 while (__lo < __hi)
01179 {
01180 *__lo = towupper(*__lo);
01181 ++__lo;
01182 }
01183 return __hi;
01184 }
01185
01186 wchar_t
01187 ctype<wchar_t>::do_tolower(wchar_t __c) const
01188 { return towlower(__c); }
01189
01190 const wchar_t*
01191 ctype<wchar_t>::do_tolower(wchar_t* __lo, const wchar_t* __hi) const
01192 {
01193 while (__lo < __hi)
01194 {
01195 *__lo = towlower(*__lo);
01196 ++__lo;
01197 }
01198 return __hi;
01199 }
01200
01201 bool
01202 ctype<wchar_t>::
01203 do_is(mask __m, char_type __c) const
01204 { return static_cast<bool>(iswctype(__c, _M_convert_to_wmask(__m))); }
01205
01206 const wchar_t*
01207 ctype<wchar_t>::
01208 do_is(const wchar_t* __lo, const wchar_t* __hi, mask* __m) const
01209 {
01210 while (__lo < __hi && !this->is(*__m, *__lo))
01211 ++__lo;
01212 return __lo;
01213 }
01214
01215 const wchar_t*
01216 ctype<wchar_t>::
01217 do_scan_is(mask __m, const wchar_t* __lo, const wchar_t* __hi) const
01218 {
01219 while (__lo < __hi && !this->is(__m, *__lo))
01220 ++__lo;
01221 return __lo;
01222 }
01223
01224 const wchar_t*
01225 ctype<wchar_t>::
01226 do_scan_not(mask __m, const char_type* __lo, const char_type* __hi) const
01227 {
01228 while (__lo < __hi && this->is(__m, *__lo) != 0)
01229 ++__lo;
01230 return __lo;
01231 }
01232
01233 wchar_t
01234 ctype<wchar_t>::
01235 do_widen(char __c) const
01236 { return btowc(__c); }
01237
01238 const char*
01239 ctype<wchar_t>::
01240 do_widen(const char* __lo, const char* __hi, wchar_t* __dest) const
01241 {
01242 mbstate_t __state;
01243 memset(static_cast<void*>(&__state), 0, sizeof(mbstate_t));
01244 mbsrtowcs(__dest, &__lo, __hi - __lo, &__state);
01245 return __hi;
01246 }
01247
01248 char
01249 ctype<wchar_t>::
01250 do_narrow(wchar_t __wc, char __dfault) const
01251 {
01252 int __c = wctob(__wc);
01253 return (__c == EOF ? __dfault : static_cast<char>(__c));
01254 }
01255
01256 const wchar_t*
01257 ctype<wchar_t>::
01258 do_narrow(const wchar_t* __lo, const wchar_t* __hi, char __dfault,
01259 char* __dest) const
01260 {
01261 mbstate_t __state;
01262 memset(static_cast<void*>(&__state), 0, sizeof(mbstate_t));
01263 size_t __len = __hi - __lo;
01264 size_t __conv = wcsrtombs(__dest, &__lo, __len, &__state);
01265 if (__conv == __len)
01266 *__dest = __dfault;
01267 return __hi;
01268 }
01269
01270 template<>
01271 ctype_byname<wchar_t>::
01272 ctype_byname(const char* , size_t __refs)
01273 : ctype<wchar_t>(__refs) { }
01274
01275 template<>
01276 collate<wchar_t>::
01277 collate(size_t __refs): locale::facet(__refs) { }
01278
01279 template<>
01280 collate<wchar_t>::
01281 ~collate() { }
01282
01283 template<>
01284 int
01285 collate<wchar_t>::
01286 do_compare(const wchar_t* , const wchar_t* ,
01287 const wchar_t* , const wchar_t* ) const
01288 {
01289 return 0;
01290 }
01291
01292 template<>
01293 wstring collate<wchar_t>::
01294 do_transform(const wchar_t* , const wchar_t* ) const
01295 {
01296 return wstring();
01297 }
01298
01299 template<>
01300 long collate<wchar_t>::
01301 do_hash(const wchar_t* , const wchar_t* ) const
01302 {
01303 return 0;
01304 }
01305
01306 template<>
01307 collate_byname<wchar_t>::
01308 collate_byname(const char* , size_t __refs)
01309 : collate<wchar_t> (__refs) { }
01310
01311 template<>
01312 messages_byname<wchar_t>::
01313 messages_byname(const char* , size_t __refs)
01314 : messages<wchar_t> (__refs) { }
01315 #endif // _GLIBCPP_USE_WCHAR_T
01316 }
01317