1// -*- C++ -*-
2//===-- utils.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_UTILS_H
11#define _PSTL_UTILS_H
12
13#include <new>
14#include <iterator>
15
16namespace __pstl
17{
18namespace __internal
19{
20
21template <typename _Fp>
22typename std::result_of<_Fp()>::type
23__except_handler(_Fp __f)
24{
25 try
26 {
27 return __f();
28 }
29 catch (const std::bad_alloc&)
30 {
31 throw; // re-throw bad_alloc according to the standard [algorithms.parallel.exceptions]
32 }
33 catch (...)
34 {
35 std::terminate(); // Good bye according to the standard [algorithms.parallel.exceptions]
36 }
37}
38
39template <typename _Fp>
40void
41__invoke_if(std::true_type, _Fp __f)
42{
43 __f();
44}
45
46template <typename _Fp>
47void
48__invoke_if(std::false_type, _Fp __f)
49{
50}
51
52template <typename _Fp>
53void
54__invoke_if_not(std::false_type, _Fp __f)
55{
56 __f();
57}
58
59template <typename _Fp>
60void
61__invoke_if_not(std::true_type, _Fp __f)
62{
63}
64
65template <typename _F1, typename _F2>
66typename std::result_of<_F1()>::type
67__invoke_if_else(std::true_type, _F1 __f1, _F2 __f2)
68{
69 return __f1();
70}
71
72template <typename _F1, typename _F2>
73typename std::result_of<_F2()>::type
74__invoke_if_else(std::false_type, _F1 __f1, _F2 __f2)
75{
76 return __f2();
77}
78
79//! Unary operator that returns reference to its argument.
80struct __no_op
81{
82 template <typename _Tp>
83 _Tp&&
84 operator()(_Tp&& __a) const
85 {
86 return std::forward<_Tp>(__a);
87 }
88};
89
90//! Logical negation of a predicate
91template <typename _Pred>
92class __not_pred
93{
94 _Pred _M_pred;
95
96 public:
97 explicit __not_pred(_Pred __pred) : _M_pred(__pred) {}
98
99 template <typename... _Args>
100 bool
101 operator()(_Args&&... __args)
102 {
103 return !_M_pred(std::forward<_Args>(__args)...);
104 }
105};
106
107template <typename _Pred>
108class __reorder_pred
109{
110 _Pred _M_pred;
111
112 public:
113 explicit __reorder_pred(_Pred __pred) : _M_pred(__pred) {}
114
115 template <typename _FTp, typename _STp>
116 bool
117 operator()(_FTp&& __a, _STp&& __b)
118 {
119 return _M_pred(std::forward<_STp>(__b), std::forward<_FTp>(__a));
120 }
121};
122
123//! "==" comparison.
124/** Not called "equal" to avoid (possibly unfounded) concerns about accidental invocation via
125 argument-dependent name lookup by code expecting to find the usual std::equal. */
126class __pstl_equal
127{
128 public:
129 explicit __pstl_equal() {}
130
131 template <typename _Xp, typename _Yp>
132 bool
133 operator()(_Xp&& __x, _Yp&& __y) const
134 {
135 return std::forward<_Xp>(__x) == std::forward<_Yp>(__y);
136 }
137};
138
139//! "<" comparison.
140class __pstl_less
141{
142 public:
143 explicit __pstl_less() {}
144
145 template <typename _Xp, typename _Yp>
146 bool
147 operator()(_Xp&& __x, _Yp&& __y) const
148 {
149 return std::forward<_Xp>(__x) < std::forward<_Yp>(__y);
150 }
151};
152
153//! Like a polymorphic lambda for pred(...,value)
154template <typename _Tp, typename _Predicate>
155class __equal_value_by_pred
156{
157 const _Tp& _M_value;
158 _Predicate _M_pred;
159
160 public:
161 __equal_value_by_pred(const _Tp& __value, _Predicate __pred) : _M_value(__value), _M_pred(__pred) {}
162
163 template <typename _Arg>
164 bool
165 operator()(_Arg&& __arg)
166 {
167 return _M_pred(std::forward<_Arg>(__arg), _M_value);
168 }
169};
170
171//! Like a polymorphic lambda for ==value
172template <typename _Tp>
173class __equal_value
174{
175 const _Tp& _M_value;
176
177 public:
178 explicit __equal_value(const _Tp& __value) : _M_value(__value) {}
179
180 template <typename _Arg>
181 bool
182 operator()(_Arg&& __arg) const
183 {
184 return std::forward<_Arg>(__arg) == _M_value;
185 }
186};
187
188//! Logical negation of ==value
189template <typename _Tp>
190class __not_equal_value
191{
192 const _Tp& _M_value;
193
194 public:
195 explicit __not_equal_value(const _Tp& __value) : _M_value(__value) {}
196
197 template <typename _Arg>
198 bool
199 operator()(_Arg&& __arg) const
200 {
201 return !(std::forward<_Arg>(__arg) == _M_value);
202 }
203};
204
205template <typename _ForwardIterator, typename _Compare>
206_ForwardIterator
207__cmp_iterators_by_values(_ForwardIterator __a, _ForwardIterator __b, _Compare __comp)
208{
209 if (__a < __b)
210 { // we should return closer iterator
211 return __comp(*__b, *__a) ? __b : __a;
212 }
213 else
214 {
215 return __comp(*__a, *__b) ? __a : __b;
216 }
217}
218
219} // namespace __internal
220} // namespace __pstl
221
222#endif /* _PSTL_UTILS_H */
223

source code of include/c++/11/pstl/utils.h