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
12#define _LIBCPP_FUNCTIONAL_BASE
13
14#include <__config>
15#include <type_traits>
16#include <typeinfo>
17#include <exception>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20#pragma GCC system_header
21#endif
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25template <class _Arg, class _Result>
26struct _LIBCPP_VISIBLE unary_function
27{
28    typedef _Arg    argument_type;
29    typedef _Result result_type;
30};
31
32template <class _Arg1, class _Arg2, class _Result>
33struct _LIBCPP_VISIBLE binary_function
34{
35    typedef _Arg1   first_argument_type;
36    typedef _Arg2   second_argument_type;
37    typedef _Result result_type;
38};
39
40template <class _Tp> struct _LIBCPP_VISIBLE hash;
41
42template <class _Tp>
43struct __has_result_type
44{
45private:
46    struct __two {char _; char __;};
47    template <class _Up> static __two __test(...);
48    template <class _Up> static char __test(typename _Up::result_type* = 0);
49public:
50    static const bool value = sizeof(__test<_Tp>(0)) == 1;
51};
52
53#ifdef _LIBCPP_HAS_NO_VARIADICS
54
55#include <__functional_base_03>
56
57#else  // _LIBCPP_HAS_NO_VARIADICS
58
59// __weak_result_type
60
61template <class _Tp>
62struct __derives_from_unary_function
63{
64private:
65    struct __two {char _; char __;};
66    static __two __test(...);
67    template <class _A, class _R>
68        static unary_function<_A, _R>
69        __test(const volatile unary_function<_A, _R>*);
70public:
71    static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
72    typedef decltype(__test((_Tp*)0)) type;
73};
74
75template <class _Tp>
76struct __derives_from_binary_function
77{
78private:
79    struct __two {char _; char __;};
80    static __two __test(...);
81    template <class _A1, class _A2, class _R>
82        static binary_function<_A1, _A2, _R>
83        __test(const volatile binary_function<_A1, _A2, _R>*);
84public:
85    static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
86    typedef decltype(__test((_Tp*)0)) type;
87};
88
89template <class _Tp, bool = __derives_from_unary_function<_Tp>::value>
90struct __maybe_derive_from_unary_function  // bool is true
91    : public __derives_from_unary_function<_Tp>::type
92{
93};
94
95template <class _Tp>
96struct __maybe_derive_from_unary_function<_Tp, false>
97{
98};
99
100template <class _Tp, bool = __derives_from_binary_function<_Tp>::value>
101struct __maybe_derive_from_binary_function  // bool is true
102    : public __derives_from_binary_function<_Tp>::type
103{
104};
105
106template <class _Tp>
107struct __maybe_derive_from_binary_function<_Tp, false>
108{
109};
110
111template <class _Tp, bool = __has_result_type<_Tp>::value>
112struct __weak_result_type_imp // bool is true
113    : public __maybe_derive_from_unary_function<_Tp>,
114      public __maybe_derive_from_binary_function<_Tp>
115{
116    typedef typename _Tp::result_type result_type;
117};
118
119template <class _Tp>
120struct __weak_result_type_imp<_Tp, false>
121    : public __maybe_derive_from_unary_function<_Tp>,
122      public __maybe_derive_from_binary_function<_Tp>
123{
124};
125
126template <class _Tp>
127struct __weak_result_type
128    : public __weak_result_type_imp<_Tp>
129{
130};
131
132// 0 argument case
133
134template <class _R>
135struct __weak_result_type<_R ()>
136{
137    typedef _R result_type;
138};
139
140template <class _R>
141struct __weak_result_type<_R (&)()>
142{
143    typedef _R result_type;
144};
145
146template <class _R>
147struct __weak_result_type<_R (*)()>
148{
149    typedef _R result_type;
150};
151
152// 1 argument case
153
154template <class _R, class _A1>
155struct __weak_result_type<_R (_A1)>
156    : public unary_function<_A1, _R>
157{
158};
159
160template <class _R, class _A1>
161struct __weak_result_type<_R (&)(_A1)>
162    : public unary_function<_A1, _R>
163{
164};
165
166template <class _R, class _A1>
167struct __weak_result_type<_R (*)(_A1)>
168    : public unary_function<_A1, _R>
169{
170};
171
172template <class _R, class _C>
173struct __weak_result_type<_R (_C::*)()>
174    : public unary_function<_C*, _R>
175{
176};
177
178template <class _R, class _C>
179struct __weak_result_type<_R (_C::*)() const>
180    : public unary_function<const _C*, _R>
181{
182};
183
184template <class _R, class _C>
185struct __weak_result_type<_R (_C::*)() volatile>
186    : public unary_function<volatile _C*, _R>
187{
188};
189
190template <class _R, class _C>
191struct __weak_result_type<_R (_C::*)() const volatile>
192    : public unary_function<const volatile _C*, _R>
193{
194};
195
196// 2 argument case
197
198template <class _R, class _A1, class _A2>
199struct __weak_result_type<_R (_A1, _A2)>
200    : public binary_function<_A1, _A2, _R>
201{
202};
203
204template <class _R, class _A1, class _A2>
205struct __weak_result_type<_R (*)(_A1, _A2)>
206    : public binary_function<_A1, _A2, _R>
207{
208};
209
210template <class _R, class _A1, class _A2>
211struct __weak_result_type<_R (&)(_A1, _A2)>
212    : public binary_function<_A1, _A2, _R>
213{
214};
215
216template <class _R, class _C, class _A1>
217struct __weak_result_type<_R (_C::*)(_A1)>
218    : public binary_function<_C*, _A1, _R>
219{
220};
221
222template <class _R, class _C, class _A1>
223struct __weak_result_type<_R (_C::*)(_A1) const>
224    : public binary_function<const _C*, _A1, _R>
225{
226};
227
228template <class _R, class _C, class _A1>
229struct __weak_result_type<_R (_C::*)(_A1) volatile>
230    : public binary_function<volatile _C*, _A1, _R>
231{
232};
233
234template <class _R, class _C, class _A1>
235struct __weak_result_type<_R (_C::*)(_A1) const volatile>
236    : public binary_function<const volatile _C*, _A1, _R>
237{
238};
239
240// 3 or more arguments
241
242template <class _R, class _A1, class _A2, class _A3, class ..._A4>
243struct __weak_result_type<_R (_A1, _A2, _A3, _A4...)>
244{
245    typedef _R result_type;
246};
247
248template <class _R, class _A1, class _A2, class _A3, class ..._A4>
249struct __weak_result_type<_R (&)(_A1, _A2, _A3, _A4...)>
250{
251    typedef _R result_type;
252};
253
254template <class _R, class _A1, class _A2, class _A3, class ..._A4>
255struct __weak_result_type<_R (*)(_A1, _A2, _A3, _A4...)>
256{
257    typedef _R result_type;
258};
259
260template <class _R, class _C, class _A1, class _A2, class ..._A3>
261struct __weak_result_type<_R (_C::*)(_A1, _A2, _A3...)>
262{
263    typedef _R result_type;
264};
265
266template <class _R, class _C, class _A1, class _A2, class ..._A3>
267struct __weak_result_type<_R (_C::*)(_A1, _A2, _A3...) const>
268{
269    typedef _R result_type;
270};
271
272template <class _R, class _C, class _A1, class _A2, class ..._A3>
273struct __weak_result_type<_R (_C::*)(_A1, _A2, _A3...) volatile>
274{
275    typedef _R result_type;
276};
277
278template <class _R, class _C, class _A1, class _A2, class ..._A3>
279struct __weak_result_type<_R (_C::*)(_A1, _A2, _A3...) const volatile>
280{
281    typedef _R result_type;
282};
283
284// __invoke
285
286// bullets 1 and 2
287
288template <class _F, class _A0, class ..._Args>
289inline _LIBCPP_INLINE_VISIBILITY
290auto
291__invoke(_F&& __f, _A0&& __a0, _Args&& ...__args)
292    -> decltype((_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...))
293{
294    return (_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...);
295}
296
297template <class _F, class _A0, class ..._Args>
298inline _LIBCPP_INLINE_VISIBILITY
299auto
300__invoke(_F&& __f, _A0&& __a0, _Args&& ...__args)
301    -> decltype(((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...))
302{
303    return ((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...);
304}
305
306// bullets 3 and 4
307
308template <class _F, class _A0>
309inline _LIBCPP_INLINE_VISIBILITY
310auto
311__invoke(_F&& __f, _A0&& __a0)
312    -> decltype(_VSTD::forward<_A0>(__a0).*__f)
313{
314    return _VSTD::forward<_A0>(__a0).*__f;
315}
316
317template <class _F, class _A0>
318inline _LIBCPP_INLINE_VISIBILITY
319auto
320__invoke(_F&& __f, _A0&& __a0)
321    -> decltype((*_VSTD::forward<_A0>(__a0)).*__f)
322{
323    return (*_VSTD::forward<_A0>(__a0)).*__f;
324}
325
326// bullet 5
327
328template <class _F, class ..._Args>
329inline _LIBCPP_INLINE_VISIBILITY
330auto
331__invoke(_F&& __f, _Args&& ...__args)
332    -> decltype(_VSTD::forward<_F>(__f)(_VSTD::forward<_Args>(__args)...))
333{
334    return _VSTD::forward<_F>(__f)(_VSTD::forward<_Args>(__args)...);
335}
336
337template <class _Tp, class ..._Args>
338struct __invoke_return
339{
340    typedef decltype(__invoke(_VSTD::declval<_Tp>(), _VSTD::declval<_Args>()...)) type;
341};
342
343template <class _Tp>
344class _LIBCPP_VISIBLE reference_wrapper
345    : public __weak_result_type<_Tp>
346{
347public:
348    // types
349    typedef _Tp type;
350private:
351    type* __f_;
352
353public:
354    // construct/copy/destroy
355    _LIBCPP_INLINE_VISIBILITY reference_wrapper(type& __f) _NOEXCEPT : __f_(&__f) {}
356#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
357    private: reference_wrapper(type&&); public: // = delete; // do not bind to temps
358#endif
359
360    // access
361    _LIBCPP_INLINE_VISIBILITY operator type&    () const _NOEXCEPT {return *__f_;}
362    _LIBCPP_INLINE_VISIBILITY          type& get() const _NOEXCEPT {return *__f_;}
363
364    // invoke
365    template <class... _ArgTypes>
366       _LIBCPP_INLINE_VISIBILITY
367       typename __invoke_of<type&, _ArgTypes...>::type
368          operator() (_ArgTypes&&... __args) const
369          {
370              return __invoke(get(), _VSTD::forward<_ArgTypes>(__args)...);
371          }
372};
373
374template <class _Tp> struct ____is_reference_wrapper : public false_type {};
375template <class _Tp> struct ____is_reference_wrapper<reference_wrapper<_Tp> > : public true_type {};
376template <class _Tp> struct __is_reference_wrapper
377    : public ____is_reference_wrapper<typename remove_cv<_Tp>::type> {};
378
379template <class _Tp>
380inline _LIBCPP_INLINE_VISIBILITY
381reference_wrapper<_Tp>
382ref(_Tp& __t) _NOEXCEPT
383{
384    return reference_wrapper<_Tp>(__t);
385}
386
387template <class _Tp>
388inline _LIBCPP_INLINE_VISIBILITY
389reference_wrapper<_Tp>
390ref(reference_wrapper<_Tp> __t) _NOEXCEPT
391{
392    return ref(__t.get());
393}
394
395template <class _Tp>
396inline _LIBCPP_INLINE_VISIBILITY
397reference_wrapper<const _Tp>
398cref(const _Tp& __t) _NOEXCEPT
399{
400    return reference_wrapper<const _Tp>(__t);
401}
402
403template <class _Tp>
404inline _LIBCPP_INLINE_VISIBILITY
405reference_wrapper<const _Tp>
406cref(reference_wrapper<_Tp> __t) _NOEXCEPT
407{
408    return cref(__t.get());
409}
410
411#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
412#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
413
414template <class _Tp> void ref(const _Tp&& __t) = delete;
415template <class _Tp> void cref(const _Tp&& __t) = delete;
416
417#else  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
418
419template <class _Tp> void ref(const _Tp&& __t);// = delete;
420template <class _Tp> void cref(const _Tp&& __t);// = delete;
421
422#endif  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
423
424#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
425
426#endif  // _LIBCPP_HAS_NO_VARIADICS
427
428_LIBCPP_END_NAMESPACE_STD
429
430#endif  // _LIBCPP_FUNCTIONAL_BASE
431