+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.
+
2004-07-01 Benjamin Kosnik <bkoz@redhat.com>
Per Bothner <per@bothner.com>
Mohan Embar <gnustuff@thisiscool.com>
// (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)
+ template<bool, typename>
+ struct __copy
{
- for (; __first != __last; ++__result, ++__first)
- *__result = *__first;
- return __result;
- }
+ template<typename _II, typename _OI>
+ static _OI
+ copy(_II __first, _II __last, _OI __result)
+ {
+ 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)
+ template<bool _BoolType>
+ struct __copy<_BoolType, random_access_iterator_tag>
{
- typedef typename iterator_traits<_RandomAccessIterator>::difference_type
- _Distance;
- for (_Distance __n = __last - __first; __n > 0; --__n)
- {
- *__result = *__first;
- ++__first;
- ++__result;
+ 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;
}
- return __result;
- }
+ };
- template<typename _Tp>
- inline _Tp*
- __copy_trivial(const _Tp* __first, const _Tp* __last, _Tp* __result)
+ template<>
+ struct __copy<true, random_access_iterator_tag>
{
- 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>
+ 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 _Tp>
- inline _Tp*
- __copy_aux2(_Tp* __first, _Tp* __last, _Tp* __result, __true_type)
- { return std::__copy_trivial(__first, __last, __result); }
+ 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);
- template<typename _Tp>
- inline _Tp*
- __copy_aux2(const _Tp* __first, const _Tp* __last, _Tp* __result,
- __true_type)
- { return std::__copy_trivial(__first, __last, __result); }
+ 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)
- {
- 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()));
- }
+ { 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)
- {
- 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());
- }
+ { return std::__copy_aux(__first, __last, __result); }
template<typename _InputIterator, typename _OutputIterator>
inline _OutputIterator
inline _BI2
__copy_backward_aux(_BI1 __first, _BI1 __last, _BI2 __result)
{
- typedef typename iterator_traits<_BI2>::value_type _ValueType;
+ 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<_ValueType>::_M_type
+ const bool __simple = (__is_trivially_copyable<_ValueType2>::_M_type
&& __is_pointer<_BI1>::_M_type
- && __is_pointer<_BI2>::_M_type);
+ && __is_pointer<_BI2>::_M_type
+ && __are_same<_ValueType1, _ValueType2>::_M_type);
- return __copy_backward<__simple, _Category>::copy_b(__first, __last,
- __result);
+ return std::__copy_backward<__simple, _Category>::copy_b(__first, __last,
+ __result);
}
template <typename _BI1, typename _BI2>
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) );
+ 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) );
- int s2[N];
- copy_backward(A, A + N, s2 + N);
- VERIFY( equal(s2, s2 + N, 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
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()) );
+ 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()) );
- int s2[N];
- copy_backward(a.begin(), a.end(), s2 + N);
- VERIFY( equal(s2, s2 + N, 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
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()) );
+ 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()) );
- int s2[N];
- copy_backward(a.begin(), a.end(), s2 + N);
- VERIFY( equal(s2, s2 + N, 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
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()) );
+ 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()) );
- int s2[N];
- copy_backward(a.begin(), a.end(), s2 + N);
- VERIFY( equal(s2, s2 + N, 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