224 lines
7.5 KiB
C++
224 lines
7.5 KiB
C++
// -*- C++ -*-
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef _PSTL_GLUE_NUMERIC_IMPL_H
|
|
#define _PSTL_GLUE_NUMERIC_IMPL_H
|
|
|
|
#include <__config>
|
|
#include <functional>
|
|
|
|
#include "execution_impl.h"
|
|
#include "numeric_fwd.h"
|
|
#include "utils.h"
|
|
|
|
namespace std {
|
|
|
|
// [exclusive.scan]
|
|
|
|
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp>
|
|
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> exclusive_scan(
|
|
_ExecutionPolicy&& __exec,
|
|
_ForwardIterator1 __first,
|
|
_ForwardIterator1 __last,
|
|
_ForwardIterator2 __result,
|
|
_Tp __init) {
|
|
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
|
|
|
|
using namespace __pstl;
|
|
return __internal::__pattern_transform_scan(
|
|
__dispatch_tag,
|
|
std::forward<_ExecutionPolicy>(__exec),
|
|
__first,
|
|
__last,
|
|
__result,
|
|
__pstl::__internal::__no_op(),
|
|
__init,
|
|
std::plus<_Tp>(),
|
|
/*inclusive=*/std::false_type());
|
|
}
|
|
|
|
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation>
|
|
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> exclusive_scan(
|
|
_ExecutionPolicy&& __exec,
|
|
_ForwardIterator1 __first,
|
|
_ForwardIterator1 __last,
|
|
_ForwardIterator2 __result,
|
|
_Tp __init,
|
|
_BinaryOperation __binary_op) {
|
|
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
|
|
|
|
using namespace __pstl;
|
|
return __internal::__pattern_transform_scan(
|
|
__dispatch_tag,
|
|
std::forward<_ExecutionPolicy>(__exec),
|
|
__first,
|
|
__last,
|
|
__result,
|
|
__pstl::__internal::__no_op(),
|
|
__init,
|
|
__binary_op,
|
|
/*inclusive=*/std::false_type());
|
|
}
|
|
|
|
// [inclusive.scan]
|
|
|
|
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
|
|
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> inclusive_scan(
|
|
_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result) {
|
|
typedef typename iterator_traits<_ForwardIterator1>::value_type _InputType;
|
|
return transform_inclusive_scan(
|
|
std::forward<_ExecutionPolicy>(__exec),
|
|
__first,
|
|
__last,
|
|
__result,
|
|
std::plus<_InputType>(),
|
|
__pstl::__internal::__no_op());
|
|
}
|
|
|
|
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryOperation>
|
|
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> inclusive_scan(
|
|
_ExecutionPolicy&& __exec,
|
|
_ForwardIterator1 __first,
|
|
_ForwardIterator1 __last,
|
|
_ForwardIterator2 __result,
|
|
_BinaryOperation __binary_op) {
|
|
return transform_inclusive_scan(
|
|
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __binary_op, __pstl::__internal::__no_op());
|
|
}
|
|
|
|
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation>
|
|
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> inclusive_scan(
|
|
_ExecutionPolicy&& __exec,
|
|
_ForwardIterator1 __first,
|
|
_ForwardIterator1 __last,
|
|
_ForwardIterator2 __result,
|
|
_BinaryOperation __binary_op,
|
|
_Tp __init) {
|
|
return transform_inclusive_scan(
|
|
std::forward<_ExecutionPolicy>(__exec),
|
|
__first,
|
|
__last,
|
|
__result,
|
|
__binary_op,
|
|
__pstl::__internal::__no_op(),
|
|
__init);
|
|
}
|
|
|
|
// [transform.exclusive.scan]
|
|
|
|
template <class _ExecutionPolicy,
|
|
class _ForwardIterator1,
|
|
class _ForwardIterator2,
|
|
class _Tp,
|
|
class _BinaryOperation,
|
|
class _UnaryOperation>
|
|
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> transform_exclusive_scan(
|
|
_ExecutionPolicy&& __exec,
|
|
_ForwardIterator1 __first,
|
|
_ForwardIterator1 __last,
|
|
_ForwardIterator2 __result,
|
|
_Tp __init,
|
|
_BinaryOperation __binary_op,
|
|
_UnaryOperation __unary_op) {
|
|
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
|
|
|
|
return __pstl::__internal::__pattern_transform_scan(
|
|
__dispatch_tag,
|
|
std::forward<_ExecutionPolicy>(__exec),
|
|
__first,
|
|
__last,
|
|
__result,
|
|
__unary_op,
|
|
__init,
|
|
__binary_op,
|
|
/*inclusive=*/std::false_type());
|
|
}
|
|
|
|
// [transform.inclusive.scan]
|
|
|
|
template <class _ExecutionPolicy,
|
|
class _ForwardIterator1,
|
|
class _ForwardIterator2,
|
|
class _BinaryOperation,
|
|
class _UnaryOperation,
|
|
class _Tp>
|
|
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> transform_inclusive_scan(
|
|
_ExecutionPolicy&& __exec,
|
|
_ForwardIterator1 __first,
|
|
_ForwardIterator1 __last,
|
|
_ForwardIterator2 __result,
|
|
_BinaryOperation __binary_op,
|
|
_UnaryOperation __unary_op,
|
|
_Tp __init) {
|
|
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
|
|
|
|
return __pstl::__internal::__pattern_transform_scan(
|
|
__dispatch_tag,
|
|
std::forward<_ExecutionPolicy>(__exec),
|
|
__first,
|
|
__last,
|
|
__result,
|
|
__unary_op,
|
|
__init,
|
|
__binary_op,
|
|
/*inclusive=*/std::true_type());
|
|
}
|
|
|
|
template <class _ExecutionPolicy,
|
|
class _ForwardIterator1,
|
|
class _ForwardIterator2,
|
|
class _UnaryOperation,
|
|
class _BinaryOperation>
|
|
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> transform_inclusive_scan(
|
|
_ExecutionPolicy&& __exec,
|
|
_ForwardIterator1 __first,
|
|
_ForwardIterator1 __last,
|
|
_ForwardIterator2 __result,
|
|
_BinaryOperation __binary_op,
|
|
_UnaryOperation __unary_op) {
|
|
if (__first != __last) {
|
|
auto __tmp = __unary_op(*__first);
|
|
*__result = __tmp;
|
|
return transform_inclusive_scan(
|
|
std::forward<_ExecutionPolicy>(__exec), ++__first, __last, ++__result, __binary_op, __unary_op, __tmp);
|
|
} else {
|
|
return __result;
|
|
}
|
|
}
|
|
|
|
// [adjacent.difference]
|
|
|
|
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryOperation>
|
|
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> adjacent_difference(
|
|
_ExecutionPolicy&& __exec,
|
|
_ForwardIterator1 __first,
|
|
_ForwardIterator1 __last,
|
|
_ForwardIterator2 __d_first,
|
|
_BinaryOperation __op) {
|
|
if (__first == __last)
|
|
return __d_first;
|
|
|
|
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __d_first);
|
|
|
|
return __pstl::__internal::__pattern_adjacent_difference(
|
|
__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, __op);
|
|
}
|
|
|
|
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
|
|
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> adjacent_difference(
|
|
_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __d_first) {
|
|
typedef typename iterator_traits<_ForwardIterator1>::value_type _ValueType;
|
|
return adjacent_difference(
|
|
std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, std::minus<_ValueType>());
|
|
}
|
|
|
|
} // namespace std
|
|
|
|
#endif /* _PSTL_GLUE_NUMERIC_IMPL_H_ */
|