OSDN Git Service

2004-01-13 Paolo Carlini <pcarlini@suse.de>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / bits / locale_facets.tcc
index 483d421..d781503 100644 (file)
 
 #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>
@@ -74,20 +69,45 @@ namespace std
                                __s2.data(), __s2.data() + __s2.length()) < 0);
     }
 
+  /**
+   *  @brief  Test for the presence of a facet.
+   *
+   *  has_facet tests the locale argument for the presence of the facet type
+   *  provided as the template parameter.  Facets derived from the facet
+   *  parameter will also return true.
+   *
+   *  @param  Facet  The facet type to test the presence of.
+   *  @param  locale  The locale to test.
+   *  @return  true if locale contains a facet of type Facet, else false.
+   *  @throw  std::bad_cast if locale doesn't contain the facet.
+  */
   template<typename _Facet>
     inline bool
     has_facet(const locale& __loc) throw()
     {
-      size_t __i = _Facet::id._M_id();
+      const size_t __i = _Facet::id._M_id();
       const locale::facet** __facets = __loc._M_impl->_M_facets;
       return (__i < __loc._M_impl->_M_facets_size && __facets[__i]);
     }
 
+  /**
+   *  @brief  Return a facet.
+   *
+   *  use_facet looks for and returns a reference to a facet of type Facet
+   *  where Facet is the template parameter.  If has_facet(locale) is true,
+   *  there is a suitable facet to return.  It throws std::bad_cast if the
+   *  locale doesn't contain a facet of type Facet.
+   *
+   *  @param  Facet  The facet type to access.
+   *  @param  locale  The locale to use.
+   *  @return  Reference to facet of type Facet.
+   *  @throw  std::bad_cast if locale doesn't contain a facet of type Facet.
+  */
   template<typename _Facet>
     inline const _Facet&
     use_facet(const locale& __loc)
     {
-      size_t __i = _Facet::id._M_id();
+      const size_t __i = _Facet::id._M_id();
       const locale::facet** __facets = __loc._M_impl->_M_facets;
       if (!(__i < __loc._M_impl->_M_facets_size && __facets[__i]))
         __throw_bad_cast();
@@ -109,7 +129,7 @@ namespace std
       const __numpunct_cache<_CharT>*
       operator() (const locale& __loc) const
       {
-       size_t __i = numpunct<_CharT>::id._M_id();
+       const size_t __i = numpunct<_CharT>::id._M_id();
        const locale::facet** __caches = __loc._M_impl->_M_caches;
        if (!__caches[__i])
          {
@@ -143,102 +163,122 @@ namespace std
       const __cache_type* __lc = __uc(__loc);
       const _CharT* __lit = __lc->_M_atoms_in;
 
-      // First check for sign.
-      int __pos = 0;
-      char_type  __c = *__beg;
-      const bool __plus = __traits_type::eq(__c, __lit[_S_iplus]);
-      if ((__plus || __traits_type::eq(__c, __lit[_S_iminus])) 
-         && __beg != __end)
-       {
-         __xtrc += __plus ? _S_atoms_in[_S_iplus] : _S_atoms_in[_S_iminus];
-         ++__pos;
-         __c = *(++__beg);
-       }
+      // True if a mantissa is found.
+      bool __found_mantissa = false;
 
-      // Next, strip leading zeros.
-      bool __found_zero = false;
-      while (__traits_type::eq(__c, __lit[_S_izero]) && __beg != __end)
+      // First check for sign.
+      if (__beg != __end)
        {
-         __c = *(++__beg);
-         __found_zero = true;
+         const char_type __c = *__beg;
+         const bool __plus = __traits_type::eq(__c, __lit[_S_iplus]);
+         if ((__plus || __traits_type::eq(__c, __lit[_S_iminus]))
+             && !__traits_type::eq(__c, __lc->_M_decimal_point)
+             && (!__lc->_M_use_grouping
+                 || !__traits_type::eq(__c, __lc->_M_thousands_sep)))
+           {
+             __xtrc += __plus ? _S_atoms_in[_S_iplus]
+                              : _S_atoms_in[_S_iminus];
+             ++__beg;
+           }
        }
-      if (__found_zero)
+         
+      // Next, look for leading zeros.
+      while (__beg != __end)
        {
-         __xtrc += _S_atoms_in[_S_izero];
-         ++__pos;
+         const char_type __c = *__beg;
+         if (__traits_type::eq(__c, __lc->_M_decimal_point)
+             || (__lc->_M_use_grouping 
+                 && __traits_type::eq(__c, __lc->_M_thousands_sep)))
+           break;
+         else if (__traits_type::eq(__c, __lit[_S_izero]))
+           {
+             if (!__found_mantissa)
+               {
+                 __xtrc += _S_atoms_in[_S_izero];
+                 __found_mantissa = true;
+               }
+             ++__beg;
+           }
+         else
+           break;
        }
 
       // Only need acceptable digits for floating point numbers.
       bool __found_dec = false;
       bool __found_sci = false;
       string __found_grouping;
-      const size_t __len = _S_iE - _S_izero + 1;
       int __sep_pos = 0;
       bool __e;
+      const char_type* __p;
       while (__beg != __end)
         {
-         // Only look in digits.
-          const char_type* __p = __traits_type::find(__lit + _S_izero, 10, 
-                                                    __c);
-
-          // NB: strchr returns true for __c == 0x0
-          if (__p && !__traits_type::eq(__c, char_type()))
+         // 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
+             && __traits_type::eq(__c, __lc->_M_thousands_sep))
            {
-             // Try first for acceptable digit; record it if found.
-             ++__pos;
-             __xtrc += _S_atoms_in[__p - __lit];
-             ++__sep_pos;
-             __c = *(++__beg);
-           }
-          else if (__traits_type::eq(__c, __lc->_M_thousands_sep) 
-                  &&  __lc->_M_use_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
+             if (!__found_dec && !__found_sci)
                {
-                 __err |= ios_base::failbit;
-                 break;
+                 // 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;
+                     ++__beg;
+                   }
+                 else
+                   {
+                     __err |= ios_base::failbit;
+                     break;
+                   }
                }
+             else
+               break;
             }
-         else if (__traits_type::eq(__c, __lc->_M_decimal_point) 
-                  && !__found_dec)
+         else if (__traits_type::eq(__c, __lc->_M_decimal_point))
            {
-             // 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;
+             if (!__found_dec && !__found_sci)
+               {
+                 // If no grouping chars are seen, no grouping check
+                 // is applied. Therefore __found_grouping is adjusted
+                 // only if decimal_point comes after some thousands_sep.
+                 if (__found_grouping.size())
+                   __found_grouping += static_cast<char>(__sep_pos);
+                 __xtrc += '.';
+                 __found_dec = true;
+                 ++__beg;
+               }
+             else
+               break;
+           }
+          else if (__p = __traits_type::find(__lit + _S_izero, 10, __c))
+           {
+             __xtrc += _S_atoms_in[__p - __lit];
+             __found_mantissa = true;
+             ++__sep_pos;
+             ++__beg;
            }
          else if ((__e = __traits_type::eq(__c, __lit[_S_ie]) 
                    || __traits_type::eq(__c, __lit[_S_iE])) 
-                  && !__found_sci && __pos)
+                  && __found_mantissa && !__found_sci)
            {
              // Scientific notation.
-             ++__pos;
              __xtrc += __e ? _S_atoms_in[_S_ie] : _S_atoms_in[_S_iE];
-             __c = *(++__beg);
+             __found_sci = true;
 
              // Remove optional plus or minus sign, if they exist.
-             const bool __plus = __traits_type::eq(__c, __lit[_S_iplus]);
-             if (__plus || __traits_type::eq(__c, __lit[_S_iminus]))
+             if (++__beg != __end)
                {
-                 ++__pos;
-                 __xtrc += __plus ? _S_atoms_in[_S_iplus] 
-                                  : _S_atoms_in[_S_iminus];
-                 __c = *(++__beg);
+                 const bool __plus = __traits_type::eq(*__beg, __lit[_S_iplus]);
+                 if (__plus || __traits_type::eq(*__beg, __lit[_S_iminus]))
+                   {
+                     __xtrc += __plus ? _S_atoms_in[_S_iplus] 
+                                      : _S_atoms_in[_S_iminus];
+                     ++__beg;
+                   }
                }
-             __found_sci = true;
            }
          else
            // Not a valid input item.
@@ -266,155 +306,203 @@ namespace std
     }
 
   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.
-      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 bool __plus = __traits_type::eq(__c, __lit[_S_iplus]);
-      if ((__plus || __traits_type::eq(__c, __lit[_S_iminus])) 
-         && __beg != __end)
-       {
-         __xtrc += __plus ? _S_atoms_in[_S_iplus] : _S_atoms_in[_S_iminus];
-         ++__pos;
-         __c = *(++__beg);
-       }
+    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)
+         { 
+           const char_type __c = *__beg;
+           if (numeric_limits<_ValueT>::is_signed)
+             __negative = __traits_type::eq(__c, __lit[_S_iminus]);
+           if ((__negative || __traits_type::eq(__c, __lit[_S_iplus]))
+               && !__traits_type::eq(__c, __lc->_M_decimal_point)
+               && (!__lc->_M_use_grouping
+                   || !__traits_type::eq(__c, __lc->_M_thousands_sep)))
+             ++__beg;
+         }
 
-      // Next, strip leading zeros and check required digits for base formats.
-      if (__base == 10)
-       {
-         bool __found_zero = false;
-         while (__traits_type::eq(__c, __lit[_S_izero]) && __beg != __end)
-           {
-             __c = *(++__beg);
-             __found_zero = true;
-           }
-         if (__found_zero)
-           {
-             __xtrc += _S_atoms_in[_S_izero];
-             ++__pos;
-             if (__basefield == 0)
-               {             
-                 const bool __x = __traits_type::eq(__c, __lit[_S_ix]);
-                 const bool __X = __traits_type::eq(__c, __lit[_S_iX]);
-                 if ((__x || __X) && __beg != __end)
-                   {
-                     __xtrc += __x ? _S_atoms_in[_S_ix] : _S_atoms_in[_S_iX];
-                     ++__pos;
-                     __c = *(++__beg);
+       // Next, look for leading zeros and check required digits
+       // for base formats.
+       while (__beg != __end)
+         {
+           const char_type __c = *__beg;
+           if (__traits_type::eq(__c, __lc->_M_decimal_point)
+               || (__lc->_M_use_grouping
+                   && __traits_type::eq(__c, __lc->_M_thousands_sep)))
+             break;
+           else if (__traits_type::eq(__c, __lit[_S_izero])
+                    && (!__found_num || __base == 10))
+             {
+               __found_num = true;
+               ++__beg;
+             }
+           else if (__found_num)
+             {
+               if (__traits_type::eq(__c, __lit[_S_ix])
+                   || __traits_type::eq(__c, __lit[_S_iX]))
+                 {
+                   if (__basefield == 0)
                      __base = 16;
-                   }
-                 else 
-                   __base = 8;
-               }
-           }
-       }
-      else if (__base == 16)
-       {
-         if (__traits_type::eq(__c, __lit[_S_izero]) && __beg != __end)
-           {
-             __xtrc += _S_atoms_in[_S_izero];
-             ++__pos;
-             __c = *(++__beg); 
-
-             const bool __x = __traits_type::eq(__c, __lit[_S_ix]);
-             const bool __X = __traits_type::eq(__c, __lit[_S_iX]);
-             if ((__x || __X) && __beg != __end)
-               {
-                 __xtrc += __x ? _S_atoms_in[_S_ix] : _S_atoms_in[_S_iX];
-                 ++__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 = _S_iend;
-      else
-       __len = __base;
-
-      // Extract.
-      string __found_grouping;
-      const char_type __sep = __lc->_M_thousands_sep;
-      int __sep_pos = 0;
-      while (__beg != __end)
-        {
-          const char_type* __p = __traits_type::find(__lit + _S_izero, 
-                                                    __len,  __c);
+                   if (__base == 16)
+                     {
+                       __found_num = false;
+                       ++__beg;
+                     }
+                 }
+               else if (__basefield == 0)
+                 __base = 8;
+               break;
+             }
+           else
+             break;
+         }
 
-          // 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 - __lit];
-             ++__pos;
-             ++__sep_pos;
-             __c = *(++__beg);
-           }
-          else if (__traits_type::eq(__c, __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;
-                 __c = *(++__beg);
-                }
-              else
-               {
-                 __err |= ios_base::failbit;
+       // 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;
+       const char_type* __p;
+       if (__negative)
+         {
+           const _ValueT __min = numeric_limits<_ValueT>::min() / __base;
+           for (; __beg != __end; ++__beg)
+             {
+               // 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
+                   && __traits_type::eq(__c, __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 if (__traits_type::eq(__c, __lc->_M_decimal_point))
                  break;
-               }
-            }
-         else
-           // Not a valid input item.
-           break;
-        }
+               else if (__p = __traits_type::find(__lit_zero, __len, __c))
+                 {
+                   int __digit = __p - __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;
+                     }
+                 }
+               else
+                 // Not a valid input item.
+                 break;
+             }
+         }
+       else
+         {
+           const _ValueT __max = numeric_limits<_ValueT>::max() / __base;
+           for (; __beg != __end; ++__beg)
+             {
+               const char_type __c = *__beg;
+               if (__lc->_M_use_grouping
+                   && __traits_type::eq(__c, __lc->_M_thousands_sep))
+                 {
+                   if (__sep_pos)
+                     {
+                       __found_grouping += static_cast<char>(__sep_pos);
+                       __sep_pos = 0;
+                     }
+                   else
+                     {
+                       __err |= ios_base::failbit;
+                       break;
+                     }
+                 }     
+               else if (__traits_type::eq(__c, __lc->_M_decimal_point))
+                 break;
+               else if (__p = __traits_type::find(__lit_zero, __len, __c))
+                 {
+                   int __digit = __p - __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;
+                     }
+                 }
+               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);
+       // 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;
+         }
 
-         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;
 
-      // Finish up.
-      __xtrc += char();
-      if (__beg == __end)
-        __err |= ios_base::eofbit;
-      return __beg;
-    }
+       if (__beg == __end)
+         __err |= ios_base::eofbit;
+       return __beg;
+      }
 
-#ifdef _GLIBCXX_RESOLVE_LIB_DEFECTS
-  //17.  Bad bool parsing
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // 17.  Bad bool parsing
   template<typename _CharT, typename _InIter>
     _InIter
     num_get<_CharT, _InIter>::
@@ -423,135 +511,85 @@ namespace std
     {
       if (!(__io.flags() & ios_base::boolalpha))
         {
-         // Parse bool values as unsigned long.
+         // Parse bool values as 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 
+         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;
+         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 size_t __tn = __traits_type::length(__lc->_M_truename) - 1;
-          const size_t __fn = __traits_type::length(__lc->_M_falsename) - 1;
 
-         bool __testf = false;
-         bool __testt = false;
-          for (size_t __n = 0; __beg != __end; ++__n)
+         bool __testf = true;
+         bool __testt = true;
+         size_t __n;
+          for (__n = 0; __beg != __end; ++__n, ++__beg)
             {
-              const char_type __c = *__beg;
-             ++__beg;
+             if (__testf)
+               if (__n < __lc->_M_falsename_len)
+                 __testf = __traits_type::eq(*__beg, __lc->_M_falsename[__n]);
+               else
+                 break;
+
+             if (__testt)
+               if (__n < __lc->_M_truename_len)
+                 __testt = __traits_type::eq(*__beg, __lc->_M_truename[__n]);
+               else
+                 break;
 
-             if (__n <= __fn)
-               __testf = __traits_type::eq(__c, __lc->_M_falsename[__n]);
-
-             if (__n <= __tn)
-               __testt = __traits_type::eq(__c, __lc->_M_truename[__n]);
-
-              if (!(__testf || __testt))
-                {
-                  __err |= ios_base::failbit;
-                  break;
-                }
-              else if (__testf && __n == __fn)
-                {
-                  __v = 0;
-                  break;
-                }
-              else if (__testt && __n == __tn)
-                {
-                  __v = 1;
-                  break;
-                }
+             if (!__testf && !__testt)
+               break;      
             }
+         if (__testf && __n == __lc->_M_falsename_len)
+           __v = 0;
+         else if (__testt && __n == __lc->_M_truename_len)
+           __v = 1;
+         else
+           __err |= ios_base::failbit;
+
           if (__beg == __end)
             __err |= ios_base::eofbit;
         }
       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
-    {
-      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;
-    }
+    { 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
-    {
-      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;
-    }
+    { 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
-    {
-      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;
-    }
+    { 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
-    {
-      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;
-    }
+    { return _M_extract_int(__beg, __end, __io, __err, __v); }
 
 #ifdef _GLIBCXX_USE_LONG_LONG
   template<typename _CharT, typename _InIter>
@@ -559,28 +597,14 @@ namespace std
     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;
-    }
+    { 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
-    {
-      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;
-    }
+    { return _M_extract_int(__beg, __end, __io, __err, __v); }
 #endif
 
   template<typename _CharT, typename _InIter>
@@ -592,8 +616,7 @@ namespace std
       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());
+      std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
       return __beg;
     }
 
@@ -631,21 +654,15 @@ namespace std
     {
       // Prepare for hex formatted input.
       typedef ios_base::fmtflags        fmtflags;
-      fmtflags __fmt = __io.flags();
-      fmtflags __fmtmask = ~(ios_base::showpos | ios_base::basefield
-                             | ios_base::uppercase | ios_base::internal);
-      __io.flags(__fmt & __fmtmask | (ios_base::hex | ios_base::showbase));
+      const fmtflags __fmt = __io.flags();
+      __io.flags(__fmt & ~ios_base::basefield | ios_base::hex);
 
-      string __xtrc;
-      int __base;
-      __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
+      unsigned long __ul;
+      __beg = _M_extract_int(__beg, __end, __io, __err, __ul);
 
       // 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 
@@ -671,8 +688,8 @@ namespace std
   // Forwarding functions to peel signed from unsigned integer types.
   template<typename _CharT>
     inline int
-    __int_to_char(_CharT* __out, const int __size, long __v,
-                 const _CharT* __lit, ios_base::fmtflags __flags)
+    __int_to_char(_CharT* __bufend, long __v, const _CharT* __lit,
+                 ios_base::fmtflags __flags)
     {
       unsigned long __ul = static_cast<unsigned long>(__v);
       bool __neg = false;
@@ -681,20 +698,20 @@ namespace std
          __ul = -__ul;
          __neg = true;
        }
-      return __int_to_char(__out, __size, __ul, __lit, __flags, __neg); 
+      return __int_to_char(__bufend, __ul, __lit, __flags, __neg); 
     }
 
   template<typename _CharT>
     inline int
-    __int_to_char(_CharT* __out, const int __size, unsigned long __v,
-                 const _CharT* __lit, ios_base::fmtflags __flags)
-    { return __int_to_char(__out, __size, __v, __lit, __flags, false); }
+    __int_to_char(_CharT* __bufend, unsigned long __v, const _CharT* __lit,
+                 ios_base::fmtflags __flags)
+    { return __int_to_char(__bufend, __v, __lit, __flags, false); }
 
 #ifdef _GLIBCXX_USE_LONG_LONG
   template<typename _CharT>
     inline int
-    __int_to_char(_CharT* __out, const int __size, long long __v,
-                 const _CharT* __lit, ios_base::fmtflags __flags)
+    __int_to_char(_CharT* __bufend, long long __v, const _CharT* __lit,
+                 ios_base::fmtflags __flags)
     { 
       unsigned long long __ull = static_cast<unsigned long long>(__v);
       bool __neg = false;
@@ -703,26 +720,25 @@ namespace std
          __ull = -__ull;
          __neg = true;
        }
-      return __int_to_char(__out, __size, __ull, __lit, __flags, __neg); 
+      return __int_to_char(__bufend, __ull, __lit, __flags, __neg); 
     }
 
   template<typename _CharT>
     inline int
-    __int_to_char(_CharT* __out, const int __size, unsigned long long __v,
-                 const _CharT* __lit, ios_base::fmtflags __flags)
-    { return __int_to_char(__out, __size, __v, __lit, __flags, false); }
+    __int_to_char(_CharT* __bufend, unsigned long long __v, const _CharT* __lit,
+                 ios_base::fmtflags __flags)
+    { return __int_to_char(__bufend, __v, __lit, __flags, false); }
 #endif
       
   template<typename _CharT, typename _ValueT>
     int
-    __int_to_char(_CharT* __out, const int __size, _ValueT __v,
-                 const _CharT* __lit, ios_base::fmtflags __flags, bool __neg)
+    __int_to_char(_CharT* __bufend, _ValueT __v, const _CharT* __lit,
+                 ios_base::fmtflags __flags, bool __neg)
     {
       // Don't write base if already 0.
       const bool __showbase = (__flags & ios_base::showbase) && __v;
       const ios_base::fmtflags __basefield = __flags & ios_base::basefield;
-      _CharT* __buf = __out + __size - 1;
-      _CharT* __bufend = __out + __size;
+      _CharT* __buf = __bufend - 1;
 
       if (__builtin_expect(__basefield != ios_base::oct &&
                           __basefield != ios_base::hex, true))
@@ -755,8 +771,8 @@ namespace std
        {
          // Hex.
          const bool __uppercase = __flags & ios_base::uppercase;
-         int __case_offset = __uppercase ? __num_base::_S_oudigits 
-                                         : __num_base::_S_odigits;
+         const int __case_offset = __uppercase ? __num_base::_S_oudigits 
+                                               : __num_base::_S_odigits;
          do 
            {
              *__buf-- = __lit[(__v & 0xf) + __case_offset];
@@ -771,8 +787,7 @@ namespace std
              *__buf-- = __lit[__num_base::_S_odigits];
            }
        }
-      int __ret = __bufend - __buf - 1;
-      return __ret;
+      return __bufend - __buf - 1;
     }
 
   template<typename _CharT, typename _OutIter>
@@ -781,7 +796,7 @@ namespace std
     _M_group_int(const string& __grouping, _CharT __sep, ios_base& __io, 
                 _CharT* __new, _CharT* __cs, int& __len) const
     {
-      // By itself __add_grouping cannot deal correctly with __ws when
+      // By itself __add_grouping cannot deal correctly with __cs when
       // ios::showbase is set and ios_base::oct || ios_base::hex.
       // Therefore we take care "by hand" of the initial 0, 0x or 0X.
       // However, remember that the latter do not occur if the number
@@ -802,8 +817,8 @@ namespace std
            __new[1] = __cs[1];
          }
       _CharT* __p;
-      __p = std::__add_grouping(__new + __off, __sep, __grouping.c_str(), 
-                               __grouping.c_str() + __grouping.size(),
+      __p = std::__add_grouping(__new + __off, __sep, __grouping.data(), 
+                               __grouping.data() + __grouping.size(),
                                __cs + __off, __cs + __len);
       __len = __p - __new;
     }
@@ -813,7 +828,7 @@ namespace std
       _OutIter
       num_put<_CharT, _OutIter>::
       _M_insert_int(_OutIter __s, ios_base& __io, _CharT __fill, 
-                    _ValueT __v) const
+                   _ValueT __v) const
       {
        typedef typename numpunct<_CharT>::__cache_type __cache_type;
        __use_cache<__cache_type> __uc;
@@ -822,35 +837,34 @@ namespace std
        const _CharT* __lit = __lc->_M_atoms_out;
 
        // Long enough to hold hex, dec, and octal representations.
-       int __ilen = 4 * sizeof(_ValueT);
+       const int __ilen = 4 * sizeof(_ValueT);
        _CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
                                                             * __ilen));
+
        // [22.2.2.2.2] Stage 1, numeric conversion to character.
        // Result is returned right-justified in the buffer.
        int __len;
-       __len = __int_to_char(&__cs[0], __ilen, __v, __lit, __io.flags());
-       __cs = __cs + __ilen - __len;
+       __len = __int_to_char(__cs + __ilen, __v, __lit, __io.flags());
+       __cs += __ilen - __len;
        
        // Add grouping, if necessary. 
-       _CharT* __cs2;
        if (__lc->_M_use_grouping)
          {
            // Grouping can add (almost) as many separators as the
            // number of digits, but no more.
-           __cs2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
-                                                         * __len * 2));
+           _CharT* __cs2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
+                                                                 * __len * 2));
            _M_group_int(__lc->_M_grouping, __lc->_M_thousands_sep, __io, 
                         __cs2, __cs, __len);
            __cs = __cs2;
          }
        
        // Pad.
-       _CharT* __cs3;
-       streamsize __w = __io.width();
+       const streamsize __w = __io.width();
        if (__w > static_cast<streamsize>(__len))
          {
-           __cs3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
-                                                         * __w));
+           _CharT* __cs3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
+                                                                 * __w));
            _M_pad(__fill, __w, __io, __cs3, __cs, __len);
            __cs = __cs3;
          }
@@ -867,13 +881,13 @@ namespace std
     _M_group_float(const string& __grouping, _CharT __sep, const _CharT* __p, 
                   _CharT* __new, _CharT* __cs, int& __len) const
     {
-#ifdef _GLIBCXX_RESOLVE_LIB_DEFECTS
-      //282. What types does numpunct grouping refer to?
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 282. What types does numpunct grouping refer to?
       // Add grouping, if necessary. 
       _CharT* __p2;
-      int __declen = __p ? __p - __cs : __len;
-      __p2 = std::__add_grouping(__new, __sep, __grouping.c_str(),
-                                __grouping.c_str() + __grouping.size(),
+      const int __declen = __p ? __p - __cs : __len;
+      __p2 = std::__add_grouping(__new, __sep, __grouping.data(),
+                                __grouping.data() + __grouping.size(),
                                 __cs, __cs + __declen);
       
       // Tack on decimal part.
@@ -884,7 +898,6 @@ namespace std
          __newlen += __len - __declen;
        }    
       __len = __newlen;
-#endif
     }
 
   // The following code uses snprintf (or sprintf(), when
@@ -984,24 +997,23 @@ namespace std
        __ws[__p - __ws] = __dec;
 
       // Add grouping, if necessary. 
-      _CharT* __ws2;
       if (__lc->_M_use_grouping)
        {
          // Grouping can add (almost) as many separators as the
          // number of digits, but no more.
-         __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
-                                                       * __len * 2));
+         _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
+                                                               * __len * 2));
          _M_group_float(__lc->_M_grouping, __lc->_M_thousands_sep, __p,
                         __ws2, __ws, __len);
          __ws = __ws2;
        }
 
       // Pad.
-      _CharT* __ws3;
-      streamsize __w = __io.width();
+      const streamsize __w = __io.width();
       if (__w > static_cast<streamsize>(__len))
        {
-         __ws3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __w));
+         _CharT* __ws3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
+                                                               * __w));
          _M_pad(__fill, __w, __io, __ws3, __ws, __len);
          __ws = __ws3;
        }
@@ -1017,7 +1029,7 @@ namespace std
     num_put<_CharT, _OutIter>::
     do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const
     {
-      ios_base::fmtflags __flags = __io.flags();
+      const ios_base::fmtflags __flags = __io.flags();
       if ((__flags & ios_base::boolalpha) == 0)
         {
           unsigned long __uv = __v;
@@ -1030,16 +1042,16 @@ namespace std
          const locale& __loc = __io._M_getloc();
          const __cache_type* __lc = __uc(__loc);
 
-         const _CharT* __name;
-         __name = __v ? __lc->_M_truename : __lc->_M_falsename;
-         int __len = char_traits<_CharT>::length(__name);
+         const _CharT* __name = __v ? __lc->_M_truename 
+                                    : __lc->_M_falsename;
+         int __len = __v ? __lc->_M_truename_len
+                         : __lc->_M_falsename_len;
 
-         _CharT* __cs;
-         streamsize __w = __io.width();
+         const streamsize __w = __io.width();
          if (__w > static_cast<streamsize>(__len))
            {
-             __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
-                                                           * __w));
+             _CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
+                                                                  * __w));
              _M_pad(__fill, __w, __io, __cs, __name, __len);
              __name = __cs;
            }
@@ -1096,21 +1108,14 @@ namespace std
     do_put(iter_type __s, ios_base& __io, char_type __fill,
            const void* __v) const
     {
-      ios_base::fmtflags __flags = __io.flags();
-      ios_base::fmtflags __fmt = ~(ios_base::showpos | ios_base::basefield
-                                  | ios_base::uppercase | ios_base::internal);
+      const ios_base::fmtflags __flags = __io.flags();
+      const ios_base::fmtflags __fmt = ~(ios_base::showpos | ios_base::basefield
+                                        | ios_base::uppercase | ios_base::internal);
       __io.flags(__flags & __fmt | (ios_base::hex | ios_base::showbase));
-      try 
-       {
-         __s = _M_insert_int(__s, __io, __fill, 
-                             reinterpret_cast<unsigned long>(__v));
-         __io.flags(__flags);
-       }
-      catch (...) 
-       {
-         __io.flags(__flags);
-         __throw_exception_again;
-       }
+      
+      __s = _M_insert_int(__s, __io, __fill, 
+                         reinterpret_cast<unsigned long>(__v));
+      __io.flags(__flags);
       return __s;
     }
 
@@ -1124,12 +1129,12 @@ namespace std
       string_type __str;
       __beg = this->do_get(__beg, __end, __intl, __io, __err, __str); 
 
-      const int __n = numeric_limits<long double>::digits10;
-      char* __cs = static_cast<char*>(__builtin_alloca(__n));
+      const int __cs_size = __str.size() + 1;
+      char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
       const locale __loc = __io.getloc();
       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 
       const _CharT* __wcs = __str.c_str();
-      __ctype.narrow(__wcs, __wcs + __str.size() + 1, char(), __cs);      
+      __ctype.narrow(__wcs, __wcs + __cs_size, char(), __cs);      
       std::__convert_to_v(__cs, __units, __err, _S_get_c_locale());
       return __beg;
     }
@@ -1154,10 +1159,10 @@ namespace std
       const money_base::pattern __p = __intl ? __mpt.neg_format() 
                                             : __mpf.neg_format();
 
-      const string_type __pos_sign =__intl ? __mpt.positive_sign() 
-                                          : __mpf.positive_sign();
-      const string_type __neg_sign =__intl ? __mpt.negative_sign() 
-                                          : __mpf.negative_sign();
+      const string_type __pos_sign = __intl ? __mpt.positive_sign() 
+                                           : __mpf.positive_sign();
+      const string_type __neg_sign = __intl ? __mpt.negative_sign() 
+                                           : __mpf.negative_sign();
       const char_type __d = __intl ? __mpt.decimal_point() 
                                   : __mpf.decimal_point();
       const char_type __sep = __intl ? __mpt.thousands_sep() 
@@ -1179,161 +1184,152 @@ namespace std
       // The tentative returned string is stored here.
       string_type __tmp_units;
 
-      char_type __c = *__beg;
-      char_type __eof = static_cast<char_type>(char_traits<char_type>::eof());
       for (int __i = 0; __beg != __end && __i < 4 && __testvalid; ++__i)
        {
-         part __which = static_cast<part>(__p.field[__i]);
+         char_type __c;
+         const part __which = static_cast<part>(__p.field[__i]);
          switch (__which)
+           {
+           case money_base::symbol:
+             if (__io.flags() & ios_base::showbase 
+                 || __i < 2 || __sign.size() > 1
+                 || ((static_cast<part>(__p.field[3]) != money_base::none)
+                     && __i == 2)) 
                {
-               case money_base::symbol:
-                 if (__io.flags() & ios_base::showbase 
-                     || __i < 2 || __sign.size() > 1
-                     || ((static_cast<part>(__p.field[3]) != money_base::none)
-                         && __i == 2)) 
-                   {
-                     // According to 22.2.6.1.2.2, symbol is required
-                     // if (__io.flags() & ios_base::showbase),
-                     // otherwise is optional and consumed only if
-                     // other characters are needed to complete the
-                     // format.
-                     const string_type __symbol = __intl ? __mpt.curr_symbol()
-                                                        : __mpf.curr_symbol();
-                     size_type __len = __symbol.size();
-                     size_type __j = 0;
-                     while (__beg != __end 
-                            && __j < __len && __symbol[__j] == __c)
-                       {
-                         __c = *(++__beg);
-                         ++__j;
-                       }
-                     // When (__io.flags() & ios_base::showbase)
-                     // symbol is required.
-                     if (__j != __len && (__io.flags() & ios_base::showbase))
-                       __testvalid = false;
-                   }
-                 break;
-               case money_base::sign:              
-                 // Sign might not exist, or be more than one character long. 
-                 if (__pos_sign.size() && __neg_sign.size())
+                 // According to 22.2.6.1.2.2, symbol is required
+                 // if (__io.flags() & ios_base::showbase),
+                 // otherwise is optional and consumed only if
+                 // other characters are needed to complete the
+                 // format.
+                 const string_type __symbol = __intl ? __mpt.curr_symbol()
+                                                     : __mpf.curr_symbol();
+                 const size_type __len = __symbol.size();
+                 size_type __j = 0;
+                 for (; __beg != __end && __j < __len
+                        && *__beg == __symbol[__j]; ++__beg, ++__j);
+                 // When (__io.flags() & ios_base::showbase)
+                 // symbol is required.
+                 if (__j != __len && (__io.flags() & ios_base::showbase))
+                   __testvalid = false;
+               }
+             break;
+           case money_base::sign:                  
+             // Sign might not exist, or be more than one character long.
+             if (__pos_sign.size() && *__beg == __pos_sign[0])
+               {
+                 __sign = __pos_sign;
+                 ++__beg;
+               }
+             else if (__neg_sign.size() && *__beg == __neg_sign[0])
+               {
+                 __sign = __neg_sign;
+                 ++__beg;
+               }
+             else if (__pos_sign.size() && __neg_sign.size())
+               {
+                 // Sign is mandatory.
+                 __testvalid = false;
+               }
+             break;
+           case money_base::value:
+             // Extract digits, remove and stash away the
+             // grouping of found thousands separators.
+             for (; __beg != __end; ++__beg)
+               if (__ctype.is(ctype_base::digit, __c = *__beg))
+                 {
+                   __tmp_units += __c;
+                   ++__sep_pos;
+                 }
+               else if (__c == __d && !__testdecfound)
                  {
-                   // Sign is mandatory.
-                   if (__c == __pos_sign[0])
+                   __grouping_tmp += static_cast<char>(__sep_pos);
+                   __sep_pos = 0;
+                   __testdecfound = true;
+                 }
+               else if (__c == __sep)
+                 {
+                   if (__grouping.size())
                      {
-                       __sign = __pos_sign;
-                       __c = *(++__beg);
+                       // Mark position for later analysis.
+                       __grouping_tmp += static_cast<char>(__sep_pos);
+                       __sep_pos = 0;
                      }
-                   else if (__c == __neg_sign[0])
+                   else
                      {
-                       __sign = __neg_sign;
-                       __c = *(++__beg);
+                       __testvalid = false;
+                       break;
                      }
-                   else
-                     __testvalid = false;
                  }
-                 else if (__pos_sign.size() && __c == __pos_sign[0])
-                   {
-                     __sign = __pos_sign;
-                     __c = *(++__beg);
-                   }
-                 else if (__neg_sign.size() && __c == __neg_sign[0])
-                   {
-                     __sign = __neg_sign;
-                     __c = *(++__beg);
-                   }
+               else
                  break;
-               case money_base::value:
-                 // Extract digits, remove and stash away the
-                 // grouping of found thousands separators.
-                 while (__beg != __end 
-                        && (__ctype.is(ctype_base::digit, __c) 
-                            || (__c == __d && !__testdecfound)
-                            || __c == __sep))
-                   {
-                     if (__c == __d)
-                       {
-                         __grouping_tmp += static_cast<char>(__sep_pos);
-                         __sep_pos = 0;
-                         __testdecfound = true;
-                       }
-                     else if (__c == __sep)
-                       {
-                         if (__grouping.size())
-                           {
-                             // Mark position for later analysis.
-                             __grouping_tmp += static_cast<char>(__sep_pos);
-                             __sep_pos = 0;
-                           }
-                         else
-                           {
-                             __testvalid = false;
-                             break;
-                           }
-                       }
-                     else
-                       {
-                         __tmp_units += __c;
-                         ++__sep_pos;
-                       }
-                     __c = *(++__beg);
-                   }
-                 break;
-               case money_base::space:
-               case money_base::none:
-                 // Only if not at the end of the pattern.
-                 if (__i != 3)
-                   while (__beg != __end 
-                          && __ctype.is(ctype_base::space, __c))
-                     __c = *(++__beg);
-                 break;
-               }
+             break;
+           case money_base::space:
+           case money_base::none:
+             // Only if not at the end of the pattern.
+             if (__i != 3)
+               for (; __beg != __end 
+                      && __ctype.is(ctype_base::space, *__beg); ++__beg);
+             break;
+           }
        }
-
+      
       // Need to get the rest of the sign characters, if they exist.
       if (__sign.size() > 1)
        {
-         size_type __len = __sign.size();
+         const size_type __len = __sign.size();
          size_type __i = 1;
-         for (; __c != __eof && __i < __len; ++__i)
-           while (__beg != __end && __c != __sign[__i])
-             __c = *(++__beg);
+         for (; __beg != __end && __i < __len; ++__i)
+           for (; __beg != __end
+                  && *__beg != __sign[__i]; ++__beg);
          
          if (__i != __len)
            __testvalid = false;
        }
 
-      // Strip leading zeros.
-      while (__tmp_units.size() > 1 && __tmp_units[0] == __ctype.widen('0'))
-       __tmp_units.erase(__tmp_units.begin());
-
-      if (__sign.size() && __sign == __neg_sign)
-       __tmp_units.insert(__tmp_units.begin(), __ctype.widen('-'));
-
-      // Test for grouping fidelity.
-      if (__grouping.size() && __grouping_tmp.size())
+      if (__testvalid && __tmp_units.size())
        {
-         if (!std::__verify_grouping(__grouping, __grouping_tmp))
-           __testvalid = false;
-       }
+         const char_type __zero = __ctype.widen('0');
 
-      // Iff no more characters are available.      
-      if (__c == __eof)
-       __err |= ios_base::eofbit;
+         // Strip leading zeros.
+         if (__tmp_units.size() > 1)
+           {
+             const size_type __first = __tmp_units.find_first_not_of(__zero);
+             const bool __only_zeros = __first == string_type::npos;
+             if (__first)
+               __tmp_units.erase(0, __only_zeros ? __tmp_units.size() - 1
+                                                 : __first);
+           }
+         
+         // 22.2.6.1.2, p4
+         if (__sign.size() && __sign == __neg_sign
+             && __tmp_units[0] != __zero)
+           __tmp_units.insert(__tmp_units.begin(), __ctype.widen('-'));
 
-      // Iff not enough digits were supplied after the decimal-point.
-      if (__testdecfound)
-       {
-         const int __frac = __intl ? __mpt.frac_digits() 
-                                   : __mpf.frac_digits();
-         if (__frac > 0)
+         // Test for grouping fidelity.
+         if (__grouping.size() && __grouping_tmp.size())
+           {
+             if (!std::__verify_grouping(__grouping, __grouping_tmp))
+               __testvalid = false;
+           }
+         
+         // Iff not enough digits were supplied after the decimal-point.
+         if (__testdecfound)
            {
-             if (__sep_pos != __frac)
+             const int __frac = __intl ? __mpt.frac_digits() 
+                                       : __mpf.frac_digits();
+             if (__frac > 0 && __sep_pos != __frac)
                __testvalid = false;
            }
        }
+      else
+       __testvalid = false;
+
+      // Iff no more characters are available.      
+      if (__beg == __end)
+       __err |= ios_base::eofbit;
 
       // Iff valid sequence is not recognized.
-      if (!__testvalid || !__tmp_units.size())
+      if (!__testvalid)
        __err |= ios_base::failbit;
       else
        // Use the "swap trick" to copy __tmp_units into __units.
@@ -1354,22 +1350,23 @@ namespace std
       // First try a buffer perhaps big enough.
       int __cs_size = 64;
       char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
-      int __len = std::__convert_from_v(__cs, __cs_size, "%.01Lf", __units, 
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 328. Bad sprintf format modifier in money_put<>::do_put()
+      int __len = std::__convert_from_v(__cs, __cs_size, "%.0Lf", __units, 
                                        _S_get_c_locale());
       // If the buffer was not large enough, try again with the correct size.
       if (__len >= __cs_size)
        {
          __cs_size = __len + 1;
          __cs = static_cast<char*>(__builtin_alloca(__cs_size));
-         __len = std::__convert_from_v(__cs, __cs_size, "%.01Lf", __units, 
+         __len = std::__convert_from_v(__cs, __cs_size, "%.0Lf", __units, 
                                        _S_get_c_locale());
        }
 #else
-      // max_exponent10 + 1 for the integer part, + 4 for sign, decimal point,
-      // decimal digit, '\0'. 
-      const int __cs_size = numeric_limits<long double>::max_exponent10 + 5;
+      // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'. 
+      const int __cs_size = numeric_limits<long double>::max_exponent10 + 3;
       char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
-      int __len = std::__convert_from_v(__cs, 0, "%.01Lf", __units, 
+      int __len = std::__convert_from_v(__cs, 0, "%.0Lf", __units, 
                                        _S_get_c_locale());
 #endif
       _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
@@ -1407,12 +1404,12 @@ namespace std
       if (*__beg != __ctype.widen('-'))
        {
          __p = __intl ? __mpt.pos_format() : __mpf.pos_format();
-         __sign =__intl ? __mpt.positive_sign() : __mpf.positive_sign();
+         __sign = __intl ? __mpt.positive_sign() : __mpf.positive_sign();
        }
       else
        {
          __p = __intl ? __mpt.neg_format() : __mpf.neg_format();
-         __sign =__intl ? __mpt.negative_sign() : __mpf.negative_sign();
+         __sign = __intl ? __mpt.negative_sign() : __mpf.negative_sign();
          ++__beg;
        }
       
@@ -1445,8 +1442,8 @@ namespace std
                {
                  // Have to pad zeros in the decimal position.
                  __value = string_type(__beg, __end);
-                 int __paddec = __frac - (__end - __beg);
-                 char_type __zero = __ctype.widen('0');
+                 const int __paddec = __frac - (__end - __beg);
+                 const char_type __zero = __ctype.widen('0');
                  __value.insert(__value.begin(), __paddec, __zero);
                  __value.insert(__value.begin(), __d);
                  __beg = __end;
@@ -1463,7 +1460,7 @@ namespace std
                {
                  const char_type __sep = __intl ? __mpt.thousands_sep() 
                                                 : __mpf.thousands_sep();
-                 const char* __gbeg = __grouping.c_str();
+                 const char* __gbeg = __grouping.data();
                  const char* __gend = __gbeg + __grouping.size();
                  const int __n = (__end - __beg) * 2;
                  _CharT* __ws2 =
@@ -1477,15 +1474,15 @@ namespace std
            }
 
          // Calculate length of resulting string.
-         ios_base::fmtflags __f = __io.flags() & ios_base::adjustfield;
+         const ios_base::fmtflags __f = __io.flags() & ios_base::adjustfield;
          size_type __len = __value.size() + __sign.size();
          __len += (__io.flags() & ios_base::showbase) ? __symbol.size() : 0;
-         bool __testipad = __f == ios_base::internal && __len < __width;
+         const bool __testipad = __f == ios_base::internal && __len < __width;
 
          // Fit formatted digits into the required pattern.
          for (int __i = 0; __i < 4; ++__i)
            {
-             part __which = static_cast<part>(__p.field[__i]);
+             const part __which = static_cast<part>(__p.field[__i]);
              switch (__which)
                {
                case money_base::symbol:
@@ -1536,7 +1533,7 @@ namespace std
            }
 
          // Write resulting, fully-formatted string to output iterator.
-         __s = std::__write(__s, __res.c_str(), __len);
+         __s = std::__write(__s, __res.data(), __len);
        }
       __io.width(0);
       return __s; 
@@ -1551,6 +1548,10 @@ namespace std
     time_get<_CharT, _InIter>::do_date_order() const
     { return time_base::no_order; }
 
+  // Recursively expand a strftime format string and parse it.  Starts w/ %x
+  // and %X from do_get_time() and do_get_date(), which translate to a more
+  // specific string, which may contain yet more strings.  I.e. %x => %r =>
+  // %H:%M:%S => extracted characters.
   template<typename _CharT, typename _InIter>
     void
     time_get<_CharT, _InIter>::
@@ -1558,25 +1559,20 @@ namespace std
                          ios_base::iostate& __err, tm* __tm, 
                          const _CharT* __format) const
     {  
-      locale __loc = __io.getloc();
-      __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
+      const locale __loc = __io.getloc();
+      const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 
-      size_t __len = char_traits<_CharT>::length(__format);
+      const size_t __len = char_traits<_CharT>::length(__format);
 
       for (size_t __i = 0; __beg != __end && __i < __len && !__err; ++__i)
        {
-         char __c = __format[__i];
-         if (__c == '%')
+         if (__ctype.narrow(__format[__i], 0) == '%')
            {
              // Verify valid formatting code, attempt to extract.
-             __c = __format[++__i];
-             char __mod = 0;
+             char __c = __ctype.narrow(__format[++__i], 0);
              int __mem = 0; 
              if (__c == 'E' || __c == 'O')
-               {
-                 __mod = __c;
-                 __c = __format[++__i];
-               }
+               __c = __ctype.narrow(__format[++__i], 0);
              switch (__c)
                {
                  const char* __cs;
@@ -1586,14 +1582,14 @@ namespace std
                  const char_type*  __days1[7];
                  __tp._M_days_abbreviated(__days1);
                  _M_extract_name(__beg, __end, __tm->tm_wday, __days1, 7, 
-                                 __err);
+                                 __ctype, __err);
                  break;
                case 'A':
                  // Weekday name [tm_wday].
                  const char_type*  __days2[7];
                  __tp._M_days(__days2);
                  _M_extract_name(__beg, __end, __tm->tm_wday, __days2, 7, 
-                                 __err);
+                                 __ctype, __err);
                  break;
                case 'h':
                case 'b':
@@ -1601,14 +1597,14 @@ namespace std
                  const char_type*  __months1[12];
                  __tp._M_months_abbreviated(__months1);
                  _M_extract_name(__beg, __end, __tm->tm_mon, __months1, 12, 
-                                 __err);
+                                 __ctype, __err);
                  break;
                case 'B':
                  // Month name [tm_mon].
                  const char_type*  __months2[12];
                  __tp._M_months(__months2);
                  _M_extract_name(__beg, __end, __tm->tm_mon, __months2, 12, 
-                                 __err);
+                                 __ctype, __err);
                  break;
                case 'c':
                  // Default time and date representation.
@@ -1622,6 +1618,16 @@ namespace std
                  _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2, 
                                 __ctype, __err);
                  break;
+               case 'e':
+                 // Day [1, 31], with single digits preceded by
+                 // space. [tm_mday]
+                 if (__ctype.is(ctype_base::space, *__beg))
+                   _M_extract_num(++__beg, __end, __tm->tm_mday, 1, 9, 1,
+                                  __ctype, __err);
+                 else
+                   _M_extract_num(__beg, __end, __tm->tm_mday, 10, 31, 2,
+                                  __ctype, __err);                 
+                 break;                    
                case 'D':
                  // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year]
                  __cs = "%m/%d/%y";
@@ -1673,7 +1679,7 @@ namespace std
                  if (__ctype.narrow(*__beg, 0) == '\t')
                    ++__beg;
                  else
-               __err |= ios_base::failbit;
+                   __err |= ios_base::failbit;
                  break;
                case 'T':
                  // Equivalent to (%H:%M:%S).
@@ -1697,14 +1703,14 @@ namespace std
                                        __times[0]);
                  break;
                case 'y':
+               case 'C': // C99
                  // Two digit year. [tm_year]
                  _M_extract_num(__beg, __end, __tm->tm_year, 0, 99, 2, 
                                 __ctype, __err);
                  break;
                case 'Y':
                  // Year [1900). [tm_year]
-                 _M_extract_num(__beg, __end, __mem, 0, 
-                                numeric_limits<int>::max(), 4, 
+                 _M_extract_num(__beg, __end, __mem, 0, 9999, 4, 
                                 __ctype, __err);
                  if (!__err)
                    __tm->tm_year = __mem - 1900;
@@ -1716,36 +1722,35 @@ namespace std
                      int __tmp;
                      _M_extract_name(__beg, __end, __tmp, 
                                      __timepunct_cache<_CharT>::_S_timezones, 
-                                     14, __err);
+                                     14, __ctype, __err);
                      
                      // GMT requires special effort.
-                     char_type __c = *__beg;
-                     if (!__err && __tmp == 0 
-                         && (__c == __ctype.widen('-') 
-                             || __c == __ctype.widen('+')))
+                     if (__beg != __end && !__err && __tmp == 0
+                         && (*__beg == __ctype.widen('-') 
+                             || *__beg == __ctype.widen('+')))
                        {
                          _M_extract_num(__beg, __end, __tmp, 0, 23, 2,
                                          __ctype, __err);
                          _M_extract_num(__beg, __end, __tmp, 0, 59, 2,
                                          __ctype, __err);
                        }           
-                         }
-                     else
-                       __err |= ios_base::failbit;
-                     break;
-                   default:
-                     // Not recognized.
-                     __err |= ios_base::failbit;
                    }
-               }
-             else
-               {
-                 // Verify format and input match, extract and discard.
-                 if (__c == __ctype.narrow(*__beg, 0))
-                   ++__beg;
                  else
                    __err |= ios_base::failbit;
+                 break;
+               default:
+                 // Not recognized.
+                 __err |= ios_base::failbit;
                }
+           }
+         else
+           {
+             // Verify format and input match, extract and discard.
+             if (__format[__i] == *__beg)
+               ++__beg;
+             else
+               __err |= ios_base::failbit;
+           }
        }
     }
 
@@ -1757,28 +1762,29 @@ namespace std
                   const ctype<_CharT>& __ctype, 
                   ios_base::iostate& __err) const
     {
+      // As-is works for __len = 1, 2, 4, the values actually used.
+      int __mult = __len == 2 ? 10 : (__len == 4 ? 1000 : 1);
+
+      ++__min;
       size_t __i = 0;
-      string __digits;
-      bool __testvalid = true;
-      char_type __c = *__beg;
-      while (__beg != __end && __i < __len 
-            && __ctype.is(ctype_base::digit, __c)) 
-       {
-         __digits += __ctype.narrow(__c, 0);
-         __c = *(++__beg);
-         ++__i;
-       }
-      if (__i == __len)
+      int __value = 0;
+      for (; __beg != __end && __i < __len; ++__beg, ++__i)
        {
-         int __value = atoi(__digits.c_str());
-         if (__min <= __value && __value <= __max)
-           __member = __value;
+         const char __c = __ctype.narrow(*__beg, '*');
+         if (__c >= '0' && __c <= '9')
+           {
+             __value = __value * 10 + (__c - '0');
+             const int __valuec = __value * __mult;
+             if (__valuec > __max || __valuec + __mult < __min)
+               break;
+             __mult /= 10;
+           }
          else
-           __testvalid = false;
+           break;
        }
+      if (__i == __len)
+       __member = __value;
       else
-       __testvalid = false;
-      if (!__testvalid)
        __err |= ios_base::failbit;
     }
 
@@ -1789,6 +1795,7 @@ namespace std
     time_get<_CharT, _InIter>::
     _M_extract_name(iter_type& __beg, iter_type& __end, int& __member,
                    const _CharT** __names, size_t __indexlen, 
+                   const ctype<_CharT>& __ctype, 
                    ios_base::iostate& __err) const
     {
       typedef char_traits<_CharT>              __traits_type;
@@ -1799,11 +1806,18 @@ namespace std
       bool __testvalid = true;
       const char_type* __name;
 
-      char_type __c = *__beg;
-      // Look for initial matches.
-      for (size_t __i1 = 0; __i1 < __indexlen; ++__i1)
-       if (__c == __names[__i1][0])
-         __matches[__nmatches++] = __i1;
+      // Look for initial matches.  
+      // NB: Some of the locale data is in the form of all lowercase
+      // names, and some is in the form of initially-capitalized
+      // names. Look for both.
+      if (__beg != __end)
+       {
+         const char_type __c = *__beg;
+         for (size_t __i1 = 0; __i1 < __indexlen; ++__i1)
+           if (__c == __names[__i1][0] 
+               || __c == __ctype.toupper(__names[__i1][0]))
+             __matches[__nmatches++] = __i1;
+       }
       
       while (__nmatches > 1)
        {
@@ -1812,15 +1826,14 @@ namespace std
          for (size_t __i2 = 0; __i2 < __nmatches; ++__i2)
            __minlen = std::min(__minlen, 
                                __traits_type::length(__names[__matches[__i2]]));
-         
+         ++__beg;
          if (__pos < __minlen && __beg != __end)
            {
              ++__pos;
-             __c = *(++__beg);
              for (size_t __i3 = 0; __i3 < __nmatches; ++__i3)
                {
                  __name = __names[__matches[__i3]];
-                 if (__name[__pos] != __c)
+                 if (__name[__pos] != *__beg)
                    __matches[__i3] = __matches[--__nmatches];
                }
            }
@@ -1830,6 +1843,13 @@ namespace std
 
       if (__nmatches == 1)
        {
+         // If there was only one match, the first compare is redundant.
+         if (__pos == 0)
+           {
+             ++__pos;
+             ++__beg;
+           }
+
          // Make sure found name is completely extracted.
          __name = __names[__matches[0]];
          const size_t __len = __traits_type::length(__name);
@@ -1855,7 +1875,7 @@ namespace std
     {
       _CharT __wcs[3];
       const char* __cs = "%X";
-      locale __loc = __io.getloc();
+      const locale __loc = __io.getloc();
       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
       __ctype.widen(__cs, __cs + 3, __wcs);
       _M_extract_via_format(__beg, __end, __io, __err, __tm, __wcs);
@@ -1872,7 +1892,7 @@ namespace std
     {
       _CharT __wcs[3];
       const char* __cs = "%x";
-      locale __loc = __io.getloc();
+      const locale __loc = __io.getloc();
       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
       __ctype.widen(__cs, __cs + 3, __wcs);
       _M_extract_via_format(__beg, __end, __io, __err, __tm, __wcs);
@@ -1888,12 +1908,13 @@ namespace std
                   ios_base::iostate& __err, tm* __tm) const
     {
       typedef char_traits<_CharT>              __traits_type;
-      locale __loc = __io.getloc();
-      __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
+      const locale __loc = __io.getloc();
+      const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
+      const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 
       const char_type*  __days[7];
       __tp._M_days_abbreviated(__days);
       int __tmpwday;
-      _M_extract_name(__beg, __end, __tmpwday, __days, 7, __err);
+      _M_extract_name(__beg, __end, __tmpwday, __days, 7, __ctype, __err);
 
       // Check to see if non-abbreviated name exists, and extract.
       // NB: Assumes both _M_days and _M_days_abbreviated organized in
@@ -1931,12 +1952,13 @@ namespace std
                      ios_base& __io, ios_base::iostate& __err, tm* __tm) const
     {
       typedef char_traits<_CharT>              __traits_type;
-      locale __loc = __io.getloc();
-      __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
+      const locale __loc = __io.getloc();
+      const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
+      const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 
       const char_type*  __months[12];
       __tp._M_months_abbreviated(__months);
       int __tmpmon;
-      _M_extract_name(__beg, __end, __tmpmon, __months, 12, __err);
+      _M_extract_name(__beg, __end, __tmpmon, __months, 12, __ctype, __err);
 
       // Check to see if non-abbreviated name exists, and extract.
       // NB: Assumes both _M_months and _M_months_abbreviated organized in
@@ -1974,29 +1996,21 @@ namespace std
     do_get_year(iter_type __beg, iter_type __end, ios_base& __io, 
                ios_base::iostate& __err, tm* __tm) const
     {
-      locale __loc = __io.getloc();
+      const locale __loc = __io.getloc();
       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 
 
-      char_type __c = *__beg;
       size_t __i = 0;
-      string __digits;
-      while (__i < 4 && __beg != __end && __ctype.is(ctype_base::digit, __c))
+      int __value = 0;
+      for (; __beg != __end && __i < 4; ++__beg, ++__i)
        {
-         __digits += __ctype.narrow(__c, 0);
-         __c = *(++__beg);
-         ++__i;
+         const char __c = __ctype.narrow(*__beg, '*');
+         if (__c >= '0' && __c <= '9')
+           __value = __value * 10 + (__c - '0');
+         else
+           break;
        }
       if (__i == 2 || __i == 4)
-       {
-         long __l;
-         std::__convert_to_v(__digits.c_str(), __l, __err,
-                             _S_get_c_locale());
-         if (!(__err & ios_base::failbit) && __l <= INT_MAX)
-           {
-             __l = __i == 2 ? __l : __l - 1900; 
-             __tm->tm_year = static_cast<int>(__l);
-           }
-       }
+       __tm->tm_year = __i == 2 ? __value : __value - 1900; 
       else
        __err |= ios_base::failbit;
       if (__beg == __end)
@@ -2010,34 +2024,33 @@ namespace std
     put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, 
        const _CharT* __beg, const _CharT* __end) const
     {
-      locale __loc = __io.getloc();
+      const locale __loc = __io.getloc();
       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
-      while (__beg != __end)
-       {
-         const _CharT __tmp = *__beg;
-         ++__beg;
-         if (__ctype.narrow(__tmp, 0) == '%' && __beg != __end)
-           {
-             char __format;
-             char __mod = 0;
-             const char __c = __ctype.narrow(*__beg, 0);
-             ++__beg;
-             if (__c == 'E' || __c == 'O')
-               {
-                 __mod = __c;
-                 __format = __ctype.narrow(*__beg, 0);
-                 ++__beg;
-               }
-             else
-               __format = __c;
-             __s = this->do_put(__s, __io, __fill, __tm, __format, __mod);
-           }
-         else
-           {
-             *__s = __tmp;
-             ++__s;
-           }
-       }
+      for (; __beg != __end; ++__beg)
+       if (__ctype.narrow(*__beg, 0) != '%')
+         {
+           *__s = *__beg;
+           ++__s;
+         }
+       else if (++__beg != __end)
+         {
+           char __format;
+           char __mod = 0;
+           const char __c = __ctype.narrow(*__beg, 0);
+           if (__c != 'E' && __c != 'O')
+             __format = __c;
+           else if (++__beg != __end)
+             {
+               __mod = __c;
+               __format = __ctype.narrow(*__beg, 0);
+             }
+           else
+             break;
+           __s = this->do_put(__s, __io, __fill, __tm,
+                              __format, __mod);
+         }
+       else
+         break;
       return __s;
     }
 
@@ -2047,14 +2060,15 @@ namespace std
     do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm, 
           char __format, char __mod) const
     { 
-      locale __loc = __io.getloc();
+      const locale __loc = __io.getloc();
       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
       __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
 
       // NB: This size is arbitrary. Should this be a data member,
       // initialized at construction?
       const size_t __maxlen = 64;
-      char_type* __res = static_cast<char_type*>(__builtin_alloca(sizeof(char_type) * __maxlen));
+      char_type* __res = static_cast<char_type*>(__builtin_alloca(sizeof(char_type)
+                                                                 * __maxlen));
 
       // NB: In IEE 1003.1-200x, and perhaps other locale models, it
       // is possible that the format character will be longer than one
@@ -2106,16 +2120,16 @@ namespace std
       const string_type __two(__lo2, __hi2);
 
       const _CharT* __p = __one.c_str();
-      const _CharT* __pend = __one.c_str() + __one.length();
+      const _CharT* __pend = __one.data() + __one.length();
       const _CharT* __q = __two.c_str();
-      const _CharT* __qend = __two.c_str() + __two.length();
+      const _CharT* __qend = __two.data() + __two.length();
 
       // strcoll stops when it sees a nul character so we break
       // the strings into zero-terminated substrings and pass those
       // to strcoll.
       for (;;)
        {
-         int __res = _M_compare(__p, __q);
+         const int __res = _M_compare(__p, __q);
          if (__res)
            return __res;
 
@@ -2133,7 +2147,7 @@ namespace std
        }
     }
 
- template<typename _CharT>
 template<typename _CharT>
     typename collate<_CharT>::string_type
     collate<_CharT>::
     do_transform(const _CharT* __lo, const _CharT* __hi) const
@@ -2142,7 +2156,7 @@ namespace std
       string_type __str(__lo, __hi);
 
       const _CharT* __p = __str.c_str();
-      const _CharT* __pend = __str.c_str() + __str.length();
+      const _CharT* __pend = __str.data() + __str.length();
 
       size_t __len = (__hi - __lo) * 2;
 
@@ -2177,7 +2191,7 @@ namespace std
        }
     }
 
- template<typename _CharT>
 template<typename _CharT>
     long
     collate<_CharT>::
     do_hash(const _CharT* __lo, const _CharT* __hi) const
@@ -2207,25 +2221,19 @@ namespace std
                                   const streamsize __newlen, 
                                   const streamsize __oldlen, const bool __num)
     {
-      size_t __plen = static_cast<size_t>(__newlen - __oldlen);
-      _CharT* __pads = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
-                                                            * __plen));
-      _Traits::assign(__pads, __plen, __fill); 
-
-      _CharT* __beg;
-      _CharT* __end;
-      size_t __mod = 0;
-      size_t __beglen; //either __plen or __oldlen
-      ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield;
+      const size_t __plen = static_cast<size_t>(__newlen - __oldlen);
+      const ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield;
 
+      // Padding last.
       if (__adjust == ios_base::left)
        {
-         // Padding last.
-         __beg = const_cast<_CharT*>(__olds);
-         __beglen = __oldlen;
-         __end = __pads;
+         _Traits::copy(__news, const_cast<_CharT*>(__olds), __oldlen);
+         _Traits::assign(__news + __oldlen, __plen, __fill);
+         return;
        }
-      else if (__adjust == ios_base::internal && __num)
+
+      size_t __mod = 0;
+      if (__adjust == ios_base::internal && __num)
        {
          // Pad after the sign, if there is one.
          // Pad after 0[xX], if there is one.
@@ -2254,43 +2262,32 @@ namespace std
              ++__news;
            }
          // else Padding first.
-         
-         __beg = __pads;
-         __beglen = __plen;
-         __end = const_cast<_CharT*>(__olds + __mod);
-       }
-      else
-       {
-         // Padding first.
-         __beg = __pads;
-         __beglen = __plen;
-         __end = const_cast<_CharT*>(__olds);
        }
-      _Traits::copy(__news, __beg, __beglen);
-      _Traits::copy(__news + __beglen, __end, __newlen - __beglen - __mod);
+      _Traits::assign(__news, __plen, __fill);
+      _Traits::copy(__news + __plen, const_cast<_CharT*>(__olds + __mod),
+                   __oldlen - __mod);
     }
 
   template<typename _CharT>
     bool
     __verify_grouping(const basic_string<_CharT>& __grouping, 
-                     basic_string<_CharT>& __grouping_tmp)
-    {         
-      size_t __i = 0;
-      size_t __j = 0;
-      const size_t __len = __grouping.size();
-      const size_t __n = __grouping_tmp.size();
+                     const basic_string<_CharT>& __grouping_tmp)
+    { 
+      const size_t __n = __grouping_tmp.size() - 1;
+      const size_t __min = std::min(__n, __grouping.size() - 1);
+      size_t __i = __n;
       bool __test = true;
-      
+
       // Parsed number groupings have to match the
       // numpunct::grouping string exactly, starting at the
       // right-most point of the parsed sequence of elements ...
-      while (__test && __i < __n - 1)
-       for (__j = 0; __test && __j < __len && __i < __n - 1; ++__j,++__i)
-         __test &= __grouping[__j] == __grouping_tmp[__n - __i - 1];
+      for (size_t __j = 0; __j < __min && __test; --__i, ++__j)
+       __test = __grouping_tmp[__i] == __grouping[__j];
+      for (; __i && __test; --__i)
+       __test = __grouping_tmp[__i] == __grouping[__min];
       // ... but the last parsed grouping can be <= numpunct
       // grouping.
-      __j == __len ? __j = 0 : __j;
-      __test &= __grouping[__j] >= __grouping_tmp[__n - __i - 1];
+      __test &= __grouping_tmp[0] <= __grouping[__min];
       return __test;
     }
 
@@ -2301,13 +2298,13 @@ namespace std
                   const _CharT* __first, const _CharT* __last)
     {
       if (__last - __first > *__gbeg)
-        {
+       {
          const bool __bump = __gbeg + 1 != __gend;
-          __s = std::__add_grouping(__s,  __sep, __gbeg + __bump,
+         __s = std::__add_grouping(__s,  __sep, __gbeg + __bump,
                                    __gend, __first, __last - *__gbeg);
-          __first = __last - *__gbeg;
-          *__s++ = __sep;
-        }
+         __first = __last - *__gbeg;
+         *__s++ = __sep;
+       }
       do
        *__s++ = *__first++;
       while (__first != __last);