This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[v3] Rewrite __copy/__copy_aux2, etc. + a bug fix
- From: Paolo Carlini <pcarlini at suse dot de>
- To: "'gcc-patches at gcc dot gnu dot org'" <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 01 Jul 2004 21:37:10 +0200
- Subject: [v3] Rewrite __copy/__copy_aux2, etc. + a bug fix
Hi,
tested x86-linux, committed to mainline.
Paolo.
////////////
2004-07-01 Paolo Carlini <pcarlini@suse.de>
* include/bits/stl_algobase.h (__copy_trivial): Remove.
(__copy_aux2): Rewrite as __copy_aux to use __is_pointer,
__is_trivially_copyable, __are_same and __copy::copy.
(__copy): Rewrite as a class template and two specializations.
(__copy_ni2): Simplify, just call __copy_aux.
* include/bits/stl_algobase.h (__copy_backward_aux): Add __are_same
check.
* testsuite/25_algorithms/copy/1.cc, 2.cc, 3.cc, 4.cc: Test also
for destination value type != source value type.
diff -prN libstdc++-v3-orig/include/bits/stl_algobase.h libstdc++-v3/include/bits/stl_algobase.h
*** libstdc++-v3-orig/include/bits/stl_algobase.h Tue Jun 29 21:00:18 2004
--- libstdc++-v3/include/bits/stl_algobase.h Thu Jul 1 15:23:13 2004
*************** namespace std
*** 226,313 ****
// (2) If we're using random access iterators, then write the loop as
// a for loop with an explicit count.
! template<typename _InputIterator, typename _OutputIterator>
! inline _OutputIterator
! __copy(_InputIterator __first, _InputIterator __last,
! _OutputIterator __result, input_iterator_tag)
{
! for (; __first != __last; ++__result, ++__first)
! *__result = *__first;
! return __result;
! }
! template<typename _RandomAccessIterator, typename _OutputIterator>
! inline _OutputIterator
! __copy(_RandomAccessIterator __first, _RandomAccessIterator __last,
! _OutputIterator __result, random_access_iterator_tag)
{
! typedef typename iterator_traits<_RandomAccessIterator>::difference_type
! _Distance;
! for (_Distance __n = __last - __first; __n > 0; --__n)
! {
! *__result = *__first;
! ++__first;
! ++__result;
}
! return __result;
! }
! template<typename _Tp>
! inline _Tp*
! __copy_trivial(const _Tp* __first, const _Tp* __last, _Tp* __result)
{
! std::memmove(__result, __first, sizeof(_Tp) * (__last - __first));
! return __result + (__last - __first);
! }
! template<typename _InputIterator, typename _OutputIterator>
! inline _OutputIterator
! __copy_aux2(_InputIterator __first, _InputIterator __last,
! _OutputIterator __result, __false_type)
! { return std::__copy(__first, __last, __result,
! std::__iterator_category(__first)); }
! template<typename _InputIterator, typename _OutputIterator>
! inline _OutputIterator
! __copy_aux2(_InputIterator __first, _InputIterator __last,
! _OutputIterator __result, __true_type)
! { return std::__copy(__first, __last, __result,
! std::__iterator_category(__first)); }
!
! template<typename _Tp>
! inline _Tp*
! __copy_aux2(_Tp* __first, _Tp* __last, _Tp* __result, __true_type)
! { return std::__copy_trivial(__first, __last, __result); }
!
! template<typename _Tp>
! inline _Tp*
! __copy_aux2(const _Tp* __first, const _Tp* __last, _Tp* __result,
! __true_type)
! { return std::__copy_trivial(__first, __last, __result); }
template<typename _InputIterator, typename _OutputIterator>
inline _OutputIterator
__copy_ni2(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, __true_type)
! {
! typedef typename iterator_traits<_InputIterator>::value_type
! _ValueType;
! typedef typename __type_traits<
! _ValueType>::has_trivial_assignment_operator _Trivial;
! return _OutputIterator(std::__copy_aux2(__first, __last, __result.base(),
! _Trivial()));
! }
template<typename _InputIterator, typename _OutputIterator>
inline _OutputIterator
__copy_ni2(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, __false_type)
! {
! typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
! typedef typename __type_traits<
! _ValueType>::has_trivial_assignment_operator _Trivial;
! return std::__copy_aux2(__first, __last, __result, _Trivial());
! }
template<typename _InputIterator, typename _OutputIterator>
inline _OutputIterator
--- 226,301 ----
// (2) If we're using random access iterators, then write the loop as
// a for loop with an explicit count.
! template<bool, typename>
! struct __copy
{
! template<typename _II, typename _OI>
! static _OI
! copy(_II __first, _II __last, _OI __result)
! {
! for (; __first != __last; ++__result, ++__first)
! *__result = *__first;
! return __result;
! }
! };
! template<bool _BoolType>
! struct __copy<_BoolType, random_access_iterator_tag>
{
! template<typename _II, typename _OI>
! static _OI
! copy(_II __first, _II __last, _OI __result)
! {
! typedef typename iterator_traits<_II>::difference_type _Distance;
! for(_Distance __n = __last - __first; __n > 0; --__n)
! {
! *__result = *__first;
! ++__first;
! ++__result;
! }
! return __result;
}
! };
! template<>
! struct __copy<true, random_access_iterator_tag>
{
! template<typename _Tp>
! static _Tp*
! copy(const _Tp* __first, const _Tp* __last, _Tp* __result)
! {
! std::memmove(__result, __first, sizeof(_Tp) * (__last - __first));
! return __result + (__last - __first);
! }
! };
! template<typename _II, typename _OI>
! inline _OI
! __copy_aux(_II __first, _II __last, _OI __result)
! {
! typedef typename iterator_traits<_II>::value_type _ValueTypeI;
! typedef typename iterator_traits<_OI>::value_type _ValueTypeO;
! typedef typename iterator_traits<_II>::iterator_category _Category;
! const bool __simple = (__is_trivially_copyable<_ValueTypeO>::_M_type
! && __is_pointer<_II>::_M_type
! && __is_pointer<_OI>::_M_type
! && __are_same<_ValueTypeI, _ValueTypeO>::_M_type);
! return std::__copy<__simple, _Category>::copy(__first, __last, __result);
! }
template<typename _InputIterator, typename _OutputIterator>
inline _OutputIterator
__copy_ni2(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, __true_type)
! { return _OutputIterator(std::__copy_aux(__first, __last,
! __result.base())); }
template<typename _InputIterator, typename _OutputIterator>
inline _OutputIterator
__copy_ni2(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, __false_type)
! { return std::__copy_aux(__first, __last, __result); }
template<typename _InputIterator, typename _OutputIterator>
inline _OutputIterator
*************** namespace std
*** 403,416 ****
inline _BI2
__copy_backward_aux(_BI1 __first, _BI1 __last, _BI2 __result)
{
! typedef typename iterator_traits<_BI2>::value_type _ValueType;
typedef typename iterator_traits<_BI1>::iterator_category _Category;
! const bool __simple = (__is_trivially_copyable<_ValueType>::_M_type
&& __is_pointer<_BI1>::_M_type
! && __is_pointer<_BI2>::_M_type);
! return __copy_backward<__simple, _Category>::copy_b(__first, __last,
! __result);
}
template <typename _BI1, typename _BI2>
--- 391,406 ----
inline _BI2
__copy_backward_aux(_BI1 __first, _BI1 __last, _BI2 __result)
{
! typedef typename iterator_traits<_BI1>::value_type _ValueType1;
! typedef typename iterator_traits<_BI2>::value_type _ValueType2;
typedef typename iterator_traits<_BI1>::iterator_category _Category;
! const bool __simple = (__is_trivially_copyable<_ValueType2>::_M_type
&& __is_pointer<_BI1>::_M_type
! && __is_pointer<_BI2>::_M_type
! && __are_same<_ValueType1, _ValueType2>::_M_type);
! return std::__copy_backward<__simple, _Category>::copy_b(__first, __last,
! __result);
}
template <typename _BI1, typename _BI2>
diff -prN libstdc++-v3-orig/testsuite/25_algorithms/copy/1.cc libstdc++-v3/testsuite/25_algorithms/copy/1.cc
*** libstdc++-v3-orig/testsuite/25_algorithms/copy/1.cc Wed Jun 30 00:41:37 2004
--- libstdc++-v3/testsuite/25_algorithms/copy/1.cc Thu Jul 1 13:53:55 2004
*************** test01()
*** 31,51 ****
const int A[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17};
const int N = sizeof(A) / sizeof(int);
! int s1[N];
! copy(A, A + N, s1);
! VERIFY( equal(s1, s1 + N, A) );
vector<int> v1(N);
copy(A, A + N, v1.begin());
VERIFY( equal(v1.begin(), v1.end(), A) );
! int s2[N];
! copy_backward(A, A + N, s2 + N);
! VERIFY( equal(s2, s2 + N, A) );
vector<int> v2(N);
copy_backward(A, A + N, v2.end());
VERIFY( equal(v2.begin(), v2.end(), A) );
}
int
--- 31,59 ----
const int A[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17};
const int N = sizeof(A) / sizeof(int);
! int i1[N];
! copy(A, A + N, i1);
! VERIFY( equal(i1, i1 + N, A) );
vector<int> v1(N);
copy(A, A + N, v1.begin());
VERIFY( equal(v1.begin(), v1.end(), A) );
! short s1[N];
! copy(A, A + N, s1);
! VERIFY( equal(s1, s1 + N, A) );
!
! int i2[N];
! copy_backward(A, A + N, i2 + N);
! VERIFY( equal(i2, i2 + N, A) );
vector<int> v2(N);
copy_backward(A, A + N, v2.end());
VERIFY( equal(v2.begin(), v2.end(), A) );
+
+ short s2[N];
+ copy_backward(A, A + N, s2 + N);
+ VERIFY( equal(s2, s2 + N, A) );
}
int
diff -prN libstdc++-v3-orig/testsuite/25_algorithms/copy/2.cc libstdc++-v3/testsuite/25_algorithms/copy/2.cc
*** libstdc++-v3-orig/testsuite/25_algorithms/copy/2.cc Wed Jun 30 00:42:17 2004
--- libstdc++-v3/testsuite/25_algorithms/copy/2.cc Thu Jul 1 13:56:42 2004
*************** test01()
*** 32,52 ****
const int N = sizeof(A) / sizeof(int);
const vector<int> a(A, A + N);
! int s1[N];
! copy(a.begin(), a.end(), s1);
! VERIFY( equal(s1, s1 + N, a.begin()) );
vector<int> v1(N);
copy(a.begin(), a.end(), v1.begin());
VERIFY( equal(v1.begin(), v1.end(), a.begin()) );
! int s2[N];
! copy_backward(a.begin(), a.end(), s2 + N);
! VERIFY( equal(s2, s2 + N, a.begin()) );
vector<int> v2(N);
copy_backward(a.begin(), a.end(), v2.end());
VERIFY( equal(v2.begin(), v2.end(), a.begin()) );
}
int
--- 32,60 ----
const int N = sizeof(A) / sizeof(int);
const vector<int> a(A, A + N);
! int i1[N];
! copy(a.begin(), a.end(), i1);
! VERIFY( equal(i1, i1 + N, a.begin()) );
vector<int> v1(N);
copy(a.begin(), a.end(), v1.begin());
VERIFY( equal(v1.begin(), v1.end(), a.begin()) );
! short s1[N];
! copy(a.begin(), a.end(), s1);
! VERIFY( equal(s1, s1 + N, a.begin()) );
!
! int i2[N];
! copy_backward(a.begin(), a.end(), i2 + N);
! VERIFY( equal(i2, i2 + N, a.begin()) );
vector<int> v2(N);
copy_backward(a.begin(), a.end(), v2.end());
VERIFY( equal(v2.begin(), v2.end(), a.begin()) );
+
+ short s2[N];
+ copy_backward(a.begin(), a.end(), s2 + N);
+ VERIFY( equal(s2, s2 + N, a.begin()) );
}
int
diff -prN libstdc++-v3-orig/testsuite/25_algorithms/copy/3.cc libstdc++-v3/testsuite/25_algorithms/copy/3.cc
*** libstdc++-v3-orig/testsuite/25_algorithms/copy/3.cc Wed Jun 30 00:42:59 2004
--- libstdc++-v3/testsuite/25_algorithms/copy/3.cc Thu Jul 1 13:57:37 2004
*************** test01()
*** 33,53 ****
const int N = sizeof(A) / sizeof(int);
const deque<int> a(A, A + N);
! int s1[N];
! copy(a.begin(), a.end(), s1);
! VERIFY( equal(s1, s1 + N, a.begin()) );
vector<int> v1(N);
copy(a.begin(), a.end(), v1.begin());
VERIFY( equal(v1.begin(), v1.end(), a.begin()) );
! int s2[N];
! copy_backward(a.begin(), a.end(), s2 + N);
! VERIFY( equal(s2, s2 + N, a.begin()) );
vector<int> v2(N);
copy_backward(a.begin(), a.end(), v2.end());
VERIFY( equal(v2.begin(), v2.end(), a.begin()) );
}
int
--- 33,61 ----
const int N = sizeof(A) / sizeof(int);
const deque<int> a(A, A + N);
! int i1[N];
! copy(a.begin(), a.end(), i1);
! VERIFY( equal(i1, i1 + N, a.begin()) );
vector<int> v1(N);
copy(a.begin(), a.end(), v1.begin());
VERIFY( equal(v1.begin(), v1.end(), a.begin()) );
! short s1[N];
! copy(a.begin(), a.end(), s1);
! VERIFY( equal(s1, s1 + N, a.begin()) );
!
! int i2[N];
! copy_backward(a.begin(), a.end(), i2 + N);
! VERIFY( equal(i2, i2 + N, a.begin()) );
vector<int> v2(N);
copy_backward(a.begin(), a.end(), v2.end());
VERIFY( equal(v2.begin(), v2.end(), a.begin()) );
+
+ short s2[N];
+ copy_backward(a.begin(), a.end(), s2 + N);
+ VERIFY( equal(s2, s2 + N, a.begin()) );
}
int
diff -prN libstdc++-v3-orig/testsuite/25_algorithms/copy/4.cc libstdc++-v3/testsuite/25_algorithms/copy/4.cc
*** libstdc++-v3-orig/testsuite/25_algorithms/copy/4.cc Wed Jun 30 00:43:42 2004
--- libstdc++-v3/testsuite/25_algorithms/copy/4.cc Thu Jul 1 13:58:38 2004
*************** test01()
*** 33,53 ****
const int N = sizeof(A) / sizeof(int);
const list<int> a(A, A + N);
! int s1[N];
! copy(a.begin(), a.end(), s1);
! VERIFY( equal(s1, s1 + N, a.begin()) );
vector<int> v1(N);
copy(a.begin(), a.end(), v1.begin());
VERIFY( equal(v1.begin(), v1.end(), a.begin()) );
! int s2[N];
! copy_backward(a.begin(), a.end(), s2 + N);
! VERIFY( equal(s2, s2 + N, a.begin()) );
vector<int> v2(N);
copy_backward(a.begin(), a.end(), v2.end());
VERIFY( equal(v2.begin(), v2.end(), a.begin()) );
}
int
--- 33,61 ----
const int N = sizeof(A) / sizeof(int);
const list<int> a(A, A + N);
! int i1[N];
! copy(a.begin(), a.end(), i1);
! VERIFY( equal(i1, i1 + N, a.begin()) );
vector<int> v1(N);
copy(a.begin(), a.end(), v1.begin());
VERIFY( equal(v1.begin(), v1.end(), a.begin()) );
! short s1[N];
! copy(a.begin(), a.end(), s1);
! VERIFY( equal(s1, s1 + N, a.begin()) );
!
! int i2[N];
! copy_backward(a.begin(), a.end(), i2 + N);
! VERIFY( equal(i2, i2 + N, a.begin()) );
vector<int> v2(N);
copy_backward(a.begin(), a.end(), v2.end());
VERIFY( equal(v2.begin(), v2.end(), a.begin()) );
+
+ short s2[N];
+ copy_backward(a.begin(), a.end(), s2 + N);
+ VERIFY( equal(s2, s2 + N, a.begin()) );
}
int