BillyONeal updated this revision to Diff 128695.
BillyONeal added a comment.
Moved things to MoveOnly.h.
https://reviews.llvm.org/D41372
Files:
include/numeric
test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_init_bop_uop.pass.cpp
test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init.pass.cpp
test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init_op_op.pass.cpp
test/support/MoveOnly.h
Index: test/support/MoveOnly.h
===================================================================
--- test/support/MoveOnly.h
+++ test/support/MoveOnly.h
@@ -19,7 +19,6 @@
class MoveOnly
{
- friend class MoveOnly2;
MoveOnly(const MoveOnly&);
MoveOnly& operator=(const MoveOnly&);
@@ -35,6 +34,8 @@
bool operator==(const MoveOnly& x) const {return data_ == x.data_;}
bool operator< (const MoveOnly& x) const {return data_ < x.data_;}
+ MoveOnly operator+(const MoveOnly& x) const { return MoveOnly{data_ + x.data_}; }
+ MoveOnly operator*(const MoveOnly& x) const { return MoveOnly{data_ * x.data_}; }
};
namespace std {
Index: test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init_op_op.pass.cpp
===================================================================
--- test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init_op_op.pass.cpp
+++ test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init_op_op.pass.cpp
@@ -19,7 +19,9 @@
#include <numeric>
#include <cassert>
+#include <iterator>
+#include "MoveOnly.h"
#include "test_iterators.h"
template <class Iter1, class Iter2, class T, class Op1, class Op2>
@@ -58,6 +60,16 @@
decltype(std::transform_reduce(p, p, p, Init{}, std::plus<>(), std::multiplies<>()))> );
}
+void test_move_only_types()
+{
+ MoveOnly ia[] = {{1}, {2}, {3}};
+ MoveOnly ib[] = {{1}, {2}, {3}};
+ assert(14 ==
+ std::transform_reduce(std::begin(ia), std::end(ia), std::begin(ib), MoveOnly{0},
+ [](const MoveOnly& lhs, const MoveOnly& rhs) { return MoveOnly{lhs.get() + rhs.get()}; },
+ [](const MoveOnly& lhs, const MoveOnly& rhs) { return MoveOnly{lhs.get() * rhs.get()}; }).get());
+}
+
int main()
{
test_return_type<char, int>();
@@ -94,4 +106,6 @@
test<const int*, unsigned int *>();
test< int*, const unsigned int *>();
test< int*, unsigned int *>();
+
+ test_move_only_types();
}
Index: test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init.pass.cpp
===================================================================
--- test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init.pass.cpp
+++ test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init.pass.cpp
@@ -17,7 +17,9 @@
#include <numeric>
#include <cassert>
+#include <iterator>
+#include "MoveOnly.h"
#include "test_iterators.h"
template <class Iter1, class Iter2, class T>
@@ -56,6 +58,14 @@
decltype(std::transform_reduce(p, p, p, Init{}))> );
}
+void test_move_only_types()
+{
+ MoveOnly ia[] = {{1}, {2}, {3}};
+ MoveOnly ib[] = {{1}, {2}, {3}};
+ assert(14 ==
+ std::transform_reduce(std::begin(ia), std::end(ia), std::begin(ib), MoveOnly{0}).get());
+}
+
int main()
{
test_return_type<char, int>();
@@ -92,4 +102,6 @@
test<const int*, unsigned int *>();
test< int*, const unsigned int *>();
test< int*, unsigned int *>();
+
+ test_move_only_types();
}
Index: test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_init_bop_uop.pass.cpp
===================================================================
--- test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_init_bop_uop.pass.cpp
+++ test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_init_bop_uop.pass.cpp
@@ -18,40 +18,26 @@
#include <numeric>
#include <cassert>
+#include <utility>
+#include <iterator>
+#include "MoveOnly.h"
#include "test_iterators.h"
-template <class T = void>
-struct identity : std::unary_function<T, T>
-{
- constexpr const T& operator()(const T& x) const { return x;}
-};
-
-template <>
-struct identity<void>
+struct identity
{
template <class T>
- constexpr auto operator()(T&& x) const
- _NOEXCEPT_(noexcept(_VSTD::forward<T>(x)))
- -> decltype (_VSTD::forward<T>(x))
- { return _VSTD::forward<T>(x); }
+ constexpr decltype(auto) operator()(T&& x) const {
+ return std::forward<T>(x);
+ }
};
-
-template <class T = void>
struct twice
-{
- constexpr const T operator()(const T& x) const noexcept { return 2 * x; }
-};
-
-template <>
-struct twice<void>
{
template <class T>
- constexpr auto operator()(const T& x) const
- _NOEXCEPT_(noexcept(2 * x))
- -> decltype (2 * x)
- { return 2 * x; }
+ constexpr auto operator()(const T& x) const {
+ return 2 * x;
+ }
};
template <class Iter1, class T, class BOp, class UOp>
@@ -70,31 +56,40 @@
int ia[] = {1, 2, 3, 4, 5, 6};
unsigned sa = sizeof(ia) / sizeof(ia[0]);
- test(Iter(ia), Iter(ia), 0, std::plus<>(), identity<>(), 0);
- test(Iter(ia), Iter(ia), 1, std::multiplies<>(), identity<>(), 1);
- test(Iter(ia), Iter(ia+1), 0, std::multiplies<>(), identity<>(), 0);
- test(Iter(ia), Iter(ia+1), 2, std::plus<>(), identity<>(), 3);
- test(Iter(ia), Iter(ia+2), 0, std::plus<>(), identity<>(), 3);
- test(Iter(ia), Iter(ia+2), 3, std::multiplies<>(), identity<>(), 6);
- test(Iter(ia), Iter(ia+sa), 4, std::multiplies<>(), identity<>(), 2880);
- test(Iter(ia), Iter(ia+sa), 4, std::plus<>(), identity<>(), 25);
-
- test(Iter(ia), Iter(ia), 0, std::plus<>(), twice<>(), 0);
- test(Iter(ia), Iter(ia), 1, std::multiplies<>(), twice<>(), 1);
- test(Iter(ia), Iter(ia+1), 0, std::multiplies<>(), twice<>(), 0);
- test(Iter(ia), Iter(ia+1), 2, std::plus<>(), twice<>(), 4);
- test(Iter(ia), Iter(ia+2), 0, std::plus<>(), twice<>(), 6);
- test(Iter(ia), Iter(ia+2), 3, std::multiplies<>(), twice<>(), 24);
- test(Iter(ia), Iter(ia+sa), 4, std::multiplies<>(), twice<>(), 184320); // 64 * 2880
- test(Iter(ia), Iter(ia+sa), 4, std::plus<>(), twice<>(), 46);
+ test(Iter(ia), Iter(ia), 0, std::plus<>(), identity(), 0);
+ test(Iter(ia), Iter(ia), 1, std::multiplies<>(), identity(), 1);
+ test(Iter(ia), Iter(ia+1), 0, std::multiplies<>(), identity(), 0);
+ test(Iter(ia), Iter(ia+1), 2, std::plus<>(), identity(), 3);
+ test(Iter(ia), Iter(ia+2), 0, std::plus<>(), identity(), 3);
+ test(Iter(ia), Iter(ia+2), 3, std::multiplies<>(), identity(), 6);
+ test(Iter(ia), Iter(ia+sa), 4, std::multiplies<>(), identity(), 2880);
+ test(Iter(ia), Iter(ia+sa), 4, std::plus<>(), identity(), 25);
+
+ test(Iter(ia), Iter(ia), 0, std::plus<>(), twice(), 0);
+ test(Iter(ia), Iter(ia), 1, std::multiplies<>(), twice(), 1);
+ test(Iter(ia), Iter(ia+1), 0, std::multiplies<>(), twice(), 0);
+ test(Iter(ia), Iter(ia+1), 2, std::plus<>(), twice(), 4);
+ test(Iter(ia), Iter(ia+2), 0, std::plus<>(), twice(), 6);
+ test(Iter(ia), Iter(ia+2), 3, std::multiplies<>(), twice(), 24);
+ test(Iter(ia), Iter(ia+sa), 4, std::multiplies<>(), twice(), 184320); // 64 * 2880
+ test(Iter(ia), Iter(ia+sa), 4, std::plus<>(), twice(), 46);
}
template <typename T, typename Init>
void test_return_type()
{
T *p = nullptr;
static_assert( std::is_same_v<Init,
- decltype(std::transform_reduce(p, p, Init{}, std::plus<>(), identity<>()))> );
+ decltype(std::transform_reduce(p, p, Init{}, std::plus<>(), identity()))> );
+}
+
+void test_move_only_types()
+{
+ MoveOnly ia[] = {{1}, {2}, {3}};
+ assert(60 ==
+ std::transform_reduce(std::begin(ia), std::end(ia), MoveOnly{0},
+ [](const MoveOnly& lhs, const MoveOnly& rhs) { return MoveOnly{lhs.get() + rhs.get()}; },
+ [](const MoveOnly& target) { return MoveOnly{target.get() * 10}; }).get());
}
int main()
@@ -118,7 +113,9 @@
// Make sure the math is done using the correct type
{
auto v = {1, 2, 3, 4, 5, 6};
- unsigned res = std::transform_reduce(v.begin(), v.end(), 1U, std::multiplies<>(), twice<>());
+ unsigned res = std::transform_reduce(v.begin(), v.end(), 1U, std::multiplies<>(), twice());
assert(res == 46080); // 6! * 64 will not fit into a char
}
+
+ test_move_only_types();
}
Index: include/numeric
===================================================================
--- include/numeric
+++ include/numeric
@@ -51,7 +51,7 @@
T
transform_reduce(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, T init); // C++17
-
+
template<class InputIterator1, class InputIterator2, class T, class BinaryOperation1, class BinaryOperation2>
T
transform_reduce(InputIterator1 first1, InputIterator1 last1,
@@ -75,10 +75,10 @@
OutputIterator
exclusive_scan(InputIterator first, InputIterator last,
OutputIterator result, T init); // C++17
-
+
template<class InputIterator, class OutputIterator, class T, class BinaryOperation>
OutputIterator
- exclusive_scan(InputIterator first, InputIterator last,
+ exclusive_scan(InputIterator first, InputIterator last,
OutputIterator result, T init, BinaryOperation binary_op); // C++17
template<class InputIterator, class OutputIterator>
@@ -108,7 +108,7 @@
transform_inclusive_scan(InputIterator first, InputIterator last,
OutputIterator result,
BinaryOperation binary_op, UnaryOperation unary_op); // C++17
-
+
template<class InputIterator, class OutputIterator,
class BinaryOperation, class UnaryOperation, class T>
OutputIterator
@@ -196,7 +196,7 @@
typename iterator_traits<_InputIterator>::value_type
reduce(_InputIterator __first, _InputIterator __last)
{
- return _VSTD::reduce(__first, __last,
+ return _VSTD::reduce(__first, __last,
typename iterator_traits<_InputIterator>::value_type{});
}
#endif
@@ -226,15 +226,15 @@
template <class _InputIterator, class _Tp, class _BinaryOp, class _UnaryOp>
inline _LIBCPP_INLINE_VISIBILITY
_Tp
-transform_reduce(_InputIterator __first, _InputIterator __last,
+transform_reduce(_InputIterator __first, _InputIterator __last,
_Tp __init, _BinaryOp __b, _UnaryOp __u)
{
for (; __first != __last; ++__first)
__init = __b(__init, __u(*__first));
return __init;
}
-template <class _InputIterator1, class _InputIterator2,
+template <class _InputIterator1, class _InputIterator2,
class _Tp, class _BinaryOp1, class _BinaryOp2>
inline _LIBCPP_INLINE_VISIBILITY
_Tp
@@ -249,10 +249,10 @@
template <class _InputIterator1, class _InputIterator2, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
_Tp
-transform_reduce(_InputIterator1 __first1, _InputIterator1 __last1,
+transform_reduce(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _Tp __init)
{
- return _VSTD::transform_reduce(__first1, __last1, __first2, __init,
+ return _VSTD::transform_reduce(__first1, __last1, __first2, _VSTD::move(__init),
_VSTD::plus<>(), _VSTD::multiplies<>());
}
#endif
@@ -298,7 +298,7 @@
template <class _InputIterator, class _OutputIterator, class _Tp, class _BinaryOp>
inline _LIBCPP_INLINE_VISIBILITY
_OutputIterator
-exclusive_scan(_InputIterator __first, _InputIterator __last,
+exclusive_scan(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, _Tp __init, _BinaryOp __b)
{
if (__first != __last)
@@ -318,14 +318,14 @@
template <class _InputIterator, class _OutputIterator, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
_OutputIterator
-exclusive_scan(_InputIterator __first, _InputIterator __last,
+exclusive_scan(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, _Tp __init)
{
return _VSTD::exclusive_scan(__first, __last, __result, __init, _VSTD::plus<>());
}
template <class _InputIterator, class _OutputIterator, class _Tp, class _BinaryOp>
-_OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last,
+_OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, _BinaryOp __b, _Tp __init)
{
for (; __first != __last; ++__first, (void) ++__result) {
@@ -336,7 +336,7 @@
}
template <class _InputIterator, class _OutputIterator, class _BinaryOp>
-_OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last,
+_OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, _BinaryOp __b)
{
if (__first != __last) {
@@ -350,17 +350,17 @@
}
template <class _InputIterator, class _OutputIterator>
-_OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last,
+_OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last,
_OutputIterator __result)
{
return _VSTD::inclusive_scan(__first, __last, __result, std::plus<>());
}
-template <class _InputIterator, class _OutputIterator, class _Tp,
+template <class _InputIterator, class _OutputIterator, class _Tp,
class _BinaryOp, class _UnaryOp>
inline _LIBCPP_INLINE_VISIBILITY
_OutputIterator
-transform_exclusive_scan(_InputIterator __first, _InputIterator __last,
+transform_exclusive_scan(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, _Tp __init,
_BinaryOp __b, _UnaryOp __u)
{
@@ -379,7 +379,7 @@
}
template <class _InputIterator, class _OutputIterator, class _Tp, class _BinaryOp, class _UnaryOp>
-_OutputIterator transform_inclusive_scan(_InputIterator __first, _InputIterator __last,
+_OutputIterator transform_inclusive_scan(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, _BinaryOp __b, _UnaryOp __u, _Tp __init)
{
for (; __first != __last; ++__first, (void) ++__result) {
@@ -391,16 +391,16 @@
}
template <class _InputIterator, class _OutputIterator, class _BinaryOp, class _UnaryOp>
-_OutputIterator transform_inclusive_scan(_InputIterator __first, _InputIterator __last,
+_OutputIterator transform_inclusive_scan(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, _BinaryOp __b, _UnaryOp __u)
{
if (__first != __last) {
typename std::iterator_traits<_InputIterator>::value_type __init = __u(*__first);
*__result++ = __init;
if (++__first != __last)
return _VSTD::transform_inclusive_scan(__first, __last, __result, __b, __u, __init);
}
-
+
return __result;
}
#endif
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits