+2004-06-30 Gabriel Dos Reis <gdr@integrable-solutions.net>
+ Paolo Carlini <pcarlini@suse.de>
+
+ * include/bits/cpp_type_traits.h: Add __is_pointer and
+ __is_trivially_copyable.
+ * include/bits/stl_algobase.h (fill, fill_n): Slightly
+ tweak to use the latter.
+ (__copy_backward_dispatch): Remove.
+ (__copy_backward_aux): Rewrite to use __is_pointer and
+ __is_trivially_copyable and __copy_backward::copy_b.
+ (__copy_backward): Rewrite as a class template and two
+ specializations.
+
+2004-06-30 Paolo Carlini <pcarlini@suse.de>
+
+ * testsuite/25_algorithms/copy.cc: Move to...
+ * testsuite/25_algorithms/copy/1.cc: ... here, extend.
+ * testsuite/25_algorithms/copy/2.cc: New.
+ * testsuite/25_algorithms/copy/3.cc: New.
+ * testsuite/25_algorithms/copy/4.cc: New.
+
2004-06-29 Paul Brook <paul@codesourcery.com>
* libsupc++/vec.cc (__cxa_vec_new2, __cxa_vec_new3): Store the
};
};
+ //
+ // Pointer types
+ //
+ template<typename _Tp>
+ struct __is_pointer
+ {
+ enum
+ {
+ _M_type = 0
+ };
+ };
+
+ template<typename _Tp>
+ struct __is_pointer<_Tp*>
+ {
+ enum
+ {
+ _M_type = 1
+ };
+ };
+
//
// An arithmetic type is an integer type or a floating point type
//
};
};
+ //
+ // A trivially copyable type is an arithmetic type or a pointer type
+ //
+ template<typename _Tp>
+ struct __is_trivially_copyable
+ {
+ enum
+ {
+ _M_type = __is_arithmetic<_Tp>::_M_type || __is_pointer<_Tp>::_M_type
+ };
+ };
+
//
// For the immediate use, the following is a good approximation
//
#include <iosfwd>
#include <bits/stl_pair.h>
#include <bits/type_traits.h>
+#include <bits/cpp_type_traits.h>
#include <bits/stl_iterator_base_types.h>
#include <bits/stl_iterator_base_funcs.h>
#include <bits/stl_iterator.h>
typedef typename _Is_normal_iterator<_InputIterator>::_Normal __Normal;
return std::__copy_ni1(__first, __last, __result, __Normal());
}
-
- template<typename _BidirectionalIterator1, typename _BidirectionalIterator2>
- inline _BidirectionalIterator2
- __copy_backward(_BidirectionalIterator1 __first,
- _BidirectionalIterator1 __last,
- _BidirectionalIterator2 __result,
- bidirectional_iterator_tag)
- {
- while (__first != __last)
- *--__result = *--__last;
- return __result;
- }
-
- template<typename _RandomAccessIterator, typename _BidirectionalIterator>
- inline _BidirectionalIterator
- __copy_backward(_RandomAccessIterator __first, _RandomAccessIterator __last,
- _BidirectionalIterator __result, random_access_iterator_tag)
- {
- typename iterator_traits<_RandomAccessIterator>::difference_type __n;
- for (__n = __last - __first; __n > 0; --__n)
- *--__result = *--__last;
- return __result;
- }
-
-
- // This dispatch class is a workaround for compilers that do not
- // have partial ordering of function templates. All we're doing is
- // creating a specialization so that we can turn a call to copy_backward
- // into a memmove whenever possible.
- template<typename _BidirectionalIterator1, typename _BidirectionalIterator2,
- typename _BoolType>
- struct __copy_backward_dispatch
- {
- static _BidirectionalIterator2
- copy(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last,
- _BidirectionalIterator2 __result)
- { return std::__copy_backward(__first, __last, __result,
- std::__iterator_category(__first)); }
+
+ template<bool, typename>
+ struct __copy_backward
+ {
+ template<typename _BI1, typename _BI2>
+ static _BI2
+ copy_b(_BI1 __first, _BI1 __last, _BI2 __result)
+ {
+ while (__first != __last)
+ *--__result = *--__last;
+ return __result;
+ }
};
- template<typename _Tp>
- struct __copy_backward_dispatch<_Tp*, _Tp*, __true_type>
- {
- static _Tp*
- copy(const _Tp* __first, const _Tp* __last, _Tp* __result)
- {
- const ptrdiff_t _Num = __last - __first;
- std::memmove(__result - _Num, __first, sizeof(_Tp) * _Num);
- return __result - _Num;
- }
+ template<bool _BoolType>
+ struct __copy_backward<_BoolType, random_access_iterator_tag>
+ {
+ template<typename _BI1, typename _BI2>
+ static _BI2
+ copy_b(_BI1 __first, _BI1 __last, _BI2 __result)
+ {
+ typename iterator_traits<_BI1>::difference_type __n;
+ for (__n = __last - __first; __n > 0; --__n)
+ *--__result = *--__last;
+ return __result;
+ }
};
- template<typename _Tp>
- struct __copy_backward_dispatch<const _Tp*, _Tp*, __true_type>
- {
- static _Tp*
- copy(const _Tp* __first, const _Tp* __last, _Tp* __result)
- {
- return std::__copy_backward_dispatch<_Tp*, _Tp*, __true_type>
- ::copy(__first, __last, __result);
- }
+ template<>
+ struct __copy_backward<true, random_access_iterator_tag>
+ {
+ template<typename _Tp>
+ static _Tp*
+ copy_b(const _Tp* __first, const _Tp* __last, _Tp* __result)
+ {
+ const ptrdiff_t _Num = __last - __first;
+ std::memmove(__result - _Num, __first, sizeof(_Tp) * _Num);
+ return __result - _Num;
+ }
};
template<typename _BI1, typename _BI2>
inline _BI2
__copy_backward_aux(_BI1 __first, _BI1 __last, _BI2 __result)
{
- typedef typename __type_traits<typename iterator_traits<_BI2>::value_type>
- ::has_trivial_assignment_operator _Trivial;
- return
- std::__copy_backward_dispatch<_BI1, _BI2, _Trivial>::copy(__first,
- __last,
- __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>
__result, __Normal());
}
- template<typename>
+ template<bool>
struct __fill
{
template<typename _ForwardIterator, typename _Tp>
};
template<>
- struct __fill<__true_type>
+ struct __fill<true>
{
template<typename _ForwardIterator, typename _Tp>
static void
_ForwardIterator>)
__glibcxx_requires_valid_range(__first, __last);
- typedef typename __type_traits<_Tp>::has_trivial_copy_constructor
- _Trivial;
- std::__fill<_Trivial>::fill(__first, __last, __value);
+ const bool __trivial = __is_trivially_copyable<_Tp>::_M_type;
+ std::__fill<__trivial>::fill(__first, __last, __value);
}
// Specialization: for one-byte types we can use memset.
std::memset(__first, static_cast<unsigned char>(__tmp), __last - __first);
}
- template<typename>
+ template<bool>
struct __fill_n
{
template<typename _OutputIterator, typename _Size, typename _Tp>
};
template<>
- struct __fill_n<__true_type>
+ struct __fill_n<true>
{
template<typename _OutputIterator, typename _Size, typename _Tp>
static _OutputIterator
// concept requirements
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, _Tp>)
- typedef typename __type_traits<_Tp>::has_trivial_copy_constructor
- _Trivial;
- return std::__fill_n<_Trivial>::fill_n(__first, __n, __value);
+ const bool __trivial = __is_trivially_copyable<_Tp>::_M_type;
+ return std::__fill_n<__trivial>::fill_n(__first, __n, __value);
}
template<typename _Size>
+++ /dev/null
-// Copyright (C) 2001 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 2, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without Pred the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING. If not, write to the Free
-// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-// USA.
-
-// 25.2.12 [lib.alg.partitions] Partitions.
-
-#include <algorithm>
-#include <testsuite_hooks.h>
-
-bool test __attribute__((unused)) = true;
-
-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);
-
-// copy
-void
-test01()
-{
- using std::copy;
-
- int s1[N];
- copy(A, A + N, s1);
- VERIFY(std::equal(s1, s1 + N, A));
-}
-
-// copy_backward
-void
-test02()
-{
- using std::copy_backward;
-
- int s1[N];
- copy_backward(A, A + N, s1 + N);
- VERIFY(std::equal(s1, s1 + N, A));
-}
-
-int
-main()
-{
- test01();
- test02();
-
- return 0;
-}
--- /dev/null
+// Copyright (C) 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without Pred the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 25.2.1 [lib.alg.copy] Copy.
+
+#include <algorithm>
+#include <vector>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ using namespace std;
+ bool test __attribute__((unused)) = true;
+
+ 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
+main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// Copyright (C) 2004 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without Pred the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 25.2.1 [lib.alg.copy] Copy.
+
+#include <algorithm>
+#include <vector>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ using namespace std;
+ bool test __attribute__((unused)) = true;
+
+ 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);
+ 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
+main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// Copyright (C) 2004 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without Pred the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 25.2.1 [lib.alg.copy] Copy.
+
+#include <algorithm>
+#include <vector>
+#include <deque>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ using namespace std;
+ bool test __attribute__((unused)) = true;
+
+ 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);
+ 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
+main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// Copyright (C) 2004 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without Pred the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 25.2.1 [lib.alg.copy] Copy.
+
+#include <algorithm>
+#include <vector>
+#include <list>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ using namespace std;
+ bool test __attribute__((unused)) = true;
+
+ 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);
+ 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
+main()
+{
+ test01();
+ return 0;
+}