1181254a7Smrg // -*- C++ -*-
2181254a7Smrg //===-- execution_impl.h --------------------------------------------------===//
3181254a7Smrg //
4181254a7Smrg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5181254a7Smrg // See https://llvm.org/LICENSE.txt for license information.
6181254a7Smrg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7181254a7Smrg //
8181254a7Smrg //===----------------------------------------------------------------------===//
9181254a7Smrg
10fb8a8121Smrg #ifndef _PSTL_EXECUTION_IMPL_H
11fb8a8121Smrg #define _PSTL_EXECUTION_IMPL_H
12181254a7Smrg
13181254a7Smrg #include <iterator>
14181254a7Smrg #include <type_traits>
15181254a7Smrg
16181254a7Smrg #include "execution_defs.h"
17181254a7Smrg
18181254a7Smrg namespace __pstl
19181254a7Smrg {
20181254a7Smrg namespace __internal
21181254a7Smrg {
22181254a7Smrg
23181254a7Smrg using namespace __pstl::execution;
24181254a7Smrg
25181254a7Smrg /* predicate */
26181254a7Smrg
27181254a7Smrg template <typename _Tp>
__lazy_and(_Tp,std::false_type)28181254a7Smrg std::false_type __lazy_and(_Tp, std::false_type)
29181254a7Smrg {
30181254a7Smrg return std::false_type{};
31*b1e83836Smrg }
32181254a7Smrg
33181254a7Smrg template <typename _Tp>
34181254a7Smrg inline _Tp
__lazy_and(_Tp __a,std::true_type)35181254a7Smrg __lazy_and(_Tp __a, std::true_type)
36181254a7Smrg {
37181254a7Smrg return __a;
38181254a7Smrg }
39181254a7Smrg
40181254a7Smrg template <typename _Tp>
__lazy_or(_Tp,std::true_type)41181254a7Smrg std::true_type __lazy_or(_Tp, std::true_type)
42181254a7Smrg {
43181254a7Smrg return std::true_type{};
44*b1e83836Smrg }
45181254a7Smrg
46181254a7Smrg template <typename _Tp>
47181254a7Smrg inline _Tp
__lazy_or(_Tp __a,std::false_type)48181254a7Smrg __lazy_or(_Tp __a, std::false_type)
49181254a7Smrg {
50181254a7Smrg return __a;
51181254a7Smrg }
52181254a7Smrg
53181254a7Smrg /* iterator */
54181254a7Smrg template <typename _IteratorType, typename... _OtherIteratorTypes>
55181254a7Smrg struct __is_random_access_iterator
56181254a7Smrg {
57fb8a8121Smrg static constexpr bool value = __internal::__is_random_access_iterator<_IteratorType>::value &&
58fb8a8121Smrg __internal::__is_random_access_iterator<_OtherIteratorTypes...>::value;
59181254a7Smrg typedef std::integral_constant<bool, value> type;
60181254a7Smrg };
61181254a7Smrg
62181254a7Smrg template <typename _IteratorType>
63181254a7Smrg struct __is_random_access_iterator<_IteratorType>
64181254a7Smrg : std::is_same<typename std::iterator_traits<_IteratorType>::iterator_category, std::random_access_iterator_tag>
65181254a7Smrg {
66181254a7Smrg };
67181254a7Smrg
68181254a7Smrg /* policy */
69181254a7Smrg template <typename _Policy>
70181254a7Smrg struct __policy_traits
71181254a7Smrg {
72181254a7Smrg };
73181254a7Smrg
74181254a7Smrg template <>
75181254a7Smrg struct __policy_traits<sequenced_policy>
76181254a7Smrg {
77181254a7Smrg typedef std::false_type allow_parallel;
78181254a7Smrg typedef std::false_type allow_unsequenced;
79181254a7Smrg typedef std::false_type allow_vector;
80181254a7Smrg };
81181254a7Smrg
82181254a7Smrg template <>
83181254a7Smrg struct __policy_traits<unsequenced_policy>
84181254a7Smrg {
85181254a7Smrg typedef std::false_type allow_parallel;
86181254a7Smrg typedef std::true_type allow_unsequenced;
87181254a7Smrg typedef std::true_type allow_vector;
88181254a7Smrg };
89181254a7Smrg
90181254a7Smrg template <>
91181254a7Smrg struct __policy_traits<parallel_policy>
92181254a7Smrg {
93181254a7Smrg typedef std::true_type allow_parallel;
94181254a7Smrg typedef std::false_type allow_unsequenced;
95181254a7Smrg typedef std::false_type allow_vector;
96181254a7Smrg };
97181254a7Smrg
98181254a7Smrg template <>
99181254a7Smrg struct __policy_traits<parallel_unsequenced_policy>
100181254a7Smrg {
101181254a7Smrg typedef std::true_type allow_parallel;
102181254a7Smrg typedef std::true_type allow_unsequenced;
103181254a7Smrg typedef std::true_type allow_vector;
104181254a7Smrg };
105181254a7Smrg
106181254a7Smrg template <typename _ExecutionPolicy>
107fb8a8121Smrg using __collector_t =
108fb8a8121Smrg typename __internal::__policy_traits<typename std::decay<_ExecutionPolicy>::type>::__collector_type;
109181254a7Smrg
110181254a7Smrg template <typename _ExecutionPolicy>
111fb8a8121Smrg using __allow_vector =
112fb8a8121Smrg typename __internal::__policy_traits<typename std::decay<_ExecutionPolicy>::type>::__allow_vector;
113181254a7Smrg
114181254a7Smrg template <typename _ExecutionPolicy>
115fb8a8121Smrg using __allow_unsequenced =
116fb8a8121Smrg typename __internal::__policy_traits<typename std::decay<_ExecutionPolicy>::type>::__allow_unsequenced;
117181254a7Smrg
118181254a7Smrg template <typename _ExecutionPolicy>
119fb8a8121Smrg using __allow_parallel =
120fb8a8121Smrg typename __internal::__policy_traits<typename std::decay<_ExecutionPolicy>::type>::__allow_parallel;
121181254a7Smrg
122181254a7Smrg template <typename _ExecutionPolicy, typename... _IteratorTypes>
123181254a7Smrg auto
124181254a7Smrg __is_vectorization_preferred(_ExecutionPolicy&& __exec)
125fb8a8121Smrg -> decltype(__internal::__lazy_and(__exec.__allow_vector(),
126fb8a8121Smrg typename __internal::__is_random_access_iterator<_IteratorTypes...>::type()))
127181254a7Smrg {
128fb8a8121Smrg return __internal::__lazy_and(__exec.__allow_vector(),
129fb8a8121Smrg typename __internal::__is_random_access_iterator<_IteratorTypes...>::type());
130181254a7Smrg }
131181254a7Smrg
132181254a7Smrg template <typename _ExecutionPolicy, typename... _IteratorTypes>
133181254a7Smrg auto
134181254a7Smrg __is_parallelization_preferred(_ExecutionPolicy&& __exec)
135fb8a8121Smrg -> decltype(__internal::__lazy_and(__exec.__allow_parallel(),
136fb8a8121Smrg typename __internal::__is_random_access_iterator<_IteratorTypes...>::type()))
137181254a7Smrg {
138fb8a8121Smrg return __internal::__lazy_and(__exec.__allow_parallel(),
139fb8a8121Smrg typename __internal::__is_random_access_iterator<_IteratorTypes...>::type());
140181254a7Smrg }
141181254a7Smrg
142181254a7Smrg template <typename policy, typename... _IteratorTypes>
143181254a7Smrg struct __prefer_unsequenced_tag
144181254a7Smrg {
145fb8a8121Smrg static constexpr bool value = __internal::__allow_unsequenced<policy>::value &&
146fb8a8121Smrg __internal::__is_random_access_iterator<_IteratorTypes...>::value;
147181254a7Smrg typedef std::integral_constant<bool, value> type;
148181254a7Smrg };
149181254a7Smrg
150181254a7Smrg template <typename policy, typename... _IteratorTypes>
151181254a7Smrg struct __prefer_parallel_tag
152181254a7Smrg {
153fb8a8121Smrg static constexpr bool value = __internal::__allow_parallel<policy>::value &&
154fb8a8121Smrg __internal::__is_random_access_iterator<_IteratorTypes...>::value;
155181254a7Smrg typedef std::integral_constant<bool, value> type;
156181254a7Smrg };
157181254a7Smrg
158181254a7Smrg } // namespace __internal
159181254a7Smrg } // namespace __pstl
160181254a7Smrg
161fb8a8121Smrg #endif /* _PSTL_EXECUTION_IMPL_H */
162