locale_facets.tcc
来自「ARM Linux Tool 各种代码包括MTD」· TCC 代码 · 共 1,228 行 · 第 1/3 页
TCC
1,228 行
// Locale support -*- C++ -*-// Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.//// This file is part of the GNU ISO C++ Library. This library is free// software; you can redistribute it and/or modify it under the// terms of the GNU General Public License as published by the// Free Software Foundation; either version 2, or (at your option)// any later version.// This library is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.// You should have received a copy of the GNU General Public License along// with this library; see the file COPYING. If not, write to the Free// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,// USA.// As a special exception, you may use this file as part of a free software// library without restriction. Specifically, if other files instantiate// templates or use macros or inline functions from this file, or you compile// this file and link it with other files to produce an executable, this// file does not by itself cause the resulting executable to be covered by// the GNU General Public License. This exception does not however// invalidate any other reasons why the executable file might be covered by// the GNU General Public License.// Warning: this file is not meant for user inclusion. Use <locale>.#ifndef _CPP_BITS_LOCFACETS_TCC#define _CPP_BITS_LOCFACETS_TCC 1#include <bits/std_cerrno.h>#include <bits/std_clocale.h> // For localeconv#include <bits/std_cstdlib.h> // For strof, strtold#include <bits/std_limits.h> // For numeric_limits#include <bits/std_memory.h> // For auto_ptr#include <bits/sbuf_iter.h> // For streambuf_iterators#include <bits/std_cctype.h> // For isspace#include <typeinfo> // For bad_cast#include <bits/std_vector.h> namespace std{ template<typename _Facet> locale locale::combine(const locale& __other) { locale __copy(*this); __copy._M_impl->_M_replace_facet(__other._M_impl, &_Facet::id); return __copy; } template<typename _CharT, typename _Traits, typename _Alloc> bool locale::operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1, const basic_string<_CharT, _Traits, _Alloc>& __s2) const { typedef std::collate<_CharT> __collate_type; const __collate_type* __fcoll = &use_facet<__collate_type>(*this); return (__fcoll->compare(__s1.data(), __s1.data() + __s1.length(), __s2.data(), __s2.data() + __s2.length()) < 0); } template<typename _Facet> const _Facet& use_facet(const locale& __loc) { typedef locale::_Impl::__vec_facet __vec_facet; size_t __i = _Facet::id._M_index; __vec_facet* __facet = __loc._M_impl->_M_facets; const locale::facet* __fp = (*__facet)[__i]; if (__fp == 0 || __i >= __facet->size()) __throw_bad_cast(); return static_cast<const _Facet&>(*__fp); } template<typename _Facet> bool has_facet(const locale& __loc) throw() { typedef locale::_Impl::__vec_facet __vec_facet; size_t __i = _Facet::id._M_index; __vec_facet* __facet = __loc._M_impl->_M_facets; return (__i < __facet->size() && (*__facet)[__i] != 0); } // __match_parallel // matches input __s against a set of __ntargs strings in __targets, // placing in __matches a vector of indices into __targets which // match, and in __remain the number of such matches. If it hits // end of sequence before it minimizes the set, sets __eof. // Empty strings are never matched. template<typename _InIter, typename _CharT> _InIter __match_parallel(_InIter __s, _InIter __end, int __ntargs, const basic_string<_CharT>* __targets, int* __matches, int& __remain, bool& __eof) { typedef basic_string<_CharT> __string_type; __eof = false; for (int __ti = 0; __ti < __ntargs; ++__ti) __matches[__ti] = __ti; __remain = __ntargs; size_t __pos = 0; do { int __ti = 0; while (__ti < __remain && __pos == __targets[__matches[__ti]].size()) ++__ti; if (__ti == __remain) { if (__pos == 0) __remain = 0; return __s; } if (__s == __end) __eof = true; bool __matched = false; for (int __ti2 = 0; __ti2 < __remain; ) { const __string_type& __target = __targets[__matches[__ti2]]; if (__pos < __target.size()) { if (__eof || __target[__pos] != *__s) { __matches[__ti2] = __matches[--__remain]; continue; } __matched = true; } ++__ti2; } if (__matched) { ++__s; ++__pos; } for (int __ti3 = 0; __ti3 < __remain;) { if (__pos > __targets[__matches[__ti3]].size()) { __matches[__ti3] = __matches[--__remain]; continue; } ++__ti3; } } while (__remain); return __s; } template<typename _CharT> _Format_cache<_CharT>::_Format_cache() : _M_valid(true), _M_use_grouping(false) { } template<> _Format_cache<char>::_Format_cache(); template<> _Format_cache<wchar_t>::_Format_cache(); template<typename _CharT> void _Format_cache<_CharT>::_M_populate(ios_base& __io) { locale __loc = __io.getloc (); numpunct<_CharT> const& __np = use_facet<numpunct<_CharT> >(__loc); _M_truename = __np.truename(); _M_falsename = __np.falsename(); _M_thousands_sep = __np.thousands_sep(); _M_decimal_point = __np.decimal_point(); _M_grouping = __np.grouping(); _M_use_grouping = _M_grouping.size() != 0 && _M_grouping.data()[0] != 0; _M_valid = true; } // This function is always called via a pointer installed in // an ios_base by ios_base::register_callback. template<typename _CharT> void _Format_cache<_CharT>:: _S_callback(ios_base::event __ev, ios_base& __ios, int __ix) throw() { void*& __p = __ios.pword(__ix); switch (__ev) { case ios_base::erase_event: delete static_cast<_Format_cache<_CharT>*>(__p); __p = 0; break; case ios_base::copyfmt_event: // If just stored zero, the callback would get registered again. try { __p = new _Format_cache<_CharT>; } catch(...) { } break; case ios_base::imbue_event: static_cast<_Format_cache<_CharT>*>(__p)->_M_valid = false; break; } } template<typename _CharT> _Format_cache<_CharT>* _Format_cache<_CharT>::_S_get(ios_base& __ios) { if (!_S_pword_ix) _S_pword_ix = ios_base::xalloc(); // XXX MT void*& __p = __ios.pword(_S_pword_ix); // XXX What if pword fails? must check failbit, throw. if (__p == 0) // XXX MT? maybe sentry takes care of it { auto_ptr<_Format_cache<_CharT> > __ap(new _Format_cache<_CharT>); __ios.register_callback(&_Format_cache<_CharT>::_S_callback, _S_pword_ix); __p = __ap.release(); } _Format_cache<_CharT>* __ncp = static_cast<_Format_cache<_CharT>*>(__p); if (!__ncp->_M_valid) __ncp->_M_populate(__ios); return __ncp; } // This member function takes an (w)istreambuf_iterator object and // parses it into a generic char array suitable for parsing with // strto[l,ll,f,d]. The thought was to encapsulate the conversion // into this one function, and thus the num_get::do_get member // functions can just adjust for the type of the overloaded // argument and process the char array returned from _M_extract. // Other things were also considered, including a fused // multiply-add loop that would obviate the need for any call to // strto... at all: however, it would b e a bit of a pain, because // you'd have to be able to return either floating or integral // types, etc etc. The current approach seems to be smack dab in // the middle between an unoptimized approach using sscanf, and // some kind of hyper-optimized approach alluded to above. // XXX // Need to do partial specialization to account for differences // between character sets. For char, this is pretty // straightforward, but for wchar_t, the conversion to a plain-jane // char type is a bit more involved. template<typename _CharT, typename _InIter> void num_get<_CharT, _InIter>:: _M_extract(_InIter /*__beg*/, _InIter /*__end*/, ios_base& /*__io*/, ios_base::iostate& /*__err*/, char* /*__xtrc*/, int& /*__base*/, bool /*__fp*/) const { // XXX Not currently done: need to expand upon char version below. } template<> void num_get<char, istreambuf_iterator<char> >:: _M_extract(istreambuf_iterator<char> __beg, istreambuf_iterator<char> __end, ios_base& __io, ios_base::iostate& __err, char* __xtrc, int& __base, bool __fp) const;#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS // NB: This is an unresolved library defect #17 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 { // Parse bool values as long if (!(__io.flags() & ios_base::boolalpha)) { // NB: We can't just call do_get(long) here, as it might // refer to a derived class. // Stage 1: extract and determine the conversion specifier. // Assuming leading zeros eliminated, thus the size of 32 for // integral types. char __xtrc[32] = {'\0'}; int __base; _M_extract(__beg, __end, __io, __err, __xtrc, __base, false); // Stage 2: convert and store results. char* __sanity; errno = 0; long __l = strtol(__xtrc, &__sanity, __base); if (!(__err & ios_base::failbit) && __l <= 1 && __sanity != __xtrc && *__sanity == '\0' && errno == 0) __v = __l; else __err |= ios_base::failbit; } // Parse bool values as alphanumeric else { typedef _Format_cache<char_type> __fcache_type; __fcache_type* __fmt = __fcache_type::_S_get(__io); const char_type* __true = __fmt->_M_truename.c_str(); const char_type* __false = __fmt->_M_falsename.c_str(); const size_t __truelen = __traits_type::length(__true) - 1; const size_t __falselen = __traits_type::length(__false) - 1; for (size_t __pos = 0; __beg != __end; ++__pos) { char_type __c = *__beg++; bool __testf = __c == __false[__pos]; bool __testt = __c == __true[__pos]; if (!(__testf || __testt)) { __err |= ios_base::failbit; break; } else if (__testf && __pos == __falselen) { __v = 0; break; } else if (__testt && __pos == __truelen) { __v = 1; break; } } if (__beg == __end) __err |= ios_base::eofbit; } return __beg; }#endif#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS 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, short& __v) const { // Stage 1: extract and determine the conversion specifier. // Assuming leading zeros eliminated, thus the size of 32 for // integral types. char __xtrc[32]= {'\0'}; int __base; _M_extract(__beg, __end, __io, __err, __xtrc, __base, false); // Stage 2: convert and store results. char* __sanity; errno = 0; long __l = strtol(__xtrc, &__sanity, __base); if (!(__err & ios_base::failbit) && __sanity != __xtrc && *__sanity == '\0' && errno == 0 && __l >= SHRT_MIN && __l <= SHRT_MAX) __v = static_cast<short>(__l); 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, int& __v) const { // Stage 1: extract and determine the conversion specifier. // Assuming leading zeros eliminated, thus the size of 32 for // integral types. char __xtrc[32] = {'\0'}; int __base; _M_extract(__beg, __end, __io, __err, __xtrc, __base, false); // Stage 2: convert and store results. char* __sanity; errno = 0; long __l = strtol(__xtrc, &__sanity, __base); if (!(__err & ios_base::failbit) && __sanity != __xtrc && *__sanity == '\0' && errno == 0 && __l >= INT_MIN && __l <= INT_MAX) __v = static_cast<int>(__l); else __err |= ios_base::failbit; 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 { // Stage 1: extract and determine the conversion specifier. // Assuming leading zeros eliminated, thus the size of 32 for // integral types. char __xtrc[32]= {'\0'}; int __base; _M_extract(__beg, __end, __io, __err, __xtrc, __base, false); // Stage 2: convert and store results. char* __sanity;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?