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
19template <class _Rp, class _Tp, class _T1>
20inline _LIBCPP_INLINE_VISIBILITY
21typename 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
31template <class _Rp, class _Tp, class _T1, class _A0>
32inline _LIBCPP_INLINE_VISIBILITY
33typename 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
43template <class _Rp, class _Tp, class _T1, class _A0, class _A1>
44inline _LIBCPP_INLINE_VISIBILITY
45typename 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
55template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
56inline _LIBCPP_INLINE_VISIBILITY
57typename 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
67template <class _Rp, class _Tp, class _T1>
68inline _LIBCPP_INLINE_VISIBILITY
69typename 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
79template <class _Rp, class _Tp, class _T1, class _A0>
80inline _LIBCPP_INLINE_VISIBILITY
81typename 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
91template <class _Rp, class _Tp, class _T1, class _A0, class _A1>
92inline _LIBCPP_INLINE_VISIBILITY
93typename 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
103template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
104inline _LIBCPP_INLINE_VISIBILITY
105typename 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
115template <class _Rp, class _Tp, class _T1>
116inline _LIBCPP_INLINE_VISIBILITY
117typename 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
127template <class _Rp, class _Tp, class _T1, class _A0>
128inline _LIBCPP_INLINE_VISIBILITY
129typename 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
139template <class _Rp, class _Tp, class _T1, class _A0, class _A1>
140inline _LIBCPP_INLINE_VISIBILITY
141typename 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
151template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
152inline _LIBCPP_INLINE_VISIBILITY
153typename 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
163template <class _Rp, class _Tp, class _T1>
164inline _LIBCPP_INLINE_VISIBILITY
165typename 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
175template <class _Rp, class _Tp, class _T1, class _A0>
176inline _LIBCPP_INLINE_VISIBILITY
177typename 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
187template <class _Rp, class _Tp, class _T1, class _A0, class _A1>
188inline _LIBCPP_INLINE_VISIBILITY
189typename 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
199template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
200inline _LIBCPP_INLINE_VISIBILITY
201typename 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
213template <class _Rp, class _Tp, class _T1>
214inline _LIBCPP_INLINE_VISIBILITY
215typename 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
225template <class _Rp, class _Tp, class _T1, class _A0>
226inline _LIBCPP_INLINE_VISIBILITY
227typename 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
237template <class _Rp, class _Tp, class _T1, class _A0, class _A1>
238inline _LIBCPP_INLINE_VISIBILITY
239typename 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
249template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
250inline _LIBCPP_INLINE_VISIBILITY
251typename 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
261template <class _Rp, class _Tp, class _T1>
262inline _LIBCPP_INLINE_VISIBILITY
263typename 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
273template <class _Rp, class _Tp, class _T1, class _A0>
274inline _LIBCPP_INLINE_VISIBILITY
275typename 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
285template <class _Rp, class _Tp, class _T1, class _A0, class _A1>
286inline _LIBCPP_INLINE_VISIBILITY
287typename 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
297template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
298inline _LIBCPP_INLINE_VISIBILITY
299typename 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
309template <class _Rp, class _Tp, class _T1>
310inline _LIBCPP_INLINE_VISIBILITY
311typename 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
321template <class _Rp, class _Tp, class _T1, class _A0>
322inline _LIBCPP_INLINE_VISIBILITY
323typename 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
333template <class _Rp, class _Tp, class _T1, class _A0, class _A1>
334inline _LIBCPP_INLINE_VISIBILITY
335typename 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
345template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
346inline _LIBCPP_INLINE_VISIBILITY
347typename 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
357template <class _Rp, class _Tp, class _T1>
358inline _LIBCPP_INLINE_VISIBILITY
359typename 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
369template <class _Rp, class _Tp, class _T1, class _A0>
370inline _LIBCPP_INLINE_VISIBILITY
371typename 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
381template <class _Rp, class _Tp, class _T1, class _A0, class _A1>
382inline _LIBCPP_INLINE_VISIBILITY
383typename 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
393template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
394inline _LIBCPP_INLINE_VISIBILITY
395typename 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
407template <class _Rp, class _Tp, class _T1>
408inline _LIBCPP_INLINE_VISIBILITY
409typename 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
423template <class _T1, class _Rp, bool>
424struct __4th_helper
425{
426};
427
428template <class _T1, class _Rp>
429struct __4th_helper<_T1, _Rp, true>
430{
431    typedef typename __apply_cv<decltype(*_VSTD::declval<_T1&>()), _Rp>::type type;
432};
433
434template <class _Rp, class _Tp, class _T1>
435inline _LIBCPP_INLINE_VISIBILITY
436typename __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
447template <class _Fp>
448inline _LIBCPP_INLINE_VISIBILITY
449decltype(_VSTD::declval<_Fp&>()())
450__invoke(_Fp& __f)
451{
452    return __f();
453}
454
455template <class _Fp, class _A0>
456inline _LIBCPP_INLINE_VISIBILITY
457decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>()))
458__invoke(_Fp& __f, _A0& __a0)
459{
460    return __f(__a0);
461}
462
463template <class _Fp, class _A0, class _A1>
464inline _LIBCPP_INLINE_VISIBILITY
465decltype(_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
471template <class _Fp, class _A0, class _A1, class _A2>
472inline _LIBCPP_INLINE_VISIBILITY
473decltype(_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
479template <class _Fp, bool = __has_result_type<__weak_result_type<_Fp> >::value>
480struct __invoke_return
481{
482    typedef typename __weak_result_type<_Fp>::result_type type;
483};
484
485template <class _Fp>
486struct __invoke_return<_Fp, false>
487{
488    typedef decltype(__invoke(_VSTD::declval<_Fp&>())) type;
489};
490
491template <class _Tp, class _A0, bool = is_member_object_pointer<_Tp>::value>
492struct __invoke_return0
493{
494    typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>())) type;
495};
496
497template <class _Rp, class _Tp, class _A0>
498struct __invoke_return0<_Rp _Tp::*, _A0, true>
499{
500    typedef typename __apply_cv<_A0, _Rp>::type& type;
501};
502
503template <class _Rp, class _Tp, class _A0>
504struct __invoke_return0<_Rp _Tp::*, _A0*, true>
505{
506    typedef typename __apply_cv<_A0, _Rp>::type& type;
507};
508
509template <class _Tp, class _A0, class _A1>
510struct __invoke_return1
511{
512    typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(),
513                                                     _VSTD::declval<_A1&>())) type;
514};
515
516template <class _Tp, class _A0, class _A1, class _A2>
517struct __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