This is the mail archive of the libstdc++@sourceware.cygnus.com mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

copy_backward refinement for normal_iterators


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);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]