1 // -*- C++ -*- 2 //===----------------------------------------------------------------------===// 3 // 4 // The LLVM Compiler Infrastructure 5 // 6 // This file is dual licensed under the MIT and the University of Illinois Open 7 // Source Licenses. See LICENSE.TXT for details. 8 // 9 //===----------------------------------------------------------------------===// 10 11 #ifndef _LIBCPP_FUNCTIONAL_BASE_03 12 #define _LIBCPP_FUNCTIONAL_BASE_03 13 14 // manual variadic expansion for <functional> 15 16 // __invoke 17 // first bullet 18 19 template <class _Rp, class _Tp, class _T1> 20 inline _LIBCPP_INLINE_VISIBILITY 21 typename enable_if 22 < 23 is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 24 _Rp 25 >::type 26 __invoke(_Rp (_Tp::*__f)(), _T1& __t1) 27 { 28 return (__t1.*__f)(); 29 } 30 31 template <class _Rp, class _Tp, class _T1, class _A0> 32 inline _LIBCPP_INLINE_VISIBILITY 33 typename enable_if 34 < 35 is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 36 _Rp 37 >::type 38 __invoke(_Rp (_Tp::*__f)(_A0), _T1& __t1, _A0& __a0) 39 { 40 return (__t1.*__f)(__a0); 41 } 42 43 template <class _Rp, class _Tp, class _T1, class _A0, class _A1> 44 inline _LIBCPP_INLINE_VISIBILITY 45 typename enable_if 46 < 47 is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 48 _Rp 49 >::type 50 __invoke(_Rp (_Tp::*__f)(_A0, _A1), _T1& __t1, _A0& __a0, _A1& __a1) 51 { 52 return (__t1.*__f)(__a0, __a1); 53 } 54 55 template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2> 56 inline _LIBCPP_INLINE_VISIBILITY 57 typename enable_if 58 < 59 is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 60 _Rp 61 >::type 62 __invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2), _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) 63 { 64 return (__t1.*__f)(__a0, __a1, __a2); 65 } 66 67 template <class _Rp, class _Tp, class _T1> 68 inline _LIBCPP_INLINE_VISIBILITY 69 typename enable_if 70 < 71 is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 72 _Rp 73 >::type 74 __invoke(_Rp (_Tp::*__f)() const, _T1& __t1) 75 { 76 return (__t1.*__f)(); 77 } 78 79 template <class _Rp, class _Tp, class _T1, class _A0> 80 inline _LIBCPP_INLINE_VISIBILITY 81 typename enable_if 82 < 83 is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 84 _Rp 85 >::type 86 __invoke(_Rp (_Tp::*__f)(_A0) const, _T1& __t1, _A0& __a0) 87 { 88 return (__t1.*__f)(__a0); 89 } 90 91 template <class _Rp, class _Tp, class _T1, class _A0, class _A1> 92 inline _LIBCPP_INLINE_VISIBILITY 93 typename enable_if 94 < 95 is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 96 _Rp 97 >::type 98 __invoke(_Rp (_Tp::*__f)(_A0, _A1) const, _T1& __t1, _A0& __a0, _A1& __a1) 99 { 100 return (__t1.*__f)(__a0, __a1); 101 } 102 103 template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2> 104 inline _LIBCPP_INLINE_VISIBILITY 105 typename enable_if 106 < 107 is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 108 _Rp 109 >::type 110 __invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2) const, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) 111 { 112 return (__t1.*__f)(__a0, __a1, __a2); 113 } 114 115 template <class _Rp, class _Tp, class _T1> 116 inline _LIBCPP_INLINE_VISIBILITY 117 typename enable_if 118 < 119 is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 120 _Rp 121 >::type 122 __invoke(_Rp (_Tp::*__f)() volatile, _T1& __t1) 123 { 124 return (__t1.*__f)(); 125 } 126 127 template <class _Rp, class _Tp, class _T1, class _A0> 128 inline _LIBCPP_INLINE_VISIBILITY 129 typename enable_if 130 < 131 is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 132 _Rp 133 >::type 134 __invoke(_Rp (_Tp::*__f)(_A0) volatile, _T1& __t1, _A0& __a0) 135 { 136 return (__t1.*__f)(__a0); 137 } 138 139 template <class _Rp, class _Tp, class _T1, class _A0, class _A1> 140 inline _LIBCPP_INLINE_VISIBILITY 141 typename enable_if 142 < 143 is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 144 _Rp 145 >::type 146 __invoke(_Rp (_Tp::*__f)(_A0, _A1) volatile, _T1& __t1, _A0& __a0, _A1& __a1) 147 { 148 return (__t1.*__f)(__a0, __a1); 149 } 150 151 template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2> 152 inline _LIBCPP_INLINE_VISIBILITY 153 typename enable_if 154 < 155 is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 156 _Rp 157 >::type 158 __invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2) volatile, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) 159 { 160 return (__t1.*__f)(__a0, __a1, __a2); 161 } 162 163 template <class _Rp, class _Tp, class _T1> 164 inline _LIBCPP_INLINE_VISIBILITY 165 typename enable_if 166 < 167 is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 168 _Rp 169 >::type 170 __invoke(_Rp (_Tp::*__f)() const volatile, _T1& __t1) 171 { 172 return (__t1.*__f)(); 173 } 174 175 template <class _Rp, class _Tp, class _T1, class _A0> 176 inline _LIBCPP_INLINE_VISIBILITY 177 typename enable_if 178 < 179 is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 180 _Rp 181 >::type 182 __invoke(_Rp (_Tp::*__f)(_A0) const volatile, _T1& __t1, _A0& __a0) 183 { 184 return (__t1.*__f)(__a0); 185 } 186 187 template <class _Rp, class _Tp, class _T1, class _A0, class _A1> 188 inline _LIBCPP_INLINE_VISIBILITY 189 typename enable_if 190 < 191 is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 192 _Rp 193 >::type 194 __invoke(_Rp (_Tp::*__f)(_A0, _A1) const volatile, _T1& __t1, _A0& __a0, _A1& __a1) 195 { 196 return (__t1.*__f)(__a0, __a1); 197 } 198 199 template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2> 200 inline _LIBCPP_INLINE_VISIBILITY 201 typename enable_if 202 < 203 is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 204 _Rp 205 >::type 206 __invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2) const volatile, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) 207 { 208 return (__t1.*__f)(__a0, __a1, __a2); 209 } 210 211 // second bullet 212 213 template <class _Rp, class _Tp, class _T1> 214 inline _LIBCPP_INLINE_VISIBILITY 215 typename enable_if 216 < 217 !is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 218 _Rp 219 >::type 220 __invoke(_Rp (_Tp::*__f)(), _T1 __t1) 221 { 222 return ((*__t1).*__f)(); 223 } 224 225 template <class _Rp, class _Tp, class _T1, class _A0> 226 inline _LIBCPP_INLINE_VISIBILITY 227 typename enable_if 228 < 229 !is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 230 _Rp 231 >::type 232 __invoke(_Rp (_Tp::*__f)(_A0), _T1 __t1, _A0& __a0) 233 { 234 return ((*__t1).*__f)(__a0); 235 } 236 237 template <class _Rp, class _Tp, class _T1, class _A0, class _A1> 238 inline _LIBCPP_INLINE_VISIBILITY 239 typename enable_if 240 < 241 !is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 242 _Rp 243 >::type 244 __invoke(_Rp (_Tp::*__f)(_A0, _A1), _T1 __t1, _A0& __a0, _A1& __a1) 245 { 246 return ((*__t1).*__f)(__a0, __a1); 247 } 248 249 template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2> 250 inline _LIBCPP_INLINE_VISIBILITY 251 typename enable_if 252 < 253 !is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 254 _Rp 255 >::type 256 __invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2), _T1 __t1, _A0& __a0, _A1& __a1, _A2& __a2) 257 { 258 return ((*__t1).*__f)(__a0, __a1, __a2); 259 } 260 261 template <class _Rp, class _Tp, class _T1> 262 inline _LIBCPP_INLINE_VISIBILITY 263 typename enable_if 264 < 265 !is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 266 _Rp 267 >::type 268 __invoke(_Rp (_Tp::*__f)() const, _T1 __t1) 269 { 270 return ((*__t1).*__f)(); 271 } 272 273 template <class _Rp, class _Tp, class _T1, class _A0> 274 inline _LIBCPP_INLINE_VISIBILITY 275 typename enable_if 276 < 277 !is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 278 _Rp 279 >::type 280 __invoke(_Rp (_Tp::*__f)(_A0) const, _T1 __t1, _A0& __a0) 281 { 282 return ((*__t1).*__f)(__a0); 283 } 284 285 template <class _Rp, class _Tp, class _T1, class _A0, class _A1> 286 inline _LIBCPP_INLINE_VISIBILITY 287 typename enable_if 288 < 289 !is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 290 _Rp 291 >::type 292 __invoke(_Rp (_Tp::*__f)(_A0, _A1) const, _T1 __t1, _A0& __a0, _A1& __a1) 293 { 294 return ((*__t1).*__f)(__a0, __a1); 295 } 296 297 template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2> 298 inline _LIBCPP_INLINE_VISIBILITY 299 typename enable_if 300 < 301 !is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 302 _Rp 303 >::type 304 __invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2) const, _T1 __t1, _A0& __a0, _A1& __a1, _A2& __a2) 305 { 306 return ((*__t1).*__f)(__a0, __a1, __a2); 307 } 308 309 template <class _Rp, class _Tp, class _T1> 310 inline _LIBCPP_INLINE_VISIBILITY 311 typename enable_if 312 < 313 !is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 314 _Rp 315 >::type 316 __invoke(_Rp (_Tp::*__f)() volatile, _T1 __t1) 317 { 318 return ((*__t1).*__f)(); 319 } 320 321 template <class _Rp, class _Tp, class _T1, class _A0> 322 inline _LIBCPP_INLINE_VISIBILITY 323 typename enable_if 324 < 325 !is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 326 _Rp 327 >::type 328 __invoke(_Rp (_Tp::*__f)(_A0) volatile, _T1 __t1, _A0& __a0) 329 { 330 return ((*__t1).*__f)(__a0); 331 } 332 333 template <class _Rp, class _Tp, class _T1, class _A0, class _A1> 334 inline _LIBCPP_INLINE_VISIBILITY 335 typename enable_if 336 < 337 !is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 338 _Rp 339 >::type 340 __invoke(_Rp (_Tp::*__f)(_A0, _A1) volatile, _T1 __t1, _A0& __a0, _A1& __a1) 341 { 342 return ((*__t1).*__f)(__a0, __a1); 343 } 344 345 template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2> 346 inline _LIBCPP_INLINE_VISIBILITY 347 typename enable_if 348 < 349 !is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 350 _Rp 351 >::type 352 __invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2) volatile, _T1 __t1, _A0& __a0, _A1& __a1, _A2& __a2) 353 { 354 return ((*__t1).*__f)(__a0, __a1, __a2); 355 } 356 357 template <class _Rp, class _Tp, class _T1> 358 inline _LIBCPP_INLINE_VISIBILITY 359 typename enable_if 360 < 361 !is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 362 _Rp 363 >::type 364 __invoke(_Rp (_Tp::*__f)() const volatile, _T1 __t1) 365 { 366 return ((*__t1).*__f)(); 367 } 368 369 template <class _Rp, class _Tp, class _T1, class _A0> 370 inline _LIBCPP_INLINE_VISIBILITY 371 typename enable_if 372 < 373 !is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 374 _Rp 375 >::type 376 __invoke(_Rp (_Tp::*__f)(_A0) const volatile, _T1 __t1, _A0& __a0) 377 { 378 return ((*__t1).*__f)(__a0); 379 } 380 381 template <class _Rp, class _Tp, class _T1, class _A0, class _A1> 382 inline _LIBCPP_INLINE_VISIBILITY 383 typename enable_if 384 < 385 !is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 386 _Rp 387 >::type 388 __invoke(_Rp (_Tp::*__f)(_A0, _A1) const volatile, _T1 __t1, _A0& __a0, _A1& __a1) 389 { 390 return ((*__t1).*__f)(__a0, __a1); 391 } 392 393 template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2> 394 inline _LIBCPP_INLINE_VISIBILITY 395 typename enable_if 396 < 397 !is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 398 _Rp 399 >::type 400 __invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2) const volatile, _T1 __t1, _A0& __a0, _A1& __a1, _A2& __a2) 401 { 402 return ((*__t1).*__f)(__a0, __a1, __a2); 403 } 404 405 // third bullet 406 407 template <class _Rp, class _Tp, class _T1> 408 inline _LIBCPP_INLINE_VISIBILITY 409 typename enable_if 410 < 411 is_member_object_pointer<_Rp _Tp::*>::value && 412 is_base_of<_Tp, typename remove_reference<_T1>::type>::value, 413 __apply_cv<_T1, _Rp> 414 >::type::type& 415 __invoke(_Rp _Tp::* __f, _T1& __t1) 416 { 417 return __t1.*__f; 418 } 419 420 421 // forth bullet 422 423 template <class _T1, class _Rp, bool> 424 struct __4th_helper 425 { 426 }; 427 428 template <class _T1, class _Rp> 429 struct __4th_helper<_T1, _Rp, true> 430 { 431 typedef typename __apply_cv<decltype(*_VSTD::declval<_T1&>()), _Rp>::type type; 432 }; 433 434 template <class _Rp, class _Tp, class _T1> 435 inline _LIBCPP_INLINE_VISIBILITY 436 typename __4th_helper<_T1, _Rp, 437 is_member_object_pointer<_Rp _Tp::*>::value && 438 !is_base_of<_Tp, typename remove_reference<_T1>::type>::value 439 >::type& 440 __invoke(_Rp _Tp::* __f, _T1& __t1) 441 { 442 return (*__t1).*__f; 443 } 444 445 // fifth bullet 446 447 template <class _Fp> 448 inline _LIBCPP_INLINE_VISIBILITY 449 decltype(_VSTD::declval<_Fp&>()()) 450 __invoke(_Fp& __f) 451 { 452 return __f(); 453 } 454 455 template <class _Fp, class _A0> 456 inline _LIBCPP_INLINE_VISIBILITY 457 decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>())) 458 __invoke(_Fp& __f, _A0& __a0) 459 { 460 return __f(__a0); 461 } 462 463 template <class _Fp, class _A0, class _A1> 464 inline _LIBCPP_INLINE_VISIBILITY 465 decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>(), _VSTD::declval<_A1&>())) 466 __invoke(_Fp& __f, _A0& __a0, _A1& __a1) 467 { 468 return __f(__a0, __a1); 469 } 470 471 template <class _Fp, class _A0, class _A1, class _A2> 472 inline _LIBCPP_INLINE_VISIBILITY 473 decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>(), _VSTD::declval<_A1&>(), _VSTD::declval<_A2&>())) 474 __invoke(_Fp& __f, _A0& __a0, _A1& __a1, _A2& __a2) 475 { 476 return __f(__a0, __a1, __a2); 477 } 478 479 template <class _Fp, bool = __has_result_type<__weak_result_type<_Fp> >::value> 480 struct __invoke_return 481 { 482 typedef typename __weak_result_type<_Fp>::result_type type; 483 }; 484 485 template <class _Fp> 486 struct __invoke_return<_Fp, false> 487 { 488 typedef decltype(__invoke(_VSTD::declval<_Fp&>())) type; 489 }; 490 491 template <class _Tp, class _A0, bool = is_member_object_pointer<_Tp>::value> 492 struct __invoke_return0 493 { 494 typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>())) type; 495 }; 496 497 template <class _Rp, class _Tp, class _A0> 498 struct __invoke_return0<_Rp _Tp::*, _A0, true> 499 { 500 typedef typename __apply_cv<_A0, _Rp>::type& type; 501 }; 502 503 template <class _Rp, class _Tp, class _A0> 504 struct __invoke_return0<_Rp _Tp::*, _A0*, true> 505 { 506 typedef typename __apply_cv<_A0, _Rp>::type& type; 507 }; 508 509 template <class _Tp, class _A0, class _A1> 510 struct __invoke_return1 511 { 512 typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(), 513 _VSTD::declval<_A1&>())) type; 514 }; 515 516 template <class _Tp, class _A0, class _A1, class _A2> 517 struct __invoke_return2 518 { 519 typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(), 520 _VSTD::declval<_A1&>(), 521 _VSTD::declval<_A2&>())) type; 522 }; 523 524 #endif // _LIBCPP_FUNCTIONAL_BASE_03 525