Numeric facets cleanup.

2001-11-27  Benjamin Kosnik  <bkoz@redhat.com>

	Numeric facets cleanup.
	* include/bits/locale_facets.h (__num_base::_S_atoms): Add, remove
	+ and - signs.
	(__num_base::_M_zero): Add
	(__num_base::_M_e): Add.
	(__num_base::_M_E): Add.
	* include/bits/locale_facets.tcc (num_get::_M_extract): Remove.
	(num_get::_M_extract_float): New.
	(num_get::_M_extract_int): New.
	* src/locale.cc (num_get::_M_extract): Remove.

	* include/bits/locale_facets.tcc (num_put::_M_insert_float):
	Simplify, use _M_insert.
	(num_put::do_put(bool)): Simplify, remove __pad.
	(__pad): Remove.
	(__pad_output): Change to __pad.
	* include/bits/ostream.tcc: And here.
	* src/locale-inst: Remove instantiations.

	* include/bits/locale_facets.h: Move helper functions in to class
	num_put.
	(num_put::_M_insert_float): Same, for __output_integer.
	(num_put::_M_insert_int): Same, for __output_float.
	(num_put::_M_insert): New.
	(__num_base): Add.
	(__num_base::_S_format_float): Move
	__build_float_format into class __num_base.
	(__num_base::_S_format_int): Move __build_int_format into class
	__num_base.
	* include/bits/locale_facets.tcc (__group_digits): Change to
	(__add_grouping): This.
	* src/locale-inst.cc: And here. Tweak instantiations.
	* src/misc-inst.cc: Remove instantiations.

	* include/bits/ostream.tcc (__pad_char): Rename, adjust inserters
	for new calling conventions, move to...
	* include/bits/locale_facets.tcc (__pad_output): Here. Adjust
	signature to make it useful for both ostream and num_put.
	(__pad_numeric): Remove.
	* src/misc-inst.cc: Remove instantiations.
	* src/locale-inst.cc: Same.

	* include/bits/locale_facets.h (_Numeric_get): Remove.
 	(_Numeric_put): Remove.
	(num_get::get(short)): Remove.
	(num_get::get(int)): Remove.
	(num_get::do_get(short)): Remove.
	(num_get::do_get(int)): Remove.
	* include/bits/istream.tcc (istream::operator>>(short)): Fix as
	per DR 118.
	(istream::operator>>(int)): Same.

	* include/bits/locale_facets.h (_Format_cache): Remove.
	* include/bits/locale_facets.tcc: Same.
	* src/locale.cc: Same.
	* src/locale-inst.cc: Same.
	* include/bits/ostream.tcc: Same.
	* src/ios.cc (ios_base::imbue): Remove here as well.

	* testsuite/22_locale/num_get.cc: New file.
	* testsuite/22_locale/num_get_members_char.cc: New file.
	* testsuite/22_locale/num_get_members_wchar_t.cc: New.
	* testsuite/22_locale/numpunct_members_wchar_t.cc: New file.
	* testsuite/22_locale/num_put.cc: New file.
	* testsuite/22_locale/num_put_members_char.cc: New file.
	* testsuite/22_locale/num_put_members_wchar_t.cc: New file.
	* testsuite/27_io/ostream_inserter_arith.cc: Fix.
	* testsuite/27_io/istream_extractor_arith.cc: Fix.

From-SVN: r47397
This commit is contained in:
Benjamin Kosnik 2001-11-28 04:07:11 +00:00 committed by Benjamin Kosnik
parent 59a64a46e0
commit 86ade44cb2
20 changed files with 1968 additions and 1489 deletions

View File

@ -1,3 +1,74 @@
2001-11-27 Benjamin Kosnik <bkoz@redhat.com>
Numeric facets cleanup.
* include/bits/locale_facets.h (__num_base::_S_atoms): Add, remove
+ and - signs.
(__num_base::_M_zero): Add
(__num_base::_M_e): Add.
(__num_base::_M_E): Add.
* include/bits/locale_facets.tcc (num_get::_M_extract): Remove.
(num_get::_M_extract_float): New.
(num_get::_M_extract_int): New.
* src/locale.cc (num_get::_M_extract): Remove.
* include/bits/locale_facets.tcc (num_put::_M_insert_float):
Simplify, use _M_insert.
(num_put::do_put(bool)): Simplify, remove __pad.
(__pad): Remove.
(__pad_output): Change to __pad.
* include/bits/ostream.tcc: And here.
* src/locale-inst: Remove instantiations.
* include/bits/locale_facets.h: Move helper functions in to class
num_put.
(num_put::_M_insert_float): Same, for __output_integer.
(num_put::_M_insert_int): Same, for __output_float.
(num_put::_M_insert): New.
(__num_base): Add.
(__num_base::_S_format_float): Move
__build_float_format into class __num_base.
(__num_base::_S_format_int): Move __build_int_format into class
__num_base.
* include/bits/locale_facets.tcc (__group_digits): Change to
(__add_grouping): This.
* src/locale-inst.cc: And here. Tweak instantiations.
* src/misc-inst.cc: Remove instantiations.
* include/bits/ostream.tcc (__pad_char): Rename, adjust inserters
for new calling conventions, move to...
* include/bits/locale_facets.tcc (__pad_output): Here. Adjust
signature to make it useful for both ostream and num_put.
(__pad_numeric): Remove.
* src/misc-inst.cc: Remove instantiations.
* src/locale-inst.cc: Same.
* include/bits/locale_facets.h (_Numeric_get): Remove.
(_Numeric_put): Remove.
(num_get::get(short)): Remove.
(num_get::get(int)): Remove.
(num_get::do_get(short)): Remove.
(num_get::do_get(int)): Remove.
* include/bits/istream.tcc (istream::operator>>(short)): Fix as
per DR 118.
(istream::operator>>(int)): Same.
* include/bits/locale_facets.h (_Format_cache): Remove.
* include/bits/locale_facets.tcc: Same.
* src/locale.cc: Same.
* src/locale-inst.cc: Same.
* include/bits/ostream.tcc: Same.
* src/ios.cc (ios_base::imbue): Remove here as well.
* testsuite/22_locale/num_get.cc: New file.
* testsuite/22_locale/num_get_members_char.cc: New file.
* testsuite/22_locale/num_get_members_wchar_t.cc: New.
* testsuite/22_locale/numpunct_members_wchar_t.cc: New file.
* testsuite/22_locale/num_put.cc: New file.
* testsuite/22_locale/num_put_members_char.cc: New file.
* testsuite/22_locale/num_put_members_wchar_t.cc: New file.
* testsuite/27_io/ostream_inserter_arith.cc: Fix.
* testsuite/27_io/istream_extractor_arith.cc: Fix.
2001-11-27 Phil Edwards <pme@gcc.gnu.org>
* docs/html/explanations.html: New section, empty for now.

View File

@ -134,8 +134,18 @@ namespace std
try
{
ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
long __l;
if (_M_check_facet(_M_fnumget))
_M_fnumget->get(*this, 0, *this, __err, __n);
_M_fnumget->get(*this, 0, *this, __err, __l);
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
// 118. basic_istream uses nonexistent num_get member functions.
if (!(__err & ios_base::failbit)
&& (numeric_limits<short>::min() <= __l
&& __l <= numeric_limits<short>::max()))
__n = __l;
else
__err |= ios_base::failbit;
#endif
this->setstate(__err);
}
catch(exception& __fail)
@ -188,8 +198,18 @@ namespace std
try
{
ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
long __l;
if (_M_check_facet(_M_fnumget))
_M_fnumget->get(*this, 0, *this, __err, __n);
_M_fnumget->get(*this, 0, *this, __err, __l);
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
// 118. basic_istream uses nonexistent num_get member functions.
if (!(__err & ios_base::failbit)
&& (numeric_limits<int>::min() <= __l
&& __l <= numeric_limits<int>::max()))
__n = __l;
else
__err |= ios_base::failbit;
#endif
this->setstate(__err);
}
catch(exception& __fail)
@ -1252,4 +1272,3 @@ namespace std
// Local Variables:
// mode:C++
// End:

View File

@ -415,415 +415,31 @@ namespace std
// 22.2.1.5 Template class codecvt
#include <bits/codecvt.h>
template<typename _CharT, typename _InIter>
class _Numeric_get; // forward
// _Format_cache holds the information extracted from the numpunct<>
// and moneypunct<> facets in a form optimized for parsing and
// formatting. It is stored via a void* pointer in the pword()
// array of an iosbase object passed to the _get and _put facets.
// NB: contains no user-serviceable parts.
template<typename _CharT>
class _Format_cache
{
public:
// Types:
typedef _CharT char_type;
typedef char_traits<_CharT> traits_type;
typedef basic_string<_CharT> string_type;
typedef typename string_type::size_type size_type;
class __num_base
{
public:
// String literal of acceptable (narrow) input, for num_get.
// "0123456789eEabcdfxABCDFX"
static const char _S_atoms[];
// Forward decls and Friends:
friend class locale;
template<typename _Char, typename _InIter>
friend class _Numeric_get;
friend class num_get<_CharT>;
friend class num_put<_CharT>;
friend class time_get<_CharT>;
friend class money_get<_CharT>;
friend class time_put<_CharT>;
friend class money_put<_CharT>;
// Data Members:
// ios_base::pword() reserved cell
static int _S_pword_ix;
// True iff data members are consistent with the current locale,
// ie imbue sets this to false.
bool _M_valid;
// A list of valid numeric literals: for the standard "C" locale,
// this would usually be: "-+xX0123456789abcdef0123456789ABCDEF"
static const char _S_literals[];
// NB: Code depends on the order of definitions of the names
// these are indices into _S_literals, above.
// This string is formatted for putting, not getting. (output, not input)
enum
{
_S_minus,
_S_plus,
_S_x,
_S_X,
_S_digits,
_S_digits_end = _S_digits + 16,
_S_udigits = _S_digits_end,
_S_udigits_end = _S_udigits + 16,
_S_ee = _S_digits + 14, // For scientific notation, 'E'
_S_Ee = _S_udigits + 14 // For scientific notation, 'e'
};
// The sign used to separate decimal values: for standard US
// locales, this would usually be: "."
// Abstracted from numpunct::decimal_point().
char_type _M_decimal_point;
// The sign used to separate groups of digits into smaller
// strings that the eye can parse with less difficulty: for
// standard US locales, this would usually be: ","
// Abstracted from numpunct::thousands_sep().
char_type _M_thousands_sep;
// However the US's "false" and "true" are translated.
// From numpunct::truename() and numpunct::falsename(), respectively.
string_type _M_truename;
string_type _M_falsename;
// If we are checking groupings. This should be equivalent to
// numpunct::groupings().size() != 0
bool _M_use_grouping;
// If we are using numpunct's groupings, this is the current
// grouping string in effect (from numpunct::grouping()).
string _M_grouping;
_Format_cache();
~_Format_cache() throw() { }
// Given a member of the ios hierarchy as an argument, extract
// out all the current formatting information into a
// _Format_cache object and return a pointer to it.
static _Format_cache<_CharT>*
_S_get(ios_base& __ios);
void
_M_populate(ios_base&);
static void
_S_callback(ios_base::event __event, ios_base& __ios, int __ix) throw();
enum
{
_M_zero,
_M_e = _M_zero + 10,
_M_E = _M_zero + 11,
_M_size = 23 + 1
};
template<typename _CharT>
int _Format_cache<_CharT>::_S_pword_ix;
template<typename _CharT>
const char _Format_cache<_CharT>::
_S_literals[] = "-+xX0123456789abcdef0123456789ABCDEF";
template<> _Format_cache<char>::_Format_cache();
#ifdef _GLIBCPP_USE_WCHAR_T
template<> _Format_cache<wchar_t>::_Format_cache();
#endif
// _Numeric_get is used by num_get, money_get, and time_get to help
// in parsing out numbers.
template<typename _CharT, typename _InIter>
class _Numeric_get
{
public:
// Types:
typedef _CharT char_type;
typedef _InIter iter_type;
// Forward decls and Friends:
template<typename _Char, typename _InIterT>
friend class num_get;
template<typename _Char, typename _InIterT>
friend class time_get;
template<typename _Char, typename _InIterT>
friend class money_get;
template<typename _Char, typename _InIterT>
friend class num_put;
template<typename _Char, typename _InIterT>
friend class time_put;
template<typename _Char, typename _InIterT>
friend class money_put;
private:
explicit
_Numeric_get() { }
virtual
~_Numeric_get() { }
iter_type
_M_get_digits(iter_type __in, iter_type __end) const;
};
template<typename _CharT, typename _InIter>
class num_get : public locale::facet
{
public:
// Types:
typedef _CharT char_type;
typedef _InIter iter_type;
typedef char_traits<_CharT> __traits_type;
static locale::id id;
explicit
num_get(size_t __refs = 0) : locale::facet(__refs) { }
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, bool& __v) const
{ return do_get(__in, __end, __io, __err, __v); }
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
//XXX. What number?
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, short& __v) const
{ return do_get(__in, __end, __io, __err, __v); }
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, int& __v) const
{ return do_get(__in, __end, __io, __err, __v); }
#endif
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, long& __v) const
{ return do_get(__in, __end, __io, __err, __v); }
#ifdef _GLIBCPP_USE_LONG_LONG
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, long long& __v) const
{ return do_get(__in, __end, __io, __err, __v); }
#endif
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, unsigned short& __v) const
{ return do_get(__in, __end, __io, __err, __v); }
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, unsigned int& __v) const
{ return do_get(__in, __end, __io, __err, __v); }
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, unsigned long& __v) const
{ return do_get(__in, __end, __io, __err, __v); }
#ifdef _GLIBCPP_USE_LONG_LONG
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, unsigned long long& __v) const
{ return do_get(__in, __end, __io, __err, __v); }
#endif
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, float& __v) const
{ return do_get(__in, __end, __io, __err, __v); }
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, double& __v) const
{ return do_get(__in, __end, __io, __err, __v); }
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, long double& __v) const
{ return do_get(__in, __end, __io, __err, __v); }
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, void*& __v) const
{ return do_get(__in, __end, __io, __err, __v); }
protected:
virtual ~num_get() { }
// This consolidates the extraction, storage and
// error-processing parts of the do_get(...) overloaded member
// functions.
// NB: This is specialized for char.
void
_M_extract(iter_type __beg, iter_type __end, ios_base& __io,
ios_base::iostate& __err, char* __xtrc,
int& __base, bool __fp = true) const;
virtual iter_type
do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const;
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
//XXX. What number?
virtual iter_type
do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, short&) const;
virtual iter_type
do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, int&) const;
#endif
virtual iter_type
do_get (iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const;
#ifdef _GLIBCPP_USE_LONG_LONG
virtual iter_type
do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
long long&) const;
#endif
virtual iter_type
do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
unsigned short&) const;
virtual iter_type
do_get(iter_type, iter_type, ios_base&,
ios_base::iostate& __err, unsigned int&) const;
virtual iter_type
do_get(iter_type, iter_type, ios_base&,
ios_base::iostate& __err, unsigned long&) const;
#ifdef _GLIBCPP_USE_LONG_LONG
virtual iter_type
do_get(iter_type, iter_type, ios_base&,
ios_base::iostate& __err, unsigned long long&) const;
#endif
virtual iter_type
do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
float&) const;
virtual iter_type
do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
double&) const;
virtual iter_type
do_get(iter_type, iter_type, ios_base&,
ios_base::iostate& __err, long double&) const;
virtual iter_type
do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
void*&) const;
};
template<typename _CharT, typename _InIter>
locale::id num_get<_CharT, _InIter>::id;
// Declare specialized extraction member function.
template<>
void
num_get<char, istreambuf_iterator<char> >::
_M_extract(istreambuf_iterator<char> __beg,
istreambuf_iterator<char> __end, ios_base& __io,
ios_base::iostate& __err, char* __xtrc,
int& __base, bool __fp) const;
// _Numeric_put is used by num_put, money_put, and time_put
// to help in formatting out numbers.
template<typename _CharT, typename _OutIter>
class _Numeric_put
{
public:
typedef _CharT char_type;
typedef _OutIter iter_type;
protected:
explicit
_Numeric_put() { }
virtual
~_Numeric_put() { }
};
template<typename _CharT, typename _OutIter>
class num_put : public locale::facet
{
public:
// Types:
typedef _CharT char_type;
typedef _OutIter iter_type;
static locale::id id;
explicit
num_put(size_t __refs = 0) : locale::facet(__refs) { }
iter_type
put(iter_type __s, ios_base& __f, char_type __fill, bool __v) const
{ return do_put(__s, __f, __fill, __v); }
iter_type
put(iter_type __s, ios_base& __f, char_type __fill, long __v) const
{ return do_put(__s, __f, __fill, __v); }
iter_type
put(iter_type __s, ios_base& __f, char_type __fill,
unsigned long __v) const
{ return do_put(__s, __f, __fill, __v); }
#ifdef _GLIBCPP_USE_LONG_LONG
iter_type
put(iter_type __s, ios_base& __f, char_type __fill, long long __v) const
{ return do_put(__s, __f, __fill, __v); }
iter_type
put(iter_type __s, ios_base& __f, char_type __fill,
unsigned long long __v) const
{ return do_put(__s, __f, __fill, __v); }
#endif
iter_type
put(iter_type __s, ios_base& __f, char_type __fill, double __v) const
{ return do_put(__s, __f, __fill, __v); }
iter_type
put(iter_type __s, ios_base& __f, char_type __fill,
long double __v) const
{ return do_put(__s, __f, __fill, __v); }
iter_type
put(iter_type __s, ios_base& __f, char_type __fill,
const void* __v) const
{ return do_put(__s, __f, __fill, __v); }
protected:
virtual
~num_put() { };
virtual iter_type
do_put(iter_type, ios_base&, char_type __fill, bool __v) const;
virtual iter_type
do_put(iter_type, ios_base&, char_type __fill, long __v) const;
#ifdef _GLIBCPP_USE_LONG_LONG
virtual iter_type
do_put(iter_type, ios_base&, char_type __fill, long long __v) const;
#endif
virtual iter_type
do_put(iter_type, ios_base&, char_type __fill, unsigned long) const;
#ifdef _GLIBCPP_USE_LONG_LONG
virtual iter_type
do_put(iter_type, ios_base&, char_type __fill, unsigned long long) const;
#endif
virtual iter_type
do_put(iter_type, ios_base&, char_type __fill, double __v) const;
virtual iter_type
do_put(iter_type, ios_base&, char_type __fill, long double __v) const;
virtual iter_type
do_put(iter_type, ios_base&, char_type __fill, const void* __v) const;
};
template <typename _CharT, typename _OutIter>
locale::id num_put<_CharT, _OutIter>::id;
// Construct and return valid scanf format for floating point types.
static bool
_S_format_float(const ios_base& __io, char* __fptr, char __mod,
streamsize __prec);
// Construct and return valid scanf format for integer types.
static void
_S_format_int(const ios_base& __io, char* __fptr, char __mod, char __modl);
};
template<typename _CharT>
class numpunct : public locale::facet
@ -919,7 +535,6 @@ namespace std
numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc);
#endif
template<typename _CharT>
class numpunct_byname : public numpunct<_CharT>
{
@ -944,6 +559,242 @@ namespace std
{ _S_destroy_c_locale(_M_c_locale_numpunct); }
};
template<typename _CharT, typename _InIter>
class num_get : public locale::facet, public __num_base
{
public:
// Types:
typedef _CharT char_type;
typedef _InIter iter_type;
static locale::id id;
explicit
num_get(size_t __refs = 0) : locale::facet(__refs) { }
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, bool& __v) const
{ return this->do_get(__in, __end, __io, __err, __v); }
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, long& __v) const
{ return this->do_get(__in, __end, __io, __err, __v); }
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, unsigned short& __v) const
{ return this->do_get(__in, __end, __io, __err, __v); }
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, unsigned int& __v) const
{ return this->do_get(__in, __end, __io, __err, __v); }
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, unsigned long& __v) const
{ return this->do_get(__in, __end, __io, __err, __v); }
#ifdef _GLIBCPP_USE_LONG_LONG
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, long long& __v) const
{ return this->do_get(__in, __end, __io, __err, __v); }
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, unsigned long long& __v) const
{ return this->do_get(__in, __end, __io, __err, __v); }
#endif
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, float& __v) const
{ return this->do_get(__in, __end, __io, __err, __v); }
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, double& __v) const
{ return this->do_get(__in, __end, __io, __err, __v); }
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, long double& __v) const
{ return this->do_get(__in, __end, __io, __err, __v); }
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, void*& __v) const
{ return this->do_get(__in, __end, __io, __err, __v); }
protected:
virtual ~num_get() { }
void
_M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&,
char* __xtrc) const;
void
_M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&,
char* __xtrc, int& __base) const;
virtual iter_type
do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const;
virtual iter_type
do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const;
virtual iter_type
do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
unsigned short&) const;
virtual iter_type
do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
unsigned int&) const;
virtual iter_type
do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
unsigned long&) const;
#ifdef _GLIBCPP_USE_LONG_LONG
virtual iter_type
do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
long long&) const;
virtual iter_type
do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
unsigned long long&) const;
#endif
virtual iter_type
do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
float&) const;
virtual iter_type
do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
double&) const;
virtual iter_type
do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
long double&) const;
virtual iter_type
do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
void*&) const;
};
template<typename _CharT, typename _InIter>
locale::id num_get<_CharT, _InIter>::id;
template<typename _CharT, typename _OutIter>
class num_put : public locale::facet, public __num_base
{
public:
// Types:
typedef _CharT char_type;
typedef _OutIter iter_type;
static locale::id id;
explicit
num_put(size_t __refs = 0) : locale::facet(__refs) { }
iter_type
put(iter_type __s, ios_base& __f, char_type __fill, bool __v) const
{ return this->do_put(__s, __f, __fill, __v); }
iter_type
put(iter_type __s, ios_base& __f, char_type __fill, long __v) const
{ return this->do_put(__s, __f, __fill, __v); }
iter_type
put(iter_type __s, ios_base& __f, char_type __fill,
unsigned long __v) const
{ return this->do_put(__s, __f, __fill, __v); }
#ifdef _GLIBCPP_USE_LONG_LONG
iter_type
put(iter_type __s, ios_base& __f, char_type __fill, long long __v) const
{ return this->do_put(__s, __f, __fill, __v); }
iter_type
put(iter_type __s, ios_base& __f, char_type __fill,
unsigned long long __v) const
{ return this->do_put(__s, __f, __fill, __v); }
#endif
iter_type
put(iter_type __s, ios_base& __f, char_type __fill, double __v) const
{ return this->do_put(__s, __f, __fill, __v); }
iter_type
put(iter_type __s, ios_base& __f, char_type __fill,
long double __v) const
{ return this->do_put(__s, __f, __fill, __v); }
iter_type
put(iter_type __s, ios_base& __f, char_type __fill,
const void* __v) const
{ return this->do_put(__s, __f, __fill, __v); }
protected:
template<typename _ValueT>
iter_type
_M_convert_float(iter_type, ios_base& __io, char_type __fill,
char __mod, _ValueT __v) const;
template<typename _ValueT>
iter_type
_M_convert_int(iter_type, ios_base& __io, char_type __fill,
char __mod, char __modl, _ValueT __v) const;
iter_type
_M_widen_float(iter_type, ios_base& __io, char_type __fill, char* __cs,
int __len) const;
iter_type
_M_widen_int(iter_type, ios_base& __io, char_type __fill, char* __cs,
int __len) const;
iter_type
_M_insert(iter_type, ios_base& __io, char_type __fill,
const char_type* __ws, int __len) const;
virtual
~num_put() { };
virtual iter_type
do_put(iter_type, ios_base&, char_type __fill, bool __v) const;
virtual iter_type
do_put(iter_type, ios_base&, char_type __fill, long __v) const;
virtual iter_type
do_put(iter_type, ios_base&, char_type __fill, unsigned long) const;
#ifdef _GLIBCPP_USE_LONG_LONG
virtual iter_type
do_put(iter_type, ios_base&, char_type __fill, long long __v) const;
virtual iter_type
do_put(iter_type, ios_base&, char_type __fill, unsigned long long) const;
#endif
virtual iter_type
do_put(iter_type, ios_base&, char_type __fill, double __v) const;
virtual iter_type
do_put(iter_type, ios_base&, char_type __fill, long double __v) const;
virtual iter_type
do_put(iter_type, ios_base&, char_type __fill, const void* __v) const;
};
template <typename _CharT, typename _OutIter>
locale::id num_put<_CharT, _OutIter>::id;
template<typename _CharT>
class collate : public locale::facet
@ -1466,8 +1317,9 @@ namespace std
};
struct money_base
class money_base
{
public:
enum part { none, space, symbol, sign, value };
struct pattern { char field[4]; };

File diff suppressed because it is too large Load Diff

View File

@ -465,93 +465,6 @@ namespace std
}
// 27.6.2.5.4 Character inserters
// Construct correctly padded string, as per 22.2.2.2.2
// Similar in theory to __pad_numeric, from num_put, but it doesn't
// use _S_fill: perhaps it should.
// Assumes
// __newlen > __oldlen
// __news is allocated for __newlen size
template<typename _CharT, typename _Traits>
void
__pad_char(basic_ios<_CharT, _Traits>& __ios,
_CharT* __news, const _CharT* __olds,
const streamsize __newlen, const streamsize __oldlen)
{
typedef _CharT char_type;
typedef _Traits traits_type;
typedef typename traits_type::int_type int_type;
int_type __plen = static_cast<size_t>(__newlen - __oldlen);
char_type* __pads = static_cast<char_type*>(__builtin_alloca(sizeof(char_type) * __plen));
traits_type::assign(__pads, __plen, __ios.fill());
char_type* __beg;
char_type* __end;
size_t __mod = 0;
size_t __beglen; //either __plen or __oldlen
ios_base::fmtflags __adjust = __ios.flags() & ios_base::adjustfield;
if (__adjust == ios_base::left)
{
// Padding last.
__beg = const_cast<char_type*>(__olds);
__beglen = __oldlen;
__end = __pads;
}
else if (__adjust == ios_base::internal)
{
// Pad after the sign, if there is one.
// Pad after 0[xX], if there is one.
// Who came up with these rules, anyway? Jeeze.
typedef _Format_cache<_CharT> __cache_type;
__cache_type const* __fmt = __cache_type::_S_get(__ios);
const char_type* __minus = traits_type::find(__olds, __oldlen,
__fmt->_S_minus);
const char_type* __plus = traits_type::find(__olds, __oldlen,
__fmt->_S_plus);
bool __testsign = __minus || __plus;
bool __testhex = __olds[0] == '0'
&& (__olds[1] == 'x' || __olds[1] == 'X');
if (__testhex)
{
__news[0] = __olds[0];
__news[1] = __olds[1];
__mod += 2;
__beg = const_cast<char_type*>(__olds + __mod);
__beglen = __oldlen - __mod;
__end = __pads;
}
else if (__testsign)
{
__mod += __plen;
const char_type* __sign = __minus ? __minus + 1: __plus + 1;
__beg = const_cast<char_type*>(__olds);
__beglen = __sign - __olds;
__end = const_cast<char_type*>(__sign + __plen);
traits_type::copy(__news + __beglen, __pads, __plen);
}
else
{
// Padding first.
__beg = __pads;
__beglen = __plen;
__end = const_cast<char_type*>(__olds);
}
}
else
{
// Padding first.
__beg = __pads;
__beglen = __plen;
__end = const_cast<char_type*>(__olds);
}
traits_type::copy(__news, __beg, __beglen);
traits_type::copy(__news + __beglen, __end, __newlen - __beglen - __mod);
}
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c)
@ -568,7 +481,7 @@ namespace std
streamsize __len = 1;
if (__w > __len)
{
__pad_char(__out, __pads, &__c, __w, __len);
__pad(__out, __out.fill(), __pads, &__c, __w, __len);
__len = __w;
}
__out.write(__pads, __len);
@ -603,7 +516,7 @@ namespace std
streamsize __len = 1;
if (__w > __len)
{
__pad_char(__out, __pads, &__c, __w, __len);
__pad(__out, __out.fill(), __pads, &__c, __w, __len);
__len = __w;
}
__out.write(__pads, __len);
@ -636,7 +549,7 @@ namespace std
streamsize __len = static_cast<streamsize>(_Traits::length(__s));
if (__w > __len)
{
__pad_char(__out, __pads, __s, __w, __len);
__pad(__out, __out.fill(), __pads, __s, __w, __len);
__s = __pads;
__len = __w;
}
@ -682,7 +595,7 @@ namespace std
if (__w > __len)
{
__pad_char(__out, __pads, __ws, __w, __len);
__pad(__out, __out.fill(), __pads, __ws, __w, __len);
__str = __pads;
__len = __w;
}
@ -717,7 +630,7 @@ namespace std
streamsize __len = static_cast<streamsize>(_Traits::length(__s));
if (__w > __len)
{
__pad_char(__out, __pads, __s, __w, __len);
__pad(__out, __out.fill(), __pads, __s, __w, __len);
__s = __pads;
__len = __w;
}
@ -755,7 +668,7 @@ namespace std
#endif
if (__w > __len)
{
__pad_char(__out, __pads, __s, __w, __len);
__pad(__out, __out.fill(), __pads, __s, __w, __len);
__s = __pads;
__len = __w;
}

View File

@ -159,21 +159,21 @@ namespace std
inline __istream_type&
get(char_type* __s, streamsize __n)
{ return get(__s, __n, this->widen('\n')); }
{ return this->get(__s, __n, this->widen('\n')); }
__istream_type&
get(__streambuf_type& __sb, char_type __delim);
inline __istream_type&
get(__streambuf_type& __sb)
{ return get(__sb, this->widen('\n')); }
{ return this->get(__sb, this->widen('\n')); }
__istream_type&
getline(char_type* __s, streamsize __n, char_type __delim);
inline __istream_type&
getline(char_type* __s, streamsize __n)
{ return getline(__s, __n, this->widen('\n')); }
{ return this->getline(__s, __n, this->widen('\n')); }
__istream_type&
ignore(streamsize __n = 1, int_type __delim = traits_type::eof());
@ -297,4 +297,3 @@ namespace std
#endif
#endif /* _CPP_ISTREAM */

View File

@ -171,8 +171,7 @@ namespace std
{
int_type __eof = traits_type::eof();
bool __thiseof = !_M_sbuf || _M_sbuf->sgetc() == __eof;
bool __beof = !__b._M_sbuf
|| __b._M_sbuf->sgetc() == __eof;
bool __beof = !__b._M_sbuf || __b._M_sbuf->sgetc() == __eof;
return (__thiseof && __beof || (!__thiseof && !__beof));
}
@ -184,8 +183,7 @@ namespace std
{
int_type __eof = traits_type::eof();
bool __thiseof = !_M_sbuf || _M_sbuf->sgetc() == __eof;
bool __beof = !__b._M_sbuf
|| __b._M_sbuf->sgetc() == __eof;
bool __beof = !__b._M_sbuf || __b._M_sbuf->sgetc() == __eof;
return (__thiseof && __beof || (!__thiseof && !__beof));
}
#endif

View File

@ -284,12 +284,6 @@ namespace std
{
locale __old = _M_ios_locale;
_M_ios_locale = __loc;
// Make sure there's a callback for the format caches so they will be
// marked dirty.
_Format_cache<char>::_S_get(*this);
#ifdef _GLIBCPP_USE_WCHAR_T
_Format_cache<wchar_t>::_S_get(*this);
#endif
_M_call_callbacks(imbue_event);
return __old;
}

View File

@ -56,7 +56,6 @@ namespace std
template class moneypunct_byname<char, true>;
template class money_get<char, ibuf_iterator>;
template class money_put<char, obuf_iterator>;
template class _Format_cache<char>;
#ifdef _GLIBCPP_USE_WCHAR_T
template class moneypunct<wchar_t, false>;
@ -65,19 +64,91 @@ namespace std
template class moneypunct_byname<wchar_t, true>;
template class money_get<wchar_t, wibuf_iterator>;
template class money_put<wchar_t, wobuf_iterator>;
template class _Format_cache<wchar_t>;
#endif
// numpunct, numpunct_byname, num_get, and num_put
template class numpunct<char>;
template class numpunct_byname<char>;
template class num_get<char, ibuf_iterator>;
template class num_put<char, obuf_iterator>;
template class num_put<char, obuf_iterator>;
template
obuf_iterator
num_put<char, obuf_iterator>::
_M_convert_int(obuf_iterator, ios_base&, char, char, char, long) const;
template
obuf_iterator
num_put<char, obuf_iterator>::
_M_convert_int(obuf_iterator, ios_base&, char, char, char,
unsigned long) const;
#ifdef _GLIBCPP_USE_LONG_LONG
template
obuf_iterator
num_put<char, obuf_iterator>::
_M_convert_int(obuf_iterator, ios_base&, char, char, char,
long long) const;
template
obuf_iterator
num_put<char, obuf_iterator>::
_M_convert_int(obuf_iterator, ios_base&, char, char, char,
unsigned long long) const;
#endif
template
obuf_iterator
num_put<char, obuf_iterator>::
_M_convert_float(obuf_iterator, ios_base&, char, char, double) const;
template
obuf_iterator
num_put<char, obuf_iterator>::
_M_convert_float(obuf_iterator, ios_base&, char, char,
long double) const;
#ifdef _GLIBCPP_USE_WCHAR_T
template class numpunct<wchar_t>;
template class numpunct_byname<wchar_t>;
template class num_get<wchar_t, wibuf_iterator>;
template class num_put<wchar_t, wobuf_iterator>;
template
wobuf_iterator
num_put<wchar_t, wobuf_iterator>::
_M_convert_int(wobuf_iterator, ios_base&, wchar_t, char, char, long) const;
template
wobuf_iterator
num_put<wchar_t, wobuf_iterator>::
_M_convert_int(wobuf_iterator, ios_base&, wchar_t, char, char,
unsigned long) const;
#ifdef _GLIBCPP_USE_LONG_LONG
template
wobuf_iterator
num_put<wchar_t, wobuf_iterator>::
_M_convert_int(wobuf_iterator, ios_base&, wchar_t, char, char,
long long) const;
template
wobuf_iterator
num_put<wchar_t, wobuf_iterator>::
_M_convert_int(wobuf_iterator, ios_base&, wchar_t, char, char,
unsigned long long) const;
#endif
template
wobuf_iterator
num_put<wchar_t, wobuf_iterator>::
_M_convert_float(wobuf_iterator, ios_base&, wchar_t, char,
double) const;
template
wobuf_iterator
num_put<wchar_t, wobuf_iterator>::
_M_convert_float(wobuf_iterator, ios_base&, wchar_t, char,
long double) const;
#endif
// time_get and time_put
@ -246,45 +317,32 @@ namespace std
typedef ostreambuf_iterator<char, char_traits<char> > ostreambuf_iter;
#ifdef _GLIBCPP_USE_WCHAR_T
typedef istreambuf_iterator<wchar_t,char_traits<wchar_t> > wistreambuf_iter;
typedef ostreambuf_iterator<wchar_t,char_traits<wchar_t> > wostreambuf_iter;
typedef istreambuf_iterator<wchar_t, char_traits<wchar_t> > wistreambuf_iter;
typedef ostreambuf_iterator<wchar_t, char_traits<wchar_t> > wostreambuf_iter;
#endif
template
bool
locale::operator()(const string&, const string&) const;
template
ostreambuf_iter
__pad<char, ostreambuf_iter, output_iterator_tag>
(ostreambuf_iter, char, int, output_iterator_tag);
template
ostreambuf_iter
__pad_numeric<char, ostreambuf_iter>
(ostreambuf_iter, ios_base::fmtflags, char, int, char const*, char const*,
char const*);
template
char*
__group_digits<char>(char*, char, char const*, char const*,
__add_grouping<char>(char*, char, char const*, char const*,
char const*, char const*);
template
bool
__verify_grouping<char>(const basic_string<char>&, basic_string<char>&);
template
ostreambuf_iter
__output_integer<char, ostreambuf_iter, unsigned long>
(ostreambuf_iter, ios_base &, char, bool, unsigned long);
#ifdef _GLIBCPP_USE_LONG_LONG
template
ostreambuf_iter
__output_integer<char, ostreambuf_iter, unsigned long long>
(ostreambuf_iter, ios_base &, char, bool, unsigned long long);
#endif
void
__pad<char>(ios_base&, char, char*, const char *, streamsize,
streamsize);
template
void
__pad<char, char_traits<char> >(ios_base&, char, char*,
const char *, streamsize, streamsize);
#ifdef _GLIBCPP_USE_WCHAR_T
template
@ -293,37 +351,25 @@ namespace std
typedef ostreambuf_iterator<wchar_t> wostreambuf_iter;
template
wostreambuf_iter
__pad<wchar_t, wostreambuf_iter, output_iterator_tag>
(wostreambuf_iter, wchar_t, int, output_iterator_tag);
template
wostreambuf_iter
__pad_numeric<wchar_t, wostreambuf_iter>
(wostreambuf_iter, ios_base::fmtflags, wchar_t __fill, int, wchar_t const*,
wchar_t const*, wchar_t const*);
template
wchar_t*
__group_digits<wchar_t>(wchar_t*, wchar_t, char const*, char const*,
__add_grouping<wchar_t>(wchar_t*, wchar_t, char const*, char const*,
wchar_t const*, wchar_t const*);
template
bool
__verify_grouping<wchar_t>(const basic_string<wchar_t>&,
basic_string<wchar_t>&);
template
wostreambuf_iter
__output_integer<wchar_t, wostreambuf_iter, unsigned long>
(wostreambuf_iter, ios_base &, wchar_t, bool, unsigned long);
#ifdef _GLIBCPP_USE_LONG_LONG
template
wostreambuf_iter
__output_integer<wchar_t, wostreambuf_iter, unsigned long long>
(wostreambuf_iter, ios_base &, wchar_t, bool, unsigned long long);
#endif
void
__pad<wchar_t>(ios_base&, wchar_t, wchar_t*, const wchar_t*,
streamsize, streamsize);
template
void
__pad<wchar_t, char_traits<wchar_t> >(ios_base&, wchar_t, wchar_t*,
const wchar_t*,
streamsize, streamsize);
#endif // _GLIBCPP_USE_WCHAR_T
template
@ -342,4 +388,3 @@ namespace std
__normal_iterator<locale::facet**, vector<locale::facet*> >,
locale::facet* const&);
} // namespace std

View File

@ -74,6 +74,8 @@ namespace std
// Definitions for static const data members of locale::id
size_t locale::id::_S_highwater; // init'd to 0 by linker
const char __num_base::_S_atoms[] = "0123456789eEabcdfxABCDFX";
// Definitions for static const data members of locale::_Impl
const locale::id* const
locale::_Impl::_S_id_ctype[] =
@ -353,7 +355,7 @@ namespace std
void
locale::facet::
_M_add_reference() throw()
{ ++_M_references; } // XXX MT
{ ++_M_references; } // XXX MT
void
locale::facet::
@ -457,22 +459,6 @@ namespace std
const money_base::pattern
money_base::_S_default_pattern = {{symbol, sign, none, value}};
template<>
_Format_cache<char>::_Format_cache()
: _M_valid(true),
_M_decimal_point('.'), _M_thousands_sep(','),
_M_truename("true"), _M_falsename("false"), _M_use_grouping(false)
{ }
#ifdef _GLIBCPP_USE_WCHAR_T
template<>
_Format_cache<wchar_t>::_Format_cache()
: _M_valid(true),
_M_decimal_point(L'.'), _M_thousands_sep(L','),
_M_truename(L"true"), _M_falsename(L"false"), _M_use_grouping(false)
{ }
#endif
template<>
const ctype<char>&
use_facet<ctype<char> >(const locale& __loc)
@ -493,310 +479,9 @@ namespace std
}
#endif
template<>
void
num_get<char, istreambuf_iterator<char> >::
_M_extract(istreambuf_iterator<char> __beg,
istreambuf_iterator<char> __end, ios_base& __io,
ios_base::iostate& __err, char* __xtrc, int& __base,
bool __fp) const
{
typedef _Format_cache<char> __cache_type;
// Prepare for possible failure
__xtrc[0] = '\0';
// Stage 1: determine a conversion specifier.
ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
if (__basefield == ios_base::dec)
__base = 10;
else if (__basefield == ios_base::oct)
__base = 8;
else if (__basefield == ios_base::hex)
__base = 16;
else
__base = 0;
// As far as I can tell, bases other than 10 are not available for
// floating point types
if (__fp)
__base = 10;
// Stage 2: extract characters.
__cache_type const* __fmt = __cache_type::_S_get(__io);
// Fail quickly if !__valid
if (__beg == __end)
{
__err |= (ios_base::eofbit | ios_base::failbit);
return;
}
// Acceptable formats for numbers here are based on 22.2.3.1
string __grp;
int __sep_pos = 0;
int __pos = 0;
const char* __lits = __fmt->_S_literals;
char __c = *__beg;
// Check first for sign
bool __testsign = false;
if ((__c == __lits[__cache_type::_S_minus])
|| (__c == __lits[__cache_type::_S_plus]))
{
__testsign = true;
__xtrc[__pos++] = __c;
++__beg;
__c = * __beg;
// Whitespace may follow a sign
while ((__beg != __end) && (isspace(__c)))
{
++__beg;
__c = *__beg;
}
// There had better be more to come...
if (__beg == __end)
{
__xtrc[__pos] = '\0';
__err |= (ios_base::eofbit | ios_base::failbit);
return;
}
}
// Now check if first character is a zero.
bool __testzero = false;
if (__c == __lits[__cache_type::_S_digits])
{
__testzero = true;
++__beg;
__c = *__beg;
// We have to check for __beg == __end here. If so,
// a plain '0' (possibly with a sign) can be got rid of now
if (__beg == __end)
{
__xtrc[__pos++] = __lits[__cache_type::_S_digits];
__xtrc[__pos] = '\0';
__err |= ios_base::eofbit;
return;
}
// Figure out base for integer types only
// Based on Table 55 of 22.2.2.1.2
if (!__fp && __base != 10 && __base != 8)
{
// Here, __base == 0 or 16
if ((__c == __lits[__cache_type::_S_x])
|| (__c == __lits[__cache_type::_S_X]))
{
++__beg;
__c = *__beg;
__base = 16;
__testzero = false; // "0x" is not a leading zero
}
else if (__base == 0)
__base = 8;
}
// Remove any more leading zeros
while (__beg != __end)
{
if (__c == __lits[__cache_type::_S_digits])
{
++__beg;
__c = *__beg;
__testzero = true;
}
else
break;
}
}
else if (__base == 0) // 1st character is not zero
__base = 10;
// We now seek "units", i.e. digits and thousands separators.
// We may need to know if anything is found here. A leading zero
// (removed by now) would count.
bool __testunits = __testzero;
while (__beg != __end)
{
const char* __p = strchr(__lits, __c);
// NB: strchr returns true for __c == 0x0
if (__p && __c
&&((__p >= &__lits[__cache_type::_S_digits]
&& __p < &__lits[__cache_type::_S_digits + __base])
|| (__p >= &__lits[__cache_type::_S_udigits]
&& __p < &__lits[__cache_type::_S_udigits + __base])))
{
// Try first for acceptable digit; record it if found.
__xtrc[__pos++] = __c;
++__sep_pos;
__testunits = true;
++__beg;
__c = *__beg;
}
else if (__c == __fmt->_M_thousands_sep && __fmt->_M_use_grouping)
{
// NB: Thousands separator at the beginning of a string
// is a no-no, as is two consecutive thousands
// separators.
if (__sep_pos)
{
__grp += static_cast<char>(__sep_pos);
__sep_pos = 0;
++__beg;
__c = *__beg;
}
else
{
__err |= ios_base::failbit;
break;
}
}
else
// Not a valid input item.
break;
}
// Digit grouping is checked. If _M_groupings() doesn't
// match, then get very very upset, and set failbit.
if (__fmt->_M_use_grouping && !__grp.empty())
{
// Add the ending grouping
__grp += static_cast<char>(__sep_pos);
if (!__verify_grouping(__fmt->_M_grouping, __grp))
{
__err |= ios_base::failbit;
__xtrc[__pos] = '\0';
if (__beg == __end)
__err |= ios_base::eofbit;
return;
}
}
// If there was nothing but zeros, put one in the output string
if (__testzero && (__pos == 0 || (__pos == 1 && __testsign)))
__xtrc[__pos++] = __lits[__cache_type::_S_digits];
// That's it for integer types. Remaining code is for floating point
if (__fp && __beg != __end)
{
// Check first for decimal point. There MUST be one if
// __testunits is false.
bool __testdec = false; // Is there a decimal point
// with digits following it?
if (__c == __fmt->_M_decimal_point)
{
__xtrc[__pos++] = '.';
++__beg;
__c = *__beg;
// Now we get any digits after the decimal point
// There MUST be some if __testunits is false.
while (__beg != __end)
{
const char* __p = strchr(__lits, __c);
if ((__p >= &__lits[__cache_type::_S_digits]
&& __p < &__lits[__cache_type::_S_digits + __base])
|| (__p >= &__lits[__cache_type::_S_udigits]
&& __p < &__lits[__cache_type::_S_udigits + __base]))
{
__xtrc[__pos++] = __c;
++__beg;
__c = *__beg;
__testdec = true;
}
else
break;
}
}
if (!__testunits && !__testdec) // Ill formed
{
__err |= ios_base::failbit;
__xtrc[__pos] = '\0';
if (__beg == __end)
__err |= ios_base::eofbit;
return;
}
// Now we may find an exponent
if (__beg != __end)
{
if ((__c == __lits[__cache_type::_S_ee])
|| (__c == __lits[__cache_type::_S_Ee]))
{
__xtrc[__pos++] = __c;
++__beg;
__c = *__beg;
// Now there may be a sign
if (__beg != __end)
{
if ((__c == __lits[__cache_type::_S_minus])
|| (__c == __lits[__cache_type::_S_plus]))
{
__xtrc[__pos++] = __c;
++__beg;
__c = *__beg;
// whitespace may follow a sign
while ((__beg != __end) && (isspace(__c)))
{
++__beg;
__c = *__beg;
}
}
}
// And now there must be some digits
if (__beg == __end)
{
__xtrc[__pos] = '\0';
__err |= (ios_base::eofbit | ios_base::failbit);
return;
}
while (__beg != __end)
{
const char* __p = strchr(__lits, __c);
if ((__p >= &__lits[__cache_type::_S_digits]
&& __p < &__lits[__cache_type::_S_digits + __base])
|| (__p >= &__lits[__cache_type::_S_udigits]
&& __p < &__lits[__cache_type::_S_udigits + __base]))
{
__xtrc[__pos++] = __c;
++__beg;
__c = *__beg;
}
else
break;
}
}
}
// Finally, that's it for floating point
}
// Finish up
__xtrc[__pos] = '\0';
if (__beg == __end)
__err |= ios_base::eofbit;
}
// The following code uses sprintf() to convert floating point
// values for insertion into a stream. The current implementation
// replicates the code in _S_pad_numeric() (in _S_output_float()) in
// order to prevent having to create a "wide" buffer in addition to
// the "narrow" buffer passed to sprintf(). An optimization would be
// to replace sprintf() with code that works directly on a wide
// buffer and then use _S_pad_numeric() to do the padding. It would
// be good to replace sprintf() anyway to avoid accidental buffer
// overruns and to gain back the efficiency that C++ provides by
// knowing up front the type of the values to insert. This
// implementation follows the C++ standard fairly directly as
// outlined in 22.2.2.2 [lib.locale.num.put]
bool
__build_float_format(ios_base& __io, char* __fptr, char __modifier,
streamsize __prec)
__num_base::_S_format_float(const ios_base& __io, char* __fptr, char __mod,
streamsize __prec)
{
bool __incl_prec = false;
ios_base::fmtflags __flags = __io.flags();
@ -809,12 +494,12 @@ namespace std
// As per [22.2.2.2.2.11]
if (__flags & ios_base::fixed || __prec > 0)
{
*__fptr++ = '.';
*__fptr++ = '*';
__incl_prec = true;
*__fptr++ = '.';
*__fptr++ = '*';
__incl_prec = true;
}
if (__modifier)
*__fptr++ = __modifier;
if (__mod)
*__fptr++ = __mod;
ios_base::fmtflags __fltfield = __flags & ios_base::floatfield;
// [22.2.2.2.2] Table 58
if (__fltfield == ios_base::fixed)
@ -826,16 +511,43 @@ namespace std
*__fptr = '\0';
return __incl_prec;
}
void
__num_base::_S_format_int(const ios_base& __io, char* __fptr, char __mod,
char __modl)
{
ios_base::fmtflags __flags = __io.flags();
*__fptr++ = '%';
// [22.2.2.2.2] Table 60
if (__flags & ios_base::showpos)
*__fptr++ = '+';
if (__flags & ios_base::showbase)
*__fptr++ = '#';
*__fptr++ = 'l';
template<>
moneypunct_byname<char, false>::moneypunct_byname(const char* /*__s*/,
size_t __refs)
: moneypunct<char, false>(__refs) { }
// For long long types.
if (__modl)
*__fptr++ = __modl;
ios_base::fmtflags __bsefield = __flags & ios_base::basefield;
if (__bsefield == ios_base::hex)
*__fptr++ = (__flags & ios_base::uppercase) ? 'X' : 'x';
else if (__bsefield == ios_base::oct)
*__fptr++ = 'o';
else
*__fptr++ = __mod;
*__fptr = '\0';
}
template<>
moneypunct_byname<char, true>::moneypunct_byname(const char* /*__s*/,
size_t __refs)
: moneypunct<char, true>(__refs) { }
moneypunct_byname<char, false>::moneypunct_byname(const char* /*__s*/,
size_t __refs)
: moneypunct<char, false>(__refs) { }
template<>
moneypunct_byname<char, true>::moneypunct_byname(const char* /*__s*/,
size_t __refs)
: moneypunct<char, true>(__refs) { }
#ifdef _GLIBCPP_USE_WCHAR_T
ctype<wchar_t>::__wmask_type

View File

@ -241,39 +241,6 @@ namespace std
(vector<string>::const_iterator, vector<string>::const_iterator,
string*, __false_type);
template
void
__pad_char(basic_ios<char>&, char*, const char*,
const streamsize, const streamsize);
#ifdef _GLIBCPP_USE_WCHAR_T
template
void
__pad_char(basic_ios<wchar_t>&, wchar_t*, const wchar_t*,
const streamsize, const streamsize);
#endif
template
ostreambuf_iterator<char>
__pad_numeric(ostreambuf_iterator<char>, _Ios_Fmtflags, char, int,
const char*, const char*, const char*);
#ifdef _GLIBCPP_USE_WCHAR_T
template
ostreambuf_iterator<wchar_t>
__pad_numeric(ostreambuf_iterator<wchar_t>, _Ios_Fmtflags, wchar_t, int,
const wchar_t*, const wchar_t*, const wchar_t*);
#endif
template
ostreambuf_iterator<char>
__output_float(ostreambuf_iterator<char>, ios_base&, char,
const char*, size_t);
#ifdef _GLIBCPP_USE_WCHAR_T
template
ostreambuf_iterator<wchar_t>
__output_float(ostreambuf_iterator<wchar_t>, ios_base&, wchar_t,
const char*, size_t);
#endif
template
streamsize
__copy_streambufs(basic_ios<char>&, basic_streambuf<char>*,

View File

@ -0,0 +1,52 @@
// 2001-11-21 Benjamin Kosnik <bkoz@redhat.com>
// Copyright (C) 2001 Free Software Foundation
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 22.2.2.1 Template class num_get
#include <locale>
void test01()
{
// Check for required base class.
typedef std::num_get<char> test_type;
typedef std::locale::facet base_type;
const test_type& obj = std::use_facet<test_type>(std::locale());
const base_type* base = &obj;
// Check for required typedefs
typedef test_type::char_type char_type;
typedef test_type::iter_type iter_type;
}
// Should be able to instantiate this for other types besides char, wchar_t
class gnu_num_get: public std::num_get<unsigned char>
{ };
void test02()
{
gnu_num_get facet01;
}
int main()
{
test01();
test02();
return 0;
}

View File

@ -0,0 +1,246 @@
// 2001-11-21 Benjamin Kosnik <bkoz@redhat.com>
// Copyright (C) 2001 Free Software Foundation
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 22.2.2.1.1 num_get members
#include <locale>
#include <sstream>
#include <testsuite_hooks.h>
// XXX This test is not working for non-glibc locale models.
// { dg-do run { xfail *-*-* } }
void test01()
{
using namespace std;
typedef istreambuf_iterator<char> iterator_type;
bool test = true;
// basic construction
locale loc_c = locale::classic();
locale loc_hk("en_HK");
locale loc_fr("fr_FR@euro");
locale loc_de("de_DE");
VERIFY( loc_c != loc_de );
VERIFY( loc_hk != loc_fr );
VERIFY( loc_hk != loc_de );
VERIFY( loc_de != loc_fr );
// cache the numpunct facets
const numpunct<char>& numpunct_c = use_facet<numpunct<char> >(loc_c);
const numpunct<char>& numpunct_de = use_facet<numpunct<char> >(loc_de);
const numpunct<char>& numpunct_hk = use_facet<numpunct<char> >(loc_hk);
// sanity check the data is correct.
const string empty;
char c;
bool b1 = true;
bool b0 = false;
long l1 = 2147483647;
long l2 = -2147483647;
long l;
unsigned long ul1 = 1294967294;
unsigned long ul2 = 0;
unsigned long ul;
double d1 = 1.02345e+308;
double d2 = 3.15e-308;
double d;
long double ld1 = 6.630025e+4;
long double ld2 = 0.0;
long double ld;
void* v;
const void* cv = &ul2;
// cache the num_get facet
istringstream iss;
iss.imbue(loc_de);
const num_get<char>& ng = use_facet<num_get<char> >(iss.getloc());
const ios_base::iostate goodbit = ios_base::goodbit;
const ios_base::iostate eofbit = ios_base::eofbit;
ios_base::iostate err = ios_base::goodbit;
// bool, simple
iss.str("1");
iterator_type os_it00 = iss.rdbuf();
iterator_type os_it01 = ng.get(os_it00, 0, iss, err, b1);
VERIFY( b1 == true );
VERIFY( err & ios_base::eofbit );
iss.str("0");
err = goodbit;
ng.get(iss.rdbuf(), 0, iss, err, b0);
VERIFY( b0 == false );
VERIFY( err & eofbit );
// bool, more twisted examples
iss.imbue(loc_c);
iss.str("true ");
iss.clear();
iss.setf(ios_base::boolalpha);
err = goodbit;
ng.get(iss.rdbuf(), 0, iss, err, b0);
VERIFY( b0 == true );
VERIFY( err == goodbit );
iss.str("false ");
iss.clear();
iss.setf(ios_base::boolalpha);
err = goodbit;
ng.get(iss.rdbuf(), 0, iss, err, b1);
VERIFY( b1 == false );
VERIFY( err == goodbit );
// long, in a locale that expects grouping
iss.imbue(loc_hk);
iss.str("2,147,483,647 ");
iss.clear();
err = goodbit;
ng.get(iss.rdbuf(), 0, iss, err, l);
VERIFY( l == l1 );
VERIFY( err == goodbit );
iss.str("-2,147,483,647++++++");
iss.clear();
err = goodbit;
ng.get(iss.rdbuf(), 0, iss, err, l);
VERIFY( l == l2 );
VERIFY( err == goodbit );
// unsigned long, in a locale that does not group
iss.imbue(loc_c);
iss.str("1294967294");
iss.clear();
err = goodbit;
ng.get(iss.rdbuf(), 0, iss, err, ul);
VERIFY( ul == ul1);
VERIFY( err == eofbit );
iss.str("0+++++++++++++++++++");
iss.clear();
err = goodbit;
ng.get(iss.rdbuf(), 0, iss, err, ul);
VERIFY( ul == ul2);
VERIFY( err == goodbit );
// ... and one that does
iss.imbue(loc_de);
iss.str("1.294.967.294+++++++");
iss.clear();
iss.width(20);
iss.setf(ios_base::left, ios_base::adjustfield);
err = goodbit;
ng.get(iss.rdbuf(), 0, iss, err, ul);
VERIFY( ul == ul1 );
VERIFY( err == goodbit );
// double
iss.imbue(loc_c);
iss.str("1.02345e+308++++++++");
iss.clear();
iss.width(20);
iss.setf(ios_base::left, ios_base::adjustfield);
err = goodbit;
ng.get(iss.rdbuf(), 0, iss, err, d);
VERIFY( d == d1 );
VERIFY( err == goodbit );
iss.str("+3.15e-308");
iss.clear();
iss.width(20);
iss.setf(ios_base::right, ios_base::adjustfield);
err = goodbit;
ng.get(iss.rdbuf(), 0, iss, err, d);
VERIFY( d == d2 );
VERIFY( err == eofbit );
iss.imbue(loc_de);
iss.str("+1,02345e+308");
iss.clear();
iss.width(20);
iss.setf(ios_base::right, ios_base::adjustfield);
iss.setf(ios_base::scientific, ios_base::floatfield);
err = goodbit;
ng.get(iss.rdbuf(), 0, iss, err, d);
VERIFY( d == d1 );
VERIFY( err == eofbit );
iss.str("3,15E-308 ");
iss.clear();
iss.width(20);
iss.precision(10);
iss.setf(ios_base::right, ios_base::adjustfield);
iss.setf(ios_base::scientific, ios_base::floatfield);
iss.setf(ios_base::uppercase);
err = goodbit;
ng.get(iss.rdbuf(), 0, iss, err, d);
VERIFY( d == d2 );
VERIFY( err == goodbit );
// long double
iss.str("6,630025e+4");
iss.clear();
err = goodbit;
ng.get(iss.rdbuf(), 0, iss, err, ld);
VERIFY( ld == ld1 );
VERIFY( err == eofbit );
iss.str("0 ");
iss.clear();
iss.precision(0);
iss.setf(ios_base::fixed, ios_base::floatfield);
err = goodbit;
ng.get(iss.rdbuf(), 0, iss, err, ld);
VERIFY( ld == 0 );
VERIFY( err == goodbit );
// const void
iss.str("0xbffff74c.");
iss.clear();
err = goodbit;
ng.get(iss.rdbuf(), 0, iss, err, v);
VERIFY( &v != &cv );
VERIFY( err == goodbit );
#ifdef _GLIBCPP_USE_LONG_LONG
long long ll1 = 9223372036854775807;
long long ll2 = -9223372036854775807;
long long ll;
iss.str("9.223.372.036.854.775.807");
iss.clear();
err = goodbit;
ng.get(iss.rdbuf(), 0, iss, err, ll);
VERIFY( ll == ll1 );
VERIFY( err == eofbit );
#endif
}
int main()
{
test01();
return 0;
}
// Kathleen Hannah, humanitarian, woman, art-thief

View File

@ -0,0 +1,52 @@
// 2001-11-19 Benjamin Kosnik <bkoz@redhat.com>
// Copyright (C) 2001 Free Software Foundation
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 22.2.2.2 Template class num_put
#include <locale>
void test01()
{
// Check for required base class.
typedef std::num_put<char> test_type;
typedef std::locale::facet base_type;
const test_type& obj = std::use_facet<test_type>(std::locale());
const base_type* base = &obj;
// Check for required typedefs
typedef test_type::char_type char_type;
typedef test_type::iter_type iter_type;
}
// Should be able to instantiate this for other types besides char, wchar_t
class gnu_num_put: public std::num_put<unsigned char>
{ };
void test02()
{
gnu_num_put facet01;
}
int main()
{
test01();
test02();
return 0;
}

View File

@ -0,0 +1,230 @@
// 2001-11-19 Benjamin Kosnik <bkoz@redhat.com>
// Copyright (C) 2001 Free Software Foundation
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 22.2.2.2.1 num_put members
#include <locale>
#include <sstream>
#include <testsuite_hooks.h>
// XXX This test is not working for non-glibc locale models.
// { dg-do run { xfail *-*-* } }
void test01()
{
using namespace std;
typedef ostreambuf_iterator<char> iterator_type;
bool test = true;
// basic construction
locale loc_c = locale::classic();
locale loc_hk("en_HK");
locale loc_fr("fr_FR@euro");
locale loc_de("de_DE");
VERIFY( loc_c != loc_de );
VERIFY( loc_hk != loc_fr );
VERIFY( loc_hk != loc_de );
VERIFY( loc_de != loc_fr );
// cache the numpunct facets
const numpunct<char>& numpunct_c = use_facet<numpunct<char> >(loc_c);
const numpunct<char>& numpunct_de = use_facet<numpunct<char> >(loc_de);
const numpunct<char>& numpunct_hk = use_facet<numpunct<char> >(loc_hk);
// sanity check the data is correct.
const string empty;
string result1;
string result2;
char c;
bool b1 = true;
bool b0 = false;
long l1 = 2147483647;
long l2 = -2147483647;
unsigned long ul1 = 1294967294;
unsigned long ul2 = 0;
double d1 = 1.7976931348623157e+308;
double d2 = 2.2250738585072014e-308;
long double ld1 = 1.7976931348623157e+308;
long double ld2 = 2.2250738585072014e-308;
const void* cv = &ld1;
// cache the num_put facet
ostringstream oss;
oss.imbue(loc_de);
const num_put<char>& np = use_facet<num_put<char> >(oss.getloc());
// bool, simple
iterator_type os_it00 = oss.rdbuf();
iterator_type os_it01 = np.put(os_it00, oss, '+', b1);
result1 = oss.str();
VERIFY( result1 == "1" );
// VERIFY( os_it00 != os_it01 );
oss.str(empty);
np.put(oss.rdbuf(), oss, '+', b0);
result2 = oss.str();
VERIFY( result2 == "0" );
// bool, more twisted examples
oss.imbue(loc_c);
oss.str(empty);
oss.width(20);
oss.setf(ios_base::right, ios_base::adjustfield);
np.put(oss.rdbuf(), oss, '+', b0);
result1 = oss.str();
VERIFY( result1 == "+++++++++++++++++++0" );
oss.str(empty);
oss.width(20);
oss.setf(ios_base::left, ios_base::adjustfield);
oss.setf(ios_base::boolalpha);
np.put(oss.rdbuf(), oss, '+', b1);
result2 = oss.str();
VERIFY( result2 == "true++++++++++++++++" );
// long, in a locale that expects grouping
oss.imbue(loc_hk);
oss.str(empty);
oss.clear();
np.put(oss.rdbuf(), oss, '+', l1);
result1 = oss.str();
VERIFY( result1 == "2,147,483,647" );
oss.str(empty);
oss.clear();
oss.width(20);
oss.setf(ios_base::left, ios_base::adjustfield);
np.put(oss.rdbuf(), oss, '+', l2);
result1 = oss.str();
VERIFY( result1 == "-2,147,483,647++++++" );
// unsigned long, in a locale that does not group
oss.imbue(loc_c);
oss.str(empty);
oss.clear();
np.put(oss.rdbuf(), oss, '+', ul1);
result1 = oss.str();
VERIFY( result1 == "1294967294" );
oss.str(empty);
oss.clear();
oss.width(20);
oss.setf(ios_base::left, ios_base::adjustfield);
np.put(oss.rdbuf(), oss, '+', ul2);
result1 = oss.str();
VERIFY( result1 == "0+++++++++++++++++++" );
// ... and one that does
oss.imbue(loc_de);
oss.str(empty);
oss.clear();
oss.width(20);
oss.setf(ios_base::left, ios_base::adjustfield);
np.put(oss.rdbuf(), oss, '+', ul1);
result1 = oss.str();
VERIFY( result1 == "1.294.967.294+++++++" );
// double
oss.str(empty);
oss.clear();
oss.width(20);
oss.setf(ios_base::left, ios_base::adjustfield);
np.put(oss.rdbuf(), oss, '+', d1);
result1 = oss.str();
VERIFY( result1 == "1,79769e+308++++++++" );
oss.str(empty);
oss.clear();
oss.width(20);
oss.setf(ios_base::right, ios_base::adjustfield);
np.put(oss.rdbuf(), oss, '+', d2);
result1 = oss.str();
VERIFY( result1 == "++++++++2,22507e-308" );
oss.str(empty);
oss.clear();
oss.width(20);
oss.setf(ios_base::right, ios_base::adjustfield);
oss.setf(ios_base::scientific, ios_base::floatfield);
np.put(oss.rdbuf(), oss, '+', d2);
result2 = oss.str();
VERIFY( result2 == "+++++++2,225074e-308" );
oss.str(empty);
oss.clear();
oss.width(20);
oss.precision(10);
oss.setf(ios_base::right, ios_base::adjustfield);
oss.setf(ios_base::scientific, ios_base::floatfield);
oss.setf(ios_base::uppercase);
np.put(oss.rdbuf(), oss, '+', d2);
result1 = oss.str();
VERIFY( result1 == "+++2,2250738585E-308" );
// long double
oss.str(empty);
oss.clear();
np.put(oss.rdbuf(), oss, '+', ld1);
result1 = oss.str();
VERIFY( result1 == "1,7976931349E+308" );
oss.str(empty);
oss.clear();
oss.precision(0);
oss.setf(ios_base::fixed, ios_base::floatfield);
np.put(oss.rdbuf(), oss, '+', ld2);
result1 = oss.str();
VERIFY( result1 == "0" );
// const void
oss.str(empty);
oss.clear();
np.put(oss.rdbuf(), oss, '+', cv);
result1 = oss.str();
// No grouping characters.
VERIFY( !char_traits<char>::find(result1.c_str(),
numpunct_de.decimal_point(),
result1.size()) );
// Should contain an 'x'.
VERIFY( !char_traits<char>::find(result1.c_str(), 'x', result1.size()) );
#ifdef _GLIBCPP_USE_LONG_LONG
long long ll1 = 9223372036854775807;
long long ll2 = -9223372036854775807;
oss.str(empty);
oss.clear();
np.put(oss.rdbuf(), oss, '+', ll1);
result1 = oss.str();
VERIFY( result1 == "9.223.372.036.854.775.807" );
#endif
}
int main()
{
test01();
return 0;
}

View File

@ -0,0 +1,234 @@
// 2001-11-19 Benjamin Kosnik <bkoz@redhat.com>
// Copyright (C) 2001 Free Software Foundation
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 22.2.2.2.1 num_put members
#include <locale>
#include <sstream>
#include <testsuite_hooks.h>
// XXX This test is not working for non-glibc locale models.
// { dg-do run { xfail *-*-* } }
#ifdef _GLIBCPP_USE_WCHAR_T
void test01()
{
using namespace std;
typedef ostreambuf_iterator<wchar_t> iterator_type;
bool test = true;
// basic construction
locale loc_c = locale::classic();
locale loc_hk("en_HK");
locale loc_fr("fr_FR@euro");
locale loc_de("de_DE");
VERIFY( loc_c != loc_de );
VERIFY( loc_hk != loc_fr );
VERIFY( loc_hk != loc_de );
VERIFY( loc_de != loc_fr );
// cache the numpunct facets
const numpunct<wchar_t>& numpunct_c = use_facet<numpunct<wchar_t> >(loc_c);
const numpunct<wchar_t>& numpunct_de = use_facet<numpunct<wchar_t> >(loc_de);
const numpunct<wchar_t>& numpunct_hk = use_facet<numpunct<wchar_t> >(loc_hk);
// sanity check the data is correct.
const wstring empty;
wstring result1;
wstring result2;
wchar_t c;
bool b1 = true;
bool b0 = false;
long l1 = 2147483647;
long l2 = -2147483647;
unsigned long ul1 = 1294967294;
unsigned long ul2 = 0;
double d1 = 1.7976931348623157e+308;
double d2 = 2.2250738585072014e-308;
long double ld1 = 1.7976931348623157e+308;
long double ld2 = 2.2250738585072014e-308;
const void* cv = &ld1;
// cache the num_put facet
wostringstream oss;
oss.imbue(loc_de);
const num_put<wchar_t>& np = use_facet<num_put<wchar_t> >(oss.getloc());
// bool, simple
iterator_type os_it00 = oss.rdbuf();
iterator_type os_it01 = np.put(os_it00, oss, '+', b1);
result1 = oss.str();
VERIFY( result1 == L"1" );
// VERIFY( os_it00 != os_it01 );
oss.str(empty);
np.put(oss.rdbuf(), oss, L'+', b0);
result2 = oss.str();
VERIFY( result2 == L"0" );
// bool, more twisted examples
oss.imbue(loc_c);
oss.str(empty);
oss.width(20);
oss.setf(ios_base::right, ios_base::adjustfield);
np.put(oss.rdbuf(), oss, L'+', b0);
result1 = oss.str();
VERIFY( result1 == L"+++++++++++++++++++0" );
oss.str(empty);
oss.width(20);
oss.setf(ios_base::left, ios_base::adjustfield);
oss.setf(ios_base::boolalpha);
np.put(oss.rdbuf(), oss, L'+', b1);
result2 = oss.str();
VERIFY( result2 == L"true++++++++++++++++" );
// long, in a locale that expects grouping
oss.imbue(loc_hk);
oss.str(empty);
oss.clear();
np.put(oss.rdbuf(), oss, L'+', l1);
result1 = oss.str();
VERIFY( result1 == L"2,147,483,647" );
oss.str(empty);
oss.clear();
oss.width(20);
oss.setf(ios_base::left, ios_base::adjustfield);
np.put(oss.rdbuf(), oss, L'+', l2);
result1 = oss.str();
VERIFY( result1 == L"-2,147,483,647++++++" );
// unsigned long, in a locale that does not group
oss.imbue(loc_c);
oss.str(empty);
oss.clear();
np.put(oss.rdbuf(), oss, L'+', ul1);
result1 = oss.str();
VERIFY( result1 == L"1294967294" );
oss.str(empty);
oss.clear();
oss.width(20);
oss.setf(ios_base::left, ios_base::adjustfield);
np.put(oss.rdbuf(), oss, L'+', ul2);
result1 = oss.str();
VERIFY( result1 == L"0+++++++++++++++++++" );
// ... and one that does
oss.imbue(loc_de);
oss.str(empty);
oss.clear();
oss.width(20);
oss.setf(ios_base::left, ios_base::adjustfield);
np.put(oss.rdbuf(), oss, L'+', ul1);
result1 = oss.str();
VERIFY( result1 == L"1.294.967.294+++++++" );
// double
oss.str(empty);
oss.clear();
oss.width(20);
oss.setf(ios_base::left, ios_base::adjustfield);
np.put(oss.rdbuf(), oss, L'+', d1);
result1 = oss.str();
VERIFY( result1 == L"1,79769e+308++++++++" );
oss.str(empty);
oss.clear();
oss.width(20);
oss.setf(ios_base::right, ios_base::adjustfield);
np.put(oss.rdbuf(), oss, L'+', d2);
result1 = oss.str();
VERIFY( result1 == L"++++++++2,22507e-308" );
oss.str(empty);
oss.clear();
oss.width(20);
oss.setf(ios_base::right, ios_base::adjustfield);
oss.setf(ios_base::scientific, ios_base::floatfield);
np.put(oss.rdbuf(), oss, L'+', d2);
result2 = oss.str();
VERIFY( result2 == L"+++++++2,225074e-308" );
oss.str(empty);
oss.clear();
oss.width(20);
oss.precision(10);
oss.setf(ios_base::right, ios_base::adjustfield);
oss.setf(ios_base::scientific, ios_base::floatfield);
oss.setf(ios_base::uppercase);
np.put(oss.rdbuf(), oss, L'+', d2);
result1 = oss.str();
VERIFY( result1 == L"+++2,2250738585E-308" );
// long double
oss.str(empty);
oss.clear();
np.put(oss.rdbuf(), oss, L'+', ld1);
result1 = oss.str();
VERIFY( result1 == L"1,7976931349E+308" );
oss.str(empty);
oss.clear();
oss.precision(0);
oss.setf(ios_base::fixed, ios_base::floatfield);
np.put(oss.rdbuf(), oss, L'+', ld2);
result1 = oss.str();
VERIFY( result1 == L"0" );
// const void
oss.str(empty);
oss.clear();
np.put(oss.rdbuf(), oss, L'+', cv);
result1 = oss.str();
// No grouping characters.
VERIFY( !char_traits<wchar_t>::find(result1.c_str(),
numpunct_de.decimal_point(),
result1.size()) );
// Should contain an 'x'.
VERIFY( !char_traits<wchar_t>::find(result1.c_str(), L'x', result1.size()) );
#ifdef _GLIBCPP_USE_LONG_LONG
long long ll1 = 9223372036854775807;
long long ll2 = -9223372036854775807;
oss.str(empty);
oss.clear();
np.put(oss.rdbuf(), oss, '+', ll1);
result1 = oss.str();
VERIFY( result1 == L"9.223.372.036.854.775.807" );
#endif
}
#endif
int main()
{
#ifdef _GLIBCPP_USE_WCHAR_T
test01();
#endif
return 0;
}
// Diana D. Brooks, former chief executive of Sotheby's
// art-thief extraordinaire

View File

@ -75,19 +75,12 @@ void test01()
VERIFY( dp2 != dp3 );
VERIFY( th2 != th3 );
#if 0
// XXX isn't actually supported right now.
VERIFY( t2 != t3 );
VERIFY( f2 != f3 );
#endif
VERIFY( dp2 != dp4 );
VERIFY( th2 != th4 );
#if 0
// XXX isn't actually supported right now.
VERIFY( t2 != t3 );
VERIFY( f2 != f3 );
#endif
// XXX This isn't actually supported right now.
// VERIFY( t2 != t3 );
// VERIFY( f2 != f3 );
}
int main()

View File

@ -0,0 +1,88 @@
// 2001-11-20 Benjamin Kosnik <bkoz@redhat.com>
// Copyright (C) 2001 Free Software Foundation
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 22.2.3.1.1 nunpunct members
#include <locale>
#include <testsuite_hooks.h>
// XXX This test is not working for non-glibc locale models.
// { dg-do run { xfail *-*-* } }
void test01()
{
using namespace std;
bool test = true;
// basic construction
locale loc_c = locale::classic();
locale loc_us("en_US");
locale loc_fr("fr_FR");
locale loc_de("de_DE");
VERIFY( loc_c != loc_de );
VERIFY( loc_us != loc_fr );
VERIFY( loc_us != loc_de );
VERIFY( loc_de != loc_fr );
// cache the numpunct facets
const numpunct<wchar_t>& nump_c = use_facet<numpunct<wchar_t> >(loc_c);
const numpunct<wchar_t>& nump_us = use_facet<numpunct<wchar_t> >(loc_us);
const numpunct<wchar_t>& nump_fr = use_facet<numpunct<wchar_t> >(loc_fr);
const numpunct<wchar_t>& nump_de = use_facet<numpunct<wchar_t> >(loc_de);
// sanity check the data is correct.
wchar_t dp1 = nump_c.decimal_point();
wchar_t th1 = nump_c.thousands_sep();
string g1 = nump_c.grouping();
wstring t1 = nump_c.truename();
wstring f1 = nump_c.falsename();
wchar_t dp2 = nump_us.decimal_point();
wchar_t th2 = nump_us.thousands_sep();
string g2 = nump_us.grouping();
wstring t2 = nump_us.truename();
wstring f2 = nump_us.falsename();
wchar_t dp3 = nump_fr.decimal_point();
wchar_t th3 = nump_fr.thousands_sep();
string g3 = nump_fr.grouping();
wstring t3 = nump_fr.truename();
wstring f3 = nump_fr.falsename();
wchar_t dp4 = nump_de.decimal_point();
wchar_t th4 = nump_de.thousands_sep();
string g4 = nump_de.grouping();
wstring t4 = nump_de.truename();
wstring f4 = nump_de.falsename();
VERIFY( dp2 != dp3 );
VERIFY( th2 != th3 );
VERIFY( dp2 != dp4 );
VERIFY( th2 != th4 );
}
int main()
{
test01();
return 0;
}

View File

@ -387,7 +387,7 @@ bool test09()
}
bool test10() {
std::string str_01("0 00 000 +0 + 0 - 0");
std::string str_01("0 00 000 +0 +0 -0");
std::stringbuf isbuf_01(str_01);
std::istream is_01(&isbuf_01);
@ -447,7 +447,7 @@ bool test10() {
VERIFY( n == 33 );
VERIFY( is_03.rdstate() == std::ios_base::eofbit );
std::string str_04("3. 4.5E+ 2a5E-3 .6E1");
std::string str_04("3. 4.5E+2a5E-3 .6E1");
std::stringbuf isbuf_04(str_04);
std::istream is_04(&isbuf_04);

View File

@ -63,13 +63,13 @@ static bool F=false;
static _TestCase testcases[] =
{
#if _GLIBCPP_USE_WCHAR_T
// standard output (no formatting applied)
// standard output (no formatting applied) 1-4
{ 1.2, 6,0,'.',' ', F,F,F,F,F,F,F,F, "1.2",L"1.2" },
{ 54, 6,0,'.',' ', F,F,F,F,F,F,F,F, "54",L"54" },
{ -.012, 6,0,'.',' ', F,F,F,F,F,F,F,F, "-0.012",L"-0.012" },
{ -.00000012, 6,0,'.',' ', F,F,F,F,F,F,F,F, "-1.2e-07",L"-1.2e-07" },
// fixed formatting
// fixed formatting 5-11
{ 10.2345, 0,0,'.',' ', T,F,F,F,F,F,F,F, "10",L"10" },
{ 10.2345, 0,0,'.',' ', T,F,F,T,F,F,F,F, "10.",L"10." },
{ 10.2345, 1,0,'.',' ', T,F,F,F,F,F,F,F, "10.2",L"10.2" },
@ -78,7 +78,7 @@ static _TestCase testcases[] =
{ -10.2345, 6,0,'.',' ', T,F,F,F,F,F,F,F, "-10.234500",L"-10.234500" },
{ -10.2345, 6,0,',',' ', T,F,F,F,F,F,F,F, "-10,234500",L"-10,234500" },
// fixed formatting with width
// fixed formatting with width 12-22
{ 10.2345, 4,5,'.',' ', T,F,F,F,F,F,F,F, "10.2345",L"10.2345" },
{ 10.2345, 4,6,'.',' ', T,F,F,F,F,F,F,F, "10.2345",L"10.2345" },
{ 10.2345, 4,7,'.',' ', T,F,F,F,F,F,F,F, "10.2345",L"10.2345" },
@ -91,7 +91,7 @@ static _TestCase testcases[] =
{ -10.2345, 4,10,'.','A', T,F,F,F,F,T,F,F, "-AA10.2345",L"-AA10.2345" },
{ 10.2345, 4,10,'.','#', T,F,T,F,F,T,F,F, "+##10.2345",L"+##10.2345" },
// scientific formatting
// scientific formatting 23-29
{ 1.23e+12, 1,0,'.',' ', F,T,F,F,F,F,F,F, "1.2e+12",L"1.2e+12" },
{ 1.23e+12, 1,0,'.',' ', F,T,F,F,T,F,F,F, "1.2E+12",L"1.2E+12" },
{ 1.23e+12, 2,0,'.',' ', F,T,F,F,F,F,F,F, "1.23e+12",L"1.23e+12" },
@ -207,7 +207,7 @@ test01()
apply_formatting(tc, os);
os << tc.val;
#ifdef TEST_NUMPUT_VERBOSE
cout << "result: " << os.str() << endl;
cout << j << "result 1: " << os.str() << endl;
#endif
VERIFY( os && os.str() == tc.result );
}
@ -220,7 +220,7 @@ test01()
apply_formatting(tc, os);
os << (long double)tc.val;
#ifdef TEST_NUMPUT_VERBOSE
cout << "result: " << os.str() << endl;
cout << j << "result 2: " << os.str() << endl;
#endif
VERIFY( os && os.str() == tc.result );
}