locale_facets.tcc: Use function object for __use_cache instead of template function.
2003-07-09 Benjamin Kosnik <bkoz@redhat.com> * include/bits/locale_facets.tcc: Use function object for __use_cache instead of template function. Partially specialize for __numpunct<_CharT>. * include/bits/locale_classes.h: Update friend declaration for __use_cache. (_M_install_cache): No throw exception specs. * src/locale.cc: Remove __use_cache specializations. * include/ext/pod_char_traits.h (length): Tweak. * include/bits/locale_facets.h (__numpunct_cache): Remove char_type typedef. * testsuite/testsuite_hooks.h (pod_unsigned_int): Remove. (pod_long): Remove. * testsuite/22_locale/numpunct/members/char/cache_1.cc: New. * testsuite/22_locale/numpunct/members/char/cache_2.cc: New. * testsuite/22_locale/numpunct/members/wchar_t/cache_1.cc: New. * testsuite/22_locale/numpunct/members/wchar_t/cache_2.cc: New. * testsuite/22_locale/numpunct/members/pod/1.cc: New. * testsuite/22_locale/numpunct/members/pod/2.cc: New. From-SVN: r69177
This commit is contained in:
parent
ae12c66624
commit
cde6384093
@ -1,3 +1,24 @@
|
||||
2003-07-09 Benjamin Kosnik <bkoz@redhat.com>
|
||||
|
||||
* include/bits/locale_facets.tcc: Use function object for
|
||||
__use_cache instead of template function. Partially specialize for
|
||||
__numpunct<_CharT>.
|
||||
* include/bits/locale_classes.h: Update friend declaration for
|
||||
__use_cache.
|
||||
(_M_install_cache): No throw exception specs.
|
||||
* src/locale.cc: Remove __use_cache specializations.
|
||||
* include/ext/pod_char_traits.h (length): Tweak.
|
||||
* include/bits/locale_facets.h (__numpunct_cache): Remove
|
||||
char_type typedef.
|
||||
* testsuite/testsuite_hooks.h (pod_unsigned_int): Remove.
|
||||
(pod_long): Remove.
|
||||
* testsuite/22_locale/numpunct/members/char/cache_1.cc: New.
|
||||
* testsuite/22_locale/numpunct/members/char/cache_2.cc: New.
|
||||
* testsuite/22_locale/numpunct/members/wchar_t/cache_1.cc: New.
|
||||
* testsuite/22_locale/numpunct/members/wchar_t/cache_2.cc: New.
|
||||
* testsuite/22_locale/numpunct/members/pod/1.cc: New.
|
||||
* testsuite/22_locale/numpunct/members/pod/2.cc: New.
|
||||
|
||||
2003-07-09 Jerry Quinn <jlquinn@optonline.net>
|
||||
|
||||
* src/ios.cc (_M_grow_words): Fix spelling.
|
||||
|
@ -73,8 +73,7 @@ namespace std
|
||||
use_facet(const locale&);
|
||||
|
||||
template<typename _Cache>
|
||||
friend const _Cache&
|
||||
__use_cache(const locale& __loc);
|
||||
friend struct __use_cache;
|
||||
|
||||
// Category values:
|
||||
// NB: Order must match _S_facet_categories definition in locale.cc
|
||||
@ -298,8 +297,7 @@ namespace std
|
||||
use_facet(const locale&);
|
||||
|
||||
template<typename _Cache>
|
||||
friend const _Cache&
|
||||
__use_cache(const locale& __loc);
|
||||
friend struct __use_cache;
|
||||
|
||||
private:
|
||||
// Data Members.
|
||||
@ -370,7 +368,7 @@ namespace std
|
||||
{ _M_install_facet(&_Facet::id, __facet); }
|
||||
|
||||
void
|
||||
_M_install_cache(const facet* __cache, size_t __index)
|
||||
_M_install_cache(const facet* __cache, size_t __index) throw()
|
||||
{
|
||||
__cache->_M_add_reference();
|
||||
_M_caches[__index] = __cache;
|
||||
|
@ -577,34 +577,31 @@ namespace std
|
||||
template<typename _CharT>
|
||||
struct __numpunct_cache : public locale::facet
|
||||
{
|
||||
// Types:
|
||||
typedef _CharT char_type;
|
||||
|
||||
const char* _M_grouping;
|
||||
bool _M_use_grouping;
|
||||
const char_type* _M_truename;
|
||||
const char_type* _M_falsename;
|
||||
char_type _M_decimal_point;
|
||||
char_type _M_thousands_sep;
|
||||
const _CharT* _M_truename;
|
||||
const _CharT* _M_falsename;
|
||||
_CharT _M_decimal_point;
|
||||
_CharT _M_thousands_sep;
|
||||
|
||||
// A list of valid numeric literals for output: in the standard
|
||||
// "C" locale, this is "-+xX0123456789abcdef0123456789ABCDEF".
|
||||
// This array contains the chars after having been passed
|
||||
// through the current locale's ctype<_CharT>.widen().
|
||||
char_type _M_atoms_out[__num_base::_S_oend + 1];
|
||||
_CharT _M_atoms_out[__num_base::_S_oend + 1];
|
||||
|
||||
// A list of valid numeric literals for output: in the standard
|
||||
// "C" locale, this is "0123456789eEabcdfABCDF"
|
||||
// This array contains the chars after having been passed
|
||||
// through the current locale's ctype<_CharT>.widen().
|
||||
char_type _M_atoms_in[__num_base::_S_iend + 1];
|
||||
_CharT _M_atoms_in[__num_base::_S_iend + 1];
|
||||
|
||||
bool _M_allocated;
|
||||
|
||||
__numpunct_cache(size_t __refs = 0) : locale::facet(__refs),
|
||||
_M_grouping(NULL), _M_use_grouping(false), _M_truename(NULL),
|
||||
_M_falsename(NULL), _M_decimal_point(char_type()),
|
||||
_M_thousands_sep(char_type()), _M_allocated(false)
|
||||
_M_falsename(NULL), _M_decimal_point(_CharT()),
|
||||
_M_thousands_sep(_CharT()), _M_allocated(false)
|
||||
{ }
|
||||
|
||||
~__numpunct_cache();
|
||||
|
@ -89,18 +89,38 @@ namespace std
|
||||
// Routine to access a cache for the facet. If the cache didn't
|
||||
// exist before, it gets constructed on the fly.
|
||||
template<typename _Facet>
|
||||
const _Facet&
|
||||
__use_cache(const locale& __loc);
|
||||
struct __use_cache
|
||||
{
|
||||
const _Facet*
|
||||
operator() (const locale& __loc) const;
|
||||
};
|
||||
|
||||
template<>
|
||||
const __numpunct_cache<char>&
|
||||
__use_cache(const locale& __loc);
|
||||
|
||||
#ifdef _GLIBCXX_USE_WCHAR_T
|
||||
template<>
|
||||
const __numpunct_cache<wchar_t>&
|
||||
__use_cache(const locale& __loc);
|
||||
#endif
|
||||
template<typename _CharT>
|
||||
struct __use_cache<__numpunct_cache<_CharT> >
|
||||
{
|
||||
const __numpunct_cache<_CharT>*
|
||||
operator() (const locale& __loc) const
|
||||
{
|
||||
size_t __i = numpunct<_CharT>::id._M_id();
|
||||
const locale::facet** __caches = __loc._M_impl->_M_caches;
|
||||
if (!__caches[__i])
|
||||
{
|
||||
__numpunct_cache<_CharT>* __tmp;
|
||||
try
|
||||
{
|
||||
__tmp = new __numpunct_cache<_CharT>;
|
||||
__tmp->_M_cache(__loc);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
delete __tmp;
|
||||
__throw_exception_again;
|
||||
}
|
||||
__loc._M_impl->_M_install_cache(__tmp, __i);
|
||||
}
|
||||
return static_cast<const __numpunct_cache<_CharT>*>(__caches[__i]);
|
||||
}
|
||||
};
|
||||
|
||||
// Stage 1: Determine a conversion specifier.
|
||||
template<typename _CharT, typename _InIter>
|
||||
@ -785,9 +805,10 @@ namespace std
|
||||
_ValueT __v) const
|
||||
{
|
||||
typedef typename numpunct<_CharT>::__cache_type __cache_type;
|
||||
__use_cache<__cache_type> __uc;
|
||||
const locale& __loc = __io._M_getloc();
|
||||
const __cache_type& __lc = __use_cache<__cache_type>(__loc);
|
||||
const _CharT* __lit = __lc._M_atoms_out;
|
||||
const __cache_type* __lc = __uc(__loc);
|
||||
const _CharT* __lit = __lc->_M_atoms_out;
|
||||
|
||||
// Long enough to hold hex, dec, and octal representations.
|
||||
int __ilen = 4 * sizeof(_ValueT);
|
||||
@ -801,13 +822,13 @@ namespace std
|
||||
|
||||
// Add grouping, if necessary.
|
||||
_CharT* __cs2;
|
||||
if (__lc._M_use_grouping)
|
||||
if (__lc->_M_use_grouping)
|
||||
{
|
||||
// Grouping can add (almost) as many separators as the
|
||||
// number of digits, but no more.
|
||||
__cs2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
|
||||
* __len * 2));
|
||||
_M_group_int(__lc._M_grouping, __lc._M_thousands_sep, __io,
|
||||
_M_group_int(__lc->_M_grouping, __lc->_M_thousands_sep, __io,
|
||||
__cs2, __cs, __len);
|
||||
__cs = __cs2;
|
||||
}
|
||||
@ -890,8 +911,9 @@ namespace std
|
||||
__prec = static_cast<streamsize>(6);
|
||||
|
||||
typedef typename numpunct<_CharT>::__cache_type __cache_type;
|
||||
__use_cache<__cache_type> __uc;
|
||||
const locale& __loc = __io._M_getloc();
|
||||
const __cache_type& __lc = __use_cache<__cache_type>(__loc);
|
||||
const __cache_type* __lc = __uc(__loc);
|
||||
|
||||
// [22.2.2.2.2] Stage 1, numeric conversion to character.
|
||||
int __len;
|
||||
@ -944,20 +966,20 @@ namespace std
|
||||
|
||||
// Replace decimal point.
|
||||
const _CharT __cdec = __ctype.widen('.');
|
||||
const _CharT __dec = __lc._M_decimal_point;
|
||||
const _CharT __dec = __lc->_M_decimal_point;
|
||||
const _CharT* __p;
|
||||
if (__p = char_traits<_CharT>::find(__ws, __len, __cdec))
|
||||
__ws[__p - __ws] = __dec;
|
||||
|
||||
// Add grouping, if necessary.
|
||||
_CharT* __ws2;
|
||||
if (__lc._M_use_grouping)
|
||||
if (__lc->_M_use_grouping)
|
||||
{
|
||||
// Grouping can add (almost) as many separators as the
|
||||
// number of digits, but no more.
|
||||
__ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
|
||||
* __len * 2));
|
||||
_M_group_float(__lc._M_grouping, __lc._M_thousands_sep, __p,
|
||||
_M_group_float(__lc->_M_grouping, __lc->_M_thousands_sep, __p,
|
||||
__ws2, __ws, __len);
|
||||
__ws = __ws2;
|
||||
}
|
||||
@ -992,15 +1014,16 @@ namespace std
|
||||
else
|
||||
{
|
||||
typedef typename numpunct<_CharT>::__cache_type __cache_type;
|
||||
__use_cache<__cache_type> __uc;
|
||||
const locale& __loc = __io._M_getloc();
|
||||
const __cache_type& __lc = __use_cache<__cache_type>(__loc);
|
||||
const __cache_type* __lc = __uc(__loc);
|
||||
|
||||
typedef basic_string<_CharT> __string_type;
|
||||
__string_type __name;
|
||||
if (__v)
|
||||
__name = __lc._M_truename;
|
||||
__name = __lc->_M_truename;
|
||||
else
|
||||
__name = __lc._M_falsename;
|
||||
__name = __lc->_M_falsename;
|
||||
|
||||
const _CharT* __cs = __name.c_str();
|
||||
int __len = __name.size();
|
||||
@ -1339,7 +1362,8 @@ namespace std
|
||||
// decimal digit, '\0'.
|
||||
const int __cs_size = numeric_limits<long double>::max_exponent10 + 5;
|
||||
char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
|
||||
int __len = std::__convert_from_v(__cs, 0, "%.01Lf", __units, _S_c_locale);
|
||||
int __len = std::__convert_from_v(__cs, 0, "%.01Lf", __units,
|
||||
_S_c_locale);
|
||||
#endif
|
||||
_CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
|
||||
* __cs_size));
|
||||
@ -2280,8 +2304,8 @@ namespace std
|
||||
{
|
||||
if (__last - __first > *__gbeg)
|
||||
{
|
||||
__s = std::__add_grouping(__s, __sep,
|
||||
(__gbeg + 1 == __gend ? __gbeg : __gbeg + 1),
|
||||
const bool __bump = __gbeg + 1 != __gend;
|
||||
__s = std::__add_grouping(__s, __sep, __gbeg + __bump,
|
||||
__gend, __first, __last - *__gbeg);
|
||||
__first = __last - *__gbeg;
|
||||
*__s++ = __sep;
|
||||
|
@ -98,7 +98,7 @@ namespace std
|
||||
length(const char_type* __s)
|
||||
{
|
||||
const char_type* __p = __s;
|
||||
while (*__p)
|
||||
while (__p->value)
|
||||
++__p;
|
||||
return (__p - __s);
|
||||
}
|
||||
|
@ -451,38 +451,6 @@ namespace std
|
||||
locale::facet::
|
||||
~facet() { }
|
||||
|
||||
template<>
|
||||
const __numpunct_cache<char>&
|
||||
__use_cache(const locale& __loc)
|
||||
{
|
||||
size_t __i = numpunct<char>::id._M_id();
|
||||
const locale::facet** __caches = __loc._M_impl->_M_caches;
|
||||
if (!__caches[__i])
|
||||
{
|
||||
__numpunct_cache<char>* __tmp = new __numpunct_cache<char>;
|
||||
__tmp->_M_cache(__loc);
|
||||
__loc._M_impl->_M_install_cache(__tmp, __i);
|
||||
}
|
||||
return static_cast<const __numpunct_cache<char>&>(*__caches[__i]);
|
||||
}
|
||||
|
||||
#ifdef _GLIBCXX_USE_WCHAR_T
|
||||
template<>
|
||||
const __numpunct_cache<wchar_t>&
|
||||
__use_cache(const locale& __loc)
|
||||
{
|
||||
size_t __i = numpunct<wchar_t>::id._M_id();
|
||||
const locale::facet** __caches = __loc._M_impl->_M_caches;
|
||||
if (!__caches[__i])
|
||||
{
|
||||
__numpunct_cache<wchar_t>* __tmp = new __numpunct_cache<wchar_t>;
|
||||
__tmp->_M_cache(__loc);
|
||||
__loc._M_impl->_M_install_cache(__tmp, __i);
|
||||
}
|
||||
return static_cast<const __numpunct_cache<wchar_t>&>(*__caches[__i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Definitions for static const data members of time_base.
|
||||
template<>
|
||||
const char*
|
||||
|
@ -0,0 +1,78 @@
|
||||
// 2003-07-06 Benjamin Kosnik <bkoz@redhat.com>
|
||||
|
||||
// Copyright (C) 2003 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 <locale>
|
||||
#include <sstream>
|
||||
#include <ostream>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
class numpunct_checked : public std::numpunct<char>
|
||||
{
|
||||
typedef std::numpunct<char> base;
|
||||
|
||||
public:
|
||||
explicit
|
||||
numpunct_checked(std::size_t refs = 0): base(refs) { }
|
||||
|
||||
string_type
|
||||
base_truename() const
|
||||
{ return base::do_truename(); }
|
||||
|
||||
protected:
|
||||
virtual string_type
|
||||
do_truename() const
|
||||
{ return base::do_truename() + "st"; }
|
||||
};
|
||||
|
||||
// Thwart locale caching strategies that incorrectly overwrite base
|
||||
// class data.
|
||||
void test01()
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
bool test = true;
|
||||
const string basestr("true");
|
||||
const string derivedstr("truest");
|
||||
|
||||
const locale loc(locale::classic(), new numpunct_checked);
|
||||
stringbuf sbuf;
|
||||
ostream os(&sbuf);
|
||||
os.setf(ios_base::boolalpha);
|
||||
|
||||
// Pre-cache sanity check.
|
||||
const numpunct<char>& np = use_facet<numpunct<char> >(loc);
|
||||
VERIFY( np.truename() == derivedstr );
|
||||
|
||||
// Cache.
|
||||
os.imbue(loc);
|
||||
os << true;
|
||||
VERIFY( sbuf.str() == derivedstr );
|
||||
|
||||
// Post-cache sanity check, make sure that base class is still fine.
|
||||
VERIFY( np.truename() == derivedstr );
|
||||
const numpunct_checked& npd = static_cast<const numpunct_checked&>(np);
|
||||
VERIFY( npd.base_truename() == basestr );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
// 2003-07-06 Benjamin Kosnik <bkoz@redhat.com>
|
||||
|
||||
// Copyright (C) 2003 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 <locale>
|
||||
#include <sstream>
|
||||
#include <ostream>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
class numpunct_checked : public std::numpunct<char>
|
||||
{
|
||||
typedef std::numpunct<char> base;
|
||||
|
||||
public:
|
||||
explicit
|
||||
numpunct_checked(std::size_t refs = 0): base(refs) { }
|
||||
|
||||
string_type
|
||||
base_truename() const
|
||||
{ return base::do_truename(); }
|
||||
|
||||
protected:
|
||||
virtual string_type
|
||||
do_truename() const
|
||||
{ return base::do_truename() + "st"; }
|
||||
};
|
||||
|
||||
// Changing caches deletes old cache, adds new one.
|
||||
void test01()
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
bool test = true;
|
||||
const string empty;
|
||||
const string basestr("true");
|
||||
const string derivedstr("truest");
|
||||
|
||||
const locale loc(locale::classic(), new numpunct_checked);
|
||||
stringbuf sbuf;
|
||||
ostream os(&sbuf);
|
||||
os.setf(ios_base::boolalpha);
|
||||
|
||||
// Pre-cache sanity check.
|
||||
const numpunct<char>& np = use_facet<numpunct<char> >(loc);
|
||||
VERIFY( np.truename() == derivedstr );
|
||||
|
||||
// Cache.
|
||||
os.imbue(loc);
|
||||
os << true;
|
||||
VERIFY( sbuf.str() == derivedstr );
|
||||
|
||||
// Re-cache.
|
||||
sbuf.str(empty);
|
||||
os.imbue(locale::classic());
|
||||
os << true;
|
||||
VERIFY( sbuf.str() == basestr );
|
||||
|
||||
// Cache new locale again.
|
||||
sbuf.str(empty);
|
||||
os.imbue(loc);
|
||||
os << true;
|
||||
VERIFY( sbuf.str() == derivedstr );
|
||||
|
||||
// Post-cache sanity check, make sure that base class is still fine.
|
||||
VERIFY( np.truename() == derivedstr );
|
||||
const numpunct_checked& npd = static_cast<const numpunct_checked&>(np);
|
||||
VERIFY( npd.base_truename() == basestr );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
134
libstdc++-v3/testsuite/22_locale/numpunct/members/pod/1.cc
Normal file
134
libstdc++-v3/testsuite/22_locale/numpunct/members/pod/1.cc
Normal file
@ -0,0 +1,134 @@
|
||||
// 2003-07-09 Benjamin Kosnik <bkoz@redhat.com>
|
||||
|
||||
// Copyright (C) 2003 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 <locale>
|
||||
#include <sstream>
|
||||
#include <ostream>
|
||||
#include <stdexcept>
|
||||
#include <ext/pod_char_traits.h>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
typedef unsigned short value_type;
|
||||
typedef unsigned int int_type;
|
||||
typedef __gnu_cxx::character<value_type, int_type> podchar_type;
|
||||
|
||||
// Member specializations for the existing facet classes.
|
||||
// NB: This isn't especially portable. Perhaps a better way would be
|
||||
// to just specialize all of numpunct and ctype.
|
||||
namespace std
|
||||
{
|
||||
template<>
|
||||
void
|
||||
numpunct<podchar_type>::_M_initialize_numpunct(__c_locale __cloc)
|
||||
{
|
||||
if (!_M_data)
|
||||
_M_data = new __numpunct_cache<podchar_type>;
|
||||
|
||||
_M_data->_M_grouping = "";
|
||||
_M_data->_M_use_grouping = false;
|
||||
|
||||
_M_data->_M_decimal_point.value = value_type('.');
|
||||
_M_data->_M_thousands_sep.value = value_type(',');
|
||||
|
||||
for (size_t i = 0; i < __num_base::_S_oend; ++i)
|
||||
{
|
||||
value_type v = __num_base::_S_atoms_out[i];
|
||||
_M_data->_M_atoms_out[i].value = v;
|
||||
}
|
||||
_M_data->_M_atoms_out[__num_base::_S_oend] = podchar_type();
|
||||
|
||||
for (size_t i = 0; i < __num_base::_S_iend; ++i)
|
||||
_M_data->_M_atoms_in[i].value = value_type(__num_base::_S_atoms_in[i]);
|
||||
_M_data->_M_atoms_in[__num_base::_S_iend] = podchar_type();
|
||||
|
||||
// "true"
|
||||
podchar_type* __truename = new podchar_type[4 + 1];
|
||||
__truename[0].value = value_type('t');
|
||||
__truename[1].value = value_type('r');
|
||||
__truename[2].value = value_type('u');
|
||||
__truename[3].value = value_type('e');
|
||||
__truename[4] = podchar_type();
|
||||
_M_data->_M_truename = __truename;
|
||||
|
||||
// "false"
|
||||
podchar_type* __falsename = new podchar_type[5 + 1];
|
||||
__falsename[0].value = value_type('f');
|
||||
__falsename[1].value = value_type('a');
|
||||
__falsename[2].value = value_type('l');
|
||||
__falsename[3].value = value_type('s');
|
||||
__falsename[4].value = value_type('e');
|
||||
__falsename[5] = podchar_type();
|
||||
_M_data->_M_falsename = __falsename;
|
||||
}
|
||||
|
||||
template<>
|
||||
numpunct<podchar_type>::~numpunct()
|
||||
{ delete _M_data; }
|
||||
}
|
||||
|
||||
// Check for numpunct and ctype dependencies. Make sure that numpunct
|
||||
// can be created without ctype.
|
||||
void test01()
|
||||
{
|
||||
using namespace std;
|
||||
typedef numpunct<podchar_type>::string_type string_type;
|
||||
typedef basic_stringbuf<podchar_type> stringbuf_type;
|
||||
typedef basic_ostream<podchar_type> ostream_type;
|
||||
|
||||
bool test = true;
|
||||
|
||||
// Pre-cache sanity check.
|
||||
const locale loc(locale::classic(), new numpunct<podchar_type>);
|
||||
const numpunct<podchar_type>& np = use_facet<numpunct<podchar_type> >(loc);
|
||||
|
||||
podchar_type dp = np.decimal_point();
|
||||
podchar_type ts = np.thousands_sep();
|
||||
string g = np.grouping();
|
||||
string_type strue = np.truename();
|
||||
string_type sfalse = np.falsename();
|
||||
|
||||
podchar_type basedp = { value_type('.') };
|
||||
podchar_type basets = { value_type(',') };
|
||||
|
||||
string_type basetrue(4, podchar_type());
|
||||
basetrue[0].value = value_type('t');
|
||||
basetrue[1].value = value_type('r');
|
||||
basetrue[2].value = value_type('u');
|
||||
basetrue[3].value = value_type('e');
|
||||
|
||||
string_type basefalse(5, podchar_type());
|
||||
basefalse[0].value = value_type('f');
|
||||
basefalse[1].value = value_type('a');
|
||||
basefalse[2].value = value_type('l');
|
||||
basefalse[3].value = value_type('s');
|
||||
basefalse[4].value = value_type('e');
|
||||
|
||||
VERIFY( char_traits<podchar_type>::eq(dp, basedp) );
|
||||
VERIFY( char_traits<podchar_type>::eq(ts, basets) );
|
||||
VERIFY( g == "" );
|
||||
VERIFY( strue == basetrue );
|
||||
VERIFY( sfalse == basefalse );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
267
libstdc++-v3/testsuite/22_locale/numpunct/members/pod/2.cc
Normal file
267
libstdc++-v3/testsuite/22_locale/numpunct/members/pod/2.cc
Normal file
@ -0,0 +1,267 @@
|
||||
// 2003-07-09 Benjamin Kosnik <bkoz@redhat.com>
|
||||
|
||||
// Copyright (C) 2003 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 <locale>
|
||||
#include <sstream>
|
||||
#include <ostream>
|
||||
#include <stdexcept>
|
||||
#include <ext/pod_char_traits.h>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
typedef unsigned short value_type;
|
||||
typedef unsigned int int_type;
|
||||
typedef __gnu_cxx::character<value_type, int_type> podchar_type;
|
||||
|
||||
// Member specializations for the existing facet classes.
|
||||
// NB: This isn't especially portable. Perhaps a better way would be
|
||||
// to just specialize all of numpunct and ctype.
|
||||
namespace std
|
||||
{
|
||||
template<>
|
||||
bool
|
||||
ctype<podchar_type>::
|
||||
do_is(mask __m, char_type __c) const { return true; }
|
||||
|
||||
template<>
|
||||
const podchar_type*
|
||||
ctype<podchar_type>::
|
||||
do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const
|
||||
{ return __lo; }
|
||||
|
||||
template<>
|
||||
const podchar_type*
|
||||
ctype<podchar_type>::
|
||||
do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const
|
||||
{ return __lo; }
|
||||
|
||||
template<>
|
||||
const podchar_type*
|
||||
ctype<podchar_type>::
|
||||
do_scan_not(mask __m, const char_type* __lo, const char_type* __hi) const
|
||||
{ return __lo; }
|
||||
|
||||
template<>
|
||||
podchar_type
|
||||
ctype<podchar_type>::
|
||||
do_toupper(char_type __c) const
|
||||
{ return __c; }
|
||||
|
||||
template<>
|
||||
const podchar_type*
|
||||
ctype<podchar_type>::
|
||||
do_toupper(char_type* __lo, const char_type* __hi) const
|
||||
{ return __hi; }
|
||||
|
||||
template<>
|
||||
podchar_type
|
||||
ctype<podchar_type>::
|
||||
do_tolower(char_type __c) const
|
||||
{ return __c; }
|
||||
|
||||
template<>
|
||||
const podchar_type*
|
||||
ctype<podchar_type>::
|
||||
do_tolower(char_type* __lo, const char_type* __hi) const
|
||||
{ return __hi; }
|
||||
|
||||
template<>
|
||||
podchar_type
|
||||
ctype<podchar_type>::
|
||||
do_widen(char __c) const
|
||||
{
|
||||
char_type ret = { value_type(__c) };
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<>
|
||||
const char*
|
||||
ctype<podchar_type>::
|
||||
do_widen(const char* __lo, const char* __hi, char_type* __dest) const
|
||||
{
|
||||
while (__lo < __hi)
|
||||
{
|
||||
*__dest = this->do_widen(*__lo);
|
||||
++__lo;
|
||||
++__dest;
|
||||
}
|
||||
return __hi;
|
||||
}
|
||||
|
||||
template<>
|
||||
char
|
||||
ctype<podchar_type>::
|
||||
do_narrow(char_type __wc, char) const
|
||||
{ return static_cast<char>(__wc.value); }
|
||||
|
||||
template<>
|
||||
const podchar_type*
|
||||
ctype<podchar_type>::
|
||||
do_narrow(const podchar_type* __lo, const podchar_type* __hi,
|
||||
char __dfault, char* __dest) const
|
||||
{
|
||||
while (__lo < __hi)
|
||||
{
|
||||
*__dest = this->do_narrow(*__lo, char());
|
||||
++__lo;
|
||||
++__dest;
|
||||
}
|
||||
return __hi;
|
||||
}
|
||||
|
||||
template<>
|
||||
ctype<podchar_type>::~ctype() { }
|
||||
|
||||
template<>
|
||||
void
|
||||
numpunct<podchar_type>::_M_initialize_numpunct(__c_locale __cloc)
|
||||
{
|
||||
if (!_M_data)
|
||||
_M_data = new __numpunct_cache<podchar_type>;
|
||||
|
||||
_M_data->_M_grouping = "";
|
||||
_M_data->_M_use_grouping = false;
|
||||
|
||||
_M_data->_M_decimal_point.value = value_type('.');
|
||||
_M_data->_M_thousands_sep.value = value_type(',');
|
||||
|
||||
for (size_t i = 0; i < __num_base::_S_oend; ++i)
|
||||
{
|
||||
value_type v = __num_base::_S_atoms_out[i];
|
||||
_M_data->_M_atoms_out[i].value = v;
|
||||
}
|
||||
_M_data->_M_atoms_out[__num_base::_S_oend] = podchar_type();
|
||||
|
||||
for (size_t i = 0; i < __num_base::_S_iend; ++i)
|
||||
_M_data->_M_atoms_in[i].value = value_type(__num_base::_S_atoms_in[i]);
|
||||
_M_data->_M_atoms_in[__num_base::_S_iend] = podchar_type();
|
||||
|
||||
// "true"
|
||||
podchar_type* __truename = new podchar_type[4 + 1];
|
||||
__truename[0].value = value_type('t');
|
||||
__truename[1].value = value_type('r');
|
||||
__truename[2].value = value_type('u');
|
||||
__truename[3].value = value_type('e');
|
||||
__truename[4] = podchar_type();
|
||||
_M_data->_M_truename = __truename;
|
||||
|
||||
// "false"
|
||||
podchar_type* __falsename = new podchar_type[5 + 1];
|
||||
__falsename[0].value = value_type('f');
|
||||
__falsename[1].value = value_type('a');
|
||||
__falsename[2].value = value_type('l');
|
||||
__falsename[3].value = value_type('s');
|
||||
__falsename[4].value = value_type('e');
|
||||
__falsename[5] = podchar_type();
|
||||
_M_data->_M_falsename = __falsename;
|
||||
}
|
||||
|
||||
template<>
|
||||
numpunct<podchar_type>::~numpunct()
|
||||
{ delete _M_data; }
|
||||
}
|
||||
|
||||
// Check for numpunct and ctype dependencies. Make sure that numpunct
|
||||
// can be created without ctype.
|
||||
void test01()
|
||||
{
|
||||
using namespace std;
|
||||
typedef numpunct<podchar_type>::string_type string_type;
|
||||
typedef basic_ostringstream<podchar_type> ostream_type;
|
||||
|
||||
bool test = true;
|
||||
|
||||
// Test formatted output.
|
||||
ostream_type os;
|
||||
const locale loc = locale::classic();
|
||||
os.imbue(loc);
|
||||
os.setf(ios_base::boolalpha);
|
||||
os.exceptions(ios_base::badbit);
|
||||
|
||||
// 1: fail, no num_put.
|
||||
try
|
||||
{
|
||||
// Calls to num_put.put will fail, as there's no num_put facet.
|
||||
os << true;
|
||||
test = false;
|
||||
}
|
||||
catch(const bad_cast& obj)
|
||||
{ }
|
||||
catch(...)
|
||||
{ test = false; }
|
||||
VERIFY( test );
|
||||
|
||||
// 2: fail, no ctype
|
||||
const locale loc2(loc, new num_put<podchar_type>);
|
||||
os.clear();
|
||||
os.imbue(loc2);
|
||||
try
|
||||
{
|
||||
// Calls to ctype.widen will fail, as there's no ctype facet.
|
||||
os << true;
|
||||
test = false;
|
||||
}
|
||||
catch(const bad_cast& obj)
|
||||
{ }
|
||||
catch(...)
|
||||
{ test = false; }
|
||||
VERIFY( test );
|
||||
|
||||
// 3: fail, no numpunct
|
||||
const locale loc3(loc, new ctype<podchar_type>);
|
||||
os.clear();
|
||||
os.imbue(loc3);
|
||||
try
|
||||
{
|
||||
// Formatted output fails as no numpunct.
|
||||
os << true;
|
||||
test = false;
|
||||
}
|
||||
catch(const bad_cast& obj)
|
||||
{ }
|
||||
catch(...)
|
||||
{ test = false; }
|
||||
VERIFY( test );
|
||||
|
||||
// 4: works.
|
||||
const locale loc4(loc3, new numpunct<podchar_type>);
|
||||
os.clear();
|
||||
os.imbue(loc4);
|
||||
try
|
||||
{
|
||||
os << long(500);
|
||||
string_type s = os.str();
|
||||
VERIFY( s.length() == 3 );
|
||||
|
||||
VERIFY( os.narrow(s[0], char()) == '5' );
|
||||
VERIFY( os.narrow(s[1], char()) == '0' );
|
||||
VERIFY( os.narrow(s[2], char()) == '0' );
|
||||
}
|
||||
catch(const bad_cast& obj)
|
||||
{ test = false; }
|
||||
catch(...)
|
||||
{ test = false; }
|
||||
VERIFY( test );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
// 2003-07-06 Benjamin Kosnik <bkoz@redhat.com>
|
||||
|
||||
// Copyright (C) 2003 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 <locale>
|
||||
#include <sstream>
|
||||
#include <ostream>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
class numpunct_checked : public std::numpunct<wchar_t>
|
||||
{
|
||||
typedef std::numpunct<wchar_t> base;
|
||||
|
||||
public:
|
||||
explicit
|
||||
numpunct_checked(std::size_t refs = 0): base(refs) { }
|
||||
|
||||
string_type
|
||||
base_truename() const
|
||||
{ return base::do_truename(); }
|
||||
|
||||
protected:
|
||||
virtual string_type
|
||||
do_truename() const
|
||||
{ return base::do_truename() + L"st"; }
|
||||
};
|
||||
|
||||
// Thwart locale caching strategies that incorrectly overwrite base
|
||||
// class data.
|
||||
void test01()
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
bool test = true;
|
||||
const wstring basestr(L"true");
|
||||
const wstring derivedstr(L"truest");
|
||||
|
||||
const locale loc(locale::classic(), new numpunct_checked);
|
||||
wstringbuf sbuf;
|
||||
wostream os(&sbuf);
|
||||
os.setf(ios_base::boolalpha);
|
||||
|
||||
// Pre-cache sanity check.
|
||||
const numpunct<wchar_t>& np = use_facet<numpunct<wchar_t> >(loc);
|
||||
VERIFY( np.truename() == derivedstr );
|
||||
|
||||
// Cache.
|
||||
os.imbue(loc);
|
||||
os << true;
|
||||
VERIFY( sbuf.str() == derivedstr );
|
||||
|
||||
// Post-cache sanity check, make sure that base class is still fine.
|
||||
VERIFY( np.truename() == derivedstr );
|
||||
const numpunct_checked& npd = static_cast<const numpunct_checked&>(np);
|
||||
VERIFY( npd.base_truename() == basestr );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
// 2003-07-06 Benjamin Kosnik <bkoz@redhat.com>
|
||||
|
||||
// Copyright (C) 2003 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 <locale>
|
||||
#include <sstream>
|
||||
#include <ostream>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
class numpunct_checked : public std::numpunct<wchar_t>
|
||||
{
|
||||
typedef std::numpunct<wchar_t> base;
|
||||
|
||||
public:
|
||||
explicit
|
||||
numpunct_checked(std::size_t refs = 0): base(refs) { }
|
||||
|
||||
string_type
|
||||
base_truename() const
|
||||
{ return base::do_truename(); }
|
||||
|
||||
protected:
|
||||
virtual string_type
|
||||
do_truename() const
|
||||
{ return base::do_truename() + L"st"; }
|
||||
};
|
||||
|
||||
// Changing caches deletes old cache, adds new one.
|
||||
void test01()
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
bool test = true;
|
||||
const wstring empty;
|
||||
const wstring basestr(L"true");
|
||||
const wstring derivedstr(L"truest");
|
||||
|
||||
const locale loc(locale::classic(), new numpunct_checked);
|
||||
wstringbuf sbuf;
|
||||
wostream os(&sbuf);
|
||||
os.setf(ios_base::boolalpha);
|
||||
|
||||
// Pre-cache sanity check.
|
||||
const numpunct<wchar_t>& np = use_facet<numpunct<wchar_t> >(loc);
|
||||
VERIFY( np.truename() == derivedstr );
|
||||
|
||||
// Cache.
|
||||
os.imbue(loc);
|
||||
os << true;
|
||||
VERIFY( sbuf.str() == derivedstr );
|
||||
|
||||
// Re-cache.
|
||||
sbuf.str(empty);
|
||||
os.imbue(locale::classic());
|
||||
os << true;
|
||||
VERIFY( sbuf.str() == basestr );
|
||||
|
||||
// Cache new locale again.
|
||||
sbuf.str(empty);
|
||||
os.imbue(loc);
|
||||
os << true;
|
||||
VERIFY( sbuf.str() == derivedstr );
|
||||
|
||||
// Post-cache sanity check, make sure that base class is still fine.
|
||||
VERIFY( np.truename() == derivedstr );
|
||||
const numpunct_checked& npd = static_cast<const numpunct_checked&>(np);
|
||||
VERIFY( npd.base_truename() == basestr );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
@ -127,16 +127,6 @@ namespace __gnu_cxx_test
|
||||
int i;
|
||||
};
|
||||
|
||||
struct pod_unsigned_int
|
||||
{
|
||||
unsigned int i;
|
||||
};
|
||||
|
||||
struct pod_long
|
||||
{
|
||||
unsigned long i;
|
||||
};
|
||||
|
||||
struct state
|
||||
{
|
||||
unsigned long l;
|
||||
|
Loading…
Reference in New Issue
Block a user