📄 locale_facets.tcc
字号:
const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); const __string_type __true = __np.truename(); const __string_type __false = __np.falsename(); const char_type* __trues = __true.c_str(); const char_type* __falses = __false.c_str(); const size_t __truen = __true.size() - 1; const size_t __falsen = __false.size() - 1; for (size_t __n = 0; __beg != __end; ++__n) { char_type __c = *__beg++; bool __testf = __n <= __falsen ? __traits_type::eq(__c, __falses[__n]) : false; bool __testt = __n <= __truen ? __traits_type::eq(__c, __trues[__n]) : false; if (!(__testf || __testt)) { __err |= ios_base::failbit; break; } else if (__testf && __n == __falsen) { __v = 0; break; } else if (__testt && __n == __truen) { __v = 1; break; } } if (__beg == __end) __err |= ios_base::eofbit; } return __beg; }#endif template<typename _CharT, typename _InIter> _InIter num_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, long& __v) const { string __xtrc; int __base; __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base); __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base); return __beg; } template<typename _CharT, typename _InIter> _InIter num_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, unsigned short& __v) const { string __xtrc; int __base; __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base); unsigned long __ul; __convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base); if (!(__err & ios_base::failbit) && __ul <= numeric_limits<unsigned short>::max()) __v = static_cast<unsigned short>(__ul); else __err |= ios_base::failbit; return __beg; } template<typename _CharT, typename _InIter> _InIter num_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, unsigned int& __v) const { string __xtrc; int __base; __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base); unsigned long __ul; __convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base); if (!(__err & ios_base::failbit) && __ul <= numeric_limits<unsigned int>::max()) __v = static_cast<unsigned int>(__ul); else __err |= ios_base::failbit; return __beg; } template<typename _CharT, typename _InIter> _InIter num_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, unsigned long& __v) const { string __xtrc; int __base; __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base); __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base); return __beg; }#ifdef _GLIBCPP_USE_LONG_LONG template<typename _CharT, typename _InIter> _InIter num_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, long long& __v) const { string __xtrc; int __base; __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base); __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base); return __beg; } template<typename _CharT, typename _InIter> _InIter num_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, unsigned long long& __v) const { string __xtrc; int __base; __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base); __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base); return __beg; }#endif template<typename _CharT, typename _InIter> _InIter num_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, float& __v) const { string __xtrc; __xtrc.reserve(32); __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale); return __beg; } template<typename _CharT, typename _InIter> _InIter num_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, double& __v) const { string __xtrc; __xtrc.reserve(32); __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale); return __beg; } template<typename _CharT, typename _InIter> _InIter num_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, long double& __v) const { string __xtrc; __xtrc.reserve(32); __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale); return __beg; } template<typename _CharT, typename _InIter> _InIter num_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, void*& __v) const { // Prepare for hex formatted input typedef ios_base::fmtflags fmtflags; fmtflags __fmt = __io.flags(); fmtflags __fmtmask = ~(ios_base::showpos | ios_base::basefield | ios_base::uppercase | ios_base::internal); __io.flags(__fmt & __fmtmask | (ios_base::hex | ios_base::showbase)); string __xtrc; int __base; __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base); // Reset from hex formatted input __io.flags(__fmt); unsigned long __ul; __convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base); if (!(__err & ios_base::failbit)) __v = reinterpret_cast<void*>(__ul); else __err |= ios_base::failbit; return __beg; } // The following code uses snprintf (or sprintf(), when _GLIBCPP_USE_C99 // is not defined) to convert floating point values for insertion into a // stream. An optimization would be to replace them with code that works // directly on a wide buffer and then use __pad to do the padding. // It would be good to replace them anyway to gain back the efficiency // that C++ provides by knowing up front the type of the values to insert. // Also, sprintf is dangerous since may lead to accidental buffer overruns. // This implementation follows the C++ standard fairly directly as // outlined in 22.2.2.2 [lib.locale.num.put] template<typename _CharT, typename _OutIter> template<typename _ValueT> _OutIter num_put<_CharT, _OutIter>:: _M_convert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod, _ValueT __v) const { // Note: digits10 is rounded down. We need to add 1 to ensure // we get the full available precision. const int __max_digits = numeric_limits<_ValueT>::digits10 + 1; streamsize __prec = __io.precision(); if (__prec > static_cast<streamsize>(__max_digits)) __prec = static_cast<streamsize>(__max_digits); // Long enough for the max format spec. char __fbuf[16]; // [22.2.2.2.2] Stage 1, numeric conversion to character. int __len;#ifdef _GLIBCPP_USE_C99 // First try a buffer perhaps big enough (for sure sufficient for // non-ios_base::fixed outputs) int __cs_size = __max_digits * 3; char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); const bool __fp = _S_format_float(__io, __fbuf, __mod, __prec); if (__fp) __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, _S_c_locale, __prec); else __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, _S_c_locale); // If the buffer was not large enough, try again with the correct size. if (__len >= __cs_size) { __cs_size = __len + 1; __cs = static_cast<char*>(__builtin_alloca(__cs_size)); if (__fp) __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, _S_c_locale, __prec); else __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, _S_c_locale); }#else // Consider the possibility of long ios_base::fixed outputs const bool __fixed = __io.flags() & ios_base::fixed; const int __max_exp = numeric_limits<_ValueT>::max_exponent10; // ios_base::fixed outputs may need up to __max_exp+1 chars // for the integer part + up to __max_digits chars for the // fractional part + 3 chars for sign, decimal point, '\0'. On // the other hand, for non-fixed outputs __max_digits*3 chars // are largely sufficient. const int __cs_size = __fixed ? __max_exp + __max_digits + 4 : __max_digits * 3; char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); if (_S_format_float(__io, __fbuf, __mod, __prec)) __len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale, __prec); else __len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale);#endif return _M_widen_float(__s, __io, __fill, __cs, __len); } template<typename _CharT, typename _OutIter> template<typename _ValueT> _OutIter num_put<_CharT, _OutIter>:: _M_convert_int(_OutIter __s, ios_base& __io, _CharT __fill, char __mod, char __modl, _ValueT __v) const { // [22.2.2.2.2] Stage 1, numeric conversion to character. // Long enough for the max format spec. char __fbuf[16]; _S_format_int(__io, __fbuf, __mod, __modl);#ifdef _GLIBCPP_USE_C99 // First try a buffer perhaps big enough. int __cs_size = 64; char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); int __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, _S_c_locale); // If the buffer was not large enough, try again with the correct size. if (__len >= __cs_size) { __cs_size = __len + 1; __cs = static_cast<char*>(__builtin_alloca(__cs_size)); __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, _S_c_locale); }#else // Leave room for "+/-," "0x," and commas. This size is // arbitrary, but should be largely sufficient. char __cs[128]; int __len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale);#endif return _M_widen_int(__s, __io, __fill, __cs, __len); } template<typename _CharT, typename _OutIter> _OutIter num_put<_CharT, _OutIter>:: _M_widen_float(_OutIter __s, ios_base& __io, _CharT __fill, char* __cs, int __len) const { typedef char_traits<_CharT> __traits_type; // [22.2.2.2.2] Stage 2, convert to char_type, using correct // numpunct.decimal_point() values for '.' and adding grouping. const locale __loc = __io.getloc(); const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len)); // Grouping can add (almost) as many separators as the number of // digits, but no more. _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len * 2)); __ctype.widen(__cs, __cs + __len, __ws); // Replace decimal point. const _CharT* __p; const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); if (__p = __traits_type::find(__ws, __len, __ctype.widen('.'))) __ws[__p - __ws] = __np.decimal_point();#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS//282. What types does numpunct grouping refer to? // Add grouping, if necessary. const string __grouping = __np.grouping(); ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield; if (__grouping.size()) { _CharT* __p2; int __declen = __p ? __p - __ws : __len; __p2 = __add_grouping(__ws2, __np.thousands_sep(), __grouping.c_str(), __grouping.c_str() + __grouping.size(), __ws, __ws + __declen); int __newlen = __p2 - __ws2; // Tack on decimal part. if (__p) { __traits_type::copy(__p2, __p, __len - __declen); __newlen += __len - __declen; } // Switch strings, establish correct new length. __ws = __ws2; __len = __newlen; }#endif return _M_insert(__s, __io, __fill, __ws, __len); } template<typename _CharT, typename _OutIter> _OutIter num_put<_CharT, _OutIter>:: _M_widen_int(_OutIter __s, ios_base& __io, _CharT __fill, char* __cs, int __len) const { // [22.2.2.2.2] Stage 2, convert to char_type, using correct // numpunct.decimal_point() values for '.' and adding grouping. const locale __loc = __io.getloc(); const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len)); // Grouping can add (almost) as many separators as the number of // digits, but no more. _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len * 2)); __ctype.widen(__cs, __cs + __len, __ws); // Add grouping, if necessary. const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); const string __grouping = __np.grouping(); const ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield; if (__grouping.size()) { // By itself __add_grouping cannot deal correctly with __ws when // ios::showbase is set and ios_base::oct || ios_base::hex. // Therefore we take care "by hand" of the initial 0, 0x or 0X. // However, remember that the latter do not occur if the number // printed is '0' (__len == 1). streamsize __off = 0; if ((__io.flags() & ios_base::showbase) && __len > 1) if (__basefield == ios_base::oct) { __off = 1; *__ws2 = *__ws; } else if (__basefield == ios_base::hex) { __off = 2; *__ws2 = *__ws; *(__ws2 + 1) = *(__ws + 1); } _CharT* __p; __p = __add_grouping(__ws2 + __off, __np.thousands_sep(), __grouping.c_str(), __grouping.c_str() + __grouping.size(), __ws + __off, __ws + __len);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -