basic_string.h (_S_create(size_t, const _Alloc&): Change signature to take two size_t...
authorPaolo Carlini <pcarlini@suse.de>
Wed, 28 Jan 2004 10:37:32 +0000 (10:37 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Wed, 28 Jan 2004 10:37:32 +0000 (10:37 +0000)
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

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/basic_string.h
libstdc++-v3/include/bits/basic_string.tcc

index 6fb3dd4..a830353 100644 (file)
@@ -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
index ae81259..b456280 100644 (file)
@@ -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)
index 733a11d..80ee245 100644 (file)
@@ -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);