locale_facets.tcc (_S_build_float_format): Move ...
authorBenjamin Kosnik <bkoz@cygnus.com>
Fri, 1 Sep 2000 08:58:07 +0000 (08:58 +0000)
committerBenjamin Kosnik <bkoz@gcc.gnu.org>
Fri, 1 Sep 2000 08:58:07 +0000 (08:58 +0000)
2000-08-31  Benjamin Kosnik  <bkoz@cygnus.com>

* bits/locale_facets.tcc (_S_build_float_format): Move ...
* src/locale.cc: Here.
* bits/locale_facets.tcc (num_get::_M_extract): Clean up generic
definition. Move specialization to ...
* src/locale.cc: Here.
* bits/locale_facets.tcc: Move _Format_cache specializations to ...
* src/locale.cc: Here.
* bits/locale_facets.tcc: Move use_facet<ctype> specializations to ...
* src/locale.cc: Here.

* bits/std_locale.h: Note that locale_facets.tcc should be
included here, for standards conformance. It may increase
compile times though. For the time being, enable.
* testsuite/22_locale/facet.cc: New file, some parts commented out
for the time being.

* mkcheck.in: Append total time to test summary file.

* bits/sbuf_iter.h : Formatting tweaks.

Clean up static const data member definitions.
* src/locale.cc: Add definitions for all missing locale,
locale::_Imp, and locale::id static data members.
(ctype<char>): Add table_size define.
(money_base): Add _S_default_pattern, uglify.
* bits/localefwd.h: Add definitions for static members of _Count_ones.
* bits/locale_facets.h: Tweaks.
* bits/locale_facets.tcc: Tweaks.
* bits/string.tcc: Add definition for npos.
* bits/ios_base.h: Tweaks.
* bits/ios_base.h (ios_base::Init::_M_ios_base_init): Change to
_S_ios_base_init.
* src/ios.cc: And here. Add _S_local_words definition.
Add definitions for __ios_flags const static data.
* src/codecvt.cc: Same for __enc_traits.
* src/locale-inst.cc: Remove money_base data member definition
here.

From-SVN: r36093

13 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/bits/ios_base.h
libstdc++-v3/bits/locale_facets.h
libstdc++-v3/bits/locale_facets.tcc
libstdc++-v3/bits/localefwd.h
libstdc++-v3/bits/sbuf_iter.h
libstdc++-v3/bits/std_locale.h
libstdc++-v3/bits/string.tcc
libstdc++-v3/src/codecvt.cc
libstdc++-v3/src/ios.cc
libstdc++-v3/src/locale-inst.cc
libstdc++-v3/src/locale.cc
libstdc++-v3/testsuite/22_locale/facet.cc [new file with mode: 0644]

index 3c27ef4..ce44272 100644 (file)
@@ -1,3 +1,43 @@
+2000-08-31  Benjamin Kosnik  <bkoz@cygnus.com>
+
+       * bits/locale_facets.tcc (_S_build_float_format): Move ...      
+       * src/locale.cc: Here.          
+       * bits/locale_facets.tcc (num_get::_M_extract): Clean up generic
+       definition. Move specialization to ...
+       * src/locale.cc: Here.  
+       * bits/locale_facets.tcc: Move _Format_cache specializations to ...
+       * src/locale.cc: Here.
+       * bits/locale_facets.tcc: Move use_facet<ctype> specializations to ...
+       * src/locale.cc: Here.
+
+       * bits/std_locale.h: Note that locale_facets.tcc should be
+       included here, for standards conformance. It may increase
+       compile times though. For the time being, enable.
+       * testsuite/22_locale/facet.cc: New file, some parts commented out
+       for the time being.
+
+       * mkcheck.in: Append total time to test summary file.
+
+       * bits/sbuf_iter.h : Formatting tweaks.
+
+       Clean up static const data member definitions.
+       * src/locale.cc: Add definitions for all missing locale,
+       locale::_Imp, and locale::id static data members.
+       (ctype<char>): Add table_size define.
+       (money_base): Add _S_default_pattern, uglify.
+       * bits/localefwd.h: Add definitions for static members of _Count_ones.
+       * bits/locale_facets.h: Tweaks.
+       * bits/locale_facets.tcc: Tweaks.       
+       * bits/string.tcc: Add definition for npos.
+       * bits/ios_base.h: Tweaks.
+       * bits/ios_base.h (ios_base::Init::_M_ios_base_init): Change to
+       _S_ios_base_init.
+       * src/ios.cc: And here. Add _S_local_words definition.
+       Add definitions for __ios_flags const static data.
+       * src/codecvt.cc: Same for __enc_traits.
+       * src/locale-inst.cc: Remove money_base data member definition
+       here.
+
 2000-08-30  Benjamin Kosnik  <bkoz@redhat.com>
 
        * testsuite/22_locale/ctype_wchar_t_members.cc (test01): New file.
index f7b8ca9..5946214 100644 (file)
@@ -294,7 +294,7 @@ namespace std {
       Init();
       ~Init();
     private:
-      static int       _M_ios_base_init;
+      static int       _S_ios_base_init;
       filebuf*                 _M_cout;
       filebuf*                 _M_cin;
       filebuf*                 _M_cerr;
index db89124..13def7d 100644 (file)
@@ -755,6 +755,7 @@ namespace std
       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); }      
+
       static locale::id id;
 
     protected:
@@ -762,7 +763,8 @@ namespace std
 
       // This consolidates the extraction, storage and
       // error-processing parts of the do_get(...) overloaded member
-      // functions. NB: this is specialized for char.
+      // 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, 
@@ -1454,7 +1456,7 @@ namespace std
     enum part { none, space, symbol, sign, value };
     struct pattern { char field[4]; };
 
-    static const pattern __default_pattern;
+    static const pattern _S_default_pattern;
   };
 
   template<typename _CharT>
@@ -1513,16 +1515,11 @@ namespace std
 
       virtual pattern      
       do_pos_format() const
-      {
-       return money_base::__default_pattern;
-      }
+      { return money_base::_S_default_pattern; }
 
       virtual pattern      
       do_neg_format() const
-      {
-       return money_base::__default_pattern;
-      }
-
+      { return money_base::_S_default_pattern; }
     };
 
   template<typename _CharT, bool _Intl>
index 44f36e7..199aa16 100644 (file)
@@ -173,20 +173,10 @@ namespace std
     { }
 
   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)
-    { }
+    _Format_cache<char>::_Format_cache();
 
-#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
+    _Format_cache<wchar_t>::_Format_cache();
 
   template<typename _CharT>
     void
@@ -278,7 +268,7 @@ namespace std
   template<typename _CharT, typename _InIter>
     void
     num_get<_CharT, _InIter>::
-    _M_extract(iter_type /*__beg*/, iter_type /*__end*/, ios_base& /*__io*/,
+    _M_extract(_InIter /*__beg*/, _InIter /*__end*/, ios_base& /*__io*/,
                ios_base::iostate& /*__err*/, char* /*__xtrc*/,
                int& /*__base*/, bool /*__fp*/) const
     {
@@ -288,305 +278,13 @@ namespace std
   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);
-      bool __valid = __beg != __end;
-      // Fail quickly if !__valid
-      if (!__valid)
-        {
-          __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]))
-        {
-          __xtrc[__pos++] = __c;
-          ++__beg;
-          __testsign = true;
-          // whitespace may follow a sign
-          while ((__beg != __end) && (isspace(*__beg)))
-            ++__beg;
-
-          // There had better be more to come...
-          if (__beg == __end)
-            {
-              __xtrc[__pos] = '\0';
-              __err |= (ios_base::eofbit | ios_base::failbit);
-              return;
-            }
-        }
-
-      bool __testzero = false;    // Has there been a leading zero?
-
-      // Now check if first character is a zero
-      __c = *__beg;
-      if (__c == __lits[__cache_type::_S_digits])
-        {
-           __testzero = true;
-           ++__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++] = __c;
-               __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
-              __c = *__beg;
-              if ((__c == __lits[__cache_type::_S_x])
-                 || (__c == __lits[__cache_type::_S_X]))
-                {
-                  ++__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 (*__beg == __lits[__cache_type::_S_digits])
-                {
-                  ++__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 (__valid && __beg != __end)
-        {
-          __valid = false;
-          __c = *__beg;
-          const char* __p = strchr(__fmt->_S_literals, __c);
-
-          // NB: strchr returns true for __c == 0x0
-          if (__p && __c)
-            {
-              // Try first for acceptable digit; record it if found
-              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;
-                  ++__sep_pos;
-                  __valid = true;
-                  __testunits = true;
-                }
-            }
-          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;
-                  __valid = true;
-                }
-              else
-                __err |= ios_base::failbit;
-            }
-          if (__valid)
-            ++__beg;
-        }
-
-      // 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);
-
-          // __grp is parsed L to R
-          // 1,222,444 == __grp of "/1/3/3"
-          // __fmt->_M_grouping is parsed R to L
-          // 1,222,444 == __fmt->_M_grouping of "/3" == "/3/3/3"
-          int __i = 0;
-          int __j = 0;
-          const int __len = __fmt->_M_grouping.size();
-          int __n = __grp.size();
-          bool __test = true;
-
-          // Parsed number groupings have to match the
-          // numpunct::grouping string exactly, starting at the
-          // right-most point of the parsed sequence of elements ...
-          while (__test && __i < __n - 1)
-            for (__j = 0; __test && __j < __len && __i < __n - 1; ++__j,++__i)
-              __test &= __fmt->_M_grouping[__j] == __grp[__n - __i - 1];
-          // ... but the last parsed grouping can be <= numpunct
-          // grouping.
-          __j == __len ? __j = 0 : __j;
-          __test &= __fmt->_M_grouping[__j] >= __grp[__n - __i - 1];
-
-          if (!__test)
-            {
-              __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)
-        {
-          __c = *__beg;
-          // 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;
-              // Now we get any digits after the decimal point
-              // There MUST be some if __testunits is false.
-              while (__beg != __end)
-                {
-                  __c = *__beg;
-                  const char* __p = strchr(__fmt->_S_literals, __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;
-                      __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)
-            {
-              __c = *__beg;
-              if ((__c == __lits[__cache_type::_S_ee])
-                   || (__c == __lits[__cache_type::_S_Ee]))
-                {
-                  __xtrc[__pos++] = __c;
-                  ++__beg;
-                  // Now there may be a sign
-                  if (__beg != __end)
-                    {
-                      __c = *__beg;
-                      if ((__c == __lits[__cache_type::_S_minus])
-                          || (__c == __lits[__cache_type::_S_plus]))
-                        {
-                          __xtrc[__pos++] = __c;
-                          ++__beg;
-                          // whitespace may follow a sign
-                          while ((__beg != __end) && (isspace(*__beg)))
-                            ++__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)
-                    {
-                      __c = *__beg;
-                      const char* __p = strchr(__fmt->_S_literals, __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;
-                        }
-                      else
-                        break;
-                    }
-                }
-            }
-          // Finally, that's it for floating point
-        }
-
-      // Finish up
-      __xtrc[__pos] = '\0';
-      if (__beg == __end)
-        __err |= ios_base::eofbit;
-    }
+    _M_extract(istreambuf_iterator<char> __beg, 
+              istreambuf_iterator<char> __end, ios_base& __io, 
+              ios_base::iostate& __err, char* __xtrc, int& __base, 
+              bool __fp) const;
 
+#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
   // NB: This is an unresolved library defect #17
-  // _GLIBCPP_RESOLVE_LIB_DEFECTS
   template<typename _CharT, typename _InIter>
     _InIter
     num_get<_CharT, _InIter>::
@@ -655,6 +353,7 @@ namespace std
 
       return __beg;
     }
+#endif
 
 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
   template<typename _CharT, typename _InIter>
@@ -1063,10 +762,23 @@ namespace std
 
   template <typename _CharT, typename _OutIter>
     _OutIter
-    _S_pad_numeric(_OutIter __s, ios_base::fmtflags __flags,
+    _S_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>
+    _S_pad_numeric(ostreambuf_iterator<_CharT> __s, ios_base::fmtflags __flags,
                    _CharT __fill, int __width, _CharT const* __first,
                    _CharT const* __middle, _CharT const* __last)
     {
+      typedef ostreambuf_iterator<_CharT>      __out_iter;
       int __padding = __width - (__last - __first);
       if (__padding < 0)
         __padding = 0;
@@ -1084,14 +796,14 @@ namespace std
             }
           copy(__first, __middle, __s);
         }
-      _OutIter __s2 = __s;
+      __out_iter __s2 = __s;
 
       if (__padding && __aflags != ios_base::left)
         {
           _S_fill(__s2, __fill, __padding);
           __padding = 0;
         }
-      _OutIter __s3 = copy(__middle, __last, __s2);
+      __out_iter __s3 = copy(__middle, __last, __s2);
       if (__padding)
         _S_fill(__s3, __fill, __padding);
       return __s3;
@@ -1271,56 +983,22 @@ namespace std
     { return _S_format(__s, __io, __fill, false, __v); }
 #endif
 
-  // 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
-  _S_build_float_format(ios_base& __io, char* __fptr, char __modifier,
-                        streamsize __prec)
-  {
-    bool __incl_prec = false;
-    ios_base::fmtflags __flags = __io.flags();
-    *__fptr++ = '%';
-    // [22.2.2.2.2] Table 60
-    if (__flags & ios_base::showpos)
-      *__fptr++ = '+';
-    if (__flags & ios_base::showpoint)
-      *__fptr++ = '#';
-    // As per [22.2.2.2.2.11]
-    if (__flags & ios_base::fixed || __prec > 0)
-      {
-        *__fptr++ = '.';
-        *__fptr++ = '*';
-        __incl_prec = true;
-      }
-    if (__modifier)
-      *__fptr++ = __modifier;
-    ios_base::fmtflags __fltfield = __flags & ios_base::floatfield;
-    // [22.2.2.2.2] Table 58
-    if (__fltfield == ios_base::fixed)
-      *__fptr++ = 'f';
-    else if (__fltfield == ios_base::scientific)
-      *__fptr++ = (__flags & ios_base::uppercase) ? 'E' : 'e';
-    else
-      *__fptr++ = (__flags & ios_base::uppercase) ? 'G' : 'g';
-    *__fptr = '\0';
-    return __incl_prec;
-  }
-
-  template<typename _CharT,typename _OutIter>
-    _OutIter
-    _S_output_float(_OutIter __s, ios_base& __io,_CharT __fill,
+  // Generic helper function
+  template<typename _CharT, typename _OutIter>
+    static _OutIter
+    _S_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>
+    static ostreambuf_iterator<_CharT>
+    _S_output_float(ostreambuf_iterator<_CharT> __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();
@@ -1364,6 +1042,10 @@ namespace std
       return __s;
     }
 
+  bool
+  _S_build_float_format(ios_base& __io, char* __fptr, char __modifier,
+                        streamsize __prec);
+
   template <typename _CharT, typename _OutIter>
     _OutIter
     num_put<_CharT, _OutIter>::
@@ -1454,7 +1136,7 @@ namespace std
 
   template<typename _Dummy>
     const char* const
-    _Weekdaynames<char,_Dummy>::_S_names[14] =
+    _Weekdaynames<char, _Dummy>::_S_names[14] =
     {
       "Sun", "Sunday",
       "Mon", "Monday",   "Tue", "Tuesday", "Wed", "Wednesday",
@@ -1463,12 +1145,12 @@ namespace std
 
 #ifdef _GLIBCPP_USE_WCHAR_T
   template<typename _Dummy>
-    struct _Weekdaynames<wchar_t,_Dummy>
+    struct _Weekdaynames<wchar_t, _Dummy>
     { static const wchar_t* const _S_names[14]; };
 
   template<typename _Dummy>
     const wchar_t* const
-    _Weekdaynames<wchar_t,_Dummy>::_S_names[14] =
+    _Weekdaynames<wchar_t, _Dummy>::_S_names[14] =
     {
       L"Sun", L"Sunday",
       L"Mon", L"Monday",   L"Tue", L"Tuesday", L"Wed", L"Wednesday",
@@ -1576,31 +1258,16 @@ namespace std
     locale::id money_put<_CharT, _OutIter>::id;
 
   template<typename _CharT, bool _Intl>
-    locale::id moneypunct<_CharT,_Intl>::id;
-
-  template<typename _CharT>
-    locale::id messages<_CharT>::id;
+    locale::id moneypunct<_CharT, _Intl>::id;
 
-  template<>
-    const ctype<char>&
-    use_facet<const ctype<char> > (const locale& __loc)
-    {
-      size_t __i = ctype<char>::id._M_index;
-      const locale::_Impl* __tmp = __loc._M_impl;
-      return static_cast<const ctype<char>&>(* (*(__tmp->_M_facets))[__i]);
-    }
+  template<typename _CharT, bool _Intl>
+    const bool moneypunct<_CharT, _Intl>::intl;
 
-#ifdef _GLIBCPP_USE_WCHAR_T
-  template<>
-    const ctype<wchar_t>&
-    use_facet< const ctype<wchar_t> > (const locale& __loc)
-    {
-      size_t __i = ctype<wchar_t>::id._M_index;
-      const locale::_Impl* __tmp = __loc._M_impl;
-      return static_cast<const ctype<wchar_t>&>(* (*(__tmp->_M_facets))[__i]);
-    }
-#endif
+  template<typename _CharT, bool _Intl>
+    const bool moneypunct_byname<_CharT, _Intl>::intl;
 
+  template<typename _CharT>
+    locale::id messages<_CharT>::id;
 } // std::
 
 #endif /* _CPP_BITS_LOCFACETS_TCC */
index 23347be..e7cbd1d 100644 (file)
@@ -45,23 +45,32 @@ namespace std
   // _Count_ones: compile-time computation of number of 1-bits in a value N
   // This takes only 5 (or 6) instantiations, doing recursive descent
   // in parallel -- ncm
-  template<unsigned _Num, int _Shift = (sizeof(unsigned) * CHAR_BIT)/2,
-           unsigned _Mask = (~0u >> _Shift) >
+  template<unsigned int _Num, int _Shift = (sizeof(unsigned) * CHAR_BIT)/2,
+           unsigned int _Mask = (~0u >> _Shift) >
     struct _Count_ones;
 
-  template<unsigned _Num, unsigned _Mask>
-    struct _Count_ones<_Num,0,_Mask> 
-    { static const unsigned _S_count = _Num; };
+  template<unsigned int _Num, unsigned int _Mask>
+    struct _Count_ones<_Num, 0, _Mask> 
+    { static const unsigned int _S_count = _Num; };
 
-  template<unsigned _Num, int _Shift, unsigned _Mask>
+  template<unsigned int _Num, unsigned int _Mask>
+    const unsigned int _Count_ones<_Num, 0, _Mask>::_S_count;
+
+  template<unsigned int _Num, int _Shift, unsigned int _Mask>
     struct _Count_ones 
     {
-      static const unsigned _S_halfcount =
+      static const unsigned int _S_halfcount =
         _Count_ones<_Num, _Shift/2, (_Mask^((~_Mask)>>(_Shift/2))) >::_S_count;
-      static const unsigned _S_count
+      static const unsigned int _S_count
       = (_S_halfcount&_Mask) + ((_S_halfcount>>_Shift)&_Mask);
     };
 
+  template<unsigned int _Num, int _Shift, unsigned int _Mask>
+    const unsigned int _Count_ones<_Num, _Shift, _Mask>::_S_count;
+
+  template<unsigned int _Num, int _Shift, unsigned int _Mask>
+    const unsigned int _Count_ones<_Num, _Shift, _Mask>::_S_halfcount;
+
   // 22.1.1 Locale
   template<typename _Tp> class allocator;
   template<typename _Tp, typename _Alloc> class vector;
index 1463479..7a0e1d5 100644 (file)
@@ -38,7 +38,7 @@ namespace std
   template<typename _CharT, typename _Traits>
     class ostreambuf_iterator
 #if 0      // XXX this is standard:
-    : public iterator<output_iterator_tag,_CharT,void,void,void>
+    : public iterator<output_iterator_tag, _CharT, void, void, void>
 #else
     : public output_iterator
 #endif
index dc3c9aa..7eaba90 100644 (file)
@@ -36,6 +36,7 @@
 
 #include <bits/localefwd.h>
 #include <bits/locale_facets.h>
+#include <bits/locale_facets.tcc>
 #include <bits/codecvt.h>
 
 #endif
index 20838e5..c8857f6 100644 (file)
@@ -53,6 +53,17 @@ namespace std
     basic_string<_CharT, _Traits, _Alloc>::
     _Rep::_S_max_size = (((npos - sizeof(_Rep))/sizeof(_CharT)) - 1) / 4;
 
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    const basic_string<_CharT, _Traits, _Alloc>::size_type
+    basic_string<_CharT, _Traits, _Alloc>::npos;
+
+  // Linker sets _S_empty_rep_storage to all 0s (one reference, empty string)
+  // at static init time (before static ctors are run).
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    basic_string<_CharT, _Traits, _Alloc>::size_type
+    basic_string<_CharT, _Traits, _Alloc>::_S_empty_rep_storage[
+    (sizeof(_Rep) + sizeof(_CharT) + sizeof(size_type) - 1)/sizeof(size_type)];
+
   // NB: This is the special case for Input Iterators, used in
   // istreambuf_iterators, etc.
   // Input Iterators have a cost structure very different from
@@ -396,13 +407,6 @@ namespace std
       return 2 * (__s <= 16 ? 16 : __s) < __r;
     }
   
-  // Linker sets _S_empty_rep_storage to all 0s (one reference, empty string)
-  // at static init time (before static ctors are run).
-  template<typename _CharT, typename _Traits, typename _Alloc>
-    basic_string<_CharT, _Traits, _Alloc>::size_type
-    basic_string<_CharT, _Traits, _Alloc>::_S_empty_rep_storage[
-    (sizeof(_Rep) + sizeof(_CharT) + sizeof(size_type) - 1)/sizeof(size_type)];
-
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
     basic_string<_CharT, _Traits, _Alloc>::resize(size_type __n, _CharT __c)
index 09f372e..839a976 100644 (file)
@@ -31,6 +31,9 @@
 
 namespace std {
 
+  // Definitions for static const data members of __enc_traits.
+  const int __enc_traits::_S_max_size;
+
   // codecvt<char, char, mbstate_t> required specialization
   locale::id codecvt<char, char, mbstate_t>::id;
 
index af0ba56..ea8fecd 100644 (file)
@@ -1,6 +1,6 @@
 // Iostreams base classes -*- C++ -*-
 
-// Copyright (C) 1997-1999 Free Software Foundation, Inc.
+// Copyright (C) 1997, 1998, 1999, 2000 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
 
 namespace std {
 
-  // Out-of-line definitions for static const ios_base members.
+  // Definitions for static const data members of __ios_flags.
+  const __ios_flags::__int_type __ios_flags::_S_boolalpha;
+  const __ios_flags::__int_type __ios_flags::_S_dec;
+  const __ios_flags::__int_type __ios_flags::_S_fixed;
+  const __ios_flags::__int_type __ios_flags::_S_hex;
+  const __ios_flags::__int_type __ios_flags::_S_internal;
+  const __ios_flags::__int_type __ios_flags::_S_left;
+  const __ios_flags::__int_type __ios_flags::_S_oct;
+  const __ios_flags::__int_type __ios_flags::_S_right;
+  const __ios_flags::__int_type __ios_flags::_S_scientific;
+  const __ios_flags::__int_type __ios_flags::_S_showbase;
+  const __ios_flags::__int_type __ios_flags::_S_showpoint;
+  const __ios_flags::__int_type __ios_flags::_S_showpos;
+  const __ios_flags::__int_type __ios_flags::_S_skipws;
+  const __ios_flags::__int_type __ios_flags::_S_unitbuf;
+  const __ios_flags::__int_type __ios_flags::_S_uppercase;
+  const __ios_flags::__int_type __ios_flags::_S_adjustfield;
+  const __ios_flags::__int_type __ios_flags::_S_basefield;
+  const __ios_flags::__int_type __ios_flags::_S_floatfield;
+
+  const __ios_flags::__int_type __ios_flags::_S_badbit;
+  const __ios_flags::__int_type __ios_flags::_S_eofbit;
+  const __ios_flags::__int_type __ios_flags::_S_failbit;
+
+  const __ios_flags::__int_type __ios_flags::_S_app;
+  const __ios_flags::__int_type __ios_flags::_S_ate;
+  const __ios_flags::__int_type __ios_flags::_S_bin;
+  const __ios_flags::__int_type __ios_flags::_S_in;
+  const __ios_flags::__int_type __ios_flags::_S_out;
+  const __ios_flags::__int_type __ios_flags::_S_trunc;
+
+  // Definitions for static const members of ios_base.
   const ios_base::fmtflags ios_base::boolalpha;
   const ios_base::fmtflags ios_base::dec;
   const ios_base::fmtflags ios_base::fixed;
@@ -73,17 +104,19 @@ namespace std {
   const ios_base::seekdir ios_base::cur;
   const ios_base::seekdir ios_base::end;
 
+  int ios_base::Init::_S_ios_base_init = 0;
+
+  const int ios_base::_S_local_words;
+
   ios_base::failure::failure(const string& __str)
   {
     strncpy(_M_name, __str.c_str(), _M_bufsize);
     _M_name[_M_bufsize - 1] = '\0';
   }
 
-  int ios_base::Init::_M_ios_base_init = 0;
-
   ios_base::Init::Init()
   {
-    if (++_M_ios_base_init == 1)
+    if (++_S_ios_base_init == 1)
       {
        // NB: std_iostream.h creates the four standard files with
        // default buffers. At this point, we swap out the default
@@ -124,7 +157,7 @@ namespace std {
 
   ios_base::Init::~Init()
   {
-    if (--_M_ios_base_init == 0)
+    if (--_S_ios_base_init == 0)
       {
        cout.flush();
        cerr.flush();
index 7a0af35..20ff88d 100644 (file)
@@ -50,10 +50,6 @@ namespace std {
   typedef istreambuf_iterator<wchar_t, char_traits<wchar_t> > wibuf_iterator;
 
   // moneypunct, money_get, and money_put
-
-  const money_base::pattern
-    money_base::__default_pattern = {{symbol, sign, none, value}};
-
   template class moneypunct<char, false>;
   template class moneypunct<char, true>;
   template class moneypunct_byname<char, false>;
index 7f9a9ff..2359de8 100644 (file)
 #endif
 namespace std {
 
+  // Definitions for static const data members of locale.
+  const locale::category locale::none;
+  const locale::category locale::collate;
+  const locale::category locale::ctype;
+  const locale::category locale::monetary;
+  const locale::category locale::numeric;
+  const locale::category locale::time;
+  const locale::category locale::messages;
+  const locale::category locale::all;
+
+  locale::_Impl* locale::_S_global;  // init'd to 0 before static ctors run
+  locale::_Impl* locale::_S_classic; // init'd to 0 before static ctors run
+  const int locale::_S_num_categories;
+
+  // Definitions for static const data members of locale::_Impl
+  const locale::id* const
+  locale::_Impl::_S_id_collate[] =
+  {
+    &std::collate<char>::id,
+#ifdef _GLIBCPP_USE_WCHAR_T
+    &std::collate<wchar_t>::id,
+#endif
+    0
+  };
+  
+  const locale::id* const
+  locale::_Impl::_S_id_ctype[] =
+  {
+    &std::ctype<char>::id, 
+#ifdef _GLIBCPP_USE_WCHAR_T
+    &std::ctype<wchar_t>::id,
+#endif
+    &std::codecvt<char, char, mbstate_t>::id,
+#ifdef _GLIBCPP_USE_WCHAR_T
+    &std::codecvt<wchar_t, char, mbstate_t>::id,
+#endif
+    0
+  };
+
+  const locale::id* const
+  locale::_Impl::_S_id_monetary[] =
+  {
+    &std::moneypunct<char, false>::id, 
+#ifdef _GLIBCPP_USE_WCHAR_T
+    &std::moneypunct<wchar_t, false>::id,
+#endif
+    &std::moneypunct<char,true >::id, 
+#ifdef _GLIBCPP_USE_WCHAR_T
+    &std::moneypunct<wchar_t,true >::id,
+#endif
+    &std::money_get<char>::id,        
+#ifdef _GLIBCPP_USE_WCHAR_T
+    &std::money_get<wchar_t>::id,
+#endif
+    &std::money_put<char>::id,        
+#ifdef _GLIBCPP_USE_WCHAR_T
+    &std::money_put<wchar_t>::id,
+#endif
+    0
+  };
+
+  const locale::id* const
+  locale::_Impl::_S_id_numeric[] =
+  {
+    &std::numpunct<char>::id, 
+#ifdef _GLIBCPP_USE_WCHAR_T
+    &std::numpunct<wchar_t>::id,
+#endif
+    &std::num_get<char>::id,  
+ #ifdef _GLIBCPP_USE_WCHAR_T
+    &std::num_get<wchar_t>::id,
+#endif
+    &std::num_put<char>::id,  
+#ifdef _GLIBCPP_USE_WCHAR_T
+    &std::num_put<wchar_t>::id,
+#endif
+    0
+  };
+  
+  const locale::id* const
+  locale::_Impl::_S_id_time[] =
+  {
+    &std::time_get<char>::id, 
+#ifdef _GLIBCPP_USE_WCHAR_T
+    &std::time_get<wchar_t>::id,
+#endif
+    &std::time_put<char>::id, 
+#ifdef _GLIBCPP_USE_WCHAR_T
+    &std::time_put<wchar_t>::id,
+#endif
+    0
+  };
+  
+  const locale::id* const
+  locale::_Impl::_S_id_messages[] =
+  {
+    &std::time_get<char>::id, 
+#ifdef _GLIBCPP_USE_WCHAR_T
+    &std::time_get<wchar_t>::id,
+#endif
+    &std::time_put<char>::id, 
+#ifdef _GLIBCPP_USE_WCHAR_T
+    &std::time_put<wchar_t>::id,
+#endif
+    0
+  };
+  
+  const locale::id* const* const
+  locale::_Impl::_S_facet_categories[] =
+  {
+    //  order must match the decl order in class locale.
+    locale::_Impl::_S_id_collate,
+    locale::_Impl::_S_id_ctype,
+    locale::_Impl::_S_id_monetary,
+    locale::_Impl::_S_id_numeric,
+    locale::_Impl::_S_id_time,
+    locale::_Impl::_S_id_messages,
+    0
+  };
+
+  // Definitions for static const data members of locale::id
+  size_t locale::id::_S_highwater;  // init'd to 0 by linker
+
+  // Definitions for static const data members of money_base
+  const money_base::pattern 
+  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<const ctype<char> > (const locale& __loc)
+    {
+      size_t __i = ctype<char>::id._M_index;
+      const locale::_Impl* __tmp = __loc._M_impl;
+      return static_cast<const ctype<char>&>(* (*(__tmp->_M_facets))[__i]);
+    }
+
+#ifdef _GLIBCPP_USE_WCHAR_T
+  template<>
+    const ctype<wchar_t>&
+    use_facet< const ctype<wchar_t> > (const locale& __loc)
+    {
+      size_t __i = ctype<wchar_t>::id._M_index;
+      const locale::_Impl* __tmp = __loc._M_impl;
+      return static_cast<const ctype<wchar_t>&>(* (*(__tmp->_M_facets))[__i]);
+    }
+#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);
+      bool __valid = __beg != __end;
+      // Fail quickly if !__valid
+      if (!__valid)
+        {
+          __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]))
+        {
+          __xtrc[__pos++] = __c;
+          ++__beg;
+          __testsign = true;
+          // whitespace may follow a sign
+          while ((__beg != __end) && (isspace(*__beg)))
+            ++__beg;
+
+          // There had better be more to come...
+          if (__beg == __end)
+            {
+              __xtrc[__pos] = '\0';
+              __err |= (ios_base::eofbit | ios_base::failbit);
+              return;
+            }
+        }
+
+      bool __testzero = false;    // Has there been a leading zero?
+
+      // Now check if first character is a zero
+      __c = *__beg;
+      if (__c == __lits[__cache_type::_S_digits])
+        {
+           __testzero = true;
+           ++__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++] = __c;
+               __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
+              __c = *__beg;
+              if ((__c == __lits[__cache_type::_S_x])
+                 || (__c == __lits[__cache_type::_S_X]))
+                {
+                  ++__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 (*__beg == __lits[__cache_type::_S_digits])
+                {
+                  ++__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 (__valid && __beg != __end)
+        {
+          __valid = false;
+          __c = *__beg;
+          const char* __p = strchr(__fmt->_S_literals, __c);
+
+          // NB: strchr returns true for __c == 0x0
+          if (__p && __c)
+            {
+              // Try first for acceptable digit; record it if found
+              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;
+                  ++__sep_pos;
+                  __valid = true;
+                  __testunits = true;
+                }
+            }
+          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;
+                  __valid = true;
+                }
+              else
+                __err |= ios_base::failbit;
+            }
+          if (__valid)
+            ++__beg;
+        }
+
+      // 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);
+
+          // __grp is parsed L to R
+          // 1,222,444 == __grp of "/1/3/3"
+          // __fmt->_M_grouping is parsed R to L
+          // 1,222,444 == __fmt->_M_grouping of "/3" == "/3/3/3"
+          int __i = 0;
+          int __j = 0;
+          const int __len = __fmt->_M_grouping.size();
+          int __n = __grp.size();
+          bool __test = true;
+
+          // Parsed number groupings have to match the
+          // numpunct::grouping string exactly, starting at the
+          // right-most point of the parsed sequence of elements ...
+          while (__test && __i < __n - 1)
+            for (__j = 0; __test && __j < __len && __i < __n - 1; ++__j,++__i)
+              __test &= __fmt->_M_grouping[__j] == __grp[__n - __i - 1];
+          // ... but the last parsed grouping can be <= numpunct
+          // grouping.
+          __j == __len ? __j = 0 : __j;
+          __test &= __fmt->_M_grouping[__j] >= __grp[__n - __i - 1];
+
+          if (!__test)
+            {
+              __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)
+        {
+          __c = *__beg;
+          // 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;
+              // Now we get any digits after the decimal point
+              // There MUST be some if __testunits is false.
+              while (__beg != __end)
+                {
+                  __c = *__beg;
+                  const char* __p = strchr(__fmt->_S_literals, __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;
+                      __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)
+            {
+              __c = *__beg;
+              if ((__c == __lits[__cache_type::_S_ee])
+                   || (__c == __lits[__cache_type::_S_Ee]))
+                {
+                  __xtrc[__pos++] = __c;
+                  ++__beg;
+                  // Now there may be a sign
+                  if (__beg != __end)
+                    {
+                      __c = *__beg;
+                      if ((__c == __lits[__cache_type::_S_minus])
+                          || (__c == __lits[__cache_type::_S_plus]))
+                        {
+                          __xtrc[__pos++] = __c;
+                          ++__beg;
+                          // whitespace may follow a sign
+                          while ((__beg != __end) && (isspace(*__beg)))
+                            ++__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)
+                    {
+                      __c = *__beg;
+                      const char* __p = strchr(__fmt->_S_literals, __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;
+                        }
+                      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
+  _S_build_float_format(ios_base& __io, char* __fptr, char __modifier,
+                        streamsize __prec)
+  {
+    bool __incl_prec = false;
+    ios_base::fmtflags __flags = __io.flags();
+    *__fptr++ = '%';
+    // [22.2.2.2.2] Table 60
+    if (__flags & ios_base::showpos)
+      *__fptr++ = '+';
+    if (__flags & ios_base::showpoint)
+      *__fptr++ = '#';
+    // As per [22.2.2.2.2.11]
+    if (__flags & ios_base::fixed || __prec > 0)
+      {
+        *__fptr++ = '.';
+        *__fptr++ = '*';
+        __incl_prec = true;
+      }
+    if (__modifier)
+      *__fptr++ = __modifier;
+    ios_base::fmtflags __fltfield = __flags & ios_base::floatfield;
+    // [22.2.2.2.2] Table 58
+    if (__fltfield == ios_base::fixed)
+      *__fptr++ = 'f';
+    else if (__fltfield == ios_base::scientific)
+      *__fptr++ = (__flags & ios_base::uppercase) ? 'E' : 'e';
+    else
+      *__fptr++ = (__flags & ios_base::uppercase) ? 'G' : 'g';
+    *__fptr = '\0';
+    return __incl_prec;
+  }
+
   // locale::_Impl
   locale::_Impl::
   ~_Impl() throw()
@@ -157,116 +665,7 @@ namespace std {
       __fpr->_M_remove_reference();
     __fpr = __fp;
   }
-
-  // locale facet category descriptions
-  const locale::id* const
-  locale::_Impl::_S_id_collate[] =
-  {
-    &std::collate<char>::id,
-#ifdef _GLIBCPP_USE_WCHAR_T
-    &std::collate<wchar_t>::id,
-#endif
-    0
-  };
-  
-  const locale::id* const
-  locale::_Impl::_S_id_ctype[] =
-  {
-    &std::ctype<char>::id, 
-#ifdef _GLIBCPP_USE_WCHAR_T
-    &std::ctype<wchar_t>::id,
-#endif
-    &std::codecvt<char, char, mbstate_t>::id,
-#ifdef _GLIBCPP_USE_WCHAR_T
-    &std::codecvt<wchar_t, char, mbstate_t>::id,
-#endif
-    0
-  };
-
-  const locale::id* const
-  locale::_Impl::_S_id_monetary[] =
-  {
-    &std::moneypunct<char, false>::id, 
-#ifdef _GLIBCPP_USE_WCHAR_T
-    &std::moneypunct<wchar_t, false>::id,
-#endif
-    &std::moneypunct<char,true >::id, 
-#ifdef _GLIBCPP_USE_WCHAR_T
-    &std::moneypunct<wchar_t,true >::id,
-#endif
-    &std::money_get<char>::id,        
-#ifdef _GLIBCPP_USE_WCHAR_T
-    &std::money_get<wchar_t>::id,
-#endif
-    &std::money_put<char>::id,        
-#ifdef _GLIBCPP_USE_WCHAR_T
-    &std::money_put<wchar_t>::id,
-#endif
-    0
-  };
-
-  const locale::id* const
-  locale::_Impl::_S_id_numeric[] =
-  {
-    &std::numpunct<char>::id, 
-#ifdef _GLIBCPP_USE_WCHAR_T
-    &std::numpunct<wchar_t>::id,
-#endif
-    &std::num_get<char>::id,  
- #ifdef _GLIBCPP_USE_WCHAR_T
-    &std::num_get<wchar_t>::id,
-#endif
-    &std::num_put<char>::id,  
-#ifdef _GLIBCPP_USE_WCHAR_T
-    &std::num_put<wchar_t>::id,
-#endif
-    0
-  };
-  
-  const locale::id* const
-  locale::_Impl::_S_id_time[] =
-  {
-    &std::time_get<char>::id, 
-#ifdef _GLIBCPP_USE_WCHAR_T
-    &std::time_get<wchar_t>::id,
-#endif
-    &std::time_put<char>::id, 
-#ifdef _GLIBCPP_USE_WCHAR_T
-    &std::time_put<wchar_t>::id,
-#endif
-    0
-  };
-  
-  const locale::id* const
-  locale::_Impl::_S_id_messages[] =
-  {
-    &std::time_get<char>::id, 
-#ifdef _GLIBCPP_USE_WCHAR_T
-    &std::time_get<wchar_t>::id,
-#endif
-    &std::time_put<char>::id, 
-#ifdef _GLIBCPP_USE_WCHAR_T
-    &std::time_put<wchar_t>::id,
-#endif
-    0
-  };
-  
-  const locale::id* const* const
-  locale::_Impl::_S_facet_categories[] =
-  {
-    //  order must match the decl order in class locale.
-    locale::_Impl::_S_id_collate,
-    locale::_Impl::_S_id_ctype,
-    locale::_Impl::_S_id_monetary,
-    locale::_Impl::_S_id_numeric,
-    locale::_Impl::_S_id_time,
-    locale::_Impl::_S_id_messages,
-    0
-  };
-  
-  locale::_Impl* locale::_S_global;  // init'd to 0 before static ctors run
-  locale::_Impl* locale::_S_classic; // init'd to 0 before static ctors run
-
   locale::
   locale(_Impl* __ip) throw()
   : _M_impl(__ip)
@@ -457,14 +856,13 @@ namespace std {
   _Bad_use_facet::
   ~_Bad_use_facet() throw() { }
   
-  size_t locale::id::_S_highwater;  // init'd to 0 by linker
-
-
   // Platform-specific initialization code for ctype tables.
   #include <ctype.cc>
 
   locale::id ctype<char>::id;
 
+  const size_t ctype<char>::table_size;
+
   ctype<char>::
   ~ctype()
   { if (_M_del) delete[] this->table(); }
@@ -501,7 +899,6 @@ namespace std {
   : ctype<char>(new mask[table_size], true, __refs)
   { }
 
-
   locale::id collate<char>::id;
 
   collate<char>::collate(size_t __refs)
diff --git a/libstdc++-v3/testsuite/22_locale/facet.cc b/libstdc++-v3/testsuite/22_locale/facet.cc
new file mode 100644 (file)
index 0000000..1930c50
--- /dev/null
@@ -0,0 +1,258 @@
+// 2000-08-31 Benjamin Kosnik <bkoz@redhat.com>
+
+// Copyright (C) 2000 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.1.1.1.2 - class locale::facet [lib.locale.facet]
+
+#include <locale>
+#include <iterator>
+#include <debug_assert.h>
+
+// 1 a class if a facet if it is publicly derived from another facet
+class gnu_input_iterator: public std::iterator<std::input_iterator_tag, char>
+{
+  value_type it;
+public:
+  gnu_input_iterator(value_type orig): it(orig) { }
+
+  value_type 
+  operator*() const { return it; }
+
+  reference
+  operator++(){ return ++it; }
+
+  reference
+  operator++(int){ ++it; return it; }
+};
+
+bool
+operator==(const gnu_input_iterator& lhs, const gnu_input_iterator& rhs)
+{ return true; }
+
+bool
+operator!=(const gnu_input_iterator& lhs, const gnu_input_iterator& rhs)
+{ return true; }
+
+class gnu_output_iterator: public std::iterator<std::output_iterator_tag, char>
+{ 
+  value_type it;
+public:
+  gnu_output_iterator(value_type orig): it(orig) { }
+
+  value_type
+  operator*(){ return it; }
+
+  gnu_output_iterator&
+  operator=(value_type obj){ it = obj; return *this; }
+
+  reference 
+  operator++(){ return ++it; }
+
+  reference 
+  operator++(int){ ++it; return it; }
+
+};
+
+class gnu_collate: public std::collate<char> { }; 
+class gnu_ctype: public std::ctype<char> { }; 
+class gnu_codecvt: public std::codecvt<char, char, mbstate_t> { }; 
+class gnu_moneypunct: public std::moneypunct<char> { }; 
+class gnu_moneypunct_true: public std::moneypunct<char, true> { }; 
+class gnu_money_get: public std::money_get<char> { }; 
+class gnu_money_put: public std::money_put<char> { }; 
+class gnu_numpunct: public std::numpunct<char> { }; 
+class gnu_num_get: public std::num_get<char> { }; 
+class gnu_num_put: public std::num_put<char> { }; 
+class gnu_time_get: public std::time_get<char> { }; 
+class gnu_time_put: public std::time_put<char> { }; 
+class gnu_messages: public std::messages<char> { }; 
+
+class gnu_collate_byname: public std::collate_byname<char> 
+{
+public:
+  explicit
+  gnu_collate_byname(const char* c, size_t refs = 0)
+  : std::collate_byname<char>(c, refs) { }
+}; 
+
+class gnu_ctype_byname: public std::ctype_byname<char> 
+{
+public:
+  explicit
+  gnu_ctype_byname(const char* c, size_t refs = 0)
+  : std::ctype_byname<char>(c, refs) { }
+}; 
+
+class gnu_moneypunct_byname_true: public std::moneypunct_byname<char, true> 
+{
+public:
+  explicit
+  gnu_moneypunct_byname_true(const char* c, size_t refs = 0)
+  : std::moneypunct_byname<char, true>(c, refs) { }
+}; 
+
+class gnu_moneypunct_byname_false: public std::moneypunct_byname<char, false> 
+{
+public:
+  explicit
+  gnu_moneypunct_byname_false(const char* c, size_t refs = 0)
+  : std::moneypunct_byname<char, false>(c, refs) { }
+}; 
+
+
+class gnu_money_get_in: public std::money_get<char, gnu_input_iterator>
+{
+public:
+  explicit
+  gnu_money_get_in(size_t refs = 0)
+  : std::money_get<char, gnu_input_iterator>(refs) { }
+};
+
+class gnu_money_put_out: public std::money_put<char, gnu_output_iterator>
+{
+public:
+  explicit
+  gnu_money_put_out(size_t refs = 0)
+  : std::money_put<char, gnu_output_iterator>(refs) { }
+};
+
+class gnu_numpunct_byname: public std::numpunct_byname<char>
+{
+public:
+  explicit
+  gnu_numpunct_byname(const char* c, size_t refs = 0)
+  : std::numpunct_byname<char>(c, refs) { }
+};
+
+class gnu_num_get_in: public std::num_get<char, gnu_input_iterator> 
+{
+public:
+  explicit
+  gnu_num_get_in(size_t refs = 0)
+  : std::num_get<char, gnu_input_iterator>(refs) { }
+};
+
+class gnu_num_put_out: public std::num_put<char, gnu_output_iterator> 
+{
+public:
+  explicit
+  gnu_num_put_out(size_t refs = 0)
+  : std::num_put<char, gnu_output_iterator>(refs) { }
+};
+
+class gnu_time_get_byname: public std::time_get_byname<char>
+{
+public:
+  explicit
+  gnu_time_get_byname(const char* c, size_t refs = 0)
+  : std::time_get_byname<char>(c, refs) { }
+};
+
+class gnu_time_get_in: public std::time_get<char, gnu_input_iterator>
+{
+public:
+  explicit
+  gnu_time_get_in(size_t refs = 0)
+  : std::time_get<char, gnu_input_iterator>(refs) { }
+};
+
+class gnu_time_put_byname: public std::time_put_byname<char> 
+{
+public:
+  explicit
+  gnu_time_put_byname(const char* c, size_t refs = 0)
+  : std::time_put_byname<char>(c, refs) { }
+};
+
+class gnu_time_put_out: public std::time_put<char, gnu_output_iterator> 
+{
+public:
+  explicit
+  gnu_time_put_out(size_t refs = 0)
+  : std::time_put<char, gnu_output_iterator>(refs) { }
+};
+
+class gnu_messages_byname: public std::messages_byname<char> 
+{
+public:
+  explicit
+  gnu_messages_byname(const char* c, size_t refs = 0)
+  : std::messages_byname<char>(c, refs) { }
+};
+
+
+// 2 or if it is a class deerived from locale:;facet and containing a
+// publicly-accessible declaration as follows:
+class gnu_facet: public std::locale::facet
+{
+public:
+  static std::locale::id id;
+};
+
+std::locale::id gnu_facet::id;
+
+void test01()
+{
+  // 1
+  gnu_collate                  obj01;
+  gnu_ctype                    obj02;
+  gnu_codecvt                  obj03;
+  gnu_moneypunct               obj04;
+  gnu_moneypunct_true          obj05;
+  gnu_money_get                        obj06;
+  gnu_money_put                        obj07;
+  gnu_numpunct                 obj08;
+  gnu_num_get                  obj09;
+  gnu_num_put                  obj10;
+  gnu_time_get                 obj11;
+  gnu_time_put                 obj12;
+  gnu_messages                 obj13;
+  gnu_time_put_out             obj14(0);
+  gnu_time_put_byname          obj15("gnu_message_byname", 0);
+  gnu_time_get_in              obj16(0);
+  gnu_time_get_byname          obj17("gnu_message_byname", 0);
+  // gnu_num_put_out           obj18(0);
+  // gnu_num_get_in            obj19(0);
+  gnu_numpunct_byname          obj20("gnu_message_byname", 0);
+  gnu_money_put_out            obj21(0);
+  gnu_money_get_in             obj22(0);
+  gnu_moneypunct_byname_false  obj23("gnu_message_byname", 0);
+  gnu_moneypunct_byname_true   obj24("gnu_message_byname", 0);
+  gnu_ctype_byname             obj25("gnu_message_byname", 0);
+  gnu_collate_byname           obj26("gnu_message_byname", 0);
+  gnu_messages_byname          obj27("gnu_message_byname", 0);
+
+  // 2
+  gnu_facet                    obj28;
+}
+
+int main ()
+{
+  test01();
+
+  return 0;
+}
+
+
+
+
+
+
+
+