From 9fbc9ca577e533f7b04789eb19757060d8355601 Mon Sep 17 00:00:00 2001 From: paolo Date: Mon, 3 May 2004 12:14:07 +0000 Subject: 2004-05-03 Paolo Carlini 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 --- libstdc++-v3/src/localename.cc | 48 ++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 18 deletions(-) (limited to 'libstdc++-v3/src/localename.cc') 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; } -- cgit v1.2.1