Commit 0e6c9eaa by Johannes Singler Committed by Benjamin Kosnik

base.h: Added plus and multiplies functor for differently typed objects.

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.

From-SVN: r129140
parent 9de88093
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.
......
......@@ -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;
......
......@@ -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); }
};
}
......
......@@ -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.
......
......@@ -190,7 +190,7 @@ namespace __gnu_parallel
default:
// Partial_sum algorithm not implemented.
_GLIBCXX_PARALLEL_ASSERT(0);
return end;
return result + n;
}
}
}
......
// 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;
}
// 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment