Author: sebor
Date: Thu Mar 22 16:38:09 2007
New Revision: 521530
URL: http://svn.apache.org/viewvc?view=rev&rev=521530
Log:
2007-03-22 Martin Sebor <[EMAIL PROTECTED]>
* vector (_C_construct): Eliminated first argument (is always end())
and replaced with _C_push_back() for efficiency.
(_C_destroy): Removed an un unnecessary argument (is always end())
and outlined.
(_C_unsafe_swap): New function defined out of line.
(insert): Added an assertion.
(erase): Simplified and optimized a wee bit.
(clear): Defined in terms of _C_destroy() outside the body
of the class template.
(swap): Optimized, called _C_unsafe_swap() for unequal allocators.
(dtor): Called _C_destroy() with a single argument for efficiency.
(assign): Called clear() instead of erase() for better efficiency.
* vector.cc (_C_realloc): Passed this to Allocator::allocate()
instead of begin() and called _C_push_back() instead of _C_construct().
(_C_unsafe_swap): Implements swap for objects with unequal allocators.
(_C_assign_n, _C_insert_1, _C_assign_range, _C_insert_range): Called
_C_push_back() instead of _C_construct() for efficiency.
Modified:
incubator/stdcxx/trunk/include/vector
incubator/stdcxx/trunk/include/vector.cc
Modified: incubator/stdcxx/trunk/include/vector
URL:
http://svn.apache.org/viewvc/incubator/stdcxx/trunk/include/vector?view=diff&rev=521530&r1=521529&r2=521530
==============================================================================
--- incubator/stdcxx/trunk/include/vector (original)
+++ incubator/stdcxx/trunk/include/vector Thu Mar 22 16:38:09 2007
@@ -215,7 +215,7 @@
~vector () {
- _C_destroy (begin (), end ());
+ _C_destroy (begin ());
_RWSTD_VALUE_ALLOC (_C_value_alloc_type, *this,
deallocate (_C_begin, _C_bufend - _C_begin));
}
@@ -367,15 +367,15 @@
void swap (vector&);
- void clear () {
- erase (begin (), end ());
- }
+ void clear ();
+
+#ifdef _RWSTD_NO_PART_SPEC_OVERLOAD
-#if defined (_RWSTD_NO_PART_SPEC_OVERLOAD)
friend void swap (vector& __lhs, vector& __rhs) {
__lhs.swap (__rhs);
}
-#endif
+
+#endif // _RWSTD_NO_PART_SPEC_OVERLOAD
private:
@@ -455,18 +455,22 @@
void _C_realloc (size_type);
- void _C_construct (pointer __where, const_reference __what) {
- _RWSTD_VALUE_ALLOC (_C_value_alloc_type,
- *this, construct (__where, __what));
- }
+ // 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);
- void _C_destroy (iterator __first, iterator __last) {
- for ( ; __first != __last; ++__first)
- _RWSTD_VALUE_ALLOC (_C_value_alloc_type, *this,
- destroy (_RWSTD_VALUE_ALLOC (_C_value_alloc_type, *this,
- address (*__first))));
+ _RWSTD_VALUE_ALLOC (_C_value_alloc_type, *this,
+ construct (_C_end, __x));
+ ++_C_end;
}
+ // destroys elements from the iterator to the end of the vector
+ // and resets end() to point to the iterator
+ void _C_destroy (iterator);
+
+ // implements swap for objects with unequal allocator
+ void _C_unsafe_swap (vector&);
+
pointer _C_begin;
pointer _C_end;
pointer _C_bufend;
@@ -571,9 +575,7 @@
_C_insert_1 (end (), __x);
}
else {
- _C_construct (_C_end, __x);
-
- ++_C_end;
+ _C_push_back (__x);
}
}
@@ -583,6 +585,8 @@
vector<_TypeT, _Allocator>::
insert (iterator __it, const_reference __x)
{
+ _RWSTD_ASSERT_RANGE (__it, end ());
+
const difference_type __off = __it - begin ();
if (end () == __it)
@@ -599,12 +603,17 @@
vector<_TypeT, _Allocator>::
erase (iterator __it)
{
- if (!empty ()) {
- if (__it + 1 != end ())
- _STD::copy (__it + 1, end (), __it);
- _RWSTD_VALUE_ALLOC (_C_value_alloc_type, *this, destroy (_C_end - 1));
- --_C_end;
- }
+ _RWSTD_ASSERT_RANGE (__it, end ());
+ _RWSTD_ASSERT (__it < end ()); // `it' must be dereferenceable
+
+ const iterator __next = __it + 1;
+
+ if (__next != end ())
+ _STD::copy (__next, end (), __it);
+
+ _RWSTD_VALUE_ALLOC (_C_value_alloc_type, *this, destroy (_C_end - 1));
+ --_C_end;
+
return __it;
}
@@ -617,13 +626,19 @@
_RWSTD_ASSERT_RANGE (__first, __last);
_RWSTD_ASSERT_RANGE (begin (), __first);
- const iterator __it = _STD::copy (__last, end (), __first);
+ _C_destroy (_STD::copy (__last, end (), __first));
- _C_destroy (__it, end ());
+ return __first;
+}
- _C_end -= __last - __first;
- return __first;
+template <class _TypeT, class _Allocator>
+inline void
+vector<_TypeT, _Allocator>::
+clear ()
+{
+ if (!empty ())
+ _C_destroy (begin ());
}
@@ -633,25 +648,19 @@
swap (vector &__other)
{
if (get_allocator () == __other.get_allocator ()) {
- _STD::swap (_C_begin, __other._C_begin);
- _STD::swap (_C_end, __other._C_end);
- _STD::swap (_C_bufend, __other._C_bufend);
+ 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;
}
- else { // not exception-safe
-
- // avoid passing the whole object to other vector member
- // functions (i.e., assign()) in case they are implemented
- // in terms of swap(); use iterators instead
-
- vector __tmp (__other.get_allocator ());
-
- // assert that the copy of the allocator compares equal
- // to the original (otherwise the swap() below will cause
- // a recursive call)
- _RWSTD_ASSERT (__tmp.get_allocator () == __other.get_allocator ());
-
- __tmp.assign (begin (), end ());
- __other.swap (__tmp);
+ else {
+ // not exception-safe
+ _C_unsafe_swap (__other);
}
}
@@ -1253,21 +1262,21 @@
template<class _InputIter>
void assign (_InputIter __first, _InputIter __last) {
- erase (begin (), end ());
+ clear ();
insert (begin (), __first, __last);
}
#else // if defined (_RWSTD_NO_INLINE_MEMBER_TEMPLATES)
void assign (const_iterator __first, const_iterator __last) {
- erase (begin (), end ());
+ clear ();
insert (begin (), __first, __last);
}
#endif // _RWSTD_NO_INLINE_MEMBER_TEMPLATES
void assign (size_type __n, const bool& __x = bool()) {
- erase (begin (), end ());
+ clear ();
insert (begin (), __n, __x);
}
Modified: incubator/stdcxx/trunk/include/vector.cc
URL:
http://svn.apache.org/viewvc/incubator/stdcxx/trunk/include/vector.cc?view=diff&rev=521530&r1=521529&r2=521530
==============================================================================
--- incubator/stdcxx/trunk/include/vector.cc (original)
+++ incubator/stdcxx/trunk/include/vector.cc Thu Mar 22 16:38:09 2007
@@ -85,7 +85,7 @@
// allocate storage of requested capacity
__tmp._C_begin =
_RWSTD_VALUE_ALLOC (_C_value_alloc_type, __tmp,
- allocate (__cap, __tmp._C_begin));
+ allocate (__cap, this));
// initialize pointers
__tmp._C_end = __tmp._C_begin;
@@ -97,10 +97,7 @@
// 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) {
-
- __tmp._C_construct (__tmp._C_end, *__ptr);
-
- ++__tmp._C_end;
+ __tmp._C_push_back (*__ptr);
}
// swap *this with the temporary, having its dtor clean up
@@ -110,6 +107,41 @@
template <class _TypeT, class _Allocator>
void vector<_TypeT, _Allocator>::
+_C_destroy (iterator __first)
+{
+ _RWSTD_ASSERT_RANGE (__first, end ());
+
+ for (size_type __n = end () - __first; !(0 == __n); --__n) {
+ _RWSTD_VALUE_ALLOC (_C_value_alloc_type, *this, destroy (--_C_end));
+ }
+}
+
+
+template <class _TypeT, class _Allocator>
+void vector<_TypeT, _Allocator>::
+_C_unsafe_swap (vector &__other)
+{
+ // called only from vector::swap() for unequal allocators
+ _RWSTD_ASSERT (!(get_allocator () == __other.get_allocator ()));
+
+ // avoid passing the whole object to other vector member
+ // functions (i.e., assign()) in case they are implemented
+ // in terms of swap(); use iterators instead
+
+ vector __tmp (__other.get_allocator ());
+
+ // assert that the copy of the allocator compares equal
+ // to the original (otherwise the swap() below will cause
+ // a recursive call)
+ _RWSTD_ASSERT (__tmp.get_allocator () == __other.get_allocator ());
+
+ __tmp.assign (begin (), end ());
+ __other.swap (__tmp);
+}
+
+
+template <class _TypeT, class _Allocator>
+void vector<_TypeT, _Allocator>::
_C_assign_n (size_type __n, const_reference __x)
{
#ifndef _RWSTD_NO_EXT_VECTOR_ASSIGN_IN_PLACE
@@ -137,11 +169,13 @@
if (size () < capacity ()) {
if (__it < end ()) {
+
+ const pointer __end = _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
- _C_construct (_C_end, *(_C_end - difference_type (1)));
-
- const pointer __end = _C_end++;
+ // and bump up end()
+ _C_push_back (*(_C_end - difference_type (1)));
// move the remaining elements from the range above one slot
// toward the end starting with the last element
@@ -151,11 +185,9 @@
*__it = __x;
}
else {
- // construct a copy of the value to be inserted in the
- // uninitialized slot
- _C_construct (_C_end, __x);
-
- ++_C_end;
+ // construct a copy of the value to be inserted
+ // in the uninitialized slot
+ _C_push_back (__x);
}
}
else {
@@ -192,33 +224,32 @@
// copy the initial range prior to `it' as if by a call to
// std::uninitialized_copy (begin (), __it, __tmp._C_begin);
- for (__i = begin (); !(__i == __it); ++__i, ++__tmp._C_end) {
+ for (__i = begin (); !(__i == __it); ++__i) {
_RWSTD_ASSERT (!(__tmp._C_end == __tmp._C_bufend));
- __tmp._C_construct (__tmp._C_end, *__i);
+ __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);
- for ( ; __n; --__n, ++__tmp._C_end) {
+ for ( ; __n; --__n) {
_RWSTD_ASSERT (!(__tmp._C_end == __tmp._C_bufend));
- __tmp._C_construct (__tmp._C_end, __x);
+ __tmp._C_push_back (__x);
}
// copy the final range of elements starting with `it'
// as if by a call to
- // std::uninitialized_copy (__it, end (),
- // __tmp._C_begin + (__size1 + __n);
+ // uninitialized_copy (__it, end (), __tmp._C_begin + __size1 + __n);
- for (__i = __it; !(__i == end ()); ++__i, ++__tmp._C_end) {
+ for (__i = __it; !(__i == end ()); ++__i) {
_RWSTD_ASSERT (!(__tmp._C_end == __tmp._C_bufend));
- __tmp._C_construct (__tmp._C_end, *__i);
+ __tmp._C_push_back (*__i);
}
// swap the sequences controlled by the temporary vector and *this
@@ -407,8 +438,8 @@
// 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 ( ; !(__first == __last); ++__first, ++__tmp._C_end)
- __tmp._C_construct (__tmp._C_end, *__first);
+ for ( ; !(__first == __last); ++__first)
+ __tmp._C_push_back (*__first);
// swap *this with the temporary, having its dtor clean up
__self->swap (__tmp);
@@ -608,7 +639,6 @@
const pointer __end = __self->_C_end;
if (__movend <= __end) {
-
// compute the beginning of the range of elements whose copies
// will be copy-constructed in the uninitialized space just past
// the current end of the sequence
@@ -616,14 +646,11 @@
// construct copies of elements that will be moved beyond
// the current end of the sequence controlled by *this
- pointer __p;
-
- for (__p = __ucpbeg; !(__p == __end); ++__p, ++__self->_C_end)
- __self->_C_construct (__self->_C_end, *__p);
+ for (pointer __p = __ucpbeg; !(__p == __end); ++__p)
+ __self->_C_push_back (*__p);
- // copy elements that will be overwritten below
// over the range of elements moved above
- for (__p = __end; __movend < __p--; )
+ for (pointer __p = __end; __movend < __p--; )
*__p = *(__p - __size2);
}
else {
@@ -638,18 +665,16 @@
// of elements being inserted, as if by a call to
// std::uninitialized_copy (__mid, __last, _C_end);
- for (_FwdIter __m = __mid ; !(__m == __last);
- ++__m, ++__self->_C_end)
- __self->_C_construct (__self->_C_end, *__m);
+ for (_FwdIter __m = __mid ; !(__m == __last); ++__m)
+ __self->_C_push_back (*__m);
// 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);
- for (pointer __p = __movbeg; !(__p == __end);
- ++__p, ++__self->_C_end)
- __self->_C_construct (__self->_C_end, *__p);
+ for (pointer __p = __movbeg; !(__p == __end); ++__p)
+ __self->_C_push_back (*__p);
__last = __mid;
}
@@ -676,22 +701,20 @@
// 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 (__ix = __self->begin (); __ix != __it; ++__ix, ++__tmp._C_end) {
-
- __tmp._C_construct (__tmp._C_end, *__ix);
+ for (__ix = __self->begin (); __ix != __it; ++__ix) {
+ __tmp._C_push_back (*__ix);
}
// append the sequence [first, last) to the temporary,
// carefully increasing the size of tmp before performing
// any operations on `first' and `last' in case they throw
for (; !(__first == __last); ++__first) {
- __tmp._C_construct (__tmp._C_end, *__first);
- ++__tmp._C_end;
+ __tmp._C_push_back (*__first);
}
// copy the remaining elements from *this
- for ( ; __ix != __self->end (); ++__ix, ++__tmp._C_end) {
- __tmp._C_construct (__tmp._C_end, *__ix);
+ for ( ; __ix != __self->end (); ++__ix) {
+ __tmp._C_push_back (*__ix);
}
// swap *this with the temporary, having its dtor clean up