From 6067bea410aa2a585f7017f2fef4842c84f0321c Mon Sep 17 00:00:00 2001
From: Benjamin Kosnik <bkoz@gcc.gnu.org>
Date: Tue, 18 Feb 2003 05:45:07 +0000
Subject: [PATCH] [multiple changes]

2003-02-17  Benjamin Kosnik  <bkoz@redhat.com>

	* include/bits/basic_ios.tcc (copyfmt): Copy locale data as well.
	* testsuite/27_io/ios_members.cc (test03): New.

2003-02-17  Jerry Quinn  <jlquinn@optonline.net>

	* include/bits/basic_ios.h (basic_ios::_M_cache_locale): Declare.
	(basic_ios::_M_cache_facets): Move into above.
	* include/bits/basic_ios.tcc (basic_ios::copyfmt): Rebuild locale
	cache.
	(basic_ios::imbue): Force locale cache to be built.
	(basic_ios::_M_init): Create and initialize locale cache.
	* include/bits/ios_base.h (__locale_cache_base): Declare.
	(ios_base::_M_locale_cache): New.
	(ios_base::_M_cache): Define.
	* include/bits/locale_facets.h:	(__num_base): Fix comment.  Add
	_S_end.
        (__locale_cache_base,__locale_cache<_CharT>):  New classes.
	(__locale_cache<char>, __locale_cache<wchar_t>): New specializations.
	* include/bits/locale_facets.tcc (num_put::_M_convert_int): Use locale
	cache literal string, grouping flag, thousands separator.
	(__locale_cache<_CharT>::__locale_cache): New.
	(__locale_cache<_CharT>::_M_init): New.
	(__locale_cache<_CharT>::_M_populate): New.
	* src/ios.cc: Clear _M_locale_cache in constructor.
	* src/locale-inst.cc (__locale_cache<char>, __locale_cache<_char_t>):
	New.

From-SVN: r63025
---
 libstdc++-v3/ChangeLog                      | 29 +++++++
 libstdc++-v3/include/bits/basic_ios.h       | 12 +--
 libstdc++-v3/include/bits/basic_ios.tcc     | 44 ++++++-----
 libstdc++-v3/include/bits/ios_base.h        | 11 +++
 libstdc++-v3/include/bits/locale_facets.h   | 87 +++++++++++++++++++--
 libstdc++-v3/include/bits/locale_facets.tcc | 43 +++++++---
 libstdc++-v3/src/ios.cc                     |  4 +-
 libstdc++-v3/src/locale-inst.cc             |  2 +
 libstdc++-v3/testsuite/27_io/ios_members.cc | 53 +++++++++----
 9 files changed, 224 insertions(+), 61 deletions(-)

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 57896f523964..f3fb9fe96e42 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,32 @@
+2003-02-17  Benjamin Kosnik  <bkoz@redhat.com>
+
+	* include/bits/basic_ios.tcc (copyfmt): Copy locale data as well.
+	* testsuite/27_io/ios_members.cc (test03): New.
+
+2003-02-17  Jerry Quinn  <jlquinn@optonline.net>
+
+	* include/bits/basic_ios.h (basic_ios::_M_cache_locale): Declare.
+	(basic_ios::_M_cache_facets): Move into above.
+	* include/bits/basic_ios.tcc (basic_ios::copyfmt): Rebuild locale
+	cache.
+	(basic_ios::imbue): Force locale cache to be built.
+	(basic_ios::_M_init): Create and initialize locale cache.
+	* include/bits/ios_base.h (__locale_cache_base): Declare.
+	(ios_base::_M_locale_cache): New.
+	(ios_base::_M_cache): Define.
+	* include/bits/locale_facets.h:	(__num_base): Fix comment.  Add
+	_S_end.
+        (__locale_cache_base,__locale_cache<_CharT>):  New classes.
+	(__locale_cache<char>, __locale_cache<wchar_t>): New specializations.
+	* include/bits/locale_facets.tcc (num_put::_M_convert_int): Use locale
+	cache literal string, grouping flag, thousands separator.
+	(__locale_cache<_CharT>::__locale_cache): New.
+	(__locale_cache<_CharT>::_M_init): New.
+	(__locale_cache<_CharT>::_M_populate): New.
+	* src/ios.cc: Clear _M_locale_cache in constructor.
+	* src/locale-inst.cc (__locale_cache<char>, __locale_cache<_char_t>):
+	New.
+
 2003-02-17  Paolo Carlini  <pcarlini@unitus.it>
 
 	* src/locale-inst.cc: Do not include <cassert>.
diff --git a/libstdc++-v3/include/bits/basic_ios.h b/libstdc++-v3/include/bits/basic_ios.h
index 29c1436cf274..7d0e47ef3af7 100644
--- a/libstdc++-v3/include/bits/basic_ios.h
+++ b/libstdc++-v3/include/bits/basic_ios.h
@@ -1,6 +1,7 @@
 // Iostreams base classes -*- C++ -*-
 
-// Copyright (C) 1997, 1998, 1999, 2001, 2002 Free Software Foundation, Inc.
+// Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003 
+// Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -90,9 +91,9 @@ namespace std
 
       // Cached use_facet<ctype>, which is based on the current locale info.
       const __ctype_type*                            _M_fctype;      
-      // From ostream.
+      // For ostream.
       const __numput_type*                           _M_fnumput;
-      // From istream.
+      // For istream.
       const __numget_type*                           _M_fnumget;
 
     public:
@@ -239,7 +240,8 @@ namespace std
        *  The parameter is passed by derived streams.
       */
       explicit 
-      basic_ios(basic_streambuf<_CharT, _Traits>* __sb) : ios_base() 
+      basic_ios(basic_streambuf<_CharT, _Traits>* __sb) 
+      : ios_base(), _M_fctype(0), _M_fnumput(0), _M_fnumget(0)
       { this->init(__sb); }
 
       /**
@@ -438,7 +440,7 @@ namespace std
       }
 
       void
-      _M_cache_facets(const locale& __loc);
+      _M_cache_locale(const locale& __loc);
     };
 } // namespace std
 
diff --git a/libstdc++-v3/include/bits/basic_ios.tcc b/libstdc++-v3/include/bits/basic_ios.tcc
index 876281ae3038..8ac1c6093225 100644
--- a/libstdc++-v3/include/bits/basic_ios.tcc
+++ b/libstdc++-v3/include/bits/basic_ios.tcc
@@ -60,12 +60,12 @@ namespace std
     basic_ios<_CharT, _Traits>&
     basic_ios<_CharT, _Traits>::copyfmt(const basic_ios& __rhs)
     {
-      // Per 27.1.1.1, do not call imbue, yet must trash all caches
+      // Per 27.1.1, do not call imbue, yet must trash all caches
       // associated with imbue()
 
       // Alloc any new word array first, so if it fails we have "rollback".
       _Words* __words = (__rhs._M_word_size <= _S_local_word_size) ?
-	_M_local_word : new _Words[__rhs._M_word_size];
+	                 _M_local_word : new _Words[__rhs._M_word_size];
 
       // Bump refs before doing callbacks, for safety.
       _Callback_list* __cb = __rhs._M_callbacks;
@@ -79,7 +79,8 @@ namespace std
 	}
       _M_dispose_callbacks();
 
-      _M_callbacks = __cb;  // NB: Don't want any added during above.
+      // NB: Don't want any added during above.
+      _M_callbacks = __cb;  
       for (int __i = 0; __i < __rhs._M_word_size; ++__i)
 	__words[__i] = __rhs._M_word[__i];
       if (_M_word != _M_local_word) 
@@ -95,10 +96,14 @@ namespace std
       this->precision(__rhs.precision());
       this->tie(__rhs.tie());
       this->fill(__rhs.fill());
+      _M_ios_locale = __rhs.getloc();
+      _M_cache_locale(_M_ios_locale);
+
+      _M_call_callbacks(copyfmt_event);
+
       // The next is required to be the last assignment.
       this->exceptions(__rhs.exceptions());
-      
-      _M_call_callbacks(copyfmt_event);
+
       return *this;
     }
 
@@ -129,7 +134,7 @@ namespace std
     {
       locale __old(this->getloc());
       ios_base::imbue(__loc);
-      _M_cache_facets(__loc);
+      _M_cache_locale(__loc);
       if (this->rdbuf() != 0)
 	this->rdbuf()->pubimbue(__loc);
       return __old;
@@ -141,8 +146,14 @@ namespace std
     {
       // NB: This may be called more than once on the same object.
       ios_base::_M_init();
-      _M_cache_facets(_M_ios_locale);
-      _M_tie = 0;
+
+      // Cache locale data and specific facets used by iostreams.
+      if (!_M_locale_cache.get())
+	{
+	  typedef __locale_cache<_CharT> __cache_t;
+	  this->_M_locale_cache = auto_ptr<__locale_cache_base>(static_cast<__locale_cache_base*>(new __cache_t));
+	  _M_cache_locale(_M_ios_locale);
+	}
 
       // NB: The 27.4.4.1 Postconditions Table specifies requirements
       // after basic_ios::init() has been called. As part of this,
@@ -159,6 +170,7 @@ namespace std
       _M_fill = _CharT();
       _M_fill_init = false;
 
+      _M_tie = 0;
       _M_exception = goodbit;
       _M_streambuf = __sb;
       _M_streambuf_state = __sb ? goodbit : badbit;
@@ -166,21 +178,15 @@ namespace std
 
   template<typename _CharT, typename _Traits>
     void
-    basic_ios<_CharT, _Traits>::_M_cache_facets(const locale& __loc)
+    basic_ios<_CharT, _Traits>::_M_cache_locale(const locale& __loc)
     {
-      if (has_facet<__ctype_type>(__loc))
+      if (__builtin_expect(has_facet<__ctype_type>(__loc), true))
 	_M_fctype = &use_facet<__ctype_type>(__loc);
-      else
-	_M_fctype = 0;
-      // Should be filled in by ostream and istream, respectively.
-      if (has_facet<__numput_type>(__loc))
+      if (__builtin_expect(has_facet<__numput_type>(__loc), true))
 	_M_fnumput = &use_facet<__numput_type>(__loc); 
-      else
-	_M_fnumput = 0;
-      if (has_facet<__numget_type>(__loc))
+      if (__builtin_expect(has_facet<__numget_type>(__loc), true))
 	_M_fnumget = &use_facet<__numget_type>(__loc); 
-      else
-	_M_fnumget = 0;
+      static_cast<__locale_cache<_CharT>&>(_M_cache())._M_init(__loc); 
     }
 
   // Inhibit implicit instantiations for required instantiations,
diff --git a/libstdc++-v3/include/bits/ios_base.h b/libstdc++-v3/include/bits/ios_base.h
index a7d4bf614c41..26ee38df383a 100644
--- a/libstdc++-v3/include/bits/ios_base.h
+++ b/libstdc++-v3/include/bits/ios_base.h
@@ -146,6 +146,8 @@ namespace std
 
   enum _Ios_Seekdir { _M_ios_seekdir_end = 1L << 16 };
 
+  class __locale_cache_base;
+
   // 27.4.2  Class ios_base
   /**
    *  @brief  The very top of the I/O class hierarchy.
@@ -430,6 +432,10 @@ namespace std
     // Members for locale and locale caching.
     locale 		_M_ios_locale;
 
+    // Cache of locale and facet data.
+    // Cast this to __locale_cache<_CharT>*
+    auto_ptr<__locale_cache_base>	_M_locale_cache;
+
     void 
     _M_init();
 
@@ -636,6 +642,11 @@ namespace std
       return __word._M_pword;
     }
 
+    // Access to the cache.  Not safe to call until basic_ios::_M_init() has
+    // happened.
+    __locale_cache_base&
+    _M_cache() { return *_M_locale_cache; }
+
     // Destructor
     /**
      *  Destroys local storage and
diff --git a/libstdc++-v3/include/bits/locale_facets.h b/libstdc++-v3/include/bits/locale_facets.h
index 1feb960c2cfb..59154f4c35e5 100644
--- a/libstdc++-v3/include/bits/locale_facets.h
+++ b/libstdc++-v3/include/bits/locale_facets.h
@@ -161,6 +161,7 @@ namespace std
       return __s;
     }
 
+
   // 22.2.1.1  Template class ctype
   // Include host and configuration specific ctype enums for ctype_base.
   #include <bits/ctype_base.h>
@@ -531,8 +532,8 @@ namespace std
   class __num_base 
   {
   public:
-    // NB: Code depends on the order of _M_atoms_out elements.
-    // Below are the indices into _M_atoms_out.
+    // NB: Code depends on the order of _S_atoms_out elements.
+    // Below are the indices into _S_atoms_out.
     enum 
       {  
         _S_minus, 
@@ -543,14 +544,15 @@ namespace std
         _S_digits_end = _S_digits + 16,
         _S_udigits = _S_digits_end,  
         _S_udigits_end = _S_udigits + 16,
-        _S_e = _S_digits + 14, // For scientific notation, 'e'
-        _S_E = _S_udigits + 14 // For scientific notation, 'E'
+        _S_e = _S_digits + 14,  // For scientific notation, 'e'
+        _S_E = _S_udigits + 14, // For scientific notation, 'E'
+	_S_end = _S_udigits_end
       };
     
-    // A list of valid numeric literals for output. 
-    // This array contains the chars after having been passed through
-    // the current locale's ctype<_CharT>.widen().
-    // For the standard "C" locale, this is 
+    // A list of valid numeric literals for output.  This array
+    // contains chars that will be passed through the current locale's
+    // ctype<_CharT>.widen() and then used to render numbers.
+    // For the standard "C" locale, this is
     // "-+xX0123456789abcdef0123456789ABCDEF".
     static const char* _S_atoms_out;
 
@@ -1931,6 +1933,75 @@ namespace std
     inline _CharT 
     tolower(_CharT __c, const locale& __loc)
     { return use_facet<ctype<_CharT> >(__loc).tolower(__c); }
+
+
+  // __locale_cache holds the information extracted from the
+  // numpunct<> and moneypunct<> facets in a form optimized for
+  // parsing and formatting.  It is stored as an
+  // auto_ptr<__locale_cache_base> member of ios_base and directly
+  // accessed via a casting to the derived __locale_cache<_CharT> in
+  // parameterized facets.
+  // The intent twofold: to avoid the costs of creating a locale
+  // object and to avoid calling the virtual functions in a locale's
+  // facet to look up data.
+  class __locale_cache_base
+  {
+  public:
+    virtual
+    ~__locale_cache_base() { }
+  };
+
+  template<typename _CharT>
+    class __locale_cache : public __locale_cache_base
+    {
+      // Types:
+      typedef _CharT               	char_type;
+      typedef char_traits<_CharT>       traits_type;
+      typedef basic_string<_CharT>	string_type;
+
+    public: 
+      // Data Members:
+
+      // A list of valid numeric literals: for the standard "C"
+      // locale, this is "-+xX0123456789abcdef0123456789ABCDEF".  This
+      // array contains the chars after having been passed through the
+      // current locale's ctype<_CharT>.widen().
+      _CharT                    _M_literals[__num_base::_S_end];
+
+      // The sign used to separate decimal values: for standard US
+      // locales, this would usually be: "."  Abstracted from
+      // numpunct::decimal_point().
+      _CharT                    _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().
+      _CharT                    _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;
+
+      __locale_cache() : _M_use_grouping(false) 
+      { };
+
+      __locale_cache& 
+      operator=(const __locale_cache& __lc);
+
+      // Make sure the cache is built before the first use.
+      void 
+      _M_init(const locale&);
+    };
 } // namespace std
 
 #endif
diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc
index ffb97ea0c9ce..857074f976f1 100644
--- a/libstdc++-v3/include/bits/locale_facets.tcc
+++ b/libstdc++-v3/include/bits/locale_facets.tcc
@@ -768,20 +768,14 @@ namespace std
       _M_convert_int(_OutIter __s, ios_base& __io, _CharT __fill, 
 		     _ValueT __v) const
       {
-	// Buildup list of digits given the current ctype.
-	_CharT __lit[_S_udigits_end];
-	const locale __loc = __io.getloc();
-	if (__builtin_expect(has_facet< ctype<_CharT> >(__loc), true))
-	  {
-	    const ctype<_CharT>& __ct = use_facet< ctype<_CharT> >(__loc);
-	    __ct.widen(_S_atoms_out, _S_atoms_out + _S_udigits_end, __lit);
-	  }
+	typedef __locale_cache<_CharT> __cache_type;
+	__cache_type& __lc = static_cast<__cache_type&>(__io._M_cache());
+	_CharT* __lit = __lc._M_literals;
 
 	// Long enough to hold hex, dec, and octal representations.
 	int __ilen = 4 * sizeof(_ValueT);
 	_CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
 							     * __ilen));
-
 	// [22.2.2.2.2] Stage 1, numeric conversion to character.
 	// Result is returned right-justified in the buffer.
 	int __len;
@@ -790,15 +784,13 @@ namespace std
 	
 	// Add grouping, if necessary. 
 	_CharT* __cs2;
-	const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
-	const string __grouping = __np.grouping();
-	if (__grouping.size())
+	if (__lc._M_use_grouping)
 	  {
 	    // Grouping can add (almost) as many separators as the
 	    // number of digits, but no more.
 	    __cs2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
 							  * __len * 2));
-	    _M_group_int(__grouping, __np.thousands_sep(), __io, 
+	    _M_group_int(__lc._M_grouping, __lc._M_thousands_sep, __io, 
 			 __cs2, __cs, __len);
 	    __cs = __cs2;
 	  }
@@ -2216,6 +2208,31 @@ namespace std
       return __s;
     }
 
+  // Generic definition, locale cache initialization.
+  template<typename _CharT>
+    void
+    __locale_cache<_CharT>::_M_init(const locale& __loc)
+    {
+      if (__builtin_expect(has_facet<numpunct<_CharT> >(__loc), true))
+	{
+	  const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
+	  _M_falsename = __np.falsename();
+	  _M_truename = __np.truename();
+	  _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;
+	}
+      if (__builtin_expect(has_facet<ctype<_CharT> >(__loc), true))
+	{
+	  const ctype<_CharT>& __ct = use_facet< ctype<_CharT> >(__loc);
+	  __ct.widen(__num_base::_S_atoms_out,
+		     __num_base::_S_atoms_out + __num_base::_S_end, 
+		     _M_literals);
+	}
+    }
+
   // Inhibit implicit instantiations for required instantiations,
   // which are defined via explicit instantiations elsewhere.  
   // NB: This syntax is a GNU extension.
diff --git a/libstdc++-v3/src/ios.cc b/libstdc++-v3/src/ios.cc
index 75fdee1e5c2e..9de6d1309f92 100644
--- a/libstdc++-v3/src/ios.cc
+++ b/libstdc++-v3/src/ios.cc
@@ -1,6 +1,6 @@
 // Iostreams base classes -*- C++ -*-
 
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -302,7 +302,7 @@ namespace std
     return __old;
   }
 
-  ios_base::ios_base() : _M_callbacks(0), _M_word(0)
+  ios_base::ios_base() : _M_callbacks(0), _M_word(0), _M_locale_cache(0)
   {
     // Do nothing: basic_ios::init() does it.  
     // NB: _M_callbacks and _M_word must be zero for non-initialized
diff --git a/libstdc++-v3/src/locale-inst.cc b/libstdc++-v3/src/locale-inst.cc
index 4dfc03b55c71..73b028df1bef 100644
--- a/libstdc++-v3/src/locale-inst.cc
+++ b/libstdc++-v3/src/locale-inst.cc
@@ -45,6 +45,7 @@ namespace std
   template class moneypunct_byname<char, true>;
   template class money_get<char, istreambuf_iterator<char> >;
   template class money_put<char, ostreambuf_iterator<char> >;
+  template class __locale_cache<char>;
 
 #ifdef _GLIBCPP_USE_WCHAR_T
   template class moneypunct<wchar_t, false>;
@@ -53,6 +54,7 @@ namespace std
   template class moneypunct_byname<wchar_t, true>;
   template class money_get<wchar_t, istreambuf_iterator<wchar_t> >;
   template class money_put<wchar_t, ostreambuf_iterator<wchar_t> >;
+  template class __locale_cache<wchar_t>;
 #endif
 
   // numpunct, numpunct_byname, num_get, and num_put
diff --git a/libstdc++-v3/testsuite/27_io/ios_members.cc b/libstdc++-v3/testsuite/27_io/ios_members.cc
index df00c6a4ce52..4c3598016789 100644
--- a/libstdc++-v3/testsuite/27_io/ios_members.cc
+++ b/libstdc++-v3/testsuite/27_io/ios_members.cc
@@ -1,6 +1,6 @@
 // 1999-09-20 bkoz
 
-// Copyright (C) 1999 Free Software Foundation, Inc.
+// Copyright (C) 1999, 2003 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -40,15 +40,15 @@ void test01()
   std::ios_base::fmtflags flag02, flag03;
   const std::ios_base::fmtflags flag01 = std::ios_base::skipws 
     					 | std::ios_base::dec;
-
-  const std::locale glocale = std::locale();
+ 
+  const std::locale c_loc = std::locale::classic();
 
   std::ios ios_01(NULL);
   std::ios::char_type ct01;
   std::ios::char_type ct02('x');;
 
   // 27.4.2.3 locales
-  ios_01.imbue(glocale);
+  ios_01.imbue(c_loc);
 
   // char narrow(char_type c, char dfault) const;
   char c1 = ios_01.narrow(ct02, 0);
@@ -57,10 +57,6 @@ void test01()
   // char_type widen(char c) const;
   ct01 = ios_01.widen('c');
   VERIFY( ct01 == 'c' );
-
-#ifdef DEBUG_ASSERT
-  assert(test);
-#endif
 }
 
 // 27.4.4.3 basic_ios iostate flags function
@@ -76,8 +72,6 @@ void test02()
   const iostate iostate01 = std::ios_base::badbit | std::ios_base::eofbit;
   const iostate iostate04 = std::ios_base::badbit;
 
-  const std::locale glocale = std::locale();
-
   std::ios ios_01(NULL);
   std::ios::char_type ct01;
   std::ios::char_type ct02('x');;
@@ -135,14 +129,45 @@ void test02()
   catch(...) {
     VERIFY( false );
   }
+}
+
+// copyfmt and locales.
+void test03()
+{
+  bool test = true;
+
+  using namespace std;
 
-#ifdef DEBUG_ASSERT
-  assert(test);
-#endif
+  typedef std::ios_base::fmtflags fmtflags;
+  typedef std::ios_base::iostate iostate;
+  locale loc_c = locale::classic();
+  locale loc_de("de_DE");
+  std::ios ios_01(NULL);
+  std::ios ios_02(NULL);
+  ios_01.imbue(loc_c);
+  ios_02.imbue(loc_de);
+  ios_02.setstate(ios_base::badbit);
+  VERIFY( loc_c == ios_01.getloc() );
+  VERIFY( loc_de == ios_02.getloc() );
+
+  iostate ios1 = ios_01.rdstate();
+  iostate ios2 = ios_02.rdstate();
+  streambuf* sb1 = ios_01.rdbuf();
+  streambuf* sb2 = ios_02.rdbuf();
+  ios_01.copyfmt(ios_02);
+
+  VERIFY( loc_de == ios_01.getloc() );
+  VERIFY( ios_01.getloc() == ios_02.getloc() );
+  VERIFY( ios1 == ios_01.rdstate() );
+  VERIFY( ios2 == ios_02.rdstate() );
+  VERIFY( sb1 == ios_01.rdbuf() );
+  VERIFY( sb2 == ios_02.rdbuf() );
 }
 
-int main() {
+int main() 
+{
   test01();
   test02();
+  test03();
   return 0;
 }
-- 
GitLab