1 // -*- C++ -*- 2 //===-- glue_numeric_impl.h -----------------------------------------------===// 3 // 4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 // See https://llvm.org/LICENSE.txt for license information. 6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef _PSTL_GLUE_NUMERIC_IMPL_H 11 #define _PSTL_GLUE_NUMERIC_IMPL_H 12 13 #include <functional> 14 15 #include "utils.h" 16 #include "numeric_fwd.h" 17 18 namespace std 19 { 20 21 // [reduce] 22 23 template <class _ExecutionPolicy, class _ForwardIterator, class _Tp, class _BinaryOperation> 24 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp> 25 reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Tp __init, 26 _BinaryOperation __binary_op) 27 { 28 return transform_reduce(std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, __binary_op, 29 __pstl::__internal::__no_op()); 30 } 31 32 template <class _ExecutionPolicy, class _ForwardIterator, class _Tp> 33 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp> 34 reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Tp __init) 35 { 36 return transform_reduce(std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, std::plus<_Tp>(), 37 __pstl::__internal::__no_op()); 38 } 39 40 template <class _ExecutionPolicy, class _ForwardIterator> 41 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, 42 typename iterator_traits<_ForwardIterator>::value_type> 43 reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) 44 { 45 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; 46 return transform_reduce(std::forward<_ExecutionPolicy>(__exec), __first, __last, _ValueType{}, 47 std::plus<_ValueType>(), __pstl::__internal::__no_op()); 48 } 49 50 // [transform.reduce] 51 52 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp> 53 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp> 54 transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, 55 _ForwardIterator2 __first2, _Tp __init) 56 { 57 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2); 58 59 typedef typename iterator_traits<_ForwardIterator1>::value_type _InputType; 60 return __pstl::__internal::__pattern_transform_reduce(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), 61 __first1, __last1, __first2, __init, std::plus<_InputType>(), 62 std::multiplies<_InputType>()); 63 } 64 65 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation1, 66 class _BinaryOperation2> 67 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp> 68 transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, 69 _ForwardIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2) 70 { 71 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2); 72 return __pstl::__internal::__pattern_transform_reduce(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), 73 __first1, __last1, __first2, __init, __binary_op1, 74 __binary_op2); 75 } 76 77 template <class _ExecutionPolicy, class _ForwardIterator, class _Tp, class _BinaryOperation, class _UnaryOperation> 78 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp> 79 transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Tp __init, 80 _BinaryOperation __binary_op, _UnaryOperation __unary_op) 81 { 82 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); 83 return __pstl::__internal::__pattern_transform_reduce(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), 84 __first, __last, __init, __binary_op, __unary_op); 85 } 86 87 // [exclusive.scan] 88 89 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp> 90 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> 91 exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, 92 _ForwardIterator2 __result, _Tp __init) 93 { 94 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); 95 96 using namespace __pstl; 97 return __internal::__pattern_transform_scan(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, 98 __result, __pstl::__internal::__no_op(), __init, std::plus<_Tp>(), 99 /*inclusive=*/std::false_type()); 100 } 101 102 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation> 103 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> 104 exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, 105 _ForwardIterator2 __result, _Tp __init, _BinaryOperation __binary_op) 106 { 107 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); 108 109 using namespace __pstl; 110 return __internal::__pattern_transform_scan(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, 111 __result, __pstl::__internal::__no_op(), std::move(__init), __binary_op, 112 /*inclusive=*/std::false_type()); 113 } 114 115 // [inclusive.scan] 116 117 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> 118 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> 119 inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, 120 _ForwardIterator2 __result) 121 { 122 typedef typename iterator_traits<_ForwardIterator1>::value_type _InputType; 123 return transform_inclusive_scan(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, 124 std::plus<_InputType>(), __pstl::__internal::__no_op()); 125 } 126 127 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryOperation> 128 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> 129 inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, 130 _ForwardIterator2 __result, _BinaryOperation __binary_op) 131 { 132 return transform_inclusive_scan(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __binary_op, 133 __pstl::__internal::__no_op()); 134 } 135 136 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation> 137 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> 138 inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, 139 _ForwardIterator2 __result, _BinaryOperation __binary_op, _Tp __init) 140 { 141 return transform_inclusive_scan(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __binary_op, 142 __pstl::__internal::__no_op(), __init); 143 } 144 145 // [transform.exclusive.scan] 146 147 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation, 148 class _UnaryOperation> 149 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> 150 transform_exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, 151 _ForwardIterator2 __result, _Tp __init, _BinaryOperation __binary_op, 152 _UnaryOperation __unary_op) 153 { 154 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); 155 156 return __pstl::__internal::__pattern_transform_scan(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, 157 __last, __result, __unary_op, __init, __binary_op, 158 /*inclusive=*/std::false_type()); 159 } 160 161 // [transform.inclusive.scan] 162 163 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryOperation, 164 class _UnaryOperation, class _Tp> 165 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> 166 transform_inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, 167 _ForwardIterator2 __result, _BinaryOperation __binary_op, _UnaryOperation __unary_op, 168 _Tp __init) 169 { 170 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); 171 172 return __pstl::__internal::__pattern_transform_scan(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, 173 __last, __result, __unary_op, __init, __binary_op, 174 /*inclusive=*/std::true_type()); 175 } 176 177 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _UnaryOperation, 178 class _BinaryOperation> 179 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> 180 transform_inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, 181 _ForwardIterator2 __result, _BinaryOperation __binary_op, _UnaryOperation __unary_op) 182 { 183 if (__first != __last) 184 { 185 auto __tmp = __unary_op(*__first); 186 *__result = __tmp; 187 return transform_inclusive_scan(std::forward<_ExecutionPolicy>(__exec), ++__first, __last, ++__result, 188 __binary_op, __unary_op, __tmp); 189 } 190 else 191 { 192 return __result; 193 } 194 } 195 196 // [adjacent.difference] 197 198 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryOperation> 199 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> 200 adjacent_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, 201 _ForwardIterator2 __d_first, _BinaryOperation __op) 202 { 203 204 if (__first == __last) 205 return __d_first; 206 207 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __d_first); 208 209 return __pstl::__internal::__pattern_adjacent_difference(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), 210 __first, __last, __d_first, __op); 211 } 212 213 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> 214 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> 215 adjacent_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, 216 _ForwardIterator2 __d_first) 217 { 218 typedef typename iterator_traits<_ForwardIterator1>::value_type _ValueType; 219 return adjacent_difference(std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, 220 std::minus<_ValueType>()); 221 } 222 223 } // namespace std 224 225 #endif /* _PSTL_GLUE_NUMERIC_IMPL_H_ */ 226