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 
     18 template <class _Ret, class _T1, bool _IsFunc, bool _IsBase>
     19 struct __enable_invoke_imp;
     20 
     21 template <class _Ret, class _T1>
     22 struct __enable_invoke_imp<_Ret, _T1, true, true> {
     23     typedef _Ret _Bullet1;
     24     typedef _Bullet1 type;
     25 };
     26 
     27 template <class _Ret, class _T1>
     28 struct __enable_invoke_imp<_Ret, _T1, true, false>  {
     29     typedef _Ret _Bullet2;
     30     typedef _Bullet2 type;
     31 };
     32 
     33 template <class _Ret, class _T1>
     34 struct __enable_invoke_imp<_Ret, _T1, false, true>  {
     35     typedef typename add_lvalue_reference<
     36                 typename __apply_cv<_T1, _Ret>::type
     37             >::type _Bullet3;
     38     typedef _Bullet3 type;
     39 };
     40 
     41 template <class _Ret, class _T1>
     42 struct __enable_invoke_imp<_Ret, _T1, false, false>  {
     43     typedef typename add_lvalue_reference<
     44                 typename __apply_cv<decltype(*_VSTD::declval<_T1>()), _Ret>::type
     45             >::type _Bullet4;
     46     typedef _Bullet4 type;
     47 };
     48 
     49 template <class _Ret, class _T1>
     50 struct __enable_invoke_imp<_Ret, _T1*, false, false>  {
     51     typedef typename add_lvalue_reference<
     52                 typename __apply_cv<_T1, _Ret>::type
     53             >::type _Bullet4;
     54     typedef _Bullet4  type;
     55 };
     56 
     57 template <class _Fn, class _T1,
     58           class _Traits = __member_pointer_traits<_Fn>,
     59           class _Ret = typename _Traits::_ReturnType,
     60           class _Class = typename _Traits::_ClassType>
     61 struct __enable_invoke : __enable_invoke_imp<
     62     _Ret, _T1,
     63     is_member_function_pointer<_Fn>::value,
     64     is_base_of<_Class, typename remove_reference<_T1>::type>::value>
     65 {
     66 };
     67 
     68 __nat __invoke(__any, ...);
     69 
     70 // first bullet
     71 
     72 template <class _Fn, class _T1>
     73 inline _LIBCPP_INLINE_VISIBILITY
     74 typename __enable_invoke<_Fn, _T1>::_Bullet1
     75 __invoke(_Fn __f, _T1& __t1) {
     76     return (__t1.*__f)();
     77 }
     78 
     79 template <class _Fn, class _T1, class _A0>
     80 inline _LIBCPP_INLINE_VISIBILITY
     81 typename __enable_invoke<_Fn, _T1>::_Bullet1
     82 __invoke(_Fn __f, _T1& __t1, _A0& __a0) {
     83     return (__t1.*__f)(__a0);
     84 }
     85 
     86 template <class _Fn, class _T1, class _A0, class _A1>
     87 inline _LIBCPP_INLINE_VISIBILITY
     88 typename __enable_invoke<_Fn, _T1>::_Bullet1
     89 __invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1) {
     90     return (__t1.*__f)(__a0, __a1);
     91 }
     92 
     93 template <class _Fn, class _T1, class _A0, class _A1, class _A2>
     94 inline _LIBCPP_INLINE_VISIBILITY
     95 typename __enable_invoke<_Fn, _T1>::_Bullet1
     96 __invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) {
     97     return (__t1.*__f)(__a0, __a1, __a2);
     98 }
     99 
    100 template <class _Fn, class _T1>
    101 inline _LIBCPP_INLINE_VISIBILITY
    102 typename __enable_invoke<_Fn, _T1>::_Bullet2
    103 __invoke(_Fn __f, _T1& __t1) {
    104     return ((*__t1).*__f)();
    105 }
    106 
    107 template <class _Fn, class _T1, class _A0>
    108 inline _LIBCPP_INLINE_VISIBILITY
    109 typename __enable_invoke<_Fn, _T1>::_Bullet2
    110 __invoke(_Fn __f, _T1& __t1, _A0& __a0) {
    111     return ((*__t1).*__f)(__a0);
    112 }
    113 
    114 template <class _Fn, class _T1, class _A0, class _A1>
    115 inline _LIBCPP_INLINE_VISIBILITY
    116 typename __enable_invoke<_Fn, _T1>::_Bullet2
    117 __invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1) {
    118     return ((*__t1).*__f)(__a0, __a1);
    119 }
    120 
    121 template <class _Fn, class _T1, class _A0, class _A1, class _A2>
    122 inline _LIBCPP_INLINE_VISIBILITY
    123 typename __enable_invoke<_Fn, _T1>::_Bullet2
    124 __invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) {
    125     return ((*__t1).*__f)(__a0, __a1, __a2);
    126 }
    127 
    128 template <class _Fn, class _T1>
    129 inline _LIBCPP_INLINE_VISIBILITY
    130 typename __enable_invoke<_Fn, _T1>::_Bullet3
    131 __invoke(_Fn __f, _T1& __t1) {
    132     return __t1.*__f;
    133 }
    134 
    135 template <class _Fn, class _T1>
    136 inline _LIBCPP_INLINE_VISIBILITY
    137 typename __enable_invoke<_Fn, _T1>::_Bullet4
    138 __invoke(_Fn __f, _T1& __t1) {
    139     return (*__t1).*__f;
    140 }
    141 
    142 // fifth bullet
    143 
    144 template <class _Fp>
    145 inline _LIBCPP_INLINE_VISIBILITY
    146 decltype(_VSTD::declval<_Fp&>()())
    147 __invoke(_Fp& __f)
    148 {
    149     return __f();
    150 }
    151 
    152 template <class _Fp, class _A0>
    153 inline _LIBCPP_INLINE_VISIBILITY
    154 decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>()))
    155 __invoke(_Fp& __f, _A0& __a0)
    156 {
    157     return __f(__a0);
    158 }
    159 
    160 template <class _Fp, class _A0, class _A1>
    161 inline _LIBCPP_INLINE_VISIBILITY
    162 decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>(), _VSTD::declval<_A1&>()))
    163 __invoke(_Fp& __f, _A0& __a0, _A1& __a1)
    164 {
    165     return __f(__a0, __a1);
    166 }
    167 
    168 template <class _Fp, class _A0, class _A1, class _A2>
    169 inline _LIBCPP_INLINE_VISIBILITY
    170 decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>(), _VSTD::declval<_A1&>(), _VSTD::declval<_A2&>()))
    171 __invoke(_Fp& __f, _A0& __a0, _A1& __a1, _A2& __a2)
    172 {
    173     return __f(__a0, __a1, __a2);
    174 }
    175 
    176 template <class _Fp, bool = __has_result_type<__weak_result_type<_Fp> >::value>
    177 struct __invoke_return
    178 {
    179     typedef typename __weak_result_type<_Fp>::result_type type;
    180 };
    181 
    182 template <class _Fp>
    183 struct __invoke_return<_Fp, false>
    184 {
    185     typedef decltype(__invoke(_VSTD::declval<_Fp&>())) type;
    186 };
    187 
    188 template <class _Tp, class _A0>
    189 struct __invoke_return0
    190 {
    191     typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>())) type;
    192 };
    193 
    194 template <class _Rp, class _Tp, class _A0>
    195 struct __invoke_return0<_Rp _Tp::*, _A0>
    196 {
    197     typedef typename __enable_invoke<_Rp _Tp::*, _A0>::type type;
    198 };
    199 
    200 template <class _Tp, class _A0, class _A1>
    201 struct __invoke_return1
    202 {
    203     typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(),
    204                                                       _VSTD::declval<_A1&>())) type;
    205 };
    206 
    207 template <class _Rp, class _Class, class _A0, class _A1>
    208 struct __invoke_return1<_Rp _Class::*, _A0, _A1> {
    209     typedef typename __enable_invoke<_Rp _Class::*, _A0>::type type;
    210 };
    211 
    212 template <class _Tp, class _A0, class _A1, class _A2>
    213 struct __invoke_return2
    214 {
    215     typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(),
    216                                                       _VSTD::declval<_A1&>(),
    217                                                       _VSTD::declval<_A2&>())) type;
    218 };
    219 
    220 template <class _Ret, class _Class, class _A0, class _A1, class _A2>
    221 struct __invoke_return2<_Ret _Class::*, _A0, _A1, _A2> {
    222     typedef typename __enable_invoke<_Ret _Class::*, _A0>::type type;
    223 };
    224 #endif  // _LIBCPP_FUNCTIONAL_BASE_03
    225