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 _LIBCPP___FUNCTIONAL_WEAK_RESULT_TYPE_H 11 #define _LIBCPP___FUNCTIONAL_WEAK_RESULT_TYPE_H 12 13 #include <__config> 14 #include <__functional/binary_function.h> 15 #include <__functional/unary_function.h> 16 #include <type_traits> 17 18 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 19 # pragma GCC system_header 20 #endif 21 22 _LIBCPP_BEGIN_NAMESPACE_STD 23 24 template <class _Tp> 25 struct __has_result_type 26 { 27 private: 28 template <class _Up> static false_type __test(...); 29 template <class _Up> static true_type __test(typename _Up::result_type* = 0); 30 public: 31 static const bool value = decltype(__test<_Tp>(0))::value; 32 }; 33 34 // __weak_result_type 35 36 template <class _Tp> 37 struct __derives_from_unary_function 38 { 39 private: 40 struct __two {char __lx; char __lxx;}; 41 static __two __test(...); 42 template <class _Ap, class _Rp> 43 static __unary_function<_Ap, _Rp> 44 __test(const volatile __unary_function<_Ap, _Rp>*); 45 46 public: 47 static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value; 48 typedef decltype(__test((_Tp*)0)) type; 49 }; 50 51 template <class _Tp> 52 struct __derives_from_binary_function 53 { 54 private: 55 struct __two {char __lx; char __lxx;}; 56 static __two __test(...); 57 template <class _A1, class _A2, class _Rp> 58 static __binary_function<_A1, _A2, _Rp> 59 __test(const volatile __binary_function<_A1, _A2, _Rp>*); 60 61 public: 62 static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value; 63 typedef decltype(__test((_Tp*)0)) type; 64 }; 65 66 template <class _Tp, bool = __derives_from_unary_function<_Tp>::value> 67 struct __maybe_derive_from_unary_function // bool is true 68 : public __derives_from_unary_function<_Tp>::type 69 { 70 }; 71 72 template <class _Tp> 73 struct __maybe_derive_from_unary_function<_Tp, false> 74 { 75 }; 76 77 template <class _Tp, bool = __derives_from_binary_function<_Tp>::value> 78 struct __maybe_derive_from_binary_function // bool is true 79 : public __derives_from_binary_function<_Tp>::type 80 { 81 }; 82 83 template <class _Tp> 84 struct __maybe_derive_from_binary_function<_Tp, false> 85 { 86 }; 87 88 template <class _Tp, bool = __has_result_type<_Tp>::value> 89 struct __weak_result_type_imp // bool is true 90 : public __maybe_derive_from_unary_function<_Tp>, 91 public __maybe_derive_from_binary_function<_Tp> 92 { 93 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 94 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = typename _Tp::result_type; 95 #endif 96 }; 97 98 template <class _Tp> 99 struct __weak_result_type_imp<_Tp, false> 100 : public __maybe_derive_from_unary_function<_Tp>, 101 public __maybe_derive_from_binary_function<_Tp> 102 { 103 }; 104 105 template <class _Tp> 106 struct __weak_result_type 107 : public __weak_result_type_imp<_Tp> 108 { 109 }; 110 111 // 0 argument case 112 113 template <class _Rp> 114 struct __weak_result_type<_Rp ()> 115 { 116 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 117 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 118 #endif 119 }; 120 121 template <class _Rp> 122 struct __weak_result_type<_Rp (&)()> 123 { 124 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 125 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 126 #endif 127 }; 128 129 template <class _Rp> 130 struct __weak_result_type<_Rp (*)()> 131 { 132 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 133 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 134 #endif 135 }; 136 137 // 1 argument case 138 139 template <class _Rp, class _A1> 140 struct __weak_result_type<_Rp (_A1)> 141 : public __unary_function<_A1, _Rp> 142 { 143 }; 144 145 template <class _Rp, class _A1> 146 struct __weak_result_type<_Rp (&)(_A1)> 147 : public __unary_function<_A1, _Rp> 148 { 149 }; 150 151 template <class _Rp, class _A1> 152 struct __weak_result_type<_Rp (*)(_A1)> 153 : public __unary_function<_A1, _Rp> 154 { 155 }; 156 157 template <class _Rp, class _Cp> 158 struct __weak_result_type<_Rp (_Cp::*)()> 159 : public __unary_function<_Cp*, _Rp> 160 { 161 }; 162 163 template <class _Rp, class _Cp> 164 struct __weak_result_type<_Rp (_Cp::*)() const> 165 : public __unary_function<const _Cp*, _Rp> 166 { 167 }; 168 169 template <class _Rp, class _Cp> 170 struct __weak_result_type<_Rp (_Cp::*)() volatile> 171 : public __unary_function<volatile _Cp*, _Rp> 172 { 173 }; 174 175 template <class _Rp, class _Cp> 176 struct __weak_result_type<_Rp (_Cp::*)() const volatile> 177 : public __unary_function<const volatile _Cp*, _Rp> 178 { 179 }; 180 181 // 2 argument case 182 183 template <class _Rp, class _A1, class _A2> 184 struct __weak_result_type<_Rp (_A1, _A2)> 185 : public __binary_function<_A1, _A2, _Rp> 186 { 187 }; 188 189 template <class _Rp, class _A1, class _A2> 190 struct __weak_result_type<_Rp (*)(_A1, _A2)> 191 : public __binary_function<_A1, _A2, _Rp> 192 { 193 }; 194 195 template <class _Rp, class _A1, class _A2> 196 struct __weak_result_type<_Rp (&)(_A1, _A2)> 197 : public __binary_function<_A1, _A2, _Rp> 198 { 199 }; 200 201 template <class _Rp, class _Cp, class _A1> 202 struct __weak_result_type<_Rp (_Cp::*)(_A1)> 203 : public __binary_function<_Cp*, _A1, _Rp> 204 { 205 }; 206 207 template <class _Rp, class _Cp, class _A1> 208 struct __weak_result_type<_Rp (_Cp::*)(_A1) const> 209 : public __binary_function<const _Cp*, _A1, _Rp> 210 { 211 }; 212 213 template <class _Rp, class _Cp, class _A1> 214 struct __weak_result_type<_Rp (_Cp::*)(_A1) volatile> 215 : public __binary_function<volatile _Cp*, _A1, _Rp> 216 { 217 }; 218 219 template <class _Rp, class _Cp, class _A1> 220 struct __weak_result_type<_Rp (_Cp::*)(_A1) const volatile> 221 : public __binary_function<const volatile _Cp*, _A1, _Rp> 222 { 223 }; 224 225 // 3 or more arguments 226 227 template <class _Rp, class _A1, class _A2, class _A3, class ..._A4> 228 struct __weak_result_type<_Rp (_A1, _A2, _A3, _A4...)> 229 { 230 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 231 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 232 #endif 233 }; 234 235 template <class _Rp, class _A1, class _A2, class _A3, class ..._A4> 236 struct __weak_result_type<_Rp (&)(_A1, _A2, _A3, _A4...)> 237 { 238 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 239 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 240 #endif 241 }; 242 243 template <class _Rp, class _A1, class _A2, class _A3, class ..._A4> 244 struct __weak_result_type<_Rp (*)(_A1, _A2, _A3, _A4...)> 245 { 246 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 247 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 248 #endif 249 }; 250 251 template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3> 252 struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...)> 253 { 254 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 255 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 256 #endif 257 }; 258 259 template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3> 260 struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const> 261 { 262 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 263 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 264 #endif 265 }; 266 267 template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3> 268 struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) volatile> 269 { 270 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 271 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 272 #endif 273 }; 274 275 template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3> 276 struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile> 277 { 278 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 279 using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; 280 #endif 281 }; 282 283 template <class _Tp, class ..._Args> 284 struct __invoke_return 285 { 286 typedef decltype(_VSTD::__invoke(declval<_Tp>(), declval<_Args>()...)) type; 287 }; 288 289 _LIBCPP_END_NAMESPACE_STD 290 291 #endif // _LIBCPP___FUNCTIONAL_WEAK_RESULT_TYPE_H 292