copy_backward refinement for normal_iterators

Philip Martin pm@corris.dircon.co.uk
Sat Apr 1 00:00:00 GMT 2000


Gabriel Dos Reis <Gabriel.Dos-Reis@cmla.ens-cachan.fr> writes:

> Philip Martin <pm@corris.dircon.co.uk> writes:
> 
> | 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,
> 
> Thanks for your patch.
> 
> Would it be possible to give more suggestive names to
> '__copy_backward_ni2', '__copy_backward_ni1'; and make 
> appropriate ChangeLog entries?  

How about
   '__copy_backward_output_normal_iterator'
and
   '__copy_backward_input_normal_iterator'?

Philip


2000-02-02  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	Thu Feb  3 19:05:08 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,416 ----
  };
  
  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_output_normal_iterator(_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_output_normal_iterator(_BI1 __first, _BI1 __last,
+                                                    _BI2 __result, __false_type){
+   return __copy_backward_aux(__first, __last, __result);
+ }
+ 
+ template <typename _BI1, typename _BI2>
+ inline _BI2 __copy_backward_input_normal_iterator(_BI1 __first, _BI1 __last,
+                                                   _BI2 __result, __true_type) {
+   typedef typename _Is_normal_iterator<_BI2>::_Normal __Normal;
+   return __copy_backward_output_normal_iterator(__first.base(), __last.base(),
+                                                 __result, __Normal());
+ }
+ 
+ template <typename _BI1, typename _BI2>
+ inline _BI2 __copy_backward_input_normal_iterator(_BI1 __first, _BI1 __last,
+                                                   _BI2 __result, __false_type) {
+   typedef typename _Is_normal_iterator<_BI2>::_Normal __Normal;
+   return __copy_backward_output_normal_iterator(__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_input_normal_iterator(__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	Tue Jan 25 20:34:47 2000
--- libstdc++-modified/stl/bits/stl_vector.h	Thu Feb  3 19:02:51 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);


More information about the Libstdc++ mailing list