This is the mail archive of the libstdc++@gcc.gnu.org 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]
Other format: [Raw text]

Re: [Patch] Remove workaround for copy_backward


Paolo Carlini <pcarlini@unitus.it> writes:

| 2003-09-27  Paolo Carlini  <pcarlini@unitus.it>
| 
| 	* include/bits/stl_algobase.h (struct __copy_backward_dispatch):
| 	Remove, thus avoiding the workaround. Use instead...
| 	(__copy_backward_dispatch(_BidirectionalIterator1,
| 	_BidirectionalIterator1, _BidirectionalIterator2, __false_type),
| 	__copy_backward_dispatch(_BidirectionalIterator1,
| 	_BidirectionalIterator1, _BidirectionalIterator2, __true_type),
| 	__copy_backward_dispatch(_Tp*, _Tp*, _Tp*, __true_type),
| 	__copy_backward_dispatch(const _Tp*, const _Tp*, _Tp*,
| 	__true_type)): ... this set of function templates, similarly
| 	to what happens in the implementation of copy(). The latter two
| 	call __copy_backward_trivial.
| 	(__copy_backward_trivial): New, similar to __copy_trivial.
| 	(__copy_backward_aux): Tweak.diff -prN libstdc++-v3-orig/include/bits/stl_algobase.h libstdc++-v3/include/bits/stl_algobase.h

Paolo,

As promised.

* I would see eliminitation of dummy arguments when dispatching.  Here
  is what I would do for/with the class dispatcher:

  // first template parameter indicates whether input and output iterators
  // are pointers AND value type has trivial copy-constructor.
  // second template parameter indicates input iterator category.
  template<bool, typename>
  struct __copy_backward {
     template<typename _BI1, typename _BI2>
       static _BI2 copy(_BI1 __f, _BI1 __l, _BI2 __o)
       {
          while (__f != __l)
            *--__r = *__l;
          return __r;
       }
  };

 template<bool b>
   struct __copy_backward<b, std::random_access_iterator_tag> {
     template<typename _BI1, typename _BI2>
       static _BI2 copy(_BI1 __f, _BI1 __l, _BI2 __o)
       {
         typename iterator_traits<_RandomAccessIterator>::difference_type __n;
         for (__n = __l - __f; __n > 0; --__n)
            *--__result = *--__last;
        return __r;
       }
   };


  template<>
    struct __copy_backward<true, std::random_access_iterator_tag> {
      template<typename _Tp>
        static _Tp* copy(const _Tp* __f, const _Tp* __l, _Tp* __o)
        {
           const ptrdiff_t __n = __l - __f;
           return (_Tp*) std::memmove(__o - __n, __f, sizeof (_Tp) * __n);
        } 
    };

  template<class _BI1, class _BI2>
    inline _BI2
    copy_backward(_BI1 __f, _BI1 __l, _BI2 __o)
    {
      typedef typename iterator_traits<_BI1>::value_type _Tp;
      return __copy_backward<__is_trivially_copyable<_Tp>::_S_value
                             && __is_pointer<_BI1>::_S_value
                             && __is_pointer<_B12>::_S_value,
                             typename iterator_traits<_BI1>::category>
               ::copy(__f, __l, __r);
    }
  

That is sketchy but it the core idea is there.

-- Gaby


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