stdcxx-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From se...@apache.org
Subject svn commit: r677756 - in /stdcxx/branches/4.2.x: include/vector include/vector.cc tests/regress/23.vector.stdcxx-494.cpp
Date Thu, 17 Jul 2008 21:58:05 GMT
Author: sebor
Date: Thu Jul 17 14:58:05 2008
New Revision: 677756

URL: http://svn.apache.org/viewvc?rev=677756&view=rev
Log:
2008-07-17  Martin Sebor  <sebor@roguewave.com>

	STDCXX-494
	* include/vector (vector): Removed Allocator base class, replacing
	it (in a binary compatible way) with a new member, _C_alloc, instead.
	(_C_value_alloc_type): Removed member typedef.
	(vector): Initialized the _C_alloc member instead of allocator_type
	in all class ctors.
	(~vector, begin, end, size, max_size, empty, swap): Referenced
	_C_begin, _C_end, and _C_bufend indirectly, via the new _C_alloc
	member.
	(pop_back, push_back): Used the new _C_alloc member to destroy
	and construct elements.
	* include/vector.cc (_C_realloc, _C_destroy, _C_insert_1,
	_C_insert_n, _C_insert_range): Same as above.
	* tests/regress/23.vector.stdcxx-494: Added regression test for
	the vector part of the issue.

Added:
    stdcxx/branches/4.2.x/tests/regress/23.vector.stdcxx-494.cpp   (with props)
Modified:
    stdcxx/branches/4.2.x/include/vector
    stdcxx/branches/4.2.x/include/vector.cc

Modified: stdcxx/branches/4.2.x/include/vector
URL: http://svn.apache.org/viewvc/stdcxx/branches/4.2.x/include/vector?rev=677756&r1=677755&r2=677756&view=diff
==============================================================================
--- stdcxx/branches/4.2.x/include/vector (original)
+++ stdcxx/branches/4.2.x/include/vector Thu Jul 17 14:58:05 2008
@@ -88,7 +88,7 @@
 
 _EXPORT
 template <class _TypeT, class _Allocator>
-class vector: private _Allocator
+class vector
 {
 public:
 
@@ -100,7 +100,6 @@
     typedef _TYPENAME allocator_type::const_reference  const_reference;
     typedef _TYPENAME allocator_type::pointer          pointer;
     typedef _TYPENAME allocator_type::const_pointer    const_pointer;
-    typedef _RWSTD_ALLOC_TYPE (allocator_type, value_type) _C_value_alloc_type;
 
 public:
 
@@ -157,33 +156,32 @@
 
     _EXPLICIT
     vector (const allocator_type &__alloc = allocator_type ())
-        : allocator_type (__alloc), _C_begin (), _C_end (), _C_bufend () { }
+        : _C_alloc (__alloc) { }
 
     _EXPLICIT
     vector (size_type __n, const_reference __x = value_type (),
             const allocator_type &__alloc = allocator_type ())
-        : allocator_type (__alloc), _C_begin (), _C_end (), _C_bufend () {
+        : _C_alloc (__alloc) {
         assign (__n, __x);
     }
 
     template <class _InputIter>
     vector (_InputIter __first, _InputIter __last,
             const allocator_type &__alloc = allocator_type ())
-        : allocator_type (__alloc), _C_begin (), _C_end (), _C_bufend () {
+        : _C_alloc (__alloc) {
         assign (__first, __last);
     }
 
     vector (const vector &__rhs)
-        : allocator_type (__rhs.get_allocator ()),
-          _C_begin (), _C_end (), _C_bufend () {
+        : _C_alloc (__rhs.get_allocator ()) {
         assign (__rhs.begin (), __rhs.end ());
     }
     
     
     ~vector () { 
-        _C_destroy (begin ()); 
-        _RWSTD_VALUE_ALLOC (_C_value_alloc_type, *this,
-                            deallocate (_C_begin, _C_bufend - _C_begin));
+        _C_destroy (begin ());
+        _C_alloc.deallocate (_C_alloc._C_begin,
+                             _C_alloc._C_bufend - _C_alloc._C_begin);
     }
     
     vector& operator= (const vector&);
@@ -199,23 +197,23 @@
     }
 
     allocator_type get_allocator () const {
-        return *this;
+        return _C_alloc;
     }
     
     iterator begin () {
-        return _C_make_iter (_C_begin);
+        return _C_make_iter (_C_alloc._C_begin);
     }
 
     const_iterator begin () const {
-        return _C_make_iter (_C_begin);
+        return _C_make_iter (_C_alloc._C_begin);
     }
 
     iterator end () {
-        return _C_make_iter (_C_end);
+        return _C_make_iter (_C_alloc._C_end);
     }
 
     const_iterator end () const {
-        return _C_make_iter (_C_end);
+        return _C_make_iter (_C_alloc._C_end);
     }
     
     reverse_iterator rbegin () { 
@@ -235,21 +233,21 @@
     }
 
     size_type size () const {
-        return size_type (_C_end - _C_begin);
+        return size_type (_C_alloc._C_end - _C_alloc._C_begin);
     }
 
     size_type max_size () const {
-        return _RWSTD_VALUE_ALLOC (_C_value_alloc_type, *this, max_size ());
+        return _C_alloc.max_size ();
     }
     
     void resize (size_type, value_type = value_type ());
 
     size_type capacity () const {
-        return _C_bufend - _C_begin;
+        return _C_alloc._C_bufend - _C_alloc._C_begin;
     }
     
     bool empty () const {
-        return _C_begin == _C_end;
+        return _C_alloc._C_begin == _C_alloc._C_end;
     }
     
     void reserve (size_type);
@@ -286,8 +284,8 @@
     
     void pop_back () {
         _RWSTD_ASSERT (!empty ());
-        _RWSTD_VALUE_ALLOC (_C_value_alloc_type, *this, destroy (_C_end - 1));
-        --_C_end;
+        _C_alloc.destroy (_C_alloc._C_end - 1);
+        --_C_alloc._C_end;
     }
 
     iterator insert (iterator, const_reference);
@@ -393,11 +391,9 @@
 
     // constructs a copy at the end and grows the size of container
     void _C_push_back (const_reference __x) {
-        _RWSTD_ASSERT (_C_end != _C_bufend);
-
-        _RWSTD_VALUE_ALLOC (_C_value_alloc_type, *this,
-                            construct (_C_end, __x));
-        ++_C_end;
+        _RWSTD_ASSERT (_C_alloc._C_end != _C_alloc._C_bufend);
+        _C_alloc.construct (_C_alloc._C_end, __x);
+        ++_C_alloc._C_end;
     }
 
     // destroys elements from the iterator to the end of the vector
@@ -407,9 +403,16 @@
     // implements swap for objects with unequal allocator
     void _C_unsafe_swap (vector&);
 
-    pointer _C_begin;
-    pointer _C_end;
-    pointer _C_bufend;
+    struct _C_VectorAlloc: allocator_type {
+
+        _C_VectorAlloc (const allocator_type &__alloc)
+            : allocator_type (__alloc), _C_begin (), _C_end (), _C_bufend ()
+            { /* empty */}
+
+        pointer _C_begin;
+        pointer _C_end;
+        pointer _C_bufend;
+    } _C_alloc;
 };
 
 
@@ -507,12 +510,10 @@
 vector<_TypeT, _Allocator>::
 push_back (const_reference __x)
 {
-    if (_C_end == _C_bufend) {
+    if (_C_alloc._C_end == _C_alloc._C_bufend)
         _C_insert_1 (end (), __x);
-    }
-    else {
+    else
         _C_push_back (__x);
-    }
 }
 
 
@@ -547,8 +548,8 @@
     if (__next != end ()) 
         _STD::copy (__next, end (), __it);
 
-    _RWSTD_VALUE_ALLOC (_C_value_alloc_type, *this, destroy (_C_end - 1));
-    --_C_end;
+    _C_alloc.destroy (_C_alloc._C_end - 1);
+    --_C_alloc._C_end;
 
     return __it;
 }
@@ -584,15 +585,15 @@
 swap (vector &__other)
 {
     if (get_allocator () == __other.get_allocator ()) {
-        pointer __tmp    = _C_begin;
-        _C_begin         = __other._C_begin;
-        __other._C_begin = __tmp;
-        __tmp            = _C_end;
-        _C_end           = __other._C_end;
-        __other._C_end   = __tmp;
-        __tmp            = _C_bufend;
-        _C_bufend        = __other._C_bufend;
-        __other._C_bufend = __tmp;
+        pointer __tmp             = _C_alloc._C_begin;
+        _C_alloc._C_begin         = __other._C_alloc._C_begin;
+        __other._C_alloc._C_begin = __tmp;
+        __tmp                     = _C_alloc._C_end;
+        _C_alloc._C_end           = __other._C_alloc._C_end;
+        __other._C_alloc._C_end   = __tmp;
+        __tmp                     = _C_alloc._C_bufend;
+        _C_alloc._C_bufend        = __other._C_alloc._C_bufend;
+        __other._C_alloc._C_bufend = __tmp;
     }
     else {
         // not exception-safe

Modified: stdcxx/branches/4.2.x/include/vector.cc
URL: http://svn.apache.org/viewvc/stdcxx/branches/4.2.x/include/vector.cc?rev=677756&r1=677755&r2=677756&view=diff
==============================================================================
--- stdcxx/branches/4.2.x/include/vector.cc (original)
+++ stdcxx/branches/4.2.x/include/vector.cc Thu Jul 17 14:58:05 2008
@@ -82,20 +82,19 @@
     vector __tmp (get_allocator ());
 
     // allocate storage of requested capacity
-    __tmp._C_begin =
-        _RWSTD_VALUE_ALLOC (_C_value_alloc_type, __tmp,
-                            allocate (__cap, this));
+    __tmp._C_alloc._C_begin = _C_alloc.allocate (__cap, this);
 
     // initialize pointers
-    __tmp._C_end    = __tmp._C_begin;
-    __tmp._C_bufend = __tmp._C_begin + __cap;
+    __tmp._C_alloc._C_end    = __tmp._C_alloc._C_begin;
+    __tmp._C_alloc._C_bufend = __tmp._C_alloc._C_begin + __cap;
 
     // copy *this into the temporary one element at a time, as if
     // by calling std::unitialized_copy(), growing the temporary
     // at each iteration so that an exception thrown by the copy
     // ctor will cause the destruction of all already constructed
     // elements (by invoking the temporary's dtor)
-    for (pointer __ptr = _C_begin; !(__ptr == _C_end); ++__ptr) {
+    for (pointer __ptr = _C_alloc._C_begin; !(__ptr == _C_alloc._C_end);
+         ++__ptr) {
         __tmp._C_push_back (*__ptr);
     }
 
@@ -110,10 +109,8 @@
 {
     _RWSTD_ASSERT_RANGE (__first, end ());
 
-    _C_value_alloc_type __alloc = _RWSTD_VALUE_ALLOC_CAST (*this);
-
     for (size_type __n = end () - __first; !(0 == __n); --__n)
-        __alloc.destroy (--_C_end);
+        _C_alloc.destroy (--_C_alloc._C_end);
 }
 
 
@@ -170,12 +167,12 @@
 
         if (__it < end ()) {
 
-            const pointer __end = _C_end;
+            const pointer __end = _C_alloc._C_end;
 
             // construct a copy of the last element in the range [it, end)
             // in the uninitialized slot just past the end of the range
             // and bump up end()
-            _C_push_back (*(_C_end - difference_type (1)));
+            _C_push_back (*(_C_alloc._C_end - difference_type (1)));
 
             // move the remaining elements from the range above one slot
             // toward the end starting with the last element
@@ -218,36 +215,40 @@
         vector __tmp (get_allocator ());
         __tmp.reserve (__size2);
 
-        _RWSTD_ASSERT (!(pointer () == __tmp._C_end));
+        _RWSTD_ASSERT (!(pointer () == __tmp._C_alloc._C_end));
 
         iterator __i;
 
         // copy the initial range prior to `it' as if by a call to
-        // std::uninitialized_copy (begin (), __it, __tmp._C_begin);
+        // uninitialized_copy (begin (), __it, __tmp._C_alloc._C_begin);
         for (__i = begin (); !(__i == __it); ++__i) {
 
-            _RWSTD_ASSERT (!(__tmp._C_end == __tmp._C_bufend));
+            _RWSTD_ASSERT (!(   __tmp._C_alloc._C_end
+                             == __tmp._C_alloc._C_bufend));
 
             __tmp._C_push_back (*__i);
         }
 
         // construct `n' copies of `x' just past the initial range,
         // as if by a call to
-        // std::uninitialized_fill_n (__tmp._C_begin + __size1, __n, __x);
+        // uninitialized_fill_n (__tmp._C_aloc._C_begin + __size1, __n, __x);
         for ( ; __n; --__n) {
 
-            _RWSTD_ASSERT (!(__tmp._C_end == __tmp._C_bufend));
+            _RWSTD_ASSERT (!(   __tmp._C_alloc._C_end
+                             == __tmp._C_alloc._C_bufend));
 
             __tmp._C_push_back (__x);
         }
 
         // copy the final range of elements starting with `it'
         // as if by a call to
-        // uninitialized_copy (__it, end (), __tmp._C_begin + __size1 + __n);
+        // uninitialized_copy (__it, end (),
+        //                     __tmp._C_alloc._C_begin + __size1 + __n);
 
         for (__i = __it; !(__i == end ()); ++__i) {
 
-            _RWSTD_ASSERT (!(__tmp._C_end == __tmp._C_bufend));
+            _RWSTD_ASSERT (!(   __tmp._C_alloc._C_end
+                             == __tmp._C_alloc._C_bufend));
 
             __tmp._C_push_back (*__i);
         }
@@ -262,14 +263,12 @@
     // controlled by *this that need to be moved (copy contructed past
     // the end of the end of the sequence or assigned over existing
     // elements)
-    const pointer __movbeg = _C_begin + __size1;
+    const pointer __movbeg = _C_alloc._C_begin + __size1;
     const pointer __movend = __movbeg + __n;
 
     _RWSTD_ASSERT (_C_make_iter (__movbeg) == __it);
 
-    _C_value_alloc_type __alloc = _RWSTD_VALUE_ALLOC_CAST (*this);
-
-    if (__movend <= _C_end) {
+    if (__movend <= _C_alloc._C_end) {
 
         // the end of the range of existing elements after being
         // moved to make room for the elements to be inserted is
@@ -277,15 +276,16 @@
 
         // compute the beginning of the range of elements whose copies
         // will be constructed just past the current end of the sequence
-        const pointer __ucpbeg = _C_end - __n;
-        const pointer __ucpend = _C_end;
+        const pointer __ucpbeg = _C_alloc._C_end - __n;
+        const pointer __ucpend = _C_alloc._C_end;
 
         // construct copies of elements that will be moved beyond
         // the current end of the sequence controlled by *this
-        _STD::uninitialized_copy (__ucpbeg, _C_end, _C_end, __alloc);
+        _STD::uninitialized_copy (__ucpbeg, _C_alloc._C_end,
+                                  _C_alloc._C_end, _C_alloc);
 
         // advance end to maintain consistent state
-        _C_end += __n;
+        _C_alloc._C_end += __n;
 
         // copy elements the will be overwritten below
         // over the range of elements moved above
@@ -299,17 +299,17 @@
         const size_type __n1 = size () - __size1;
         const size_type __n2 = __n - __n1;
 
-        _STD::uninitialized_fill_n (_C_end, __n2, __x, __alloc);
+        _STD::uninitialized_fill_n (_C_alloc._C_end, __n2, __x, _C_alloc);
 
-        const pointer __end = _C_end;
+        const pointer __end = _C_alloc._C_end;
 
-        _C_end += __n2;
+        _C_alloc._C_end += __n2;
 
         // construct copies of the range of elements [pos, end)
         // past the end of the range of elements inserted above
-        _STD::uninitialized_copy (__movbeg, __end, _C_end, __alloc);
+        _STD::uninitialized_copy (__movbeg, __end, _C_alloc._C_end, _C_alloc);
 
-        _C_end += __end - __movbeg;
+        _C_alloc._C_end += __end - __movbeg;
 
         __n = __n1;
     }
@@ -527,23 +527,23 @@
     if (__inx < __size) {
         // swap the inserted elements with the elements before which
         // they should be inserted, as if by calling
-        // std::rotate (__beg, __mid, _C_end)
-        const pointer __beg = __self->_C_begin + __inx;
-        const pointer __mid = __self->_C_begin + __size;
+        // std::rotate (__beg, __mid, _C_alloc._C_end)
+        const pointer __beg = __self->_C_alloc._C_begin + __inx;
+        const pointer __mid = __self->_C_alloc._C_begin + __size;
 
         if (__beg < __mid) {
             for (pointer __p0 = __beg, __p1 = __mid; __p0 < --__p1; ++__p0)
                 _STD::iter_swap (__p0, __p1);
         }
 
-        if (__mid < __self->_C_end) {
-            for (pointer __p0 = __mid, __p1 = __self->_C_end;
+        if (__mid < __self->_C_alloc._C_end) {
+            for (pointer __p0 = __mid, __p1 = __self->_C_alloc._C_end;
                  __p0 < --__p1; ++__p0)
                 _STD::iter_swap (__p0, __p1);
         }
 
-        if (__beg < __self->_C_end) {
-            for (pointer __p0 = __beg, __p1 = __self->_C_end;
+        if (__beg < __self->_C_alloc._C_end) {
+            for (pointer __p0 = __beg, __p1 = __self->_C_alloc._C_end;
                  __p0 < --__p1; ++__p0)
                 _STD::iter_swap (__p0, __p1);
         }
@@ -633,12 +633,12 @@
         // in the sequence controlled by *this that need to be moved
         // (copy contructed past the end of the end of the sequence
         // or assigned over existing elements)
-        const pointer __movbeg = __self->_C_begin + __size1;
+        const pointer __movbeg = __self->_C_alloc._C_begin + __size1;
         const pointer __movend = __movbeg + __size2;
 
         _RWSTD_ASSERT (__self->_C_make_iter (__movbeg) == __it);
 
-        const pointer __end = __self->_C_end;
+        const pointer __end = __self->_C_alloc._C_end;
 
         if (__movend <= __end) {
             // compute the beginning of the range of elements whose copies
@@ -667,7 +667,7 @@
 
             // construct copies of the trailing subsequence of the range
             // of elements being inserted, as if by a call to
-            // std::uninitialized_copy (__mid, __last, _C_end);
+            // std::uninitialized_copy (__mid, __last, _C_alloc._C_end);
 
             for (_FwdIter __m = __mid ; !(__m == __last); ++__m)
                 __self->_C_push_back (*__m);
@@ -675,7 +675,7 @@
             // construct copies of the range of elements [pos, end)
             // past the end of the range of elements inserted above,
             // as if by a call to 
-            // std::uninitialized_copy (__movbeg, __end, _C_end);
+            // std::uninitialized_copy (__movbeg, __end, _C_alloc._C_end);
 
             for (pointer __p = __movbeg; !(__p == __end); ++__p)
                 __self->_C_push_back (*__p);

Added: stdcxx/branches/4.2.x/tests/regress/23.vector.stdcxx-494.cpp
URL: http://svn.apache.org/viewvc/stdcxx/branches/4.2.x/tests/regress/23.vector.stdcxx-494.cpp?rev=677756&view=auto
==============================================================================
--- stdcxx/branches/4.2.x/tests/regress/23.vector.stdcxx-494.cpp (added)
+++ stdcxx/branches/4.2.x/tests/regress/23.vector.stdcxx-494.cpp Thu Jul 17 14:58:05 2008
@@ -0,0 +1,71 @@
+/************************************************************************
+ *
+ * 23.vector.stdcxx-494.cpp - regression test for STDCXX-494
+ *
+ * https://issues.apache.org/jira/browse/STDCXX-611
+ *
+ * $Id$
+ *
+ ***************************************************************************
+ *
+ * Licensed to the Apache Software  Foundation (ASF) under one or more
+ * contributor  license agreements.  See  the NOTICE  file distributed
+ * with  this  work  for  additional information  regarding  copyright
+ * ownership.   The ASF  licenses this  file to  you under  the Apache
+ * License, Version  2.0 (the  "License"); you may  not use  this file
+ * except in  compliance with the License.   You may obtain  a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the  License is distributed on an  "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY  KIND, either  express or
+ * implied.   See  the License  for  the  specific language  governing
+ * permissions and limitations under the License.
+ *
+ **************************************************************************/
+
+#include <cassert>   // for assert()
+#include <cstddef>   // for size_t
+#include <memory>    // for allocator
+#include <vector>    // for vector
+
+
+template <class T>
+struct EmptyAllocator: std::allocator<T>
+{
+    template <class U>
+    struct rebind { typedef EmptyAllocator<U> other; };
+
+    EmptyAllocator () { }
+    EmptyAllocator (const EmptyAllocator &rhs)
+        : std::allocator<T>(rhs) { }
+
+    template <class U>
+    EmptyAllocator (const EmptyAllocator<U> &rhs)
+        : std::allocator<T>(rhs) { }
+
+    void* operator new (std::size_t) { return 0; }
+    void operator delete (void*) { }
+};
+
+
+int main ()
+{
+    // verify that vector doesn't derive from allocator
+    // (otherwise the replacement operator new and delete
+    // are in conflict)
+
+    typedef std::vector<int, EmptyAllocator<int> > EmptyVector;
+
+    delete new EmptyVector;
+
+    // verifies empty base optimization
+    assert (sizeof (std::vector<int>) == sizeof (EmptyVector));
+
+    // assert that the size of vector is exactly 3 pointers
+    assert (sizeof (std::vector<int>) == 3 * sizeof (int*));
+
+    return 0;
+}

Propchange: stdcxx/branches/4.2.x/tests/regress/23.vector.stdcxx-494.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: stdcxx/branches/4.2.x/tests/regress/23.vector.stdcxx-494.cpp
------------------------------------------------------------------------------
    svn:keywords = Id



Mime
View raw message