]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
locale_facets.tcc (num_get<>::_M_extract_int): Evaluate *__beg the exact strict minim...
authorPaolo Carlini <paolo@gcc.gnu.org>
Wed, 3 Nov 2004 01:05:08 +0000 (01:05 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Wed, 3 Nov 2004 01:05:08 +0000 (01:05 +0000)
2004-11-02  Paolo Carlini  <pcarlini@suse.de>

* include/bits/locale_facets.tcc (num_get<>::_M_extract_int):
Evaluate *__beg the exact strict minimum number of times; likewise
for __beg != __end; slightly simplify main parsing loop.

From-SVN: r90012

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/locale_facets.tcc

index dbbbea991137f377063ef62ca2fb7a7e3d0f1c64..9063603c0a29c997241a156c84aefee7b477be46 100644 (file)
@@ -1,3 +1,9 @@
+2004-11-02  Paolo Carlini  <pcarlini@suse.de>
+
+       * include/bits/locale_facets.tcc (num_get<>::_M_extract_int):
+       Evaluate *__beg the exact strict minimum number of times; likewise
+       for __beg != __end; slightly simplify main parsing loop.
+
 2004-11-02  Benjamin Kosnik  <bkoz@redhat.com>
            Lothar Werzinger  <lothar@xcerla.com>
        
@@ -34,9 +40,9 @@
        
 2004-11-01  Chris Jefferson  <chris@bubblescope.net>
 
-        PR libstdc++/18159
-        * include/tr1/tuple (get(pair)): Change occurrences of _I to _Int.
-        (get(const pair)): Likewise.
+       PR libstdc++/18159
+       * include/tr1/tuple (get(pair)): Change occurrences of _I to _Int.
+       (get(const pair)): Likewise.
 
 2004-11-01  Paolo Carlini  <pcarlini@suse.de>
 
index 0f92db205a116a34a9f8f1c8f5d9f04ab4aebf88..c32a65da765e66cbd351404b582f13c64f80a14f 100644 (file)
@@ -301,10 +301,8 @@ namespace std
            }
        }
 
-      // True if a mantissa is found.
-      bool __found_mantissa = false;
-
       // Next, look for leading zeros.
+      bool __found_mantissa = false;
       while (!__testeof)
        {
          if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep
@@ -452,6 +450,7 @@ namespace std
        const locale& __loc = __io._M_getloc();
        const __cache_type* __lc = __uc(__loc);
        const _CharT* __lit = __lc->_M_atoms_in;
+       char_type __c = char_type();
 
        // NB: Iff __basefield == 0, __base can change based on contents.
        const ios_base::fmtflags __basefield = __io.flags()
@@ -459,37 +458,39 @@ namespace std
        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;
+       // True if __beg becomes equal to __end.
+       bool __testeof = __beg == __end;
 
        // First check for sign.
        bool __negative = false;
-       if (__beg != __end)
+       if (!__testeof)
          {
-           const char_type __c = *__beg;
+           __c = *__beg;
            if (numeric_limits<_ValueT>::is_signed)
              __negative = __c == __lit[__num_base::_S_iminus];
            if ((__negative || __c == __lit[__num_base::_S_iplus])
                && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
                && !(__c == __lc->_M_decimal_point))
-             ++__beg;
+             {
+               if (++__beg != __end)
+                 __c = *__beg;
+               else
+                 __testeof = true;
+             }
          }
 
        // Next, look for leading zeros and check required digits
        // for base formats.
-       while (__beg != __end)
+       bool __found_zero = false;
+       while (!__testeof)
          {
-           const char_type __c = *__beg;
            if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep
                || __c == __lc->_M_decimal_point)
              break;
            else if (__c == __lit[__num_base::_S_izero] 
-                    && (!__found_num || __base == 10))
-             {
-               __found_num = true;
-               ++__beg;
-             }
-           else if (__found_num)
+                    && (!__found_zero || __base == 10))
+             __found_zero = true;
+           else if (__found_zero)
              {
                if (__c == __lit[__num_base::_S_ix] 
                    || __c == __lit[__num_base::_S_iX])
@@ -497,19 +498,30 @@ namespace std
                    if (__basefield == 0)
                      __base = 16;
                    if (__base == 16)
-                     {
-                       __found_num = false;
-                       ++__beg;
-                     }
+                     __found_zero = false;
+                   else
+                     break;
+                 }
+               else
+                 {
+                   if (__basefield == 0)
+                     __base = 8;
+                   break;
                  }
-               else if (__basefield == 0)
-                 __base = 8;
-               break;
              }
            else
              break;
-         }
 
+           if (++__beg != __end)
+             {
+               __c = *__beg;
+               if (!__found_zero)
+                 break;
+             }
+           else
+             __testeof = true;
+         }
+       
        // At this point, base is determined. If not hex, only allow
        // base digits as valid input.
        const size_t __len = (__base == 16 ? __num_base::_S_iend
@@ -522,15 +534,15 @@ namespace std
        int __sep_pos = 0;
        bool __overflow = false;
        _ValueT __result = 0;
+       const char_type* __q;
        const char_type* __lit_zero = __lit + __num_base::_S_izero;
        if (__negative)
          {
            const _ValueT __min = numeric_limits<_ValueT>::min() / __base;
-           for (; __beg != __end; ++__beg)
+           while (!__testeof)
              {
                // According to 22.2.2.1.2, p8-9, first look for thousands_sep
                // and decimal_point.
-               const char_type __c = *__beg;
                if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
                  {
                    // NB: Thousands separator at the beginning of a string
@@ -548,39 +560,37 @@ namespace std
                  }
                else if (__c == __lc->_M_decimal_point)
                  break;
-               else
+               else if ((__q = __traits_type::find(__lit_zero, __len, __c)))
                  {
-                   const char_type* __q = __traits_type::find(__lit_zero, 
-                                                              __len, __c);
-                   if (__q)
+                   int __digit = __q - __lit_zero;
+                   if (__digit > 15)
+                     __digit -= 6;
+                   if (__result < __min)
+                     __overflow = true;
+                   else
                      {
-                       int __digit = __q - __lit_zero;
-                       if (__digit > 15)
-                         __digit -= 6;
-                       if (__result < __min)
-                         __overflow = true;
-                       else
-                         {
-                           const _ValueT __new_result = (__result * __base
-                                                         - __digit);
-                           __overflow |= __new_result > __result;
-                           __result = __new_result;
-                           ++__sep_pos;
-                           __found_num = true;
-                         }
+                       const _ValueT __new_result = (__result * __base
+                                                     - __digit);
+                       __overflow |= __new_result > __result;
+                       __result = __new_result;
+                       ++__sep_pos;
                      }
-                   else
-                     // Not a valid input item.
-                     break;
                  }
+               else
+                 // Not a valid input item.
+                 break;
+
+               if (++__beg != __end)
+                 __c = *__beg;
+               else
+                 __testeof = true;
              }
          }
        else
          {
            const _ValueT __max = numeric_limits<_ValueT>::max() / __base;
-           for (; __beg != __end; ++__beg)
+           while (!__testeof)
              {
-               const char_type __c = *__beg;
                if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
                  {
                    if (__sep_pos)
@@ -596,30 +606,29 @@ namespace std
                  }
                else if (__c == __lc->_M_decimal_point)
                  break;
-               else
+               else if ((__q = __traits_type::find(__lit_zero, __len, __c)))
                  {
-                   const char_type* __q = __traits_type::find(__lit_zero,
-                                                              __len, __c);    
-                   if (__q)
+                   int __digit = __q - __lit_zero;
+                   if (__digit > 15)
+                     __digit -= 6;
+                   if (__result > __max)
+                     __overflow = true;
+                   else
                      {
-                       int __digit = __q - __lit_zero;
-                       if (__digit > 15)
-                         __digit -= 6;
-                       if (__result > __max)
-                         __overflow = true;
-                       else
-                         {
-                           const _ValueT __new_result = (__result * __base
-                                                         + __digit);
-                           __overflow |= __new_result < __result;
-                           __result = __new_result;
-                           ++__sep_pos;
-                           __found_num = true;
-                         }
+                       const _ValueT __new_result = (__result * __base
+                                                     + __digit);
+                       __overflow |= __new_result < __result;
+                       __result = __new_result;
+                       ++__sep_pos;
                      }
-                   else
-                     break;
                  }
+               else
+                 break;
+
+               if (++__beg != __end)
+                 __c = *__beg;
+               else
+                 __testeof = true;
              }
          }
 
@@ -637,12 +646,12 @@ namespace std
          }
 
        if (!(__err & ios_base::failbit) && !__overflow
-           && __found_num)
+           && (__sep_pos || __found_zero || __found_grouping.size()))
          __v = __result;
        else
          __err |= ios_base::failbit;
 
-       if (__beg == __end)
+       if (__testeof)
          __err |= ios_base::eofbit;
        return __beg;
       }