summaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>2000-08-22 08:18:10 +0000
committerbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>2000-08-22 08:18:10 +0000
commit98b638cf622ec29dc67acc06b370078c5b269e4b (patch)
tree5208c08351eec22070a9a231c88f51f4119b3b89 /libstdc++-v3
parentfabd00bc5278e4890a0c9726acde2c5fa192154a (diff)
downloadgcc-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/ChangeLog14
-rw-r--r--libstdc++-v3/bits/char_traits.h4
-rw-r--r--libstdc++-v3/bits/codecvt.h328
-rw-r--r--libstdc++-v3/bits/locale_facets.h30
-rw-r--r--libstdc++-v3/bits/locale_facets.tcc13
-rw-r--r--libstdc++-v3/bits/localefwd.h42
-rw-r--r--libstdc++-v3/src/codecvt.cc97
-rw-r--r--libstdc++-v3/src/locale-inst.cc13
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 &);