Commit 69971cd8 by Benjamin Kosnik Committed by Benjamin Kosnik

Implement std::money_put.


2001-09-09  Benjamin Kosnik  <bkoz@redhat.com>

	Implement std::money_put.
	* include/bits/locale_facets.h
	(moneypunct::_M_initialize_moneypunct): Split up specializations
	to account for _Intl.  More grody hacking to get around the
	ill-considered use of const bool as a template parameter.
	* config/locale/moneypunct_members_gnu.cc: And here.
	* config/locale/moneypunct_members_generic.cc: And here.
	* testsuite/22_locale/moneypunct_members_char.cc: Add tests.
	* testsuite/22_locale/moneypunct.cc: Add tests.
	* testsuite/22_locale/money_put_members_wchar_t.cc: New file.
	* testsuite/22_locale/moneypunct_members_wchar_t.cc: New file.

	* src/locale.cc (money_base::_S_construct_pattern): Move into
	gnu-specific file.
	* config/locale/moneypunct_members_gnu.cc: Add here.
	* config/locale/moneypunct_members_generic.cc: Add generic version
	here.

	* include/bits/locale_facets.tcc (money_put::do_put): Move member
	function definitions here.
	* include/bits/locale_facets.h (money_put): Implement.
	* src/locale-inst.cc: Add use_facet instantiations for moneypunct.
	Correct money_get, money_put instantiations.
	* src/locale.cc (money_base::_S_construct_pattern): Handle case
	where __posn == 0.
	* testsuite/22_locale/money_put_members_char.cc: Add tests.

From-SVN: r45496
parent 1650fcad
2001-09-09 Benjamin Kosnik <bkoz@redhat.com>
Implement std::money_put.
* include/bits/locale_facets.h
(moneypunct::_M_initialize_moneypunct): Split up specializations
to account for _Intl. More grody hacking to get around the
ill-considered use of const bool as a template parameter.
* config/locale/moneypunct_members_gnu.cc: And here.
* config/locale/moneypunct_members_generic.cc: And here.
* testsuite/22_locale/moneypunct_members_char.cc: Add tests.
* testsuite/22_locale/moneypunct.cc: Add tests.
* testsuite/22_locale/money_put_members_wchar_t.cc: New file.
* testsuite/22_locale/moneypunct_members_wchar_t.cc: New file.
* src/locale.cc (money_base::_S_construct_pattern): Move into
gnu-specific file.
* config/locale/moneypunct_members_gnu.cc: Add here.
* config/locale/moneypunct_members_generic.cc: Add generic version
here.
* include/bits/locale_facets.tcc (money_put::do_put): Move member
function definitions here.
* include/bits/locale_facets.h (money_put): Implement.
* src/locale-inst.cc: Add use_facet instantiations for moneypunct.
Correct money_get, money_put instantiations.
* src/locale.cc (money_base::_S_construct_pattern): Handle case
where __posn == 0.
* testsuite/22_locale/money_put_members_char.cc: Add tests.
2001-09-05 Phil Edwards <pme@sources.redhat.com>
* testsuite_flags.in: No longer need to search testsuite builddir.
......
......@@ -37,9 +37,31 @@
namespace std
{
// Construct and return valid pattern consisting of some combination of:
// space none symbol sign value
money_base::pattern
money_base::_S_construct_pattern(char __preceeds, char __space, char __posn)
{ return _S_default_pattern; }
template<>
void
moneypunct<char, true>::_M_initialize_moneypunct(__c_locale)
{
// "C" locale
_M_decimal_point = '.';
_M_thousands_sep = ',';
_M_grouping = "";
_M_curr_symbol = string_type();
_M_positive_sign = string_type();
_M_negative_sign = string_type();
_M_frac_digits = 0;
_M_pos_format = money_base::_S_default_pattern;
_M_neg_format = money_base::_S_default_pattern;
}
template<>
void
moneypunct<char>::_M_initialize_moneypunct(__c_locale)
moneypunct<char, false>::_M_initialize_moneypunct(__c_locale)
{
// "C" locale
_M_decimal_point = '.';
......@@ -56,7 +78,23 @@ namespace std
#ifdef _GLIBCPP_USE_WCHAR_T
template<>
void
moneypunct<wchar_t>::_M_initialize_moneypunct(__c_locale)
moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale)
{
// "C" locale
_M_decimal_point = L'.';
_M_thousands_sep = L',';
_M_grouping = "";
_M_curr_symbol = string_type();
_M_positive_sign = string_type();
_M_negative_sign = string_type();
_M_frac_digits = 0;
_M_pos_format = money_base::_S_default_pattern;
_M_neg_format = money_base::_S_default_pattern;
}
template<>
void
moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale)
{
// "C" locale
_M_decimal_point = L'.';
......
......@@ -1271,26 +1271,24 @@ namespace std
iter_type
put(iter_type __s, bool __intl, ios_base& __f,
char_type __fill, long double __units) const
{ return do_put(__s, __intl, __f, __fill, __units); }
{ return this->do_put(__s, __intl, __f, __fill, __units); }
iter_type
put(iter_type __s, bool __intl, ios_base& __f,
char_type __fill, const string_type& __digits) const
{ return do_put(__s, __intl, __f, __fill, __digits); }
{ return this->do_put(__s, __intl, __f, __fill, __digits); }
protected:
virtual
~money_put() { }
virtual iter_type
do_put(iter_type __s, bool, ios_base& /*__io*/, char_type /*__fill*/,
long double /*__units*/) const
{ return __s; }
do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
long double __units) const;
virtual iter_type
do_put(iter_type __s, bool, ios_base& /*__io*/, char_type /*__fill*/,
const string_type& /*__digits*/) const
{ return __s; }
do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
const string_type& __digits) const;
};
template<typename _CharT, typename _OutIter>
......@@ -1417,8 +1415,8 @@ namespace std
{ return _M_neg_format; }
// For use at construction time only.
void
_M_initialize_moneypunct(__c_locale __cloc = NULL);
void
_M_initialize_moneypunct(__c_locale __cloc = NULL);
};
template<typename _CharT, bool _Intl>
......@@ -1427,21 +1425,28 @@ namespace std
template<typename _CharT, bool _Intl>
const bool moneypunct<_CharT, _Intl>::intl;
// NB: Cannot be made generic.
template<typename _CharT, bool _Intl>
void
moneypunct<_CharT, _Intl>::_M_initialize_moneypunct(__c_locale /*__cloc*/)
{
// NB: Cannot be made generic.
}
moneypunct<_CharT, _Intl>::_M_initialize_moneypunct(__c_locale)
{ }
template<>
void
moneypunct<char, true>::_M_initialize_moneypunct(__c_locale __cloc);
template<>
void
moneypunct<char>::_M_initialize_moneypunct(__c_locale __cloc);
moneypunct<char, false>::_M_initialize_moneypunct(__c_locale __cloc);
#ifdef _GLIBCPP_USE_WCHAR_T
template<>
void
moneypunct<wchar_t>::_M_initialize_moneypunct(__c_locale __cloc);
moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale __cloc);
template<>
void
moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale __cloc);
#endif
template<typename _CharT, bool _Intl>
......@@ -1625,10 +1630,10 @@ namespace std
};
// Subclause convenience interfaces, inlines
// NB: these are inline
// because, when used in a loop, some compilers can hoist the body
// out of the loop; then it's just as fast as the C is*() function.
// Subclause convenience interfaces, inlines.
// NB: These are inline because, when used in a loop, some compilers
// can hoist the body out of the loop; then it's just as fast as the
// C is*() function.
template<typename _CharT>
inline bool
isspace(_CharT __c, const locale& __loc)
......@@ -1694,8 +1699,4 @@ namespace std
{ return use_facet<ctype<_CharT> >(__loc).tolower(__c); }
} // namespace std
#endif /* _CPP_BITS_LOCFACETS_H */
// Local Variables:
// mode:c++
// End:
#endif
......@@ -128,9 +128,4 @@ namespace std
#endif
} // namespace std
#endif // _CPP_IOSFWD
#endif
......@@ -54,10 +54,8 @@ namespace std
template class moneypunct<char, true>;
template class moneypunct_byname<char, false>;
template class moneypunct_byname<char, true>;
template class money_get<char, obuf_iterator>;
template class money_put<char, obuf_iterator>;
template class money_get<char, ibuf_iterator>;
template class money_put<char, ibuf_iterator>;
template class money_put<char, obuf_iterator>;
template class _Format_cache<char>;
#ifdef _GLIBCPP_USE_WCHAR_T
......@@ -65,10 +63,8 @@ namespace std
template class moneypunct<wchar_t, true>;
template class moneypunct_byname<wchar_t, false>;
template class moneypunct_byname<wchar_t, true>;
template class money_get<wchar_t, wobuf_iterator>;
template class money_put<wchar_t, wobuf_iterator>;
template class money_get<wchar_t, wibuf_iterator>;
template class money_put<wchar_t, wibuf_iterator>;
template class money_put<wchar_t, wobuf_iterator>;
template class _Format_cache<wchar_t>;
#endif
......@@ -149,6 +145,12 @@ namespace std
template
const collate<char>&
use_facet<collate<char> >(const locale&);
template
const moneypunct<char, true>&
use_facet<moneypunct<char, true> >(const locale&);
template
const moneypunct<char, false>&
use_facet<moneypunct<char, false> >(const locale&);
#ifdef _GLIBCPP_USE_WCHAR_T
template
const num_put<wchar_t, wobuf_iterator>&
......@@ -165,6 +167,12 @@ namespace std
template
const collate<wchar_t>&
use_facet<collate<wchar_t> >(const locale&);
template
const moneypunct<wchar_t, true>&
use_facet<moneypunct<wchar_t, true> >(const locale&);
template
const moneypunct<wchar_t, false>&
use_facet<moneypunct<wchar_t, false> >(const locale&);
#endif
// has_facet
......
......@@ -162,182 +162,6 @@ namespace std
0
};
// Construct and return valid pattern consisting of some combination of:
// space none symbol sign value
money_base::pattern
money_base::_S_construct_pattern(char __preceeds, char __space, char __posn)
{
pattern __ret;
// This insanely complicated routine attempts to construct a valid
// pattern for use with monyepunct. A couple of invariants:
// if (__preceeds) symbol -> value
// else value -> symbol
// if (__space) space
// else none
// none == never first
// space never first or last
// Any elegant implementations of this are welcome.
switch (__posn)
{
case 1:
// 1 The sign precedes the value and symbol.
if (__space)
{
// Pattern starts with sign.
if (__preceeds)
{
__ret.field[1] = symbol;
__ret.field[2] = space;
__ret.field[3] = value;
}
else
{
__ret.field[1] = value;
__ret.field[2] = space;
__ret.field[3] = symbol;
}
__ret.field[0] = sign;
}
else
{
// Pattern starts with sign and ends with none.
if (__preceeds)
{
__ret.field[1] = symbol;
__ret.field[2] = value;
}
else
{
__ret.field[1] = value;
__ret.field[2] = symbol;
}
__ret.field[0] = sign;
__ret.field[3] = none;
}
break;
case 2:
// 2 The sign follows the value and symbol.
if (__space)
{
// Pattern either ends with sign.
if (__preceeds)
{
__ret.field[0] = symbol;
__ret.field[1] = space;
__ret.field[2] = value;
}
else
{
__ret.field[0] = value;
__ret.field[1] = space;
__ret.field[2] = symbol;
}
__ret.field[3] = sign;
}
else
{
// Pattern ends with sign then none.
if (__preceeds)
{
__ret.field[0] = symbol;
__ret.field[1] = value;
}
else
{
__ret.field[0] = value;
__ret.field[1] = symbol;
}
__ret.field[2] = sign;
__ret.field[3] = none;
}
break;
case 3:
// 3 The sign immediately precedes the symbol.
if (__space)
{
// Have space.
if (__preceeds)
{
__ret.field[0] = sign;
__ret.field[1] = symbol;
__ret.field[2] = space;
__ret.field[3] = value;
}
else
{
__ret.field[0] = value;
__ret.field[1] = space;
__ret.field[2] = sign;
__ret.field[3] = symbol;
}
}
else
{
// Have none.
if (__preceeds)
{
__ret.field[0] = sign;
__ret.field[1] = symbol;
__ret.field[2] = value;
}
else
{
__ret.field[0] = value;
__ret.field[1] = sign;
__ret.field[2] = symbol;
}
__ret.field[3] = none;
}
break;
case 4:
// 4 The sign immediately follows the symbol.
if (__space)
{
// Have space.
if (__preceeds)
{
__ret.field[0] = symbol;
__ret.field[1] = sign;
__ret.field[2] = space;
__ret.field[3] = value;
}
else
{
__ret.field[0] = value;
__ret.field[1] = space;
__ret.field[2] = symbol;
__ret.field[3] = sign;
}
}
else
{
// Have none.
if (__preceeds)
{
__ret.field[0] = symbol;
__ret.field[1] = sign;
__ret.field[2] = value;
}
else
{
__ret.field[0] = value;
__ret.field[1] = symbol;
__ret.field[2] = sign;
}
__ret.field[3] = none;
}
break;
default:
;
}
return __ret;
}
locale::~locale() throw()
{ _M_impl->_M_remove_reference(); }
......
......@@ -96,7 +96,7 @@ namespace std
_M_init_facet(new std::ctype<char>);
_M_init_facet(new codecvt<char, char, mbstate_t>);
_M_init_facet(new moneypunct<char, false>(__cloc));
_M_init_facet(new moneypunct<char,true>(__cloc));
_M_init_facet(new moneypunct<char, true>(__cloc));
_M_init_facet(new money_get<char>);
_M_init_facet(new money_put<char>);
_M_init_facet(new numpunct<char>(__cloc));
......@@ -111,7 +111,7 @@ namespace std
_M_init_facet(new std::ctype<wchar_t>);
_M_init_facet(new codecvt<wchar_t, char, mbstate_t>);
_M_init_facet(new moneypunct<wchar_t, false>(__cloc));
_M_init_facet(new moneypunct<wchar_t,true>(__cloc));
_M_init_facet(new moneypunct<wchar_t, true>(__cloc));
_M_init_facet(new money_get<wchar_t>);
_M_init_facet(new money_put<wchar_t>);
_M_init_facet(new numpunct<wchar_t>(__cloc));
......
......@@ -21,16 +21,19 @@
// 22.2.6.2.1 money_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 *-*-* } }
// test string version
void test01()
{
using namespace std;
typedef money_base::part part;
typedef money_base::pattern pattern;
typedef ostreambuf_iterator<char> iterator_type;
bool test = true;
string str;
......@@ -39,11 +42,11 @@ void test01()
locale loc_c = locale::classic();
str = loc_c.name();
locale loc_us("en_US");
str = loc_us.name();
VERIFY( loc_c != loc_us );
locale loc_hk("en_HK");
str = loc_hk.name();
VERIFY( loc_c != loc_hk );
locale loc_fr("fr_FR");
locale loc_fr("fr_FR@euro");
str = loc_fr.name();
VERIFY( loc_c != loc_fr );
......@@ -51,23 +54,218 @@ void test01()
str = loc_de.name();
VERIFY( loc_c != loc_de );
VERIFY( loc_us != loc_fr );
VERIFY( loc_us != loc_de );
VERIFY( loc_hk != loc_fr );
VERIFY( loc_hk != loc_de );
VERIFY( loc_de != loc_fr );
// cache the money_put facets
const money_put<char>& monp_c = use_facet<money_put<char> >(loc_c);
const money_put<char>& monp_us = use_facet<money_put<char> >(loc_us);
const money_put<char>& monp_fr = use_facet<money_put<char> >(loc_fr);
const money_put<char>& monp_de = use_facet<money_put<char> >(loc_de);
// cache the moneypunct facets
typedef moneypunct<char, true> __money_true;
typedef moneypunct<char, false> __money_false;
const __money_true& monpunct_c_t = use_facet<__money_true>(loc_c);
const __money_true& monpunct_de_t = use_facet<__money_true>(loc_de);
const __money_false& monpunct_c_f = use_facet<__money_false>(loc_c);
const __money_false& monpunct_de_f = use_facet<__money_false>(loc_de);
const __money_true& monpunct_hk_t = use_facet<__money_true>(loc_hk);
const __money_false& monpunct_hk_f = use_facet<__money_false>(loc_hk);
// sanity check the data is correct.
// VERIFY( dp1 != dp2 );
const string empty;
// total EPA budget FY 2002
const string digits1("720000000000");
// est. cost, national missle "defense", expressed as a loss in USD 2001
const string digits2("-10000000000000");
// not valid input
const string digits3("-A");
// input less than frac_digits
const string digits4("-1");
ostringstream oss;
oss.imbue(loc_de);
// cache the money_put facet
const money_put<char>& mon_put = use_facet<money_put<char> >(oss.getloc());
iterator_type os_it01 = mon_put.put(oss.rdbuf(), true, oss, '*', digits1);
string result1 = oss.str();
VERIFY( result1 == "7.200.000.000,00 ");
oss.str(empty);
iterator_type os_it02 = mon_put.put(oss.rdbuf(), false, oss, '*', digits1);
string result2 = oss.str();
VERIFY( result2 == "7.200.000.000,00 ");
// intl and non-intl versions should be the same.
VERIFY( result1 == result2 );
// now try with showbase, to get currency symbol in format
oss.setf(ios_base::showbase);
oss.str(empty);
iterator_type os_it03 = mon_put.put(oss.rdbuf(), true, oss, '*', digits1);
string result3 = oss.str();
VERIFY( result3 == "7.200.000.000,00 DEM ");
oss.str(empty);
iterator_type os_it04 = mon_put.put(oss.rdbuf(), false, oss, '*', digits1);
string result4 = oss.str();
VERIFY( result4 == "7.200.000.000,00 DM");
// intl and non-intl versions should be different.
VERIFY( result3 != result4 );
VERIFY( result3 != result1 );
VERIFY( result4 != result2 );
// test sign of more than one digit, say hong kong.
oss.imbue(loc_hk);
oss.str(empty);
iterator_type os_it05 = mon_put.put(oss.rdbuf(), false, oss, '*', digits1);
string result5 = oss.str();
VERIFY( result5 == "HK$7,200,000,000.00");
oss.str(empty);
iterator_type os_it06 = mon_put.put(oss.rdbuf(), true, oss, '*', digits2);
string result6 = oss.str();
VERIFY( result6 == "(HKD 100,000,000,000.00)");
// test one-digit formats without zero padding
oss.imbue(loc_c);
oss.str(empty);
iterator_type os_it07 = mon_put.put(oss.rdbuf(), true, oss, '*', digits4);
string result7 = oss.str();
VERIFY( result7 == "1");
// test one-digit formats with zero padding, zero frac widths
oss.imbue(loc_hk);
oss.str(empty);
iterator_type os_it08 = mon_put.put(oss.rdbuf(), true, oss, '*', digits4);
string result8 = oss.str();
VERIFY( result8 == "(HKD .01)");
oss.unsetf(ios_base::showbase);
// test bunk input
oss.str(empty);
iterator_type os_it09 = mon_put.put(oss.rdbuf(), true, oss, '*', digits3);
string result9 = oss.str();
VERIFY( result9 == "");
// test io.width() > length
// test various fill strategies
oss.imbue(loc_de);
oss.str(empty);
oss.width(20);
iterator_type os_it10 = mon_put.put(oss.rdbuf(), true, oss, '*', digits4);
string result10 = oss.str();
VERIFY( result10 == "***************-,01 ");
oss.str(empty);
oss.width(20);
oss.setf(ios_base::internal);
iterator_type os_it11 = mon_put.put(oss.rdbuf(), true, oss, '*', digits4);
string result11 = oss.str();
VERIFY( result11 == "-,01****************");
}
// test double/string versions
void test02()
{
using namespace std;
typedef money_base::part part;
typedef money_base::pattern pattern;
typedef ostreambuf_iterator<char> iterator_type;
bool test = true;
string str;
// basic construction
locale loc_c = locale::classic();
str = loc_c.name();
locale loc_hk("en_HK");
str = loc_hk.name();
VERIFY( loc_c != loc_hk );
locale loc_fr("fr_FR@euro");
str = loc_fr.name();
VERIFY( loc_c != loc_fr );
locale loc_de("de_DE");
str = loc_de.name();
VERIFY( loc_c != loc_de );
VERIFY( loc_hk != loc_fr );
VERIFY( loc_hk != loc_de );
VERIFY( loc_de != loc_fr );
// cache the moneypunct facets
typedef moneypunct<char, true> __money_true;
typedef moneypunct<char, false> __money_false;
const __money_true& monpunct_c_t = use_facet<__money_true>(loc_c);
const __money_true& monpunct_de_t = use_facet<__money_true>(loc_de);
const __money_false& monpunct_c_f = use_facet<__money_false>(loc_c);
const __money_false& monpunct_de_f = use_facet<__money_false>(loc_de);
const __money_true& monpunct_hk_t = use_facet<__money_true>(loc_hk);
const __money_false& monpunct_hk_f = use_facet<__money_false>(loc_hk);
// sanity check the data is correct.
const string empty;
// total EPA budget FY 2002
const long double digits1 = 720000000000;
// est. cost, national missle "defense", expressed as a loss in USD 2001
const long double digits2 = -10000000000000;
// input less than frac_digits
const long double digits4 = -1;
ostringstream oss;
oss.imbue(loc_de);
// cache the money_put facet
const money_put<char>& mon_put = use_facet<money_put<char> >(oss.getloc());
iterator_type os_it01 = mon_put.put(oss.rdbuf(), true, oss, '*', digits1);
string result1 = oss.str();
VERIFY( result1 == "7.200.000.000,00 ");
oss.str(empty);
iterator_type os_it02 = mon_put.put(oss.rdbuf(), false, oss, '*', digits1);
string result2 = oss.str();
VERIFY( result2 == "7.200.000.000,00 ");
// intl and non-intl versions should be the same.
VERIFY( result1 == result2 );
// now try with showbase, to get currency symbol in format
oss.setf(ios_base::showbase);
oss.str(empty);
iterator_type os_it03 = mon_put.put(oss.rdbuf(), true, oss, '*', digits1);
string result3 = oss.str();
VERIFY( result3 == "7.200.000.000,00 DEM ");
oss.str(empty);
iterator_type os_it04 = mon_put.put(oss.rdbuf(), false, oss, '*', digits1);
string result4 = oss.str();
VERIFY( result4 == "7.200.000.000,00 DM");
// intl and non-intl versions should be different.
VERIFY( result3 != result4 );
VERIFY( result3 != result1 );
VERIFY( result4 != result2 );
}
int main()
{
test01();
test02();
return 0;
}
// 2001-09-09 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.6.2.1 money_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
// test string version
void test01()
{
using namespace std;
typedef money_base::part part;
typedef money_base::pattern pattern;
typedef ostreambuf_iterator<wchar_t> iterator_type;
bool test = true;
string str;
// basic construction
locale loc_c = locale::classic();
str = loc_c.name();
locale loc_hk("en_HK");
str = loc_hk.name();
VERIFY( loc_c != loc_hk );
locale loc_fr("fr_FR@euro");
str = loc_fr.name();
VERIFY( loc_c != loc_fr );
locale loc_de("de_DE");
str = loc_de.name();
VERIFY( loc_c != loc_de );
VERIFY( loc_hk != loc_fr );
VERIFY( loc_hk != loc_de );
VERIFY( loc_de != loc_fr );
// cache the moneypunct facets
typedef moneypunct<wchar_t, true> __money_true;
typedef moneypunct<wchar_t, false> __money_false;
const __money_true& monpunct_c_t = use_facet<__money_true>(loc_c);
const __money_true& monpunct_de_t = use_facet<__money_true>(loc_de);
const __money_false& monpunct_c_f = use_facet<__money_false>(loc_c);
const __money_false& monpunct_de_f = use_facet<__money_false>(loc_de);
const __money_true& monpunct_hk_t = use_facet<__money_true>(loc_hk);
const __money_false& monpunct_hk_f = use_facet<__money_false>(loc_hk);
// sanity check the data is correct.
const wstring empty;
// total EPA budget FY 2002
const wstring digits1(L"720000000000");
// est. cost, national missle "defense", expressed as a loss in USD 2001
const wstring digits2(L"-10000000000000");
// not valid input
const wstring digits3(L"-A");
// input less than frac_digits
const wstring digits4(L"-1");
wostringstream oss;
oss.imbue(loc_de);
// cache the money_put facet
const money_put<wchar_t>& mon_put = use_facet<money_put<wchar_t> >(oss.getloc());
iterator_type os_it01 = mon_put.put(oss.rdbuf(), true, oss, '*', digits1);
wstring result1 = oss.str();
VERIFY( result1 == L"7.200.000.000,00 ");
oss.str(empty);
iterator_type os_it02 = mon_put.put(oss.rdbuf(), false, oss, '*', digits1);
wstring result2 = oss.str();
VERIFY( result2 == L"7.200.000.000,00 ");
// intl and non-intl versions should be the same.
VERIFY( result1 == result2 );
// now try with showbase, to get currency symbol in format
oss.setf(ios_base::showbase);
oss.str(empty);
iterator_type os_it03 = mon_put.put(oss.rdbuf(), true, oss, '*', digits1);
wstring result3 = oss.str();
VERIFY( result3 == L"7.200.000.000,00 DEM ");
oss.str(empty);
iterator_type os_it04 = mon_put.put(oss.rdbuf(), false, oss, '*', digits1);
wstring result4 = oss.str();
VERIFY( result4 == L"7.200.000.000,00 DM");
// intl and non-intl versions should be different.
VERIFY( result3 != result4 );
VERIFY( result3 != result1 );
VERIFY( result4 != result2 );
// test sign of more than one digit, say hong kong.
oss.imbue(loc_hk);
oss.str(empty);
iterator_type os_it05 = mon_put.put(oss.rdbuf(), false, oss, '*', digits1);
wstring result5 = oss.str();
VERIFY( result5 == L"HK$7,200,000,000.00");
oss.str(empty);
iterator_type os_it06 = mon_put.put(oss.rdbuf(), true, oss, '*', digits2);
wstring result6 = oss.str();
VERIFY( result6 == L"(HKD 100,000,000,000.00)");
// test one-digit formats without zero padding
oss.imbue(loc_c);
oss.str(empty);
iterator_type os_it07 = mon_put.put(oss.rdbuf(), true, oss, '*', digits4);
wstring result7 = oss.str();
VERIFY( result7 == L"1");
// test one-digit formats with zero padding, zero frac widths
oss.imbue(loc_hk);
oss.str(empty);
iterator_type os_it08 = mon_put.put(oss.rdbuf(), true, oss, '*', digits4);
wstring result8 = oss.str();
VERIFY( result8 == L"(HKD .01)");
oss.unsetf(ios_base::showbase);
// test bunk input
oss.str(empty);
iterator_type os_it09 = mon_put.put(oss.rdbuf(), true, oss, '*', digits3);
wstring result9 = oss.str();
VERIFY( result9 == L"");
// test io.width() > length
// test various fill strategies
oss.imbue(loc_de);
oss.str(empty);
oss.width(20);
iterator_type os_it10 = mon_put.put(oss.rdbuf(), true, oss, '*', digits4);
wstring result10 = oss.str();
VERIFY( result10 == L"***************-,01 ");
oss.str(empty);
oss.width(20);
oss.setf(ios_base::internal);
iterator_type os_it11 = mon_put.put(oss.rdbuf(), true, oss, '*', digits4);
wstring result11 = oss.str();
VERIFY( result11 == L"-,01****************");
}
// test double/wstring versions
void test02()
{
using namespace std;
typedef money_base::part part;
typedef money_base::pattern pattern;
typedef ostreambuf_iterator<wchar_t> iterator_type;
bool test = true;
string str;
// basic construction
locale loc_c = locale::classic();
str = loc_c.name();
locale loc_hk("en_HK");
str = loc_hk.name();
VERIFY( loc_c != loc_hk );
locale loc_fr("fr_FR@euro");
str = loc_fr.name();
VERIFY( loc_c != loc_fr );
locale loc_de("de_DE");
str = loc_de.name();
VERIFY( loc_c != loc_de );
VERIFY( loc_hk != loc_fr );
VERIFY( loc_hk != loc_de );
VERIFY( loc_de != loc_fr );
// cache the moneypunct facets
typedef moneypunct<wchar_t, true> __money_true;
typedef moneypunct<wchar_t, false> __money_false;
const __money_true& monpunct_c_t = use_facet<__money_true>(loc_c);
const __money_true& monpunct_de_t = use_facet<__money_true>(loc_de);
const __money_false& monpunct_c_f = use_facet<__money_false>(loc_c);
const __money_false& monpunct_de_f = use_facet<__money_false>(loc_de);
const __money_true& monpunct_hk_t = use_facet<__money_true>(loc_hk);
const __money_false& monpunct_hk_f = use_facet<__money_false>(loc_hk);
// sanity check the data is correct.
const wstring empty;
// total EPA budget FY 2002
const long double digits1 = 720000000000;
// est. cost, national missle "defense", expressed as a loss in USD 2001
const long double digits2 = -10000000000000;
// input less than frac_digits
const long double digits4 = -1;
wostringstream oss;
oss.imbue(loc_de);
// cache the money_put facet
const money_put<wchar_t>& mon_put = use_facet<money_put<wchar_t> >(oss.getloc());
iterator_type os_it01 = mon_put.put(oss.rdbuf(), true, oss, '*', digits1);
wstring result1 = oss.str();
VERIFY( result1 == L"7.200.000.000,00 ");
oss.str(empty);
iterator_type os_it02 = mon_put.put(oss.rdbuf(), false, oss, '*', digits1);
wstring result2 = oss.str();
VERIFY( result2 == L"7.200.000.000,00 ");
// intl and non-intl versions should be the same.
VERIFY( result1 == result2 );
// now try with showbase, to get currency symbol in format
oss.setf(ios_base::showbase);
oss.str(empty);
iterator_type os_it03 = mon_put.put(oss.rdbuf(), true, oss, '*', digits1);
wstring result3 = oss.str();
VERIFY( result3 == L"7.200.000.000,00 DEM ");
oss.str(empty);
iterator_type os_it04 = mon_put.put(oss.rdbuf(), false, oss, '*', digits1);
wstring result4 = oss.str();
VERIFY( result4 == L"7.200.000.000,00 DM");
// intl and non-intl versions should be different.
VERIFY( result3 != result4 );
VERIFY( result3 != result1 );
VERIFY( result4 != result2 );
}
#endif
int main()
{
#ifdef _GLIBCPP_USE_WCHAR_T
test01();
test02();
#endif
return 0;
}
......@@ -21,11 +21,25 @@
// 22.2.6.3 Template class moneypunct
#include <locale>
#include <testsuite_hooks.h>
void test01()
{
// Check for required base class.
typedef std::moneypunct<char> test_type;
typedef std::moneypunct<char, true> 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::string_type string_type;
}
void test02()
{
// Check for required base class.
typedef std::moneypunct<char, false> test_type;
typedef std::locale::facet base_type;
const test_type& obj = std::use_facet<test_type>(std::locale());
const base_type* base = &obj;
......@@ -36,17 +50,24 @@ void test01()
}
// Should be able to instantiate this for other types besides char, wchar_t
class gnu_moneypunct: public std::moneypunct<unsigned char>
class gnu_moneypunct_t: public std::moneypunct<unsigned char, true>
{ };
void test02()
class gnu_moneypunct_f: public std::moneypunct<unsigned char, false>
{ };
void test03()
{
gnu_moneypunct facet01;
gnu_moneypunct_t facet01;
gnu_moneypunct_f facet02;
VERIFY (facet01.intl == true);
VERIFY (facet02.intl == false);
}
int main()
{
test01();
test02();
test03();
return 0;
}
......@@ -56,31 +56,47 @@ void test01()
VERIFY( loc_de != loc_fr );
// cache the moneypunct facets
const moneypunct<char>& monp_c = use_facet<moneypunct<char> >(loc_c);
const moneypunct<char>& monp_us = use_facet<moneypunct<char> >(loc_us);
const moneypunct<char>& monp_fr = use_facet<moneypunct<char> >(loc_fr);
const moneypunct<char>& monp_de = use_facet<moneypunct<char> >(loc_de);
typedef moneypunct<char, true> __money_true;
typedef moneypunct<char, false> __money_false;
const __money_true& monp_c_t = use_facet<__money_true>(loc_c);
const __money_true& monp_us_t = use_facet<__money_true>(loc_us);
const __money_true& monp_fr_t = use_facet<__money_true>(loc_fr);
const __money_true& monp_de_t = use_facet<__money_true>(loc_de);
const __money_false& monp_c_f = use_facet<__money_false>(loc_c);
const __money_false& monp_us_f = use_facet<__money_false>(loc_us);
const __money_false& monp_fr_f = use_facet<__money_false>(loc_fr);
const __money_false& monp_de_f = use_facet<__money_false>(loc_de);
// quick sanity check for data.
char q1 = monp_c_t.decimal_point();
char q2 = monp_c_t.thousands_sep();
char q3 = monp_c_f.decimal_point();
char q4 = monp_c_f.thousands_sep();
VERIFY( q1 != char() );
VERIFY( q2 != char() );
VERIFY( q3 != char() );
VERIFY( q4 != char() );
// sanity check the data is correct.
char dp1 = monp_c.decimal_point();
char th1 = monp_c.thousands_sep();
string g1 = monp_c.grouping();
string cs1 = monp_c.curr_symbol();
string ps1 = monp_c.positive_sign();
string ns1 = monp_c.negative_sign();
int fd1 = monp_c.frac_digits();
pattern pos1 = monp_c.pos_format();
pattern neg1 = monp_c.neg_format();
char dp2 = monp_de.decimal_point();
char th2 = monp_de.thousands_sep();
string g2 = monp_de.grouping();
string cs2 = monp_de.curr_symbol();
string ps2 = monp_de.positive_sign();
string ns2 = monp_de.negative_sign();
int fd2 = monp_de.frac_digits();
pattern pos2 = monp_de.pos_format();
pattern neg2 = monp_de.neg_format();
char dp1 = monp_c_t.decimal_point();
char th1 = monp_c_t.thousands_sep();
string g1 = monp_c_t.grouping();
string cs1 = monp_c_t.curr_symbol();
string ps1 = monp_c_t.positive_sign();
string ns1 = monp_c_t.negative_sign();
int fd1 = monp_c_t.frac_digits();
pattern pos1 = monp_c_t.pos_format();
pattern neg1 = monp_c_t.neg_format();
char dp2 = monp_de_t.decimal_point();
char th2 = monp_de_t.thousands_sep();
string g2 = monp_de_t.grouping();
string cs2 = monp_de_t.curr_symbol();
string ps2 = monp_de_t.positive_sign();
string ns2 = monp_de_t.negative_sign();
int fd2 = monp_de_t.frac_digits();
pattern pos2 = monp_de_t.pos_format();
pattern neg2 = monp_de_t.neg_format();
VERIFY( dp1 != dp2 );
VERIFY( th1 != th2 );
......
// 2001-09-09 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.6.3.1 moneypunct members
#include <locale>
#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 money_base::part part;
typedef money_base::pattern pattern;
bool test = true;
string str;
// basic construction
locale loc_c = locale::classic();
str = loc_c.name();
locale loc_us("en_US");
str = loc_us.name();
VERIFY( loc_c != loc_us );
locale loc_fr("fr_FR");
str = loc_fr.name();
VERIFY( loc_c != loc_fr );
locale loc_de("de_DE");
str = loc_de.name();
VERIFY( loc_c != loc_de );
VERIFY( loc_us != loc_fr );
VERIFY( loc_us != loc_de );
VERIFY( loc_de != loc_fr );
// cache the moneypunct facets
typedef moneypunct<wchar_t, true> __money_true;
typedef moneypunct<wchar_t, false> __money_false;
const __money_true& monp_c_t = use_facet<__money_true>(loc_c);
const __money_true& monp_us_t = use_facet<__money_true>(loc_us);
const __money_true& monp_fr_t = use_facet<__money_true>(loc_fr);
const __money_true& monp_de_t = use_facet<__money_true>(loc_de);
const __money_false& monp_c_f = use_facet<__money_false>(loc_c);
const __money_false& monp_us_f = use_facet<__money_false>(loc_us);
const __money_false& monp_fr_f = use_facet<__money_false>(loc_fr);
const __money_false& monp_de_f = use_facet<__money_false>(loc_de);
// quick sanity check for data.
wchar_t q1 = monp_c_t.decimal_point();
wchar_t q2 = monp_c_t.thousands_sep();
wchar_t q3 = monp_c_f.decimal_point();
wchar_t q4 = monp_c_f.thousands_sep();
VERIFY( q1 != wchar_t() );
VERIFY( q2 != wchar_t() );
VERIFY( q3 != wchar_t() );
VERIFY( q4 != wchar_t() );
// sanity check the data is correct.
wchar_t dp1 = monp_c_t.decimal_point();
wchar_t th1 = monp_c_t.thousands_sep();
string g1 = monp_c_t.grouping();
wstring cs1 = monp_c_t.curr_symbol();
wstring ps1 = monp_c_t.positive_sign();
wstring ns1 = monp_c_t.negative_sign();
int fd1 = monp_c_t.frac_digits();
pattern pos1 = monp_c_t.pos_format();
pattern neg1 = monp_c_t.neg_format();
wchar_t dp2 = monp_de_t.decimal_point();
wchar_t th2 = monp_de_t.thousands_sep();
string g2 = monp_de_t.grouping();
wstring cs2 = monp_de_t.curr_symbol();
wstring ps2 = monp_de_t.positive_sign();
wstring ns2 = monp_de_t.negative_sign();
int fd2 = monp_de_t.frac_digits();
pattern pos2 = monp_de_t.pos_format();
pattern neg2 = monp_de_t.neg_format();
VERIFY( dp1 != dp2 );
VERIFY( th1 != th2 );
VERIFY( g1 != g2 );
VERIFY( cs1 != cs2 );
// VERIFY( ps1 != ps2 );
VERIFY( ns1 != ns2 );
VERIFY( fd1 != fd2 );
VERIFY(static_cast<part>(pos1.field[0]) != static_cast<part>(pos2.field[0]));
VERIFY(static_cast<part>(pos1.field[1]) != static_cast<part>(pos2.field[1]));
VERIFY(static_cast<part>(pos1.field[2]) != static_cast<part>(pos2.field[2]));
VERIFY(static_cast<part>(pos1.field[3]) != static_cast<part>(pos2.field[3]));
VERIFY(static_cast<part>(neg1.field[0]) != static_cast<part>(neg2.field[0]));
VERIFY(static_cast<part>(neg1.field[1]) != static_cast<part>(neg2.field[1]));
VERIFY(static_cast<part>(neg1.field[2]) != static_cast<part>(neg2.field[2]));
VERIFY(static_cast<part>(neg1.field[3]) != static_cast<part>(neg2.field[3]));
}
#endif
int main()
{
#ifdef _GLIBCPP_USE_WCHAR_T
test01();
#endif
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment