Commit a5834d1b by Benjamin Kosnik Committed by Benjamin Kosnik

codecvt.h: Implement codecvt<wchar_t, char, mbstate_t>.


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
parent 199acebb
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> 2000-08-21 Gabriel Dos Reis <gdr@merlin.codesourcery.com>
* bits/std_cmath.h (std::abs): Overload for int and long. * bits/std_cmath.h (std::abs): Overload for int and long.
......
...@@ -82,8 +82,8 @@ namespace std { ...@@ -82,8 +82,8 @@ namespace std {
compare(const char_type* __s1, const char_type* __s2, size_t __n) compare(const char_type* __s1, const char_type* __s2, size_t __n)
{ {
for (size_t __i = 0; __i < __n; ++__i) for (size_t __i = 0; __i < __n; ++__i)
if (!eq(__s1[__i],__s2[__i])) if (!eq(__s1[__i], __s2[__i]))
return lt(__s1[__i],__s2[__i]) ? -1 : 1; return lt(__s1[__i], __s2[__i]) ? -1 : 1;
return 0; return 0;
} }
......
...@@ -39,9 +39,8 @@ ...@@ -39,9 +39,8 @@
#define _CPP_BITS_CODECVT_H 1 #define _CPP_BITS_CODECVT_H 1
#ifdef _GLIBCPP_USE_WCHAR_T #ifdef _GLIBCPP_USE_WCHAR_T
// #include <localefwd.h>
// XXX include iconv here or higher up....
#include <iconv.h> // For iconv, iconv_t #include <iconv.h> // For iconv, iconv_t
#include <langinfo.h>
#endif #endif
namespace std namespace std
...@@ -53,16 +52,14 @@ namespace std ...@@ -53,16 +52,14 @@ namespace std
// including conversions and comparisons between various character // including conversions and comparisons between various character
// sets. This object encapsulates data that may need to be shared between // sets. This object encapsulates data that may need to be shared between
// char_traits, codecvt and ctype. // char_traits, codecvt and ctype.
template<typename _InternT, typename _ExternT>
class __enc_traits class __enc_traits
{ {
public: public:
// Types: // Types:
typedef _InternT __intc_type;
typedef _ExternT __extc_type;
typedef iconv_t __conv_type; typedef iconv_t __conv_type;
typedef mbstate_t __state_type; typedef mbstate_t __state_type;
protected:
// Data Members: // Data Members:
// Max size of charset encoding name // Max size of charset encoding name
static const int __max_size = 32; static const int __max_size = 32;
...@@ -72,62 +69,71 @@ namespace std ...@@ -72,62 +69,71 @@ namespace std
char __extc_enc[__max_size]; char __extc_enc[__max_size];
// Conversion descriptor between external encoding to internal encoding. // Conversion descriptor between external encoding to internal encoding.
__conv_type __in_conv; __conv_type __in_desc;
// Conversion descriptor between internal encoding to external encoding. // 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 // __intc_end = whatever we are using internally, which is
// UCS4 (linux) // 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... // XXX Currently don't know how to get this data from target system...
strcpy(__intc_enc, "UCS4"); strcpy(__intc_enc, "UCS4");
// __extc_end = external codeset in current locale // __extc_end = external codeset in current locale
strcpy(__extc_enc, nl_langinfo(CODESET)); 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) __enc_traits(const char* __int, const char* __ext)
: __in_desc(0), __out_desc(0)
{ {
strcpy(__intc_enc, __int); strcpy(__intc_enc, __int);
strcpy(__extc_enc, __ext); 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) ~__enc_traits()
{
iconv_close(__in_desc);
iconv_close(__out_desc);
}
// Initializes
void
_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. // XXX Extended error checking.
} }
} }
~__enc_traits() bool
_M_good()
{ {
iconv_close(__in_conv); return __out_desc && __in_desc
iconv_close(__out_conv); && __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* const char*
_M_get_intc_enc(void) _M_get_internal_enc()
{ return __intc_enc; } { return __intc_enc; }
void
_M_set_intc_enc(const char* __c)
{ strcpy(__intc_enc, __c); }
const char* const char*
_M_get_extc_enc(void) _M_get_external_enc()
{ return __extc_enc; } { return __extc_enc; }
void
_M_set_extc_enc(const char* __c)
{ strcpy(__extc_enc, __c); }
protected: protected:
// 21.1.2 traits typedefs // 21.1.2 traits typedefs
// p4 // p4
...@@ -163,6 +169,7 @@ namespace std ...@@ -163,6 +169,7 @@ namespace std
{ {
public: public:
// Types: // Types:
typedef codecvt_base::result result;
typedef _InternT intern_type; typedef _InternT intern_type;
typedef _ExternT extern_type; typedef _ExternT extern_type;
typedef _StateT state_type; typedef _StateT state_type;
...@@ -171,26 +178,26 @@ namespace std ...@@ -171,26 +178,26 @@ namespace std
result result
out(state_type& __state, const intern_type* __from, out(state_type& __state, const intern_type* __from,
const intern_type* __from_end, const intern_type*& __from_next, 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 extern_type*& __to_next) const
{ {
return this->do_out(__state, __from, __from_end, __from_next, return this->do_out(__state, __from, __from_end, __from_next,
__to, __to_limit, __to_next); __to, __to_end, __to_next);
} }
result 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 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 result
in(state_type& __state, const extern_type* __from, in(state_type& __state, const extern_type* __from,
const extern_type* __from_end, const extern_type*& __from_next, 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 intern_type*& __to_next) const
{ {
return this->do_in(__state, __from, __from_end, __from_next, return this->do_in(__state, __from, __from_end, __from_next,
__to, __to_limit, __to_next); __to, __to_end, __to_next);
} }
int int
...@@ -220,17 +227,17 @@ namespace std ...@@ -220,17 +227,17 @@ namespace std
virtual result virtual result
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, 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; extern_type*& __to_next) const = 0;
virtual result virtual result
do_unshift(state_type& __state, extern_type* __to, 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 virtual result
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, 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; intern_type*& __to_next) const = 0;
virtual int virtual int
...@@ -255,6 +262,7 @@ namespace std ...@@ -255,6 +262,7 @@ namespace std
{ {
public: public:
// Types: // Types:
typedef codecvt_base::result result;
typedef _InternT intern_type; typedef _InternT intern_type;
typedef _ExternT extern_type; typedef _ExternT extern_type;
typedef _StateT state_type; typedef _StateT state_type;
...@@ -275,11 +283,219 @@ namespace std ...@@ -275,11 +283,219 @@ namespace std
locale::id codecvt<_InternT, _ExternT, _StateT>::id; locale::id codecvt<_InternT, _ExternT, _StateT>::id;
// partial specialization // partial specialization
// This specialization takes advantage of iconv to provide code
// conversions between a large number of character encodings.
template<typename _InternT, typename _ExternT> template<typename _InternT, typename _ExternT>
class codecvt<_InternT, _ExternT, __enc_traits<_InternT, _ExternT> > class codecvt<_InternT, _ExternT, __enc_traits>
: public __codecvt_abstract_base<_InternT, : public __codecvt_abstract_base<_InternT, _ExternT, __enc_traits>
_ExternT, __enc_traits<_InternT, _ExternT> > {
{ }; 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 // codecvt<char, char, mbstate_t> required specialization
template<> template<>
...@@ -305,17 +521,17 @@ namespace std ...@@ -305,17 +521,17 @@ namespace std
virtual result virtual result
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, 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; extern_type*& __to_next) const;
virtual result virtual result
do_unshift(state_type& __state, extern_type* __to, 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 virtual result
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, 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; intern_type*& __to_next) const;
virtual int virtual int
...@@ -357,19 +573,19 @@ namespace std ...@@ -357,19 +573,19 @@ namespace std
virtual result virtual result
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, 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; extern_type*& __to_next) const;
virtual result virtual result
do_unshift(state_type& __state, do_unshift(state_type& __state,
extern_type* __to, extern_type* __to_limit, extern_type* __to, extern_type* __to_end,
extern_type*& __to_next) const; extern_type*& __to_next) const;
virtual result virtual result
do_in(state_type& __state, do_in(state_type& __state,
const extern_type* __from, const extern_type* __from_end, const extern_type* __from, const extern_type* __from_end,
const extern_type*& __from_next, const extern_type*& __from_next,
intern_type* __to, intern_type* __to_limit, intern_type* __to, intern_type* __to_end,
intern_type*& __to_next) const; intern_type*& __to_next) const;
virtual virtual
......
...@@ -389,7 +389,7 @@ namespace std ...@@ -389,7 +389,7 @@ namespace std
template<> template<>
const ctype<char>& const ctype<char>&
use_facet<const ctype<char> > (const locale& __loc); use_facet<const ctype<char> >(const locale& __loc);
#ifdef _GLIBCPP_USE_WCHAR_T #ifdef _GLIBCPP_USE_WCHAR_T
// ctype<wchar_t> specialization // ctype<wchar_t> specialization
...@@ -455,7 +455,7 @@ namespace std ...@@ -455,7 +455,7 @@ namespace std
template<> template<>
const ctype<wchar_t>& 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 #endif //_GLIBCPP_USE_WCHAR_T
// Include host-specific ctype specializations. // Include host-specific ctype specializations.
...@@ -1615,66 +1615,66 @@ namespace std ...@@ -1615,66 +1615,66 @@ namespace std
template<typename _CharT> template<typename _CharT>
inline bool inline bool
isspace(_CharT __c, const locale& __loc) 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> template<typename _CharT>
inline bool inline bool
isprint(_CharT __c, const locale& __loc) 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> template<typename _CharT>
inline bool inline bool
iscntrl(_CharT __c, const locale& __loc) 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> template<typename _CharT>
inline bool inline bool
isupper(_CharT __c, const locale& __loc) 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> template<typename _CharT>
inline bool islower(_CharT __c, const locale& __loc) 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> template<typename _CharT>
inline bool inline bool
isalpha(_CharT __c, const locale& __loc) 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> template<typename _CharT>
inline bool inline bool
isdigit(_CharT __c, const locale& __loc) 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> template<typename _CharT>
inline bool inline bool
ispunct(_CharT __c, const locale& __loc) 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> template<typename _CharT>
inline bool inline bool
isxdigit(_CharT __c, const locale& __loc) 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> template<typename _CharT>
inline bool inline bool
isalnum(_CharT __c, const locale& __loc) 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> template<typename _CharT>
inline bool inline bool
isgraph(_CharT __c, const locale& __loc) 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> template<typename _CharT>
inline _CharT inline _CharT
toupper(_CharT __c, const locale& __loc) 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> template<typename _CharT>
inline _CharT inline _CharT
tolower(_CharT __c, const locale& __loc) tolower(_CharT __c, const locale& __loc)
{ return use_facet<ctype<_CharT> > (__loc).tolower(__c); } { return use_facet<ctype<_CharT> >(__loc).tolower(__c); }
} // namespace std } // namespace std
......
...@@ -35,10 +35,10 @@ ...@@ -35,10 +35,10 @@
#include <bits/std_cerrno.h> #include <bits/std_cerrno.h>
#include <bits/std_cstdlib.h> // For strof, strtold #include <bits/std_cstdlib.h> // For strof, strtold
#include <bits/std_limits.h> // For numeric_limits #include <bits/std_limits.h> // For numeric_limits
#include <bits/std_vector.h>
#include <bits/std_memory.h> // For auto_ptr #include <bits/std_memory.h> // For auto_ptr
#include <bits/sbuf_iter.h> // For streambuf_iterators #include <bits/sbuf_iter.h> // For streambuf_iterators
#include <bits/std_cctype.h> // For isspace #include <bits/std_cctype.h> // For isspace
#include <bits/std_vector.h>
namespace std namespace std
{ {
...@@ -69,12 +69,12 @@ namespace std ...@@ -69,12 +69,12 @@ namespace std
const _Facet& const _Facet&
use_facet(const locale& __loc) use_facet(const locale& __loc)
{ {
typedef locale::_Impl::__vec_facet __vec_facet;
const locale::facet* __fp = (const _Facet*)0; // check derivation const locale::facet* __fp = (const _Facet*)0; // check derivation
locale::id& __id = _Facet::id; // check member id locale::id& __id = _Facet::id; // check member id
size_t __i = __id._M_index; size_t __i = __id._M_index;
const locale::_Impl* __tmp = __loc._M_impl; __vec_facet* __facet = __loc._M_impl->_M_facets;
if (__id._M_index >= __loc._M_impl->_M_facets->size() if (__i >= __facet->size() || (__fp = (*(__facet))[__i]) == 0)
|| (__fp = (*(__tmp->_M_facets))[__i]) == 0)
return _Use_facet_failure_handler<_Facet>(__loc); return _Use_facet_failure_handler<_Facet>(__loc);
return static_cast<const _Facet&>(*__fp); return static_cast<const _Facet&>(*__fp);
} }
...@@ -86,8 +86,8 @@ namespace std ...@@ -86,8 +86,8 @@ namespace std
typedef locale::_Impl::__vec_facet __vec_facet; typedef locale::_Impl::__vec_facet __vec_facet;
locale::id& __id = _Facet::id; // check member id locale::id& __id = _Facet::id; // check member id
size_t __i = __id._M_index; size_t __i = __id._M_index;
__vec_facet* __tmpv = __loc._M_impl->_M_facets; __vec_facet* __facet = __loc._M_impl->_M_facets;
return (__i < __tmpv->size() && (*__tmpv)[__i] != 0); return (__i < __facet->size() && (*__facet)[__i] != 0);
} }
// __match_parallel // __match_parallel
...@@ -405,7 +405,6 @@ namespace std ...@@ -405,7 +405,6 @@ namespace std
// We now seek "units", i.e. digits and thousands separators. // We now seek "units", i.e. digits and thousands separators.
// We may need to know if anything is found here. A leading zero // We may need to know if anything is found here. A leading zero
// (removed by now) would count. // (removed by now) would count.
bool __testunits = __testzero; bool __testunits = __testzero;
while (__valid && __beg != __end) while (__valid && __beg != __end)
{ {
......
...@@ -67,14 +67,6 @@ namespace std ...@@ -67,14 +67,6 @@ namespace std
template<typename _Tp, typename _Alloc> class vector; template<typename _Tp, typename _Alloc> class vector;
class locale; 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 // 22.1.3 Convenience interfaces
template<typename _CharT> template<typename _CharT>
inline bool inline bool
...@@ -289,10 +281,14 @@ namespace std ...@@ -289,10 +281,14 @@ namespace std
classic(); classic();
private: private:
_Impl* _M_impl; // The (shared) implementation // The (shared) implementation
_Impl* _M_impl;
static _Impl* _S_classic; // The one true C reference locale // The one true C reference locale
static _Impl* _S_global; // Current global reference locale static _Impl* _S_classic;
// Current global reference locale
static _Impl* _S_global;
explicit explicit
locale(_Impl*) throw(); locale(_Impl*) throw();
...@@ -312,10 +308,11 @@ namespace std ...@@ -312,10 +308,11 @@ namespace std
// locale implementation object // locale implementation object
class locale::_Impl class locale::_Impl
{ {
// Types.
typedef vector<facet*, allocator<facet*> > __vec_facet; typedef vector<facet*, allocator<facet*> > __vec_facet;
typedef vector<string, allocator<string> > __vec_string; typedef vector<string, allocator<string> > __vec_string;
// Friends: // Friends.
friend class locale; friend class locale;
friend class facet; friend class facet;
...@@ -327,6 +324,7 @@ namespace std ...@@ -327,6 +324,7 @@ namespace std
friend bool friend bool
has_facet(const locale&) throw(); has_facet(const locale&) throw();
// Data Members.
size_t _M_num_references; size_t _M_num_references;
__vec_facet* _M_facets; __vec_facet* _M_facets;
__vec_string* _M_category_names; __vec_string* _M_category_names;
...@@ -467,11 +465,13 @@ namespace std ...@@ -467,11 +465,13 @@ namespace std
public: public:
id() {}; id() {};
private: 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 // before the constructor is run; the effect of calling a member
// function (even an inline) would be undefined. // function (even an inline) would be undefined.
mutable size_t _M_index; mutable size_t _M_index;
static size_t _S_highwater; // last id number assigned
// Last id number assigned
static size_t _S_highwater;
void void
operator=(const id&); // not defined operator=(const id&); // not defined
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
namespace std { namespace std {
// codecvt<char, char, mbstate_t> required specialization
locale::id codecvt<char, char, mbstate_t>::id; locale::id codecvt<char, char, mbstate_t>::id;
codecvt<char, char, mbstate_t>:: codecvt<char, char, mbstate_t>::
...@@ -48,10 +49,8 @@ namespace std { ...@@ -48,10 +49,8 @@ namespace std {
extern_type* __to, extern_type* __to_end, extern_type* __to, extern_type* __to_end,
extern_type*& __to_next) const extern_type*& __to_next) const
{ {
size_t __sizefrom = __from_end - __from; size_t __len = min(__from_end - __from, __to_end - __to);
size_t __sizeto = __to_end - __to; memcpy(__to, __from, __len);
size_t __length = __sizefrom <= __sizeto ? __sizefrom : __sizeto;
memcpy(__to, __from, __length);
__from_next = __from; __from_next = __from;
__to_next = __to; __to_next = __to;
return noconv; return noconv;
...@@ -60,7 +59,7 @@ namespace std { ...@@ -60,7 +59,7 @@ namespace std {
codecvt_base::result codecvt_base::result
codecvt<char, char, mbstate_t>:: codecvt<char, char, mbstate_t>::
do_unshift(state_type& /*__state*/, extern_type* __to, 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; __to_next = __to;
return noconv; return noconv;
...@@ -73,10 +72,8 @@ namespace std { ...@@ -73,10 +72,8 @@ namespace std {
intern_type* __to, intern_type* __to_end, intern_type* __to, intern_type* __to_end,
intern_type*& __to_next) const intern_type*& __to_next) const
{ {
size_t __sizefrom = __from_end - __from; size_t __len = min(__from_end - __from, __to_end - __to);
size_t __sizeto = __to_end - __to; memcpy(__to, __from, __len);
size_t __length = __sizefrom <= __sizeto ? __sizefrom : __sizeto;
memcpy(__to, __from, __length);
__from_next = __from; __from_next = __from;
__to_next = __to; __to_next = __to;
return noconv; return noconv;
...@@ -84,21 +81,24 @@ namespace std { ...@@ -84,21 +81,24 @@ namespace std {
int int
codecvt<char, char, mbstate_t>:: codecvt<char, char, mbstate_t>::
do_encoding() const throw() { return 1; } do_encoding() const throw()
{ return 1; }
bool bool
codecvt<char, char, mbstate_t>:: codecvt<char, char, mbstate_t>::
do_always_noconv() const throw() { return true; } do_always_noconv() const throw()
{ return true; }
int int
codecvt<char, char, mbstate_t>:: codecvt<char, char, mbstate_t>::
do_length (const state_type& /*__state*/, const extern_type* __from, do_length (const state_type& /*__state*/, const extern_type* __from,
const extern_type* __end, size_t __max) const 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 int
codecvt<char, char, mbstate_t>:: 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<char, char, mbstate_t>::
codecvt_byname(const char* /*__s*/, size_t __refs) codecvt_byname(const char* /*__s*/, size_t __refs)
...@@ -108,6 +108,7 @@ namespace std { ...@@ -108,6 +108,7 @@ namespace std {
~codecvt_byname() { } ~codecvt_byname() { }
#ifdef _GLIBCPP_USE_WCHAR_T #ifdef _GLIBCPP_USE_WCHAR_T
// codecvt<wchar_t, char, mbstate_t> required specialization
locale::id codecvt<wchar_t, char, mbstate_t>::id; locale::id codecvt<wchar_t, char, mbstate_t>::id;
codecvt<wchar_t, char, mbstate_t>:: codecvt<wchar_t, char, mbstate_t>::
...@@ -119,21 +120,37 @@ namespace std { ...@@ -119,21 +120,37 @@ namespace std {
codecvt_base::result codecvt_base::result
codecvt<wchar_t, char, mbstate_t>:: 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, 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 extern_type*& __to_next) const
{ {
for (; __from < __from_end && __to < __to_limit; ++__from, ++__to) result __ret = error;
*__to = static_cast<char>(*__from); size_t __len = min(__from_end - __from, __to_end - __to);
__from_next = __from; __to_next = __to; size_t __conv = wcsrtombs(__to, &__from, __len, &__state);
return __from == __from_end ? ok : partial;
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_base::result
codecvt<wchar_t, char, mbstate_t>:: codecvt<wchar_t, char, mbstate_t>::
do_unshift (state_type& /*__state*/, extern_type* __to, 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; __to_next = __to;
return noconv; return noconv;
...@@ -141,22 +158,37 @@ namespace std { ...@@ -141,22 +158,37 @@ namespace std {
codecvt_base::result codecvt_base::result
codecvt<wchar_t, char, mbstate_t>:: 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, 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 intern_type*& __to_next) const
{ {
for (; __from < __from_end && __to < __to_limit; ++__from, ++__to) result __ret = error;
*__to = static_cast<wchar_t>(*__from); size_t __len = min(__from_end - __from, __to_end - __to);
size_t __conv = mbsrtowcs(__to, &__from, __len, &__state);
if (__conv == __len)
{
__from_next = __from; __from_next = __from;
__to_next = __to; __to_next = __to + __conv;
return __from == __from_end ? ok : partial; __ret = ok;
}
else if (__conv > 0 && __conv < __len)
{
__from_next = __from;
__to_next = __to + __conv;
__ret = partial;
}
else
__ret = error;
return __ret;
} }
int int
codecvt<wchar_t, char, mbstate_t>:: codecvt<wchar_t, char, mbstate_t>::
do_encoding() const throw() do_encoding() const throw()
{ return 1; } { return 0; }
bool bool
codecvt<wchar_t, char, mbstate_t>:: codecvt<wchar_t, char, mbstate_t>::
...@@ -167,10 +199,11 @@ namespace std { ...@@ -167,10 +199,11 @@ namespace std {
codecvt<wchar_t, char, mbstate_t>:: codecvt<wchar_t, char, mbstate_t>::
do_length(const state_type& /*__state*/, const extern_type* __from, do_length(const state_type& /*__state*/, const extern_type* __from,
const extern_type* __end, size_t __max) const 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 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; } { return 1; }
codecvt_byname<wchar_t, char, mbstate_t>:: codecvt_byname<wchar_t, char, mbstate_t>::
......
...@@ -135,6 +135,15 @@ namespace std { ...@@ -135,6 +135,15 @@ namespace std {
// codecvt // codecvt
template class __codecvt_abstract_base<char, char, mbstate_t>; template class __codecvt_abstract_base<char, char, mbstate_t>;
template class __codecvt_abstract_base<wchar_t, 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 // collate
template class _Collate<char>; template class _Collate<char>;
...@@ -160,7 +169,7 @@ namespace std { ...@@ -160,7 +169,7 @@ namespace std {
use_facet<ctype<char> >(const locale& __loc); use_facet<ctype<char> >(const locale& __loc);
template template
const codecvt<char, char, mbstate_t>& const codecvt<char, char, mbstate_t>&
use_facet<codecvt<char, char, mbstate_t> >(locale const &); use_facet<codecvt<char, char, mbstate_t> >(const locale&);
template template
const num_put<char, obuf_iterator>& const num_put<char, obuf_iterator>&
_Use_facet_failure_handler<num_put<char, obuf_iterator> > _Use_facet_failure_handler<num_put<char, obuf_iterator> >
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment