• 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_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