locale_facets.h: Tweaks for 80 column.

2004-03-23  Benjamin Kosnik  <bkoz@redhat.com>

	* include/bits/locale_facets.h: Tweaks for 80 column.
	(__numpunct_cache::_M_cache): Move to locale_facets.tcc.
	(__moneypunct_cache::_M_cache): Same.
	(num_get): Don't inherit from __num_base.
	(num_put): Same.
	(money_get): Don't inherit from money_base.
	(money_put): Same.
	(__timepunct::_M_am_pm_format): New.
	(time_get::_M_extract_num): Return iterator, use ios_base as argument.
	(time_get::_M_extract_name): Same.
	(time_get::_M_extract_via_format): Same.
	* include/bits/locale_facets.tcc: Tweaks for 80 column.
	Use _M_getloc instead of getloc.
	* testsuite/22_locale/money_put/put/char/9780-3.cc: New.
	* testsuite/22_locale/num_put/put/char/9780-2.cc: New.
	* testsuite/22_locale/time_put/put/char/9780-1.cc: New.

From-SVN: r79902
This commit is contained in:
Benjamin Kosnik 2004-03-24 06:41:07 +00:00 committed by Benjamin Kosnik
parent ae87624ff0
commit 586b5f2013
6 changed files with 510 additions and 255 deletions

View file

@ -1,3 +1,22 @@
2004-03-23 Benjamin Kosnik <bkoz@redhat.com>
* include/bits/locale_facets.h: Tweaks for 80 column.
(__numpunct_cache::_M_cache): Move to locale_facets.tcc.
(__moneypunct_cache::_M_cache): Same.
(num_get): Don't inherit from __num_base.
(num_put): Same.
(money_get): Don't inherit from money_base.
(money_put): Same.
(__timepunct::_M_am_pm_format): New.
(time_get::_M_extract_num): Return iterator, use ios_base as argument.
(time_get::_M_extract_name): Same.
(time_get::_M_extract_via_format): Same.
* include/bits/locale_facets.tcc: Tweaks for 80 column.
Use _M_getloc instead of getloc.
* testsuite/22_locale/money_put/put/char/9780-3.cc: New.
* testsuite/22_locale/num_put/put/char/9780-2.cc: New.
* testsuite/22_locale/time_put/put/char/9780-1.cc: New.
2004-03-22 Paolo Carlini <pcarlini@suse.de>
* acinclude.m4 (GLIBCXX_ENABLE_ALLOCATOR): Add pool_allocator.

View file

@ -1451,14 +1451,15 @@ namespace std
/**
* @brief Narrow wchar_t to char
*
* This virtual function converts the argument to char using the
* simplest reasonable transformation. If the conversion fails, dfault
* is returned instead. For an underived ctype<wchar_t> facet, @a c will
* be cast to char and returned.
* This virtual function converts the argument to char using
* the simplest reasonable transformation. If the conversion
* fails, dfault is returned instead. For an underived
* ctype<wchar_t> facet, @a c will be cast to char and
* returned.
*
* do_narrow() is a hook for a derived facet to change the behavior of
* narrowing. do_narrow() must always return the same result for the
* same input.
* do_narrow() is a hook for a derived facet to change the
* behavior of narrowing. do_narrow() must always return the
* same result for the same input.
*
* Note: this is not what you want for codepage conversions. See
* codecvt for that.
@ -1625,40 +1626,6 @@ namespace std
_M_cache(const locale& __loc);
};
template<typename _CharT>
void
__numpunct_cache<_CharT>::_M_cache(const locale& __loc)
{
_M_allocated = true;
const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
_M_grouping_size = __np.grouping().size();
char* __grouping = new char[_M_grouping_size];
__np.grouping().copy(__grouping, _M_grouping_size);
_M_grouping = __grouping;
_M_use_grouping = _M_grouping_size && __np.grouping()[0] != 0;
_M_truename_size = __np.truename().size();
_CharT* __truename = new _CharT[_M_truename_size];
__np.truename().copy(__truename, _M_truename_size);
_M_truename = __truename;
_M_falsename_size = __np.falsename().size();
_CharT* __falsename = new _CharT[_M_falsename_size];
__np.falsename().copy(__falsename, _M_falsename_size);
_M_falsename = __falsename;
_M_decimal_point = __np.decimal_point();
_M_thousands_sep = __np.thousands_sep();
const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
__ct.widen(__num_base::_S_atoms_out,
__num_base::_S_atoms_out + __num_base::_S_oend, _M_atoms_out);
__ct.widen(__num_base::_S_atoms_in,
__num_base::_S_atoms_in + __num_base::_S_iend, _M_atoms_in);
}
template<typename _CharT>
__numpunct_cache<_CharT>::~__numpunct_cache()
{
@ -1755,8 +1722,8 @@ namespace std
/**
* @brief Return thousands separator character.
*
* This function returns a char_type to use as a thousands separator. It
* does so by returning returning
* This function returns a char_type to use as a thousands
* separator. It does so by returning returning
* numpunct<char_type>::do_thousands_sep().
*
* @return char_type representing a thousands separator.
@ -1772,18 +1739,20 @@ namespace std
* integer part of a number. Groupings indicate where thousands
* separators should be inserted in the integer part of a number.
*
* Each char in the return string is interpret as an integer rather
* than a character. These numbers represent the number of digits in a
* group. The first char in the string represents the number of digits
* in the least significant group. If a char is negative, it indicates
* an unlimited number of digits for the group. If more chars from the
* Each char in the return string is interpret as an integer
* rather than a character. These numbers represent the number
* of digits in a group. The first char in the string
* represents the number of digits in the least significant
* group. If a char is negative, it indicates an unlimited
* number of digits for the group. If more chars from the
* string are required to group a number, the last char is used
* repeatedly.
*
* For example, if the grouping() returns "\003\002" and is applied to
* the number 123456789, this corresponds to 12,34,56,789. Note that
* if the string was "32", this would put more than 50 digits into the
* least significant group if the character set is ASCII.
* For example, if the grouping() returns "\003\002" and is
* applied to the number 123456789, this corresponds to
* 12,34,56,789. Note that if the string was "32", this would
* put more than 50 digits into the least significant group if
* the character set is ASCII.
*
* The string is returned by calling
* numpunct<char_type>::do_grouping().
@ -1950,7 +1919,7 @@ namespace std
* implement the behavior they require from the num_get facet.
*/
template<typename _CharT, typename _InIter>
class num_get : public locale::facet, public __num_base
class num_get : public locale::facet
{
public:
// Types:
@ -1979,10 +1948,11 @@ namespace std
* Parses the input stream into the bool @a v. It does so by calling
* num_put::do_put().
*
* If ios_base::boolalpha is set, attempts to read ctype<CharT>::truename() or
* ctype<CharT>::falsename(). Sets @a v to true or false if
* successful. Sets err to ios_base::failbit if reading the string
* fails. Sets err to ios_base::eofbit if the stream is emptied.
* If ios_base::boolalpha is set, attempts to read
* ctype<CharT>::truename() or ctype<CharT>::falsename(). Sets
* @a v to true or false if successful. Sets err to
* ios_base::failbit if reading the string fails. Sets err to
* ios_base::eofbit if the stream is emptied.
*
* If ios_base::boolalpha is not set, proceeds as with reading a long,
* except if the value is 1, sets @a v to true, if the value is 0, sets
@ -2228,7 +2198,7 @@ namespace std
* implement the behavior they require from the num_put facet.
*/
template<typename _CharT, typename _OutIter>
class num_put : public locale::facet, public __num_base
class num_put : public locale::facet
{
public:
// Types:
@ -2274,8 +2244,8 @@ namespace std
/**
* @brief Numeric formatting.
*
* Formats the integral value @a v and inserts it into a stream. It does so
* by calling num_put::do_put().
* Formats the integral value @a v and inserts it into a
* stream. It does so by calling num_put::do_put().
*
* Formatting is affected by the flag settings in @a io.
*
@ -2794,7 +2764,7 @@ namespace std
{
if (_M_allocated)
{
// XXX.
// Unused.
}
}
@ -2870,13 +2840,6 @@ namespace std
__time[1] = _M_data->_M_time_era_format;
}
void
_M_ampm(const _CharT** __ampm) const
{
__ampm[0] = _M_data->_M_am;
__ampm[1] = _M_data->_M_pm;
}
void
_M_date_time_formats(const _CharT** __dt) const
{
@ -2885,6 +2848,17 @@ namespace std
__dt[1] = _M_data->_M_date_time_era_format;
}
void
_M_am_pm_format(const _CharT* __ampm) const
{ __ampm = _M_data->_M_am_pm_format; }
void
_M_am_pm(const _CharT** __ampm) const
{
__ampm[0] = _M_data->_M_am;
__ampm[1] = _M_data->_M_pm;
}
void
_M_days(const _CharT** __days) const
{
@ -3280,23 +3254,21 @@ namespace std
ios_base::iostate& __err, tm* __tm) const;
// Extract numeric component of length __len.
void
_M_extract_num(iter_type& __beg, iter_type& __end, int& __member,
iter_type
_M_extract_num(iter_type __beg, iter_type __end, int& __member,
int __min, int __max, size_t __len,
const ctype<_CharT>& __ctype,
ios_base::iostate& __err) const;
ios_base& __io, ios_base::iostate& __err) const;
// Extract day or month name, or any unique array of string
// literals in a const _CharT* array.
void
_M_extract_name(iter_type& __beg, iter_type& __end, int& __member,
iter_type
_M_extract_name(iter_type __beg, iter_type __end, int& __member,
const _CharT** __names, size_t __indexlen,
const ctype<_CharT>& __ctype,
ios_base::iostate& __err) const;
ios_base& __io, ios_base::iostate& __err) const;
// Extract on a component-by-component basis, via __format argument.
void
_M_extract_via_format(iter_type& __beg, iter_type& __end, ios_base& __io,
iter_type
_M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io,
ios_base::iostate& __err, tm* __tm,
const _CharT* __format) const;
};
@ -3333,7 +3305,7 @@ namespace std
* implement the behavior they require from the time_put facet.
*/
template<typename _CharT, typename _OutIter>
class time_put : public locale::facet, public time_base
class time_put : public locale::facet
{
public:
// Types:
@ -3535,48 +3507,6 @@ namespace std
}
}
template<typename _CharT, bool _Intl>
void
__moneypunct_cache<_CharT, _Intl>::_M_cache(const locale& __loc)
{
_M_allocated = true;
const moneypunct<_CharT, _Intl>& __mp =
use_facet<moneypunct<_CharT, _Intl> >(__loc);
_M_grouping_size = __mp.grouping().size();
char* __grouping = new char[_M_grouping_size];
__mp.grouping().copy(__grouping, _M_grouping_size);
_M_grouping = __grouping;
_M_use_grouping = _M_grouping_size && __mp.grouping()[0] != 0;
_M_decimal_point = __mp.decimal_point();
_M_thousands_sep = __mp.thousands_sep();
_M_frac_digits = __mp.frac_digits();
_M_curr_symbol_size = __mp.curr_symbol().size();
_CharT* __curr_symbol = new _CharT[_M_curr_symbol_size];
__mp.curr_symbol().copy(__curr_symbol, _M_curr_symbol_size);
_M_curr_symbol = __curr_symbol;
_M_positive_sign_size = __mp.positive_sign().size();
_CharT* __positive_sign = new _CharT[_M_positive_sign_size];
__mp.positive_sign().copy(__positive_sign, _M_positive_sign_size);
_M_positive_sign = __positive_sign;
_M_negative_sign_size = __mp.negative_sign().size();
_CharT* __negative_sign = new _CharT[_M_negative_sign_size];
__mp.negative_sign().copy(__negative_sign, _M_negative_sign_size);
_M_negative_sign = __negative_sign;
_M_pos_format = __mp.pos_format();
_M_neg_format = __mp.neg_format();
const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
__ct.widen(money_base::_S_atoms,
money_base::_S_atoms + money_base::_S_end, _M_atoms);
}
/**
* @brief Facet for formatting data for money amounts.
*
@ -3660,8 +3590,8 @@ namespace std
/**
* @brief Return thousands separator character.
*
* This function returns a char_type to use as a thousands separator. It
* does so by returning returning
* This function returns a char_type to use as a thousands
* separator. It does so by returning returning
* moneypunct<char_type>::do_thousands_sep().
*
* @return char_type representing a thousands separator.
@ -4012,7 +3942,7 @@ namespace std
* the money_get facet.
*/
template<typename _CharT, typename _InIter>
class money_get : public locale::facet, public money_base
class money_get : public locale::facet
{
public:
// Types:
@ -4147,7 +4077,7 @@ namespace std
* the money_put facet.
*/
template<typename _CharT, typename _OutIter>
class money_put : public locale::facet, public money_base
class money_put : public locale::facet
{
public:
//@{

View file

@ -122,6 +122,7 @@ namespace std
operator() (const locale& __loc) const;
};
// Specializations.
template<typename _CharT>
struct __use_cache<__numpunct_cache<_CharT> >
{
@ -149,6 +150,111 @@ namespace std
}
};
template<typename _CharT, bool _Intl>
struct __use_cache<__moneypunct_cache<_CharT, _Intl> >
{
const __moneypunct_cache<_CharT, _Intl>*
operator() (const locale& __loc) const
{
const size_t __i = moneypunct<_CharT, _Intl>::id._M_id();
const locale::facet** __caches = __loc._M_impl->_M_caches;
if (!__caches[__i])
{
__moneypunct_cache<_CharT, _Intl>* __tmp = NULL;
try
{
__tmp = new __moneypunct_cache<_CharT, _Intl>;
__tmp->_M_cache(__loc);
}
catch(...)
{
delete __tmp;
__throw_exception_again;
}
__loc._M_impl->_M_install_cache(__tmp, __i);
}
return static_cast<
const __moneypunct_cache<_CharT, _Intl>*>(__caches[__i]);
}
};
template<typename _CharT>
void
__numpunct_cache<_CharT>::_M_cache(const locale& __loc)
{
_M_allocated = true;
const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
_M_grouping_size = __np.grouping().size();
char* __grouping = new char[_M_grouping_size];
__np.grouping().copy(__grouping, _M_grouping_size);
_M_grouping = __grouping;
_M_use_grouping = _M_grouping_size && __np.grouping()[0] != 0;
_M_truename_size = __np.truename().size();
_CharT* __truename = new _CharT[_M_truename_size];
__np.truename().copy(__truename, _M_truename_size);
_M_truename = __truename;
_M_falsename_size = __np.falsename().size();
_CharT* __falsename = new _CharT[_M_falsename_size];
__np.falsename().copy(__falsename, _M_falsename_size);
_M_falsename = __falsename;
_M_decimal_point = __np.decimal_point();
_M_thousands_sep = __np.thousands_sep();
const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
__ct.widen(__num_base::_S_atoms_out,
__num_base::_S_atoms_out + __num_base::_S_oend, _M_atoms_out);
__ct.widen(__num_base::_S_atoms_in,
__num_base::_S_atoms_in + __num_base::_S_iend, _M_atoms_in);
}
template<typename _CharT, bool _Intl>
void
__moneypunct_cache<_CharT, _Intl>::_M_cache(const locale& __loc)
{
_M_allocated = true;
const moneypunct<_CharT, _Intl>& __mp =
use_facet<moneypunct<_CharT, _Intl> >(__loc);
_M_grouping_size = __mp.grouping().size();
char* __grouping = new char[_M_grouping_size];
__mp.grouping().copy(__grouping, _M_grouping_size);
_M_grouping = __grouping;
_M_use_grouping = _M_grouping_size && __mp.grouping()[0] != 0;
_M_decimal_point = __mp.decimal_point();
_M_thousands_sep = __mp.thousands_sep();
_M_frac_digits = __mp.frac_digits();
_M_curr_symbol_size = __mp.curr_symbol().size();
_CharT* __curr_symbol = new _CharT[_M_curr_symbol_size];
__mp.curr_symbol().copy(__curr_symbol, _M_curr_symbol_size);
_M_curr_symbol = __curr_symbol;
_M_positive_sign_size = __mp.positive_sign().size();
_CharT* __positive_sign = new _CharT[_M_positive_sign_size];
__mp.positive_sign().copy(__positive_sign, _M_positive_sign_size);
_M_positive_sign = __positive_sign;
_M_negative_sign_size = __mp.negative_sign().size();
_CharT* __negative_sign = new _CharT[_M_negative_sign_size];
__mp.negative_sign().copy(__negative_sign, _M_negative_sign_size);
_M_negative_sign = __negative_sign;
_M_pos_format = __mp.pos_format();
_M_neg_format = __mp.neg_format();
const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
__ct.widen(money_base::_S_atoms,
money_base::_S_atoms + money_base::_S_end, _M_atoms);
}
// Used by both numeric and monetary facets.
// Check to make sure that the __grouping_tmp string constructed in
// money_get or num_get matches the canonical grouping for a given
@ -181,8 +287,8 @@ namespace std
if (__beg != __end)
{
const char_type __c = *__beg;
const bool __plus = __c == __lit[_S_iplus];
if ((__plus || __c == __lit[_S_iminus])
const bool __plus = __c == __lit[__num_base::_S_iplus];
if ((__plus || __c == __lit[__num_base::_S_iminus])
&& !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
&& !(__c == __lc->_M_decimal_point))
{
@ -198,7 +304,7 @@ namespace std
if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep
|| __c == __lc->_M_decimal_point)
break;
else if (__c == __lit[_S_izero])
else if (__c == __lit[__num_base::_S_izero])
{
if (!__found_mantissa)
{
@ -218,7 +324,7 @@ namespace std
if (__lc->_M_use_grouping)
__found_grouping.reserve(32);
int __sep_pos = 0;
const char_type* __lit_zero = __lit + _S_izero;
const char_type* __lit_zero = __lit + __num_base::_S_izero;
const char_type* __q;
while (__beg != __end)
{
@ -264,12 +370,13 @@ namespace std
}
else if (__q = __traits_type::find(__lit_zero, 10, __c))
{
__xtrc += _S_atoms_in[__q - __lit];
__xtrc += __num_base::_S_atoms_in[__q - __lit];
__found_mantissa = true;
++__sep_pos;
++__beg;
}
else if ((__c == __lit[_S_ie] || __c == __lit[_S_iE])
else if ((__c == __lit[__num_base::_S_ie]
|| __c == __lit[__num_base::_S_iE])
&& __found_mantissa && !__found_sci)
{
// Scientific notation.
@ -281,8 +388,8 @@ namespace std
// Remove optional plus or minus sign, if they exist.
if (++__beg != __end)
{
const bool __plus = *__beg == __lit[_S_iplus];
if ((__plus || *__beg == __lit[_S_iminus])
const bool __plus = *__beg == __lit[__num_base::_S_iplus];
if ((__plus || *__beg == __lit[__num_base::_S_iminus])
&& !(__lc->_M_use_grouping
&& *__beg == __lc->_M_thousands_sep)
&& !(*__beg == __lc->_M_decimal_point))
@ -305,7 +412,8 @@ namespace std
if (!__found_dec && !__found_sci)
__found_grouping += static_cast<char>(__sep_pos);
if (!std::__verify_grouping(__lc->_M_grouping, __lc->_M_grouping_size,
if (!std::__verify_grouping(__lc->_M_grouping,
__lc->_M_grouping_size,
__found_grouping))
__err |= ios_base::failbit;
}
@ -345,8 +453,8 @@ namespace std
{
const char_type __c = *__beg;
if (numeric_limits<_ValueT>::is_signed)
__negative = __c == __lit[_S_iminus];
if ((__negative || __c == __lit[_S_iplus])
__negative = __c == __lit[__num_base::_S_iminus];
if ((__negative || __c == __lit[__num_base::_S_iplus])
&& !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
&& !(__c == __lc->_M_decimal_point))
++__beg;
@ -360,14 +468,16 @@ namespace std
if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep
|| __c == __lc->_M_decimal_point)
break;
else if (__c == __lit[_S_izero] && (!__found_num || __base == 10))
else if (__c == __lit[__num_base::_S_izero]
&& (!__found_num || __base == 10))
{
__found_num = true;
++__beg;
}
else if (__found_num)
{
if (__c == __lit[_S_ix] || __c == __lit[_S_iX])
if (__c == __lit[__num_base::_S_ix]
|| __c == __lit[__num_base::_S_iX])
{
if (__basefield == 0)
__base = 16;
@ -387,7 +497,7 @@ namespace std
// At this point, base is determined. If not hex, only allow
// base digits as valid input.
const size_t __len = __base == 16 ? _S_iend - _S_izero : __base;
const size_t __len = __base == 16 ? __num_base::_S_iend - __num_base::_S_izero : __base;
// Extract.
string __found_grouping;
@ -396,7 +506,7 @@ namespace std
int __sep_pos = 0;
bool __overflow = false;
_ValueT __result = 0;
const char_type* __lit_zero = __lit + _S_izero;
const char_type* __lit_zero = __lit + __num_base::_S_izero;
const char_type* __q;
if (__negative)
{
@ -736,8 +846,8 @@ namespace std
template<typename _CharT>
inline int
__int_to_char(_CharT* __bufend, unsigned long long __v, const _CharT* __lit,
ios_base::fmtflags __flags)
__int_to_char(_CharT* __bufend, unsigned long long __v,
const _CharT* __lit, ios_base::fmtflags __flags)
{ return __int_to_char(__bufend, __v, __lit, __flags, false); }
#endif
@ -960,7 +1070,7 @@ namespace std
int __cs_size = __max_digits * 3;
char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
_S_format_float(__io, __fbuf, __mod);
__num_base::_S_format_float(__io, __fbuf, __mod);
__len = std::__convert_from_v(__cs, __cs_size, __fbuf, __v,
_S_get_c_locale(), __prec);
@ -987,7 +1097,7 @@ namespace std
: __max_digits * 3;
char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
_S_format_float(__io, __fbuf, __mod);
__num_base::_S_format_float(__io, __fbuf, __mod);
__len = std::__convert_from_v(__cs, 0, __fbuf, __v,
_S_get_c_locale(), __prec);
#endif
@ -1133,34 +1243,6 @@ namespace std
return __s;
}
template<typename _CharT, bool _Intl>
struct __use_cache<__moneypunct_cache<_CharT, _Intl> >
{
const __moneypunct_cache<_CharT, _Intl>*
operator() (const locale& __loc) const
{
const size_t __i = moneypunct<_CharT, _Intl>::id._M_id();
const locale::facet** __caches = __loc._M_impl->_M_caches;
if (!__caches[__i])
{
__moneypunct_cache<_CharT, _Intl>* __tmp = NULL;
try
{
__tmp = new __moneypunct_cache<_CharT, _Intl>;
__tmp->_M_cache(__loc);
}
catch(...)
{
delete __tmp;
__throw_exception_again;
}
__loc._M_impl->_M_install_cache(__tmp, __i);
}
return static_cast<
const __moneypunct_cache<_CharT, _Intl>*>(__caches[__i]);
}
};
template<typename _CharT, typename _InIter>
template<bool _Intl>
_InIter
@ -1205,7 +1287,7 @@ namespace std
string __res;
__res.reserve(32);
const char_type* __lit_zero = __lit + _S_zero;
const char_type* __lit_zero = __lit + money_base::_S_zero;
const char_type* __q;
const money_base::pattern __p = __lc->_M_neg_format;
for (int __i = 0; __i < 4 && __testvalid; ++__i)
@ -1222,9 +1304,9 @@ namespace std
|| __i == 0
|| (__i == 1 && (__mandatory_sign
|| (static_cast<part>(__p.field[0])
== sign)
== money_base::sign)
|| (static_cast<part>(__p.field[2])
== space)))
== money_base::space)))
|| (__i == 2 && ((static_cast<part>(__p.field[3])
== money_base::value)
|| __mandatory_sign
@ -1270,7 +1352,7 @@ namespace std
for (; __beg != __end; ++__beg)
if (__q = __traits_type::find(__lit_zero, 10, *__beg))
{
__res += _S_atoms[__q - __lit];
__res += money_base::_S_atoms[__q - __lit];
++__n;
}
else if (*__beg == __lc->_M_decimal_point && !__testdecfound)
@ -1443,7 +1525,7 @@ namespace std
money_base::pattern __p;
const char_type* __sign;
size_type __sign_size;
if (*__beg != __lit[_S_minus])
if (*__beg != __lit[money_base::_S_minus])
{
__p = __lc->_M_pos_format;
__sign = __lc->_M_positive_sign;
@ -1501,13 +1583,14 @@ namespace std
else
{
// Have to pad zeros in the decimal position.
__value.append(-__paddec, __lit[_S_zero]);
__value.append(-__paddec, __lit[money_base::_S_zero]);
__value.append(__beg, __len);
}
}
// Calculate length of resulting string.
const ios_base::fmtflags __f = __io.flags() & ios_base::adjustfield;
const ios_base::fmtflags __f = __io.flags()
& ios_base::adjustfield;
__len = __value.size() + __sign_size;
__len += ((__io.flags() & ios_base::showbase)
? __lc->_M_curr_symbol_size : 0);
@ -1515,7 +1598,7 @@ namespace std
string_type __res;
__res.reserve(2 * __len);
const size_type __width = static_cast<size_type>(__io.width());
const size_type __width = static_cast<size_type>(__io.width());
const bool __testipad = (__f == ios_base::internal
&& __len < __width);
// Fit formatted digits into the required pattern.
@ -1626,6 +1709,7 @@ namespace std
{ return __intl ? _M_insert<true>(__s, __io, __fill, __digits)
: _M_insert<false>(__s, __io, __fill, __digits); }
// NB: Not especially useful. Without an ios_base object or some
// kind of locale reference, we are left clawing at the air where
// the side of the mountain used to be...
@ -1639,13 +1723,13 @@ namespace std
// specific string, which may contain yet more strings. I.e. %x => %r =>
// %H:%M:%S => extracted characters.
template<typename _CharT, typename _InIter>
void
_InIter
time_get<_CharT, _InIter>::
_M_extract_via_format(iter_type& __beg, iter_type& __end, ios_base& __io,
_M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io,
ios_base::iostate& __err, tm* __tm,
const _CharT* __format) const
{
const locale __loc = __io.getloc();
const locale& __loc = __io._M_getloc();
const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
const size_t __len = char_traits<_CharT>::length(__format);
@ -1667,81 +1751,81 @@ namespace std
// Abbreviated weekday name [tm_wday]
const char_type* __days1[7];
__tp._M_days_abbreviated(__days1);
_M_extract_name(__beg, __end, __tm->tm_wday, __days1, 7,
__ctype, __err);
__beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days1,
7, __io, __err);
break;
case 'A':
// Weekday name [tm_wday].
const char_type* __days2[7];
__tp._M_days(__days2);
_M_extract_name(__beg, __end, __tm->tm_wday, __days2, 7,
__ctype, __err);
__beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days2,
7, __io, __err);
break;
case 'h':
case 'b':
// Abbreviated month name [tm_mon]
const char_type* __months1[12];
__tp._M_months_abbreviated(__months1);
_M_extract_name(__beg, __end, __tm->tm_mon, __months1, 12,
__ctype, __err);
__beg = _M_extract_name(__beg, __end, __tm->tm_mon,
__months1, 12, __io, __err);
break;
case 'B':
// Month name [tm_mon].
const char_type* __months2[12];
__tp._M_months(__months2);
_M_extract_name(__beg, __end, __tm->tm_mon, __months2, 12,
__ctype, __err);
__beg = _M_extract_name(__beg, __end, __tm->tm_mon,
__months2, 12, __io, __err);
break;
case 'c':
// Default time and date representation.
const char_type* __dt[2];
__tp._M_date_time_formats(__dt);
_M_extract_via_format(__beg, __end, __io, __err, __tm,
__dt[0]);
__beg = _M_extract_via_format(__beg, __end, __io, __err,
__tm, __dt[0]);
break;
case 'd':
// Day [01, 31]. [tm_mday]
_M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2,
__ctype, __err);
__beg = _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2,
__io, __err);
break;
case 'e':
// Day [1, 31], with single digits preceded by
// space. [tm_mday]
if (__ctype.is(ctype_base::space, *__beg))
_M_extract_num(++__beg, __end, __tm->tm_mday, 1, 9, 1,
__ctype, __err);
__beg = _M_extract_num(++__beg, __end, __tm->tm_mday, 1, 9,
1, __io, __err);
else
_M_extract_num(__beg, __end, __tm->tm_mday, 10, 31, 2,
__ctype, __err);
__beg = _M_extract_num(__beg, __end, __tm->tm_mday, 10, 31,
2, __io, __err);
break;
case 'D':
// Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year]
__cs = "%m/%d/%y";
__ctype.widen(__cs, __cs + 9, __wcs);
_M_extract_via_format(__beg, __end, __io, __err, __tm,
__wcs);
__beg = _M_extract_via_format(__beg, __end, __io, __err,
__tm, __wcs);
break;
case 'H':
// Hour [00, 23]. [tm_hour]
_M_extract_num(__beg, __end, __tm->tm_hour, 0, 23, 2,
__ctype, __err);
__beg = _M_extract_num(__beg, __end, __tm->tm_hour, 0, 23, 2,
__io, __err);
break;
case 'I':
// Hour [01, 12]. [tm_hour]
_M_extract_num(__beg, __end, __tm->tm_hour, 1, 12, 2,
__ctype, __err);
__beg = _M_extract_num(__beg, __end, __tm->tm_hour, 1, 12, 2,
__io, __err);
break;
case 'm':
// Month [01, 12]. [tm_mon]
_M_extract_num(__beg, __end, __mem, 1, 12, 2, __ctype,
__err);
__beg = _M_extract_num(__beg, __end, __mem, 1, 12, 2,
__io, __err);
if (!__err)
__tm->tm_mon = __mem - 1;
break;
case 'M':
// Minute [00, 59]. [tm_min]
_M_extract_num(__beg, __end, __tm->tm_min, 0, 59, 2,
__ctype, __err);
__beg = _M_extract_num(__beg, __end, __tm->tm_min, 0, 59, 2,
__io, __err);
break;
case 'n':
if (__ctype.narrow(*__beg, 0) == '\n')
@ -1753,13 +1837,13 @@ namespace std
// Equivalent to (%H:%M).
__cs = "%H:%M";
__ctype.widen(__cs, __cs + 6, __wcs);
_M_extract_via_format(__beg, __end, __io, __err, __tm,
__wcs);
__beg = _M_extract_via_format(__beg, __end, __io, __err,
__tm, __wcs);
break;
case 'S':
// Seconds.
_M_extract_num(__beg, __end, __tm->tm_sec, 0, 59, 2,
__ctype, __err);
__beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 59, 2,
__io, __err);
break;
case 't':
if (__ctype.narrow(*__beg, 0) == '\t')
@ -1771,33 +1855,33 @@ namespace std
// Equivalent to (%H:%M:%S).
__cs = "%H:%M:%S";
__ctype.widen(__cs, __cs + 9, __wcs);
_M_extract_via_format(__beg, __end, __io, __err, __tm,
__wcs);
__beg = _M_extract_via_format(__beg, __end, __io, __err,
__tm, __wcs);
break;
case 'x':
// Locale's date.
const char_type* __dates[2];
__tp._M_date_formats(__dates);
_M_extract_via_format(__beg, __end, __io, __err, __tm,
__dates[0]);
__beg = _M_extract_via_format(__beg, __end, __io, __err,
__tm, __dates[0]);
break;
case 'X':
// Locale's time.
const char_type* __times[2];
__tp._M_time_formats(__times);
_M_extract_via_format(__beg, __end, __io, __err, __tm,
__times[0]);
__beg = _M_extract_via_format(__beg, __end, __io, __err,
__tm, __times[0]);
break;
case 'y':
case 'C': // C99
// Two digit year. [tm_year]
_M_extract_num(__beg, __end, __tm->tm_year, 0, 99, 2,
__ctype, __err);
__beg = _M_extract_num(__beg, __end, __tm->tm_year, 0, 99, 2,
__io, __err);
break;
case 'Y':
// Year [1900). [tm_year]
_M_extract_num(__beg, __end, __mem, 0, 9999, 4,
__ctype, __err);
__beg = _M_extract_num(__beg, __end, __mem, 0, 9999, 4,
__io, __err);
if (!__err)
__tm->tm_year = __mem - 1900;
break;
@ -1806,19 +1890,19 @@ namespace std
if (__ctype.is(ctype_base::upper, *__beg))
{
int __tmp;
_M_extract_name(__beg, __end, __tmp,
__timepunct_cache<_CharT>::_S_timezones,
14, __ctype, __err);
__beg = _M_extract_name(__beg, __end, __tmp,
__timepunct_cache<_CharT>::_S_timezones,
14, __io, __err);
// GMT requires special effort.
if (__beg != __end && !__err && __tmp == 0
&& (*__beg == __ctype.widen('-')
|| *__beg == __ctype.widen('+')))
{
_M_extract_num(__beg, __end, __tmp, 0, 23, 2,
__ctype, __err);
_M_extract_num(__beg, __end, __tmp, 0, 59, 2,
__ctype, __err);
__beg = _M_extract_num(__beg, __end, __tmp, 0, 23, 2,
__io, __err);
__beg = _M_extract_num(__beg, __end, __tmp, 0, 59, 2,
__io, __err);
}
}
else
@ -1838,16 +1922,19 @@ namespace std
__err |= ios_base::failbit;
}
}
return __beg;
}
template<typename _CharT, typename _InIter>
void
_InIter
time_get<_CharT, _InIter>::
_M_extract_num(iter_type& __beg, iter_type& __end, int& __member,
_M_extract_num(iter_type __beg, iter_type __end, int& __member,
int __min, int __max, size_t __len,
const ctype<_CharT>& __ctype,
ios_base::iostate& __err) const
ios_base& __io, ios_base::iostate& __err) const
{
const locale& __loc = __io._M_getloc();
const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
// As-is works for __len = 1, 2, 4, the values actually used.
int __mult = __len == 2 ? 10 : (__len == 4 ? 1000 : 1);
@ -1872,19 +1959,22 @@ namespace std
__member = __value;
else
__err |= ios_base::failbit;
return __beg;
}
// Assumptions:
// All elements in __names are unique.
template<typename _CharT, typename _InIter>
void
_InIter
time_get<_CharT, _InIter>::
_M_extract_name(iter_type& __beg, iter_type& __end, int& __member,
_M_extract_name(iter_type __beg, iter_type __end, int& __member,
const _CharT** __names, size_t __indexlen,
const ctype<_CharT>& __ctype,
ios_base::iostate& __err) const
ios_base& __io, ios_base::iostate& __err) const
{
typedef char_traits<_CharT> __traits_type;
const locale& __loc = __io._M_getloc();
const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
int* __matches = static_cast<int*>(__builtin_alloca(sizeof(int)
* __indexlen));
size_t __nmatches = 0;
@ -1911,7 +2001,7 @@ namespace std
size_t __minlen = 10;
for (size_t __i2 = 0; __i2 < __nmatches; ++__i2)
__minlen = std::min(__minlen,
__traits_type::length(__names[__matches[__i2]]));
__traits_type::length(__names[__matches[__i2]]));
++__beg;
if (__pos < __minlen && __beg != __end)
{
@ -1951,6 +2041,7 @@ namespace std
__testvalid = false;
if (!__testvalid)
__err |= ios_base::failbit;
return __beg;
}
template<typename _CharT, typename _InIter>
@ -1961,10 +2052,10 @@ namespace std
{
_CharT __wcs[3];
const char* __cs = "%X";
const locale __loc = __io.getloc();
const locale& __loc = __io._M_getloc();
ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
__ctype.widen(__cs, __cs + 3, __wcs);
_M_extract_via_format(__beg, __end, __io, __err, __tm, __wcs);
__beg = _M_extract_via_format(__beg, __end, __io, __err, __tm, __wcs);
if (__beg == __end)
__err |= ios_base::eofbit;
return __beg;
@ -1978,10 +2069,10 @@ namespace std
{
_CharT __wcs[3];
const char* __cs = "%x";
const locale __loc = __io.getloc();
const locale& __loc = __io._M_getloc();
ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
__ctype.widen(__cs, __cs + 3, __wcs);
_M_extract_via_format(__beg, __end, __io, __err, __tm, __wcs);
__beg = _M_extract_via_format(__beg, __end, __io, __err, __tm, __wcs);
if (__beg == __end)
__err |= ios_base::eofbit;
return __beg;
@ -1994,13 +2085,13 @@ namespace std
ios_base::iostate& __err, tm* __tm) const
{
typedef char_traits<_CharT> __traits_type;
const locale __loc = __io.getloc();
const locale& __loc = __io._M_getloc();
const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
const char_type* __days[7];
__tp._M_days_abbreviated(__days);
int __tmpwday;
_M_extract_name(__beg, __end, __tmpwday, __days, 7, __ctype, __err);
__beg = _M_extract_name(__beg, __end, __tmpwday, __days, 7, __io, __err);
// Check to see if non-abbreviated name exists, and extract.
// NB: Assumes both _M_days and _M_days_abbreviated organized in
@ -2038,13 +2129,14 @@ namespace std
ios_base& __io, ios_base::iostate& __err, tm* __tm) const
{
typedef char_traits<_CharT> __traits_type;
const locale __loc = __io.getloc();
const locale& __loc = __io._M_getloc();
const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
const char_type* __months[12];
__tp._M_months_abbreviated(__months);
int __tmpmon;
_M_extract_name(__beg, __end, __tmpmon, __months, 12, __ctype, __err);
__beg = _M_extract_name(__beg, __end, __tmpmon, __months, 12,
__io, __err);
// Check to see if non-abbreviated name exists, and extract.
// NB: Assumes both _M_months and _M_months_abbreviated organized in
@ -2082,7 +2174,7 @@ namespace std
do_get_year(iter_type __beg, iter_type __end, ios_base& __io,
ios_base::iostate& __err, tm* __tm) const
{
const locale __loc = __io.getloc();
const locale& __loc = __io._M_getloc();
const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
size_t __i = 0;
@ -2110,7 +2202,7 @@ namespace std
put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm,
const _CharT* __beg, const _CharT* __end) const
{
const locale __loc = __io.getloc();
const locale& __loc = __io._M_getloc();
ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
for (; __beg != __end; ++__beg)
if (__ctype.narrow(*__beg, 0) != '%')
@ -2132,8 +2224,7 @@ namespace std
}
else
break;
__s = this->do_put(__s, __io, __fill, __tm,
__format, __mod);
__s = this->do_put(__s, __io, __fill, __tm, __format, __mod);
}
else
break;
@ -2146,16 +2237,15 @@ namespace std
do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm,
char __format, char __mod) const
{
const locale __loc = __io.getloc();
const locale& __loc = __io._M_getloc();
ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
__timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
// NB: This size is arbitrary. Should this be a data member,
// initialized at construction?
const size_t __maxlen = 64;
char_type* __res =
static_cast<char_type*>(__builtin_alloca(sizeof(char_type)
* __maxlen));
char_type* __res =
static_cast<char_type*>(__builtin_alloca(sizeof(char_type) * __maxlen));
// NB: In IEE 1003.1-200x, and perhaps other locale models, it
// is possible that the format character will be longer than one

View file

@ -0,0 +1,43 @@
// Copyright (C) 2004 Free Software Foundation, Inc.
//
// 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.
#include <sstream>
#include <locale>
#include <testsuite_hooks.h>
int main()
{
using namespace std;
bool test __attribute__((unused)) = true;
locale l1 = __gnu_test::try_named_locale("de_DE");
locale l2 = __gnu_test::try_named_locale("es_ES");
const money_put<char>& mp = use_facet<money_put<char> >(l1);
ostringstream oss;
oss.imbue(l2);
oss.setf(ios_base::showbase);
long double ld = -1234567890;
mp.put(oss.rdbuf(), true, oss, ' ', ld); // -EUR 12.345.678,90
string res = oss.str();
VERIFY( res == "-EUR 12.345.678,90" );
return 0;
}

View file

@ -0,0 +1,42 @@
// Copyright (C) 2004 Free Software Foundation, Inc.
//
// 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.
#include <sstream>
#include <locale>
#include <testsuite_hooks.h>
int main()
{
using namespace std;
bool test __attribute__((unused)) = true;
locale l1 = __gnu_test::try_named_locale("de_DE");
locale l2 = __gnu_test::try_named_locale("es_ES");
const num_put<char>& np = use_facet<num_put<char> >(l1);
ostringstream oss;
oss.imbue(l2);
long l = 1234567890;
np.put(oss.rdbuf(), oss, ' ', l); // 1234567890
string res = oss.str();
VERIFY( res == "1234567890" );
return 0;
}

View file

@ -0,0 +1,131 @@
// Copyright (C) 2004 Free Software Foundation, Inc.
//
// 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.
#include <sstream>
#include <locale>
#include <testsuite_hooks.h>
int main()
{
using namespace std;
bool test __attribute__((unused)) = true;
locale l1 = __gnu_test::try_named_locale("de_DE");
locale l2 = __gnu_test::try_named_locale("es_ES");
const time_put<char> &tp = use_facet<time_put<char> >(l1);
ostringstream oss;
oss.imbue(l2);
tm t = tm();
tp.put(oss.rdbuf(), oss, ' ', &t, 'A');
string res = oss.str();
VERIFY( res == "domingo" );
return 0;
}
// Two interpretations of the standard.
// 1 : time_get, time_put each have their own data internally
// use internal data for time and date specifics
// use getloc for ctype info
// 2 : time_get, time_put use the ios_base& argument and getloc to
// retrieve the necessary data.
// use getloc for ctype, time and date specifics
// It is my opinion that the language in the standard is sufficiently
// vague to permit both interpretations. In particular, the interface
// for time_get and time_put is based on strftime, which as
// POSIX notes is dependent on LC_TIME. The C++ standard, however,
// does not specify the equivalent mappings of LC_TIME to time_get and
// time_put.
/*
The problems with the first approach, as above, are numerous.
1) Then locale usage and design for formatters and parers becomes
fragmented. On one side, num_put and money_put, and on the other,
time_put. This inconsistency is not useful.
2) The data structures for time and date formatting are the largest in
the locale library. Making time_put and time_get keep separate
copies is inefficient. (Note that time_put and time_get are in the
same locale::category).
*/
/*
22.2.5 - The time category [lib.category.time]
-1- Templates time_get<charT,InputIterator> and
time_put<charT,OutputIterator> provide date and time formatting and
parsing. All specifications of member functions for time_put and
time_get in the subclauses of lib.category.time only apply to the
instantiations required in Tables ?? and ??
(lib.locale.category). Their members use their ios_base&,
ios_base::iostate&, and fill arguments as described in
(lib.locale.categories), and the ctype<> facet, to determine
formatting details.
*/
/*
22.2 - Standard locale categories [lib.locale.categories]
-1- Each of the standard categories includes a family of facets. Some
of these implement formatting or parsing of a datum, for use by
standard or users' iostream operators << and >>, as members put() and
get(), respectively. Each such member function takes an ios_base&
argument whose members flags(), precision(), and width(), specify the
format of the corresponding datum. (lib.ios.base). Those functions
which need to use other facets call its member getloc() to retrieve
the locale imbued there. Formatting facets use the character argument
fill to fill out the specified width where necessary.
*/
/*
With GCC/libstdc++, the output of the program with the arguments
of de_DE es_ES is:
domingo
lunes
martes
miércoles
jueves
viernes
sábado
With Intel C++, it is: (this is clearly wrong)
Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
And with RogueWave C++
Sonntag
Montag
Dienstag
Mittwoch
Donnerstag
Freitag
Samstag
*/