summaryrefslogtreecommitdiff
path: root/libstdc++-v3/src/localename.cc
diff options
context:
space:
mode:
authorbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>2003-06-27 07:25:38 +0000
committerbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>2003-06-27 07:25:38 +0000
commit36bcb738883bca27b122874e065301e98c98c0a8 (patch)
tree55f27f578e57b31cc0b90efe9cb35cc77809288e /libstdc++-v3/src/localename.cc
parent2207a6a9591bb7f8a3f12ece565124de77f1a763 (diff)
downloadgcc-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.cc114
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