OSDN Git Service

2007-10-08 Johannes Singler <singler@ira.uka.de>
authorbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 8 Oct 2007 21:14:45 +0000 (21:14 +0000)
committerbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 8 Oct 2007 21:14:45 +0000 (21:14 +0000)
* 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

libstdc++-v3/ChangeLog
libstdc++-v3/include/parallel/base.h
libstdc++-v3/include/parallel/for_each_selectors.h
libstdc++-v3/include/parallel/numeric
libstdc++-v3/include/parallel/partial_sum.h
libstdc++-v3/testsuite/26_numerics/accumulate/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/26_numerics/inner_product/1.cc [new file with mode: 0644]

index 834f6ee..90ea0bf 100644 (file)
@@ -1,3 +1,13 @@
+2007-10-08  Johannes Singler  <singler@ira.uka.de>
+
+       * 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  <pcarlini@suse.de>
 
        * include/bits/stl_move.h (_GLIBCXX_MOVE): Add.
index 12bba04..0a86d83 100644 (file)
@@ -112,14 +112,6 @@ namespace __gnu_parallel
   };
 
 
-  /** @brief Similar to std::equal_to, but allows two different types. */
-  template<typename T1, typename T2>
-  struct equal_to : std::binary_function<T1, T2, bool>
-  {
-    bool operator()(const T1& t1, const T2& t2) const
-    { return t1 == t2; }
-  };
-
   /** @brief Similar to std::binder1st, but giving the argument types explicitly. */
   template<typename _Predicate, typename argument_type>
     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<typename T1, typename T2>
+  struct equal_to : std::binary_function<T1, T2, bool>
+  {
+    bool operator()(const T1& t1, const T2& t2) const
+    { return t1 == t2; }
+  };
+
   /** @brief Similar to std::less, but allows two different types. */
   template<typename T1, typename T2>
   struct less : std::binary_function<T1, T2, bool>
@@ -212,6 +212,53 @@ namespace __gnu_parallel
       { return __x < __y; }
     };
 
+
+    /** @brief Similar to std::plus, but allows two different types. */
+  template<typename _Tp1, typename _Tp2>
+    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<typename _Tp>
+    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<typename _Tp1, typename _Tp2>
+    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<typename _Tp>
+    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<typename T, typename _DifferenceTp>
   class pseudo_sequence;
 
index f1d0abf..392cc6a 100644 (file)
@@ -335,8 +335,8 @@ namespace __gnu_parallel
 
     explicit accumulate_binop_reduct(BinOp& b) : binop(b) {}
 
-    template<typename T>
-    inline T operator()(T x, T y) { return binop(x, y); }
+    template<typename Result, typename Addend>
+    Result operator()(const Result& x, const Addend& y) { return binop(x, y); }
   };
 }
 
index 52fa600..21b8eea 100644 (file)
@@ -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<value_type>(), 
+    return accumulate_switch(begin, end, init, __gnu_parallel::plus<T, value_type>(),
                             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<value_type>(), 
+    return accumulate_switch(begin, end, init, __gnu_parallel::plus<T, value_type>(),
                             iterator_category());
   }
 
@@ -241,10 +241,17 @@ namespace __parallel
                InputIterator2 first2, T init, 
                __gnu_parallel::parallelism parallelism_tag)
   {
-    typedef iterator_traits<InputIterator1> traits_type;
-    typedef typename traits_type::value_type value_type;
-    return inner_product(first1, last1, first2, init, std::plus<value_type>(), 
-                        std::multiplies<value_type>(), parallelism_tag);
+    typedef iterator_traits<InputIterator1> traits_type1;
+    typedef typename traits_type1::value_type value_type1;
+    typedef iterator_traits<InputIterator2> traits_type2;
+    typedef typename traits_type2::value_type value_type2;
+
+    typedef typename __gnu_parallel::multiplies<value_type1, value_type2>::result
+        multiplies_result_type;
+    return inner_product(first1, last1, first2, init,
+                           __gnu_parallel::plus<T, multiplies_result_type>(),
+                           __gnu_parallel::multiplies<value_type1, value_type2>(),
+                           parallelism_tag);
   }
 
   template<typename InputIterator1, typename InputIterator2, typename T>
@@ -252,10 +259,16 @@ namespace __parallel
   inner_product(InputIterator1 first1, InputIterator1 last1, 
                InputIterator2 first2, T init)
   {
-    typedef iterator_traits<InputIterator1> traits_type;
-    typedef typename traits_type::value_type value_type;
-    return inner_product(first1, last1, first2, init, std::plus<value_type>(), 
-                        std::multiplies<value_type>());
+    typedef iterator_traits<InputIterator1> traits_type1;
+    typedef typename traits_type1::value_type value_type1;
+    typedef iterator_traits<InputIterator2> traits_type2;
+    typedef typename traits_type2::value_type value_type2;
+
+    typedef typename __gnu_parallel::multiplies<value_type1, value_type2>::result
+        multiplies_result_type;
+    return inner_product(first1, last1, first2, init,
+                           __gnu_parallel::plus<T, multiplies_result_type>(),
+                           __gnu_parallel::multiplies<value_type1, value_type2>());
   }
 
   // Sequential fallback.
index 31ded50..fbba686 100644 (file)
@@ -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 (file)
index 0000000..046532d
--- /dev/null
@@ -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 <numeric>
+#include <testsuite_hooks.h>
+
+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 (file)
index 0000000..d63c1d9
--- /dev/null
@@ -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 <numeric>
+#include <testsuite_hooks.h>
+
+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;
+}