• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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