diff options
author | bkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-08-22 08:18:10 +0000 |
---|---|---|
committer | bkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-08-22 08:18:10 +0000 |
commit | 98b638cf622ec29dc67acc06b370078c5b269e4b (patch) | |
tree | 5208c08351eec22070a9a231c88f51f4119b3b89 /libstdc++-v3 | |
parent | fabd00bc5278e4890a0c9726acde2c5fa192154a (diff) | |
download | gcc-98b638cf622ec29dc67acc06b370078c5b269e4b.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@35870 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/ChangeLog | 14 | ||||
-rw-r--r-- | libstdc++-v3/bits/char_traits.h | 4 | ||||
-rw-r--r-- | libstdc++-v3/bits/codecvt.h | 328 | ||||
-rw-r--r-- | libstdc++-v3/bits/locale_facets.h | 30 | ||||
-rw-r--r-- | libstdc++-v3/bits/locale_facets.tcc | 13 | ||||
-rw-r--r-- | libstdc++-v3/bits/localefwd.h | 42 | ||||
-rw-r--r-- | libstdc++-v3/src/codecvt.cc | 97 | ||||
-rw-r--r-- | libstdc++-v3/src/locale-inst.cc | 13 |
8 files changed, 406 insertions, 135 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 024a7baa740..f66ac57ddfb 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -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. diff --git a/libstdc++-v3/bits/char_traits.h b/libstdc++-v3/bits/char_traits.h index 7b9516667eb..9d4b4ff58ec 100644 --- a/libstdc++-v3/bits/char_traits.h +++ b/libstdc++-v3/bits/char_traits.h @@ -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; } diff --git a/libstdc++-v3/bits/codecvt.h b/libstdc++-v3/bits/codecvt.h index 90245d639b0..18339025b9b 100644 --- a/libstdc++-v3/bits/codecvt.h +++ b/libstdc++-v3/bits/codecvt.h @@ -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 diff --git a/libstdc++-v3/bits/locale_facets.h b/libstdc++-v3/bits/locale_facets.h index a8bf7bb1381..94950e4dfe8 100644 --- a/libstdc++-v3/bits/locale_facets.h +++ b/libstdc++-v3/bits/locale_facets.h @@ -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 diff --git a/libstdc++-v3/bits/locale_facets.tcc b/libstdc++-v3/bits/locale_facets.tcc index 9d98612da54..44f36e78400 100644 --- a/libstdc++-v3/bits/locale_facets.tcc +++ b/libstdc++-v3/bits/locale_facets.tcc @@ -35,10 +35,10 @@ #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) { diff --git a/libstdc++-v3/bits/localefwd.h b/libstdc++-v3/bits/localefwd.h index 719ad0250ff..23347be37a7 100644 --- a/libstdc++-v3/bits/localefwd.h +++ b/libstdc++-v3/bits/localefwd.h @@ -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 diff --git a/libstdc++-v3/src/codecvt.cc b/libstdc++-v3/src/codecvt.cc index c456b00334e..09f372e522b 100644 --- a/libstdc++-v3/src/codecvt.cc +++ b/libstdc++-v3/src/codecvt.cc @@ -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>:: diff --git a/libstdc++-v3/src/locale-inst.cc b/libstdc++-v3/src/locale-inst.cc index a313aaf68d1..d17f3322adc 100644 --- a/libstdc++-v3/src/locale-inst.cc +++ b/libstdc++-v3/src/locale-inst.cc @@ -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 &); |