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_UTILS_H
11 #define _PSTL_UTILS_H
12
13 #include <new>
14 #include <iterator>
15
16 _PSTL_HIDE_FROM_ABI_PUSH
17
18 namespace __pstl
19 {
20 namespace __internal
21 {
22
23 template <typename _Fp>
24 typename std::result_of<_Fp()>::type
__except_handler(_Fp __f)25 __except_handler(_Fp __f)
26 {
27 try
28 {
29 return __f();
30 }
31 catch (const std::bad_alloc&)
32 {
33 throw; // re-throw bad_alloc according to the standard [algorithms.parallel.exceptions]
34 }
35 catch (...)
36 {
37 std::terminate(); // Good bye according to the standard [algorithms.parallel.exceptions]
38 }
39 }
40
41 template <typename _Fp>
42 void
__invoke_if(std::true_type,_Fp __f)43 __invoke_if(std::true_type, _Fp __f)
44 {
45 __f();
46 }
47
48 template <typename _Fp>
__invoke_if(std::false_type,_Fp)49 void __invoke_if(std::false_type, _Fp)
50 {
51 }
52
53 template <typename _Fp>
54 void
__invoke_if_not(std::false_type,_Fp __f)55 __invoke_if_not(std::false_type, _Fp __f)
56 {
57 __f();
58 }
59
60 template <typename _Fp>
__invoke_if_not(std::true_type,_Fp)61 void __invoke_if_not(std::true_type, _Fp)
62 {
63 }
64
65 template <typename _F1, typename _F2>
66 typename std::result_of<_F1()>::type
__invoke_if_else(std::true_type,_F1 __f1,_F2)67 __invoke_if_else(std::true_type, _F1 __f1, _F2)
68 {
69 return __f1();
70 }
71
72 template <typename _F1, typename _F2>
73 typename std::result_of<_F2()>::type
__invoke_if_else(std::false_type,_F1,_F2 __f2)74 __invoke_if_else(std::false_type, _F1, _F2 __f2)
75 {
76 return __f2();
77 }
78
79 //! Unary operator that returns reference to its argument.
80 struct __no_op
81 {
82 template <typename _Tp>
83 _Tp&&
operator__no_op84 operator()(_Tp&& __a) const
85 {
86 return std::forward<_Tp>(__a);
87 }
88 };
89
90 template <typename _Pred>
91 class __reorder_pred
92 {
93 _Pred _M_pred;
94
95 public:
__reorder_pred(_Pred __pred)96 explicit __reorder_pred(_Pred __pred) : _M_pred(__pred) {}
97
98 template <typename _FTp, typename _STp>
99 bool
operator()100 operator()(_FTp&& __a, _STp&& __b)
101 {
102 return _M_pred(std::forward<_STp>(__b), std::forward<_FTp>(__a));
103 }
104 };
105
106 //! Like a polymorphic lambda for pred(...,value)
107 template <typename _Tp, typename _Predicate>
108 class __equal_value_by_pred
109 {
110 const _Tp& _M_value;
111 _Predicate _M_pred;
112
113 public:
__equal_value_by_pred(const _Tp & __value,_Predicate __pred)114 __equal_value_by_pred(const _Tp& __value, _Predicate __pred) : _M_value(__value), _M_pred(__pred) {}
115
116 template <typename _Arg>
117 bool
operator()118 operator()(_Arg&& __arg)
119 {
120 return _M_pred(std::forward<_Arg>(__arg), _M_value);
121 }
122 };
123
124 //! Like a polymorphic lambda for ==value
125 template <typename _Tp>
126 class __equal_value
127 {
128 const _Tp& _M_value;
129
130 public:
__equal_value(const _Tp & __value)131 explicit __equal_value(const _Tp& __value) : _M_value(__value) {}
132
133 template <typename _Arg>
134 bool
operator()135 operator()(_Arg&& __arg) const
136 {
137 return std::forward<_Arg>(__arg) == _M_value;
138 }
139 };
140
141 //! Logical negation of ==value
142 template <typename _Tp>
143 class __not_equal_value
144 {
145 const _Tp& _M_value;
146
147 public:
__not_equal_value(const _Tp & __value)148 explicit __not_equal_value(const _Tp& __value) : _M_value(__value) {}
149
150 template <typename _Arg>
151 bool
operator()152 operator()(_Arg&& __arg) const
153 {
154 return !(std::forward<_Arg>(__arg) == _M_value);
155 }
156 };
157
158 template <typename _ForwardIterator, typename _Compare>
159 _ForwardIterator
__cmp_iterators_by_values(_ForwardIterator __a,_ForwardIterator __b,_Compare __comp)160 __cmp_iterators_by_values(_ForwardIterator __a, _ForwardIterator __b, _Compare __comp)
161 {
162 if (__a < __b)
163 { // we should return closer iterator
164 return __comp(*__b, *__a) ? __b : __a;
165 }
166 else
167 {
168 return __comp(*__a, *__b) ? __a : __b;
169 }
170 }
171
172 } // namespace __internal
173 } // namespace __pstl
174
175 _PSTL_HIDE_FROM_ABI_POP
176
177 #endif /* _PSTL_UTILS_H */
178