Home | History | Annotate | Download | only in include
      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