OSDN Git Service

2001-11-27 Benjamin Kosnik <bkoz@redhat.com>
authorbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 28 Nov 2001 04:07:11 +0000 (04:07 +0000)
committerbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 28 Nov 2001 04:07:11 +0000 (04:07 +0000)
Numeric facets cleanup.
* include/bits/locale_facets.h (__num_base::_S_atoms): Add, remove
+ and - signs.
(__num_base::_M_zero): Add
(__num_base::_M_e): Add.
(__num_base::_M_E): Add.
* include/bits/locale_facets.tcc (num_get::_M_extract): Remove.
(num_get::_M_extract_float): New.
(num_get::_M_extract_int): New.
* src/locale.cc (num_get::_M_extract): Remove.

* include/bits/locale_facets.tcc (num_put::_M_insert_float):
Simplify, use _M_insert.
(num_put::do_put(bool)): Simplify, remove __pad.
(__pad): Remove.
(__pad_output): Change to __pad.
* include/bits/ostream.tcc: And here.
* src/locale-inst: Remove instantiations.

* include/bits/locale_facets.h: Move helper functions in to class
num_put.
(num_put::_M_insert_float): Same, for __output_integer.
(num_put::_M_insert_int): Same, for __output_float.
(num_put::_M_insert): New.
(__num_base): Add.
(__num_base::_S_format_float): Move
__build_float_format into class __num_base.
(__num_base::_S_format_int): Move __build_int_format into class
__num_base.
* include/bits/locale_facets.tcc (__group_digits): Change to
(__add_grouping): This.
* src/locale-inst.cc: And here. Tweak instantiations.
* src/misc-inst.cc: Remove instantiations.

* include/bits/ostream.tcc (__pad_char): Rename, adjust inserters
for new calling conventions, move to...
* include/bits/locale_facets.tcc (__pad_output): Here. Adjust
signature to make it useful for both ostream and num_put.
(__pad_numeric): Remove.
* src/misc-inst.cc: Remove instantiations.
* src/locale-inst.cc: Same.

* include/bits/locale_facets.h (_Numeric_get): Remove.
  (_Numeric_put): Remove.
(num_get::get(short)): Remove.
(num_get::get(int)): Remove.
(num_get::do_get(short)): Remove.
(num_get::do_get(int)): Remove.
* include/bits/istream.tcc (istream::operator>>(short)): Fix as
per DR 118.
(istream::operator>>(int)): Same.

* include/bits/locale_facets.h (_Format_cache): Remove.
* include/bits/locale_facets.tcc: Same.
* src/locale.cc: Same.
* src/locale-inst.cc: Same.
* include/bits/ostream.tcc: Same.
* src/ios.cc (ios_base::imbue): Remove here as well.

* testsuite/22_locale/num_get.cc: New file.
* testsuite/22_locale/num_get_members_char.cc: New file.
* testsuite/22_locale/num_get_members_wchar_t.cc: New.
* testsuite/22_locale/numpunct_members_wchar_t.cc: New file.
* testsuite/22_locale/num_put.cc: New file.
* testsuite/22_locale/num_put_members_char.cc: New file.
* testsuite/22_locale/num_put_members_wchar_t.cc: New file.
* testsuite/27_io/ostream_inserter_arith.cc: Fix.
* testsuite/27_io/istream_extractor_arith.cc: Fix.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@47397 138bc75d-0d04-0410-961f-82ee72b054a4

20 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/istream.tcc
libstdc++-v3/include/bits/locale_facets.h
libstdc++-v3/include/bits/locale_facets.tcc
libstdc++-v3/include/bits/ostream.tcc
libstdc++-v3/include/bits/std_istream.h
libstdc++-v3/include/bits/streambuf_iterator.h
libstdc++-v3/src/ios.cc
libstdc++-v3/src/locale-inst.cc
libstdc++-v3/src/locale.cc
libstdc++-v3/src/misc-inst.cc
libstdc++-v3/testsuite/22_locale/num_get.cc [new file with mode: 0644]
libstdc++-v3/testsuite/22_locale/num_get_members_char.cc [new file with mode: 0644]
libstdc++-v3/testsuite/22_locale/num_put.cc [new file with mode: 0644]
libstdc++-v3/testsuite/22_locale/num_put_members_char.cc [new file with mode: 0644]
libstdc++-v3/testsuite/22_locale/num_put_members_wchar_t.cc [new file with mode: 0644]
libstdc++-v3/testsuite/22_locale/numpunct_members_char.cc
libstdc++-v3/testsuite/22_locale/numpunct_members_wchar_t.cc [new file with mode: 0644]
libstdc++-v3/testsuite/27_io/istream_extractor_arith.cc
libstdc++-v3/testsuite/27_io/ostream_inserter_arith.cc

index 0f58b3c..b86bf98 100644 (file)
@@ -1,3 +1,74 @@
+2001-11-27  Benjamin Kosnik  <bkoz@redhat.com>
+
+       Numeric facets cleanup.
+       * include/bits/locale_facets.h (__num_base::_S_atoms): Add, remove
+       + and - signs.
+       (__num_base::_M_zero): Add
+       (__num_base::_M_e): Add.
+       (__num_base::_M_E): Add.        
+       * include/bits/locale_facets.tcc (num_get::_M_extract): Remove.
+       (num_get::_M_extract_float): New.
+       (num_get::_M_extract_int): New.
+       * src/locale.cc (num_get::_M_extract): Remove.
+       
+       * include/bits/locale_facets.tcc (num_put::_M_insert_float):
+       Simplify, use _M_insert.
+       (num_put::do_put(bool)): Simplify, remove __pad. 
+       (__pad): Remove.
+       (__pad_output): Change to __pad.
+       * include/bits/ostream.tcc: And here.
+       * src/locale-inst: Remove instantiations.
+
+       * include/bits/locale_facets.h: Move helper functions in to class
+       num_put.
+       (num_put::_M_insert_float): Same, for __output_integer.
+       (num_put::_M_insert_int): Same, for __output_float.
+       (num_put::_M_insert): New.
+       (__num_base): Add.
+       (__num_base::_S_format_float): Move
+       __build_float_format into class __num_base.
+       (__num_base::_S_format_int): Move __build_int_format into class
+       __num_base.
+       * include/bits/locale_facets.tcc (__group_digits): Change to
+       (__add_grouping): This.
+       * src/locale-inst.cc: And here. Tweak instantiations.
+       * src/misc-inst.cc: Remove instantiations.
+       
+       * include/bits/ostream.tcc (__pad_char): Rename, adjust inserters
+       for new calling conventions, move to...
+       * include/bits/locale_facets.tcc (__pad_output): Here. Adjust
+       signature to make it useful for both ostream and num_put.
+       (__pad_numeric): Remove.
+       * src/misc-inst.cc: Remove instantiations.
+       * src/locale-inst.cc: Same.
+
+       * include/bits/locale_facets.h (_Numeric_get): Remove.
+       (_Numeric_put): Remove.
+       (num_get::get(short)): Remove.
+       (num_get::get(int)): Remove.    
+       (num_get::do_get(short)): Remove.
+       (num_get::do_get(int)): Remove. 
+       * include/bits/istream.tcc (istream::operator>>(short)): Fix as
+       per DR 118.
+       (istream::operator>>(int)): Same.
+
+       * include/bits/locale_facets.h (_Format_cache): Remove.
+       * include/bits/locale_facets.tcc: Same.
+       * src/locale.cc: Same.
+       * src/locale-inst.cc: Same.
+       * include/bits/ostream.tcc: Same.
+       * src/ios.cc (ios_base::imbue): Remove here as well.
+
+       * testsuite/22_locale/num_get.cc: New file.
+       * testsuite/22_locale/num_get_members_char.cc: New file.
+       * testsuite/22_locale/num_get_members_wchar_t.cc: New.
+       * testsuite/22_locale/numpunct_members_wchar_t.cc: New file.
+       * testsuite/22_locale/num_put.cc: New file.
+       * testsuite/22_locale/num_put_members_char.cc: New file.
+       * testsuite/22_locale/num_put_members_wchar_t.cc: New file.
+       * testsuite/27_io/ostream_inserter_arith.cc: Fix.
+       * testsuite/27_io/istream_extractor_arith.cc: Fix.
+       
 2001-11-27  Phil Edwards  <pme@gcc.gnu.org>
 
        * docs/html/explanations.html:  New section, empty for now.
index 47b01f6..43ea6a5 100644 (file)
@@ -134,8 +134,18 @@ namespace std
          try 
            {
              ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+             long __l;
              if (_M_check_facet(_M_fnumget))
-               _M_fnumget->get(*this, 0, *this, __err, __n);
+               _M_fnumget->get(*this, 0, *this, __err, __l);
+#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
+             // 118. basic_istream uses nonexistent num_get member functions.
+             if (!(__err & ios_base::failbit)
+                 && (numeric_limits<short>::min() <= __l 
+                     && __l <= numeric_limits<short>::max()))
+               __n = __l;
+             else
+                __err |= ios_base::failbit;
+#endif
              this->setstate(__err);
            }
          catch(exception& __fail)
@@ -188,8 +198,18 @@ namespace std
          try 
            {
              ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+             long __l;
              if (_M_check_facet(_M_fnumget))
-               _M_fnumget->get(*this, 0, *this, __err, __n);
+               _M_fnumget->get(*this, 0, *this, __err, __l);
+#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
+             // 118. basic_istream uses nonexistent num_get member functions.
+             if (!(__err & ios_base::failbit)
+                 && (numeric_limits<int>::min() <= __l 
+                     && __l <= numeric_limits<int>::max()))
+               __n = __l;
+             else
+                __err |= ios_base::failbit;
+#endif
              this->setstate(__err);
            }
          catch(exception& __fail)
@@ -1252,4 +1272,3 @@ namespace std
 // Local Variables:
 // mode:C++
 // End:
-
index 8ea0ed5..878f8b2 100644 (file)
@@ -415,162 +415,157 @@ namespace std
   // 22.2.1.5  Template class codecvt
   #include <bits/codecvt.h>
 
-  template<typename _CharT, typename _InIter>
-    class _Numeric_get;  // forward
 
-  // _Format_cache holds the information extracted from the numpunct<>
-  // and moneypunct<> facets in a form optimized for parsing and
-  // formatting.  It is stored via a void* pointer in the pword()
-  // array of an iosbase object passed to the _get and _put facets.
-  // NB: contains no user-serviceable parts.
+  class __num_base
+  {
+  public:
+    // String literal of acceptable (narrow) input, for num_get.
+    // "0123456789eEabcdfxABCDFX"
+    static const char _S_atoms[];
+
+    enum 
+    {  
+      _M_zero,
+      _M_e = _M_zero + 10,
+      _M_E = _M_zero + 11,
+      _M_size = 23 + 1
+    };
+
+    // Construct and return valid scanf format for floating point types.
+    static bool
+    _S_format_float(const ios_base& __io, char* __fptr, char __mod, 
+                   streamsize __prec);
+    
+    // Construct and return valid scanf format for integer types.
+    static void
+    _S_format_int(const ios_base& __io, char* __fptr, char __mod, char __modl);
+  };
+
   template<typename _CharT>
-    class _Format_cache
+    class numpunct : public locale::facet
     {
-    public: 
+    public:
       // Types:
-      typedef _CharT                           char_type;
-      typedef char_traits<_CharT>              traits_type;
-      typedef basic_string<_CharT>             string_type;
-      typedef typename string_type::size_type  size_type;
-
-      // Forward decls and Friends:
-      friend class locale;
-      template<typename _Char, typename _InIter>
-        friend class _Numeric_get;
-      friend class num_get<_CharT>;
-      friend class num_put<_CharT>;
-      friend class time_get<_CharT>;
-      friend class money_get<_CharT>;
-      friend class time_put<_CharT>;
-      friend class money_put<_CharT>;
+      typedef _CharT                   char_type;
+      typedef basic_string<_CharT>     string_type;
 
-      // Data Members:
+      static locale::id                id;
 
-      // ios_base::pword() reserved cell
-      static int               _S_pword_ix; 
-
-      // True iff data members are consistent with the current locale,
-      // ie imbue sets this to false.
-      bool                     _M_valid;
-
-      // A list of valid numeric literals: for the standard "C" locale,
-      // this would usually be: "-+xX0123456789abcdef0123456789ABCDEF"
-      static const char        _S_literals[];
-
-      // NB: Code depends on the order of definitions of the names
-      // these are indices into _S_literals, above.
-      // This string is formatted for putting, not getting. (output, not input)
-      enum 
-      {  
-       _S_minus, 
-       _S_plus, 
-       _S_x, 
-       _S_X, 
-       _S_digits,
-       _S_digits_end = _S_digits + 16,
-       _S_udigits = _S_digits_end,  
-       _S_udigits_end = _S_udigits + 16,
-       _S_ee = _S_digits + 14, // For scientific notation, 'E'
-       _S_Ee = _S_udigits + 14 // For scientific notation, 'e'
-      };
-
-      // The sign used to separate decimal values: for standard US
-      // locales, this would usually be: "."
-      // Abstracted from numpunct::decimal_point().
-      char_type                _M_decimal_point;
-
-      // The sign used to separate groups of digits into smaller
-      // strings that the eye can parse with less difficulty: for
-      // standard US locales, this would usually be: ","
-      // Abstracted from numpunct::thousands_sep().
-      char_type                        _M_thousands_sep;
-
-      // However the US's "false" and "true" are translated.
-      // From numpunct::truename() and numpunct::falsename(), respectively.
-      string_type              _M_truename;
-      string_type              _M_falsename;
-
-      // If we are checking groupings. This should be equivalent to 
-      // numpunct::groupings().size() != 0
-      bool                     _M_use_grouping;
-
-      // If we are using numpunct's groupings, this is the current
-      // grouping string in effect (from numpunct::grouping()).
-      string                   _M_grouping;
-
-      _Format_cache();
-
-      ~_Format_cache() throw() { }
-
-      // Given a member of the ios hierarchy as an argument, extract
-      // out all the current formatting information into a
-      // _Format_cache object and return a pointer to it.
-      static _Format_cache<_CharT>* 
-      _S_get(ios_base& __ios);
+    private:
+      char_type                        _M_decimal_point;
+      char_type                        _M_thousands_sep;
+      string                           _M_grouping;
+      string_type                      _M_truename;
+      string_type                      _M_falsename;
 
-      void 
-      _M_populate(ios_base&);
+    public:
+      explicit 
+      numpunct(size_t __refs = 0) : locale::facet(__refs) 
+      { _M_initialize_numpunct(); }
+
+      explicit 
+      numpunct(__c_locale __cloc, size_t __refs = 0) : locale::facet(__refs) 
+      { _M_initialize_numpunct(__cloc); }
+
+      char_type    
+      decimal_point() const
+      { return this->do_decimal_point(); }
+
+      char_type    
+      thousands_sep() const
+      { return this->do_thousands_sep(); }
+
+      string       
+      grouping() const
+      { return this->do_grouping(); }
+
+      string_type  
+      truename() const
+      { return this->do_truename(); }
+
+      string_type  
+      falsename() const
+      { return this->do_falsename(); }
+
+    protected:
+      virtual 
+      ~numpunct() { }
+
+      virtual char_type    
+      do_decimal_point() const
+      { return _M_decimal_point; }
 
-      static void 
-      _S_callback(ios_base::event __event, ios_base& __ios, int __ix) throw();
+      virtual char_type    
+      do_thousands_sep() const
+      { return _M_thousands_sep; }
+
+      virtual string
+      do_grouping() const
+      { return _M_grouping; }
+
+      virtual string_type  
+      do_truename() const
+      { return _M_truename; }
+
+      virtual string_type  
+      do_falsename() const
+      { return _M_falsename; }
+
+      // For use at construction time only.
+      void 
+      _M_initialize_numpunct(__c_locale __cloc = NULL);
     };
 
   template<typename _CharT>
-    int _Format_cache<_CharT>::_S_pword_ix;
+    locale::id numpunct<_CharT>::id;
 
+  // NB: Cannot be made generic. 
   template<typename _CharT>
-    const char _Format_cache<_CharT>::
-    _S_literals[] = "-+xX0123456789abcdef0123456789ABCDEF";
+    void
+    numpunct<_CharT>::_M_initialize_numpunct(__c_locale)
+    { }
 
-   template<> _Format_cache<char>::_Format_cache();
+  template<> 
+    void
+    numpunct<char>::_M_initialize_numpunct(__c_locale __cloc);
 
 #ifdef _GLIBCPP_USE_WCHAR_T
-   template<> _Format_cache<wchar_t>::_Format_cache();
+  template<> 
+    void
+    numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc);
 #endif
 
-  // _Numeric_get is used by num_get, money_get, and time_get to help
-  // in parsing out numbers.
-  template<typename _CharT, typename _InIter>
-    class _Numeric_get
+  template<typename _CharT>
+    class numpunct_byname : public numpunct<_CharT>
     {
+      // Data Member.
+      __c_locale                       _M_c_locale_numpunct;
+
     public:
-      // Types:
-      typedef _CharT     char_type;
-      typedef _InIter    iter_type;
-
-      // Forward decls and Friends:
-      template<typename _Char, typename _InIterT>
-      friend class num_get;
-      template<typename _Char, typename _InIterT>
-      friend class time_get;
-      template<typename _Char, typename _InIterT>
-      friend class money_get;
-      template<typename _Char, typename _InIterT>
-      friend class num_put;
-      template<typename _Char, typename _InIterT>
-      friend class time_put;
-      template<typename _Char, typename _InIterT>
-      friend class money_put;
+      typedef _CharT                   char_type;
+      typedef basic_string<_CharT>     string_type;
 
-    private:
       explicit 
-      _Numeric_get() { }
+      numpunct_byname(const char* __s, size_t __refs = 0)
+      : numpunct<_CharT>(__refs)
+      {
+       _S_create_c_locale(_M_c_locale_numpunct, __s);
+       _M_initialize_numpunct(_M_c_locale_numpunct);   
+      }
 
+    protected:
       virtual 
-      ~_Numeric_get() { }
-
-      iter_type 
-      _M_get_digits(iter_type __in, iter_type __end) const;
+      ~numpunct_byname() 
+      { _S_destroy_c_locale(_M_c_locale_numpunct); }
     };
 
   template<typename _CharT, typename _InIter>
-    class num_get : public locale::facet
+    class num_get : public locale::facet, public __num_base
     {
     public:
       // Types:
       typedef _CharT                           char_type;
       typedef _InIter                          iter_type;
-      typedef char_traits<_CharT>      __traits_type;
 
       static locale::id                id;
 
@@ -580,118 +575,99 @@ namespace std
       iter_type 
       get(iter_type __in, iter_type __end, ios_base& __io,
          ios_base::iostate& __err, bool& __v) const
-      { return do_get(__in, __end, __io, __err, __v); }
-
-#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
-      //XXX.  What number?
-      iter_type 
-      get(iter_type __in, iter_type __end, ios_base& __io,
-         ios_base::iostate& __err, short& __v) const
-      { return do_get(__in, __end, __io, __err, __v); }
-
-      iter_type 
-      get(iter_type __in, iter_type __end, ios_base& __io,
-         ios_base::iostate& __err, int& __v)   const
-      { return do_get(__in, __end, __io, __err, __v); }
-#endif
+      { return this->do_get(__in, __end, __io, __err, __v); }
 
       iter_type
       get(iter_type __in, iter_type __end, ios_base& __io, 
          ios_base::iostate& __err, long& __v) const
-      { return do_get(__in, __end, __io, __err, __v); }
-
-#ifdef _GLIBCPP_USE_LONG_LONG
-      iter_type 
-      get(iter_type __in, iter_type __end, ios_base& __io,
-         ios_base::iostate& __err, long long& __v) const
-      { return do_get(__in, __end, __io, __err, __v); }
-#endif
+      { return this->do_get(__in, __end, __io, __err, __v); }
 
       iter_type 
       get(iter_type __in, iter_type __end, ios_base& __io,
          ios_base::iostate& __err, unsigned short& __v) const
-      { return do_get(__in, __end, __io, __err, __v); }
+      { return this->do_get(__in, __end, __io, __err, __v); }
 
       iter_type 
       get(iter_type __in, iter_type __end, ios_base& __io,
          ios_base::iostate& __err, unsigned int& __v)   const
-      { return do_get(__in, __end, __io, __err, __v); }
+      { return this->do_get(__in, __end, __io, __err, __v); }
 
       iter_type 
       get(iter_type __in, iter_type __end, ios_base& __io,
          ios_base::iostate& __err, unsigned long& __v)  const
-      { return do_get(__in, __end, __io, __err, __v); }
+      { return this->do_get(__in, __end, __io, __err, __v); }
 
 #ifdef _GLIBCPP_USE_LONG_LONG
       iter_type 
       get(iter_type __in, iter_type __end, ios_base& __io,
+         ios_base::iostate& __err, long long& __v) const
+      { return this->do_get(__in, __end, __io, __err, __v); }
+
+      iter_type 
+      get(iter_type __in, iter_type __end, ios_base& __io,
          ios_base::iostate& __err, unsigned long long& __v)  const
-      { return do_get(__in, __end, __io, __err, __v); }
+      { return this->do_get(__in, __end, __io, __err, __v); }
 #endif
 
       iter_type 
       get(iter_type __in, iter_type __end, ios_base& __io,
          ios_base::iostate& __err, float& __v) const
-      { return do_get(__in, __end, __io, __err, __v); }
+      { return this->do_get(__in, __end, __io, __err, __v); }
 
       iter_type 
       get(iter_type __in, iter_type __end, ios_base& __io,
          ios_base::iostate& __err, double& __v) const
-      { return do_get(__in, __end, __io, __err, __v); }
+      { return this->do_get(__in, __end, __io, __err, __v); }
 
       iter_type 
       get(iter_type __in, iter_type __end, ios_base& __io,
          ios_base::iostate& __err, long double& __v) const
-      { return do_get(__in, __end, __io, __err, __v); }
+      { return this->do_get(__in, __end, __io, __err, __v); }
 
       iter_type 
       get(iter_type __in, iter_type __end, ios_base& __io,
          ios_base::iostate& __err, void*& __v) const
-      { return do_get(__in, __end, __io, __err, __v); }      
+      { return this->do_get(__in, __end, __io, __err, __v); }      
 
     protected:
       virtual ~num_get() { }
 
-      // This consolidates the extraction, storage and
-      // error-processing parts of the do_get(...) overloaded member
-      // functions. 
-      // NB: This is specialized for char.
       void 
-      _M_extract(iter_type __beg, iter_type __end, ios_base& __io, 
-                ios_base::iostate& __err, char* __xtrc, 
-                int& __base, bool __fp = true) const;
+      _M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&, 
+                      char* __xtrc) const;
+
+      void 
+      _M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&, 
+                    char* __xtrc, int& __base) const;
 
       virtual iter_type 
       do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const;
 
-#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
-      //XXX.  What number?
       virtual iter_type 
-      do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, short&) const;
+      do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const;
+
       virtual iter_type 
-      do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, int&) const;
-#endif
+      do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 
+             unsigned short&) const;
+
+      virtual iter_type 
+      do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 
+            unsigned int&) const;
+
       virtual iter_type 
-      do_get (iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const;
+      do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 
+            unsigned long&) const;
+
 #ifdef _GLIBCPP_USE_LONG_LONG 
       virtual iter_type 
       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 
             long long&) const;
-#endif
+
       virtual iter_type 
       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 
-             unsigned short&) const;
-      virtual iter_type 
-      do_get(iter_type, iter_type, ios_base&,
-             ios_base::iostate& __err, unsigned int&) const;
-      virtual iter_type 
-      do_get(iter_type, iter_type, ios_base&,
-             ios_base::iostate& __err, unsigned long&) const;
-#ifdef _GLIBCPP_USE_LONG_LONG 
-      virtual iter_type 
-      do_get(iter_type, iter_type, ios_base&,
-            ios_base::iostate& __err, unsigned long long&) const;
+            unsigned long long&) const;
 #endif
+
       virtual iter_type 
       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 
             float&) const;
@@ -701,8 +677,8 @@ namespace std
             double&) const;
 
       virtual iter_type 
-      do_get(iter_type, iter_type, ios_base&, 
-            ios_base::iostate& __err, long double&) const;
+      do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 
+            long double&) const;
 
       virtual iter_type 
       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, 
@@ -712,38 +688,13 @@ namespace std
   template<typename _CharT, typename _InIter>
     locale::id num_get<_CharT, _InIter>::id;
 
-  // Declare specialized extraction member function.
-  template<>
-    void
-    num_get<char, istreambuf_iterator<char> >::    
-    _M_extract(istreambuf_iterator<char> __beg, 
-              istreambuf_iterator<char> __end, ios_base& __io, 
-              ios_base::iostate& __err, char* __xtrc, 
-              int& __base, bool __fp) const;
-
-  // _Numeric_put is used by num_put, money_put, and time_put
-  //   to help in formatting out numbers.
   template<typename _CharT, typename _OutIter>
-    class _Numeric_put
-    {
-    public:
-      typedef _CharT      char_type;
-      typedef _OutIter    iter_type;
-    protected:
-      explicit 
-      _Numeric_put() { }
-
-      virtual 
-      ~_Numeric_put() { }
-    };
-
-  template<typename _CharT, typename _OutIter>
-    class num_put : public locale::facet
+    class num_put : public locale::facet, public __num_base
     {
     public:
       // Types:
-      typedef _CharT       char_type;
-      typedef _OutIter     iter_type;
+      typedef _CharT           char_type;
+      typedef _OutIter         iter_type;
 
       static locale::id                id;
 
@@ -752,43 +703,65 @@ namespace std
 
       iter_type 
       put(iter_type __s, ios_base& __f, char_type __fill, bool __v) const
-      { return do_put(__s, __f, __fill, __v); }
+      { return this->do_put(__s, __f, __fill, __v); }
 
       iter_type 
       put(iter_type __s, ios_base& __f, char_type __fill, long __v) const
-      { return do_put(__s, __f, __fill, __v); }
+      { return this->do_put(__s, __f, __fill, __v); }
 
       iter_type 
       put(iter_type __s, ios_base& __f, char_type __fill, 
          unsigned long __v) const
-      { return do_put(__s, __f, __fill, __v); }
+      { return this->do_put(__s, __f, __fill, __v); }
 
 #ifdef _GLIBCPP_USE_LONG_LONG 
       iter_type 
       put(iter_type __s, ios_base& __f, char_type __fill, long long __v) const
-      { return do_put(__s, __f, __fill, __v); }
+      { return this->do_put(__s, __f, __fill, __v); }
 
       iter_type 
       put(iter_type __s, ios_base& __f, char_type __fill, 
          unsigned long long __v) const
-      { return do_put(__s, __f, __fill, __v); }
+      { return this->do_put(__s, __f, __fill, __v); }
 #endif
 
       iter_type 
       put(iter_type __s, ios_base& __f, char_type __fill, double __v) const
-      { return do_put(__s, __f, __fill, __v); }
+      { return this->do_put(__s, __f, __fill, __v); }
 
       iter_type 
       put(iter_type __s, ios_base& __f, char_type __fill, 
          long double __v) const
-      { return do_put(__s, __f, __fill, __v); }
+      { return this->do_put(__s, __f, __fill, __v); }
 
       iter_type 
       put(iter_type __s, ios_base& __f, char_type __fill, 
          const void* __v) const
-      { return do_put(__s, __f, __fill, __v); }
+      { return this->do_put(__s, __f, __fill, __v); }
 
     protected:
+      template<typename _ValueT>
+        iter_type
+        _M_convert_float(iter_type, ios_base& __io, char_type __fill, 
+                        char __mod, _ValueT __v) const;
+
+      template<typename _ValueT>
+        iter_type
+        _M_convert_int(iter_type, ios_base& __io, char_type __fill, 
+                      char __mod, char __modl, _ValueT __v) const;
+
+      iter_type
+      _M_widen_float(iter_type, ios_base& __io, char_type __fill, char* __cs, 
+                    int __len) const;
+
+      iter_type
+      _M_widen_int(iter_type, ios_base& __io, char_type __fill, char* __cs, 
+                  int __len) const;
+
+      iter_type
+      _M_insert(iter_type, ios_base& __io, char_type __fill, 
+               const char_type* __ws, int __len) const;
+
       virtual 
       ~num_put() { };
 
@@ -798,15 +771,13 @@ namespace std
       virtual iter_type 
       do_put(iter_type, ios_base&, char_type __fill, long __v) const;
 
-#ifdef _GLIBCPP_USE_LONG_LONG 
       virtual iter_type 
-      do_put(iter_type, ios_base&, char_type __fill, long long __v) const;
-#endif
+      do_put(iter_type, ios_base&, char_type __fill, unsigned long) const;
 
+#ifdef _GLIBCPP_USE_LONG_LONG 
       virtual iter_type 
-      do_put(iter_type, ios_base&, char_type __fill, unsigned long) const;
+      do_put(iter_type, ios_base&, char_type __fill, long long __v) const;
 
-#ifdef _GLIBCPP_USE_LONG_LONG
       virtual iter_type
       do_put(iter_type, ios_base&, char_type __fill, unsigned long long) const;
 #endif
@@ -826,126 +797,6 @@ namespace std
 
 
   template<typename _CharT>
-    class numpunct : public locale::facet
-    {
-    public:
-      // Types:
-      typedef _CharT                   char_type;
-      typedef basic_string<_CharT>     string_type;
-
-      static locale::id                id;
-
-    private:
-      char_type                        _M_decimal_point;
-      char_type                        _M_thousands_sep;
-      string                           _M_grouping;
-      string_type                      _M_truename;
-      string_type                      _M_falsename;
-
-    public:
-      explicit 
-      numpunct(size_t __refs = 0) : locale::facet(__refs) 
-      { _M_initialize_numpunct(); }
-
-      explicit 
-      numpunct(__c_locale __cloc, size_t __refs = 0) : locale::facet(__refs) 
-      { _M_initialize_numpunct(__cloc); }
-
-      char_type    
-      decimal_point() const
-      { return this->do_decimal_point(); }
-
-      char_type    
-      thousands_sep() const
-      { return this->do_thousands_sep(); }
-
-      string       
-      grouping() const
-      { return this->do_grouping(); }
-
-      string_type  
-      truename() const
-      { return this->do_truename(); }
-
-      string_type  
-      falsename() const
-      { return this->do_falsename(); }
-
-    protected:
-      virtual 
-      ~numpunct() { }
-
-      virtual char_type    
-      do_decimal_point() const
-      { return _M_decimal_point; }
-
-      virtual char_type    
-      do_thousands_sep() const
-      { return _M_thousands_sep; }
-
-      virtual string
-      do_grouping() const
-      { return _M_grouping; }
-
-      virtual string_type  
-      do_truename() const
-      { return _M_truename; }
-
-      virtual string_type  
-      do_falsename() const
-      { return _M_falsename; }
-
-      // For use at construction time only.
-      void 
-      _M_initialize_numpunct(__c_locale __cloc = NULL);
-    };
-
-  template<typename _CharT>
-    locale::id numpunct<_CharT>::id;
-
-  // NB: Cannot be made generic. 
-  template<typename _CharT>
-    void
-    numpunct<_CharT>::_M_initialize_numpunct(__c_locale)
-    { }
-
-  template<> 
-    void
-    numpunct<char>::_M_initialize_numpunct(__c_locale __cloc);
-
-#ifdef _GLIBCPP_USE_WCHAR_T
-  template<> 
-    void
-    numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc);
-#endif
-
-
-  template<typename _CharT>
-    class numpunct_byname : public numpunct<_CharT>
-    {
-      // Data Member.
-      __c_locale                       _M_c_locale_numpunct;
-
-    public:
-      typedef _CharT                   char_type;
-      typedef basic_string<_CharT>     string_type;
-
-      explicit 
-      numpunct_byname(const char* __s, size_t __refs = 0)
-      : numpunct<_CharT>(__refs)
-      {
-       _S_create_c_locale(_M_c_locale_numpunct, __s);
-       _M_initialize_numpunct(_M_c_locale_numpunct);   
-      }
-
-    protected:
-      virtual 
-      ~numpunct_byname() 
-      { _S_destroy_c_locale(_M_c_locale_numpunct); }
-    };
-
-
-  template<typename _CharT>
     class collate : public locale::facet
     {
     public:
@@ -1466,8 +1317,9 @@ namespace std
     };
 
 
-  struct money_base
+  class money_base
   {
+  public:
     enum part { none, space, symbol, sign, value };
     struct pattern { char field[4]; };
 
index b4c7f7c..3b9148e 100644 (file)
@@ -59,18 +59,17 @@ namespace std
                        const basic_string<_CharT, _Traits, _Alloc>& __s2) const
     {
       typedef std::collate<_CharT> __collate_type;
-      const __collate_type* __fcoll = &use_facet<__collate_type>(*this);
-      return (__fcoll->compare(__s1.data(), __s1.data() + __s1.length(),
-                               __s2.data(), __s2.data() + __s2.length()) < 0);
+      const __collate_type& __collate = use_facet<__collate_type>(*this);
+      return (__collate.compare(__s1.data(), __s1.data() + __s1.length(),
+                               __s2.data(), __s2.data() + __s2.length()) < 0);
     }
 
   template<typename _Facet>
     const _Facet&
     use_facet(const locale& __loc)
     {
-      typedef locale::_Impl::__vec_facet        __vec_facet;
       size_t __i = _Facet::id._M_index;
-      __vec_facet* __facet = __loc._M_impl->_M_facets;
+      locale::_Impl::__vec_facet* __facet = __loc._M_impl->_M_facets;
       const locale::facet* __fp = (*__facet)[__i]; 
       if (__fp == 0 || __i >= __facet->size())
         __throw_bad_cast();
@@ -81,52 +80,262 @@ namespace std
     bool
     has_facet(const locale& __loc) throw()
     {
-      typedef locale::_Impl::__vec_facet        __vec_facet;
       size_t __i = _Facet::id._M_index;
-      __vec_facet* __facet = __loc._M_impl->_M_facets;
+      locale::_Impl::__vec_facet* __facet = __loc._M_impl->_M_facets;
       return (__i < __facet->size() && (*__facet)[__i] != 0);
     }
 
 
-  // This member function takes an (w)istreambuf_iterator object and
-  // parses it into a generic char array suitable for parsing with
-  // strto[l,ll,f,d]. The thought was to encapsulate the conversion
-  // into this one function, and thus the num_get::do_get member
-  // functions can just adjust for the type of the overloaded
-  // argument and process the char array returned from _M_extract.
-  // Other things were also considered, including a fused
-  // multiply-add loop that would obviate the need for any call to
-  // strto... at all: however, it would b e a bit of a pain, because
-  // you'd have to be able to return either floating or integral
-  // types, etc etc. The current approach seems to be smack dab in
-  // the middle between an unoptimized approach using sscanf, and
-  // some kind of hyper-optimized approach alluded to above.
-
-  // XXX
-  // Need to do partial specialization to account for differences
-  // between character sets. For char, this is pretty
-  // straightforward, but for wchar_t, the conversion to a plain-jane
-  // char type is a bit more involved.
   template<typename _CharT, typename _InIter>
     void
     num_get<_CharT, _InIter>::
-    _M_extract(_InIter /*__beg*/, _InIter /*__end*/, ios_base& /*__io*/,
-               ios_base::iostate& /*__err*/, char* /*__xtrc*/,
-               int& /*__base*/, bool /*__fp*/) const
+    _M_extract_float(_InIter __beg, _InIter __end, ios_base& __io,
+                    ios_base::iostate& __err, char* __xtrc) const
     {
-      // XXX Not currently done: need to expand upon char version below.
+      const locale __loc = __io.getloc();
+      const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
+      const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
+      int __pos = 0;
+      char_type  __c = *__beg;
+
+      // Check first for sign.
+      const char_type __plus = __ctype.widen('+');
+      const char_type __minus = __ctype.widen('-');
+      if ((__c == __plus || __c == __minus) && __beg != __end)
+       {
+         __xtrc[__pos++] = __ctype.narrow(__c, char());
+         __c = *(++__beg);
+       }
+
+      // Next, strip leading zeros.
+      const char_type __zero = __ctype.widen(_S_atoms[_M_zero]);
+      bool __found_zero = false;
+      while (__c == __zero && __beg != __end)
+       {
+         __c = *(++__beg);
+         __found_zero = true;
+       }
+      if (__found_zero)
+       __xtrc[__pos++] = _S_atoms[_M_zero];
+
+      // Only need acceptable digits for floating point numbers.
+      const size_t __len = _M_E - _M_zero + 1;
+      char_type  __watoms[__len];
+      __ctype.widen(_S_atoms, _S_atoms + __len, __watoms);
+      bool __found_dec = false;
+      bool __found_sci = false;
+      const char_type __dec = __np.decimal_point();
+
+      string __found_grouping;
+      const string __grouping = __np.grouping();
+      bool __check_grouping = __grouping.size();
+      int __sep_pos = 0;
+      const char_type __sep = __np.thousands_sep();
+
+      while (__beg != __end)
+        {
+         // Only look in digits.
+         typedef char_traits<_CharT>   __traits_type;
+          const char_type* __p = __traits_type::find(__watoms, 10,  __c);
+
+          // NB: strchr returns true for __c == 0x0
+          if (__p && __c)
+           {
+             // Try first for acceptable digit; record it if found.
+             __xtrc[__pos++] = _S_atoms[__p - __watoms];
+             ++__sep_pos;
+             __c = *(++__beg);
+           }
+          else if (__c == __sep && __check_grouping && !__found_dec)
+           {
+              // NB: Thousands separator at the beginning of a string
+              // is a no-no, as is two consecutive thousands separators.
+              if (__sep_pos)
+                {
+                  __found_grouping += static_cast<char>(__sep_pos);
+                  __sep_pos = 0;
+                 __c = *(++__beg);
+                }
+              else
+               {
+                 __err |= ios_base::failbit;
+                 break;
+               }
+            }
+         else if (__c == __dec && !__found_dec)
+           {
+             __found_grouping += static_cast<char>(__sep_pos);
+             __xtrc[__pos++] = '.';
+             __c = *(++__beg);
+             __found_dec = true;
+           }
+         else if ((__c == __watoms[_M_e] || __c == __watoms[_M_E]) 
+                  && !__found_sci && __pos)
+           {
+             // Scientific notation.
+             __xtrc[__pos++] = __ctype.narrow(__c, char());
+             __c = *(++__beg);
+
+             // Remove optional plus or minus sign, if they exist.
+             if (__c == __plus || __c == __minus)
+               {
+                 __xtrc[__pos++] = __ctype.narrow(__c, char());
+                 __c = *(++__beg);
+               }
+             __found_sci = true;
+           }
+         else
+           // Not a valid input item.
+           break;
+        }
+
+      // Digit grouping is checked. If grouping and found_grouping don't
+      // match, then get very very upset, and set failbit.
+      if (__check_grouping && __found_grouping.size())
+        {
+          // Add the ending grouping if a decimal wasn't found.
+         if (!__found_dec)
+           __found_grouping += static_cast<char>(__sep_pos);
+
+          if (!__verify_grouping(__grouping, __found_grouping))
+            {
+              __err |= ios_base::failbit;
+              __xtrc[__pos] = '\0';
+              if (__beg == __end)
+                __err |= ios_base::eofbit;
+              return;
+            }
+        }
+
+      // Finish up
+      __xtrc[__pos] = char_type();
+      if (__beg == __end)
+        __err |= ios_base::eofbit;
     }
 
-  template<>
+  template<typename _CharT, typename _InIter>
     void
-    num_get<char, istreambuf_iterator<char> >::
-    _M_extract(istreambuf_iterator<char> __beg, 
-              istreambuf_iterator<char> __end, ios_base& __io, 
-              ios_base::iostate& __err, char* __xtrc, int& __base, 
-              bool __fp) const;
+    num_get<_CharT, _InIter>::
+    _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io,
+                  ios_base::iostate& __err, char* __xtrc, int& __base) const
+    {
+      // Stage 1: determine a conversion specifier.
+      ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
+      if (__basefield == ios_base::oct)
+        __base = 8;
+      else if (__basefield == ios_base::hex)
+        __base = 16;
+      else
+       __base = 10;
+
+      const locale __loc = __io.getloc();
+      const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
+      const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
+      int __pos = 0;
+      char_type  __c = *__beg;
+
+      // Check first for sign.
+      if ((__c == __ctype.widen('+') || __c == __ctype.widen('-'))
+         && __beg != __end)
+       {
+         __xtrc[__pos++] = __ctype.narrow(__c, char());
+         __c = *(++__beg);
+       }
+
+      // Next, strip leading zeros
+      const char_type __zero = __ctype.widen(_S_atoms[_M_zero]);
+      bool __found_zero = false;
+      while (__base == 10 && __c == __zero && __beg != __end)
+       {
+         __c = *(++__beg);
+         __found_zero = true;
+       }
+      if (__found_zero)
+       {
+         __xtrc[__pos++] = _S_atoms[_M_zero];
+         if (__basefield == 0)
+           {
+             // Depending on what is discovered, the base may change.
+             if (__c == __ctype.widen('x') || __c == __ctype.widen('X'))
+               __base = 16;
+             else
+               __base = 8;
+           }
+       }
+
+      // At this point, base is determined. If not hex, only allow
+      // base digits as valid input.
+      size_t __len;
+      if (__base == 16)
+       __len = _M_size;
+      else
+       __len = __base;
+
+      char_type  __watoms[_M_size];
+      __ctype.widen(_S_atoms, _S_atoms + __len, __watoms);
+      string __found_grouping;
+      const string __grouping = __np.grouping();
+      bool __check_grouping = __grouping.size() && __base == 10;
+      int __sep_pos = 0;
+      const char_type __sep = __np.thousands_sep();
+      while (__beg != __end)
+        {
+         typedef char_traits<_CharT>   __traits_type;
+          const char_type* __p = __traits_type::find(__watoms, __len,  __c);
+
+          // NB: strchr returns true for __c == 0x0
+          if (__p && __c)
+           {
+             // Try first for acceptable digit; record it if found.
+             __xtrc[__pos++] = _S_atoms[__p - __watoms];
+             ++__sep_pos;
+             __c = *(++__beg);
+           }
+          else if (__c == __sep && __check_grouping)
+           {
+              // NB: Thousands separator at the beginning of a string
+              // is a no-no, as is two consecutive thousands separators.
+              if (__sep_pos)
+                {
+                  __found_grouping += static_cast<char>(__sep_pos);
+                  __sep_pos = 0;
+                 __c = *(++__beg);
+                }
+              else
+               {
+                 __err |= ios_base::failbit;
+                 break;
+               }
+            }
+         else
+           // Not a valid input item.
+           break;
+        }
+
+      // Digit grouping is checked. If grouping and found_grouping don't
+      // match, then get very very upset, and set failbit.
+      if (__check_grouping && __found_grouping.size())
+        {
+          // Add the ending grouping
+          __found_grouping += static_cast<char>(__sep_pos);
+
+          if (!__verify_grouping(__grouping, __found_grouping))
+            {
+              __err |= ios_base::failbit;
+              __xtrc[__pos] = '\0';
+              if (__beg == __end)
+                __err |= ios_base::eofbit;
+              return;
+            }
+        }
+
+      // Finish up
+      __xtrc[__pos] = char_type();
+      if (__beg == __end)
+        __err |= ios_base::eofbit;
+    }
 
 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
-  // NB: This is an unresolved library defect #17
   //17.  Bad bool parsing
   template<typename _CharT, typename _InIter>
     _InIter
@@ -145,7 +354,7 @@ namespace std
           // integral types.
           char __xtrc[32] = {'\0'};
           int __base;
-          _M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
+          _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
 
           // Stage 2: convert and store results.
           char* __sanity;
@@ -162,29 +371,30 @@ namespace std
       // Parse bool values as alphanumeric
       else
         {
-          typedef _Format_cache<char_type> __fcache_type;
-          __fcache_type* __fmt = __fcache_type::_S_get(__io);
-          const char_type* __true = __fmt->_M_truename.c_str();
-          const char_type* __false = __fmt->_M_falsename.c_str();
-          const size_t __truelen =  __traits_type::length(__true) - 1;
-          const size_t __falselen =  __traits_type::length(__false) - 1;
-
-          for (size_t __pos = 0; __beg != __end; ++__pos)
+          locale __loc = __io.getloc();
+         const numpunct<char_type>& __np = use_facet<numpunct<char_type> >(__loc); 
+          const char_type* __true = __np.truename().c_str();
+          const char_type* __false = __np.falsename().c_str();
+
+          const size_t __truen =  __np.truename().size() - 1;
+          const size_t __falsen =  __np.falsename().size() - 1;
+
+          for (size_t __n = 0; __beg != __end; ++__n)
             {
               char_type __c = *__beg++;
-              bool __testf = __c == __false[__pos];
-              bool __testt = __c == __true[__pos];
+              bool __testf = __n <= __falsen ? __c == __false[__n] : false;
+              bool __testt = __n <= __truen ? __c == __true[__n] : false;
               if (!(__testf || __testt))
                 {
                   __err |= ios_base::failbit;
                   break;
                 }
-              else if (__testf && __pos == __falselen)
+              else if (__testf && __n == __falsen)
                 {
                   __v = 0;
                   break;
                 }
-              else if (__testt && __pos == __truelen)
+              else if (__testt && __n == __truen)
                 {
                   __v = 1;
                   break;
@@ -198,63 +408,6 @@ namespace std
     }
 #endif
 
-#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
-  //XXX.  Which number?  Presumably same as in locale_facets.h...
-  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, short& __v) const
-    {
-      // Stage 1: extract and determine the conversion specifier.
-      // Assuming leading zeros eliminated, thus the size of 32 for
-      // integral types.
-      char __xtrc[32]= {'\0'};
-      int __base;
-      _M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
-
-      // Stage 2: convert and store results.
-      char* __sanity;
-      errno = 0;
-      long __l = strtol(__xtrc, &__sanity, __base);
-      if (!(__err & ios_base::failbit)
-          && __sanity != __xtrc && *__sanity == '\0' && errno == 0
-          && __l >= SHRT_MIN && __l <= SHRT_MAX)
-        __v = static_cast<short>(__l);
-      else
-        __err |= ios_base::failbit;
-
-      return __beg;
-    }
-
-  template<typename _CharT, typename _InIter>
-    _InIter
-    num_get<_CharT, _InIter>::
-    do_get(iter_type __beg, iter_type __end, ios_base& __io,
-           ios_base::iostate& __err, int& __v) const
-    {
-      // Stage 1: extract and determine the conversion specifier.
-      // Assuming leading zeros eliminated, thus the size of 32 for
-      // integral types.
-      char __xtrc[32] = {'\0'};
-      int __base;
-      _M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
-
-      // Stage 2: convert and store results.
-      char* __sanity;
-      errno = 0;
-      long __l = strtol(__xtrc, &__sanity, __base);
-      if (!(__err & ios_base::failbit)
-          && __sanity != __xtrc && *__sanity == '\0' && errno == 0
-          && __l >= INT_MIN && __l <= INT_MAX)
-        __v = static_cast<int>(__l);
-      else
-        __err |= ios_base::failbit;
-
-      return __beg;
-    }
-#endif
-
   template<typename _CharT, typename _InIter>
     _InIter
     num_get<_CharT, _InIter>::
@@ -266,7 +419,7 @@ namespace std
       // integral types.
       char __xtrc[32]= {'\0'};
       int __base;
-      _M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
+      _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
 
       // Stage 2: convert and store results.
       char* __sanity;
@@ -281,46 +434,45 @@ namespace std
       return __beg;
     }
 
-#ifdef _GLIBCPP_USE_LONG_LONG
   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 long& __v) const
+           ios_base::iostate& __err, unsigned short& __v) const
     {
       // Stage 1: extract and determine the conversion specifier.
       // Assuming leading zeros eliminated, thus the size of 32 for
       // integral types.
       char __xtrc[32]= {'\0'};
       int __base;
-      _M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
+      _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
 
       // Stage 2: convert and store results.
       char* __sanity;
       errno = 0;
-      long long __ll = strtoll(__xtrc, &__sanity, __base);
+      unsigned long __ul = strtoul(__xtrc, &__sanity, __base);
       if (!(__err & ios_base::failbit)
-          && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
-        __v = __ll;
+          && __sanity != __xtrc && *__sanity == '\0' && errno == 0
+          && __ul <= USHRT_MAX)
+        __v = static_cast<unsigned short>(__ul);
       else
         __err |= ios_base::failbit;
 
       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, unsigned short& __v) const
+           ios_base::iostate& __err, unsigned int& __v) const
     {
       // Stage 1: extract and determine the conversion specifier.
       // Assuming leading zeros eliminated, thus the size of 32 for
       // integral types.
       char __xtrc[32]= {'\0'};
       int __base;
-      _M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
+      _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
 
       // Stage 2: convert and store results.
       char* __sanity;
@@ -328,8 +480,8 @@ namespace std
       unsigned long __ul = strtoul(__xtrc, &__sanity, __base);
       if (!(__err & ios_base::failbit)
           && __sanity != __xtrc && *__sanity == '\0' && errno == 0
-          && __ul <= USHRT_MAX)
-        __v = static_cast<unsigned short>(__ul);
+          && __ul <= UINT_MAX)
+        __v = static_cast<unsigned int>(__ul);
       else
         __err |= ios_base::failbit;
 
@@ -340,56 +492,55 @@ namespace std
     _InIter
     num_get<_CharT, _InIter>::
     do_get(iter_type __beg, iter_type __end, ios_base& __io,
-           ios_base::iostate& __err, unsigned int& __v) const
+           ios_base::iostate& __err, unsigned long& __v) const
     {
       // Stage 1: extract and determine the conversion specifier.
       // Assuming leading zeros eliminated, thus the size of 32 for
       // integral types.
-      char __xtrc[32]= {'\0'};
+      char __xtrc[32] = {'\0'};
       int __base;
-      _M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
+      _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
 
       // Stage 2: convert and store results.
       char* __sanity;
       errno = 0;
       unsigned long __ul = strtoul(__xtrc, &__sanity, __base);
       if (!(__err & ios_base::failbit)
-          && __sanity != __xtrc && *__sanity == '\0' && errno == 0
-          && __ul <= UINT_MAX)
-        __v = static_cast<unsigned int>(__ul);
+          && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
+        __v = __ul;
       else
         __err |= ios_base::failbit;
 
       return __beg;
     }
 
+#ifdef _GLIBCPP_USE_LONG_LONG
   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
+           ios_base::iostate& __err, long long& __v) const
     {
       // Stage 1: extract and determine the conversion specifier.
       // Assuming leading zeros eliminated, thus the size of 32 for
       // integral types.
-      char __xtrc[32] = {'\0'};
+      char __xtrc[32]= {'\0'};
       int __base;
-      _M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
+      _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
 
       // Stage 2: convert and store results.
       char* __sanity;
       errno = 0;
-      unsigned long __ul = strtoul(__xtrc, &__sanity, __base);
+      long long __ll = strtoll(__xtrc, &__sanity, __base);
       if (!(__err & ios_base::failbit)
           && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
-        __v = __ul;
+        __v = __ll;
       else
         __err |= ios_base::failbit;
 
       return __beg;
     }
 
-#ifdef _GLIBCPP_USE_LONG_LONG
   template<typename _CharT, typename _InIter>
     _InIter
     num_get<_CharT, _InIter>::
@@ -401,7 +552,7 @@ namespace std
       // integral types.
       char __xtrc[32]= {'\0'};
       int __base;
-      _M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
+      _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
 
       // Stage 2: convert and store results.
       char* __sanity;
@@ -420,15 +571,14 @@ namespace std
   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, float& __v) const
+    do_get(iter_type __beg, iter_type __end, ios_base& __io, 
+          ios_base::iostate& __err, float& __v) const
     {
       // Stage 1: extract and determine the conversion specifier.
       // Assuming leading zeros eliminated, thus the size of 256 for
       // floating-point types.
       char __xtrc[32]= {'\0'};
-      int __base;
-      _M_extract(__beg, __end, __io, __err, __xtrc, __base, true);
+      _M_extract_float(__beg, __end, __io, __err, __xtrc);
 
       // Stage 2: convert and store results.
       char* __sanity;
@@ -457,8 +607,7 @@ namespace std
       // Assuming leading zeros eliminated, thus the size of 256 for
       // floating-point types.
       char __xtrc[32]= {'\0'};
-      int __base;
-      _M_extract(__beg, __end, __io, __err, __xtrc, __base, true);
+      _M_extract_float(__beg, __end, __io, __err, __xtrc);
 
       // Stage 2: convert and store results.
       char* __sanity;
@@ -483,8 +632,7 @@ namespace std
       // Assuming leading zeros eliminated, thus the size of 256 for
       // floating-point types.
       char __xtrc[32]= {'\0'};
-      int __base;
-      _M_extract(__beg, __end, __io, __err, __xtrc, __base, true);
+      _M_extract_float(__beg, __end, __io, __err, __xtrc);
 
 #if defined(_GLIBCPP_USE_C99) && !defined(__hpux)
       // Stage 2: convert and store results.
@@ -539,7 +687,7 @@ namespace std
       // integral types.
       char __xtrc[32]= {'\0'};
       int __base;
-      _M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
+      _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
 
       // Stage 2: convert and store results.
       char* __sanity;
@@ -556,83 +704,138 @@ namespace std
       return __beg;
     }
 
-  // __pad is specialized for ostreambuf_iterator, random access iterator.
+
+  // The following code uses sprintf() to convert floating point
+  // values for insertion into a stream.  An optimization would be to
+  // replace sprintf() with code that works directly on a wide buffer
+  // and then use __pad to do the padding. It would be good
+  // to replace sprintf() anyway to avoid accidental buffer overruns
+  // and to gain back the efficiency that C++ provides by knowing up
+  // front the type of the values to insert. This implementation
+  // follows the C++ standard fairly directly as outlined in 22.2.2.2
+  // [lib.locale.num.put]
   template<typename _CharT, typename _OutIter>
-    inline _OutIter
-    __pad(_OutIter __s, _CharT __fill, int __padding);
+    template<typename _ValueT>
+      _OutIter
+      num_put<_CharT, _OutIter>::
+      _M_convert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
+                      _ValueT __v) const
+      {
+       const streamsize __max_prec = numeric_limits<_ValueT>::digits10;
+       streamsize __prec = __io.precision();
+       // Protect against sprintf() buffer overflows.
+       if (__prec > __max_prec)
+         __prec = __max_prec;
+
+       // Long enough for the max format spec.
+       char __fbuf[16];
+       char __cs[64];
+       int __len;
+       // [22.2.2.2.2] Stage 1, numeric conversion to character.
+       if (_S_format_float(__io, __fbuf, __mod, __prec))
+         __len = sprintf(__cs, __fbuf, __prec, __v);
+       else
+         __len = sprintf(__cs, __fbuf, __v);
+       return _M_widen_float(__s, __io, __fill, __cs, __len);
+      }
 
-  template<typename _CharT, typename _RaIter>
-    _RaIter
-    __pad(_RaIter __s, _CharT __fill, int __padding, 
-         random_access_iterator_tag)
-    {
-      fill_n(__s, __fill);
-      return __s + __padding;
-    }
+  template<typename _CharT, typename _OutIter>
+    template<typename _ValueT>
+      _OutIter
+      num_put<_CharT, _OutIter>::
+      _M_convert_int(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
+                    char __modl, _ValueT __v) const
+      {
+       // [22.2.2.2.2] Stage 1, numeric conversion to character.
+       // Leave room for "+/-," "0x," and commas. This size is
+       // arbitrary, but should work.
+       char __cs[64];
+       // Long enough for the max format spec.
+       char __fbuf[16];
+       _S_format_int(__io, __fbuf, __mod, __modl);
+       int __len = sprintf(__cs, __fbuf, __v);
+       return _M_widen_int(__s, __io, __fill, __cs, __len);
+      }
 
-  template<typename _CharT, typename _OutIter, typename _Tag>
+  template<typename _CharT, typename _OutIter>
     _OutIter
-    __pad(_OutIter __s, _CharT __fill, int __padding, _Tag)
+    num_put<_CharT, _OutIter>::
+    _M_widen_float(_OutIter __s, ios_base& __io, _CharT __fill, char* __cs, 
+                  int __len) const
     {
-      while (--__padding >= 0) { *__s = __fill; ++__s; }
-      return __s;
+      // [22.2.2.2.2] Stage 2, convert to char_type, using correct
+      // numpunct.decimal_point() values for '.' and adding grouping.
+      const locale __loc = __io.getloc();
+      const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
+      _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * 64));
+      __ctype.widen(__cs, __cs + __len, __ws);
+      
+      const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
+      // Replace decimal point.
+      const _CharT* __p;
+      if (__p = char_traits<_CharT>::find(__ws, __len, __ctype.widen('.')))
+       __ws[__p - __ws] = __np.decimal_point();
+      return _M_insert(__s, __io, __fill, __ws, __len);
     }
 
   template<typename _CharT, typename _OutIter>
-    inline _OutIter
-    __pad(_OutIter __s, _CharT __fill, int __padding)
+    _OutIter
+    num_put<_CharT, _OutIter>::
+    _M_widen_int(_OutIter __s, ios_base& __io, _CharT __fill, char* __cs, 
+                int __len) const
     {
-      return __pad(__s, __fill, __padding, 
-                  typename iterator_traits<_OutIter>::iterator_category());
+      // [22.2.2.2.2] Stage 2, convert to char_type, using correct
+      // numpunct.decimal_point() values for '.' and adding grouping.
+      const locale __loc = __io.getloc();
+      const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
+      _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * 64));
+      _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * 64));
+      __ctype.widen(__cs, __cs + __len, __ws);
+
+      // Add grouping, if necessary.
+      const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
+      string __grouping = __np.grouping();
+      ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
+      bool __dec = __basefield != ios_base::oct 
+                  && __basefield != ios_base::hex;
+      if (__grouping.size() && __dec)
+       {
+         _CharT* __p;
+         __p = __add_grouping(__ws2, __np.thousands_sep(), __grouping.c_str(),
+                              __grouping.c_str() + __grouping.size(),
+                              __ws, __ws + __len);
+         __len = __p - __ws2;
+         // Switch strings.
+         __ws = __ws2;
+       }
+      return _M_insert(__s, __io, __fill, __ws, __len);
     }
 
+  // For use by integer and floating-point types after they have been
+  // converted into a char_type string.
   template<typename _CharT, typename _OutIter>
     _OutIter
-    __pad_numeric(_OutIter __s, ios_base::fmtflags /*__flags*/,
-                 _CharT /*__fill*/, int /*__width*/, 
-                 _CharT const* /*__first*/, _CharT const* /*__middle*/, 
-                 _CharT const* /*__last*/)
-  {
-      // XXX Not currently done: non streambuf_iterator
-      return __s;
-    }
-
-  // Partial specialization for ostreambuf_iterator.
-  template<typename _CharT>   
-    ostreambuf_iterator<_CharT>
-    __pad_numeric(ostreambuf_iterator<_CharT> __s, ios_base::fmtflags __flags,
-                 _CharT __fill, int __width, _CharT const* __first,
-                 _CharT const* __middle, _CharT const* __last)
+    num_put<_CharT, _OutIter>::
+    _M_insert(_OutIter __s, ios_base& __io, _CharT __fill, const _CharT* __ws, 
+             int __len) const
     {
-      typedef ostreambuf_iterator<_CharT>      __out_iter;
-      int __padding = __width - (__last - __first);
-      if (__padding < 0)
-        __padding = 0;
-      ios_base::fmtflags __aflags = __flags & ios_base::adjustfield;
-      bool __testfield = __padding == 0 || __aflags == ios_base::left
-                         || __aflags == ios_base::internal;
-
-      // This was needlessly complicated.
-      if (__first != __middle)
-        {
-          if (!__testfield)
-            {
-              __pad(__s, __fill, __padding);
-              __padding = 0;
-            }
-          copy(__first, __middle, __s);
-        }
-      __out_iter __s2 = __s;
+      // [22.2.2.2.2] Stage 3.
+      _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * 64));
+      streamsize __w = __io.width();
+      if (__w > static_cast<streamsize>(__len))
+       {
+         __pad(__io, __fill, __ws2, __ws, __w, __len);
+         __len = static_cast<int>(__w);
+         // Switch strings.
+         __ws = __ws2;
+       }
+      __io.width(0);
 
-      if (__padding && __aflags != ios_base::left)
-        {
-          __pad(__s2, __fill, __padding);
-          __padding = 0;
-        }
-      __out_iter __s3 = copy(__middle, __last, __s2);
-      if (__padding)
-        __pad(__s3, __fill, __padding);
-      return __s3;
+      // [22.2.2.2.2] Stage 4.
+      // Write resulting, fully-formatted string to output iterator.
+      for (int __j = 0; __j < __len; ++__j, ++__s)
+       *__s = __ws[__j];
+      return __s;
     }
 
   template<typename _CharT, typename _OutIter>
@@ -640,278 +843,73 @@ namespace std
     num_put<_CharT, _OutIter>::
     do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const
     {
-      const _Format_cache<_CharT>* __fmt = _Format_cache<_CharT>::_S_get(__io);
       ios_base::fmtflags __flags = __io.flags();
-
       if ((__flags & ios_base::boolalpha) == 0)
         {
           unsigned long __uv = __v;
-          return __output_integer(__s, __io, __fill, false, __uv);
+          _M_convert_int(__s, __io, __fill, 'u', char_type(), __uv);
         }
       else
         {
-          const char_type* __first;
-          const char_type* __last;
+          locale __loc = __io.getloc();
+         const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); 
+          const char_type* __ws;
+          int __len;
           if (__v)
             {
-              __first = __fmt->_M_truename.data();
-              __last = __first + __fmt->_M_truename.size();
+              __ws = __np.truename().c_str();
+              __len = __np.truename().size();
             }
           else
             {
-              __first = __fmt->_M_falsename.data();
-              __last = __first + __fmt->_M_falsename.size();
+              __ws = __np.falsename().c_str();
+              __len = __np.falsename().size();
             }
-        streamsize __width = __io.width(0);
-        if (__last - __first >= __width)
-          return copy(__first, __last, __s);
-        else
-          {
-            int __padding = __width - (__last - __first);
-            ios_base::fmtflags __aflags = __flags & ios_base::adjustfield;
-            if (__aflags != ios_base::left)
-              {
-                __pad(__s, __fill, __padding);
-                return copy(__first, __last, __s);
-              }
-            else
-              {
-                copy(__first, __last, __s);
-                return __pad(__s, __fill, __padding);
-              }
-          }
-      }
-    }
-
-  template<typename _CharT, typename _OutIter, typename _ValueT>
-    _OutIter
-    __output_integer(_OutIter __s, ios_base& __io, _CharT __fill, bool __neg,
-                    _ValueT __v)
-    {
-      // Leave room for "+/-," "0x," and commas. This size is
-      // arbitrary, but should work.
-      const int __n = numeric_limits<_ValueT>::digits10 * 2 + 4;
-      _CharT* __digits = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
-      _CharT* __digits_end = __digits + __n;
-      ios_base::fmtflags __flags = __io.flags();
-      const _Format_cache<_CharT>* __fmt = _Format_cache<_CharT>::_S_get(__io);
-      char const* __table = __fmt->_S_literals + __fmt->_S_digits;
-
-      ios_base::fmtflags __basefield = (__flags & __io.basefield);
-      _CharT* __sign_end = __digits_end;
-      if (__basefield == ios_base::hex)
-        {
-          if (__flags & ios_base::uppercase)
-            __table += 16;  // use ABCDEF
-          do
-            *--__digits_end = __table[__v & 15];
-          while ((__v >>= 4) != 0);
-          __sign_end = __digits_end;
-          if (__flags & ios_base::showbase)
-            {
-              *--__digits_end = __fmt->_S_literals[__fmt->_S_x +
-                       ((__flags & ios_base::uppercase) ? 1 : 0)];
-              *--__digits_end = __table[0];
-            }
-        }
-      else if (__basefield == ios_base::oct)
-        {
-          do
-            *--__digits_end = __table[__v & 7];
-          while ((__v >>= 3) != 0);
-          if (__flags & ios_base::showbase
-              && static_cast<char>(*__digits_end) != __table[0])
-            *--__digits_end = __table[0];
-          __sign_end = __digits_end;
-        }
-      else
-        {
-          // NB: This is _lots_ faster than using ldiv.
-          do
-            *--__digits_end = __table[__v % 10];
-          while ((__v /= 10) != 0);
-          __sign_end = __digits_end;
-          // NB: ios_base:hex || ios_base::oct assumed to be unsigned.
-          if (__neg || (__flags & ios_base::showpos))
-            *--__digits_end = __fmt->_S_literals[__fmt->_S_plus - __neg];
-        }
-
-      // XXX should specialize!
-      if (!__fmt->_M_use_grouping && !__io.width())
-        return copy(__digits_end, __digits + __n, __s);
-
-      if (!__fmt->_M_use_grouping)
-        return __pad_numeric(__s, __flags, __fill, __io.width(0),
-                            __digits_end, __sign_end, __digits + __n);
-
-      _CharT* __p = __digits;
-      while (__digits_end < __sign_end)
-        *__p++ = *__digits_end++;
-      const char* __gbeg = __fmt->_M_grouping.data();
-      const char* __gend = __gbeg + __fmt->_M_grouping.size();
-      __digits_end = __group_digits(__p, __fmt->_M_thousands_sep, 
-                                   __gbeg, __gend,
-                                   __sign_end, __digits + __n);
-      return __pad_numeric(__s, __flags, __fill, __io.width(0),
-                          __digits, __p, __digits_end);
+         _M_insert(__s, __io, __fill, __ws, __len); 
+       }
+      return __s;
     }
 
   template<typename _CharT, typename _OutIter>
     _OutIter
     num_put<_CharT, _OutIter>::
     do_put(iter_type __s, ios_base& __io, char_type __fill, long __v) const
-    {
-      unsigned long __uv = __v;
-      bool __neg = false;
-      if (__v < 0)
-        {
-          __neg = true;
-          __uv = -__uv;
-        }
-      return __output_integer(__s, __io, __fill, __neg, __uv);
-    }
+    { return _M_convert_int(__s, __io, __fill, 'd', char_type(), __v); }
 
   template<typename _CharT, typename _OutIter>
     _OutIter
     num_put<_CharT, _OutIter>::
     do_put(iter_type __s, ios_base& __io, char_type __fill,
            unsigned long __v) const
-    { return __output_integer(__s, __io, __fill, false, __v); }
+    { return _M_convert_int(__s, __io, __fill, 'u', char_type(), __v); }
 
 #ifdef _GLIBCPP_USE_LONG_LONG
   template<typename _CharT, typename _OutIter>
     _OutIter
     num_put<_CharT, _OutIter>::
     do_put(iter_type __s, ios_base& __b, char_type __fill, long long __v) const
-    {
-      unsigned long long __uv = __v;
-      bool __neg = false;
-      if (__v < 0)
-        {
-          __neg = true;
-          __uv = -__uv;
-        }
-      return __output_integer(__s, __b, __fill, __neg, __uv);
-    }
+    { return _M_convert_int(__s, __b, __fill, 'd', 'l', __v); }
 
   template<typename _CharT, typename _OutIter>
     _OutIter
     num_put<_CharT, _OutIter>::
     do_put(iter_type __s, ios_base& __io, char_type __fill,
            unsigned long long __v) const
-    { return __output_integer(__s, __io, __fill, false, __v); }
+    { return _M_convert_int(__s, __io, __fill, 'u', 'l', __v); }
 #endif
 
-  // Generic helper function
-  template<typename _CharT, typename _Traits, typename _OutIter>
-    _OutIter
-    __output_float(_OutIter __s, ios_base& __io, _CharT __fill,
-                    const char* __sptr, size_t __slen)
-    {
-      // XXX Not currently done: non-streambuf_iterator
-      return __s;
-    }
-
-  // Partial specialization for ostreambuf_iterator.
-  template<typename _CharT, typename _Traits>
-    ostreambuf_iterator<_CharT, _Traits>
-    __output_float(ostreambuf_iterator<_CharT, _Traits> __s, ios_base& __io, 
-                  _CharT __fill, const char* __sptr, size_t __slen)
-    {
-      size_t __padding = __io.width() > streamsize(__slen) ?
-                         __io.width() -__slen : 0;
-      locale __loc = __io.getloc();
-      ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
-      ios_base::fmtflags __adjfield = __io.flags() & ios_base::adjustfield;
-      const char* const __eptr = __sptr + __slen;
-      // [22.2.2.2.2.19] Table 61
-      if (__adjfield == ios_base::internal)
-       {
-         // [22.2.2.2.2.14]; widen()
-         if (__sptr < __eptr && (*__sptr == '+' || *__sptr == '-'))
-           {
-             __s = __ctype.widen(*__sptr);
-             ++__s;
-             ++__sptr;
-           }
-         __s = __pad(__s, __fill, __padding);
-         __padding = 0;
-       }
-      else if (__adjfield != ios_base::left)
-        {
-          __s = __pad(__s, __fill, __padding);
-          __padding = 0;
-        }
-      // the "C" locale decimal character
-      char __decimal_point = *(localeconv()->decimal_point);
-      const _Format_cache<_CharT>* __fmt = _Format_cache<_CharT>::_S_get(__io);
-      for (; __sptr != __eptr; ++__s, ++__sptr)
-       {
-         // [22.2.2.2.2.17]; decimal point conversion
-         if (*__sptr == __decimal_point)
-           __s = __fmt->_M_decimal_point;
-         // [22.2.2.2.2.14]; widen()
-         else
-           __s = __ctype.widen(*__sptr);
-       }
-      // [22.2.2.2.2.19] Table 61
-      if (__padding)
-        __pad(__s, __fill, __padding);
-      __io.width(0);
-      return __s;
-    }
-
-  bool
-  __build_float_format(ios_base& __io, char* __fptr, char __modifier,
-                      streamsize __prec);
-
   template<typename _CharT, typename _OutIter>
     _OutIter
     num_put<_CharT, _OutIter>::
     do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const
-    {
-      const streamsize __max_prec = numeric_limits<double>::digits10 + 3;
-      streamsize __prec = __io.precision();
-      // Protect against sprintf() buffer overflows.
-      if (__prec > __max_prec)
-        __prec = __max_prec;
-      // The *2 provides for signs, exp, 'E', and pad.
-      char __sbuf[__max_prec * 2];
-      size_t __slen;
-      // Long enough for the max format spec.
-      char __fbuf[16];
-      if (__build_float_format(__io, __fbuf, 0, __prec))
-        __slen = sprintf(__sbuf, __fbuf, __prec, __v);
-      else
-        __slen = sprintf(__sbuf, __fbuf, __v);
-      // [22.2.2.2.2] Stages 2-4.
-      return __output_float(__s, __io, __fill, __sbuf, __slen);
-    }
+    { return _M_convert_float(__s, __io, __fill, char_type(), __v); }
 
   template<typename _CharT, typename _OutIter>
     _OutIter
     num_put<_CharT, _OutIter>::
-    do_put(iter_type __s, ios_base& __io, char_type __fill,
-           long double __v) const
-    {
-      const streamsize __max_prec = numeric_limits<long double>::digits10 + 3;
-      streamsize __prec = __io.precision();
-      // Protect against sprintf() buffer overflows.
-      if (__prec > __max_prec)
-        __prec = __max_prec;
-      // The *2 provides for signs, exp, 'E', and pad.
-      char __sbuf[__max_prec * 2];
-      size_t __slen;
-      // Long enough for the max format spec.
-      char __fbuf[16];
-      // 'L' as per [22.2.2.2.2] Table 59
-      if (__build_float_format(__io, __fbuf, 'L', __prec))
-        __slen = sprintf(__sbuf, __fbuf, __prec, __v);
-      else
-        __slen = sprintf(__sbuf, __fbuf, __v);
-      // [22.2.2.2.2] Stages 2-4
-      return __output_float(__s, __io, __fill, __sbuf, __slen);
-    }
+    do_put(iter_type __s, ios_base& __io, char_type __fill, 
+          long double __v) const
+    { return _M_convert_float(__s, __io, __fill, 'L', __v); }
 
   template<typename _CharT, typename _OutIter>
     _OutIter
@@ -919,21 +917,22 @@ namespace std
     do_put(iter_type __s, ios_base& __io, char_type __fill,
            const void* __v) const
     {
-      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));
-      try {
-        _OutIter __s2 = __output_integer(__s, __io, __fill, false,
-                                  reinterpret_cast<unsigned long>(__v));
-        __io.flags(__fmt);
-        return __s2;
-      }
-      catch (...) {
-        __io.flags(__fmt);
-        __throw_exception_again;
-      }
+      ios_base::fmtflags __flags = __io.flags();
+      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 
+       {
+         _M_convert_int(__s, __io, __fill, 'u', char_type(),
+                        reinterpret_cast<unsigned long>(__v));
+         __io.flags(__flags);
+       }
+      catch (...) 
+       {
+         __io.flags(__flags);
+         __throw_exception_again;
+       }
+      return __s;
     }
 
 
@@ -1253,13 +1252,13 @@ namespace std
                {
                  const char_type __sep = __intl ? __mpt.thousands_sep() 
                                                 : __mpf.thousands_sep();
-                 const char* __gbeg = __grouping.data();
+                 const char* __gbeg = __grouping.c_str();
                  const char* __gend = __gbeg + __grouping.size();
                  const int __n = numeric_limits<long double>::digits10 * 2;
-                 _CharT* __s = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
-                 _CharT* __s_end = __group_digits(__s, __sep, __gbeg, 
-                                                  __gend, __beg, __end);
-                 __value.insert(0, __s, __s_end - __s);
+                 _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
+                 _CharT* __ws_end = __add_grouping(__ws2, __sep, __gbeg, 
+                                                   __gend, __beg, __end);
+                 __value.insert(0, __ws2, __ws_end - __ws2);
                }
              else
                __value.insert(0, string_type(__beg, __end));
@@ -1921,6 +1920,100 @@ namespace std
       return static_cast<long>(__val);
     }
 
+  // Construct correctly padded string, as per 22.2.2.2.2
+  // Assumes 
+  // __newlen > __oldlen
+  // __news is allocated for __newlen size
+  // Used by both num_put and ostream inserters.
+  template<typename _CharT, typename _Traits>
+    void
+    __pad(ios_base& __io, _CharT __fill, _CharT* __news, const _CharT* __olds,
+         const streamsize __newlen, const streamsize __oldlen)
+    {
+      typedef _CharT   char_type;
+      typedef _Traits  traits_type;
+      typedef typename traits_type::int_type int_type;
+      
+      int_type __plen = static_cast<size_t>(__newlen - __oldlen); 
+      char_type* __pads = static_cast<char_type*>(__builtin_alloca(sizeof(char_type) * __plen));
+      traits_type::assign(__pads, __plen, __fill); 
+
+      char_type* __beg;
+      char_type* __end;
+      size_t __mod = 0;
+      size_t __beglen; //either __plen or __oldlen
+      ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield;
+
+      if (__adjust == ios_base::left)
+       {
+         // Padding last.
+         __beg = const_cast<char_type*>(__olds);
+         __beglen = __oldlen;
+         __end = __pads;
+       }
+      else if (__adjust == ios_base::internal)
+       {
+         // Pad after the sign, if there is one.
+         // Pad after 0[xX], if there is one.
+         // Who came up with these rules, anyway? Jeeze.
+          locale __loc = __io.getloc();
+         const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 
+         const char_type __minus = __ctype.widen('-');
+         const char_type __plus = __ctype.widen('+');
+         bool __testsign = __olds[0] == __minus || __olds[0] == __plus;
+         bool __testhex = __ctype.widen('0') == __olds[0] 
+                          && (__ctype.widen('x') == __olds[1] 
+                              || __ctype.widen('X') == __olds[1]);
+         if (__testhex)
+           {
+             __news[0] = __olds[0]; 
+             __news[1] = __olds[1];
+             __mod += 2;
+             __news += 2;
+             __beg = const_cast<char_type*>(__olds + __mod);
+             __beglen = __oldlen - __mod;
+             __end = __pads;
+           }
+         else if (__testsign)
+           {
+             __news[0] = __olds[0] == __plus ? __plus : __minus;
+             ++__mod;
+             ++__news;
+             __beg = __pads;
+             __beglen = __plen;
+             __end = const_cast<char_type*>(__olds + __mod);
+           }
+         else
+           {
+             // Padding first.
+             __beg = __pads;
+             __beglen = __plen;
+             __end = const_cast<char_type*>(__olds);
+           }
+       }
+      else
+       {
+         // Padding first.
+         __beg = __pads;
+         __beglen = __plen;
+         __end = const_cast<char_type*>(__olds);
+       }
+      traits_type::copy(__news, __beg, __beglen);
+      traits_type::copy(__news + __beglen, __end, __newlen - __beglen - __mod);
+    }
+
+  // NB: Can't have default argument on non-member template, and
+  // num_put doesn't have a _Traits template parameter, so this
+  // forwarding template adds in the default template argument.
+  template<typename _CharT>
+    void
+    __pad(ios_base& __io, _CharT __fill, _CharT* __news, const _CharT* __olds,
+         const streamsize __newlen, const streamsize __oldlen)
+    { 
+      return __pad<_CharT, char_traits<_CharT> >(__io, __fill, __news, 
+                                                __olds, __newlen, __oldlen); 
+    }
+
   // Used by both numeric and monetary facets.
   // Check to make sure that the __grouping_tmp string constructed in
   // money_get or num_get matches the canonical grouping for a given
@@ -1960,102 +2053,23 @@ namespace std
   // only with __gbeg != __gend.
   template<typename _CharT>
     _CharT*
-    __group_digits(_CharT* __s, _CharT __sep,  
+    __add_grouping(_CharT* __s, _CharT __sep,  
                   const char* __gbeg, const char* __gend, 
                   const _CharT* __first, const _CharT* __last)
     {
       if (__last - __first > *__gbeg)
         {
-          __s = __group_digits(__s,  __sep,
+          __s = __add_grouping(__s,  __sep, 
                               (__gbeg + 1 == __gend ? __gbeg : __gbeg + 1),
                               __gend, __first, __last - *__gbeg);
           __first = __last - *__gbeg;
           *__s++ = __sep;
         }
       do
-        {
-          *__s++ = *__first++;
-        }
+       *__s++ = *__first++;
       while (__first != __last);
       return __s;
     }
-
-  // XXX This stuff needs to be re-examined, heavily modified, or ditched.
-  template<typename _CharT>
-    _Format_cache<_CharT>::_Format_cache()
-    : _M_valid(true), _M_use_grouping(false)
-    { }
-
-  template<>
-    _Format_cache<char>::_Format_cache();
-
-  template<>
-    _Format_cache<wchar_t>::_Format_cache();
-
-  template<typename _CharT>
-    void
-    _Format_cache<_CharT>::_M_populate(ios_base& __io)
-    {
-      locale __loc = __io.getloc();
-      numpunct<_CharT> const& __np = use_facet<numpunct<_CharT> >(__loc);
-      _M_truename = __np.truename();
-      _M_falsename = __np.falsename();
-      _M_thousands_sep = __np.thousands_sep();
-      _M_decimal_point = __np.decimal_point();
-      _M_grouping = __np.grouping();
-      _M_use_grouping = _M_grouping.size() != 0 && _M_grouping.data()[0] != 0;
-      _M_valid = true;
-    }
-
-  // This function is always called via a pointer installed in
-  // an ios_base by ios_base::register_callback.
-  template<typename _CharT>
-    void
-    _Format_cache<_CharT>::
-    _S_callback(ios_base::event __ev, ios_base& __ios, int __ix) throw()
-    {
-      void*& __p = __ios.pword(__ix);
-      switch (__ev)
-        {
-        case ios_base::erase_event:
-          delete static_cast<_Format_cache<_CharT>*>(__p);
-         __p = 0;
-          break;
-        case ios_base::copyfmt_event:
-          // If just stored zero, the callback would get registered again.
-          try 
-           { __p = new _Format_cache<_CharT>; }
-          catch(...) 
-           { }
-          break;
-        case ios_base::imbue_event:
-          static_cast<_Format_cache<_CharT>*>(__p)->_M_valid = false;
-          break;
-        }
-    }
-
-  template<typename _CharT>
-    _Format_cache<_CharT>*
-    _Format_cache<_CharT>::_S_get(ios_base& __ios)
-    {
-      if (!_S_pword_ix)
-        _S_pword_ix = ios_base::xalloc();  // XXX MT
-      void*& __p = __ios.pword(_S_pword_ix);
-
-      // XXX What if pword fails? must check failbit, throw.
-      if (__p == 0)  // XXX MT?  maybe sentry takes care of it
-        {
-          auto_ptr<_Format_cache<_CharT> > __ap(new _Format_cache<_CharT>);
-          __ios.register_callback(&_Format_cache<_CharT>::_S_callback,
-                                  _S_pword_ix);
-          __p = __ap.release();
-        }
-      _Format_cache<_CharT>* __ncp = static_cast<_Format_cache<_CharT>*>(__p);
-      if (!__ncp->_M_valid)
-        __ncp->_M_populate(__ios);
-
-      return __ncp;
-    }
 } // namespace std
 
 #endif
index ff9283d..8ecd019 100644 (file)
@@ -465,93 +465,6 @@ namespace std
     }
 
   // 27.6.2.5.4 Character inserters
-
-  // Construct correctly padded string, as per 22.2.2.2.2
-  // Similar in theory to __pad_numeric, from num_put, but it doesn't
-  // use _S_fill: perhaps it should.
-  // Assumes 
-  // __newlen > __oldlen
-  // __news is allocated for __newlen size
-  template<typename _CharT, typename _Traits>
-    void
-    __pad_char(basic_ios<_CharT, _Traits>& __ios, 
-              _CharT* __news, const _CharT* __olds,
-              const streamsize __newlen, const streamsize __oldlen)
-    {
-      typedef _CharT   char_type;
-      typedef _Traits  traits_type;
-      typedef typename traits_type::int_type int_type;
-      
-      int_type __plen = static_cast<size_t>(__newlen - __oldlen); 
-      char_type* __pads = static_cast<char_type*>(__builtin_alloca(sizeof(char_type) * __plen));
-      traits_type::assign(__pads, __plen, __ios.fill()); 
-
-      char_type* __beg;
-      char_type* __end;
-      size_t __mod = 0;
-      size_t __beglen; //either __plen or __oldlen
-      ios_base::fmtflags __adjust = __ios.flags() & ios_base::adjustfield;
-
-      if (__adjust == ios_base::left)
-       {
-         // Padding last.
-         __beg = const_cast<char_type*>(__olds);
-         __beglen = __oldlen;
-         __end = __pads;
-       }
-      else if (__adjust == ios_base::internal)
-       {
-         // Pad after the sign, if there is one.
-         // Pad after 0[xX], if there is one.
-         // Who came up with these rules, anyway? Jeeze.
-         typedef _Format_cache<_CharT> __cache_type;
-         __cache_type const* __fmt = __cache_type::_S_get(__ios);
-         const char_type* __minus = traits_type::find(__olds, __oldlen, 
-                                                      __fmt->_S_minus);
-         const char_type* __plus = traits_type::find(__olds, __oldlen, 
-                                                     __fmt->_S_plus);
-         bool __testsign = __minus || __plus;
-         bool __testhex = __olds[0] == '0' 
-                          && (__olds[1] == 'x' || __olds[1] == 'X');
-
-         if (__testhex)
-           {
-             __news[0] = __olds[0]; 
-             __news[1] = __olds[1];
-             __mod += 2;
-             __beg = const_cast<char_type*>(__olds + __mod);
-             __beglen = __oldlen - __mod;
-             __end = __pads;
-           }
-         else if (__testsign)
-           {
-             __mod += __plen;
-             const char_type* __sign = __minus ? __minus + 1: __plus + 1;
-             __beg = const_cast<char_type*>(__olds);
-             __beglen = __sign - __olds;
-             __end = const_cast<char_type*>(__sign + __plen);
-             traits_type::copy(__news + __beglen, __pads, __plen);
-           }
-         else
-           {
-             // Padding first.
-             __beg = __pads;
-             __beglen = __plen;
-             __end = const_cast<char_type*>(__olds);
-           }
-       }
-      else
-       {
-         // Padding first.
-         __beg = __pads;
-         __beglen = __plen;
-         __end = const_cast<char_type*>(__olds);
-       }
-
-      traits_type::copy(__news, __beg, __beglen);
-      traits_type::copy(__news + __beglen, __end, __newlen - __beglen - __mod);
-    }
-
   template<typename _CharT, typename _Traits>
     basic_ostream<_CharT, _Traits>&
     operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c)
@@ -568,7 +481,7 @@ namespace std
              streamsize __len = 1;
              if (__w > __len)
                {
-                 __pad_char(__out, __pads, &__c, __w, __len);
+                 __pad(__out, __out.fill(), __pads, &__c, __w, __len);
                  __len = __w;
                }
              __out.write(__pads, __len);
@@ -603,7 +516,7 @@ namespace std
              streamsize __len = 1;
              if (__w > __len)
                {
-                 __pad_char(__out, __pads, &__c, __w, __len);
+                 __pad(__out, __out.fill(), __pads, &__c, __w, __len);
                  __len = __w;
                }
              __out.write(__pads, __len);
@@ -636,7 +549,7 @@ namespace std
              streamsize __len = static_cast<streamsize>(_Traits::length(__s));
              if (__w > __len)
                {
-                 __pad_char(__out, __pads, __s, __w, __len);
+                 __pad(__out, __out.fill(), __pads, __s, __w, __len);
                  __s = __pads;
                  __len = __w;
                }
@@ -682,7 +595,7 @@ namespace std
              
              if (__w > __len)
                {
-                 __pad_char(__out, __pads, __ws, __w, __len);
+                 __pad(__out, __out.fill(), __pads, __ws, __w, __len);
                  __str = __pads;
                  __len = __w;
                }
@@ -717,7 +630,7 @@ namespace std
              streamsize __len = static_cast<streamsize>(_Traits::length(__s));
              if (__w > __len)
                {
-                 __pad_char(__out, __pads, __s, __w, __len);
+                 __pad(__out, __out.fill(), __pads, __s, __w, __len);
                  __s = __pads;
                  __len = __w;
                }
@@ -755,7 +668,7 @@ namespace std
 #endif
          if (__w > __len)
            {
-             __pad_char(__out, __pads, __s, __w, __len);
+             __pad(__out, __out.fill(), __pads, __s, __w, __len);
              __s = __pads;
              __len = __w;
            }
index 3f690d7..4afbbc0 100644 (file)
@@ -159,21 +159,21 @@ namespace std
 
       inline __istream_type& 
       get(char_type* __s, streamsize __n)
-      { return get(__s, __n, this->widen('\n')); }
+      { return this->get(__s, __n, this->widen('\n')); }
 
       __istream_type&
       get(__streambuf_type& __sb, char_type __delim);
 
       inline __istream_type&
       get(__streambuf_type& __sb)
-      { return get(__sb, this->widen('\n')); }
+      { return this->get(__sb, this->widen('\n')); }
 
       __istream_type& 
       getline(char_type* __s, streamsize __n, char_type __delim);
 
       inline __istream_type& 
       getline(char_type* __s, streamsize __n)
-      { return getline(__s, __n, this->widen('\n')); }
+      { return this->getline(__s, __n, this->widen('\n')); }
 
       __istream_type& 
       ignore(streamsize __n = 1, int_type __delim = traits_type::eof());
@@ -297,4 +297,3 @@ namespace std
 #endif
 
 #endif /* _CPP_ISTREAM */
-
index 2f8b4b4..3061fcc 100644 (file)
@@ -171,8 +171,7 @@ namespace std
       { 
        int_type __eof = traits_type::eof();
        bool __thiseof = !_M_sbuf || _M_sbuf->sgetc() == __eof;
-       bool __beof = !__b._M_sbuf 
-                     || __b._M_sbuf->sgetc() == __eof;
+       bool __beof = !__b._M_sbuf || __b._M_sbuf->sgetc() == __eof;
        return (__thiseof && __beof || (!__thiseof && !__beof));
       }
 
@@ -184,8 +183,7 @@ namespace std
       {
        int_type __eof = traits_type::eof();
        bool __thiseof = !_M_sbuf || _M_sbuf->sgetc() == __eof;
-       bool __beof = !__b._M_sbuf 
-                     || __b._M_sbuf->sgetc() == __eof;
+       bool __beof = !__b._M_sbuf || __b._M_sbuf->sgetc() == __eof;
        return (__thiseof && __beof || (!__thiseof && !__beof));
       }
 #endif
index faa11fb..90379fb 100644 (file)
@@ -284,12 +284,6 @@ namespace std
   {
     locale __old = _M_ios_locale;
     _M_ios_locale = __loc;
-    // Make sure there's a callback for the format caches so they will be
-    // marked dirty.
-    _Format_cache<char>::_S_get(*this);
-#ifdef _GLIBCPP_USE_WCHAR_T
-    _Format_cache<wchar_t>::_S_get(*this);
-#endif
     _M_call_callbacks(imbue_event);
     return __old;
   }
index ac07215..5107a29 100644 (file)
@@ -56,7 +56,6 @@ namespace std
   template class moneypunct_byname<char, true>;
   template class money_get<char, ibuf_iterator>;
   template class money_put<char, obuf_iterator>;
-  template class _Format_cache<char>;
 
 #ifdef _GLIBCPP_USE_WCHAR_T
   template class moneypunct<wchar_t, false>;
@@ -65,19 +64,91 @@ namespace std
   template class moneypunct_byname<wchar_t, true>;
   template class money_get<wchar_t, wibuf_iterator>;
   template class money_put<wchar_t, wobuf_iterator>;
-  template class _Format_cache<wchar_t>;
 #endif
 
   // numpunct, numpunct_byname, num_get, and num_put
   template class numpunct<char>;
   template class numpunct_byname<char>;
   template class num_get<char, ibuf_iterator>;
-  template class num_put<char, obuf_iterator>;
+  template class num_put<char, obuf_iterator>; 
+  template
+    obuf_iterator
+    num_put<char, obuf_iterator>::
+    _M_convert_int(obuf_iterator, ios_base&, char, char, char, long) const;
+
+  template
+    obuf_iterator
+    num_put<char, obuf_iterator>::
+    _M_convert_int(obuf_iterator, ios_base&, char, char, char, 
+                  unsigned long) const;
+
+#ifdef _GLIBCPP_USE_LONG_LONG
+  template
+    obuf_iterator
+    num_put<char, obuf_iterator>::
+    _M_convert_int(obuf_iterator, ios_base&, char, char, char, 
+                  long long) const;
+
+  template
+    obuf_iterator
+    num_put<char, obuf_iterator>::
+    _M_convert_int(obuf_iterator, ios_base&, char, char, char,
+                  unsigned long long) const;
+#endif
+
+  template
+    obuf_iterator
+    num_put<char, obuf_iterator>::
+    _M_convert_float(obuf_iterator, ios_base&, char, char, double) const;
+
+  template
+    obuf_iterator
+    num_put<char, obuf_iterator>::
+    _M_convert_float(obuf_iterator, ios_base&, char, char, 
+                   long double) const;
+
 #ifdef _GLIBCPP_USE_WCHAR_T
   template class numpunct<wchar_t>;
   template class numpunct_byname<wchar_t>;
   template class num_get<wchar_t, wibuf_iterator>;
   template class num_put<wchar_t, wobuf_iterator>;
+
+  template
+    wobuf_iterator
+    num_put<wchar_t, wobuf_iterator>::
+    _M_convert_int(wobuf_iterator, ios_base&, wchar_t, char, char, long) const;
+
+  template
+    wobuf_iterator
+    num_put<wchar_t, wobuf_iterator>::
+    _M_convert_int(wobuf_iterator, ios_base&, wchar_t, char, char,
+                  unsigned long) const;
+
+#ifdef _GLIBCPP_USE_LONG_LONG
+  template
+    wobuf_iterator
+    num_put<wchar_t, wobuf_iterator>::
+    _M_convert_int(wobuf_iterator, ios_base&, wchar_t, char, char,
+                  long long) const;
+
+  template
+    wobuf_iterator
+    num_put<wchar_t, wobuf_iterator>::
+    _M_convert_int(wobuf_iterator, ios_base&, wchar_t, char, char,
+                  unsigned long long) const;
+#endif
+
+  template
+    wobuf_iterator
+    num_put<wchar_t, wobuf_iterator>::
+    _M_convert_float(wobuf_iterator, ios_base&, wchar_t, char, 
+                    double) const;
+
+  template
+    wobuf_iterator
+    num_put<wchar_t, wobuf_iterator>::
+    _M_convert_float(wobuf_iterator, ios_base&, wchar_t, char, 
+                    long double) const;
 #endif
 
   // time_get and time_put
@@ -246,8 +317,8 @@ namespace std
   typedef ostreambuf_iterator<char, char_traits<char> > ostreambuf_iter;
 
 #ifdef _GLIBCPP_USE_WCHAR_T
-  typedef istreambuf_iterator<wchar_t,char_traits<wchar_t> > wistreambuf_iter;
-  typedef ostreambuf_iterator<wchar_t,char_traits<wchar_t> > wostreambuf_iter;
+  typedef istreambuf_iterator<wchar_t, char_traits<wchar_t> > wistreambuf_iter;
+  typedef ostreambuf_iterator<wchar_t, char_traits<wchar_t> > wostreambuf_iter;
 #endif
 
   template 
@@ -255,36 +326,23 @@ namespace std
     locale::operator()(const string&, const string&) const;
 
   template
-    ostreambuf_iter
-    __pad<char, ostreambuf_iter, output_iterator_tag>
-    (ostreambuf_iter, char, int, output_iterator_tag);
-
-  template 
-    ostreambuf_iter
-    __pad_numeric<char, ostreambuf_iter>
-    (ostreambuf_iter, ios_base::fmtflags, char, int, char const*, char const*, 
-     char const*);
-
-  template
     char*
-    __group_digits<char>(char*, char, char const*, char const*, 
+    __add_grouping<char>(char*, char, char const*, char const*, 
                         char const*, char const*);
 
   template
     bool
     __verify_grouping<char>(const basic_string<char>&, basic_string<char>&);
 
-  template 
-    ostreambuf_iter
-    __output_integer<char, ostreambuf_iter, unsigned long>
-    (ostreambuf_iter, ios_base &, char, bool, unsigned long);
+  template
+    void 
+    __pad<char>(ios_base&, char, char*, const char *, streamsize, 
+               streamsize);
 
-#ifdef _GLIBCPP_USE_LONG_LONG
   template
-    ostreambuf_iter
-    __output_integer<char, ostreambuf_iter, unsigned long long>
-    (ostreambuf_iter, ios_base &, char, bool, unsigned long long);
-#endif
+    void 
+    __pad<char, char_traits<char> >(ios_base&, char, char*, 
+                                   const char *, streamsize, streamsize);
 
 #ifdef _GLIBCPP_USE_WCHAR_T
   template 
@@ -294,36 +352,24 @@ namespace std
   typedef ostreambuf_iterator<wchar_t> wostreambuf_iter;
 
   template
-    wostreambuf_iter
-    __pad<wchar_t, wostreambuf_iter, output_iterator_tag>
-    (wostreambuf_iter, wchar_t, int, output_iterator_tag);
-
-  template 
-    wostreambuf_iter
-    __pad_numeric<wchar_t, wostreambuf_iter>
-    (wostreambuf_iter, ios_base::fmtflags, wchar_t __fill, int, wchar_t const*,
-     wchar_t const*, wchar_t const*);
-
-  template
     wchar_t*
-    __group_digits<wchar_t>(wchar_t*, wchar_t, char const*, char const*, 
+    __add_grouping<wchar_t>(wchar_t*, wchar_t, char const*, char const*, 
                            wchar_t const*, wchar_t const*);
   template
     bool
     __verify_grouping<wchar_t>(const basic_string<wchar_t>&, 
                               basic_string<wchar_t>&);
 
-  template 
-    wostreambuf_iter
-    __output_integer<wchar_t, wostreambuf_iter, unsigned long>
-    (wostreambuf_iter, ios_base &, wchar_t, bool, unsigned long);
+  template
+    void 
+    __pad<wchar_t>(ios_base&, wchar_t, wchar_t*, const wchar_t*, 
+                  streamsize, streamsize);
 
-#ifdef _GLIBCPP_USE_LONG_LONG
   template
-    wostreambuf_iter
-    __output_integer<wchar_t, wostreambuf_iter, unsigned long long>
-    (wostreambuf_iter, ios_base &, wchar_t, bool, unsigned long long);
-#endif
+    void 
+    __pad<wchar_t, char_traits<wchar_t> >(ios_base&, wchar_t, wchar_t*, 
+                                         const wchar_t*, 
+                                         streamsize, streamsize);
 #endif // _GLIBCPP_USE_WCHAR_T
 
   template 
@@ -342,4 +388,3 @@ namespace std
          __normal_iterator<locale::facet**, vector<locale::facet*> >,
          locale::facet* const&);
 } // namespace std
-
index 02297d1..c3572c4 100644 (file)
@@ -74,6 +74,8 @@ namespace std
   // Definitions for static const data members of locale::id
   size_t locale::id::_S_highwater;  // init'd to 0 by linker
 
+  const char __num_base::_S_atoms[] = "0123456789eEabcdfxABCDFX";
+
   // Definitions for static const data members of locale::_Impl
   const locale::id* const
   locale::_Impl::_S_id_ctype[] =
@@ -353,7 +355,7 @@ namespace std
   void  
   locale::facet::
   _M_add_reference() throw()
-  { ++_M_references; }                     // XXX MT
+  { ++_M_references; }  // XXX MT
 
   void  
   locale::facet::
@@ -458,22 +460,6 @@ namespace std
   money_base::_S_default_pattern =  {{symbol, sign, none, value}};
 
   template<>
-    _Format_cache<char>::_Format_cache()
-    : _M_valid(true),
-    _M_decimal_point('.'), _M_thousands_sep(','),
-    _M_truename("true"), _M_falsename("false"), _M_use_grouping(false)
-    { }
-
-#ifdef _GLIBCPP_USE_WCHAR_T
-  template<>
-    _Format_cache<wchar_t>::_Format_cache()
-    : _M_valid(true),
-    _M_decimal_point(L'.'), _M_thousands_sep(L','),
-    _M_truename(L"true"), _M_falsename(L"false"), _M_use_grouping(false)
-    { }
-#endif
-
-  template<>
     const ctype<char>&
     use_facet<ctype<char> >(const locale& __loc)
     {
@@ -493,310 +479,9 @@ namespace std
     }
 #endif
 
-  template<>
-    void
-    num_get<char, istreambuf_iterator<char> >::
-    _M_extract(istreambuf_iterator<char> __beg, 
-              istreambuf_iterator<char> __end, ios_base& __io, 
-              ios_base::iostate& __err, char* __xtrc, int& __base, 
-              bool __fp) const
-    {
-      typedef _Format_cache<char> __cache_type;        
-
-      // Prepare for possible failure
-      __xtrc[0] = '\0';
-
-      // Stage 1: determine a conversion specifier.
-      ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
-      if (__basefield == ios_base::dec)
-        __base = 10;
-      else if (__basefield == ios_base::oct)
-        __base = 8;
-      else if (__basefield == ios_base::hex)
-        __base = 16;
-      else
-        __base = 0;
-      // As far as I can tell, bases other than 10 are not available for
-      // floating point types
-      if (__fp)
-        __base = 10;
-
-      // Stage 2: extract characters.
-      __cache_type const* __fmt = __cache_type::_S_get(__io);
-
-      // Fail quickly if !__valid
-      if (__beg == __end)
-        {
-          __err |= (ios_base::eofbit | ios_base::failbit);
-          return;
-        }
-
-      // Acceptable formats for numbers here are based on 22.2.3.1
-      string __grp;
-      int __sep_pos = 0;
-      int __pos = 0;
-      const char* __lits = __fmt->_S_literals;
-      char __c = *__beg;
-
-      // Check first for sign
-      bool __testsign = false;
-      if ((__c == __lits[__cache_type::_S_minus])
-         || (__c == __lits[__cache_type::_S_plus]))
-        {
-          __testsign = true;
-          __xtrc[__pos++] = __c;
-          ++__beg;
-         __c = * __beg;
-
-          // Whitespace may follow a sign
-          while ((__beg != __end) && (isspace(__c)))
-           {
-             ++__beg;
-             __c = *__beg;
-           }
-
-          // There had better be more to come...
-          if (__beg == __end)
-            {
-              __xtrc[__pos] = '\0';
-              __err |= (ios_base::eofbit | ios_base::failbit);
-              return;
-            }
-        }
-
-      // Now check if first character is a zero.
-      bool __testzero = false;    
-      if (__c == __lits[__cache_type::_S_digits])
-        {
-           __testzero = true;
-           ++__beg;
-          __c = *__beg;
-
-           // We have to check for __beg == __end here. If so,
-           // a plain '0' (possibly with a sign) can be got rid of now
-           if (__beg == __end)
-             {
-               __xtrc[__pos++] = __lits[__cache_type::_S_digits];
-               __xtrc[__pos] = '\0';
-               __err |= ios_base::eofbit;
-               return;
-             }
-
-          // Figure out base for integer types only
-          // Based on Table 55 of 22.2.2.1.2
-          if (!__fp && __base != 10 && __base != 8)
-            {
-              // Here, __base == 0 or 16
-              if ((__c == __lits[__cache_type::_S_x])
-                 || (__c == __lits[__cache_type::_S_X]))
-                {
-                  ++__beg;
-                 __c = *__beg;
-                  __base = 16;
-                  __testzero = false; // "0x" is not a leading zero
-                }
-              else if (__base == 0)
-                __base = 8;
-            }
-
-          // Remove any more leading zeros
-          while (__beg != __end)
-            {
-              if (__c == __lits[__cache_type::_S_digits])
-                {
-                  ++__beg;
-                 __c = *__beg;
-                  __testzero = true;
-                }
-              else
-                break;
-            }
-        }
-      else if (__base == 0) // 1st character is not zero
-        __base = 10;
-
-      // We now seek "units", i.e. digits and thousands separators.
-      // We may need to know if anything is found here. A leading zero
-      // (removed by now) would count.
-      bool __testunits = __testzero;
-      while (__beg != __end)
-        {
-          const char* __p = strchr(__lits, __c);
-
-          // NB: strchr returns true for __c == 0x0
-          if (__p && __c
-             &&((__p >= &__lits[__cache_type::_S_digits]
-                 && __p < &__lits[__cache_type::_S_digits + __base])
-                || (__p >= &__lits[__cache_type::_S_udigits]
-                    && __p < &__lits[__cache_type::_S_udigits + __base])))
-           {
-             // Try first for acceptable digit; record it if found.
-             __xtrc[__pos++] = __c;
-             ++__sep_pos;
-             __testunits = true;
-             ++__beg;
-             __c = *__beg;
-           }
-          else if (__c == __fmt->_M_thousands_sep && __fmt->_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)
-                {
-                  __grp += static_cast<char>(__sep_pos);
-                  __sep_pos = 0;
-                 ++__beg;
-                 __c = *__beg;
-                }
-              else
-               {
-                 __err |= ios_base::failbit;
-                 break;
-               }
-            }
-         else
-           // Not a valid input item.
-           break;
-        }
-
-      // Digit grouping is checked. If _M_groupings() doesn't
-      // match, then get very very upset, and set failbit.
-      if (__fmt->_M_use_grouping && !__grp.empty())
-        {
-          // Add the ending grouping
-          __grp += static_cast<char>(__sep_pos);
-
-          if (!__verify_grouping(__fmt->_M_grouping, __grp))
-            {
-              __err |= ios_base::failbit;
-              __xtrc[__pos] = '\0';
-              if (__beg == __end)
-                __err |= ios_base::eofbit;
-              return;
-            }
-        }
-
-      // If there was nothing but zeros, put one in the output string
-      if (__testzero && (__pos == 0 || (__pos == 1 && __testsign)))
-        __xtrc[__pos++] = __lits[__cache_type::_S_digits];
-
-      // That's it for integer types. Remaining code is for floating point
-      if (__fp && __beg != __end)
-        {
-          // Check first for decimal point. There MUST be one if
-          // __testunits is false.
-          bool __testdec = false;    // Is there a decimal point
-                                     // with digits following it?
-          if (__c == __fmt->_M_decimal_point)
-            {
-              __xtrc[__pos++] = '.';
-              ++__beg;
-             __c = *__beg;
-
-              // Now we get any digits after the decimal point
-              // There MUST be some if __testunits is false.
-              while (__beg != __end)
-                {
-                  const char* __p = strchr(__lits, __c);
-                  if ((__p >= &__lits[__cache_type::_S_digits]
-                        && __p < &__lits[__cache_type::_S_digits + __base])
-                       || (__p >= &__lits[__cache_type::_S_udigits]
-                           && __p < &__lits[__cache_type::_S_udigits + __base]))
-                    {
-                      __xtrc[__pos++] = __c;
-                      ++__beg;
-                     __c = *__beg;
-                      __testdec = true;
-                    }
-                  else
-                    break;
-                }
-            }
-          if (!__testunits && !__testdec) // Ill formed
-            {
-              __err |= ios_base::failbit;
-              __xtrc[__pos] = '\0';
-              if (__beg == __end)
-                __err |= ios_base::eofbit;
-              return;
-            }
-
-          // Now we may find an exponent
-          if (__beg != __end)
-            {
-              if ((__c == __lits[__cache_type::_S_ee])
-                   || (__c == __lits[__cache_type::_S_Ee]))
-                {
-                  __xtrc[__pos++] = __c;
-                  ++__beg;
-                 __c = *__beg;
-
-                  // Now there may be a sign
-                  if (__beg != __end)
-                    {
-                      if ((__c == __lits[__cache_type::_S_minus])
-                          || (__c == __lits[__cache_type::_S_plus]))
-                        {
-                          __xtrc[__pos++] = __c;
-                          ++__beg;
-                         __c = *__beg;
-                          // whitespace may follow a sign
-                          while ((__beg != __end) && (isspace(__c)))
-                           {
-                             ++__beg;
-                             __c = *__beg;
-                           }
-                        }
-                    }
-                  // And now there must be some digits
-                  if (__beg == __end)
-                    {
-                      __xtrc[__pos] = '\0';
-                      __err |= (ios_base::eofbit | ios_base::failbit);
-                      return;
-                    }
-                  while (__beg != __end)
-                    {
-                      const char* __p = strchr(__lits, __c);
-                      if ((__p >= &__lits[__cache_type::_S_digits]
-                            && __p < &__lits[__cache_type::_S_digits + __base])
-                           || (__p >= &__lits[__cache_type::_S_udigits]
-                               && __p < &__lits[__cache_type::_S_udigits + __base]))
-                        {
-                          __xtrc[__pos++] = __c;
-                          ++__beg;
-                         __c = *__beg;
-                        }
-                      else
-                        break;
-                    }
-                }
-            }
-          // Finally, that's it for floating point
-        }
-
-      // Finish up
-      __xtrc[__pos] = '\0';
-      if (__beg == __end)
-        __err |= ios_base::eofbit;
-    }
-
-  // The following code uses sprintf() to convert floating point
-  // values for insertion into a stream. The current implementation
-  // replicates the code in _S_pad_numeric() (in _S_output_float()) in
-  // order to prevent having to create a "wide" buffer in addition to
-  // the "narrow" buffer passed to sprintf(). An optimization would be
-  // to replace sprintf() with code that works directly on a wide
-  // buffer and then use _S_pad_numeric() to do the padding. It would
-  // be good to replace sprintf() anyway to avoid accidental buffer
-  // overruns and to gain back the efficiency that C++ provides by
-  // knowing up front the type of the values to insert. This
-  // implementation follows the C++ standard fairly directly as
-  // outlined in 22.2.2.2 [lib.locale.num.put]
   bool
-  __build_float_format(ios_base& __io, char* __fptr, char __modifier,
-                      streamsize __prec)
+  __num_base::_S_format_float(const ios_base& __io, char* __fptr, char __mod,
+                             streamsize __prec)
   {
     bool __incl_prec = false;
     ios_base::fmtflags __flags = __io.flags();
@@ -809,12 +494,12 @@ namespace std
     // As per [22.2.2.2.2.11]
     if (__flags & ios_base::fixed || __prec > 0)
       {
-        *__fptr++ = '.';
-        *__fptr++ = '*';
-        __incl_prec = true;
+       *__fptr++ = '.';
+       *__fptr++ = '*';
+       __incl_prec = true;
       }
-    if (__modifier)
-      *__fptr++ = __modifier;
+    if (__mod)
+      *__fptr++ = __mod;
     ios_base::fmtflags __fltfield = __flags & ios_base::floatfield;
     // [22.2.2.2.2] Table 58
     if (__fltfield == ios_base::fixed)
@@ -826,16 +511,43 @@ namespace std
     *__fptr = '\0';
     return __incl_prec;
   }
+  
+  void
+  __num_base::_S_format_int(const ios_base& __io, char* __fptr, char __mod, 
+                           char __modl)
+  {
+    ios_base::fmtflags __flags = __io.flags();
+    *__fptr++ = '%';
+    // [22.2.2.2.2] Table 60
+    if (__flags & ios_base::showpos)
+      *__fptr++ = '+';
+    if (__flags & ios_base::showbase)
+      *__fptr++ = '#';
+    *__fptr++ = 'l';
+
+    // For long long types.
+    if (__modl)
+      *__fptr++ = __modl;
 
+    ios_base::fmtflags __bsefield = __flags & ios_base::basefield;
+    if (__bsefield == ios_base::hex)
+      *__fptr++ = (__flags & ios_base::uppercase) ? 'X' : 'x';
+    else if (__bsefield == ios_base::oct)
+      *__fptr++ = 'o';
+    else
+      *__fptr++ = __mod;
+    *__fptr = '\0';
+  }
+  
   template<>
-  moneypunct_byname<char, false>::moneypunct_byname(const char* /*__s*/, 
-                                                   size_t __refs)
-  : moneypunct<char, false>(__refs) { }
+    moneypunct_byname<char, false>::moneypunct_byname(const char* /*__s*/, 
+                                                     size_t __refs)
+    : moneypunct<char, false>(__refs) { }
   
   template<>
-  moneypunct_byname<char, true>::moneypunct_byname(const char* /*__s*/, 
-                                                  size_t __refs)
-  : moneypunct<char, true>(__refs) { }
+    moneypunct_byname<char, true>::moneypunct_byname(const char* /*__s*/, 
+                                                    size_t __refs)
+    : moneypunct<char, true>(__refs) { }
   
 #ifdef _GLIBCPP_USE_WCHAR_T  
   ctype<wchar_t>::__wmask_type
index 45cd0bc..484a551 100644 (file)
@@ -242,39 +242,6 @@ namespace std
      string*, __false_type);
 
   template
-    void 
-    __pad_char(basic_ios<char>&, char*, const char*,
-               const streamsize, const streamsize);
-#ifdef _GLIBCPP_USE_WCHAR_T
-  template
-    void 
-    __pad_char(basic_ios<wchar_t>&, wchar_t*, const wchar_t*,
-               const streamsize, const streamsize);
-#endif
-
-  template
-    ostreambuf_iterator<char>
-    __pad_numeric(ostreambuf_iterator<char>, _Ios_Fmtflags, char, int,
-                 const char*, const char*, const char*);
-#ifdef _GLIBCPP_USE_WCHAR_T
-  template
-    ostreambuf_iterator<wchar_t>
-    __pad_numeric(ostreambuf_iterator<wchar_t>, _Ios_Fmtflags, wchar_t, int,
-                 const wchar_t*, const wchar_t*, const wchar_t*);
-#endif
-
-  template
-    ostreambuf_iterator<char>
-    __output_float(ostreambuf_iterator<char>, ios_base&, char, 
-                  const char*, size_t);
-#ifdef _GLIBCPP_USE_WCHAR_T
-  template
-    ostreambuf_iterator<wchar_t>
-    __output_float(ostreambuf_iterator<wchar_t>, ios_base&, wchar_t, 
-                  const char*, size_t);
-#endif
-
-  template
     streamsize
     __copy_streambufs(basic_ios<char>&, basic_streambuf<char>*,
                      basic_streambuf<char>*); 
diff --git a/libstdc++-v3/testsuite/22_locale/num_get.cc b/libstdc++-v3/testsuite/22_locale/num_get.cc
new file mode 100644 (file)
index 0000000..fae184d
--- /dev/null
@@ -0,0 +1,52 @@
+// 2001-11-21  Benjamin Kosnik  <bkoz@redhat.com>
+
+// Copyright (C) 2001 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 22.2.2.1  Template class num_get
+
+#include <locale>
+
+void test01()
+{
+  // Check for required base class.
+  typedef std::num_get<char> test_type;
+  typedef std::locale::facet base_type;
+  const test_type& obj = std::use_facet<test_type>(std::locale()); 
+  const base_type* base = &obj;
+  
+  // Check for required typedefs
+  typedef test_type::char_type char_type;
+  typedef test_type::iter_type iter_type;
+}
+
+// Should be able to instantiate this for other types besides char, wchar_t
+class gnu_num_get: public std::num_get<unsigned char> 
+{ };
+
+void test02()
+{ 
+  gnu_num_get facet01;
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/22_locale/num_get_members_char.cc b/libstdc++-v3/testsuite/22_locale/num_get_members_char.cc
new file mode 100644 (file)
index 0000000..3ab6236
--- /dev/null
@@ -0,0 +1,246 @@
+// 2001-11-21 Benjamin Kosnik  <bkoz@redhat.com>
+
+// Copyright (C) 2001 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 22.2.2.1.1  num_get members
+
+#include <locale>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+// XXX This test is not working for non-glibc locale models.
+// { dg-do run { xfail *-*-* } }
+
+void test01()
+{
+  using namespace std;
+  typedef istreambuf_iterator<char> iterator_type;
+
+  bool test = true;
+
+  // basic construction
+  locale loc_c = locale::classic();
+  locale loc_hk("en_HK");
+  locale loc_fr("fr_FR@euro");
+  locale loc_de("de_DE");
+  VERIFY( loc_c != loc_de );
+  VERIFY( loc_hk != loc_fr );
+  VERIFY( loc_hk != loc_de );
+  VERIFY( loc_de != loc_fr );
+
+  // cache the numpunct facets
+  const numpunct<char>& numpunct_c = use_facet<numpunct<char> >(loc_c); 
+  const numpunct<char>& numpunct_de = use_facet<numpunct<char> >(loc_de); 
+  const numpunct<char>& numpunct_hk = use_facet<numpunct<char> >(loc_hk); 
+
+  // sanity check the data is correct.
+  const string empty;
+  char c;
+
+  bool b1 = true;
+  bool b0 = false;
+  long l1 = 2147483647;
+  long l2 = -2147483647;
+  long l;
+  unsigned long ul1 = 1294967294;
+  unsigned long ul2 = 0;
+  unsigned long ul;
+  double d1 =  1.02345e+308;
+  double d2 = 3.15e-308;
+  double d;
+  long double ld1 = 6.630025e+4;
+  long double ld2 = 0.0;
+  long double ld;
+  void* v;
+  const void* cv = &ul2;
+
+  // cache the num_get facet
+  istringstream iss;
+  iss.imbue(loc_de);
+  const num_get<char>& ng = use_facet<num_get<char> >(iss.getloc()); 
+  const ios_base::iostate goodbit = ios_base::goodbit;
+  const ios_base::iostate eofbit = ios_base::eofbit;
+  ios_base::iostate err = ios_base::goodbit;
+
+  // bool, simple
+  iss.str("1");
+  iterator_type os_it00 = iss.rdbuf();
+  iterator_type os_it01 = ng.get(os_it00, 0, iss, err, b1);
+  VERIFY( b1 == true );
+  VERIFY( err & ios_base::eofbit );
+
+  iss.str("0");
+  err = goodbit;
+  ng.get(iss.rdbuf(), 0, iss, err, b0);
+  VERIFY( b0 == false );
+  VERIFY( err & eofbit );
+
+  // bool, more twisted examples
+  iss.imbue(loc_c);
+  iss.str("true ");
+  iss.clear();
+  iss.setf(ios_base::boolalpha);
+  err = goodbit;
+  ng.get(iss.rdbuf(), 0, iss, err, b0);
+  VERIFY( b0 == true );
+  VERIFY( err == goodbit );
+
+  iss.str("false ");
+  iss.clear();
+  iss.setf(ios_base::boolalpha);
+  err = goodbit;
+  ng.get(iss.rdbuf(), 0, iss, err, b1);
+  VERIFY( b1 == false );
+  VERIFY( err == goodbit );
+
+  // long, in a locale that expects grouping
+  iss.imbue(loc_hk);
+  iss.str("2,147,483,647 ");
+  iss.clear();
+  err = goodbit;
+  ng.get(iss.rdbuf(), 0, iss, err, l);
+  VERIFY( l == l1 );
+  VERIFY( err == goodbit );
+
+  iss.str("-2,147,483,647++++++");
+  iss.clear();
+  err = goodbit;
+  ng.get(iss.rdbuf(), 0, iss, err, l);
+  VERIFY( l == l2 );
+  VERIFY( err == goodbit );
+
+  // unsigned long, in a locale that does not group
+  iss.imbue(loc_c);
+  iss.str("1294967294");
+  iss.clear();
+  err = goodbit;
+  ng.get(iss.rdbuf(), 0, iss, err, ul);
+  VERIFY( ul == ul1);
+  VERIFY( err == eofbit );
+
+  iss.str("0+++++++++++++++++++");
+  iss.clear();
+  err = goodbit;
+  ng.get(iss.rdbuf(), 0, iss, err, ul);
+  VERIFY( ul == ul2);
+  VERIFY( err == goodbit );
+
+  // ... and one that does
+  iss.imbue(loc_de);
+  iss.str("1.294.967.294+++++++");
+  iss.clear();
+  iss.width(20);
+  iss.setf(ios_base::left, ios_base::adjustfield);
+  err = goodbit;
+  ng.get(iss.rdbuf(), 0, iss, err, ul);
+  VERIFY( ul == ul1 );
+  VERIFY( err == goodbit );
+
+  // double
+  iss.imbue(loc_c);
+  iss.str("1.02345e+308++++++++");
+  iss.clear();
+  iss.width(20);
+  iss.setf(ios_base::left, ios_base::adjustfield);
+  err = goodbit;
+  ng.get(iss.rdbuf(), 0, iss, err, d);
+  VERIFY( d == d1 );
+  VERIFY( err == goodbit );
+
+  iss.str("+3.15e-308");
+  iss.clear();
+  iss.width(20);
+  iss.setf(ios_base::right, ios_base::adjustfield);
+  err = goodbit;
+  ng.get(iss.rdbuf(), 0, iss, err, d);
+  VERIFY( d == d2 );
+  VERIFY( err == eofbit );
+
+  iss.imbue(loc_de);
+  iss.str("+1,02345e+308");
+  iss.clear();
+  iss.width(20);
+  iss.setf(ios_base::right, ios_base::adjustfield);
+  iss.setf(ios_base::scientific, ios_base::floatfield);
+  err = goodbit;
+  ng.get(iss.rdbuf(), 0, iss, err, d);
+  VERIFY( d == d1 );
+  VERIFY( err == eofbit );
+
+  iss.str("3,15E-308 ");
+  iss.clear();
+  iss.width(20);
+  iss.precision(10);
+  iss.setf(ios_base::right, ios_base::adjustfield);
+  iss.setf(ios_base::scientific, ios_base::floatfield);
+  iss.setf(ios_base::uppercase);
+  err = goodbit;
+  ng.get(iss.rdbuf(), 0, iss, err, d);
+  VERIFY( d == d2 );
+  VERIFY( err == goodbit );
+
+  // long double
+  iss.str("6,630025e+4");
+  iss.clear();
+  err = goodbit;
+  ng.get(iss.rdbuf(), 0, iss, err, ld);
+  VERIFY( ld == ld1 );
+  VERIFY( err == eofbit );
+
+  iss.str("0 ");
+  iss.clear();
+  iss.precision(0);
+  iss.setf(ios_base::fixed, ios_base::floatfield);
+  err = goodbit;
+  ng.get(iss.rdbuf(), 0, iss, err, ld);
+  VERIFY( ld == 0 );
+  VERIFY( err == goodbit );
+
+  // const void
+  iss.str("0xbffff74c.");
+  iss.clear();
+  err = goodbit;
+  ng.get(iss.rdbuf(), 0, iss, err, v);
+  VERIFY( &v != &cv );
+  VERIFY( err == goodbit );
+
+
+#ifdef _GLIBCPP_USE_LONG_LONG
+  long long ll1 = 9223372036854775807;
+  long long ll2 = -9223372036854775807;
+  long long ll;
+
+  iss.str("9.223.372.036.854.775.807");
+  iss.clear();
+  err = goodbit;
+  ng.get(iss.rdbuf(), 0, iss, err, ll);
+  VERIFY( ll == ll1 );
+  VERIFY( err == eofbit );
+#endif
+}
+
+
+int main()
+{
+  test01();
+  return 0;
+}
+
+
+// Kathleen Hannah, humanitarian, woman, art-thief
diff --git a/libstdc++-v3/testsuite/22_locale/num_put.cc b/libstdc++-v3/testsuite/22_locale/num_put.cc
new file mode 100644 (file)
index 0000000..1715231
--- /dev/null
@@ -0,0 +1,52 @@
+// 2001-11-19  Benjamin Kosnik  <bkoz@redhat.com>
+
+// Copyright (C) 2001 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 22.2.2.2  Template class num_put
+
+#include <locale>
+
+void test01()
+{
+  // Check for required base class.
+  typedef std::num_put<char> test_type;
+  typedef std::locale::facet base_type;
+  const test_type& obj = std::use_facet<test_type>(std::locale()); 
+  const base_type* base = &obj;
+  
+  // Check for required typedefs
+  typedef test_type::char_type char_type;
+  typedef test_type::iter_type iter_type;
+}
+
+// Should be able to instantiate this for other types besides char, wchar_t
+class gnu_num_put: public std::num_put<unsigned char> 
+{ };
+
+void test02()
+{ 
+  gnu_num_put facet01;
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/22_locale/num_put_members_char.cc b/libstdc++-v3/testsuite/22_locale/num_put_members_char.cc
new file mode 100644 (file)
index 0000000..9bc5dce
--- /dev/null
@@ -0,0 +1,230 @@
+// 2001-11-19 Benjamin Kosnik  <bkoz@redhat.com>
+
+// Copyright (C) 2001 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 22.2.2.2.1  num_put members
+
+#include <locale>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+// XXX This test is not working for non-glibc locale models.
+// { dg-do run { xfail *-*-* } }
+
+void test01()
+{
+  using namespace std;
+  typedef ostreambuf_iterator<char> iterator_type;
+
+  bool test = true;
+
+  // basic construction
+  locale loc_c = locale::classic();
+  locale loc_hk("en_HK");
+  locale loc_fr("fr_FR@euro");
+  locale loc_de("de_DE");
+  VERIFY( loc_c != loc_de );
+  VERIFY( loc_hk != loc_fr );
+  VERIFY( loc_hk != loc_de );
+  VERIFY( loc_de != loc_fr );
+
+  // cache the numpunct facets
+  const numpunct<char>& numpunct_c = use_facet<numpunct<char> >(loc_c); 
+  const numpunct<char>& numpunct_de = use_facet<numpunct<char> >(loc_de); 
+  const numpunct<char>& numpunct_hk = use_facet<numpunct<char> >(loc_hk); 
+
+  // sanity check the data is correct.
+  const string empty;
+  string result1;
+  string result2;
+  char c;
+
+  bool b1 = true;
+  bool b0 = false;
+  long l1 = 2147483647;
+  long l2 = -2147483647;
+  unsigned long ul1 = 1294967294;
+  unsigned long ul2 = 0;
+  double d1 =  1.7976931348623157e+308;
+  double d2 = 2.2250738585072014e-308;
+  long double ld1 = 1.7976931348623157e+308;
+  long double ld2 = 2.2250738585072014e-308;
+  const void* cv = &ld1;
+
+  // cache the num_put facet
+  ostringstream oss;
+  oss.imbue(loc_de);
+  const num_put<char>& np = use_facet<num_put<char> >(oss.getloc()); 
+
+  // bool, simple
+  iterator_type os_it00 = oss.rdbuf();
+  iterator_type os_it01 = np.put(os_it00, oss, '+', b1);
+  result1 = oss.str();
+  VERIFY( result1 == "1" );
+  //  VERIFY( os_it00 != os_it01 );
+
+  oss.str(empty);
+  np.put(oss.rdbuf(), oss, '+', b0);
+  result2 = oss.str();
+  VERIFY( result2 == "0" );
+
+  // bool, more twisted examples
+  oss.imbue(loc_c);
+  oss.str(empty);
+  oss.width(20);
+  oss.setf(ios_base::right, ios_base::adjustfield);
+  np.put(oss.rdbuf(), oss, '+', b0);
+  result1 = oss.str();
+  VERIFY( result1 == "+++++++++++++++++++0" );
+
+  oss.str(empty);
+  oss.width(20);
+  oss.setf(ios_base::left, ios_base::adjustfield);
+  oss.setf(ios_base::boolalpha);
+  np.put(oss.rdbuf(), oss, '+', b1);
+  result2 = oss.str();
+  VERIFY( result2 == "true++++++++++++++++" );
+
+  // long, in a locale that expects grouping
+  oss.imbue(loc_hk);
+  oss.str(empty);
+  oss.clear();
+  np.put(oss.rdbuf(), oss, '+', l1);
+  result1 = oss.str();
+  VERIFY( result1 == "2,147,483,647" );
+
+  oss.str(empty);
+  oss.clear();
+  oss.width(20);
+  oss.setf(ios_base::left, ios_base::adjustfield);
+  np.put(oss.rdbuf(), oss, '+', l2);
+  result1 = oss.str();
+  VERIFY( result1 == "-2,147,483,647++++++" );
+
+  // unsigned long, in a locale that does not group
+  oss.imbue(loc_c);
+  oss.str(empty);
+  oss.clear();
+  np.put(oss.rdbuf(), oss, '+', ul1);
+  result1 = oss.str();
+  VERIFY( result1 == "1294967294" );
+
+  oss.str(empty);
+  oss.clear();
+  oss.width(20);
+  oss.setf(ios_base::left, ios_base::adjustfield);
+  np.put(oss.rdbuf(), oss, '+', ul2);
+  result1 = oss.str();
+  VERIFY( result1 == "0+++++++++++++++++++" );
+
+  // ... and one that does
+  oss.imbue(loc_de);
+  oss.str(empty);
+  oss.clear();
+  oss.width(20);
+  oss.setf(ios_base::left, ios_base::adjustfield);
+  np.put(oss.rdbuf(), oss, '+', ul1);
+  result1 = oss.str();
+  VERIFY( result1 == "1.294.967.294+++++++" );
+
+  // double
+  oss.str(empty);
+  oss.clear();
+  oss.width(20);
+  oss.setf(ios_base::left, ios_base::adjustfield);
+  np.put(oss.rdbuf(), oss, '+', d1);
+  result1 = oss.str();
+  VERIFY( result1 == "1,79769e+308++++++++" );
+
+  oss.str(empty);
+  oss.clear();
+  oss.width(20);
+  oss.setf(ios_base::right, ios_base::adjustfield);
+  np.put(oss.rdbuf(), oss, '+', d2);
+  result1 = oss.str();
+  VERIFY( result1 == "++++++++2,22507e-308" );
+
+  oss.str(empty);
+  oss.clear();
+  oss.width(20);
+  oss.setf(ios_base::right, ios_base::adjustfield);
+  oss.setf(ios_base::scientific, ios_base::floatfield);
+  np.put(oss.rdbuf(), oss, '+', d2);
+  result2 = oss.str();
+  VERIFY( result2 == "+++++++2,225074e-308" );
+
+  oss.str(empty);
+  oss.clear();
+  oss.width(20);
+  oss.precision(10);
+  oss.setf(ios_base::right, ios_base::adjustfield);
+  oss.setf(ios_base::scientific, ios_base::floatfield);
+  oss.setf(ios_base::uppercase);
+  np.put(oss.rdbuf(), oss, '+', d2);
+  result1 = oss.str();
+  VERIFY( result1 == "+++2,2250738585E-308" );
+
+  // long double
+  oss.str(empty);
+  oss.clear();
+  np.put(oss.rdbuf(), oss, '+', ld1);
+  result1 = oss.str();
+  VERIFY( result1 == "1,7976931349E+308" );
+
+  oss.str(empty);
+  oss.clear();
+  oss.precision(0);
+  oss.setf(ios_base::fixed, ios_base::floatfield);
+  np.put(oss.rdbuf(), oss, '+', ld2);
+  result1 = oss.str();
+  VERIFY( result1 == "0" );
+
+  // const void
+  oss.str(empty);
+  oss.clear();
+  np.put(oss.rdbuf(), oss, '+', cv);
+  result1 = oss.str();
+  // No grouping characters.
+  VERIFY( !char_traits<char>::find(result1.c_str(), 
+                                  numpunct_de.decimal_point(), 
+                                  result1.size()) );
+  // Should contain an 'x'.
+  VERIFY( !char_traits<char>::find(result1.c_str(), 'x', result1.size()) );
+
+#ifdef _GLIBCPP_USE_LONG_LONG
+  long long ll1 = 9223372036854775807;
+  long long ll2 = -9223372036854775807;
+
+  oss.str(empty);
+  oss.clear();
+  np.put(oss.rdbuf(), oss, '+', ll1);
+  result1 = oss.str();
+  VERIFY( result1 == "9.223.372.036.854.775.807" );
+#endif
+}
+
+
+int main()
+{
+  test01();
+  return 0;
+}
+
+
+
diff --git a/libstdc++-v3/testsuite/22_locale/num_put_members_wchar_t.cc b/libstdc++-v3/testsuite/22_locale/num_put_members_wchar_t.cc
new file mode 100644 (file)
index 0000000..885df82
--- /dev/null
@@ -0,0 +1,234 @@
+// 2001-11-19 Benjamin Kosnik  <bkoz@redhat.com>
+
+// Copyright (C) 2001 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 22.2.2.2.1  num_put members
+
+#include <locale>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+// XXX This test is not working for non-glibc locale models.
+// { dg-do run { xfail *-*-* } }
+
+#ifdef _GLIBCPP_USE_WCHAR_T
+void test01()
+{
+  using namespace std;
+  typedef ostreambuf_iterator<wchar_t> iterator_type;
+
+  bool test = true;
+
+  // basic construction
+  locale loc_c = locale::classic();
+  locale loc_hk("en_HK");
+  locale loc_fr("fr_FR@euro");
+  locale loc_de("de_DE");
+  VERIFY( loc_c != loc_de );
+  VERIFY( loc_hk != loc_fr );
+  VERIFY( loc_hk != loc_de );
+  VERIFY( loc_de != loc_fr );
+
+  // cache the numpunct facets
+  const numpunct<wchar_t>& numpunct_c = use_facet<numpunct<wchar_t> >(loc_c); 
+  const numpunct<wchar_t>& numpunct_de = use_facet<numpunct<wchar_t> >(loc_de); 
+  const numpunct<wchar_t>& numpunct_hk = use_facet<numpunct<wchar_t> >(loc_hk); 
+
+  // sanity check the data is correct.
+  const wstring empty;
+  wstring result1;
+  wstring result2;
+  wchar_t c;
+
+  bool b1 = true;
+  bool b0 = false;
+  long l1 = 2147483647;
+  long l2 = -2147483647;
+  unsigned long ul1 = 1294967294;
+  unsigned long ul2 = 0;
+  double d1 =  1.7976931348623157e+308;
+  double d2 = 2.2250738585072014e-308;
+  long double ld1 = 1.7976931348623157e+308;
+  long double ld2 = 2.2250738585072014e-308;
+  const void* cv = &ld1;
+
+  // cache the num_put facet
+  wostringstream oss;
+  oss.imbue(loc_de);
+  const num_put<wchar_t>& np = use_facet<num_put<wchar_t> >(oss.getloc()); 
+
+  // bool, simple
+  iterator_type os_it00 = oss.rdbuf();
+  iterator_type os_it01 = np.put(os_it00, oss, '+', b1);
+  result1 = oss.str();
+  VERIFY( result1 == L"1" );
+  //  VERIFY( os_it00 != os_it01 );
+
+  oss.str(empty);
+  np.put(oss.rdbuf(), oss, L'+', b0);
+  result2 = oss.str();
+  VERIFY( result2 == L"0" );
+
+  // bool, more twisted examples
+  oss.imbue(loc_c);
+  oss.str(empty);
+  oss.width(20);
+  oss.setf(ios_base::right, ios_base::adjustfield);
+  np.put(oss.rdbuf(), oss, L'+', b0);
+  result1 = oss.str();
+  VERIFY( result1 == L"+++++++++++++++++++0" );
+
+  oss.str(empty);
+  oss.width(20);
+  oss.setf(ios_base::left, ios_base::adjustfield);
+  oss.setf(ios_base::boolalpha);
+  np.put(oss.rdbuf(), oss, L'+', b1);
+  result2 = oss.str();
+  VERIFY( result2 == L"true++++++++++++++++" );
+
+  // long, in a locale that expects grouping
+  oss.imbue(loc_hk);
+  oss.str(empty);
+  oss.clear();
+  np.put(oss.rdbuf(), oss, L'+', l1);
+  result1 = oss.str();
+  VERIFY( result1 == L"2,147,483,647" );
+
+  oss.str(empty);
+  oss.clear();
+  oss.width(20);
+  oss.setf(ios_base::left, ios_base::adjustfield);
+  np.put(oss.rdbuf(), oss, L'+', l2);
+  result1 = oss.str();
+  VERIFY( result1 == L"-2,147,483,647++++++" );
+
+  // unsigned long, in a locale that does not group
+  oss.imbue(loc_c);
+  oss.str(empty);
+  oss.clear();
+  np.put(oss.rdbuf(), oss, L'+', ul1);
+  result1 = oss.str();
+  VERIFY( result1 == L"1294967294" );
+
+  oss.str(empty);
+  oss.clear();
+  oss.width(20);
+  oss.setf(ios_base::left, ios_base::adjustfield);
+  np.put(oss.rdbuf(), oss, L'+', ul2);
+  result1 = oss.str();
+  VERIFY( result1 == L"0+++++++++++++++++++" );
+
+  // ... and one that does
+  oss.imbue(loc_de);
+  oss.str(empty);
+  oss.clear();
+  oss.width(20);
+  oss.setf(ios_base::left, ios_base::adjustfield);
+  np.put(oss.rdbuf(), oss, L'+', ul1);
+  result1 = oss.str();
+  VERIFY( result1 == L"1.294.967.294+++++++" );
+
+  // double
+  oss.str(empty);
+  oss.clear();
+  oss.width(20);
+  oss.setf(ios_base::left, ios_base::adjustfield);
+  np.put(oss.rdbuf(), oss, L'+', d1);
+  result1 = oss.str();
+  VERIFY( result1 == L"1,79769e+308++++++++" );
+
+  oss.str(empty);
+  oss.clear();
+  oss.width(20);
+  oss.setf(ios_base::right, ios_base::adjustfield);
+  np.put(oss.rdbuf(), oss, L'+', d2);
+  result1 = oss.str();
+  VERIFY( result1 == L"++++++++2,22507e-308" );
+
+  oss.str(empty);
+  oss.clear();
+  oss.width(20);
+  oss.setf(ios_base::right, ios_base::adjustfield);
+  oss.setf(ios_base::scientific, ios_base::floatfield);
+  np.put(oss.rdbuf(), oss, L'+', d2);
+  result2 = oss.str();
+  VERIFY( result2 == L"+++++++2,225074e-308" );
+
+  oss.str(empty);
+  oss.clear();
+  oss.width(20);
+  oss.precision(10);
+  oss.setf(ios_base::right, ios_base::adjustfield);
+  oss.setf(ios_base::scientific, ios_base::floatfield);
+  oss.setf(ios_base::uppercase);
+  np.put(oss.rdbuf(), oss, L'+', d2);
+  result1 = oss.str();
+  VERIFY( result1 == L"+++2,2250738585E-308" );
+
+  // long double
+  oss.str(empty);
+  oss.clear();
+  np.put(oss.rdbuf(), oss, L'+', ld1);
+  result1 = oss.str();
+  VERIFY( result1 == L"1,7976931349E+308" );
+
+  oss.str(empty);
+  oss.clear();
+  oss.precision(0);
+  oss.setf(ios_base::fixed, ios_base::floatfield);
+  np.put(oss.rdbuf(), oss, L'+', ld2);
+  result1 = oss.str();
+  VERIFY( result1 == L"0" );
+
+  // const void
+  oss.str(empty);
+  oss.clear();
+  np.put(oss.rdbuf(), oss, L'+', cv);
+  result1 = oss.str();
+  // No grouping characters.
+  VERIFY( !char_traits<wchar_t>::find(result1.c_str(), 
+                                  numpunct_de.decimal_point(), 
+                                  result1.size()) );
+  // Should contain an 'x'.
+  VERIFY( !char_traits<wchar_t>::find(result1.c_str(), L'x', result1.size()) );
+
+#ifdef _GLIBCPP_USE_LONG_LONG
+  long long ll1 = 9223372036854775807;
+  long long ll2 = -9223372036854775807;
+
+  oss.str(empty);
+  oss.clear();
+  np.put(oss.rdbuf(), oss, '+', ll1);
+  result1 = oss.str();
+  VERIFY( result1 == L"9.223.372.036.854.775.807" );
+#endif
+}
+#endif
+
+int main()
+{
+#ifdef _GLIBCPP_USE_WCHAR_T
+  test01();
+#endif
+  return 0;
+}
+
+
+// Diana D. Brooks, former chief executive of Sotheby's
+// art-thief extraordinaire
index 0527c99..901de4c 100644 (file)
@@ -75,19 +75,12 @@ void test01()
 
   VERIFY( dp2 != dp3 );
   VERIFY( th2 != th3 );
-#if 0
-  // XXX isn't actually supported right now.
-  VERIFY( t2 != t3 );
-  VERIFY( f2 != f3 );
-#endif
 
   VERIFY( dp2 != dp4 );
   VERIFY( th2 != th4 );
-#if 0
-  // XXX isn't actually supported right now.
-  VERIFY( t2 != t3 );
-  VERIFY( f2 != f3 );
-#endif
+  // XXX This isn't actually supported right now.
+  // VERIFY( t2 != t3 );
+  // VERIFY( f2 != f3 );
 }
 
 int main()
diff --git a/libstdc++-v3/testsuite/22_locale/numpunct_members_wchar_t.cc b/libstdc++-v3/testsuite/22_locale/numpunct_members_wchar_t.cc
new file mode 100644 (file)
index 0000000..afb7eb9
--- /dev/null
@@ -0,0 +1,88 @@
+// 2001-11-20 Benjamin Kosnik  <bkoz@redhat.com>
+
+// Copyright (C) 2001 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 22.2.3.1.1 nunpunct members
+
+#include <locale>
+#include <testsuite_hooks.h>
+
+// XXX This test is not working for non-glibc locale models.
+// { dg-do run { xfail *-*-* } }
+
+void test01()
+{
+  using namespace std;
+  
+  bool test = true;
+
+  // basic construction
+  locale loc_c = locale::classic();
+  locale loc_us("en_US");
+  locale loc_fr("fr_FR");
+  locale loc_de("de_DE");
+  VERIFY( loc_c != loc_de );
+  VERIFY( loc_us != loc_fr );
+  VERIFY( loc_us != loc_de );
+  VERIFY( loc_de != loc_fr );
+
+  // cache the numpunct facets
+  const numpunct<wchar_t>& nump_c = use_facet<numpunct<wchar_t> >(loc_c); 
+  const numpunct<wchar_t>& nump_us = use_facet<numpunct<wchar_t> >(loc_us); 
+  const numpunct<wchar_t>& nump_fr = use_facet<numpunct<wchar_t> >(loc_fr); 
+  const numpunct<wchar_t>& nump_de = use_facet<numpunct<wchar_t> >(loc_de); 
+
+  // sanity check the data is correct.
+  wchar_t dp1 = nump_c.decimal_point();
+  wchar_t th1 = nump_c.thousands_sep();
+  string g1 = nump_c.grouping();
+  wstring t1 = nump_c.truename();
+  wstring f1 = nump_c.falsename();
+
+  wchar_t dp2 = nump_us.decimal_point();
+  wchar_t th2 = nump_us.thousands_sep();
+  string g2 = nump_us.grouping();
+  wstring t2 = nump_us.truename();
+  wstring f2 = nump_us.falsename();
+
+  wchar_t dp3 = nump_fr.decimal_point();
+  wchar_t th3 = nump_fr.thousands_sep();
+  string g3 = nump_fr.grouping();
+  wstring t3 = nump_fr.truename();
+  wstring f3 = nump_fr.falsename();
+
+  wchar_t dp4 = nump_de.decimal_point();
+  wchar_t th4 = nump_de.thousands_sep();
+  string g4 = nump_de.grouping();
+  wstring t4 = nump_de.truename();
+  wstring f4 = nump_de.falsename();
+
+  VERIFY( dp2 != dp3 );
+  VERIFY( th2 != th3 );
+
+  VERIFY( dp2 != dp4 );
+  VERIFY( th2 != th4 );
+}
+
+int main()
+{
+  test01();
+
+  return 0;
+}
index e6bb415..0cb5ae0 100644 (file)
@@ -387,7 +387,7 @@ bool test09()
 }
 
 bool test10() {
-  std::string str_01("0 00 000 +0 +  0 -   0");
+  std::string str_01("0 00 000 +0 +0 -0");
   std::stringbuf isbuf_01(str_01);
   std::istream is_01(&isbuf_01);
 
@@ -447,7 +447,7 @@ bool test10() {
   VERIFY( n == 33 );
   VERIFY( is_03.rdstate() == std::ios_base::eofbit );
 
-  std::string str_04("3. 4.5E+  2a5E-3 .6E1");
+  std::string str_04("3. 4.5E+2a5E-3 .6E1");
   std::stringbuf isbuf_04(str_04);
   std::istream is_04(&isbuf_04);
 
index af45aaa..bd49ebf 100644 (file)
@@ -63,13 +63,13 @@ static bool F=false;
 static _TestCase testcases[] =
 {
 #if _GLIBCPP_USE_WCHAR_T
-  // standard output (no formatting applied)
+  // standard output (no formatting applied) 1-4
   { 1.2, 6,0,'.',' ', F,F,F,F,F,F,F,F, "1.2",L"1.2" },
   { 54, 6,0,'.',' ', F,F,F,F,F,F,F,F, "54",L"54" },
   { -.012, 6,0,'.',' ', F,F,F,F,F,F,F,F, "-0.012",L"-0.012" },
   { -.00000012, 6,0,'.',' ', F,F,F,F,F,F,F,F, "-1.2e-07",L"-1.2e-07" },
     
-  // fixed formatting
+  // fixed formatting 5-11
   { 10.2345, 0,0,'.',' ', T,F,F,F,F,F,F,F, "10",L"10" },
   { 10.2345, 0,0,'.',' ', T,F,F,T,F,F,F,F, "10.",L"10." },
   { 10.2345, 1,0,'.',' ', T,F,F,F,F,F,F,F, "10.2",L"10.2" },
@@ -78,7 +78,7 @@ static _TestCase testcases[] =
   { -10.2345, 6,0,'.',' ', T,F,F,F,F,F,F,F, "-10.234500",L"-10.234500" },
   { -10.2345, 6,0,',',' ', T,F,F,F,F,F,F,F, "-10,234500",L"-10,234500" },
 
-  // fixed formatting with width
+  // fixed formatting with width 12-22
   { 10.2345, 4,5,'.',' ', T,F,F,F,F,F,F,F, "10.2345",L"10.2345" },
   { 10.2345, 4,6,'.',' ', T,F,F,F,F,F,F,F, "10.2345",L"10.2345" },
   { 10.2345, 4,7,'.',' ', T,F,F,F,F,F,F,F, "10.2345",L"10.2345" },
@@ -91,7 +91,7 @@ static _TestCase testcases[] =
   { -10.2345, 4,10,'.','A', T,F,F,F,F,T,F,F, "-AA10.2345",L"-AA10.2345" },
   { 10.2345, 4,10,'.','#', T,F,T,F,F,T,F,F, "+##10.2345",L"+##10.2345" },
 
-  // scientific formatting
+  // scientific formatting 23-29
   { 1.23e+12, 1,0,'.',' ', F,T,F,F,F,F,F,F, "1.2e+12",L"1.2e+12" },
   { 1.23e+12, 1,0,'.',' ', F,T,F,F,T,F,F,F, "1.2E+12",L"1.2E+12" },
   { 1.23e+12, 2,0,'.',' ', F,T,F,F,F,F,F,F, "1.23e+12",L"1.23e+12" },
@@ -207,7 +207,7 @@ test01()
         apply_formatting(tc, os);
         os << tc.val;
 #ifdef TEST_NUMPUT_VERBOSE
-        cout << "result: " << os.str() << endl;
+        cout << j << "result 1: " << os.str() << endl;
 #endif
         VERIFY( os && os.str() == tc.result );
       }
@@ -220,7 +220,7 @@ test01()
         apply_formatting(tc, os);
         os << (long double)tc.val;
 #ifdef TEST_NUMPUT_VERBOSE
-        cout << "result: " << os.str() << endl;
+        cout << j << "result 2: " << os.str() << endl;
 #endif
         VERIFY( os && os.str() == tc.result );
       }