This is the mail archive of the
libstdc++@sourceware.cygnus.com
mailing list for the libstdc++ project.
copy_backward refinement for normal_iterators
- To: libstdc++ at sourceware dot cygnus dot com
- Subject: copy_backward refinement for normal_iterators
- From: Philip Martin <pm at corris dot dircon dot co dot uk>
- Date: 16 Jan 2000 21:56:16 +0000
Hi
When vector iterators were C++ pointers the code:
std::vector<int> v1(4);
std::vector<int> v2(4);
std::copy_backward( v2.begin(), v2.end(), v1.end() ); // memmove
was implemented as a call to memmove(). The following patch restores
that behaviour. It also includes some minor changes to the vector code
to reduce the dependency on the iterator implementation.
Philip
2000-01-16 Philip Martin <pm@corris.dircon.co.uk>
* stl/bits/stl_algobase.h: Add traits based dispatch for
__normal_iterator in the copy_backward()algorithm
* stl/bits/stl_vector.h: Reduce use of __normal_iterator
base() function.
diff -c3prN libstdc++/stl/bits/stl_algobase.h libstdc++-modified/stl/bits/stl_algobase.h
*** libstdc++/stl/bits/stl_algobase.h Fri Nov 19 20:14:50 1999
--- libstdc++-modified/stl/bits/stl_algobase.h Sun Jan 16 21:03:22 2000
*************** struct __copy_backward_dispatch<const _T
*** 370,381 ****
};
template <class _BI1, class _BI2>
! inline _BI2 copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) {
typedef typename __type_traits<typename iterator_traits<_BI2>::value_type>
::has_trivial_assignment_operator
_Trivial;
return __copy_backward_dispatch<_BI1, _BI2, _Trivial>
::copy(__first, __last, __result);
}
#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
--- 370,414 ----
};
template <class _BI1, class _BI2>
! inline _BI2 __copy_backward_aux(_BI1 __first, _BI1 __last, _BI2 __result) {
typedef typename __type_traits<typename iterator_traits<_BI2>::value_type>
::has_trivial_assignment_operator
_Trivial;
return __copy_backward_dispatch<_BI1, _BI2, _Trivial>
::copy(__first, __last, __result);
+ }
+
+ template <typename _BI1, typename _BI2>
+ inline _BI2 __copy_backward_ni2(_BI1 __first, _BI1 __last, _BI2 __result,
+ __true_type) {
+ return _BI2(__copy_backward_aux(__first, __last, __result.base()));
+ }
+
+ template <typename _BI1, typename _BI2>
+ inline _BI2 __copy_backward_ni2(_BI1 __first, _BI1 __last, _BI2 __result,
+ __false_type) {
+ return __copy_backward_aux(__first, __last, __result);
+ }
+
+ template <typename _BI1, typename _BI2>
+ inline _BI2 __copy_backward_ni1(_BI1 __first, _BI1 __last, _BI2 __result,
+ __true_type) {
+ typedef typename _Is_normal_iterator<_BI2>::_Normal __Normal;
+ return __copy_backward_ni2(__first.base(), __last.base(), __result,
+ __Normal());
+ }
+
+ template <typename _BI1, typename _BI2>
+ inline _BI2 __copy_backward_ni1(_BI1 __first, _BI1 __last, _BI2 __result,
+ __false_type) {
+ typedef typename _Is_normal_iterator<_BI2>::_Normal __Normal;
+ return __copy_backward_ni2(__first, __last, __result, __Normal());
+ }
+
+ template <typename _BI1, typename _BI2>
+ inline _BI2 copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) {
+ typedef typename _Is_normal_iterator<_BI1>::_Normal __Normal;
+ return __copy_backward_ni1(__first, __last, __result, __Normal());
}
#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
diff -c3prN libstdc++/stl/bits/stl_vector.h libstdc++-modified/stl/bits/stl_vector.h
*** libstdc++/stl/bits/stl_vector.h Mon Nov 15 16:53:20 1999
--- libstdc++-modified/stl/bits/stl_vector.h Sun Jan 16 21:15:29 2000
*************** vector<_Tp,_Alloc>::operator=(const vect
*** 556,562 ****
}
else if (size() >= __xlen) {
iterator __i(copy(__x.begin(), __x.end(), begin()));
! destroy(__i.base(), _M_finish);
}
else {
copy(__x.begin(), __x.begin() + size(), _M_start);
--- 556,562 ----
}
else if (size() >= __xlen) {
iterator __i(copy(__x.begin(), __x.end(), begin()));
! destroy(__i, end());
}
else {
copy(__x.begin(), __x.begin() + size(), _M_start);
*************** vector<_Tp, _Alloc>::_M_assign_aux(_Forw
*** 612,618 ****
}
else if (size() >= __len) {
iterator __new_finish(copy(__first, __last, _M_start));
! destroy(__new_finish.base(), _M_finish);
_M_finish = __new_finish;
}
else {
--- 612,618 ----
}
else if (size() >= __len) {
iterator __new_finish(copy(__first, __last, _M_start));
! destroy(__new_finish, end());
_M_finish = __new_finish;
}
else {
*************** void vector<_Tp, _Alloc>::_M_fill_insert
*** 722,731 ****
iterator __new_start(_M_allocate(__len));
iterator __new_finish(__new_start);
__STL_TRY {
! __new_finish = uninitialized_copy(_M_start, __position.base(), __new_start);
__new_finish = uninitialized_fill_n(__new_finish, __n, __x);
__new_finish
! = uninitialized_copy(__position.base(), _M_finish, __new_finish);
}
__STL_UNWIND((destroy(__new_start,__new_finish),
_M_deallocate(__new_start.base(),__len)));
--- 722,731 ----
iterator __new_start(_M_allocate(__len));
iterator __new_finish(__new_start);
__STL_TRY {
! __new_finish = uninitialized_copy(begin(), __position, __new_start);
__new_finish = uninitialized_fill_n(__new_finish, __n, __x);
__new_finish
! = uninitialized_copy(__position, end(), __new_finish);
}
__STL_UNWIND((destroy(__new_start,__new_finish),
_M_deallocate(__new_start.base(),__len)));
*************** vector<_Tp, _Alloc>::_M_range_insert(ite
*** 764,770 ****
size_type __n = 0;
distance(__first, __last, __n);
if (size_type(_M_end_of_storage - _M_finish) >= __n) {
! const size_type __elems_after = _M_finish - __position.base();
iterator __old_finish(_M_finish);
if (__elems_after > __n) {
uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);
--- 764,770 ----
size_type __n = 0;
distance(__first, __last, __n);
if (size_type(_M_end_of_storage - _M_finish) >= __n) {
! const size_type __elems_after = end() - __position;
iterator __old_finish(_M_finish);
if (__elems_after > __n) {
uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);