mirror of git://gcc.gnu.org/git/gcc.git
Optimize locale::_M_impl->_M_names for the most common cases...
2004-05-03 Paolo Carlini <pcarlini@suse.de> Optimize locale::_M_impl->_M_names for the most common cases: !_M_names[0] means unnamed; !_M_names[1] means all the categories the same name (_M_names[0] && _M_names[1] means that the full set of _M_names must be processed, the general case). * include/bits/locale_classes.h (locale::_Impl::_M_check_same_name): Tweak, saving work when !_M_names[1]. (locale::locale(const locale&, _Facet*): Simplify: now just setting _M_names[0] = 0 means unnamed. * src/locale.cc (locale::operator==): Deal first with the common, easy cases, otherwise fall back to locale::name(). (locale::name()): Tweak, if !_M_names[0] just return "*". (locale::_Impl::_Impl(const _Impl&, size_t): Tweak, early stop copying __imp._M_names if !__imp._M_names[0] or !__imp._M_names[1]. * src/locale_init.cc (locale::_Impl::_Impl(size_t)): Tweak. * src/localename.cc (locale::_Impl::_Impl(const char*, size_t): Simplify when !std::strchr, just updating _M_names[0]; clean up. (locale::_Impl::_M_replace_categories): When !_M_names[1] prepare for the general case (full set of names), then do the usual work; clean up. * src/locale.cc (locale::name()): Reserve space in __ret. * src/locale_init.cc (locale::global(const locale&)): Save the name in a temporary. * src/localename.cc (locale::locale(const char*)): Reserve space in __str. From-SVN: r81430
This commit is contained in:
parent
9f4fd324ab
commit
4df9c41de5
|
@ -1,3 +1,31 @@
|
|||
2004-05-03 Paolo Carlini <pcarlini@suse.de>
|
||||
|
||||
Optimize locale::_M_impl->_M_names for the most common cases:
|
||||
!_M_names[0] means unnamed; !_M_names[1] means all the categories
|
||||
the same name (_M_names[0] && _M_names[1] means that the full set
|
||||
of _M_names must be processed, the general case).
|
||||
* include/bits/locale_classes.h (locale::_Impl::_M_check_same_name):
|
||||
Tweak, saving work when !_M_names[1].
|
||||
(locale::locale(const locale&, _Facet*): Simplify: now just setting
|
||||
_M_names[0] = 0 means unnamed.
|
||||
* src/locale.cc (locale::operator==): Deal first with the common,
|
||||
easy cases, otherwise fall back to locale::name().
|
||||
(locale::name()): Tweak, if !_M_names[0] just return "*".
|
||||
(locale::_Impl::_Impl(const _Impl&, size_t): Tweak, early stop
|
||||
copying __imp._M_names if !__imp._M_names[0] or !__imp._M_names[1].
|
||||
* src/locale_init.cc (locale::_Impl::_Impl(size_t)): Tweak.
|
||||
* src/localename.cc (locale::_Impl::_Impl(const char*, size_t):
|
||||
Simplify when !std::strchr, just updating _M_names[0]; clean up.
|
||||
(locale::_Impl::_M_replace_categories): When !_M_names[1] prepare
|
||||
for the general case (full set of names), then do the usual work;
|
||||
clean up.
|
||||
|
||||
* src/locale.cc (locale::name()): Reserve space in __ret.
|
||||
* src/locale_init.cc (locale::global(const locale&)): Save
|
||||
the name in a temporary.
|
||||
* src/localename.cc (locale::locale(const char*)): Reserve space
|
||||
in __str.
|
||||
|
||||
2004-04-29 Paolo Carlini <pcarlini@suse.de>
|
||||
|
||||
* src/locale.cc (locale::operator==): Always avoid constructing
|
||||
|
|
|
@ -534,6 +534,8 @@ namespace std
|
|||
_M_check_same_name()
|
||||
{
|
||||
bool __ret = true;
|
||||
if (_M_names[1])
|
||||
// We must actually compare all the _M_names: can be all equal!
|
||||
for (size_t __i = 0; __ret && __i < _S_categories_size - 1; ++__i)
|
||||
__ret = std::strcmp(_M_names[__i], _M_names[__i + 1]) == 0;
|
||||
return __ret;
|
||||
|
@ -569,30 +571,15 @@ namespace std
|
|||
{
|
||||
_M_impl = new _Impl(*__other._M_impl, 1);
|
||||
|
||||
char* _M_tmp_names[_S_categories_size];
|
||||
size_t __i = 0;
|
||||
try
|
||||
{
|
||||
for (; __i < _S_categories_size; ++__i)
|
||||
{
|
||||
_M_tmp_names[__i] = new char[2];
|
||||
std::strcpy(_M_tmp_names[__i], "*");
|
||||
}
|
||||
_M_impl->_M_install_facet(&_Facet::id, __f);
|
||||
}
|
||||
{ _M_impl->_M_install_facet(&_Facet::id, __f); }
|
||||
catch(...)
|
||||
{
|
||||
_M_impl->_M_remove_reference();
|
||||
for (size_t __j = 0; __j < __i; ++__j)
|
||||
delete [] _M_tmp_names[__j];
|
||||
__throw_exception_again;
|
||||
}
|
||||
|
||||
for (size_t __k = 0; __k < _S_categories_size; ++__k)
|
||||
{
|
||||
delete [] _M_impl->_M_names[__k];
|
||||
_M_impl->_M_names[__k] = _M_tmp_names[__k];
|
||||
}
|
||||
delete [] _M_impl->_M_names[0];
|
||||
_M_impl->_M_names[0] = 0; // Unnamed.
|
||||
}
|
||||
} // namespace std
|
||||
|
||||
|
|
|
@ -70,15 +70,21 @@ namespace std
|
|||
bool
|
||||
locale::operator==(const locale& __rhs) const throw()
|
||||
{
|
||||
bool __ret = true;
|
||||
// Deal first with the common cases, fast to process: refcopies,
|
||||
// unnamed (i.e., !_M_names[0]), "simple" (!_M_names[1] => all the
|
||||
// categories same name, i.e., _M_names[0]). Otherwise fall back
|
||||
// to the general locale::name().
|
||||
bool __ret;
|
||||
if (_M_impl == __rhs._M_impl)
|
||||
;
|
||||
else if (!std::strcmp(_M_impl->_M_names[0], "*"))
|
||||
__ret = true;
|
||||
else if (!_M_impl->_M_names[0] || !__rhs._M_impl->_M_names[0]
|
||||
|| std::strcmp(_M_impl->_M_names[0],
|
||||
__rhs._M_impl->_M_names[0]) != 0)
|
||||
__ret = false;
|
||||
else if (!_M_impl->_M_names[1] && !__rhs._M_impl->_M_names[1])
|
||||
__ret = true;
|
||||
else
|
||||
for (size_t __i = 0; __ret && __i < _S_categories_size; ++__i)
|
||||
__ret = !std::strcmp(_M_impl->_M_names[__i],
|
||||
__rhs._M_impl->_M_names[__i]);
|
||||
__ret = this->name() == __rhs.name();
|
||||
return __ret;
|
||||
}
|
||||
|
||||
|
@ -95,10 +101,13 @@ namespace std
|
|||
locale::name() const
|
||||
{
|
||||
string __ret;
|
||||
if (_M_impl->_M_check_same_name())
|
||||
if (!_M_impl->_M_names[0])
|
||||
__ret = '*';
|
||||
else if (_M_impl->_M_check_same_name())
|
||||
__ret = _M_impl->_M_names[0];
|
||||
else
|
||||
{
|
||||
__ret.reserve(128);
|
||||
__ret += _S_categories[0];
|
||||
__ret += '=';
|
||||
__ret += _M_impl->_M_names[0];
|
||||
|
@ -242,12 +251,13 @@ namespace std
|
|||
for (size_t __i = 0; __i < _S_categories_size; ++__i)
|
||||
_M_names[__i] = 0;
|
||||
|
||||
// Name all the categories.
|
||||
for (size_t __i = 0; __i < _S_categories_size; ++__i)
|
||||
// Name the categories.
|
||||
for (size_t __i = 0; (__i < _S_categories_size
|
||||
&& __imp._M_names[__i]); ++__i)
|
||||
{
|
||||
char* __new = new char[std::strlen(__imp._M_names[__i]) + 1];
|
||||
std::strcpy(__new, __imp._M_names[__i]);
|
||||
_M_names[__i] = __new;
|
||||
const size_t __len = std::strlen(__imp._M_names[__i]) + 1;
|
||||
_M_names[__i] = new char[__len];
|
||||
std::memcpy(_M_names[__i], __imp._M_names[__i], __len);
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
|
@ -354,7 +364,6 @@ namespace std
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// locale::id
|
||||
// Definitions for static const data members of locale::id
|
||||
_Atomic_word locale::id::_S_refcount; // init'd to 0 by linker
|
||||
|
|
|
@ -115,8 +115,9 @@ namespace std
|
|||
_Impl* __old = _S_global;
|
||||
__other._M_impl->_M_add_reference();
|
||||
_S_global = __other._M_impl;
|
||||
if (__other.name() != "*")
|
||||
setlocale(LC_ALL, __other.name().c_str());
|
||||
const string __other_name = __other.name();
|
||||
if (__other_name != "*")
|
||||
setlocale(LC_ALL, __other_name.c_str());
|
||||
__glibcxx_mutex_unlock(__gnu_internal::locale_global_mutex);
|
||||
|
||||
// Reference count sanity check: one reference removed for the
|
||||
|
@ -255,13 +256,12 @@ namespace std
|
|||
for (size_t __i = 0; __i < _M_facets_size; ++__i)
|
||||
_M_facets[__i] = _M_caches[__i] = 0;
|
||||
|
||||
// Name all the categories.
|
||||
// Name the categories.
|
||||
_M_names = new (&name_vec) char*[_S_categories_size];
|
||||
for (size_t __i = 0; __i < _S_categories_size; ++__i)
|
||||
{
|
||||
_M_names[__i] = new (&name_c[__i]) char[2];
|
||||
std::strcpy(_M_names[__i], locale::facet::_S_get_c_name());
|
||||
}
|
||||
_M_names[0] = new (&name_c[0]) char[2];
|
||||
std::memcpy(_M_names[0], locale::facet::_S_get_c_name(), 2);
|
||||
for (size_t __i = 1; __i < _S_categories_size; ++__i)
|
||||
_M_names[__i] = 0;
|
||||
|
||||
// This is needed as presently the C++ version of "C" locales
|
||||
// != data in the underlying locale model for __timepunct,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
|
||||
// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
|
||||
// Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
|
@ -34,7 +34,6 @@ namespace std
|
|||
{
|
||||
using namespace __gnu_cxx;
|
||||
|
||||
|
||||
locale::locale(const char* __s)
|
||||
{
|
||||
if (__s)
|
||||
|
@ -95,6 +94,7 @@ namespace std
|
|||
if (__i < _S_categories_size)
|
||||
{
|
||||
string __str;
|
||||
__str.reserve(128);
|
||||
for (size_t __j = 0; __j < __i; ++__j)
|
||||
{
|
||||
__str += _S_categories[__j];
|
||||
|
@ -199,15 +199,12 @@ namespace std
|
|||
for (size_t __i = 0; __i < _S_categories_size; ++__i)
|
||||
_M_names[__i] = 0;
|
||||
|
||||
// Name all the categories.
|
||||
// Name the categories.
|
||||
const size_t __len = std::strlen(__s);
|
||||
if (!std::strchr(__s, ';'))
|
||||
{
|
||||
for (size_t __i = 0; __i < _S_categories_size; ++__i)
|
||||
{
|
||||
_M_names[__i] = new char[__len + 1];
|
||||
std::strcpy(_M_names[__i], __s);
|
||||
}
|
||||
_M_names[0] = new char[__len + 1];
|
||||
std::memcpy(_M_names[0], __s, __len + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -218,10 +215,9 @@ namespace std
|
|||
const char* __end = std::strchr(__beg, ';');
|
||||
if (!__end)
|
||||
__end = __s + __len;
|
||||
char* __new = new char[__end - __beg + 1];
|
||||
std::memcpy(__new, __beg, __end - __beg);
|
||||
__new[__end - __beg] = '\0';
|
||||
_M_names[__i] = __new;
|
||||
_M_names[__i] = new char[__end - __beg + 1];
|
||||
std::memcpy(_M_names[__i], __beg, __end - __beg);
|
||||
_M_names[__i][__end - __beg] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -271,19 +267,35 @@ namespace std
|
|||
locale::_Impl::
|
||||
_M_replace_categories(const _Impl* __imp, category __cat)
|
||||
{
|
||||
for (size_t __ix = 0; __ix < _S_categories_size; ++__ix)
|
||||
category __mask = 1;
|
||||
const bool __have_names = _M_names[0] && __imp->_M_names[0];
|
||||
for (size_t __ix = 0; __ix < _S_categories_size; ++__ix, __mask <<= 1)
|
||||
{
|
||||
const category __mask = 1 << __ix;
|
||||
if (__mask & __cat)
|
||||
{
|
||||
// Need to replace entry in _M_facets with other locale's info.
|
||||
_M_replace_category(__imp, _S_facet_categories[__ix]);
|
||||
// If both have names, go ahead and mangle.
|
||||
if (std::strcmp(_M_names[__ix], "*") != 0
|
||||
&& std::strcmp(__imp->_M_names[__ix], "*") != 0)
|
||||
if (__have_names)
|
||||
{
|
||||
char* __new = new char[std::strlen(__imp->_M_names[__ix]) + 1];
|
||||
std::strcpy(__new, __imp->_M_names[__ix]);
|
||||
if (!_M_names[1])
|
||||
{
|
||||
// A full set of _M_names must be prepared, all identical
|
||||
// to _M_names[0] to begin with. Then, below, a few will
|
||||
// be replaced by the corresponding __imp->_M_names. I.e.,
|
||||
// not a "simple" locale anymore (see locale::operator==).
|
||||
const size_t __len = std::strlen(_M_names[0]) + 1;
|
||||
for (size_t __i = 1; __i < _S_categories_size; ++__i)
|
||||
{
|
||||
_M_names[__i] = new char[__len];
|
||||
std::memcpy(_M_names[__i], _M_names[0], __len);
|
||||
}
|
||||
}
|
||||
char* __src = __imp->_M_names[__ix] ? __imp->_M_names[__ix]
|
||||
: __imp->_M_names[0];
|
||||
const size_t __len = std::strlen(__src) + 1;
|
||||
char* __new = new char[__len];
|
||||
std::memcpy(__new, __src, __len);
|
||||
delete [] _M_names[__ix];
|
||||
_M_names[__ix] = __new;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue