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

📄 locale_facets.tcc

📁 俄罗斯高人Mamaich的Pocket gcc编译器(运行在PocketPC上)的全部源代码。
💻 TCC
📖 第 1 页 / 共 5 页
字号:
// Locale support -*- C++ -*-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004// 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#pragma GCC system_header#include <cerrno>#include <clocale>   		// For localeconv#include <cstdlib>   		// For strof, strtold#include <cmath>     		// For ceil#include <cctype>    		// For isspace#include <limits>    		// For numeric_limits#include <typeinfo>  		// For bad_cast.#include <bits/streambuf_iterator.h>namespace std{  template<typename _Facet>    locale    locale::combine(const locale& __other) const    {      _Impl* __tmp = new _Impl(*_M_impl, 1);      try	{	  __tmp->_M_replace_facet(__other._M_impl, &_Facet::id);	}      catch(...)	{	  __tmp->_M_remove_reference();	  __throw_exception_again;	}      return locale(__tmp);    }  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& __collate = use_facet<__collate_type>(*this);      return (__collate.compare(__s1.data(), __s1.data() + __s1.length(),				__s2.data(), __s2.data() + __s2.length()) < 0);    }  template<typename _Facet>    const _Facet&    use_facet(const locale& __loc)    {      size_t __i = _Facet::id._M_id();      locale::facet** __facets = __loc._M_impl->_M_facets;      if (!(__i < __loc._M_impl->_M_facets_size && __facets[__i]))        __throw_bad_cast();      return static_cast<const _Facet&>(*__facets[__i]);    }  template<typename _Facet>    bool    has_facet(const locale& __loc) throw()    {      size_t __i = _Facet::id._M_id();      locale::facet** __facets = __loc._M_impl->_M_facets;      return (__i < __loc._M_impl->_M_facets_size && __facets[__i]);    }  // Routine to access a cache for the locale.  If the cache didn't  // exist before, it gets constructed on the fly.  template<typename _Facet>    inline const __locale_cache<_Facet>&    __use_cache(const locale& __loc)    {      size_t __i = _Facet::id._M_id();      if (__builtin_expect(__i >= __loc._M_impl->_M_facets_size,false))	__throw_bad_cast();      __locale_cache_base* __cache = __loc._M_impl->_M_get_cache(__i);      if (__builtin_expect(!__cache, false))	{	  __cache = new __locale_cache<_Facet>(__loc);	  __loc._M_impl->_M_install_cache(__cache, __i);	}      return static_cast<const __locale_cache<_Facet>&>(*__cache);    }  // Stage 1: Determine a conversion specifier.  template<typename _CharT, typename _InIter>    _InIter    num_get<_CharT, _InIter>::    _M_extract_float(_InIter __beg, _InIter __end, ios_base& __io,		     ios_base::iostate& __err, string& __xtrc) const    {      typedef char_traits<_CharT>		__traits_type;      const locale __loc = __io.getloc();      const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);      const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);      // First check for sign.      const char_type __plus = __ctype.widen('+');      const char_type __minus = __ctype.widen('-');      int __pos = 0;      char_type  __c = *__beg;      if ((__traits_type::eq(__c, __plus) || __traits_type::eq(__c, __minus))	  && __beg != __end)	{	  __xtrc += __ctype.narrow(__c, char());	  ++__pos;	  __c = *(++__beg);	}      // Next, strip leading zeros.      const char_type __zero = __ctype.widen(_S_atoms_in[_M_zero]);      bool __found_zero = false;      while (__traits_type::eq(__c, __zero) && __beg != __end)	{	  __c = *(++__beg);	  __found_zero = true;	}      if (__found_zero)	{	  __xtrc += _S_atoms_in[_M_zero];	  ++__pos;	}      // Only need acceptable digits for floating point numbers.      const size_t __len = _M_E - _M_zero + 1;      char_type  __watoms[__len];      __ctype.widen(_S_atoms_in, _S_atoms_in + __len, __watoms);      bool __found_dec = false;      bool __found_sci = false;      const char_type __dec = __np.decimal_point();      string __found_grouping;      const string __grouping = __np.grouping();      bool __check_grouping = __grouping.size();      int __sep_pos = 0;      const char_type __sep = __np.thousands_sep();      while (__beg != __end)        {	  // Only look in digits.          const char_type* __p = __traits_type::find(__watoms, 10,  __c);          // NB: strchr returns true for __c == 0x0          if (__p && !__traits_type::eq(__c, char_type()))	    {	      // Try first for acceptable digit; record it if found.	      ++__pos;	      __xtrc += _S_atoms_in[__p - __watoms];	      ++__sep_pos;	      __c = *(++__beg);	    }          else if (__traits_type::eq(__c, __sep) 		   && __check_grouping && !__found_dec)	    {              // 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;		  __c = *(++__beg);                }              else		{		  __err |= ios_base::failbit;		  break;		}            }	  else if (__traits_type::eq(__c, __dec) && !__found_dec)	    {	      // According to the standard, if no grouping chars are seen,	      // no grouping check is applied. Therefore __found_grouping	      // must be adjusted only if __dec comes after some __sep.	      if (__found_grouping.size())		__found_grouping += static_cast<char>(__sep_pos);	      ++__pos;	      __xtrc += '.';	      __c = *(++__beg);	      __found_dec = true;	    }	  else if ((__traits_type::eq(__c, __watoms[_M_e]) 		    || __traits_type::eq(__c, __watoms[_M_E])) 		   && !__found_sci && __pos)	    {	      // Scientific notation.	      ++__pos;	      __xtrc += __ctype.narrow(__c, char());	      __c = *(++__beg);	      // Remove optional plus or minus sign, if they exist.	      if (__traits_type::eq(__c, __plus) 		  || __traits_type::eq(__c, __minus))		{		  ++__pos;		  __xtrc += __ctype.narrow(__c, char());		  __c = *(++__beg);		}	      __found_sci = true;	    }	  else	    // Not a valid input item.	    break;        }      // Digit grouping is checked. If grouping and found_grouping don't      // match, then get very very upset, and set failbit.      if (__check_grouping && __found_grouping.size())        {          // Add the ending grouping if a decimal wasn't found.	  if (!__found_dec)	    __found_grouping += static_cast<char>(__sep_pos);          if (!__verify_grouping(__grouping, __found_grouping))	    __err |= ios_base::failbit;        }      // Finish up      __xtrc += char();      if (__beg == __end)        __err |= ios_base::eofbit;      return __beg;    }  // Stage 1: Determine a conversion specifier.  template<typename _CharT, typename _InIter>    _InIter    num_get<_CharT, _InIter>::    _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io,		   ios_base::iostate& __err, string& __xtrc, int& __base) const    {      typedef char_traits<_CharT>		__traits_type;      const locale __loc = __io.getloc();      const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);      const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);       // NB: Iff __basefield == 0, this can change based on contents.      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;      // First check for sign.      int __pos = 0;      char_type  __c = *__beg;      const char_type __plus = __ctype.widen('+');      const char_type __minus = __ctype.widen('-');      if ((__traits_type::eq(__c, __plus) || __traits_type::eq(__c, __minus))	  && __beg != __end)	{	  __xtrc += __ctype.narrow(__c, char());	  ++__pos;	  __c = *(++__beg);	}      // Next, strip leading zeros and check required digits for base formats.      const char_type __zero = __ctype.widen(_S_atoms_in[_M_zero]);      const char_type __x = __ctype.widen('x');      const char_type __X = __ctype.widen('X');      if (__base == 10)	{	  bool __found_zero = false;	  while (__traits_type::eq(__c, __zero) && __beg != __end)	    {	      __c = *(++__beg);	      __found_zero = true;	    }	  if (__found_zero)	    {	      __xtrc += _S_atoms_in[_M_zero];	      ++__pos;	      if (__basefield == 0)		{	      		  if ((__traits_type::eq(__c, __x) 		       || __traits_type::eq(__c, __X))		      && __beg != __end)		    {		      __xtrc += __ctype.narrow(__c, char());		      ++__pos;		      __c = *(++__beg);		      __base = 16;		    }		  else 		    __base = 8;		}	    }	}      else if (__base == 16)	{	  if (__traits_type::eq(__c, __zero) && __beg != __end)	    {	      __xtrc += _S_atoms_in[_M_zero];	      ++__pos;	      __c = *(++__beg); 	      if ((__traits_type::eq(__c, __x) || __traits_type::eq(__c, __X))		  && __beg != __end)		{		  __xtrc += __ctype.narrow(__c, char());		  ++__pos;		  __c = *(++__beg);		}	    }	}      // At this point, base is determined. If not hex, only allow      // base digits as valid input.      size_t __len;      if (__base == 16)	__len = _M_size;      else	__len = __base;      // Extract.      char_type __watoms[_M_size];      __ctype.widen(_S_atoms_in, _S_atoms_in + __len, __watoms);      string __found_grouping;      const string __grouping = __np.grouping();      bool __check_grouping = __grouping.size();      int __sep_pos = 0;      const char_type __sep = __np.thousands_sep();      while (__beg != __end)        {          const char_type* __p = __traits_type::find(__watoms, __len,  __c);          // NB: strchr returns true for __c == 0x0          if (__p && !__traits_type::eq(__c, char_type()))	    {	      // Try first for acceptable digit; record it if found.	      __xtrc += _S_atoms_in[__p - __watoms];	      ++__pos;	      ++__sep_pos;	      __c = *(++__beg);	    }          else if (__traits_type::eq(__c, __sep) && __check_grouping)	    {              // 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;		  __c = *(++__beg);                }              else		{		  __err |= ios_base::failbit;		  break;		}            }	  else	    // Not a valid input item.	    break;        }      // Digit grouping is checked. If grouping and found_grouping don't      // match, then get very very upset, and set failbit.      if (__check_grouping && __found_grouping.size())        {          // Add the ending grouping.          __found_grouping += static_cast<char>(__sep_pos);          if (!__verify_grouping(__grouping, __found_grouping))	    __err |= ios_base::failbit;        }      // Finish up.      __xtrc += char();      if (__beg == __end)        __err |= ios_base::eofbit;      return __beg;    }#ifdef _GLIBCPP_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    {      // Parse bool values as unsigned 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.

⌨️ 快捷键说明

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