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 + -
显示快捷键?