diff options
author | bkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-06-27 07:25:38 +0000 |
---|---|---|
committer | bkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-06-27 07:25:38 +0000 |
commit | 36bcb738883bca27b122874e065301e98c98c0a8 (patch) | |
tree | 55f27f578e57b31cc0b90efe9cb35cc77809288e /libstdc++-v3/src/localename.cc | |
parent | 2207a6a9591bb7f8a3f12ece565124de77f1a763 (diff) | |
download | gcc-36bcb738883bca27b122874e065301e98c98c0a8.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@68558 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/src/localename.cc')
-rw-r--r-- | libstdc++-v3/src/localename.cc | 114 |
1 files changed, 101 insertions, 13 deletions
diff --git a/libstdc++-v3/src/localename.cc b/libstdc++-v3/src/localename.cc index c09900b628f..424bc64fec7 100644 --- a/libstdc++-v3/src/localename.cc +++ b/libstdc++-v3/src/localename.cc @@ -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 { @@ -113,6 +124,22 @@ namespace std 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]; } catch(...) @@ -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) + __newf[__i] = _M_facets[__i]; + for (size_t __i2 = _M_facets_size; __i2 < __new_size; ++__i2) + __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) - __new[__i] = _M_facets[__i]; + __newc[__i] = _M_caches[__i]; for (size_t __i2 = _M_facets_size; __i2 < __new_size; ++__i2) - __new[__i2] = 0; + __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 |