1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
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_EXECUTION_IMPL_H
11 #define _PSTL_EXECUTION_IMPL_H
12
13 #include <iterator>
14 #include <type_traits>
15
16 #include "pstl_config.h"
17 #include "execution_defs.h"
18
19 _PSTL_HIDE_FROM_ABI_PUSH
20
21 namespace __pstl
22 {
23 namespace __internal
24 {
25
26 using namespace __pstl::execution;
27
28 /* predicate */
29
30 template <typename _Tp>
__lazy_and(_Tp,std::false_type)31 std::false_type __lazy_and(_Tp, std::false_type)
32 {
33 return std::false_type{};
34 }
35
36 template <typename _Tp>
37 inline _Tp
__lazy_and(_Tp __a,std::true_type)38 __lazy_and(_Tp __a, std::true_type)
39 {
40 return __a;
41 }
42
43 template <typename _Tp>
__lazy_or(_Tp,std::true_type)44 std::true_type __lazy_or(_Tp, std::true_type)
45 {
46 return std::true_type{};
47 }
48
49 template <typename _Tp>
50 inline _Tp
__lazy_or(_Tp __a,std::false_type)51 __lazy_or(_Tp __a, std::false_type)
52 {
53 return __a;
54 }
55
56 /* iterator */
57 template <typename _IteratorType, typename... _OtherIteratorTypes>
58 struct __is_random_access_iterator
59 {
60 static constexpr bool value = __internal::__is_random_access_iterator<_IteratorType>::value &&
61 __internal::__is_random_access_iterator<_OtherIteratorTypes...>::value;
62 typedef std::integral_constant<bool, value> type;
63 };
64
65 template <typename _IteratorType>
66 struct __is_random_access_iterator<_IteratorType>
67 : std::is_same<typename std::iterator_traits<_IteratorType>::iterator_category, std::random_access_iterator_tag>
68 {
69 };
70
71 /* policy */
72 template <typename Policy>
73 struct __policy_traits
74 {
75 };
76
77 template <>
78 struct __policy_traits<sequenced_policy>
79 {
80 typedef std::false_type allow_parallel;
81 typedef std::false_type allow_unsequenced;
82 typedef std::false_type allow_vector;
83 };
84
85 template <>
86 struct __policy_traits<unsequenced_policy>
87 {
88 typedef std::false_type allow_parallel;
89 typedef std::true_type allow_unsequenced;
90 typedef std::true_type allow_vector;
91 };
92
93 template <>
94 struct __policy_traits<parallel_policy>
95 {
96 typedef std::true_type allow_parallel;
97 typedef std::false_type allow_unsequenced;
98 typedef std::false_type allow_vector;
99 };
100
101 template <>
102 struct __policy_traits<parallel_unsequenced_policy>
103 {
104 typedef std::true_type allow_parallel;
105 typedef std::true_type allow_unsequenced;
106 typedef std::true_type allow_vector;
107 };
108
109 template <typename _ExecutionPolicy>
110 using __collector_t =
111 typename __internal::__policy_traits<typename std::decay<_ExecutionPolicy>::type>::__collector_type;
112
113 template <typename _ExecutionPolicy>
114 using __allow_vector =
115 typename __internal::__policy_traits<typename std::decay<_ExecutionPolicy>::type>::__allow_vector;
116
117 template <typename _ExecutionPolicy>
118 using __allow_unsequenced =
119 typename __internal::__policy_traits<typename std::decay<_ExecutionPolicy>::type>::__allow_unsequenced;
120
121 template <typename _ExecutionPolicy>
122 using __allow_parallel =
123 typename __internal::__policy_traits<typename std::decay<_ExecutionPolicy>::type>::__allow_parallel;
124
125 template <typename _ExecutionPolicy, typename... _IteratorTypes>
126 auto
127 __is_vectorization_preferred(_ExecutionPolicy&& __exec)
128 -> decltype(__internal::__lazy_and(__exec.__allow_vector(),
129 typename __internal::__is_random_access_iterator<_IteratorTypes...>::type()))
130 {
131 return __internal::__lazy_and(__exec.__allow_vector(),
132 typename __internal::__is_random_access_iterator<_IteratorTypes...>::type());
133 }
134
135 template <typename _ExecutionPolicy, typename... _IteratorTypes>
136 auto
137 __is_parallelization_preferred(_ExecutionPolicy&& __exec)
138 -> decltype(__internal::__lazy_and(__exec.__allow_parallel(),
139 typename __internal::__is_random_access_iterator<_IteratorTypes...>::type()))
140 {
141 return __internal::__lazy_and(__exec.__allow_parallel(),
142 typename __internal::__is_random_access_iterator<_IteratorTypes...>::type());
143 }
144
145 template <typename policy, typename... _IteratorTypes>
146 struct __prefer_unsequenced_tag
147 {
148 static constexpr bool value = __internal::__allow_unsequenced<policy>::value &&
149 __internal::__is_random_access_iterator<_IteratorTypes...>::value;
150 typedef std::integral_constant<bool, value> type;
151 };
152
153 template <typename policy, typename... _IteratorTypes>
154 struct __prefer_parallel_tag
155 {
156 static constexpr bool value = __internal::__allow_parallel<policy>::value &&
157 __internal::__is_random_access_iterator<_IteratorTypes...>::value;
158 typedef std::integral_constant<bool, value> type;
159 };
160
161 } // namespace __internal
162 } // namespace __pstl
163
164 _PSTL_HIDE_FROM_ABI_POP
165
166 #endif /* _PSTL_EXECUTION_IMPL_H */
167