codecvt.h: Implement codecvt<wchar_t, char, mbstate_t>.
authorBenjamin Kosnik <bkoz@purist.soma.redhat.com>
Tue, 22 Aug 2000 08:18:10 +0000 (08:18 +0000)
committerBenjamin Kosnik <bkoz@gcc.gnu.org>
Tue, 22 Aug 2000 08:18:10 +0000 (08:18 +0000)
2000-08-21  Benjamin Kosnik  <bkoz@purist.soma.redhat.com>

* bits/codecvt.h: Implement codecvt<wchar_t, char, mbstate_t>. Fix
up __enc_traits template so as to be marginally useful.
* src/codecvt.cc: And here.
* bits/char_traits: Tweak.
* bits/locale_facets.h: Tweak.
* bits/locale_facets.tcc: Tweak.
* bits/localefwd.h: Tweak.
* src/locale-inst.cc: Add use_facet/has_facet instantiations here.
* testsuite/22_locale/codecvt_wchar_t_cc.cc: New file.
* testsuite/22_locale/codecvt_char_char.cc: New file.
* testsuite/22_locale/codecvt_unicode_char.cc: New file.

From-SVN: r35870

libstdc++-v3/ChangeLog
libstdc++-v3/bits/char_traits.h
libstdc++-v3/bits/codecvt.h
libstdc++-v3/bits/locale_facets.h
libstdc++-v3/bits/locale_facets.tcc
libstdc++-v3/bits/localefwd.h
libstdc++-v3/src/codecvt.cc
libstdc++-v3/src/locale-inst.cc

index 024a7ba..f66ac57 100644 (file)
@@ -1,3 +1,17 @@
+2000-08-21  Benjamin Kosnik  <bkoz@purist.soma.redhat.com>
+
+       * bits/codecvt.h: Implement codecvt<wchar_t, char, mbstate_t>. Fix
+       up __enc_traits template so as to be marginally useful.
+       * src/codecvt.cc: And here.
+       * bits/char_traits: Tweak.
+       * bits/locale_facets.h: Tweak.
+       * bits/locale_facets.tcc: Tweak.
+       * bits/localefwd.h: Tweak.
+       * src/locale-inst.cc: Add use_facet/has_facet instantiations here.
+       * testsuite/22_locale/codecvt_wchar_t_cc.cc: New file.
+       * testsuite/22_locale/codecvt_char_char.cc: New file.
+       * testsuite/22_locale/codecvt_unicode_char.cc: New file.
+       
 2000-08-21  Gabriel Dos Reis  <gdr@merlin.codesourcery.com>
 
        * bits/std_cmath.h (std::abs): Overload for int and long.
index 7b95166..9d4b4ff 100644 (file)
@@ -82,8 +82,8 @@ namespace std {
       compare(const char_type* __s1, const char_type* __s2, size_t __n)
       { 
        for (size_t __i = 0; __i < __n; ++__i)
-         if (!eq(__s1[__i],__s2[__i]))
-           return lt(__s1[__i],__s2[__i]) ? -1 : 1;
+         if (!eq(__s1[__i], __s2[__i]))
+           return lt(__s1[__i], __s2[__i]) ? -1 : 1;
        return 0; 
       }
 
index 90245d6..1833902 100644 (file)
@@ -39,9 +39,8 @@
 #define _CPP_BITS_CODECVT_H    1
 
 #ifdef _GLIBCPP_USE_WCHAR_T
-// #include <localefwd.h>
-// XXX include iconv here or higher up.... 
 #include <iconv.h>             // For iconv, iconv_t
+#include <langinfo.h>
 #endif
 
 namespace std
@@ -53,16 +52,14 @@ namespace std
   // including conversions and comparisons between various character
   // sets.  This object encapsulates data that may need to be shared between
   // char_traits, codecvt and ctype.
-  template<typename _InternT, typename _ExternT>
   class __enc_traits
   {
   public:
     // Types:
-    typedef _InternT   __intc_type;
-    typedef _ExternT   __extc_type;
     typedef iconv_t    __conv_type;
     typedef mbstate_t  __state_type;
     
+  protected:
     // Data Members:
     // Max size of charset encoding name
     static const int   __max_size = 32;
@@ -72,62 +69,71 @@ namespace std
     char               __extc_enc[__max_size];
 
     // Conversion descriptor between external encoding to internal encoding.
-    __conv_type                __in_conv;
+    __conv_type                __in_desc;
     // Conversion descriptor between internal encoding to external encoding.
-    __conv_type                __out_conv;
+    __conv_type                __out_desc;
 
-    __enc_traits()
+  public:
+    __enc_traits() : __in_desc(0), __out_desc(0)
     {
       // __intc_end = whatever we are using internally, which is
       // UCS4 (linux) 
-      // UCS2 (microsoft, java, aix, whatever...)
+      // UCS2 == UNICODE  (microsoft, java, aix, whatever...)
       // XXX Currently don't know how to get this data from target system...
       strcpy(__intc_enc, "UCS4");
 
       // __extc_end = external codeset in current locale
       strcpy(__extc_enc, nl_langinfo(CODESET));
-      __in_conv = iconv_open(__intc_enc, __extc_enc);
-      __out_conv = iconv_open(__extc_enc, __intc_enc);
-      if (__out_conv == (iconv_t) -1 || __in_conv == (iconv_t) -1)
-       {
-         // XXX Extended error checking.
-       }
     }
 
     __enc_traits(const char* __int, const char* __ext)
+    : __in_desc(0), __out_desc(0)
     {
       strcpy(__intc_enc, __int);
       strcpy(__extc_enc, __ext);
-      __in_conv = iconv_open(__intc_enc, __extc_enc);
-      __out_conv = iconv_open(__extc_enc, __intc_enc);
-      if (__out_conv == (iconv_t) -1 || __in_conv == (iconv_t) -1)
-       {
-         // XXX Extended error checking.
-       }
     }
 
     ~__enc_traits()
     {
-      iconv_close(__in_conv);
-      iconv_close(__out_conv);
+      iconv_close(__in_desc);
+      iconv_close(__out_desc);
     } 
 
-    const char* 
-    _M_get_intc_enc(void)
-    { return __intc_enc; }
-
+    // Initializes
     void
-    _M_set_intc_enc(const char* __c)
-    { strcpy(__intc_enc, __c); }
+    _M_init()
+    {
+      __in_desc = iconv_open(__intc_enc, __extc_enc);
+      __out_desc = iconv_open(__extc_enc, __intc_enc);
+      if (__out_desc == (iconv_t) -1 || __in_desc == (iconv_t) -1)
+       {
+         // XXX Extended error checking.
+       }
+    }
+
+    bool
+    _M_good()
+    { 
+      return __out_desc && __in_desc 
+            && __out_desc != iconv_t(-1) && __in_desc != iconv_t(-1);
+    }
+
+    const __conv_type* 
+    _M_get_in_descriptor()
+    { return &__in_desc; }
+
+    const __conv_type* 
+    _M_get_out_descriptor()
+    { return &__out_desc; }
+
+   const char* 
+    _M_get_internal_enc()
+    { return __intc_enc; }
 
     const char* 
-    _M_get_extc_enc(void)
+    _M_get_external_enc()
     { return __extc_enc; }
 
-    void
-    _M_set_extc_enc(const char* __c)
-    { strcpy(__extc_enc, __c); }
-   
   protected:
     // 21.1.2 traits typedefs
     // p4
@@ -163,34 +169,35 @@ namespace std
     {
     public:
       // Types:
-      typedef _InternT intern_type;
-      typedef _ExternT extern_type;
-      typedef _StateT  state_type;
+      typedef codecvt_base::result                     result;
+      typedef _InternT                                         intern_type;
+      typedef _ExternT                                         extern_type;
+      typedef _StateT                                          state_type;
       
       // 22.2.1.5.1 codecvt members
       result
       out(state_type& __state, const intern_type* __from, 
          const intern_type* __from_end, const intern_type*& __from_next,
-         extern_type* __to, extern_type* __to_limit
+         extern_type* __to, extern_type* __to_end
          extern_type*& __to_next) const
       { 
        return this->do_out(__state, __from, __from_end, __from_next, 
-                           __to, __to_limit, __to_next); 
+                           __to, __to_end, __to_next); 
       }
 
       result
-      unshift(state_type& __state, extern_type* __to, extern_type* __to_limit,
+      unshift(state_type& __state, extern_type* __to, extern_type* __to_end,
              extern_type*& __to_next) const
-      { return this->do_unshift(__state, __to,__to_limit,__to_next); }
+      { return this->do_unshift(__state, __to,__to_end,__to_next); }
 
       result
       in(state_type& __state, const extern_type* __from, 
         const extern_type* __from_end, const extern_type*& __from_next,
-        intern_type* __to, intern_type* __to_limit
+        intern_type* __to, intern_type* __to_end
         intern_type*& __to_next) const
       { 
        return this->do_in(__state, __from, __from_end, __from_next,
-                          __to, __to_limit, __to_next); 
+                          __to, __to_end, __to_next); 
       }
 
       int 
@@ -220,17 +227,17 @@ namespace std
       virtual result
       do_out(state_type& __state, const intern_type* __from, 
             const intern_type* __from_end, const intern_type*& __from_next,
-            extern_type* __to, extern_type* __to_limit,
+            extern_type* __to, extern_type* __to_end,
             extern_type*& __to_next) const = 0;
 
       virtual result
       do_unshift(state_type& __state, extern_type* __to, 
-                extern_type* __to_limit, extern_type*& __to_next) const = 0;
+                extern_type* __to_end, extern_type*& __to_next) const = 0;
       
       virtual result
       do_in(state_type& __state, const extern_type* __from, 
            const extern_type* __from_end, const extern_type*& __from_next, 
-           intern_type* __to, intern_type* __to_limit
+           intern_type* __to, intern_type* __to_end
            intern_type*& __to_next) const = 0;
       
       virtual int 
@@ -255,6 +262,7 @@ namespace std
     {
     public:      
       // Types:
+      typedef codecvt_base::result                     result;
       typedef _InternT intern_type;
       typedef _ExternT extern_type;
       typedef _StateT  state_type;
@@ -275,11 +283,219 @@ namespace std
     locale::id codecvt<_InternT, _ExternT, _StateT>::id;
 
   // partial specialization
+  // This specialization takes advantage of iconv to provide code
+  // conversions between a large number of character encodings.
   template<typename _InternT, typename _ExternT>
-  class codecvt<_InternT, _ExternT, __enc_traits<_InternT, _ExternT> >
-  : public __codecvt_abstract_base<_InternT, 
-                                  _ExternT, __enc_traits<_InternT, _ExternT> >
-  { };
+    class codecvt<_InternT, _ExternT, __enc_traits>
+    : public __codecvt_abstract_base<_InternT, _ExternT, __enc_traits>
+    {
+    public:      
+      // Types:
+      typedef codecvt_base::result                     result;
+      typedef _InternT                                         intern_type;
+      typedef _ExternT                                         extern_type;
+      typedef __enc_traits                             state_type;
+      typedef __enc_traits::__conv_type                __conv_type;
+      typedef __enc_traits                             __enc_type;
+
+      // Data Members:
+      static locale::id                id;
+
+      explicit 
+      codecvt(size_t __refs = 0)
+      : __codecvt_abstract_base<intern_type, extern_type, state_type>(__refs)
+      { }
+
+      explicit 
+      codecvt(__enc_type* __enc, size_t __refs = 0)
+      : __codecvt_abstract_base<intern_type, extern_type, state_type>(__refs)
+      { }
+
+    protected:
+      virtual 
+      ~codecvt() { }
+
+      virtual result
+      do_out(state_type& __state, const intern_type* __from, 
+            const intern_type* __from_end, const intern_type*& __from_next,
+            extern_type* __to, extern_type* __to_end,
+            extern_type*& __to_next) const;
+
+      virtual result
+      do_unshift(state_type& __state, extern_type* __to, 
+                extern_type* __to_end, extern_type*& __to_next) const;
+
+      virtual result
+      do_in(state_type& __state, const extern_type* __from, 
+           const extern_type* __from_end, const extern_type*& __from_next,
+           intern_type* __to, intern_type* __to_end, 
+           intern_type*& __to_next) const;
+
+      virtual int 
+      do_encoding() const throw();
+
+      virtual bool 
+      do_always_noconv() const throw();
+
+      virtual int 
+      do_length(const state_type&, const extern_type* __from, 
+               const extern_type* __end, size_t __max) const;
+
+      virtual int 
+      do_max_length() const throw();
+    };
+
+  template<typename _InternT, typename _ExternT>
+    locale::id 
+    codecvt<_InternT, _ExternT, __enc_traits>::id;
+
+  template<typename _InternT, typename _ExternT>
+    codecvt_base::result
+    codecvt<_InternT, _ExternT, __enc_traits>::
+    do_out(state_type& __state, const intern_type* __from, 
+          const intern_type* __from_end, const intern_type*& __from_next,
+          extern_type* __to, extern_type* __to_end,
+          extern_type*& __to_next) const
+    {
+      result __ret = error;
+      if (__state._M_good())
+       {
+         typedef state_type::__conv_type       __conv_type;
+         const __conv_type* __desc = __state._M_get_out_descriptor();
+         const size_t __fmultiple = sizeof(intern_type) / sizeof(char);
+         size_t __flen = __fmultiple * (__from_end - __from);
+         const size_t __tmultiple = sizeof(extern_type) / sizeof(char);
+         size_t __tlen = __tmultiple * (__to_end - __to); 
+         
+         // Argument list for iconv specifies a byte sequence. Thus,
+         // all to/from arrays must be brutally casted to char*.
+         const char* __cfrom = reinterpret_cast<const char*>(__from);
+         char* __cto = reinterpret_cast<char*>(__to);
+         size_t __conv = iconv(*__desc, &__cfrom, &__flen, &__cto, &__tlen); 
+         
+         if (__conv != size_t(-1))
+           {
+             __from_next = reinterpret_cast<const intern_type*>(__cfrom);
+             __to_next = reinterpret_cast<extern_type*>(__cto);
+             __ret = ok;
+           }
+         else 
+           {
+             if (__flen < __from_end - __from)
+               {
+                 __from_next = reinterpret_cast<const intern_type*>(__cfrom);
+                 __to_next = reinterpret_cast<extern_type*>(__cto);
+                 __ret = partial;
+               }
+             else
+               __ret = error;
+           }
+       }
+      return __ret; 
+    }
+
+  template<typename _InternT, typename _ExternT>
+    codecvt_base::result
+    codecvt<_InternT, _ExternT, __enc_traits>::
+    do_unshift(state_type& __state, extern_type* __to, 
+              extern_type* __to_end, extern_type*& __to_next) const
+    {
+      result __ret = error;
+      if (__state._M_good())
+       {
+         typedef state_type::__conv_type       __conv_type;
+         const __conv_type* __desc = __state._M_get_in_descriptor();
+         const size_t __tmultiple = sizeof(intern_type) / sizeof(char);
+         size_t __tlen = __tmultiple * (__to_end - __to); 
+         
+         // Argument list for iconv specifies a byte sequence. Thus,
+         // all to/from arrays must be brutally casted to char*.
+         char* __cto = reinterpret_cast<char*>(__to);
+         size_t __conv = iconv(*__desc, NULL, NULL, &__cto, &__tlen); 
+         
+         if (__conv != size_t(-1))
+           {
+             __to_next = reinterpret_cast<extern_type*>(__cto);
+             __ret = ok;
+           }
+         else 
+           __ret = error;
+       }
+      return __ret; 
+    }
+   
+  template<typename _InternT, typename _ExternT>
+    codecvt_base::result
+    codecvt<_InternT, _ExternT, __enc_traits>::
+    do_in(state_type& __state, const extern_type* __from, 
+         const extern_type* __from_end, const extern_type*& __from_next,
+         intern_type* __to, intern_type* __to_end, 
+         intern_type*& __to_next) const
+    { 
+      result __ret = error;
+      if (__state._M_good())
+       {
+         typedef state_type::__conv_type       __conv_type;
+         const __conv_type* __desc = __state._M_get_in_descriptor();
+         const size_t __fmultiple = sizeof(extern_type) / sizeof(char);
+         size_t __flen = __fmultiple * (__from_end - __from);
+         const size_t __tmultiple = sizeof(intern_type) / sizeof(char);
+         size_t __tlen = __tmultiple * (__to_end - __to); 
+         
+         // Argument list for iconv specifies a byte sequence. Thus,
+         // all to/from arrays must be brutally casted to char*.
+         const char* __cfrom = reinterpret_cast<const char*>(__from);
+         char* __cto = reinterpret_cast<char*>(__to);
+         size_t __conv = iconv(*__desc, &__cfrom, &__flen, &__cto, &__tlen); 
+         
+         if (__conv != size_t(-1))
+           {
+             __from_next = reinterpret_cast<const extern_type*>(__cfrom);
+             __to_next = reinterpret_cast<intern_type*>(__cto);
+             __ret = ok;
+           }
+         else 
+           {
+             if (__flen < __from_end - __from)
+               {
+                 __from_next = reinterpret_cast<const extern_type*>(__cfrom);
+                 __to_next = reinterpret_cast<intern_type*>(__cto);
+                 __ret = partial;
+               }
+             else
+               __ret = error;
+           }
+       }
+      return __ret; 
+    }
+  
+  template<typename _InternT, typename _ExternT>
+    int 
+    codecvt<_InternT, _ExternT, __enc_traits>::
+    do_encoding() const throw()
+    { return 0; }
+  
+  template<typename _InternT, typename _ExternT>
+    bool 
+    codecvt<_InternT, _ExternT, __enc_traits>::
+    do_always_noconv() const throw()
+    { return false; }
+  
+  template<typename _InternT, typename _ExternT>
+    int 
+    codecvt<_InternT, _ExternT, __enc_traits>::
+    do_length(const state_type& __state, const extern_type* __from, 
+             const extern_type* __end, size_t __max) const
+    { return min(__max, static_cast<size_t>(__end - __from)); }
+
+#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
+// 74.  Garbled text for codecvt::do_max_length
+  template<typename _InternT, typename _ExternT>
+    int 
+    codecvt<_InternT, _ExternT, __enc_traits>::
+    do_max_length() const throw()
+    { return 1; }
+#endif
 
   // codecvt<char, char, mbstate_t> required specialization
   template<>
@@ -305,17 +521,17 @@ namespace std
       virtual result
       do_out(state_type& __state, const intern_type* __from, 
             const intern_type* __from_end, const intern_type*& __from_next,
-            extern_type* __to, extern_type* __to_limit,
+            extern_type* __to, extern_type* __to_end,
             extern_type*& __to_next) const;
 
       virtual result
       do_unshift(state_type& __state, extern_type* __to, 
-                extern_type* __to_limit, extern_type*& __to_next) const;
+                extern_type* __to_end, extern_type*& __to_next) const;
 
       virtual result
       do_in(state_type& __state, const extern_type* __from, 
            const extern_type* __from_end, const extern_type*& __from_next,
-           intern_type* __to, intern_type* __to_limit
+           intern_type* __to, intern_type* __to_end
            intern_type*& __to_next) const;
 
       virtual int 
@@ -357,19 +573,19 @@ namespace std
       virtual result
       do_out(state_type& __state, const intern_type* __from, 
             const intern_type* __from_end, const intern_type*& __from_next,
-            extern_type* __to, extern_type* __to_limit,
+            extern_type* __to, extern_type* __to_end,
             extern_type*& __to_next) const;
 
       virtual result
       do_unshift(state_type& __state,
-                extern_type* __to, extern_type* __to_limit,
+                extern_type* __to, extern_type* __to_end,
                 extern_type*& __to_next) const;
 
       virtual result
       do_in(state_type& __state,
             const extern_type* __from, const extern_type* __from_end,
             const extern_type*& __from_next,
-            intern_type* __to, intern_type* __to_limit,
+            intern_type* __to, intern_type* __to_end,
             intern_type*& __to_next) const;
 
       virtual 
index a8bf7bb..94950e4 100644 (file)
@@ -389,7 +389,7 @@ namespace std
  
   template<>
     const ctype<char>&
-    use_facet<const ctype<char> > (const locale& __loc);
+    use_facet<const ctype<char> >(const locale& __loc);
 
 #ifdef _GLIBCPP_USE_WCHAR_T
   // ctype<wchar_t> specialization
@@ -455,7 +455,7 @@ namespace std
 
   template<>
     const ctype<wchar_t>&
-    use_facet< const ctype<wchar_t> > (const locale& __loc);
+    use_facet< const ctype<wchar_t> >(const locale& __loc);
 #endif //_GLIBCPP_USE_WCHAR_T
 
   // Include host-specific ctype specializations.
@@ -1615,66 +1615,66 @@ namespace std
   template<typename _CharT>
     inline bool 
     isspace(_CharT __c, const locale& __loc)
-    { return use_facet<ctype<_CharT> > (__loc).is(ctype_base::space, __c); }
+    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c); }
 
   template<typename _CharT>
     inline bool 
     isprint(_CharT __c, const locale& __loc)
-    { return use_facet<ctype<_CharT> > (__loc).is(ctype_base::print, __c); }
+    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c); }
 
   template<typename _CharT>
     inline bool 
     iscntrl(_CharT __c, const locale& __loc)
-    { return use_facet<ctype<_CharT> > (__loc).is(ctype_base::cntrl, __c); }
+    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c); }
 
   template<typename _CharT>
     inline bool 
     isupper(_CharT __c, const locale& __loc)
-    { return use_facet<ctype<_CharT> > (__loc).is(ctype_base::upper, __c); }
+    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c); }
 
   template<typename _CharT>
     inline bool islower(_CharT __c, const locale& __loc)
-    { return use_facet<ctype<_CharT> > (__loc).is(ctype_base::lower, __c); }
+    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c); }
 
   template<typename _CharT>
     inline bool 
     isalpha(_CharT __c, const locale& __loc)
-    { return use_facet<ctype<_CharT> > (__loc).is(ctype_base::alpha, __c); }
+    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c); }
 
   template<typename _CharT>
     inline bool 
     isdigit(_CharT __c, const locale& __loc)
-    { return use_facet<ctype<_CharT> > (__loc).is(ctype_base::digit, __c); }
+    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c); }
 
   template<typename _CharT>
     inline bool 
     ispunct(_CharT __c, const locale& __loc)
-    { return use_facet<ctype<_CharT> > (__loc).is(ctype_base::punct, __c); }
+    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c); }
 
   template<typename _CharT>
     inline bool 
     isxdigit(_CharT __c, const locale& __loc)
-    { return use_facet<ctype<_CharT> > (__loc).is(ctype_base::xdigit, __c); }
+    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c); }
 
   template<typename _CharT>
     inline bool 
     isalnum(_CharT __c, const locale& __loc)
-    { return use_facet<ctype<_CharT> > (__loc).is(ctype_base::alnum, __c); }
+    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c); }
 
   template<typename _CharT>
     inline bool 
     isgraph(_CharT __c, const locale& __loc)
-    { return use_facet<ctype<_CharT> > (__loc).is(ctype_base::graph, __c); }
+    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c); }
 
   template<typename _CharT>
     inline _CharT 
     toupper(_CharT __c, const locale& __loc)
-    { return use_facet<ctype<_CharT> > (__loc).toupper(__c); }
+    { return use_facet<ctype<_CharT> >(__loc).toupper(__c); }
 
   template<typename _CharT>
     inline _CharT 
     tolower(_CharT __c, const locale& __loc)
-    { return use_facet<ctype<_CharT> > (__loc).tolower(__c); }
+    { return use_facet<ctype<_CharT> >(__loc).tolower(__c); }
 
 } // namespace std
 
index 9d98612..44f36e7 100644 (file)
 #include <bits/std_cerrno.h>
 #include <bits/std_cstdlib.h>   // For strof, strtold
 #include <bits/std_limits.h>    // For numeric_limits
-#include <bits/std_vector.h>
 #include <bits/std_memory.h>    // For auto_ptr
 #include <bits/sbuf_iter.h>     // For streambuf_iterators
 #include <bits/std_cctype.h>    // For isspace
+#include <bits/std_vector.h>   
 
 namespace std
 {
@@ -69,12 +69,12 @@ namespace std
     const _Facet&
     use_facet(const locale& __loc)
     {
+      typedef locale::_Impl::__vec_facet        __vec_facet;
       const locale::facet* __fp = (const _Facet*)0;    // check derivation
       locale::id& __id = _Facet::id;         // check member id
       size_t __i = __id._M_index;
-      const locale::_Impl* __tmp = __loc._M_impl;
-      if (__id._M_index >= __loc._M_impl->_M_facets->size()
-          || (__fp = (*(__tmp->_M_facets))[__i]) == 0)
+      __vec_facet* __facet = __loc._M_impl->_M_facets;
+      if (__i >= __facet->size() || (__fp = (*(__facet))[__i]) == 0)
         return _Use_facet_failure_handler<_Facet>(__loc);
       return static_cast<const _Facet&>(*__fp);
     }
@@ -86,8 +86,8 @@ namespace std
       typedef locale::_Impl::__vec_facet        __vec_facet;
       locale::id& __id = _Facet::id;         // check member id
       size_t __i = __id._M_index;
-      __vec_facet* __tmpv = __loc._M_impl->_M_facets;
-      return (__i < __tmpv->size() && (*__tmpv)[__i] != 0);
+      __vec_facet* __facet = __loc._M_impl->_M_facets;
+      return (__i < __facet->size() && (*__facet)[__i] != 0);
     }
 
   // __match_parallel
@@ -405,7 +405,6 @@ namespace std
       // 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)
         {
index 719ad02..23347be 100644 (file)
@@ -67,14 +67,6 @@ namespace std
   template<typename _Tp, typename _Alloc> class vector;
   class locale;
 
-  template<typename _Facet>
-    const _Facet&  
-    use_facet(const locale&);
-
-  template<typename _Facet>
-    bool           
-    has_facet(const locale&) throw();
-
   // 22.1.3 Convenience interfaces
   template<typename _CharT> 
     inline bool 
@@ -289,10 +281,14 @@ namespace std
     classic();
 
   private:
-    _Impl* _M_impl;  // The (shared) implementation
+    // The (shared) implementation
+    _Impl*             _M_impl;  
 
-    static _Impl* _S_classic; // The one true C reference locale
-    static _Impl* _S_global;  // Current global reference locale
+    // The one true C reference locale
+    static _Impl*      _S_classic; 
+
+    // Current global reference locale
+    static _Impl*      _S_global;  
 
     explicit 
     locale(_Impl*) throw();
@@ -312,10 +308,11 @@ namespace std
   // locale implementation object
   class locale::_Impl
   {
+    // Types.
     typedef vector<facet*, allocator<facet*> > __vec_facet;
     typedef vector<string, allocator<string> > __vec_string;
 
-    // Friends:
+    // Friends.
     friend class locale;
     friend class facet;
 
@@ -327,12 +324,13 @@ namespace std
       friend bool  
       has_facet(const locale&) throw();
 
-    size_t _M_num_references;
-    __vec_facet* _M_facets;
-    __vec_string* _M_category_names;
-    bool _M_has_name;
-    bool _M_cached_name_ok;
-    string _M_cached_name;
+    // Data Members.
+    size_t             _M_num_references;
+    __vec_facet*       _M_facets;
+    __vec_string*      _M_category_names;
+    bool               _M_has_name;
+    bool               _M_cached_name_ok;
+    string             _M_cached_name;
 
     inline void 
     _M_add_reference() throw()
@@ -467,11 +465,13 @@ namespace std
   public:
     id() {};
   private:
-    // NB: there is no accessor for _M_index because it may be used
+    // NB: There is no accessor for _M_index because it may be used
     // before the constructor is run; the effect of calling a member
     // function (even an inline) would be undefined.
-    mutable size_t _M_index;
-    static size_t _S_highwater;   // last id number assigned
+    mutable size_t     _M_index;
+
+    // Last id number assigned
+    static size_t      _S_highwater;   
 
     void 
     operator=(const id&);  // not defined
index c456b00..09f372e 100644 (file)
@@ -31,6 +31,7 @@
 
 namespace std {
 
+  // codecvt<char, char, mbstate_t> required specialization
   locale::id codecvt<char, char, mbstate_t>::id;
 
   codecvt<char, char, mbstate_t>::
@@ -48,10 +49,8 @@ namespace std {
         extern_type* __to, extern_type* __to_end, 
         extern_type*& __to_next) const
   { 
-    size_t __sizefrom = __from_end - __from;
-    size_t __sizeto = __to_end - __to;
-    size_t __length = __sizefrom <= __sizeto ? __sizefrom : __sizeto;
-    memcpy(__to, __from, __length);
+    size_t __len = min(__from_end - __from, __to_end - __to);
+    memcpy(__to, __from, __len);
     __from_next = __from; 
     __to_next = __to;
     return noconv;  
@@ -60,7 +59,7 @@ namespace std {
   codecvt_base::result
   codecvt<char, char, mbstate_t>::
   do_unshift(state_type& /*__state*/, extern_type* __to,
-             extern_type* /*__to_limit*/, extern_type*& __to_next) const
+             extern_type* /*__to_end*/, extern_type*& __to_next) const
   { 
     __to_next = __to; 
     return noconv; 
@@ -73,10 +72,8 @@ namespace std {
        intern_type* __to, intern_type* __to_end, 
        intern_type*& __to_next) const
   { 
-    size_t __sizefrom = __from_end - __from;
-    size_t __sizeto = __to_end - __to;
-    size_t __length = __sizefrom <= __sizeto ? __sizefrom : __sizeto;
-    memcpy(__to, __from, __length);
+    size_t __len = min(__from_end - __from, __to_end - __to);
+    memcpy(__to, __from, __len);
     __from_next = __from; 
     __to_next = __to;
     return noconv;  
@@ -84,21 +81,24 @@ namespace std {
 
   int 
   codecvt<char, char, mbstate_t>::
-  do_encoding() const throw() { return 1; }
+  do_encoding() const throw() 
+  { return 1; }
   
   bool 
   codecvt<char, char, mbstate_t>::
-  do_always_noconv() const throw() { return true; }
+  do_always_noconv() const throw() 
+  { return true; }
   
   int 
   codecvt<char, char, mbstate_t>::
   do_length (const state_type& /*__state*/, const extern_type* __from,
             const extern_type* __end, size_t __max) const
-  { return (__max < size_t(__end - __from)) ? __max : __end - __from; }
+  { return min(__max, static_cast<size_t>(__end - __from)); }
   
   int 
   codecvt<char, char, mbstate_t>::
-  do_max_length() const throw() { return 1; }
+  do_max_length() const throw() 
+  { return 1; }
   
   codecvt_byname<char, char, mbstate_t>::
   codecvt_byname(const char* /*__s*/, size_t __refs)
@@ -108,6 +108,7 @@ namespace std {
   ~codecvt_byname() { }
 
 #ifdef _GLIBCPP_USE_WCHAR_T
+  // codecvt<wchar_t, char, mbstate_t> required specialization
   locale::id codecvt<wchar_t, char, mbstate_t>::id;
 
   codecvt<wchar_t, char, mbstate_t>::
@@ -119,21 +120,37 @@ namespace std {
   
   codecvt_base::result
   codecvt<wchar_t, char, mbstate_t>::
-  do_out(state_type& /*__state*/, const intern_type* __from, 
+  do_out(state_type& __state, const intern_type* __from, 
         const intern_type* __from_end, const intern_type*& __from_next,
-        extern_type* __to, extern_type* __to_limit,
+        extern_type* __to, extern_type* __to_end,
         extern_type*& __to_next) const
   {
-    for (; __from < __from_end && __to < __to_limit; ++__from, ++__to)
-      *__to = static_cast<char>(*__from);
-    __from_next = __from; __to_next = __to;
-    return __from == __from_end ? ok : partial;
+    result __ret = error;
+    size_t __len = min(__from_end - __from, __to_end - __to);
+    size_t __conv = wcsrtombs(__to, &__from, __len, &__state);
+
+    if (__conv == __len)
+      {
+       __from_next = __from;
+       __to_next = __to + __conv;
+       __ret = ok;
+      }
+    else if (__conv > 0 && __conv < __len)
+      {
+       __from_next = __from;
+       __to_next = __to + __conv;
+       __ret = partial;
+      }
+    else
+      __ret = error;
+       
+    return __ret; 
   }
   
   codecvt_base::result
   codecvt<wchar_t, char, mbstate_t>::
-  do_unshift (state_type& /*__state*/, extern_type* __to,
-              extern_type* /*__to_limit*/, extern_type*& __to_next) const
+  do_unshift(state_type& /*__state*/, extern_type* __to,
+            extern_type* /*__to_end*/, extern_type*& __to_next) const
   {
     __to_next = __to;
     return noconv;
@@ -141,22 +158,37 @@ namespace std {
   
   codecvt_base::result
   codecvt<wchar_t, char, mbstate_t>::
-  do_in(state_type& /*__state*/, const extern_type* __from, 
+  do_in(state_type& __state, const extern_type* __from, 
        const extern_type* __from_end, const extern_type*& __from_next,
-       intern_type* __to, intern_type* __to_limit,
+       intern_type* __to, intern_type* __to_end,
        intern_type*& __to_next) const
   {
-    for (; __from < __from_end && __to < __to_limit; ++__from, ++__to)
-      *__to = static_cast<wchar_t>(*__from);
-    __from_next = __from; 
-    __to_next = __to;
-    return __from == __from_end ? ok : partial;
+    result __ret = error;
+    size_t __len = min(__from_end - __from, __to_end - __to);
+    size_t __conv = mbsrtowcs(__to, &__from, __len, &__state);
+
+    if (__conv == __len)
+      {
+       __from_next = __from;
+       __to_next = __to + __conv;
+       __ret = ok;
+      }
+    else if (__conv > 0 && __conv < __len)
+      {
+       __from_next = __from;
+       __to_next = __to + __conv;
+       __ret = partial;
+      }
+    else
+      __ret = error;
+       
+    return __ret; 
   }
   
   int 
   codecvt<wchar_t, char, mbstate_t>::
   do_encoding() const throw()
-  { return 1; }
+  { return 0; }
   
   bool 
   codecvt<wchar_t, char, mbstate_t>::
@@ -167,10 +199,11 @@ namespace std {
   codecvt<wchar_t, char, mbstate_t>::
   do_length(const state_type& /*__state*/, const extern_type* __from,
            const extern_type* __end, size_t __max) const
-  { return (__max < size_t(__end - __from)) ? __max : __end - __from; }
-  
+  { return min(__max, static_cast<size_t>(__end - __from)); }
+
   int 
-  codecvt<wchar_t, char, mbstate_t>::do_max_length() const throw()
+  codecvt<wchar_t, char, mbstate_t>::
+  do_max_length() const throw()
   { return 1; }
 
   codecvt_byname<wchar_t, char, mbstate_t>::
index a313aaf..d17f332 100644 (file)
@@ -135,6 +135,15 @@ namespace std {
   // codecvt
   template class __codecvt_abstract_base<char, char, mbstate_t>;
   template class __codecvt_abstract_base<wchar_t, char, mbstate_t>;
+#ifdef _GLIBCPP_USE_WCHAR_T
+  typedef unsigned short                       unicode_t;
+  template
+    const codecvt<unicode_t, char, __enc_traits>& 
+    use_facet<codecvt<unicode_t, char, __enc_traits> >(const locale&);
+  template 
+    bool
+    has_facet<codecvt<unicode_t, char, __enc_traits> >(const locale &);
+#endif
 
   // collate
   template class _Collate<char>;
@@ -160,8 +169,8 @@ namespace std {
     use_facet<ctype<char> >(const locale& __loc);
   template
     const codecvt<char, char, mbstate_t>& 
-    use_facet<codecvt<char, char, mbstate_t> >(locale const &);
-  template 
+    use_facet<codecvt<char, char, mbstate_t> >(const locale&);
+   template 
     const num_put<char, obuf_iterator>& 
     _Use_facet_failure_handler<num_put<char, obuf_iterator> >
     (const locale &);