summaryrefslogtreecommitdiff
path: root/libstdc++-v3/src/localename.cc
diff options
context:
space:
mode:
authorpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>2004-05-03 12:14:07 +0000
committerpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>2004-05-03 12:14:07 +0000
commit9fbc9ca577e533f7b04789eb19757060d8355601 (patch)
treeadeda0cd9647262ca6172ca50e4e8ce89f154b80 /libstdc++-v3/src/localename.cc
parent93735cb819eb1e9ab7b4f2cd34e1d86ea9ea5052 (diff)
downloadgcc-9fbc9ca577e533f7b04789eb19757060d8355601.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@81430 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/src/localename.cc')
-rw-r--r--libstdc++-v3/src/localename.cc48
1 files changed, 30 insertions, 18 deletions
diff --git a/libstdc++-v3/src/localename.cc b/libstdc++-v3/src/localename.cc
index 4cd1af189fa..ca09b065156 100644
--- a/libstdc++-v3/src/localename.cc
+++ b/libstdc++-v3/src/localename.cc
@@ -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;
}