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