mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-02 16:23:56 +08:00
ios_base.h (ios_base::_M_getloc): Return reference to the imbued locale.
2003-06-26 Benjamin Kosnik <bkoz@redhat.com> * include/bits/ios_base.h (ios_base::_M_getloc): Return reference to the imbued locale. * include/bits/locale_facets.tcc (num_put::_M_convert_int): Use _M_getloc. (num_put::_M_convert_float): Use. 2003-06-26 Benjamin Kosnik <bkoz@redhat.com> Jerry Quinn <jlquinn@optonline.net> * config/linker-map.gnu: Add __numpunct_cache. * config/locale/gnu/numeric_members.cc (numpunct::_M_initialize_numpunct): Account for _M_data, fill in all elements for "C" locale. (numpunct::~numpunct): Delete _M_data. * config/locale/generic/numeric_members.cc: Same. * include/bits/basic_ios.tcc (basic_ios::init): Remove __locale_cache bits. (basic_ios::_M_cache_locale): Same. * include/bits/ios_base.h: Same. Tweaks. * include/bits/locale_classes.h: Tweaks. Reorder classes. (__use_cache): Make friends with _Impl, locale. (_Impl::_M_caches): Add. (_Impl::_M_install_cache): Add. * include/bits/locale_facets.h (__numpunct_cache): New. (numpunct): Encapsulate data members in __numpunct_cache member, _M_data. Adjust virtuals. (numpunct::numpunct): New ctor for the same. (__locale_cache_base): Remove. (__locale_cache): Remove. * include/bits/locale_facets.tcc (__use_cache): New function, specializations. (num_put::_M_convert_int, _M_convert_float, do_put): Use it. * src/globals.cc: Add cache_vec, numpunct_cache_c, numpunct_cache_w. * src/ios.cc (ios_base::ios_base): Remove __locale_cache. * src/locale-inst.cc: Same. Add __numpunct_cache. * src/locale.cc: Tweak inlines. (__use_cache): Define specializations. * src/localename.cc: Use global bits. (_Impl::~Impl): Deal with __numpunct_cache destruction. (_Impl::_Impl): Same. Pre-cache standard numpunct facets. (_Impl::_M_init_facet): Take into account __numpunct_cache. * testsuite/27_io/ios_base/cons/assign_neg.cc: Update line numbers. * testsuite/27_io/ios_base/cons/copy_neg.cc: Same. Co-Authored-By: Jerry Quinn <jlquinn@optonline.net> From-SVN: r68558
This commit is contained in:
parent
d51d146fb0
commit
215f9e283a
@ -1,3 +1,49 @@
|
||||
2003-06-26 Benjamin Kosnik <bkoz@redhat.com>
|
||||
|
||||
* include/bits/ios_base.h (ios_base::_M_getloc): Return reference
|
||||
to the imbued locale.
|
||||
* include/bits/locale_facets.tcc (num_put::_M_convert_int): Use
|
||||
_M_getloc.
|
||||
(num_put::_M_convert_float): Use.
|
||||
|
||||
2003-06-26 Benjamin Kosnik <bkoz@redhat.com>
|
||||
Jerry Quinn <jlquinn@optonline.net>
|
||||
|
||||
* config/linker-map.gnu: Add __numpunct_cache.
|
||||
* config/locale/gnu/numeric_members.cc
|
||||
(numpunct::_M_initialize_numpunct): Account for _M_data, fill in
|
||||
all elements for "C" locale.
|
||||
(numpunct::~numpunct): Delete _M_data.
|
||||
* config/locale/generic/numeric_members.cc: Same.
|
||||
* include/bits/basic_ios.tcc
|
||||
(basic_ios::init): Remove __locale_cache bits.
|
||||
(basic_ios::_M_cache_locale): Same.
|
||||
* include/bits/ios_base.h: Same. Tweaks.
|
||||
* include/bits/locale_classes.h: Tweaks. Reorder classes.
|
||||
(__use_cache): Make friends with _Impl, locale.
|
||||
(_Impl::_M_caches): Add.
|
||||
(_Impl::_M_install_cache): Add.
|
||||
* include/bits/locale_facets.h (__numpunct_cache): New.
|
||||
(numpunct): Encapsulate data members in __numpunct_cache member,
|
||||
_M_data. Adjust virtuals.
|
||||
(numpunct::numpunct): New ctor for the same.
|
||||
(__locale_cache_base): Remove.
|
||||
(__locale_cache): Remove.
|
||||
* include/bits/locale_facets.tcc (__use_cache): New function,
|
||||
specializations.
|
||||
(num_put::_M_convert_int, _M_convert_float, do_put): Use it.
|
||||
* src/globals.cc: Add cache_vec, numpunct_cache_c, numpunct_cache_w.
|
||||
* src/ios.cc (ios_base::ios_base): Remove __locale_cache.
|
||||
* src/locale-inst.cc: Same. Add __numpunct_cache.
|
||||
* src/locale.cc: Tweak inlines.
|
||||
(__use_cache): Define specializations.
|
||||
* src/localename.cc: Use global bits.
|
||||
(_Impl::~Impl): Deal with __numpunct_cache destruction.
|
||||
(_Impl::_Impl): Same. Pre-cache standard numpunct facets.
|
||||
(_Impl::_M_init_facet): Take into account __numpunct_cache.
|
||||
* testsuite/27_io/ios_base/cons/assign_neg.cc: Update line numbers.
|
||||
* testsuite/27_io/ios_base/cons/copy_neg.cc: Same.
|
||||
|
||||
2003-06-26 Nathan C. Myers <ncm-nospam@cantrip.org>
|
||||
Paolo Carlini <pcarlini@unitus.it>
|
||||
|
||||
|
@ -55,7 +55,8 @@ GLIBCPP_3.4 {
|
||||
std::__num_base::_S_format_float*;
|
||||
std::__num_base::_S_format_int*;
|
||||
std::__num_base::_S_atoms_in;
|
||||
std::__num_base::_S_atoms_out
|
||||
std::__num_base::_S_atoms_out;
|
||||
std::__numpunct_cache*;
|
||||
};
|
||||
|
||||
# Names not in an 'extern' block are mangled names.
|
||||
|
@ -1,6 +1,6 @@
|
||||
// std::numpunct implementation details, generic version -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2001, 2002 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2001, 2002, 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
|
||||
@ -42,16 +42,30 @@ namespace std
|
||||
numpunct<char>::_M_initialize_numpunct(__c_locale)
|
||||
{
|
||||
// "C" locale
|
||||
_M_decimal_point = '.';
|
||||
_M_thousands_sep = ',';
|
||||
_M_grouping = "";
|
||||
_M_truename = "true";
|
||||
_M_falsename = "false";
|
||||
if (!_M_data)
|
||||
_M_data = new __numpunct_cache<char>;
|
||||
|
||||
_M_data->_M_grouping = "";
|
||||
_M_data->_M_use_grouping = false;
|
||||
|
||||
_M_data->_M_decimal_point = '.';
|
||||
_M_data->_M_thousands_sep = ',';
|
||||
|
||||
for (size_t i = 0; i < __num_base::_S_oend; ++i)
|
||||
_M_data->_M_atoms_out[i] = __num_base::_S_atoms_out[i];
|
||||
_M_data->_M_atoms_out[__num_base::_S_oend] = wchar_t();
|
||||
|
||||
for (size_t i = 0; i < __num_base::_S_iend; ++i)
|
||||
_M_data->_M_atoms_in[i] = __num_base::_S_atoms_in[i];
|
||||
_M_data->_M_atoms_in[__num_base::_S_iend] = wchar_t();
|
||||
|
||||
_M_data->_M_truename = "true";
|
||||
_M_data->_M_falsename = "false";
|
||||
}
|
||||
|
||||
template<>
|
||||
numpunct<char>::~numpunct()
|
||||
{ }
|
||||
{ delete _M_data; }
|
||||
|
||||
#ifdef _GLIBCPP_USE_WCHAR_T
|
||||
template<>
|
||||
@ -59,15 +73,37 @@ namespace std
|
||||
numpunct<wchar_t>::_M_initialize_numpunct(__c_locale)
|
||||
{
|
||||
// "C" locale
|
||||
_M_decimal_point = L'.';
|
||||
_M_thousands_sep = L',';
|
||||
_M_grouping = "";
|
||||
_M_truename = L"true";
|
||||
_M_falsename = L"false";
|
||||
if (!_M_data)
|
||||
_M_data = new __numpunct_cache<wchar_t>;
|
||||
|
||||
_M_data->_M_grouping = "";
|
||||
_M_data->_M_use_grouping = false;
|
||||
|
||||
_M_data->_M_decimal_point = L'.';
|
||||
_M_data->_M_thousands_sep = L',';
|
||||
|
||||
// Use ctype::widen code without the facet...
|
||||
unsigned char uc;
|
||||
for (size_t i = 0; i < __num_base::_S_oend; ++i)
|
||||
{
|
||||
uc = static_cast<unsigned char>(__num_base::_S_atoms_out[i]);
|
||||
_M_data->_M_atoms_out[i] = btowc(uc);
|
||||
}
|
||||
_M_data->_M_atoms_out[__num_base::_S_oend] = wchar_t();
|
||||
|
||||
for (size_t i = 0; i < __num_base::_S_iend; ++i)
|
||||
{
|
||||
uc = static_cast<unsigned char>(__num_base::_S_atoms_in[i]);
|
||||
_M_data->_M_atoms_in[i] = btowc(uc);
|
||||
}
|
||||
_M_data->_M_atoms_in[__num_base::_S_iend] = wchar_t();
|
||||
|
||||
_M_data->_M_truename = L"true";
|
||||
_M_data->_M_falsename = L"false";
|
||||
}
|
||||
|
||||
template<>
|
||||
numpunct<wchar_t>::~numpunct()
|
||||
{ }
|
||||
{ delete _M_data; }
|
||||
#endif
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
// std::numpunct implementation details, GNU version -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2001, 2002 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2001, 2002, 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
|
||||
@ -42,70 +42,112 @@ namespace std
|
||||
void
|
||||
numpunct<char>::_M_initialize_numpunct(__c_locale __cloc)
|
||||
{
|
||||
if (!_M_data)
|
||||
_M_data = new __numpunct_cache<char>;
|
||||
|
||||
if (!__cloc)
|
||||
{
|
||||
// "C" locale
|
||||
_M_decimal_point = '.';
|
||||
_M_thousands_sep = ',';
|
||||
_M_grouping = "";
|
||||
_M_data->_M_grouping = "";
|
||||
_M_data->_M_use_grouping = false;
|
||||
|
||||
_M_data->_M_decimal_point = '.';
|
||||
_M_data->_M_thousands_sep = ',';
|
||||
|
||||
for (size_t i = 0; i < __num_base::_S_oend; ++i)
|
||||
_M_data->_M_atoms_out[i] = __num_base::_S_atoms_out[i];
|
||||
_M_data->_M_atoms_out[__num_base::_S_oend] = wchar_t();
|
||||
|
||||
for (size_t i = 0; i < __num_base::_S_iend; ++i)
|
||||
_M_data->_M_atoms_in[i] = __num_base::_S_atoms_in[i];
|
||||
_M_data->_M_atoms_in[__num_base::_S_iend] = wchar_t();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Named locale.
|
||||
_M_decimal_point = *(__nl_langinfo_l(RADIXCHAR, __cloc));
|
||||
_M_thousands_sep = *(__nl_langinfo_l(THOUSEP, __cloc));
|
||||
// Check for NUL, which implies no grouping.
|
||||
if (_M_thousands_sep == '\0')
|
||||
_M_grouping = "";
|
||||
_M_data->_M_decimal_point = *(__nl_langinfo_l(RADIXCHAR, __cloc));
|
||||
_M_data->_M_thousands_sep = *(__nl_langinfo_l(THOUSEP, __cloc));
|
||||
|
||||
// Check for NULL, which implies no grouping.
|
||||
if (_M_data->_M_thousands_sep == '\0')
|
||||
_M_data->_M_grouping = "";
|
||||
else
|
||||
_M_grouping = __nl_langinfo_l(GROUPING, __cloc);
|
||||
_M_data->_M_grouping = __nl_langinfo_l(GROUPING, __cloc);
|
||||
}
|
||||
// NB: There is no way to extact this info from posix locales.
|
||||
// _M_truename = __nl_langinfo_l(YESSTR, __cloc);
|
||||
_M_truename = "true";
|
||||
_M_data->_M_truename = "true";
|
||||
// _M_falsename = __nl_langinfo_l(NOSTR, __cloc);
|
||||
_M_falsename = "false";
|
||||
_M_data->_M_falsename = "false";
|
||||
}
|
||||
|
||||
template<>
|
||||
numpunct<char>::~numpunct()
|
||||
{ }
|
||||
{ delete _M_data; }
|
||||
|
||||
#ifdef _GLIBCPP_USE_WCHAR_T
|
||||
template<>
|
||||
void
|
||||
numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc)
|
||||
{
|
||||
if (!_M_data)
|
||||
_M_data = new __numpunct_cache<wchar_t>;
|
||||
|
||||
if (!__cloc)
|
||||
{
|
||||
// "C" locale
|
||||
_M_decimal_point = L'.';
|
||||
_M_thousands_sep = L',';
|
||||
_M_grouping = "";
|
||||
_M_data->_M_grouping = "";
|
||||
_M_data->_M_use_grouping = false;
|
||||
|
||||
_M_data->_M_decimal_point = L'.';
|
||||
_M_data->_M_thousands_sep = L',';
|
||||
|
||||
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
|
||||
__c_locale __old = __uselocale(_S_c_locale);
|
||||
#endif
|
||||
// Use ctype::widen code without the facet...
|
||||
unsigned char uc;
|
||||
for (size_t i = 0; i < __num_base::_S_oend; ++i)
|
||||
{
|
||||
uc = static_cast<unsigned char>(__num_base::_S_atoms_out[i]);
|
||||
_M_data->_M_atoms_out[i] = btowc(uc);
|
||||
}
|
||||
_M_data->_M_atoms_out[__num_base::_S_oend] = wchar_t();
|
||||
|
||||
for (size_t i = 0; i < __num_base::_S_iend; ++i)
|
||||
{
|
||||
uc = static_cast<unsigned char>(__num_base::_S_atoms_in[i]);
|
||||
_M_data->_M_atoms_in[i] = btowc(uc);
|
||||
}
|
||||
_M_data->_M_atoms_in[__num_base::_S_iend] = wchar_t();
|
||||
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
|
||||
__uselocale(__old);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// Named locale.
|
||||
union __s_and_w { const char *__s; unsigned int __w; } __u;
|
||||
__u.__s = __nl_langinfo_l(_NL_NUMERIC_DECIMAL_POINT_WC, __cloc);
|
||||
_M_decimal_point = static_cast<wchar_t>(__u.__w);
|
||||
_M_data->_M_decimal_point = static_cast<wchar_t>(__u.__w);
|
||||
|
||||
__u.__s = __nl_langinfo_l(_NL_NUMERIC_THOUSANDS_SEP_WC, __cloc);
|
||||
_M_thousands_sep = static_cast<wchar_t>(__u.__w);
|
||||
if (_M_thousands_sep == L'\0')
|
||||
_M_grouping = "";
|
||||
_M_data->_M_thousands_sep = static_cast<wchar_t>(__u.__w);
|
||||
|
||||
if (_M_data->_M_thousands_sep == L'\0')
|
||||
_M_data->_M_grouping = "";
|
||||
else
|
||||
_M_grouping = __nl_langinfo_l(GROUPING, __cloc);
|
||||
_M_data->_M_grouping = __nl_langinfo_l(GROUPING, __cloc);
|
||||
}
|
||||
// NB: There is no way to extact this info from posix locales.
|
||||
// _M_truename = __nl_langinfo_l(YESSTR, __cloc);
|
||||
_M_truename = L"true";
|
||||
_M_data->_M_truename = L"true";
|
||||
// _M_falsename = __nl_langinfo_l(NOSTR, __cloc);
|
||||
_M_falsename = L"false";
|
||||
_M_data->_M_falsename = L"false";
|
||||
}
|
||||
|
||||
template<>
|
||||
numpunct<wchar_t>::~numpunct()
|
||||
{ }
|
||||
{ delete _M_data; }
|
||||
#endif
|
||||
}
|
||||
|
@ -138,12 +138,7 @@ namespace std
|
||||
ios_base::_M_init();
|
||||
|
||||
// Cache locale data and specific facets used by iostreams.
|
||||
if (!_M_locale_cache.get())
|
||||
{
|
||||
typedef __locale_cache<_CharT> __cache_t;
|
||||
this->_M_locale_cache = auto_ptr<__locale_cache_base>(static_cast<__locale_cache_base*>(new __cache_t));
|
||||
_M_cache_locale(_M_ios_locale);
|
||||
}
|
||||
_M_cache_locale(_M_ios_locale);
|
||||
|
||||
// NB: The 27.4.4.1 Postconditions Table specifies requirements
|
||||
// after basic_ios::init() has been called. As part of this,
|
||||
@ -176,7 +171,6 @@ namespace std
|
||||
_M_num_put = &use_facet<__numput_type>(__loc);
|
||||
if (__builtin_expect(has_facet<__numget_type>(__loc), true))
|
||||
_M_num_get = &use_facet<__numget_type>(__loc);
|
||||
static_cast<__locale_cache<_CharT>&>(_M_cache())._M_init(__loc);
|
||||
}
|
||||
|
||||
// Inhibit implicit instantiations for required instantiations,
|
||||
|
@ -146,8 +146,6 @@ namespace std
|
||||
|
||||
enum _Ios_Seekdir { _S_ios_seekdir_end = 1L << 16 };
|
||||
|
||||
class __locale_cache_base;
|
||||
|
||||
// 27.4.2 Class ios_base
|
||||
/**
|
||||
* @brief The very top of the I/O class hierarchy.
|
||||
@ -212,47 +210,65 @@ namespace std
|
||||
* - floatfield
|
||||
*/
|
||||
typedef _Ios_Fmtflags fmtflags;
|
||||
|
||||
/// Insert/extract @c bool in alphabetic rather than numeric format.
|
||||
static const fmtflags boolalpha = fmtflags(__ios_flags::_S_boolalpha);
|
||||
|
||||
/// Converts integer input or generates integer output in decimal base.
|
||||
static const fmtflags dec = fmtflags(__ios_flags::_S_dec);
|
||||
|
||||
/// Generate floating-point output in fixed-point notation.
|
||||
static const fmtflags fixed = fmtflags(__ios_flags::_S_fixed);
|
||||
|
||||
/// Converts integer input or generates integer output in hexadecimal base.
|
||||
static const fmtflags hex = fmtflags(__ios_flags::_S_hex);
|
||||
|
||||
/// Adds fill characters at a designated internal point in certain
|
||||
/// generated output, or identical to @c right if no such point is
|
||||
/// designated.
|
||||
static const fmtflags internal = fmtflags(__ios_flags::_S_internal);
|
||||
|
||||
/// Adds fill characters on the right (final positions) of certain
|
||||
/// generated output. (I.e., the thing you print is flush left.)
|
||||
static const fmtflags left = fmtflags(__ios_flags::_S_left);
|
||||
|
||||
/// Converts integer input or generates integer output in octal base.
|
||||
static const fmtflags oct = fmtflags(__ios_flags::_S_oct);
|
||||
|
||||
/// Adds fill characters on the left (initial positions) of certain
|
||||
/// generated output. (I.e., the thing you print is flush right.)
|
||||
static const fmtflags right = fmtflags(__ios_flags::_S_right);
|
||||
|
||||
/// Generates floating-point output in scientific notation.
|
||||
static const fmtflags scientific = fmtflags(__ios_flags::_S_scientific);
|
||||
|
||||
/// Generates a prefix indicating the numeric base of generated integer
|
||||
/// output.
|
||||
static const fmtflags showbase = fmtflags(__ios_flags::_S_showbase);
|
||||
|
||||
/// Generates a decimal-point character unconditionally in generated
|
||||
/// floating-point output.
|
||||
static const fmtflags showpoint = fmtflags(__ios_flags::_S_showpoint);
|
||||
|
||||
/// Generates a + sign in non-negative generated numeric output.
|
||||
static const fmtflags showpos = fmtflags(__ios_flags::_S_showpos);
|
||||
|
||||
/// Skips leading white space before certain input operations.
|
||||
static const fmtflags skipws = fmtflags(__ios_flags::_S_skipws);
|
||||
|
||||
/// Flushes output after each output operation.
|
||||
static const fmtflags unitbuf = fmtflags(__ios_flags::_S_unitbuf);
|
||||
|
||||
/// Replaces certain lowercase letters with their uppercase equivalents
|
||||
/// in generated output.
|
||||
static const fmtflags uppercase = fmtflags(__ios_flags::_S_uppercase);
|
||||
|
||||
/// A mask of left|right|internal. Useful for the 2-arg form of @c setf.
|
||||
static const fmtflags adjustfield = fmtflags(__ios_flags::_S_adjustfield);
|
||||
|
||||
/// A mask of dec|oct|hex. Useful for the 2-arg form of @c setf.
|
||||
static const fmtflags basefield = fmtflags(__ios_flags::_S_basefield);
|
||||
|
||||
/// A mask of scientific|fixed. Useful for the 2-arg form of @c setf.
|
||||
static const fmtflags floatfield = fmtflags(__ios_flags::_S_floatfield);
|
||||
|
||||
@ -269,15 +285,19 @@ namespace std
|
||||
* - goodbit
|
||||
*/
|
||||
typedef _Ios_Iostate iostate;
|
||||
|
||||
/// Indicates a loss of integrity in an input or output sequence (such
|
||||
/// as an irrecoverable read error from a file).
|
||||
static const iostate badbit = iostate(__ios_flags::_S_badbit);
|
||||
|
||||
/// Indicates that an input operation reached the end of an input sequence.
|
||||
static const iostate eofbit = iostate(__ios_flags::_S_eofbit);
|
||||
|
||||
/// Indicates that an input operation failed to read the expected
|
||||
/// characters, or that an output operation failed to generate the
|
||||
/// desired characters.
|
||||
static const iostate failbit = iostate(__ios_flags::_S_failbit);
|
||||
|
||||
/// Indicates all is well.
|
||||
static const iostate goodbit = iostate(0);
|
||||
|
||||
@ -296,19 +316,25 @@ namespace std
|
||||
* - trunc
|
||||
*/
|
||||
typedef _Ios_Openmode openmode;
|
||||
|
||||
/// Seek to end before each write.
|
||||
static const openmode app = openmode(__ios_flags::_S_app);
|
||||
|
||||
/// Open and seek to end immediately after opening.
|
||||
static const openmode ate = openmode(__ios_flags::_S_ate);
|
||||
|
||||
/// Perform input and output in binary mode (as opposed to text mode).
|
||||
/// This is probably not what you think it is; see
|
||||
/// http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#3 and
|
||||
/// http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#7 for more.
|
||||
static const openmode binary = openmode(__ios_flags::_S_bin);
|
||||
|
||||
/// Open for input. Default for @c ifstream and fstream.
|
||||
static const openmode in = openmode(__ios_flags::_S_in);
|
||||
|
||||
/// Open for output. Default for @c ofstream and fstream.
|
||||
static const openmode out = openmode(__ios_flags::_S_out);
|
||||
|
||||
/// Open for input. Default for @c ofstream.
|
||||
static const openmode trunc = openmode(__ios_flags::_S_trunc);
|
||||
|
||||
@ -323,10 +349,13 @@ namespace std
|
||||
* - end, equivalent to @c SEEK_END in the C standard library.
|
||||
*/
|
||||
typedef _Ios_Seekdir seekdir;
|
||||
|
||||
/// Request a seek relative to the beginning of the stream.
|
||||
static const seekdir beg = seekdir(0);
|
||||
|
||||
/// Request a seek relative to the current position within the sequence.
|
||||
static const seekdir cur = seekdir(SEEK_CUR);
|
||||
|
||||
/// Request a seek relative to the current end of the sequence.
|
||||
static const seekdir end = seekdir(SEEK_END);
|
||||
|
||||
@ -432,10 +461,6 @@ namespace std
|
||||
// Members for locale and locale caching.
|
||||
locale _M_ios_locale;
|
||||
|
||||
// Cache of locale and facet data.
|
||||
// Cast this to __locale_cache<_CharT>*
|
||||
auto_ptr<__locale_cache_base> _M_locale_cache;
|
||||
|
||||
void
|
||||
_M_init();
|
||||
|
||||
@ -604,7 +629,7 @@ namespace std
|
||||
|
||||
/**
|
||||
* @brief Locale access
|
||||
* @return The locale currently in effect.
|
||||
* @return A copy of the current locale.
|
||||
*
|
||||
* If @c imbue(loc) has previously been called, then this function
|
||||
* returns @c loc. Otherwise, it returns a copy of @c std::locale(),
|
||||
@ -613,6 +638,16 @@ namespace std
|
||||
inline locale
|
||||
getloc() const { return _M_ios_locale; }
|
||||
|
||||
/**
|
||||
* @brief Locale access
|
||||
* @return A reference to the current locale.
|
||||
*
|
||||
* Like getloc above, but returns a reference instead of
|
||||
* generating a copy.
|
||||
*/
|
||||
inline const locale&
|
||||
_M_getloc() const { return _M_ios_locale; }
|
||||
|
||||
// [27.4.2.5] ios_base storage functions
|
||||
/**
|
||||
* @doctodo
|
||||
@ -642,11 +677,6 @@ namespace std
|
||||
return __word._M_pword;
|
||||
}
|
||||
|
||||
// Access to the cache. Not safe to call until basic_ios::_M_init() has
|
||||
// happened.
|
||||
__locale_cache_base&
|
||||
_M_cache() { return *_M_locale_cache; }
|
||||
|
||||
// Destructor
|
||||
/**
|
||||
* Destroys local storage and
|
||||
|
@ -71,7 +71,11 @@ namespace std
|
||||
template<typename _Facet>
|
||||
friend const _Facet&
|
||||
use_facet(const locale&);
|
||||
|
||||
|
||||
template<typename _Cache>
|
||||
friend const _Cache&
|
||||
__use_cache(const locale& __loc);
|
||||
|
||||
// Category values:
|
||||
// NB: Order must match _S_facet_categories definition in locale.cc
|
||||
static const category none = 0;
|
||||
@ -141,6 +145,12 @@ namespace std
|
||||
// Current global locale
|
||||
static _Impl* _S_global;
|
||||
|
||||
// Names of underlying locale categories.
|
||||
// NB: locale::global() has to know how to modify all the
|
||||
// underlying categories, not just the ones required by the C++
|
||||
// standard.
|
||||
static const char** _S_categories;
|
||||
|
||||
// Number of standard categories. For C++, these categories are
|
||||
// collate, ctype, monetary, numeric, time, and messages. These
|
||||
// directly correspond to ISO C99 macros LC_COLLATE, LC_CTYPE,
|
||||
@ -153,12 +163,6 @@ namespace std
|
||||
// and LC_IDENTIFICATION.
|
||||
static const size_t _S_categories_size = 6 + _GLIBCPP_NUM_CATEGORIES;
|
||||
|
||||
// Names of underlying locale categories.
|
||||
// NB: locale::global() has to know how to modify all the
|
||||
// underlying categories, not just the ones required by the C++
|
||||
// standard.
|
||||
static const char** _S_categories;
|
||||
|
||||
explicit
|
||||
locale(_Impl*) throw();
|
||||
|
||||
@ -177,7 +181,107 @@ namespace std
|
||||
};
|
||||
|
||||
|
||||
// Implementation object for locale
|
||||
// 22.1.1.1.2 Class locale::facet
|
||||
class locale::facet
|
||||
{
|
||||
private:
|
||||
friend class locale;
|
||||
friend class locale::_Impl;
|
||||
|
||||
mutable _Atomic_word _M_references;
|
||||
|
||||
protected:
|
||||
// Contains data from the underlying "C" library for the classic locale.
|
||||
static __c_locale _S_c_locale;
|
||||
|
||||
// String literal for the name of the classic locale.
|
||||
static char _S_c_name[2];
|
||||
|
||||
explicit
|
||||
facet(size_t __refs = 0) throw() : _M_references(__refs ? 1 : 0)
|
||||
{ }
|
||||
|
||||
virtual
|
||||
~facet();
|
||||
|
||||
static void
|
||||
_S_create_c_locale(__c_locale& __cloc, const char* __s,
|
||||
__c_locale __old = 0);
|
||||
|
||||
static __c_locale
|
||||
_S_clone_c_locale(__c_locale& __cloc);
|
||||
|
||||
static void
|
||||
_S_destroy_c_locale(__c_locale& __cloc);
|
||||
|
||||
private:
|
||||
inline void
|
||||
_M_add_reference() const throw()
|
||||
{ __atomic_add(&_M_references, 1); }
|
||||
|
||||
inline void
|
||||
_M_remove_reference() const throw()
|
||||
{
|
||||
if (__exchange_and_add(&_M_references, -1) == 1)
|
||||
{
|
||||
try
|
||||
{ delete this; }
|
||||
catch (...)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
|
||||
facet(const facet&); // Not defined.
|
||||
|
||||
void
|
||||
operator=(const facet&); // Not defined.
|
||||
};
|
||||
|
||||
|
||||
// 22.1.1.1.3 Class locale::id
|
||||
class locale::id
|
||||
{
|
||||
private:
|
||||
friend class locale;
|
||||
friend class locale::_Impl;
|
||||
|
||||
template<typename _Facet>
|
||||
friend const _Facet&
|
||||
use_facet(const locale&);
|
||||
|
||||
template<typename _Facet>
|
||||
friend bool
|
||||
has_facet(const locale&) throw ();
|
||||
|
||||
// NB: There is no accessor for _M_index because it may be used
|
||||
// before the constructor is run; the effect of calling a member
|
||||
// function (even an inline) would be undefined.
|
||||
mutable size_t _M_index;
|
||||
|
||||
// Last id number assigned.
|
||||
static _Atomic_word _S_highwater;
|
||||
|
||||
void
|
||||
operator=(const id&); // Not defined.
|
||||
|
||||
id(const id&); // Not defined.
|
||||
|
||||
public:
|
||||
// NB: This class is always a static data member, and thus can be
|
||||
// counted on to be zero-initialized.
|
||||
id() { }
|
||||
|
||||
inline size_t
|
||||
_M_id() const
|
||||
{
|
||||
if (!_M_index)
|
||||
_M_index = 1 + __exchange_and_add(&_S_highwater, 1);
|
||||
return _M_index - 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Implementation object for locale.
|
||||
class locale::_Impl
|
||||
{
|
||||
public:
|
||||
@ -185,19 +289,24 @@ namespace std
|
||||
friend class locale;
|
||||
friend class locale::facet;
|
||||
|
||||
template<typename _Facet>
|
||||
friend bool
|
||||
has_facet(const locale&) throw();
|
||||
|
||||
template<typename _Facet>
|
||||
friend const _Facet&
|
||||
use_facet(const locale&);
|
||||
|
||||
template<typename _Facet>
|
||||
friend bool
|
||||
has_facet(const locale&) throw();
|
||||
template<typename _Cache>
|
||||
friend const _Cache&
|
||||
__use_cache(const locale& __loc);
|
||||
|
||||
private:
|
||||
// Data Members.
|
||||
_Atomic_word _M_references;
|
||||
const facet** _M_facets;
|
||||
size_t _M_facets_size;
|
||||
const facet** _M_caches;
|
||||
char** _M_names;
|
||||
static const locale::id* const _S_id_ctype[];
|
||||
static const locale::id* const _S_id_numeric[];
|
||||
@ -258,7 +367,14 @@ namespace std
|
||||
template<typename _Facet>
|
||||
inline void
|
||||
_M_init_facet(_Facet* __facet)
|
||||
{ _M_install_facet(&_Facet::id, __facet); }
|
||||
{ _M_install_facet(&_Facet::id, __facet); }
|
||||
|
||||
void
|
||||
_M_install_cache(const facet* __cache, size_t __index)
|
||||
{
|
||||
__cache->_M_add_reference();
|
||||
_M_caches[__index] = __cache;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename _Facet>
|
||||
@ -274,93 +390,6 @@ namespace std
|
||||
_M_impl->_M_names[__i] = __new;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 22.1.1.1.2 Class locale::facet
|
||||
class locale::facet
|
||||
{
|
||||
private:
|
||||
friend class locale;
|
||||
friend class locale::_Impl;
|
||||
|
||||
mutable _Atomic_word _M_references;
|
||||
|
||||
protected:
|
||||
// Contains data from the underlying "C" library for the classic locale.
|
||||
static __c_locale _S_c_locale;
|
||||
|
||||
// String literal for the name of the classic locale.
|
||||
static char _S_c_name[2];
|
||||
|
||||
explicit
|
||||
facet(size_t __refs = 0) throw();
|
||||
|
||||
virtual
|
||||
~facet();
|
||||
|
||||
static void
|
||||
_S_create_c_locale(__c_locale& __cloc, const char* __s,
|
||||
__c_locale __old = 0);
|
||||
|
||||
static __c_locale
|
||||
_S_clone_c_locale(__c_locale& __cloc);
|
||||
|
||||
static void
|
||||
_S_destroy_c_locale(__c_locale& __cloc);
|
||||
|
||||
private:
|
||||
void
|
||||
_M_add_reference() const throw();
|
||||
|
||||
void
|
||||
_M_remove_reference() const throw();
|
||||
|
||||
facet(const facet&); // Not defined.
|
||||
|
||||
void
|
||||
operator=(const facet&); // Not defined.
|
||||
};
|
||||
|
||||
|
||||
// 22.1.1.1.3 Class locale::id
|
||||
class locale::id
|
||||
{
|
||||
private:
|
||||
friend class locale;
|
||||
friend class locale::_Impl;
|
||||
template<typename _Facet>
|
||||
friend const _Facet&
|
||||
use_facet(const locale&);
|
||||
template<typename _Facet>
|
||||
friend bool
|
||||
has_facet(const locale&) throw ();
|
||||
|
||||
// NB: There is no accessor for _M_index because it may be used
|
||||
// before the constructor is run; the effect of calling a member
|
||||
// function (even an inline) would be undefined.
|
||||
mutable size_t _M_index;
|
||||
|
||||
// Last id number assigned.
|
||||
static _Atomic_word _S_highwater;
|
||||
|
||||
void
|
||||
operator=(const id&); // Not defined.
|
||||
|
||||
id(const id&); // Not defined.
|
||||
|
||||
public:
|
||||
// NB: This class is always a static data member, and thus can be
|
||||
// counted on to be zero-initialized.
|
||||
id();
|
||||
|
||||
inline size_t
|
||||
_M_id() const
|
||||
{
|
||||
if (!_M_index)
|
||||
_M_index = 1 + __exchange_and_add(&_S_highwater, 1);
|
||||
return _M_index - 1;
|
||||
}
|
||||
};
|
||||
} // namespace std
|
||||
|
||||
#endif
|
||||
|
@ -574,6 +574,96 @@ namespace std
|
||||
_S_format_float(const ios_base& __io, char* __fptr, char __mod);
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
// 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().
|
||||
_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().
|
||||
_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)
|
||||
{ }
|
||||
|
||||
~__numpunct_cache();
|
||||
|
||||
void
|
||||
_M_cache(const locale& __loc);
|
||||
};
|
||||
|
||||
template<typename _CharT>
|
||||
void
|
||||
__numpunct_cache<_CharT>::_M_cache(const locale& __loc)
|
||||
{
|
||||
const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
|
||||
string __grouping = __np.grouping();
|
||||
char* __group = new char[__grouping.length() + 1];
|
||||
__grouping.copy(__group, __grouping.length());
|
||||
__group[__grouping.length()] = _CharT();
|
||||
_M_grouping = __group;
|
||||
|
||||
_M_use_grouping = __grouping.length() != 0 && __grouping.data()[0] != 0;
|
||||
|
||||
typedef basic_string<_CharT> __string_type;
|
||||
|
||||
__string_type __true = __np.truename();
|
||||
_CharT* __truename = new _CharT[__true.length() + 1];
|
||||
__true.copy(__truename, __true.length());
|
||||
__truename[__true.length()] = _CharT();
|
||||
_M_truename = __truename;
|
||||
|
||||
__string_type __false = __np.falsename();
|
||||
_CharT* __falsename = new _CharT[__false.length() + 1];
|
||||
__false.copy(__falsename, __false.length());
|
||||
__falsename[__false.length()] = _CharT();
|
||||
_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);
|
||||
_M_atoms_out[__num_base::_S_oend] = _CharT();
|
||||
__ct.widen(__num_base::_S_atoms_in,
|
||||
__num_base::_S_atoms_in + __num_base::_S_iend, _M_atoms_in);
|
||||
_M_atoms_in[__num_base::_S_iend] = _CharT();
|
||||
|
||||
_M_allocated = true;
|
||||
}
|
||||
|
||||
template<typename _CharT>
|
||||
__numpunct_cache<_CharT>::~__numpunct_cache()
|
||||
{
|
||||
if (_M_allocated)
|
||||
{
|
||||
delete [] _M_grouping;
|
||||
delete [] _M_truename;
|
||||
delete [] _M_falsename;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename _CharT>
|
||||
class numpunct : public locale::facet
|
||||
@ -582,23 +672,26 @@ namespace std
|
||||
// Types:
|
||||
typedef _CharT char_type;
|
||||
typedef basic_string<_CharT> string_type;
|
||||
typedef __numpunct_cache<_CharT> __cache_type;
|
||||
|
||||
static locale::id id;
|
||||
|
||||
private:
|
||||
char_type _M_decimal_point;
|
||||
char_type _M_thousands_sep;
|
||||
const char* _M_grouping;
|
||||
const char_type* _M_truename;
|
||||
const char_type* _M_falsename;
|
||||
protected:
|
||||
__cache_type* _M_data;
|
||||
|
||||
public:
|
||||
static locale::id id;
|
||||
|
||||
explicit
|
||||
numpunct(size_t __refs = 0) : locale::facet(__refs)
|
||||
numpunct(size_t __refs = 0) : facet(__refs), _M_data(NULL)
|
||||
{ _M_initialize_numpunct(); }
|
||||
|
||||
explicit
|
||||
numpunct(__c_locale __cloc, size_t __refs = 0) : locale::facet(__refs)
|
||||
numpunct(__cache_type* __cache, size_t __refs = 0)
|
||||
: facet(__refs), _M_data(__cache)
|
||||
{ _M_initialize_numpunct(); }
|
||||
|
||||
explicit
|
||||
numpunct(__c_locale __cloc, size_t __refs = 0)
|
||||
: locale::facet(__refs), _M_data(NULL)
|
||||
{ _M_initialize_numpunct(__cloc); }
|
||||
|
||||
char_type
|
||||
@ -627,23 +720,23 @@ namespace std
|
||||
|
||||
virtual char_type
|
||||
do_decimal_point() const
|
||||
{ return _M_decimal_point; }
|
||||
{ return _M_data->_M_decimal_point; }
|
||||
|
||||
virtual char_type
|
||||
do_thousands_sep() const
|
||||
{ return _M_thousands_sep; }
|
||||
{ return _M_data->_M_thousands_sep; }
|
||||
|
||||
virtual string
|
||||
do_grouping() const
|
||||
{ return _M_grouping; }
|
||||
{ return _M_data->_M_grouping; }
|
||||
|
||||
virtual string_type
|
||||
do_truename() const
|
||||
{ return _M_truename; }
|
||||
{ return _M_data->_M_truename; }
|
||||
|
||||
virtual string_type
|
||||
do_falsename() const
|
||||
{ return _M_falsename; }
|
||||
{ return _M_data->_M_falsename; }
|
||||
|
||||
// For use at construction time only.
|
||||
void
|
||||
@ -1928,75 +2021,6 @@ namespace std
|
||||
inline _CharT
|
||||
tolower(_CharT __c, const locale& __loc)
|
||||
{ return use_facet<ctype<_CharT> >(__loc).tolower(__c); }
|
||||
|
||||
|
||||
// __locale_cache holds the information extracted from the
|
||||
// numpunct<> and moneypunct<> facets in a form optimized for
|
||||
// parsing and formatting. It is stored as an
|
||||
// auto_ptr<__locale_cache_base> member of ios_base and directly
|
||||
// accessed via a casting to the derived __locale_cache<_CharT> in
|
||||
// parameterized facets.
|
||||
// The intent twofold: to avoid the costs of creating a locale
|
||||
// object and to avoid calling the virtual functions in a locale's
|
||||
// facet to look up data.
|
||||
class __locale_cache_base
|
||||
{
|
||||
public:
|
||||
virtual
|
||||
~__locale_cache_base() { }
|
||||
};
|
||||
|
||||
template<typename _CharT>
|
||||
class __locale_cache : public __locale_cache_base
|
||||
{
|
||||
// Types:
|
||||
typedef _CharT char_type;
|
||||
typedef char_traits<_CharT> traits_type;
|
||||
typedef basic_string<_CharT> string_type;
|
||||
|
||||
public:
|
||||
// Data Members:
|
||||
|
||||
// A list of valid numeric literals: for the standard "C"
|
||||
// locale, this is "-+xX0123456789abcdef0123456789ABCDEF". This
|
||||
// array contains the chars after having been passed through the
|
||||
// current locale's ctype<_CharT>.widen().
|
||||
_CharT _M_literals[__num_base::_S_oend];
|
||||
|
||||
// The sign used to separate decimal values: for standard US
|
||||
// locales, this would usually be: "." Abstracted from
|
||||
// numpunct::decimal_point().
|
||||
_CharT _M_decimal_point;
|
||||
|
||||
// The sign used to separate groups of digits into smaller
|
||||
// strings that the eye can parse with less difficulty: for
|
||||
// standard US locales, this would usually be: "," Abstracted
|
||||
// from numpunct::thousands_sep().
|
||||
_CharT _M_thousands_sep;
|
||||
|
||||
// However the US's "false" and "true" are translated. From
|
||||
// numpunct::truename() and numpunct::falsename(), respectively.
|
||||
string_type _M_truename;
|
||||
string_type _M_falsename;
|
||||
|
||||
// If we are checking groupings. This should be equivalent to
|
||||
// numpunct::groupings().size() != 0
|
||||
bool _M_use_grouping;
|
||||
|
||||
// If we are using numpunct's groupings, this is the current
|
||||
// grouping string in effect (from numpunct::grouping()).
|
||||
string _M_grouping;
|
||||
|
||||
__locale_cache() : _M_use_grouping(false)
|
||||
{ };
|
||||
|
||||
__locale_cache&
|
||||
operator=(const __locale_cache& __lc);
|
||||
|
||||
// Make sure the cache is built before the first use.
|
||||
void
|
||||
_M_init(const locale&);
|
||||
};
|
||||
} // namespace std
|
||||
|
||||
#endif
|
||||
|
@ -86,6 +86,21 @@ namespace std
|
||||
return static_cast<const _Facet&>(*__facets[__i]);
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
template<>
|
||||
const __numpunct_cache<char>&
|
||||
__use_cache(const locale& __loc);
|
||||
|
||||
#ifdef _GLIBCPP_USE_WCHAR_T
|
||||
template<>
|
||||
const __numpunct_cache<wchar_t>&
|
||||
__use_cache(const locale& __loc);
|
||||
#endif
|
||||
|
||||
// Stage 1: Determine a conversion specifier.
|
||||
template<typename _CharT, typename _InIter>
|
||||
@ -768,11 +783,12 @@ namespace std
|
||||
_M_convert_int(_OutIter __s, ios_base& __io, _CharT __fill,
|
||||
_ValueT __v) const
|
||||
{
|
||||
typedef __locale_cache<_CharT> __cache_type;
|
||||
__cache_type& __lc = static_cast<__cache_type&>(__io._M_cache());
|
||||
_CharT* __lit = __lc._M_literals;
|
||||
typedef typename numpunct<_CharT>::__cache_type __cache_type;
|
||||
const locale& __loc = __io._M_getloc();
|
||||
const __cache_type& __lc = __use_cache<__cache_type>(__loc);
|
||||
const _CharT* __lit = __lc._M_atoms_out;
|
||||
|
||||
// Long enough to hold hex, dec, and octal representations.
|
||||
// Long enough to hold hex, dec, and octal representations.
|
||||
int __ilen = 4 * sizeof(_ValueT);
|
||||
_CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
|
||||
* __ilen));
|
||||
@ -872,8 +888,9 @@ namespace std
|
||||
else if (__prec < static_cast<streamsize>(0))
|
||||
__prec = static_cast<streamsize>(6);
|
||||
|
||||
typedef __locale_cache<_CharT> __cache_type;
|
||||
__cache_type& __lc = static_cast<__cache_type&>(__io._M_cache());
|
||||
typedef typename numpunct<_CharT>::__cache_type __cache_type;
|
||||
const locale& __loc = __io._M_getloc();
|
||||
const __cache_type& __lc = __use_cache<__cache_type>(__loc);
|
||||
|
||||
// [22.2.2.2.2] Stage 1, numeric conversion to character.
|
||||
int __len;
|
||||
@ -918,7 +935,6 @@ namespace std
|
||||
|
||||
// [22.2.2.2.2] Stage 2, convert to char_type, using correct
|
||||
// numpunct.decimal_point() values for '.' and adding grouping.
|
||||
const locale __loc = __io.getloc();
|
||||
const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
|
||||
|
||||
_CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
|
||||
@ -974,8 +990,10 @@ namespace std
|
||||
}
|
||||
else
|
||||
{
|
||||
typedef __locale_cache<_CharT> __cache_type;
|
||||
__cache_type& __lc = static_cast<__cache_type&>(__io._M_cache());
|
||||
typedef typename numpunct<_CharT>::__cache_type __cache_type;
|
||||
const locale& __loc = __io._M_getloc();
|
||||
const __cache_type& __lc = __use_cache<__cache_type>(__loc);
|
||||
|
||||
typedef basic_string<_CharT> __string_type;
|
||||
__string_type __name;
|
||||
if (__v)
|
||||
@ -2273,31 +2291,6 @@ namespace std
|
||||
return __s;
|
||||
}
|
||||
|
||||
// Generic definition, locale cache initialization.
|
||||
template<typename _CharT>
|
||||
void
|
||||
__locale_cache<_CharT>::_M_init(const locale& __loc)
|
||||
{
|
||||
if (__builtin_expect(has_facet<numpunct<_CharT> >(__loc), true))
|
||||
{
|
||||
const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
|
||||
_M_falsename = __np.falsename();
|
||||
_M_truename = __np.truename();
|
||||
_M_thousands_sep = __np.thousands_sep();
|
||||
_M_decimal_point = __np.decimal_point();
|
||||
_M_grouping = __np.grouping();
|
||||
_M_use_grouping = _M_grouping.size() != 0
|
||||
&& _M_grouping.data()[0] != 0;
|
||||
}
|
||||
if (__builtin_expect(has_facet<ctype<_CharT> >(__loc), true))
|
||||
{
|
||||
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_literals);
|
||||
}
|
||||
}
|
||||
|
||||
// Inhibit implicit instantiations for required instantiations,
|
||||
// which are defined via explicit instantiations elsewhere.
|
||||
// NB: This syntax is a GNU extension.
|
||||
|
@ -127,6 +127,10 @@ namespace __gnu_cxx
|
||||
__attribute__ ((aligned(__alignof__(locale::facet*))));
|
||||
fake_facet_vec facet_vec[_GLIBCPP_NUM_FACETS];
|
||||
|
||||
typedef char fake_cache_vec[sizeof(locale::facet*)]
|
||||
__attribute__ ((aligned(__alignof__(locale::facet*))));
|
||||
fake_cache_vec cache_vec[_GLIBCPP_NUM_FACETS];
|
||||
|
||||
typedef char fake_ctype_c[sizeof(std::ctype<char>)]
|
||||
__attribute__ ((aligned(__alignof__(std::ctype<char>))));
|
||||
fake_ctype_c ctype_c;
|
||||
@ -235,6 +239,17 @@ namespace __gnu_cxx
|
||||
fake_messages_w messages_w;
|
||||
#endif
|
||||
|
||||
// Storage for C locale caches
|
||||
typedef char fake_locale_cache_c[sizeof(std::__numpunct_cache<char>)]
|
||||
__attribute__ ((aligned(__alignof__(std::__numpunct_cache<char>))));
|
||||
fake_locale_cache_c numpunct_cache_c;
|
||||
|
||||
#ifdef _GLIBCPP_USE_WCHAR_T
|
||||
typedef char fake_locale_cache_w[sizeof(std::__numpunct_cache<wchar_t>)]
|
||||
__attribute__ ((aligned(__alignof__(std::__numpunct_cache<wchar_t>))));
|
||||
fake_locale_cache_w numpunct_cache_w;
|
||||
#endif
|
||||
|
||||
// Globals for once-only runtime initialization of mutex objects. This
|
||||
// allows static initialization of these objects on systems that need a
|
||||
// function call to initialize a mutex. For example, see stl_threads.h.
|
||||
|
@ -297,8 +297,8 @@ namespace std
|
||||
return __old;
|
||||
}
|
||||
|
||||
ios_base::ios_base() : _M_callbacks(0), _M_word_size(_S_local_word_size),
|
||||
_M_word(_M_local_word), _M_locale_cache(0)
|
||||
ios_base::ios_base()
|
||||
: _M_callbacks(0), _M_word_size(_S_local_word_size), _M_word(_M_local_word)
|
||||
{
|
||||
// Do nothing: basic_ios::init() does it.
|
||||
// NB: _M_callbacks and _M_word must be zero for non-initialized
|
||||
|
@ -45,7 +45,6 @@ namespace std
|
||||
template class moneypunct_byname<char, true>;
|
||||
template class money_get<char, istreambuf_iterator<char> >;
|
||||
template class money_put<char, ostreambuf_iterator<char> >;
|
||||
template class __locale_cache<char>;
|
||||
|
||||
#ifdef _GLIBCPP_USE_WCHAR_T
|
||||
template class moneypunct<wchar_t, false>;
|
||||
@ -54,11 +53,11 @@ namespace std
|
||||
template class moneypunct_byname<wchar_t, true>;
|
||||
template class money_get<wchar_t, istreambuf_iterator<wchar_t> >;
|
||||
template class money_put<wchar_t, ostreambuf_iterator<wchar_t> >;
|
||||
template class __locale_cache<wchar_t>;
|
||||
#endif
|
||||
|
||||
// numpunct, numpunct_byname, num_get, and num_put
|
||||
template class numpunct<char>;
|
||||
template struct __numpunct_cache<char>;
|
||||
template class numpunct_byname<char>;
|
||||
template class num_get<char, istreambuf_iterator<char> >;
|
||||
template class num_put<char, ostreambuf_iterator<char> >;
|
||||
@ -102,6 +101,7 @@ namespace std
|
||||
|
||||
#ifdef _GLIBCPP_USE_WCHAR_T
|
||||
template class numpunct<wchar_t>;
|
||||
template struct __numpunct_cache<wchar_t>;
|
||||
template class numpunct_byname<wchar_t>;
|
||||
template class num_get<wchar_t, istreambuf_iterator<wchar_t> >;
|
||||
template class num_put<wchar_t, ostreambuf_iterator<wchar_t> >;
|
||||
|
@ -449,30 +449,37 @@ namespace std
|
||||
locale::facet::
|
||||
~facet() { }
|
||||
|
||||
locale::facet::
|
||||
facet(size_t __refs) throw() : _M_references(__refs ? 1 : 0)
|
||||
{ }
|
||||
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]);
|
||||
}
|
||||
|
||||
void
|
||||
locale::facet::
|
||||
_M_add_reference() const throw()
|
||||
{ __atomic_add(&_M_references, 1); }
|
||||
|
||||
void
|
||||
locale::facet::
|
||||
_M_remove_reference() const throw()
|
||||
{
|
||||
if (__exchange_and_add(&_M_references, -1) == 1)
|
||||
{
|
||||
try
|
||||
{ delete this; }
|
||||
catch (...)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
|
||||
locale::id::id()
|
||||
{ }
|
||||
#ifdef _GLIBCPP_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<>
|
||||
|
@ -69,6 +69,12 @@ namespace __gnu_cxx
|
||||
extern time_put<wchar_t> time_put_w;
|
||||
extern std::messages<wchar_t> messages_w;
|
||||
#endif
|
||||
|
||||
extern locale::facet* cache_vec[_GLIBCPP_NUM_FACETS];
|
||||
extern std::__numpunct_cache<char> numpunct_cache_c;
|
||||
#ifdef _GLIBCPP_USE_WCHAR_T
|
||||
extern std::__numpunct_cache<wchar_t> numpunct_cache_w;
|
||||
#endif
|
||||
} // namespace __gnu_cxx
|
||||
|
||||
namespace std
|
||||
@ -83,6 +89,11 @@ namespace std
|
||||
_M_facets[__i]->_M_remove_reference();
|
||||
delete [] _M_facets;
|
||||
|
||||
for (size_t __i = 0; __i < _M_facets_size; ++__i)
|
||||
if (_M_caches[__i])
|
||||
_M_caches[__i]->_M_remove_reference();
|
||||
delete [] _M_caches;
|
||||
|
||||
for (size_t __i = 0; __i < _S_categories_size; ++__i)
|
||||
delete [] _M_names[__i];
|
||||
delete [] _M_names;
|
||||
@ -91,7 +102,7 @@ namespace std
|
||||
// Clone existing _Impl object.
|
||||
locale::_Impl::
|
||||
_Impl(const _Impl& __imp, size_t __refs)
|
||||
: _M_references(__refs), _M_facets_size(__imp._M_facets_size) // XXX
|
||||
: _M_references(__refs), _M_facets_size(__imp._M_facets_size)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -111,6 +122,22 @@ namespace std
|
||||
_M_facets[__i]->_M_add_reference();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_M_caches = new const facet*[_M_facets_size];
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
delete [] _M_caches;
|
||||
__throw_exception_again;
|
||||
}
|
||||
for (size_t __i = 0; __i < _M_facets_size; ++__i)
|
||||
{
|
||||
_M_caches[__i] = __imp._M_caches[__i];
|
||||
if (_M_caches[__i])
|
||||
_M_caches[__i]->_M_add_reference();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_M_names = new char*[_S_categories_size];
|
||||
@ -131,10 +158,10 @@ namespace std
|
||||
// Construct named _Impl.
|
||||
locale::_Impl::
|
||||
_Impl(const char* __s, size_t __refs)
|
||||
: _M_references(__refs), _M_facets_size(_GLIBCPP_NUM_FACETS)
|
||||
: _M_references(__refs), _M_facets_size(_GLIBCPP_NUM_FACETS)
|
||||
{
|
||||
// Initialize the underlying locale model, which also checks
|
||||
// to see if the given name is valid.
|
||||
// Initialize the underlying locale model, which also checks to
|
||||
// see if the given name is valid.
|
||||
__c_locale __cloc;
|
||||
locale::facet::_S_create_c_locale(__cloc, __s);
|
||||
|
||||
@ -150,6 +177,18 @@ namespace std
|
||||
__throw_exception_again;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_M_caches = new const facet*[_M_facets_size];
|
||||
for (size_t __i = 0; __i < _M_facets_size; ++__i)
|
||||
_M_caches[__i] = 0;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
delete [] _M_caches;
|
||||
__throw_exception_again;
|
||||
}
|
||||
|
||||
// Name all the categories.
|
||||
try
|
||||
{
|
||||
@ -235,6 +274,10 @@ namespace std
|
||||
for (size_t __i = 0; __i < _M_facets_size; ++__i)
|
||||
_M_facets[__i] = 0;
|
||||
|
||||
_M_caches = new (&cache_vec) const facet*[_M_facets_size];
|
||||
for (size_t __i = 0; __i < _M_facets_size; ++__i)
|
||||
_M_caches[__i] = 0;
|
||||
|
||||
// Name all the categories.
|
||||
_M_names = new (&name_vec) char*[_S_categories_size];
|
||||
for (size_t __i = 0; __i < _S_categories_size; ++__i)
|
||||
@ -252,7 +295,12 @@ namespace std
|
||||
// destroyed.
|
||||
_M_init_facet(new (&ctype_c) std::ctype<char>(0, false, 1));
|
||||
_M_init_facet(new (&codecvt_c) codecvt<char, char, mbstate_t>(1));
|
||||
_M_init_facet(new (&numpunct_c) numpunct<char>(1));
|
||||
|
||||
// Safe to cache this.
|
||||
typedef __numpunct_cache<char> num_cache_c;
|
||||
num_cache_c* __npc = new (&numpunct_cache_c) num_cache_c(2);
|
||||
_M_init_facet(new (&numpunct_c) numpunct<char>(__npc, 1));
|
||||
|
||||
_M_init_facet(new (&num_get_c) num_get<char>(1));
|
||||
_M_init_facet(new (&num_put_c) num_put<char>(1));
|
||||
_M_init_facet(new (&collate_c) std::collate<char>(1));
|
||||
@ -264,10 +312,15 @@ namespace std
|
||||
_M_init_facet(new (&time_get_c) time_get<char>(1));
|
||||
_M_init_facet(new (&time_put_c) time_put<char>(1));
|
||||
_M_init_facet(new (&messages_c) std::messages<char>(1));
|
||||
|
||||
#ifdef _GLIBCPP_USE_WCHAR_T
|
||||
_M_init_facet(new (&ctype_w) std::ctype<wchar_t>(1));
|
||||
_M_init_facet(new (&codecvt_w) codecvt<wchar_t, char, mbstate_t>(1));
|
||||
_M_init_facet(new (&numpunct_w) numpunct<wchar_t>(1));
|
||||
|
||||
typedef __numpunct_cache<wchar_t> num_cache_w;
|
||||
num_cache_w* __npw = new (&numpunct_cache_w) num_cache_w(2);
|
||||
_M_init_facet(new (&numpunct_w) numpunct<wchar_t>(__npw, 1));
|
||||
|
||||
_M_init_facet(new (&num_get_w) num_get<wchar_t>(1));
|
||||
_M_init_facet(new (&num_put_w) num_put<wchar_t>(1));
|
||||
_M_init_facet(new (&collate_w) std::collate<wchar_t>(1));
|
||||
@ -280,6 +333,13 @@ namespace std
|
||||
_M_init_facet(new (&time_put_w) time_put<wchar_t>(1));
|
||||
_M_init_facet(new (&messages_w) std::messages<wchar_t>(1));
|
||||
#endif
|
||||
|
||||
// This locale is safe to pre-cache, after all the facets have
|
||||
// been installed.
|
||||
_M_caches[numpunct<char>::id._M_id()] = __npc;
|
||||
#ifdef _GLIBCPP_USE_WCHAR_T
|
||||
_M_caches[numpunct<wchar_t>::id._M_id()] = __npw;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@ -336,18 +396,31 @@ namespace std
|
||||
// Check size of facet vector to ensure adequate room.
|
||||
if (__index > _M_facets_size - 1)
|
||||
{
|
||||
const facet** __old = _M_facets;
|
||||
const facet** __new;
|
||||
const size_t __new_size = __index + 4;
|
||||
__new = new const facet*[__new_size];
|
||||
|
||||
// New facet array.
|
||||
const facet** __oldf = _M_facets;
|
||||
const facet** __newf;
|
||||
__newf = new const facet*[__new_size];
|
||||
for (size_t __i = 0; __i < _M_facets_size; ++__i)
|
||||
__new[__i] = _M_facets[__i];
|
||||
__newf[__i] = _M_facets[__i];
|
||||
for (size_t __i2 = _M_facets_size; __i2 < __new_size; ++__i2)
|
||||
__new[__i2] = 0;
|
||||
__newf[__i2] = 0;
|
||||
|
||||
// New cache array.
|
||||
const facet** __oldc = _M_caches;
|
||||
const facet** __newc;
|
||||
__newc = new const facet*[__new_size];
|
||||
for (size_t __i = 0; __i < _M_facets_size; ++__i)
|
||||
__newc[__i] = _M_caches[__i];
|
||||
for (size_t __i2 = _M_facets_size; __i2 < __new_size; ++__i2)
|
||||
__newc[__i2] = 0;
|
||||
|
||||
_M_facets_size = __new_size;
|
||||
_M_facets = __new;
|
||||
delete [] __old;
|
||||
_M_facets = __newf;
|
||||
_M_caches = __newc;
|
||||
delete [] __oldf;
|
||||
delete [] __oldc;
|
||||
}
|
||||
|
||||
__fp->_M_add_reference();
|
||||
@ -365,6 +438,21 @@ namespace std
|
||||
// swanky-fresh _Impl.
|
||||
_M_facets[__index] = __fp;
|
||||
}
|
||||
|
||||
// Ideally, it would be nice to only remove the caches that
|
||||
// are now incorrect. However, some of the caches depend on
|
||||
// multiple facets, and we only know about one facet
|
||||
// here. It's no great loss: the first use of the new facet
|
||||
// will create a new, correctly cached facet anyway.
|
||||
for (size_t __i = 0; __i < _M_facets_size; ++__i)
|
||||
{
|
||||
const facet* __cpr = _M_caches[__i];
|
||||
if (__cpr)
|
||||
{
|
||||
__cpr->_M_remove_reference();
|
||||
_M_caches[__i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace std
|
||||
|
@ -41,5 +41,5 @@ void test01()
|
||||
io1 = io2;
|
||||
}
|
||||
// { dg-error "within this context" "" { target *-*-* } 41 }
|
||||
// { dg-error "is private" "" { target *-*-* } 666 }
|
||||
// { dg-error "is private" "" { target *-*-* } 696 }
|
||||
// { dg-error "operator=" "" { target *-*-* } 0 }
|
||||
|
@ -41,5 +41,5 @@ void test02()
|
||||
test_base io2 = io1;
|
||||
}
|
||||
// { dg-error "within this context" "" { target *-*-* } 41 }
|
||||
// { dg-error "is private" "" { target *-*-* } 663 }
|
||||
// { dg-error "is private" "" { target *-*-* } 693 }
|
||||
// { dg-error "copy constructor" "" { target *-*-* } 0 }
|
||||
|
Loading…
Reference in New Issue
Block a user