This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

[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

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