📄 locale_facets.tcc
字号:
// Finish up. if (__beg == __end) __err |= ios_base::eofbit; return __beg; } template<typename _CharT, typename _InIter> template<typename _ValueT> _InIter num_get<_CharT, _InIter>:: _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io, ios_base::iostate& __err, _ValueT& __v) const { typedef char_traits<_CharT> __traits_type; typedef typename numpunct<_CharT>::__cache_type __cache_type; __use_cache<__cache_type> __uc; const locale& __loc = __io._M_getloc(); const __cache_type* __lc = __uc(__loc); const _CharT* __lit = __lc->_M_atoms_in; // NB: Iff __basefield == 0, __base can change based on contents. const ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield; const bool __oct = __basefield == ios_base::oct; int __base = __oct ? 8 : (__basefield == ios_base::hex ? 16 : 10); // True if numeric digits are found. bool __found_num = false; // First check for sign. bool __negative = false; if (__beg != __end) { const char_type __c = *__beg; if (numeric_limits<_ValueT>::is_signed) __negative = __c == __lit[__num_base::_S_iminus]; if ((__negative || __c == __lit[__num_base::_S_iplus]) && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) && !(__c == __lc->_M_decimal_point)) ++__beg; } // Next, look for leading zeros and check required digits // for base formats. while (__beg != __end) { const char_type __c = *__beg; if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep || __c == __lc->_M_decimal_point) break; else if (__c == __lit[__num_base::_S_izero] && (!__found_num || __base == 10)) { __found_num = true; ++__beg; } else if (__found_num) { if (__c == __lit[__num_base::_S_ix] || __c == __lit[__num_base::_S_iX]) { if (__basefield == 0) __base = 16; if (__base == 16) { __found_num = false; ++__beg; } } else if (__basefield == 0) __base = 8; break; } else break; } // At this point, base is determined. If not hex, only allow // base digits as valid input. const size_t __len = __base == 16 ? (__num_base::_S_iend - __num_base::_S_izero) : __base; // Extract. string __found_grouping; if (__lc->_M_use_grouping) __found_grouping.reserve(32); int __sep_pos = 0; bool __overflow = false; _ValueT __result = 0; const char_type* __lit_zero = __lit + __num_base::_S_izero; const char_type* __q; if (__negative) { const _ValueT __min = numeric_limits<_ValueT>::min() / __base; for (; __beg != __end; ++__beg) { // According to 22.2.2.1.2, p8-9, first look for thousands_sep // and decimal_point. const char_type __c = *__beg; if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) { // NB: Thousands separator at the beginning of a string // is a no-no, as is two consecutive thousands separators. if (__sep_pos) { __found_grouping += static_cast<char>(__sep_pos); __sep_pos = 0; } else { __err |= ios_base::failbit; break; } } else if (__c == __lc->_M_decimal_point) break; else if (__q = __traits_type::find(__lit_zero, __len, __c)) { int __digit = __q - __lit_zero; if (__digit > 15) __digit -= 6; if (__result < __min) __overflow = true; else { const _ValueT __new_result = __result * __base - __digit; __overflow |= __new_result > __result; __result = __new_result; ++__sep_pos; __found_num = true; } } else // Not a valid input item. break; } } else { const _ValueT __max = numeric_limits<_ValueT>::max() / __base; for (; __beg != __end; ++__beg) { const char_type __c = *__beg; if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) { if (__sep_pos) { __found_grouping += static_cast<char>(__sep_pos); __sep_pos = 0; } else { __err |= ios_base::failbit; break; } } else if (__c == __lc->_M_decimal_point) break; else if (__q = __traits_type::find(__lit_zero, __len, __c)) { int __digit = __q - __lit_zero; if (__digit > 15) __digit -= 6; if (__result > __max) __overflow = true; else { const _ValueT __new_result = __result * __base + __digit; __overflow |= __new_result < __result; __result = __new_result; ++__sep_pos; __found_num = true; } } else break; } } // Digit grouping is checked. If grouping and found_grouping don't // match, then get very very upset, and set failbit. if (__lc->_M_use_grouping && __found_grouping.size()) { // Add the ending grouping. __found_grouping += static_cast<char>(__sep_pos); if (!std::__verify_grouping(__lc->_M_grouping, __lc->_M_grouping_size, __found_grouping)) __err |= ios_base::failbit; } if (!(__err & ios_base::failbit) && !__overflow && __found_num) __v = __result; else __err |= ios_base::failbit; if (__beg == __end) __err |= ios_base::eofbit; return __beg; } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 17. Bad bool parsing 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, bool& __v) const { if (!(__io.flags() & ios_base::boolalpha)) { // Parse bool values as long. // NB: We can't just call do_get(long) here, as it might // refer to a derived class. long __l = -1; __beg = _M_extract_int(__beg, __end, __io, __err, __l); if (__l == 0 || __l == 1) __v = __l; else __err |= ios_base::failbit; } else { // Parse bool values as alphanumeric. typedef char_traits<_CharT> __traits_type; typedef typename numpunct<_CharT>::__cache_type __cache_type; __use_cache<__cache_type> __uc; const locale& __loc = __io._M_getloc(); const __cache_type* __lc = __uc(__loc); bool __testf = true; bool __testt = true; size_t __n; for (__n = 0; __beg != __end; ++__n, ++__beg) { if (__testf) if (__n < __lc->_M_falsename_size) __testf = *__beg == __lc->_M_falsename[__n]; else break; if (__testt) if (__n < __lc->_M_truename_size) __testt = *__beg == __lc->_M_truename[__n]; else break; if (!__testf && !__testt) break; } if (__testf && __n == __lc->_M_falsename_size) __v = 0; else if (__testt && __n == __lc->_M_truename_size) __v = 1; else __err |= ios_base::failbit; if (__beg == __end) __err |= ios_base::eofbit; } 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& __v) const { return _M_extract_int(__beg, __end, __io, __err, __v); } 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 { return _M_extract_int(__beg, __end, __io, __err, __v); } 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 { return _M_extract_int(__beg, __end, __io, __err, __v); } 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 { return _M_extract_int(__beg, __end, __io, __err, __v); }#ifdef _GLIBCXX_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 { return _M_extract_int(__beg, __end, __io, __err, __v); } 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 { return _M_extract_int(__beg, __end, __io, __err, __v); }#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); std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_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); std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_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); std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_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; const fmtflags __fmt = __io.flags(); __io.flags(__fmt & ~ios_base::basefield | ios_base::hex); unsigned long __ul; __beg = _M_extract_int(__beg, __end, __io, __err, __ul); // Reset from hex formatted input. __io.flags(__fmt); if (!(__err & ios_base::failbit)) __v = reinterpret_cast<void*>(__ul); else __err |= ios_base::failbit; return __beg; } // For use by integer and floating-point types after they have been // converted into a char_type string. template<typename _CharT, typename _OutIter> void num_put<_CharT, _OutIter>:: _M_pad(_CharT __fill, streamsize __w, ios_base& __io, _CharT* __new, const _CharT* __cs, int& __len) const { // [22.2.2.2.2] Stage 3. // If necessary, pad. __pad<_CharT, char_traits<_CharT> >::_S_pad(__io, __fill, __new, __cs, __w, __len, true); __len = static_cast<int>(__w); } // Forwarding functions to peel signed from unsigned integer types. template<typename _CharT> inline int __int_to_char(_CharT* __bufend, long __v, const _CharT* __lit, ios_base::fmtflags __flags) { unsigned long __ul = static_cast<unsigned long>(__v); bool __neg = false; if (__v < 0) { __ul = -__ul; __neg = true; } return __int_to_char(__bufend, __ul, __lit, __flags, __neg); } template<typename _CharT> inline int __int_to_char(_CharT* __bufend, unsigned long __v, const _CharT* __lit, ios_base::fmtflags __flags) { // About showpos, see Table 60 and C99 7.19.6.1, p6 (+). return __int_to_char(__bufend, __v, __lit, __flags & ~ios_base::showpos, false); }#ifdef _GLIBCXX_USE_LONG_LONG template<typename _CharT>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -