This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: [Patch] Remove workaround for copy_backward
- From: Gabriel Dos Reis <gdr at integrable-solutions dot net>
- To: Paolo Carlini <pcarlini at unitus dot it>
- Cc: libstdc++ at gcc dot gnu dot org
- Date: 28 Sep 2003 17:45:23 +0200
- Subject: Re: [Patch] Remove workaround for copy_backward
- Organization: Integrable Solutions
- References: <3F75BC34.2050604@unitus.it>
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