xref: /llvm-project/libcxx/include/__numeric/pstl.h (revision 24e70e3930724ce499ad05d669bfbc4423c542e0)
1e406d5edSLouis Dionne //===----------------------------------------------------------------------===//
2e406d5edSLouis Dionne //
3e406d5edSLouis Dionne // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e406d5edSLouis Dionne // See https://llvm.org/LICENSE.txt for license information.
5e406d5edSLouis Dionne // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e406d5edSLouis Dionne //
7e406d5edSLouis Dionne //===----------------------------------------------------------------------===//
8e406d5edSLouis Dionne 
9e406d5edSLouis Dionne #ifndef _LIBCPP___NUMERIC_PSTL_H
10e406d5edSLouis Dionne #define _LIBCPP___NUMERIC_PSTL_H
11e406d5edSLouis Dionne 
12e406d5edSLouis Dionne #include <__config>
13acb896a3SLouis Dionne 
14acb896a3SLouis Dionne #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15acb896a3SLouis Dionne #  pragma GCC system_header
16acb896a3SLouis Dionne #endif
17acb896a3SLouis Dionne 
18acb896a3SLouis Dionne _LIBCPP_PUSH_MACROS
19acb896a3SLouis Dionne #include <__undef_macros>
20acb896a3SLouis Dionne 
21*24e70e39SNikolas Klauser #if _LIBCPP_HAS_EXPERIMENTAL_PSTL && _LIBCPP_STD_VER >= 17
22acb896a3SLouis Dionne 
23e406d5edSLouis Dionne #  include <__functional/identity.h>
24e406d5edSLouis Dionne #  include <__functional/operations.h>
25e406d5edSLouis Dionne #  include <__iterator/cpp17_iterator_concepts.h>
26e406d5edSLouis Dionne #  include <__iterator/iterator_traits.h>
279540950aSLouis Dionne #  include <__pstl/backend.h>
289540950aSLouis Dionne #  include <__pstl/dispatch.h>
299540950aSLouis Dionne #  include <__pstl/handle_exception.h>
309540950aSLouis Dionne #  include <__type_traits/enable_if.h>
31e406d5edSLouis Dionne #  include <__type_traits/is_execution_policy.h>
329540950aSLouis Dionne #  include <__type_traits/remove_cvref.h>
339540950aSLouis Dionne #  include <__utility/forward.h>
34e406d5edSLouis Dionne #  include <__utility/move.h>
35e406d5edSLouis Dionne 
36e406d5edSLouis Dionne _LIBCPP_BEGIN_NAMESPACE_STD
37e406d5edSLouis Dionne 
38e406d5edSLouis Dionne template <class _ExecutionPolicy,
399540950aSLouis Dionne           class _ForwardIterator,
40e406d5edSLouis Dionne           class _Tp,
419540950aSLouis Dionne           class _BinaryOperation,
42e406d5edSLouis Dionne           class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
43e406d5edSLouis Dionne           enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
449540950aSLouis Dionne _LIBCPP_HIDE_FROM_ABI _Tp reduce(
459540950aSLouis Dionne     _ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Tp __init, _BinaryOperation __op) {
469540950aSLouis Dionne   _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "reduce requires ForwardIterators");
479540950aSLouis Dionne   using _Implementation = __pstl::__dispatch<__pstl::__reduce, __pstl::__current_configuration, _RawPolicy>;
489540950aSLouis Dionne   return __pstl::__handle_exception<_Implementation>(
499540950aSLouis Dionne       std::forward<_ExecutionPolicy>(__policy),
509540950aSLouis Dionne       std::move(__first),
519540950aSLouis Dionne       std::move(__last),
52e406d5edSLouis Dionne       std::move(__init),
539540950aSLouis Dionne       std::move(__op));
549540950aSLouis Dionne }
559540950aSLouis Dionne 
569540950aSLouis Dionne template <class _ExecutionPolicy,
579540950aSLouis Dionne           class _ForwardIterator,
589540950aSLouis Dionne           class _Tp,
599540950aSLouis Dionne           class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
609540950aSLouis Dionne           enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
619540950aSLouis Dionne _LIBCPP_HIDE_FROM_ABI _Tp
629540950aSLouis Dionne reduce(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Tp __init) {
639540950aSLouis Dionne   _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "reduce requires ForwardIterators");
649540950aSLouis Dionne   using _Implementation = __pstl::__dispatch<__pstl::__reduce, __pstl::__current_configuration, _RawPolicy>;
659540950aSLouis Dionne   return __pstl::__handle_exception<_Implementation>(
669540950aSLouis Dionne       std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__init), plus{});
679540950aSLouis Dionne }
689540950aSLouis Dionne 
699540950aSLouis Dionne template <class _ExecutionPolicy,
709540950aSLouis Dionne           class _ForwardIterator,
719540950aSLouis Dionne           class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
729540950aSLouis Dionne           enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
739540950aSLouis Dionne _LIBCPP_HIDE_FROM_ABI __iter_value_type<_ForwardIterator>
749540950aSLouis Dionne reduce(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last) {
759540950aSLouis Dionne   _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "reduce requires ForwardIterators");
769540950aSLouis Dionne   using _Implementation = __pstl::__dispatch<__pstl::__reduce, __pstl::__current_configuration, _RawPolicy>;
779540950aSLouis Dionne   return __pstl::__handle_exception<_Implementation>(
789540950aSLouis Dionne       std::forward<_ExecutionPolicy>(__policy),
799540950aSLouis Dionne       std::move(__first),
809540950aSLouis Dionne       std::move(__last),
819540950aSLouis Dionne       __iter_value_type<_ForwardIterator>(),
829540950aSLouis Dionne       plus{});
83e406d5edSLouis Dionne }
84e406d5edSLouis Dionne 
85e406d5edSLouis Dionne template <class _ExecutionPolicy,
86e406d5edSLouis Dionne           class _ForwardIterator1,
87e406d5edSLouis Dionne           class _ForwardIterator2,
88e406d5edSLouis Dionne           class _Tp,
89e406d5edSLouis Dionne           class _BinaryOperation1,
90e406d5edSLouis Dionne           class _BinaryOperation2,
91e406d5edSLouis Dionne           class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
92e406d5edSLouis Dionne           enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
93e406d5edSLouis Dionne _LIBCPP_HIDE_FROM_ABI _Tp transform_reduce(
94e406d5edSLouis Dionne     _ExecutionPolicy&& __policy,
95e406d5edSLouis Dionne     _ForwardIterator1 __first1,
96e406d5edSLouis Dionne     _ForwardIterator1 __last1,
97e406d5edSLouis Dionne     _ForwardIterator2 __first2,
98e406d5edSLouis Dionne     _Tp __init,
99e406d5edSLouis Dionne     _BinaryOperation1 __reduce,
100e406d5edSLouis Dionne     _BinaryOperation2 __transform) {
101e406d5edSLouis Dionne   _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "transform_reduce requires ForwardIterators");
102e406d5edSLouis Dionne   _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "transform_reduce requires ForwardIterators");
1039540950aSLouis Dionne   using _Implementation =
1049540950aSLouis Dionne       __pstl::__dispatch<__pstl::__transform_reduce_binary, __pstl::__current_configuration, _RawPolicy>;
1059540950aSLouis Dionne   return __pstl::__handle_exception<_Implementation>(
1069540950aSLouis Dionne       std::forward<_ExecutionPolicy>(__policy),
107e406d5edSLouis Dionne       std::move(__first1),
108e406d5edSLouis Dionne       std::move(__last1),
109e406d5edSLouis Dionne       std::move(__first2),
110e406d5edSLouis Dionne       std::move(__init),
111e406d5edSLouis Dionne       std::move(__reduce),
112e406d5edSLouis Dionne       std::move(__transform));
113e406d5edSLouis Dionne }
114e406d5edSLouis Dionne 
115e406d5edSLouis Dionne // This overload doesn't get a customization point because it's trivial to detect (through e.g.
116e406d5edSLouis Dionne // __desugars_to_v) when specializing the more general variant, which should always be preferred
117e406d5edSLouis Dionne template <class _ExecutionPolicy,
118e406d5edSLouis Dionne           class _ForwardIterator1,
119e406d5edSLouis Dionne           class _ForwardIterator2,
120e406d5edSLouis Dionne           class _Tp,
1219540950aSLouis Dionne           class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
1229540950aSLouis Dionne           enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
123e406d5edSLouis Dionne _LIBCPP_HIDE_FROM_ABI _Tp transform_reduce(
124e406d5edSLouis Dionne     _ExecutionPolicy&& __policy,
125e406d5edSLouis Dionne     _ForwardIterator1 __first1,
126e406d5edSLouis Dionne     _ForwardIterator1 __last1,
127e406d5edSLouis Dionne     _ForwardIterator2 __first2,
128e406d5edSLouis Dionne     _Tp __init) {
129e406d5edSLouis Dionne   _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "transform_reduce requires ForwardIterators");
130e406d5edSLouis Dionne   _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "transform_reduce requires ForwardIterators");
1319540950aSLouis Dionne   using _Implementation =
1329540950aSLouis Dionne       __pstl::__dispatch<__pstl::__transform_reduce_binary, __pstl::__current_configuration, _RawPolicy>;
1339540950aSLouis Dionne   return __pstl::__handle_exception<_Implementation>(
1349540950aSLouis Dionne       std::forward<_ExecutionPolicy>(__policy),
1359540950aSLouis Dionne       std::move(__first1),
1369540950aSLouis Dionne       std::move(__last1),
1379540950aSLouis Dionne       std::move(__first2),
138e406d5edSLouis Dionne       std::move(__init),
1399540950aSLouis Dionne       plus{},
1409540950aSLouis Dionne       multiplies{});
141e406d5edSLouis Dionne }
142e406d5edSLouis Dionne 
143e406d5edSLouis Dionne template <class _ExecutionPolicy,
144e406d5edSLouis Dionne           class _ForwardIterator,
145e406d5edSLouis Dionne           class _Tp,
146e406d5edSLouis Dionne           class _BinaryOperation,
147e406d5edSLouis Dionne           class _UnaryOperation,
148e406d5edSLouis Dionne           class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
149e406d5edSLouis Dionne           enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
150e406d5edSLouis Dionne _LIBCPP_HIDE_FROM_ABI _Tp transform_reduce(
151e406d5edSLouis Dionne     _ExecutionPolicy&& __policy,
152e406d5edSLouis Dionne     _ForwardIterator __first,
153e406d5edSLouis Dionne     _ForwardIterator __last,
154e406d5edSLouis Dionne     _Tp __init,
155e406d5edSLouis Dionne     _BinaryOperation __reduce,
156e406d5edSLouis Dionne     _UnaryOperation __transform) {
157e406d5edSLouis Dionne   _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "transform_reduce requires ForwardIterators");
1589540950aSLouis Dionne   using _Implementation = __pstl::__dispatch<__pstl::__transform_reduce, __pstl::__current_configuration, _RawPolicy>;
1599540950aSLouis Dionne   return __pstl::__handle_exception<_Implementation>(
1609540950aSLouis Dionne       std::forward<_ExecutionPolicy>(__policy),
161e406d5edSLouis Dionne       std::move(__first),
162e406d5edSLouis Dionne       std::move(__last),
163e406d5edSLouis Dionne       std::move(__init),
1649540950aSLouis Dionne       std::move(__reduce),
1659540950aSLouis Dionne       std::move(__transform));
166e406d5edSLouis Dionne }
167e406d5edSLouis Dionne 
168e406d5edSLouis Dionne _LIBCPP_END_NAMESPACE_STD
169e406d5edSLouis Dionne 
170*24e70e39SNikolas Klauser #endif // _LIBCPP_HAS_EXPERIMENTAL_PSTL && _LIBCPP_STD_VER >= 17
171e406d5edSLouis Dionne 
172e406d5edSLouis Dionne _LIBCPP_POP_MACROS
173e406d5edSLouis Dionne 
174e406d5edSLouis Dionne #endif // _LIBCPP___NUMERIC_PSTL_H
175