⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 locale_facets.tcc

📁 c++编程宝典源码及Quincy99编译器 是《标准C++编程宝典》电子工业出版社的光盘
💻 TCC
📖 第 1 页 / 共 3 页
字号:
// Locale support -*- C++ -*-// Copyright (C) 1997-1999 Cygnus Solutions//// 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_cstdlib.h> 	// For strof, strtold#include <bits/std_limits.h>	// For numeric_limits#include <bits/std_vector.h>#include <bits/std_memory.h>	// For auto_ptr#include <bits/sbuf_iter.h>	// For streambuf_iteratorsnamespace std{  template<typename _Facet>    locale     locale::combine(const locale& __other)    {      locale __copy(*this);      __copy._M_impl->_M_replace_facet(__other._M_impl, &_Facet::id);      __copy._M_impl->_M_has_name = false;      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    {      return use_facet< std::collate<_CharT> > (*this) (        __s1.data(), __s1.data() + __s1.length(),       __s2.data(), __s2.data() + __s2.length()) < 0;    }  template<typename _Facet>    const _Facet&    use_facet(const locale& __loc)    {      const locale::facet* __fp = (const _Facet*)0;    // check derivation      locale::id& __id = _Facet::id;         // check member id      size_t __i = __id._M_index;      const locale::_Impl* __tmp = __loc._M_impl;      if (__id._M_index >= __loc._M_impl->_M_facets->size() ||	  (__fp = (*(__tmp->_M_facets))[__i]) == 0)	return _Use_facet_failure_handler<_Facet>(__loc);      return static_cast<const _Facet&>(*__fp);    }  template<typename _Facet>    inline bool    has_facet(const locale& __loc) throw()    {      const locale::facet* __fp = (const _Facet*)0;   // check derivation      locale::id& __id = _Facet::id;         // check member id      size_t __i = __id._M_index;      const locale::_Impl* __tmp = __loc._M_impl;      return (__id._M_index < (*(__tmp->_M_facets))->size() &&	      (*(__tmp->_M_facets))[__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;	    for (;__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 __ti = 0; __ti < __remain; ) 	    {	      const __string_type& __target = __targets[__matches[__ti]];	      if (__pos < __target.size()) 		{		  if (__eof || __target[__pos] != *__s)		    { 		      __matches[__ti] = __matches[--__remain]; 		      continue; 		    }		  __matched = true;		}	      ++__ti;	    }	  if (__matched) 	    { 	      ++__s; 	      ++__pos; 	    }	  for (int __ti = 0; __ti < __remain;) 	    {	      if (__pos > __targets[__matches[__ti]].size())		{ 		  __matches[__ti] = __matches[--__remain]; 		  continue; 		}	      ++__ti;	    }	}       while (__remain);      return __s;    }    template<typename _CharT>    locale::id ctype<_CharT>::id;  template<typename _InternT, typename _ExternT, typename _StateT>    locale::id  codecvt<_InternT,_ExternT,_StateT>::id;  template<typename _CharT>    int _Format_cache<_CharT>::_S_pword_ix;  template<typename _CharT>    const char _Format_cache<_CharT>::    _S_literals[] = "-+xX0123456789abcdef0123456789ABCDEF";  template<typename _CharT>    _Format_cache<_CharT>::_Format_cache()    : _M_valid(true), _M_use_grouping(false)    { }  template<>    _Format_cache<char>::_Format_cache()    : _M_valid(true),     _M_decimal_point('.'), _M_thousands_sep(','),     _M_truename("true"), _M_falsename("false"), _M_use_grouping(false)    { } #ifdef _GLIBCPP_USE_WCHAR_T  template<>    _Format_cache<wchar_t>::_Format_cache()    : _M_valid(true),     _M_decimal_point(L'.'), _M_thousands_sep(L','),     _M_truename(L"true"), _M_falsename(L"false"), _M_use_grouping(false)    { }#endif  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;    }  template<typename _CharT, typename _InIter>    locale::id num_get<_CharT, _InIter>::id;  // 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(iter_type /*__beg*/, iter_type /*__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    {      typedef _Format_cache<char> __cache_type;      // Stage 1: determine a conversion specifier.      ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;      if (__basefield == ios_base::oct)	__base = 8;      else if (__basefield == ios_base::hex)	__base = 16;      else	__base = 10;            // Stage 2: extract characters.      __cache_type const* __fmt =__cache_type::_S_get(__io);      bool __valid = __beg != __end;      string __grp;      int __i;      int __pos = 0;      // XXX Need to deal with discarding leading zeros for non-octal numbers!      for (__i = 0; __valid && __beg != __end; ++__i, ++__beg)        {          __valid = false;          char __c = *__beg;	  const char* __lits = __fmt->_S_literals;	  char* __p = strchr(__fmt->_S_literals, __c);	  	  if (__p)	    {	      if (!__c) 		break;  // NB: strchr returns true for __c == 0x0	      if ((__p >= &__lits[__cache_type::_S_digits + __base]		   && __p < &__lits[__cache_type::_S_digits_end]) ||		  (__p >= &__lits[__cache_type::_S_udigits+__base]		   && __p < &__lits[__cache_type::_S_udigits_end]))		{		  if (!(__fp && (__p == &__lits[__cache_type::_S_ee] 				  || __p == &__lits[__cache_type::_S_Ee]))) 		    break;		}	      __xtrc[__pos] = __c;	      ++__pos;	      __valid = true;	    }          else if (__c == __fmt->_M_thousands_sep)            {              if (__fmt->_M_use_grouping)                __grp += static_cast<char>(__i);              __valid = true;            }	  else if (__c == __fmt->_M_decimal_point)             {               if (!__fp) 		 break;               __xtrc[__pos] = '.';               ++__pos;               __valid = true;             }	  if (!__valid) 	    break;  // NB: for otherwise we consume another character	}      __xtrc[__pos] = '\0';      if (__beg == __end)	__err |= ios_base::eofbit;            // Digit grouping is checked. If _M_groupings() doesn't      // match, then get very very upset, and set failbit.      if (__fmt->_M_use_grouping && __grp != __fmt->_M_grouping)	__err |= ios_base::failbit;    }    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))	{	  unsigned long __l = 0;	  this->do_get(__beg, __end, __io, __err, __l);	  if ((__err & ios_base::failbit) == 0)	    {	      if (__l <= 1) 		__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();	  char_type __itrue[sizeof(__true)]; 	  char_type __ifalse[sizeof(__false)];	  bool __valid = __beg != __end;	  int __pos = 0;	  for (; __valid; ++__pos)	    {	      __valid = false;	      char_type __c = *__beg++;	      if (__c == __false[__pos])		{		  __ifalse[__pos] = __c;		  __valid = true;		  if (__pos == sizeof(__false) - sizeof(char_type))		    {		      __err |= ios_base::goodbit;		      __v = 0;		    }		}	      else if (__c == __true[__pos])		{		  __itrue[__pos] = __c;		  __valid = true;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -