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