This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[v3] Speed up integer types parsing


Hi,

this is what I have finally committed. Tested i686-pc-linux-gnu
and x86_64-unknown-linux-gnu, both generic/gnu locale models.

Paolo.

/////////////
2003-12-08  Paolo Carlini  <pcarlini@suse.de>

	* config/locale/generic/c_locale.cc (__convert_to_v(long&),
	__convert_to_v(unsigned long&), __convert_to_v(long long&),
	__convert_to_v(unsigned long long&): Remove.
	(__convert_to_v(float&), __convert_to_v(double&),
	__convert_to_v(long double&)): Remove last unused parameter.
	* config/locale/gnu/c_locale.cc: Likewise.
	* include/bits/locale_facets.h: Likewise.
	(num_get::_M_extract_int): Update declaration.
	(class __num_base): Tweak _S_ie and _S_iE according to the
	_S_atoms_in changes.
	* include/bits/locale_facets.tcc (num_get::_M_extract_int):
	Provide directly the final _ValueT, not a string: accumulate
	the result checking for overflow at each digit.
	(num_get::do_get(bool&), num_get::do_get(long&),
	num_get::do_get(unsigned short&), num_get::do_get(unsigned int&),
	num_get::do_get(unsigned long&), num_get::do_get(long long&),
	num_get::do_get(unsigned long long&), num_get::do_get(void*&)):
	Use the new _M_extract_int, simplify.
	* src/locale-inst.cc (num_get::_M_extract_int(long&),
	num_get::_M_extract_int(unsigned short&),
	num_get::_M_extract_int(unsigned int&),
	num_get::_M_extract_int(unsigned long&),
	num_get::_M_extract_int(long long&),
	num_get::_M_extract_int(unsigned long long&): Instantiate.
	* src/locale_facets.cc (__num_base::_S_atoms_in): Reorder
        the chars in the natural order: abcdefABCDEF.

diff -prN libstdc++-v3-orig/config/locale/generic/c_locale.cc libstdc++-v3/config/locale/generic/c_locale.cc
*** libstdc++-v3-orig/config/locale/generic/c_locale.cc	Wed Oct 29 14:34:04 2003
--- libstdc++-v3/config/locale/generic/c_locale.cc	Sun Dec  7 11:01:59 2003
*************** namespace std 
*** 47,124 ****
    // Specializations for all types used in num_get.
    template<>
      void
-     __convert_to_v(const char* __s, long& __v, ios_base::iostate& __err, 
- 		   const __c_locale&, int __base)
-     {
-       if (!(__err & ios_base::failbit))
-       {
- 	char* __sanity;
- 	errno = 0;
- 	long __l = strtol(__s, &__sanity, __base);
- 	if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
- 	  __v = __l;
- 	else
- 	  __err |= ios_base::failbit;
-       }
-     }
- 
-   template<>
-     void
-     __convert_to_v(const char* __s, unsigned long& __v, 
- 		   ios_base::iostate& __err, const __c_locale&, int __base)
-     {
-       if (!(__err & ios_base::failbit))
- 	{
- 	  char* __sanity;
- 	  errno = 0;
- 	  unsigned long __ul = strtoul(__s, &__sanity, __base);
-           if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
- 	    __v = __ul;
- 	  else
- 	    __err |= ios_base::failbit;
- 	}
-     }
- 
- #ifdef _GLIBCXX_USE_LONG_LONG
-   template<>
-     void
-     __convert_to_v(const char* __s, long long& __v, ios_base::iostate& __err, 
- 		   const __c_locale&, int __base)
-     {
-       if (!(__err & ios_base::failbit))
- 	{
- 	  char* __sanity;
- 	  errno = 0;
- 	  long long __ll = strtoll(__s, &__sanity, __base);
-           if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
- 	    __v = __ll;
- 	  else
- 	    __err |= ios_base::failbit;
- 	}
-     }
- 
-   template<>
-     void
-     __convert_to_v(const char* __s, unsigned long long& __v, 
- 		   ios_base::iostate& __err, const __c_locale&, int __base)
-     {
-       if (!(__err & ios_base::failbit))
- 	{      
- 	  char* __sanity;
- 	  errno = 0;
- 	  unsigned long long __ull = strtoull(__s, &__sanity, __base);
-           if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
- 	    __v = __ull;
- 	  else
- 	    __err |= ios_base::failbit;
- 	}  
-     }
- #endif
- 
-   template<>
-     void
      __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err, 
! 		   const __c_locale&, int) 	      
      {
        if (!(__err & ios_base::failbit))
  	{
--- 47,54 ----
    // Specializations for all types used in num_get.
    template<>
      void
      __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err, 
! 		   const __c_locale&) 	      
      {
        if (!(__err & ios_base::failbit))
  	{
*************** namespace std 
*** 158,164 ****
    template<>
      void
      __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err, 
! 		   const __c_locale&, int) 
      {
        if (!(__err & ios_base::failbit))
  	{
--- 88,94 ----
    template<>
      void
      __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err, 
! 		   const __c_locale&) 
      {
        if (!(__err & ios_base::failbit))
  	{
*************** namespace std 
*** 180,186 ****
    template<>
      void
      __convert_to_v(const char* __s, long double& __v, 
! 		   ios_base::iostate& __err, const __c_locale&, int) 
      {
        if (!(__err & ios_base::failbit))
  	{
--- 110,116 ----
    template<>
      void
      __convert_to_v(const char* __s, long double& __v, 
! 		   ios_base::iostate& __err, const __c_locale&) 
      {
        if (!(__err & ios_base::failbit))
  	{
diff -prN libstdc++-v3-orig/config/locale/gnu/c_locale.cc libstdc++-v3/config/locale/gnu/c_locale.cc
*** libstdc++-v3-orig/config/locale/gnu/c_locale.cc	Wed Oct 29 11:08:01 2003
--- libstdc++-v3/config/locale/gnu/c_locale.cc	Sun Dec  7 11:00:49 2003
*************** namespace std 
*** 43,123 ****
  {
    template<>
      void
-     __convert_to_v(const char* __s, long& __v, ios_base::iostate& __err, 
- 		   const __c_locale& __cloc, int __base)
-     {
-       if (!(__err & ios_base::failbit))
-       {
- 	char* __sanity;
- 	errno = 0;
- 	long __l = __strtol_l(__s, &__sanity, __base, __cloc);
- 	if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
- 	  __v = __l;
- 	else
- 	  __err |= ios_base::failbit;
-       }
-     }
- 
-   template<>
-     void
-     __convert_to_v(const char* __s, unsigned long& __v, 
- 		   ios_base::iostate& __err, const __c_locale& __cloc, 
- 		   int __base)
-     {
-       if (!(__err & ios_base::failbit))
- 	{
- 	  char* __sanity;
- 	  errno = 0;
- 	  unsigned long __ul = __strtoul_l(__s, &__sanity, __base, __cloc);
-           if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
- 	    __v = __ul;
- 	  else
- 	    __err |= ios_base::failbit;
- 	}
-     }
- 
- #ifdef _GLIBCXX_USE_LONG_LONG
-   template<>
-     void
-     __convert_to_v(const char* __s, long long& __v, ios_base::iostate& __err, 
- 		   const __c_locale& __cloc, int __base)
-     {
-       if (!(__err & ios_base::failbit))
- 	{
- 	  char* __sanity;
- 	  errno = 0;
- 	  long long __ll = __strtoll_l(__s, &__sanity, __base, __cloc);
-           if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
- 	    __v = __ll;
- 	  else
- 	    __err |= ios_base::failbit;
- 	}
-     }
- 
-   template<>
-     void
-     __convert_to_v(const char* __s, unsigned long long& __v, 
- 		   ios_base::iostate& __err, const __c_locale& __cloc, 
- 		   int __base)
-     {
-       if (!(__err & ios_base::failbit))
- 	{      
- 	  char* __sanity;
- 	  errno = 0;
- 	  unsigned long long __ull = __strtoull_l(__s, &__sanity, __base, 
- 						  __cloc);
-           if (__sanity != __s && *__sanity == '\0' && errno != ERANGE)
- 	    __v = __ull;
- 	  else
- 	    __err |= ios_base::failbit;
- 	}  
-     }
- #endif
- 
-   template<>
-     void
      __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err, 
! 		   const __c_locale& __cloc, int)
      {
        if (!(__err & ios_base::failbit))
  	{
--- 43,50 ----
  {
    template<>
      void
      __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err, 
! 		   const __c_locale& __cloc)
      {
        if (!(__err & ios_base::failbit))
  	{
*************** namespace std 
*** 134,140 ****
    template<>
      void
      __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err, 
! 		   const __c_locale& __cloc, int)
      {
        if (!(__err & ios_base::failbit))
  	{
--- 61,67 ----
    template<>
      void
      __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err, 
! 		   const __c_locale& __cloc)
      {
        if (!(__err & ios_base::failbit))
  	{
*************** namespace std 
*** 151,157 ****
    template<>
      void
      __convert_to_v(const char* __s, long double& __v, ios_base::iostate& __err,
! 		   const __c_locale& __cloc, int)
      {
        if (!(__err & ios_base::failbit))
  	{
--- 78,84 ----
    template<>
      void
      __convert_to_v(const char* __s, long double& __v, ios_base::iostate& __err,
! 		   const __c_locale& __cloc)
      {
        if (!(__err & ios_base::failbit))
  	{
diff -prN libstdc++-v3-orig/include/bits/locale_facets.h libstdc++-v3/include/bits/locale_facets.h
*** libstdc++-v3-orig/include/bits/locale_facets.h	Wed Nov 26 12:47:01 2003
--- libstdc++-v3/include/bits/locale_facets.h	Sun Dec  7 14:05:05 2003
*************** namespace std
*** 63,107 ****
    template<typename _Tv>
      void
      __convert_to_v(const char* __in, _Tv& __out, ios_base::iostate& __err, 
! 		   const __c_locale& __cloc, int __base = 10);
  
    // Explicit specializations for required types.
    template<>
      void
-     __convert_to_v(const char*, long&, ios_base::iostate&, 
- 		   const __c_locale&, int);
- 
-   template<>
-     void
-     __convert_to_v(const char*, unsigned long&, ios_base::iostate&, 
- 		   const __c_locale&, int);
- 
- #ifdef _GLIBCXX_USE_LONG_LONG
-   template<>
-     void
-     __convert_to_v(const char*, long long&, ios_base::iostate&, 
- 		   const __c_locale&, int);
- 
-   template<>
-     void
-     __convert_to_v(const char*, unsigned long long&, ios_base::iostate&, 
- 		   const __c_locale&, int);
- #endif
- 
-   template<>
-     void
      __convert_to_v(const char*, float&, ios_base::iostate&, 
! 		   const __c_locale&, int);
  
    template<>
      void
      __convert_to_v(const char*, double&, ios_base::iostate&, 
! 		   const __c_locale&, int);
  
!  template<>
      void
      __convert_to_v(const char*, long double&, ios_base::iostate&, 
! 		   const __c_locale&, int);
  
    // NB: __pad is a struct, rather than a function, so it can be
    // partially-specialized.
--- 63,85 ----
    template<typename _Tv>
      void
      __convert_to_v(const char* __in, _Tv& __out, ios_base::iostate& __err, 
! 		   const __c_locale& __cloc);
  
    // Explicit specializations for required types.
    template<>
      void
      __convert_to_v(const char*, float&, ios_base::iostate&, 
! 		   const __c_locale&);
  
    template<>
      void
      __convert_to_v(const char*, double&, ios_base::iostate&, 
! 		   const __c_locale&);
  
!   template<>
      void
      __convert_to_v(const char*, long double&, ios_base::iostate&, 
! 		   const __c_locale&);
  
    // NB: __pad is a struct, rather than a function, so it can be
    // partially-specialized.
*************** namespace std
*** 586,592 ****
      static const char* _S_atoms_out;
  
      // String literal of acceptable (narrow) input, for num_get.
!     // "-+xX0123456789eEabcdfABCDF"
      static const char* _S_atoms_in;
  
      enum 
--- 564,570 ----
      static const char* _S_atoms_out;
  
      // String literal of acceptable (narrow) input, for num_get.
!     // "-+xX0123456789abcdefABCDEF"
      static const char* _S_atoms_in;
  
      enum 
*************** namespace std
*** 596,603 ****
        _S_ix, 
        _S_iX, 
        _S_izero,
!       _S_ie = _S_izero + 10,
!       _S_iE = _S_izero + 11,
        _S_iend = 26
      };
  
--- 574,581 ----
        _S_ix, 
        _S_iX, 
        _S_izero,
!       _S_ie = _S_izero + 14,
!       _S_iE = _S_izero + 20,
        _S_iend = 26
      };
  
*************** namespace std
*** 624,630 ****
        _CharT                    	_M_atoms_out[__num_base::_S_oend + 1];
  
        // A list of valid numeric literals for input: in the standard
!       // "C" locale, this is "-+xX0123456789eEabcdfABCDF"
        // This array contains the chars after having been passed
        // through the current locale's ctype<_CharT>.widen().
        _CharT                    	_M_atoms_in[__num_base::_S_iend + 1];
--- 602,608 ----
        _CharT                    	_M_atoms_out[__num_base::_S_oend + 1];
  
        // A list of valid numeric literals for input: in the standard
!       // "C" locale, this is "-+xX0123456789abcdefABCDEF"
        // This array contains the chars after having been passed
        // through the current locale's ctype<_CharT>.widen().
        _CharT                    	_M_atoms_in[__num_base::_S_iend + 1];
*************** namespace std
*** 893,901 ****
        _M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&, 
  		       string& __xtrc) const;
  
!       iter_type 
!       _M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&, 
! 		     string& __xtrc, int& __base) const;
  
        virtual iter_type 
        do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const;
--- 871,880 ----
        _M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&, 
  		       string& __xtrc) const;
  
!       template<typename _ValueT>
!         iter_type 
!         _M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&, 
! 		       _ValueT& __v) const;
  
        virtual iter_type 
        do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const;
diff -prN libstdc++-v3-orig/include/bits/locale_facets.tcc libstdc++-v3/include/bits/locale_facets.tcc
*** libstdc++-v3-orig/include/bits/locale_facets.tcc	Wed Dec  3 10:17:20 2003
--- libstdc++-v3/include/bits/locale_facets.tcc	Mon Dec  8 09:44:42 2003
*************** namespace std
*** 258,401 ****
      }
  
    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;
!       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, this can change based on contents.
!       const 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.
!       if (__beg != __end)
! 	{
! 	  const char_type __c = *__beg;
! 	  const bool __plus = __traits_type::eq(__c, __lit[_S_iplus]);
! 	  if (__plus || __traits_type::eq(__c, __lit[_S_iminus]))
! 	    {
! 	      __xtrc += __plus ? _S_atoms_in[_S_iplus]
! 		               : _S_atoms_in[_S_iminus];
! 	      ++__beg;
! 	    }
! 	}
  
!       // Next, look for leading zeros and check required digits for base formats.
!       if (__builtin_expect(__base == 10, true))
! 	{
! 	  // Look for a zero...
! 	  if (__beg != __end && __traits_type::eq(*__beg, __lit[_S_izero]))
! 	    {
! 	      __xtrc += _S_atoms_in[_S_izero];
  	      ++__beg;
! 	      // ... and skip the additional ones.
! 	      for (; __beg != __end
! 		     && __traits_type::eq(*__beg, __lit[_S_izero]); ++__beg);
! 	      
! 	      // Check required digits.
! 	      if (__beg != __end && __basefield == 0)
! 		{	  
! 		  const bool __x = __traits_type::eq(*__beg, __lit[_S_ix]);
! 		  if (__x || __traits_type::eq(*__beg, __lit[_S_iX]))
! 		    {
! 		      __xtrc += __x ? _S_atoms_in[_S_ix] 
! 			            : _S_atoms_in[_S_iX];
! 		      __base = 16;
! 		      ++__beg;		      
! 		    }
! 		  else 
! 		    __base = 8;
! 		}	      
! 	    }
! 	}
!       else if (__base == 16)
! 	{
! 	  if (__beg != __end && __traits_type::eq(*__beg, __lit[_S_izero]))
! 	    {
! 	      __xtrc += _S_atoms_in[_S_izero];
! 	      
! 	      if (++__beg != __end)
! 		{
! 		  const bool __x = __traits_type::eq(*__beg, __lit[_S_ix]);
! 		  if (__x || __traits_type::eq(*__beg, __lit[_S_iX]))
! 		    {
! 		      __xtrc += __x ? _S_atoms_in[_S_ix] 
! 			            : _S_atoms_in[_S_iX];
! 		      ++__beg;
! 		    }
! 		}
! 	    }
! 	}
  
!       // At this point, base is determined. If not hex, only allow
!       // base digits as valid input.
!       const size_t __len = __base == 16 ? _S_iend : __base;
  
!       // Extract.
!       string __found_grouping;
!       int __sep_pos = 0;
!       for (; __beg != __end; ++__beg)
!         {
! 	  const char_type __c = *__beg;
!           const char_type* __p = __traits_type::find(__lit + _S_izero,
! 						     __len, __c);
!           if (__p)
! 	    {
! 	      // Try first for acceptable digit; record it if found.
! 	      __xtrc += _S_atoms_in[__p - __lit];
! 	      ++__sep_pos;
! 	    }
!           else if (__traits_type::eq(__c, __lc->_M_thousands_sep)
! 		   && __lc->_M_use_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;
!                 }
!               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 (__lc->_M_use_grouping && __found_grouping.size())
!         {
!           // Add the ending grouping.
!           __found_grouping += static_cast<char>(__sep_pos);
  
! 	  const string __grouping = __lc->_M_grouping;
!           if (!std::__verify_grouping(__grouping, __found_grouping))
! 	    __err |= ios_base::failbit;
!         }
  
!       // Finish up.
!       __xtrc += char();
!       if (__beg == __end)
!         __err |= ios_base::eofbit;
!       return __beg;
!     }
  
    // _GLIBCXX_RESOLVE_LIB_DEFECTS
    // 17.  Bad bool parsing
--- 258,451 ----
      }
  
    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)
! 	  {
! 	    __negative = __traits_type::eq(*__beg, __lit[_S_iminus]);
! 	    if (__negative && numeric_limits<_ValueT>::is_signed
! 		|| __traits_type::eq(*__beg, __lit[_S_iplus]))
  	      ++__beg;
! 	  }
  
! 	// Next, look for leading zeros and check required digits
! 	// for base formats.
! 	if (__beg != __end && __traits_type::eq(*__beg, __lit[_S_izero]))
! 	  {
! 	    __found_num = true;
! 	    ++__beg;
! 	    if (__builtin_expect(__base == 10, true))
! 	      {
! 		// Skip the additional zeros.
! 		for (; __beg != __end
! 		       && __traits_type::eq(*__beg, __lit[_S_izero]); ++__beg);
! 		
! 		// Check required digits.
! 		if (__beg != __end && __basefield == 0)
! 		  {	  
! 		    const bool __x = __traits_type::eq(*__beg, __lit[_S_ix]);
! 		    if (__x || __traits_type::eq(*__beg, __lit[_S_iX]))
! 		      {
! 			__base = 16;
! 			++__beg;
! 			__found_num = false;
! 		      }
! 		    else
! 		      __base = 8;
! 		  }	      
! 	      }
! 	    else if (__base == 16 && __beg != __end)
! 	      {
! 		const bool __x = __traits_type::eq(*__beg, __lit[_S_ix]);
! 		if (__x || __traits_type::eq(*__beg, __lit[_S_iX]))
! 		  {
! 		    ++__beg;
! 		    __found_num = false;
! 		  }
! 	      }
! 	  }
  
! 	// At this point, base is determined. If not hex, only allow
! 	// base digits as valid input.
! 	const size_t __len = __base == 16 ? _S_iend : __base;
! 
! 	// Extract.
! 	string __found_grouping;
! 	int __sep_pos = 0;
! 	bool __overflow = false;
! 	_ValueT __result = 0;
! 	const char_type* __lit_zero = __lit + _S_izero;
! 	if (__negative)
! 	  {
! 	    const _ValueT __min = numeric_limits<_ValueT>::min() / __base;
! 	    for (; __beg != __end; ++__beg)
! 	      {
! 		const char_type* __p = __traits_type::find(__lit_zero,
! 							   __len, *__beg);
! 		if (__p)
! 		  {
! 		    int __digit = __p - __lit_zero;
! 		    if (__digit > 15)
! 		      __digit -= 6;
! 		    if (__result < __min)
! 		      __overflow = true;
! 		    else
! 		      {
! 			const _ValueT __new_result = __result * __base - __digit;
! 			if (__result)
! 			  __overflow |= __new_result >= __result;
! 			__result = __new_result;
! 			++__sep_pos;
! 			__found_num = true;
! 		      }
! 		  }
! 		else if (__lc->_M_use_grouping
! 			 && __traits_type::eq(*__beg, __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
! 		  // Not a valid input item.
  		  break;
! 	      }
! 	  }
! 	else
! 	  {
! 	    const _ValueT __max = numeric_limits<_ValueT>::max() / __base;
! 	    for (; __beg != __end; ++__beg)
! 	      {
! 		const char_type* __p = __traits_type::find(__lit_zero,
! 							   __len, *__beg);
! 		if (__p)
! 		  {
! 		    int __digit = __p - __lit_zero;
! 		    if (__digit > 15)
! 		      __digit -= 6;
! 		    if (__result > __max)
! 		      __overflow = true;
! 		    else
! 		      {
! 			const _ValueT __new_result = __result * __base + __digit;
! 			if (__result)
! 			  __overflow |= __new_result <= __result;
! 			__result = __new_result;
! 			++__sep_pos;
! 			__found_num = true;
! 		      }
! 		  }
! 		else if (__lc->_M_use_grouping
! 			 && __traits_type::eq(*__beg, __lc->_M_thousands_sep))
! 		  {
! 		    if (__sep_pos)
! 		      {
! 			__found_grouping += static_cast<char>(__sep_pos);
! 			__sep_pos = 0;
! 		      }
! 		    else
! 		      {
! 			__err |= ios_base::failbit;
! 			break;
! 		      }
! 		  }
! 		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);
! 	    
! 	    const string __grouping = __lc->_M_grouping;
! 	    if (!std::__verify_grouping(__grouping, __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
*************** namespace std
*** 407,432 ****
      {
        if (!(__io.flags() & ios_base::boolalpha))
          {
! 	  // Parse bool values as unsigned long.
            // NB: We can't just call do_get(long) here, as it might
            // refer to a derived class.
!           string __xtrc;
!           int __base;
!           __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
! 
! 	  unsigned long __ul; 
! 	  std::__convert_to_v(__xtrc.c_str(), __ul, __err, 
! 			      _S_get_c_locale(), __base);
! 	  if (!(__err & ios_base::failbit) && __ul <= 1)
! 	    __v = __ul;
! 	  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);
--- 457,477 ----
      {
        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);
*************** namespace std
*** 473,540 ****
      num_get<_CharT, _InIter>::
      do_get(iter_type __beg, iter_type __end, ios_base& __io,
             ios_base::iostate& __err, long& __v) const
!     {
!       string __xtrc;
!       int __base;
!       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
!       std::__convert_to_v(__xtrc.c_str(), __v, __err,
! 			  _S_get_c_locale(), __base);
!       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, unsigned short& __v) const
!     {
!       string __xtrc;
!       int __base;
!       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
!       unsigned long __ul;
!       std::__convert_to_v(__xtrc.c_str(), __ul, __err,
! 			  _S_get_c_locale(), __base);
!       if (!(__err & ios_base::failbit) 
! 	  && __ul <= numeric_limits<unsigned short>::max())
! 	__v = static_cast<unsigned short>(__ul);
!       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, unsigned int& __v) const
!     {
!       string __xtrc;
!       int __base;
!       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
!       unsigned long __ul;
!       std::__convert_to_v(__xtrc.c_str(), __ul, __err,
! 			  _S_get_c_locale(), __base);
!       if (!(__err & ios_base::failbit) 
! 	  && __ul <= numeric_limits<unsigned int>::max())
! 	__v = static_cast<unsigned int>(__ul);
!       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, unsigned long& __v) const
!     {
!       string __xtrc;
!       int __base;
!       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
!       std::__convert_to_v(__xtrc.c_str(), __v, __err,
! 			  _S_get_c_locale(), __base);
!       return __beg;
!     }
  
  #ifdef _GLIBCXX_USE_LONG_LONG
    template<typename _CharT, typename _InIter>
--- 518,545 ----
      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>
*************** namespace std
*** 542,569 ****
      num_get<_CharT, _InIter>::
      do_get(iter_type __beg, iter_type __end, ios_base& __io,
             ios_base::iostate& __err, long long& __v) const
!     {
!       string __xtrc;
!       int __base;
!       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
!       std::__convert_to_v(__xtrc.c_str(), __v, __err,
! 			  _S_get_c_locale(), __base);
!       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, unsigned long long& __v) const
!     {
!       string __xtrc;
!       int __base;
!       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
!       std::__convert_to_v(__xtrc.c_str(), __v, __err,
! 			  _S_get_c_locale(), __base);
!       return __beg;
!     }
  #endif
  
    template<typename _CharT, typename _InIter>
--- 547,560 ----
      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>
*************** namespace std
*** 575,582 ****
        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;
      }
  
--- 566,572 ----
        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;
      }
  
*************** namespace std
*** 619,634 ****
  				   | ios_base::uppercase | ios_base::internal);
        __io.flags(__fmt & __fmtmask | (ios_base::hex | ios_base::showbase));
  
!       string __xtrc;
!       int __base;
!       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
  
        // Reset from hex formatted input.
        __io.flags(__fmt);
  
-       unsigned long __ul;
-       std::__convert_to_v(__xtrc.c_str(), __ul, __err, 
- 			  _S_get_c_locale(), __base);
        if (!(__err & ios_base::failbit))
  	__v = reinterpret_cast<void*>(__ul);
        else 
--- 609,620 ----
  				   | ios_base::uppercase | ios_base::internal);
        __io.flags(__fmt & __fmtmask | (ios_base::hex | ios_base::showbase));
  
!       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 
*************** namespace std
*** 794,800 ****
        _OutIter
        num_put<_CharT, _OutIter>::
        _M_insert_int(_OutIter __s, ios_base& __io, _CharT __fill, 
! 		     _ValueT __v) const
        {
  	typedef typename numpunct<_CharT>::__cache_type	__cache_type;
  	__use_cache<__cache_type> __uc;
--- 780,786 ----
        _OutIter
        num_put<_CharT, _OutIter>::
        _M_insert_int(_OutIter __s, ios_base& __io, _CharT __fill, 
! 		    _ValueT __v) const
        {
  	typedef typename numpunct<_CharT>::__cache_type	__cache_type;
  	__use_cache<__cache_type> __uc;
diff -prN libstdc++-v3-orig/src/locale-inst.cc libstdc++-v3/src/locale-inst.cc
*** libstdc++-v3-orig/src/locale-inst.cc	Mon Oct 27 17:21:13 2003
--- libstdc++-v3/src/locale-inst.cc	Sun Dec  7 11:26:33 2003
*************** namespace std
*** 56,61 ****
--- 56,105 ----
    template class num_get<C, istreambuf_iterator<C> >;
    template class num_put<C, ostreambuf_iterator<C> >; 
    template
+     istreambuf_iterator<C>
+     num_get<C, istreambuf_iterator<C> >::
+     _M_extract_int(istreambuf_iterator<C>, istreambuf_iterator<C>,
+ 		   ios_base&, ios_base::iostate&,
+ 		   long&) const;
+ 
+   template
+     istreambuf_iterator<C>
+     num_get<C, istreambuf_iterator<C> >::
+     _M_extract_int(istreambuf_iterator<C>, istreambuf_iterator<C>,
+ 		   ios_base&, ios_base::iostate&, 
+ 		   unsigned short&) const;
+ 
+   template
+     istreambuf_iterator<C>
+     num_get<C, istreambuf_iterator<C> >::
+     _M_extract_int(istreambuf_iterator<C>, istreambuf_iterator<C>,
+ 		   ios_base&, ios_base::iostate&,
+ 		   unsigned int&) const;
+ 
+   template
+     istreambuf_iterator<C>
+     num_get<C, istreambuf_iterator<C> >::
+     _M_extract_int(istreambuf_iterator<C>, istreambuf_iterator<C>,
+ 		   ios_base&, ios_base::iostate&,
+ 		   unsigned long&) const;
+ 
+ #ifdef _GLIBCXX_USE_LONG_LONG
+   template
+     istreambuf_iterator<C>
+     num_get<C, istreambuf_iterator<C> >::
+     _M_extract_int(istreambuf_iterator<C>, istreambuf_iterator<C>,
+ 		   ios_base&, ios_base::iostate&,
+ 		   long long&) const;
+ 
+   template
+     istreambuf_iterator<C>
+     num_get<C, istreambuf_iterator<C> >::
+     _M_extract_int(istreambuf_iterator<C>, istreambuf_iterator<C>,
+ 		   ios_base&, ios_base::iostate&,
+ 		   unsigned long long&) const;
+ #endif
+ 
+   template
      ostreambuf_iterator<C>
      num_put<C, ostreambuf_iterator<C> >::
      _M_insert_int(ostreambuf_iterator<C>, ios_base&, C, 
diff -prN libstdc++-v3-orig/src/locale_facets.cc libstdc++-v3/src/locale_facets.cc
*** libstdc++-v3-orig/src/locale_facets.cc	Fri Oct 17 16:47:30 2003
--- libstdc++-v3/src/locale_facets.cc	Sun Dec  7 10:57:47 2003
*************** namespace std 
*** 53,59 ****
    const money_base::pattern 
    money_base::_S_default_pattern =  { {symbol, sign, none, value} };
  
!   const char* __num_base::_S_atoms_in = "-+xX0123456789eEabcdfABCDF";
    const char* __num_base::_S_atoms_out ="-+xX0123456789abcdef0123456789ABCDEF";
  
    // _GLIBCXX_RESOLVE_LIB_DEFECTS
--- 53,59 ----
    const money_base::pattern 
    money_base::_S_default_pattern =  { {symbol, sign, none, value} };
  
!   const char* __num_base::_S_atoms_in = "-+xX0123456789abcdefABCDEF";
    const char* __num_base::_S_atoms_out ="-+xX0123456789abcdef0123456789ABCDEF";
  
    // _GLIBCXX_RESOLVE_LIB_DEFECTS

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]