aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <pcarlini@suse.de>2004-01-28 10:37:32 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2004-01-28 10:37:32 +0000
commit234e0d312169ca44b701314d4f67c2a07cd5a896 (patch)
treeec59f9b8a30f81398a50bb6d291a5d0d8b9431a5
parent220a38ab6e9973dac69fa339127b88b57e44dc9b (diff)
downloadgcc-234e0d312169ca44b701314d4f67c2a07cd5a896.zip
gcc-234e0d312169ca44b701314d4f67c2a07cd5a896.tar.gz
gcc-234e0d312169ca44b701314d4f67c2a07cd5a896.tar.bz2
basic_string.h (_S_create(size_t, const _Alloc&): Change signature to take two size_type arguments.
2004-01-28 Paolo Carlini <pcarlini@suse.de> * 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
-rw-r--r--libstdc++-v3/ChangeLog22
-rw-r--r--libstdc++-v3/include/bits/basic_string.h4
-rw-r--r--libstdc++-v3/include/bits/basic_string.tcc112
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 <pcarlini@suse.de>
+
+ * 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 <bkoz@redhat.com>
* 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<size_type>(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<typename _CharT, typename _Traits, typename _Alloc>
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 _CharT, typename _Traits, typename _Alloc>
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);