blob: 8407dcfa39ca3688411966d33aa44c343a4994d2 [file] [log] [blame]
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
Howard Hinnantf5256e12010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005//
Howard Hinnantb64f8b02010-11-16 22:09:02 +00006// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00008//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_FUNCTIONAL_BASE_03
12#define _LIBCPP_FUNCTIONAL_BASE_03
13
14// manual variadic expansion for <functional>
15
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000016// __invoke
Dan Austinee226c02016-06-08 22:25:43 +000017
18template <class _Ret, class _T1, bool _IsFunc, bool _IsBase>
19struct __enable_invoke_imp;
20
21template <class _Ret, class _T1>
22struct __enable_invoke_imp<_Ret, _T1, true, true> {
23 typedef _Ret _Bullet1;
24 typedef _Bullet1 type;
25};
26
27template <class _Ret, class _T1>
28struct __enable_invoke_imp<_Ret, _T1, true, false> {
29 typedef _Ret _Bullet2;
30 typedef _Bullet2 type;
31};
32
33template <class _Ret, class _T1>
34struct __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
41template <class _Ret, class _T1>
42struct __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
49template <class _Ret, class _T1>
50struct __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
57template <class _Fn, class _T1,
58 class _Traits = __member_pointer_traits<_Fn>,
59 class _Ret = typename _Traits::_ReturnType,
60 class _Class = typename _Traits::_ClassType>
61struct __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
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000070// first bullet
71
Dan Austinee226c02016-06-08 22:25:43 +000072template <class _Fn, class _T1>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000073inline _LIBCPP_INLINE_VISIBILITY
Dan Austinee226c02016-06-08 22:25:43 +000074typename __enable_invoke<_Fn, _T1>::_Bullet1
75__invoke(_Fn __f, _T1& __t1) {
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000076 return (__t1.*__f)();
77}
78
Dan Austinee226c02016-06-08 22:25:43 +000079template <class _Fn, class _T1, class _A0>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000080inline _LIBCPP_INLINE_VISIBILITY
Dan Austinee226c02016-06-08 22:25:43 +000081typename __enable_invoke<_Fn, _T1>::_Bullet1
82__invoke(_Fn __f, _T1& __t1, _A0& __a0) {
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000083 return (__t1.*__f)(__a0);
84}
85
Dan Austinee226c02016-06-08 22:25:43 +000086template <class _Fn, class _T1, class _A0, class _A1>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000087inline _LIBCPP_INLINE_VISIBILITY
Dan Austinee226c02016-06-08 22:25:43 +000088typename __enable_invoke<_Fn, _T1>::_Bullet1
89__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1) {
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000090 return (__t1.*__f)(__a0, __a1);
91}
92
Dan Austinee226c02016-06-08 22:25:43 +000093template <class _Fn, class _T1, class _A0, class _A1, class _A2>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000094inline _LIBCPP_INLINE_VISIBILITY
Dan Austinee226c02016-06-08 22:25:43 +000095typename __enable_invoke<_Fn, _T1>::_Bullet1
96__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) {
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000097 return (__t1.*__f)(__a0, __a1, __a2);
98}
99
Dan Austinee226c02016-06-08 22:25:43 +0000100template <class _Fn, class _T1>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000101inline _LIBCPP_INLINE_VISIBILITY
Dan Austinee226c02016-06-08 22:25:43 +0000102typename __enable_invoke<_Fn, _T1>::_Bullet2
103__invoke(_Fn __f, _T1& __t1) {
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000104 return ((*__t1).*__f)();
105}
106
Dan Austinee226c02016-06-08 22:25:43 +0000107template <class _Fn, class _T1, class _A0>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000108inline _LIBCPP_INLINE_VISIBILITY
Dan Austinee226c02016-06-08 22:25:43 +0000109typename __enable_invoke<_Fn, _T1>::_Bullet2
110__invoke(_Fn __f, _T1& __t1, _A0& __a0) {
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000111 return ((*__t1).*__f)(__a0);
112}
113
Dan Austinee226c02016-06-08 22:25:43 +0000114template <class _Fn, class _T1, class _A0, class _A1>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000115inline _LIBCPP_INLINE_VISIBILITY
Dan Austinee226c02016-06-08 22:25:43 +0000116typename __enable_invoke<_Fn, _T1>::_Bullet2
117__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1) {
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000118 return ((*__t1).*__f)(__a0, __a1);
119}
120
Dan Austinee226c02016-06-08 22:25:43 +0000121template <class _Fn, class _T1, class _A0, class _A1, class _A2>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000122inline _LIBCPP_INLINE_VISIBILITY
Dan Austinee226c02016-06-08 22:25:43 +0000123typename __enable_invoke<_Fn, _T1>::_Bullet2
124__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) {
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000125 return ((*__t1).*__f)(__a0, __a1, __a2);
126}
127
Dan Austinee226c02016-06-08 22:25:43 +0000128template <class _Fn, class _T1>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000129inline _LIBCPP_INLINE_VISIBILITY
Dan Austinee226c02016-06-08 22:25:43 +0000130typename __enable_invoke<_Fn, _T1>::_Bullet3
131__invoke(_Fn __f, _T1& __t1) {
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000132 return __t1.*__f;
133}
134
Dan Austinee226c02016-06-08 22:25:43 +0000135template <class _Fn, class _T1>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000136inline _LIBCPP_INLINE_VISIBILITY
Dan Austinee226c02016-06-08 22:25:43 +0000137typename __enable_invoke<_Fn, _T1>::_Bullet4
138__invoke(_Fn __f, _T1& __t1) {
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000139 return (*__t1).*__f;
140}
141
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000142// fifth bullet
143
Howard Hinnant99968442011-11-29 18:15:50 +0000144template <class _Fp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000145inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier12ddf2c2015-07-28 01:52:08 +0000146decltype(_VSTD::declval<_Fp&>()())
147__invoke(_Fp& __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000148{
149 return __f();
150}
151
Howard Hinnant99968442011-11-29 18:15:50 +0000152template <class _Fp, class _A0>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000153inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier12ddf2c2015-07-28 01:52:08 +0000154decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>()))
155__invoke(_Fp& __f, _A0& __a0)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000156{
157 return __f(__a0);
158}
159
Howard Hinnant99968442011-11-29 18:15:50 +0000160template <class _Fp, class _A0, class _A1>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000161inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier12ddf2c2015-07-28 01:52:08 +0000162decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>(), _VSTD::declval<_A1&>()))
163__invoke(_Fp& __f, _A0& __a0, _A1& __a1)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000164{
165 return __f(__a0, __a1);
166}
167
Howard Hinnant99968442011-11-29 18:15:50 +0000168template <class _Fp, class _A0, class _A1, class _A2>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000169inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier12ddf2c2015-07-28 01:52:08 +0000170decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>(), _VSTD::declval<_A1&>(), _VSTD::declval<_A2&>()))
171__invoke(_Fp& __f, _A0& __a0, _A1& __a1, _A2& __a2)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000172{
173 return __f(__a0, __a1, __a2);
174}
175
Howard Hinnant99968442011-11-29 18:15:50 +0000176template <class _Fp, bool = __has_result_type<__weak_result_type<_Fp> >::value>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000177struct __invoke_return
178{
Howard Hinnant99968442011-11-29 18:15:50 +0000179 typedef typename __weak_result_type<_Fp>::result_type type;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000180};
181
Howard Hinnant99968442011-11-29 18:15:50 +0000182template <class _Fp>
183struct __invoke_return<_Fp, false>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000184{
Eric Fiselier12ddf2c2015-07-28 01:52:08 +0000185 typedef decltype(__invoke(_VSTD::declval<_Fp&>())) type;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000186};
187
Dan Austinee226c02016-06-08 22:25:43 +0000188template <class _Tp, class _A0>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000189struct __invoke_return0
190{
Eric Fiselier12ddf2c2015-07-28 01:52:08 +0000191 typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>())) type;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000192};
193
Howard Hinnant99968442011-11-29 18:15:50 +0000194template <class _Rp, class _Tp, class _A0>
Dan Austinee226c02016-06-08 22:25:43 +0000195struct __invoke_return0<_Rp _Tp::*, _A0>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000196{
Dan Austinee226c02016-06-08 22:25:43 +0000197 typedef typename __enable_invoke<_Rp _Tp::*, _A0>::type type;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000198};
199
200template <class _Tp, class _A0, class _A1>
201struct __invoke_return1
202{
Eric Fiselier12ddf2c2015-07-28 01:52:08 +0000203 typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(),
Dan Austinee226c02016-06-08 22:25:43 +0000204 _VSTD::declval<_A1&>())) type;
205};
206
207template <class _Rp, class _Class, class _A0, class _A1>
208struct __invoke_return1<_Rp _Class::*, _A0, _A1> {
209 typedef typename __enable_invoke<_Rp _Class::*, _A0>::type type;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000210};
211
212template <class _Tp, class _A0, class _A1, class _A2>
213struct __invoke_return2
214{
Eric Fiselier12ddf2c2015-07-28 01:52:08 +0000215 typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(),
216 _VSTD::declval<_A1&>(),
217 _VSTD::declval<_A2&>())) type;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000218};
219
Dan Austinee226c02016-06-08 22:25:43 +0000220template <class _Ret, class _Class, class _A0, class _A1, class _A2>
221struct __invoke_return2<_Ret _Class::*, _A0, _A1, _A2> {
222 typedef typename __enable_invoke<_Ret _Class::*, _A0>::type type;
223};
Howard Hinnant324bb032010-08-22 00:02:43 +0000224#endif // _LIBCPP_FUNCTIONAL_BASE_03