From badd64ad92b21a93d38da6ce99c559fff9a0ca0e Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Wed, 30 Jun 2004 09:20:18 +0000 Subject: [PATCH] [multiple changes] 2004-06-30 Gabriel Dos Reis Paolo Carlini * 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 * 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. From-SVN: r83897 --- libstdc++-v3/ChangeLog | 21 +++ libstdc++-v3/include/bits/cpp_type_traits.h | 33 +++++ libstdc++-v3/include/bits/stl_algobase.h | 125 ++++++++---------- .../25_algorithms/{copy.cc => copy/1.cc} | 48 ++++--- .../testsuite/25_algorithms/copy/2.cc | 57 ++++++++ .../testsuite/25_algorithms/copy/3.cc | 58 ++++++++ .../testsuite/25_algorithms/copy/4.cc | 58 ++++++++ 7 files changed, 302 insertions(+), 98 deletions(-) rename libstdc++-v3/testsuite/25_algorithms/{copy.cc => copy/1.cc} (61%) create mode 100644 libstdc++-v3/testsuite/25_algorithms/copy/2.cc create mode 100644 libstdc++-v3/testsuite/25_algorithms/copy/3.cc create mode 100644 libstdc++-v3/testsuite/25_algorithms/copy/4.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index e433113f1f2..92158acffc0 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,24 @@ +2004-06-30 Gabriel Dos Reis + Paolo Carlini + + * 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 + + * 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 * libsupc++/vec.cc (__cxa_vec_new2, __cxa_vec_new3): Store the diff --git a/libstdc++-v3/include/bits/cpp_type_traits.h b/libstdc++-v3/include/bits/cpp_type_traits.h index d4e4ea0410a..bf9254fd204 100644 --- a/libstdc++-v3/include/bits/cpp_type_traits.h +++ b/libstdc++-v3/include/bits/cpp_type_traits.h @@ -303,6 +303,27 @@ namespace std }; }; + // + // Pointer types + // + template + struct __is_pointer + { + enum + { + _M_type = 0 + }; + }; + + template + struct __is_pointer<_Tp*> + { + enum + { + _M_type = 1 + }; + }; + // // An arithmetic type is an integer type or a floating point type // @@ -327,6 +348,18 @@ namespace std }; }; + // + // A trivially copyable type is an arithmetic type or a pointer type + // + template + 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 // diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h index 0db0ef7daac..1b7c4b49ad5 100644 --- a/libstdc++-v3/include/bits/stl_algobase.h +++ b/libstdc++-v3/include/bits/stl_algobase.h @@ -70,6 +70,7 @@ #include #include #include +#include #include #include #include @@ -357,79 +358,59 @@ namespace std typedef typename _Is_normal_iterator<_InputIterator>::_Normal __Normal; return std::__copy_ni1(__first, __last, __result, __Normal()); } - - template - inline _BidirectionalIterator2 - __copy_backward(_BidirectionalIterator1 __first, - _BidirectionalIterator1 __last, - _BidirectionalIterator2 __result, - bidirectional_iterator_tag) - { - while (__first != __last) - *--__result = *--__last; - return __result; - } - - template - 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 - 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 + struct __copy_backward + { + template + static _BI2 + copy_b(_BI1 __first, _BI1 __last, _BI2 __result) + { + while (__first != __last) + *--__result = *--__last; + return __result; + } }; - template - 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 + struct __copy_backward<_BoolType, random_access_iterator_tag> + { + template + 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 - struct __copy_backward_dispatch - { - 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 + { + template + 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 inline _BI2 __copy_backward_aux(_BI1 __first, _BI1 __last, _BI2 __result) { - typedef typename __type_traits::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 @@ -499,7 +480,7 @@ namespace std __result, __Normal()); } - template + template struct __fill { template @@ -513,7 +494,7 @@ namespace std }; template<> - struct __fill<__true_type> + struct __fill { template static void @@ -546,9 +527,8 @@ namespace std _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. @@ -576,7 +556,7 @@ namespace std std::memset(__first, static_cast(__tmp), __last - __first); } - template + template struct __fill_n { template @@ -590,7 +570,7 @@ namespace std }; template<> - struct __fill_n<__true_type> + struct __fill_n { template static _OutputIterator @@ -621,9 +601,8 @@ namespace std // 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 diff --git a/libstdc++-v3/testsuite/25_algorithms/copy.cc b/libstdc++-v3/testsuite/25_algorithms/copy/1.cc similarity index 61% rename from libstdc++-v3/testsuite/25_algorithms/copy.cc rename to libstdc++-v3/testsuite/25_algorithms/copy/1.cc index 6e699113b58..8574522972d 100644 --- a/libstdc++-v3/testsuite/25_algorithms/copy.cc +++ b/libstdc++-v3/testsuite/25_algorithms/copy/1.cc @@ -16,43 +16,41 @@ // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, // USA. -// 25.2.12 [lib.alg.partitions] Partitions. +// 25.2.1 [lib.alg.copy] Copy. #include +#include #include -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)); + 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 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 v2(N); + copy_backward(A, A + N, v2.end()); + VERIFY( equal(v2.begin(), v2.end(), A) ); } int main() { test01(); - test02(); - return 0; } diff --git a/libstdc++-v3/testsuite/25_algorithms/copy/2.cc b/libstdc++-v3/testsuite/25_algorithms/copy/2.cc new file mode 100644 index 00000000000..d7bd1793e41 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/copy/2.cc @@ -0,0 +1,57 @@ +// 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 +#include +#include + +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 a(A, A + N); + + int s1[N]; + copy(a.begin(), a.end(), s1); + VERIFY( equal(s1, s1 + N, a.begin()) ); + + vector 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 v2(N); + copy_backward(a.begin(), a.end(), v2.end()); + VERIFY( equal(v2.begin(), v2.end(), a.begin()) ); +} + +int +main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/copy/3.cc b/libstdc++-v3/testsuite/25_algorithms/copy/3.cc new file mode 100644 index 00000000000..0453ce81632 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/copy/3.cc @@ -0,0 +1,58 @@ +// 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 +#include +#include +#include + +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 a(A, A + N); + + int s1[N]; + copy(a.begin(), a.end(), s1); + VERIFY( equal(s1, s1 + N, a.begin()) ); + + vector 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 v2(N); + copy_backward(a.begin(), a.end(), v2.end()); + VERIFY( equal(v2.begin(), v2.end(), a.begin()) ); +} + +int +main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/copy/4.cc b/libstdc++-v3/testsuite/25_algorithms/copy/4.cc new file mode 100644 index 00000000000..703adf81c41 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/copy/4.cc @@ -0,0 +1,58 @@ +// 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 +#include +#include +#include + +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 a(A, A + N); + + int s1[N]; + copy(a.begin(), a.end(), s1); + VERIFY( equal(s1, s1 + N, a.begin()) ); + + vector 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 v2(N); + copy_backward(a.begin(), a.end(), v2.end()); + VERIFY( equal(v2.begin(), v2.end(), a.begin()) ); +} + +int +main() +{ + test01(); + return 0; +} -- 2.30.2