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