From 234e0d312169ca44b701314d4f67c2a07cd5a896 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Wed, 28 Jan 2004 10:37:32 +0000 Subject: [PATCH] basic_string.h (_S_create(size_t, const _Alloc&): Change signature to take two size_type arguments. 2004-01-28 Paolo Carlini * include/bits/basic_string.h (_S_create(size_t, const _Alloc&): Change signature to take two size_type arguments. * include/bits/basic_string.tcc (_S_construct(_InIterator, _InIterator, const _Alloc&, input_iterator_tag)): Update call, tweak a bit. (_S_construct(_InIterator, _InIterator, const _Alloc&, forward_iterator_tag)): Likewise. (_S_construct(size_type, _CharT, const _Alloc&)): Likewise. (_M_mutate(size_type, size_type, size_type)): Don't implement the exponential growth policy, demand it to _S_create, update call and simplify. (_M_clone(const _Alloc&, size_type)): Likewise. (_S_create(size_type, size_type, const _Alloc&)): Implement the growth policy, simplify otherwise. * include/bits/basic_string.h (_Rep::operator[]): Tweak signature to take a size_type, consistently with the other members. From-SVN: r76786 --- libstdc++-v3/ChangeLog | 22 ++++++ libstdc++-v3/include/bits/basic_string.h | 4 +- libstdc++-v3/include/bits/basic_string.tcc | 112 +++++++++++++---------------- 3 files changed, 72 insertions(+), 66 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 6fb3dd4..a830353 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,25 @@ +2004-01-28 Paolo Carlini + + * include/bits/basic_string.h (_S_create(size_t, + const _Alloc&): Change signature to take two size_type + arguments. + * include/bits/basic_string.tcc (_S_construct(_InIterator, + _InIterator, const _Alloc&, input_iterator_tag)): Update + call, tweak a bit. + (_S_construct(_InIterator, _InIterator, const _Alloc&, + forward_iterator_tag)): Likewise. + (_S_construct(size_type, _CharT, const _Alloc&)): Likewise. + (_M_mutate(size_type, size_type, size_type)): Don't + implement the exponential growth policy, demand it to + _S_create, update call and simplify. + (_M_clone(const _Alloc&, size_type)): Likewise. + (_S_create(size_type, size_type, const _Alloc&)): Implement + the growth policy, simplify otherwise. + + * include/bits/basic_string.h (_Rep::operator[]): Tweak + signature to take a size_type, consistently with the other + members. + 2004-01-27 Benjamin Kosnik * testsuite/27_io/ios_base/storage/11584.cc: Correct new and diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index ae81259..b456280 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -198,7 +198,7 @@ namespace std { return reinterpret_cast<_CharT*>(this + 1); } _CharT& - operator[](size_t __s) throw() + operator[](size_type __s) throw() { return _M_refdata() [__s]; } _CharT* @@ -210,7 +210,7 @@ namespace std // Create & Destroy static _Rep* - _S_create(size_t, const _Alloc&); + _S_create(size_type, size_type, const _Alloc&); void _M_dispose(const _Alloc& __a) diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc index 733a11d..80ee245 100644 --- a/libstdc++-v3/include/bits/basic_string.tcc +++ b/libstdc++-v3/include/bits/basic_string.tcc @@ -98,7 +98,7 @@ namespace std __buf[__i++] = *__beg; ++__beg; } - _Rep* __r = _Rep::_S_create(__i, __a); + _Rep* __r = _Rep::_S_create(__i, size_type(0), __a); traits_type::copy(__r->_M_refdata(), __buf, __i); __r->_M_length = __i; try @@ -124,8 +124,8 @@ namespace std ++__beg; } // Allocate more space. - const size_type __len = __p - __r->_M_refdata(); - _Rep* __another = _Rep::_S_create(__len + 1, __a); + const size_type __len = __r->_M_capacity; + _Rep* __another = _Rep::_S_create(__len + 1, __len, __a); traits_type::copy(__another->_M_refdata(), __r->_M_refdata(), __len); __r->_M_destroy(__a); @@ -157,9 +157,8 @@ namespace std const size_type __dnew = static_cast(std::distance(__beg, __end)); - // Check for out_of_range and length_error exceptions. - _Rep* __r = _Rep::_S_create(__dnew, __a); + _Rep* __r = _Rep::_S_create(__dnew, size_type(0), __a); try { _S_copy_chars(__r->_M_refdata(), __beg, __end); } catch(...) @@ -182,7 +181,7 @@ namespace std return _S_empty_rep()._M_refdata(); // Check for out_of_range and length_error exceptions. - _Rep* __r = _Rep::_S_create(__n, __a); + _Rep* __r = _Rep::_S_create(__n, size_type(0), __a); if (__n) traits_type::assign(__r->_M_refdata(), __n, __c); @@ -391,12 +390,6 @@ namespace std _M_rep()->_M_set_leaked(); } - // _M_mutate and, below, _M_clone, include, in the same form, an exponential - // growth policy, necessary to meet amortized linear time requirements of - // the library: see http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html. - // The policy is active for allocations requiring an amount of memory above - // system pagesize. This is consistent with the requirements of the standard: - // see, f.i., http://gcc.gnu.org/ml/libstdc++/2001-07/msg00130.html template void basic_string<_CharT, _Traits, _Alloc>:: @@ -412,26 +405,12 @@ namespace std { // Must reallocate. const allocator_type __a = get_allocator(); - // See below (_S_create) for the meaning and value of these - // constants. - const size_type __pagesize = 4096; - const size_type __malloc_header_size = 4 * sizeof (void*); - // The biggest string which fits in a memory page - const size_type __page_capacity = (__pagesize - __malloc_header_size - - sizeof(_Rep) - sizeof(_CharT)) - / sizeof(_CharT); - _Rep* __r; - if (__new_size > capacity() && __new_size > __page_capacity) - // Growing exponentially. - __r = _Rep::_S_create(__new_size > 2*capacity() ? - __new_size : 2*capacity(), __a); - else - __r = _Rep::_S_create(__new_size, __a); + _Rep* __r = _Rep::_S_create(__new_size, capacity(), __a); if (__pos) traits_type::copy(__r->_M_refdata(), _M_data(), __pos); if (__how_much) - traits_type::copy(__r->_M_refdata() + __pos + __len2, + traits_type::copy(__r->_M_refdata() + __pos + __len2, __src, __how_much); _M_rep()->_M_dispose(__a); @@ -494,7 +473,8 @@ namespace std template typename basic_string<_CharT, _Traits, _Alloc>::_Rep* basic_string<_CharT, _Traits, _Alloc>::_Rep:: - _S_create(size_t __capacity, const _Alloc& __alloc) + _S_create(size_type __capacity, size_type __old_capacity, + const _Alloc& __alloc) { typedef basic_string<_CharT, _Traits, _Alloc> __string_type; // _GLIBCXX_RESOLVE_LIB_DEFECTS @@ -502,15 +482,11 @@ namespace std if (__capacity > _S_max_size) __throw_length_error(__N("basic_string::_S_create")); - // NB: Need an array of char_type[__capacity], plus a - // terminating null char_type() element, plus enough for the - // _Rep data structure. Whew. Seemingly so needy, yet so elemental. - size_t __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep_base); - // The standard places no restriction on allocating more memory // than is strictly needed within this layer at the moment or as - // requested by an explicit application call to reserve(). Many - // malloc implementations perform quite poorly when an + // requested by an explicit application call to reserve(). + + // Many malloc implementations perform quite poorly when an // application attempts to allocate memory in a stepwise fashion // growing each allocation size by only 1 char. Additionally, // it makes little sense to allocate less linear memory than the @@ -529,24 +505,46 @@ namespace std // low-balling it (especially when this algorithm is used with // malloc implementations that allocate memory blocks rounded up // to a size which is a power of 2). - const size_t __pagesize = 4096; // must be 2^i * __subpagesize - const size_t __subpagesize = 128; // should be >> __malloc_header_size - const size_t __malloc_header_size = 4 * sizeof (void*); - if ((__size + __malloc_header_size) > __pagesize) + const size_type __pagesize = 4096; // must be 2^i * __subpagesize + const size_type __subpagesize = 128; // should be >> __malloc_header_size + const size_type __malloc_header_size = 4 * sizeof (void*); + + // The below implements an exponential growth policy, necessary to + // meet amortized linear time requirements of the library: see + // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html. + // It's active for allocations requiring an amount of memory above + // system pagesize. This is consistent with the requirements of the + // standard: http://gcc.gnu.org/ml/libstdc++/2001-07/msg00130.html + + // The biggest string which fits in a memory page + const size_type __page_capacity = ((__pagesize - __malloc_header_size + - sizeof(_Rep) - sizeof(_CharT)) + / sizeof(_CharT)); + + if (__capacity > __old_capacity && __capacity < 2 * __old_capacity + && __capacity > __page_capacity) + __capacity = 2 * __old_capacity; + + // NB: Need an array of char_type[__capacity], plus a terminating + // null char_type() element, plus enough for the _Rep data structure. + // Whew. Seemingly so needy, yet so elemental. + size_type __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep); + + if (__size + __malloc_header_size > __pagesize) { - const size_t __extra = - (__pagesize - ((__size + __malloc_header_size) % __pagesize)) - % __pagesize; + const size_type __extra = (__pagesize + - (__size + __malloc_header_size) + % __pagesize); __capacity += __extra / sizeof(_CharT); - __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep_base); + __size += __extra; } else if (__size > __subpagesize) { - const size_t __extra = - (__subpagesize - ((__size + __malloc_header_size) % __subpagesize)) - % __subpagesize; + const size_type __extra = (__subpagesize + - (__size + __malloc_header_size) + % __subpagesize); __capacity += __extra / sizeof(_CharT); - __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep_base); + __size += __extra; } // NB: Might throw, but no worries about a leak, mate: _Rep() @@ -566,22 +564,8 @@ namespace std { // Requested capacity of the clone. const size_type __requested_cap = this->_M_length + __res; - // See above (_S_create) for the meaning and value of these constants. - const size_type __pagesize = 4096; - const size_type __malloc_header_size = 4 * sizeof (void*); - // The biggest string which fits in a memory page. - const size_type __page_capacity = - (__pagesize - __malloc_header_size - sizeof(_Rep_base) - sizeof(_CharT)) - / sizeof(_CharT); - _Rep* __r; - if (__requested_cap > this->_M_capacity - && __requested_cap > __page_capacity) - // Growing exponentially. - __r = _Rep::_S_create(__requested_cap > 2*this->_M_capacity ? - __requested_cap : 2*this->_M_capacity, __alloc); - else - __r = _Rep::_S_create(__requested_cap, __alloc); - + _Rep* __r = _Rep::_S_create(__requested_cap, this->_M_capacity, + __alloc); if (this->_M_length) traits_type::copy(__r->_M_refdata(), _M_refdata(), this->_M_length); -- 2.7.4