From 50f44d58119cc789e685eae84a257312efbe5ce9 Mon Sep 17 00:00:00 2001
From: paolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Thu, 1 Jul 2004 17:53:21 +0000
Subject: [PATCH] 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.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@83991 138bc75d-0d04-0410-961f-82ee72b054a4
---
 libstdc++-v3/ChangeLog                        |  13 ++
 libstdc++-v3/include/bits/stl_algobase.h      | 128 ++++++++----------
 .../testsuite/25_algorithms/copy/1.cc         |  20 ++-
 .../testsuite/25_algorithms/copy/2.cc         |  20 ++-
 .../testsuite/25_algorithms/copy/3.cc         |  20 ++-
 .../testsuite/25_algorithms/copy/4.cc         |  20 ++-
 6 files changed, 128 insertions(+), 93 deletions(-)

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 6d2eed8a5e57..f981c0f1ca6e 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,16 @@
+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>
diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h
index 1b7c4b49ad5d..1b441e0a6d4c 100644
--- a/libstdc++-v3/include/bits/stl_algobase.h
+++ b/libstdc++-v3/include/bits/stl_algobase.h
@@ -226,88 +226,76 @@ namespace std
   // (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
@@ -403,14 +391,16 @@ namespace std
     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>
diff --git a/libstdc++-v3/testsuite/25_algorithms/copy/1.cc b/libstdc++-v3/testsuite/25_algorithms/copy/1.cc
index 8574522972d2..7c45db2e0e43 100644
--- a/libstdc++-v3/testsuite/25_algorithms/copy/1.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/copy/1.cc
@@ -31,21 +31,29 @@ test01()
   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
diff --git a/libstdc++-v3/testsuite/25_algorithms/copy/2.cc b/libstdc++-v3/testsuite/25_algorithms/copy/2.cc
index d7bd1793e41c..8fe3b3a61c8c 100644
--- a/libstdc++-v3/testsuite/25_algorithms/copy/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/copy/2.cc
@@ -32,21 +32,29 @@ test01()
   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
diff --git a/libstdc++-v3/testsuite/25_algorithms/copy/3.cc b/libstdc++-v3/testsuite/25_algorithms/copy/3.cc
index 0453ce816328..0bf0432dccc9 100644
--- a/libstdc++-v3/testsuite/25_algorithms/copy/3.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/copy/3.cc
@@ -33,21 +33,29 @@ test01()
   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
diff --git a/libstdc++-v3/testsuite/25_algorithms/copy/4.cc b/libstdc++-v3/testsuite/25_algorithms/copy/4.cc
index 703adf81c415..91818f366735 100644
--- a/libstdc++-v3/testsuite/25_algorithms/copy/4.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/copy/4.cc
@@ -33,21 +33,29 @@ test01()
   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
-- 
GitLab