From: bkoz Date: Mon, 8 Oct 2007 21:14:45 +0000 (+0000) Subject: 2007-10-08 Johannes Singler X-Git-Url: http://git.sourceforge.jp/view?a=commitdiff_plain;h=a3f1bfe44de645a8a22743ed4156143af45bcada;p=pf3gnuchains%2Fgcc-fork.git 2007-10-08 Johannes Singler * include/parallel/base.h: Added plus and multiplies functor for differently typed objects. * include/parallel/numeric: Use it. * include/parallel/for_each_selectors.h: Allowed different types. * include/parallel/partial_sum.h: Fixed return value. * testsuite/26_numerics/accumulate/1.cc: Tests for accumulate. * testsuite/26_numerics/inner_product/1.cc: Tests for inner_product. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@129140 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 834f6ee4442..90ea0bf8155 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,13 @@ +2007-10-08 Johannes Singler + + * include/parallel/base.h: Added plus and multiplies functor + for differently typed objects. + * include/parallel/numeric: Use it. + * include/parallel/for_each_selectors.h: Allowed different types. + * include/parallel/partial_sum.h: Fixed return value. + * testsuite/26_numerics/accumulate/1.cc: Tests for accumulate. + * testsuite/26_numerics/inner_product/1.cc: Tests for inner_product. + 2007-10-08 Paolo Carlini * include/bits/stl_move.h (_GLIBCXX_MOVE): Add. diff --git a/libstdc++-v3/include/parallel/base.h b/libstdc++-v3/include/parallel/base.h index 12bba0455fc..0a86d8351fe 100644 --- a/libstdc++-v3/include/parallel/base.h +++ b/libstdc++-v3/include/parallel/base.h @@ -112,14 +112,6 @@ namespace __gnu_parallel }; - /** @brief Similar to std::equal_to, but allows two different types. */ - template - struct equal_to : std::binary_function - { - bool operator()(const T1& t1, const T2& t2) const - { return t1 == t2; } - }; - /** @brief Similar to std::binder1st, but giving the argument types explicitly. */ template class unary_negate @@ -190,6 +182,14 @@ namespace __gnu_parallel { return op(__x, value); } }; + /** @brief Similar to std::equal_to, but allows two different types. */ + template + struct equal_to : std::binary_function + { + bool operator()(const T1& t1, const T2& t2) const + { return t1 == t2; } + }; + /** @brief Similar to std::less, but allows two different types. */ template struct less : std::binary_function @@ -212,6 +212,53 @@ namespace __gnu_parallel { return __x < __y; } }; + + /** @brief Similar to std::plus, but allows two different types. */ + template + struct plus : public std::binary_function<_Tp1, _Tp2, _Tp1> + { + typedef typeof(*static_cast<_Tp1*>(NULL) + *static_cast<_Tp2*>(NULL)) result; + + result + operator()(const _Tp1& __x, const _Tp2& __y) const + { return __x + __y; } + }; + + // Partial specialization for one type. Same as std::plus. + template + struct plus<_Tp, _Tp> : public std::binary_function<_Tp, _Tp, _Tp> + { + typedef typeof(*static_cast<_Tp*>(NULL) + *static_cast<_Tp*>(NULL)) result; + + result + operator()(const _Tp& __x, const _Tp& __y) const + { return __x + __y; } + }; + + + /** @brief Similar to std::multiplies, but allows two different types. */ + template + struct multiplies : public std::binary_function<_Tp1, _Tp2, _Tp1> + { + typedef typeof(*static_cast<_Tp1*>(NULL) * *static_cast<_Tp2*>(NULL)) result; + + result + operator()(const _Tp1& __x, const _Tp2& __y) const + { return __x * __y; } + }; + + // Partial specialization for one type. Same as std::multiplies. + template + struct multiplies<_Tp, _Tp> : public std::binary_function<_Tp, _Tp, _Tp> + { + typedef typeof(*static_cast<_Tp*>(NULL) * *static_cast<_Tp*>(NULL)) result; + + result + operator()(const _Tp& __x, const _Tp& __y) const + { return __x * __y; } + }; + + template class pseudo_sequence; diff --git a/libstdc++-v3/include/parallel/for_each_selectors.h b/libstdc++-v3/include/parallel/for_each_selectors.h index f1d0abf255b..392cc6ac7ea 100644 --- a/libstdc++-v3/include/parallel/for_each_selectors.h +++ b/libstdc++-v3/include/parallel/for_each_selectors.h @@ -335,8 +335,8 @@ namespace __gnu_parallel explicit accumulate_binop_reduct(BinOp& b) : binop(b) {} - template - inline T operator()(T x, T y) { return binop(x, y); } + template + Result operator()(const Result& x, const Addend& y) { return binop(x, y); } }; } diff --git a/libstdc++-v3/include/parallel/numeric b/libstdc++-v3/include/parallel/numeric index 52fa600ddba..21b8eea3fdd 100644 --- a/libstdc++-v3/include/parallel/numeric +++ b/libstdc++-v3/include/parallel/numeric @@ -114,7 +114,7 @@ namespace __parallel typedef typename iterator_traits::value_type value_type; typedef typename iterator_traits::iterator_category iterator_category; - return accumulate_switch(begin, end, init, std::plus(), + return accumulate_switch(begin, end, init, __gnu_parallel::plus(), iterator_category(), parallelism_tag); } @@ -126,7 +126,7 @@ namespace __parallel typedef typename iterator_traits::value_type value_type; typedef typename iterator_traits::iterator_category iterator_category; - return accumulate_switch(begin, end, init, std::plus(), + return accumulate_switch(begin, end, init, __gnu_parallel::plus(), iterator_category()); } @@ -241,10 +241,17 @@ namespace __parallel InputIterator2 first2, T init, __gnu_parallel::parallelism parallelism_tag) { - typedef iterator_traits traits_type; - typedef typename traits_type::value_type value_type; - return inner_product(first1, last1, first2, init, std::plus(), - std::multiplies(), parallelism_tag); + typedef iterator_traits traits_type1; + typedef typename traits_type1::value_type value_type1; + typedef iterator_traits traits_type2; + typedef typename traits_type2::value_type value_type2; + + typedef typename __gnu_parallel::multiplies::result + multiplies_result_type; + return inner_product(first1, last1, first2, init, + __gnu_parallel::plus(), + __gnu_parallel::multiplies(), + parallelism_tag); } template @@ -252,10 +259,16 @@ namespace __parallel inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init) { - typedef iterator_traits traits_type; - typedef typename traits_type::value_type value_type; - return inner_product(first1, last1, first2, init, std::plus(), - std::multiplies()); + typedef iterator_traits traits_type1; + typedef typename traits_type1::value_type value_type1; + typedef iterator_traits traits_type2; + typedef typename traits_type2::value_type value_type2; + + typedef typename __gnu_parallel::multiplies::result + multiplies_result_type; + return inner_product(first1, last1, first2, init, + __gnu_parallel::plus(), + __gnu_parallel::multiplies()); } // Sequential fallback. diff --git a/libstdc++-v3/include/parallel/partial_sum.h b/libstdc++-v3/include/parallel/partial_sum.h index 31ded50733b..fbba6860184 100644 --- a/libstdc++-v3/include/parallel/partial_sum.h +++ b/libstdc++-v3/include/parallel/partial_sum.h @@ -190,7 +190,7 @@ namespace __gnu_parallel default: // Partial_sum algorithm not implemented. _GLIBCXX_PARALLEL_ASSERT(0); - return end; + return result + n; } } } diff --git a/libstdc++-v3/testsuite/26_numerics/accumulate/1.cc b/libstdc++-v3/testsuite/26_numerics/accumulate/1.cc new file mode 100644 index 00000000000..046532debef --- /dev/null +++ b/libstdc++-v3/testsuite/26_numerics/accumulate/1.cc @@ -0,0 +1,54 @@ +// Copyright (C) 2001, 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 even 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// 26.4.1 [lib.accumulate] + +#include +#include + +int A[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; +const int NA = sizeof(A) / sizeof(int); + +void +test01() +{ + bool test __attribute__((unused)) = true; + + int res = std::accumulate(A, A + NA, 11); + VERIFY( res == 66 ); +} + +bool B[] = {true, false, true, true, false, true, false, true, true, false}; +const int NB = sizeof(B) / sizeof(bool); + +void +test02() +{ + bool test __attribute__((unused)) = true; + + int res = std::accumulate(B, B + NB, 100); + VERIFY( res == 106 ); +} + +int +main() +{ + test01(); + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/26_numerics/inner_product/1.cc b/libstdc++-v3/testsuite/26_numerics/inner_product/1.cc new file mode 100644 index 00000000000..d63c1d91099 --- /dev/null +++ b/libstdc++-v3/testsuite/26_numerics/inner_product/1.cc @@ -0,0 +1,56 @@ +// Copyright (C) 2001, 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 even 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// 26.4.2 [lib.inner_product] + +#include +#include + +int A1[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; +int A2[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29}; +const int NA = sizeof(A1) / sizeof(int); + +bool B1[] = {false, true, true, false, true, false, true, true, false, true}; +bool B2[] = {true, false, true, true, false, true, false, true, true, false}; +const int NB = sizeof(B1) / sizeof(bool); + +void +test01() +{ + bool test __attribute__((unused)) = true; + + int res = std::inner_product(A1, A1 + NA, A2, 31); + VERIFY( res == 983 ); +} + +void +test02() +{ + bool test __attribute__((unused)) = true; + + int res = std::inner_product(B1, B1 + NB, B2, 100); + VERIFY( res == 102 ); +} + +int +main() +{ + test01(); + test02(); + return 0; +}