blob: f2aa5041b87be84a99d4a705e8395ce94e8ab9d3 [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
12#define _LIBCPP_FUNCTIONAL_BASE
13
14#include <__config>
15#include <type_traits>
16#include <typeinfo>
17#include <exception>
18
19#pragma GCC system_header
20
21_LIBCPP_BEGIN_NAMESPACE_STD
22
23template <class _Arg, class _Result>
Howard Hinnant99acc502010-09-21 17:32:39 +000024struct _LIBCPP_VISIBLE unary_function
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000025{
26 typedef _Arg argument_type;
27 typedef _Result result_type;
28};
29
30template <class _Arg1, class _Arg2, class _Result>
Howard Hinnant99acc502010-09-21 17:32:39 +000031struct _LIBCPP_VISIBLE binary_function
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000032{
33 typedef _Arg1 first_argument_type;
34 typedef _Arg2 second_argument_type;
35 typedef _Result result_type;
36};
37
Howard Hinnant99acc502010-09-21 17:32:39 +000038template <class _Tp> struct _LIBCPP_VISIBLE hash;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000039
40template <class _Tp>
41struct __has_result_type
42{
43private:
44 struct __two {char _; char __;};
45 template <class _Up> static __two __test(...);
46 template <class _Up> static char __test(typename _Up::result_type* = 0);
47public:
48 static const bool value = sizeof(__test<_Tp>(0)) == 1;
49};
50
51#ifdef _LIBCPP_HAS_NO_VARIADICS
52
53#include <__functional_base_03>
54
55#else // _LIBCPP_HAS_NO_VARIADICS
56
57// __weak_result_type
58
59template <class _Tp>
60struct __derives_from_unary_function
61{
62private:
63 struct __two {char _; char __;};
64 static __two __test(...);
65 template <class _A, class _R>
66 static unary_function<_A, _R>
67 __test(const volatile unary_function<_A, _R>*);
68public:
69 static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
70 typedef decltype(__test((_Tp*)0)) type;
71};
72
73template <class _Tp>
74struct __derives_from_binary_function
75{
76private:
77 struct __two {char _; char __;};
78 static __two __test(...);
79 template <class _A1, class _A2, class _R>
80 static binary_function<_A1, _A2, _R>
81 __test(const volatile binary_function<_A1, _A2, _R>*);
82public:
83 static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
84 typedef decltype(__test((_Tp*)0)) type;
85};
86
87template <class _Tp, bool = __derives_from_unary_function<_Tp>::value>
88struct __maybe_derive_from_unary_function // bool is true
89 : public __derives_from_unary_function<_Tp>::type
90{
91};
92
93template <class _Tp>
94struct __maybe_derive_from_unary_function<_Tp, false>
95{
96};
97
98template <class _Tp, bool = __derives_from_binary_function<_Tp>::value>
99struct __maybe_derive_from_binary_function // bool is true
100 : public __derives_from_binary_function<_Tp>::type
101{
102};
103
104template <class _Tp>
105struct __maybe_derive_from_binary_function<_Tp, false>
106{
107};
108
109template <class _Tp, bool = __has_result_type<_Tp>::value>
110struct __weak_result_type_imp // bool is true
111 : public __maybe_derive_from_unary_function<_Tp>,
112 public __maybe_derive_from_binary_function<_Tp>
113{
114 typedef typename _Tp::result_type result_type;
115};
116
117template <class _Tp>
118struct __weak_result_type_imp<_Tp, false>
119 : public __maybe_derive_from_unary_function<_Tp>,
120 public __maybe_derive_from_binary_function<_Tp>
121{
122};
123
124template <class _Tp>
125struct __weak_result_type
126 : public __weak_result_type_imp<_Tp>
127{
128};
129
130// 0 argument case
131
132template <class _R>
133struct __weak_result_type<_R ()>
134{
135 typedef _R result_type;
136};
137
138template <class _R>
139struct __weak_result_type<_R (&)()>
140{
141 typedef _R result_type;
142};
143
144template <class _R>
145struct __weak_result_type<_R (*)()>
146{
147 typedef _R result_type;
148};
149
150// 1 argument case
151
152template <class _R, class _A1>
153struct __weak_result_type<_R (_A1)>
154 : public unary_function<_A1, _R>
155{
156};
157
158template <class _R, class _A1>
159struct __weak_result_type<_R (&)(_A1)>
160 : public unary_function<_A1, _R>
161{
162};
163
164template <class _R, class _A1>
165struct __weak_result_type<_R (*)(_A1)>
166 : public unary_function<_A1, _R>
167{
168};
169
170template <class _R, class _C>
171struct __weak_result_type<_R (_C::*)()>
172 : public unary_function<_C*, _R>
173{
174};
175
176template <class _R, class _C>
177struct __weak_result_type<_R (_C::*)() const>
178 : public unary_function<const _C*, _R>
179{
180};
181
182template <class _R, class _C>
183struct __weak_result_type<_R (_C::*)() volatile>
184 : public unary_function<volatile _C*, _R>
185{
186};
187
188template <class _R, class _C>
189struct __weak_result_type<_R (_C::*)() const volatile>
190 : public unary_function<const volatile _C*, _R>
191{
192};
193
194// 2 argument case
195
196template <class _R, class _A1, class _A2>
197struct __weak_result_type<_R (_A1, _A2)>
198 : public binary_function<_A1, _A2, _R>
199{
200};
201
202template <class _R, class _A1, class _A2>
203struct __weak_result_type<_R (*)(_A1, _A2)>
204 : public binary_function<_A1, _A2, _R>
205{
206};
207
208template <class _R, class _A1, class _A2>
209struct __weak_result_type<_R (&)(_A1, _A2)>
210 : public binary_function<_A1, _A2, _R>
211{
212};
213
214template <class _R, class _C, class _A1>
215struct __weak_result_type<_R (_C::*)(_A1)>
216 : public binary_function<_C*, _A1, _R>
217{
218};
219
220template <class _R, class _C, class _A1>
221struct __weak_result_type<_R (_C::*)(_A1) const>
222 : public binary_function<const _C*, _A1, _R>
223{
224};
225
226template <class _R, class _C, class _A1>
227struct __weak_result_type<_R (_C::*)(_A1) volatile>
228 : public binary_function<volatile _C*, _A1, _R>
229{
230};
231
232template <class _R, class _C, class _A1>
233struct __weak_result_type<_R (_C::*)(_A1) const volatile>
234 : public binary_function<const volatile _C*, _A1, _R>
235{
236};
237
238// 3 or more arguments
239
240template <class _R, class _A1, class _A2, class _A3, class ..._A4>
241struct __weak_result_type<_R (_A1, _A2, _A3, _A4...)>
242{
243 typedef _R result_type;
244};
245
246template <class _R, class _A1, class _A2, class _A3, class ..._A4>
247struct __weak_result_type<_R (&)(_A1, _A2, _A3, _A4...)>
248{
249 typedef _R result_type;
250};
251
252template <class _R, class _A1, class _A2, class _A3, class ..._A4>
253struct __weak_result_type<_R (*)(_A1, _A2, _A3, _A4...)>
254{
255 typedef _R result_type;
256};
257
258template <class _R, class _C, class _A1, class _A2, class ..._A3>
259struct __weak_result_type<_R (_C::*)(_A1, _A2, _A3...)>
260{
261 typedef _R result_type;
262};
263
264template <class _R, class _C, class _A1, class _A2, class ..._A3>
265struct __weak_result_type<_R (_C::*)(_A1, _A2, _A3...) const>
266{
267 typedef _R result_type;
268};
269
270template <class _R, class _C, class _A1, class _A2, class ..._A3>
271struct __weak_result_type<_R (_C::*)(_A1, _A2, _A3...) volatile>
272{
273 typedef _R result_type;
274};
275
276template <class _R, class _C, class _A1, class _A2, class ..._A3>
277struct __weak_result_type<_R (_C::*)(_A1, _A2, _A3...) const volatile>
278{
279 typedef _R result_type;
280};
281
282// __invoke
283
Howard Hinnantbd89e4b2011-05-20 22:02:53 +0000284// bullets 1 and 2
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000285
Howard Hinnantbd89e4b2011-05-20 22:02:53 +0000286template <class _F, class _A0, class ..._Args>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000287inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbd89e4b2011-05-20 22:02:53 +0000288auto
289__invoke(_F&& __f, _A0&& __a0, _Args&& ...__args)
290 -> decltype((_STD::forward<_A0>(__a0).*__f)(_STD::forward<_Args>(__args)...))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000291{
Howard Hinnantbd89e4b2011-05-20 22:02:53 +0000292 return (_STD::forward<_A0>(__a0).*__f)(_STD::forward<_Args>(__args)...);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000293}
294
Howard Hinnantbd89e4b2011-05-20 22:02:53 +0000295template <class _F, class _A0, class ..._Args>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000296inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbd89e4b2011-05-20 22:02:53 +0000297auto
298__invoke(_F&& __f, _A0&& __a0, _Args&& ...__args)
299 -> decltype(((*_STD::forward<_A0>(__a0)).*__f)(_STD::forward<_Args>(__args)...))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000300{
Howard Hinnantbd89e4b2011-05-20 22:02:53 +0000301 return ((*_STD::forward<_A0>(__a0)).*__f)(_STD::forward<_Args>(__args)...);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000302}
303
Howard Hinnantbd89e4b2011-05-20 22:02:53 +0000304// bullets 3 and 4
305
306template <class _F, class _A0>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000307inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbd89e4b2011-05-20 22:02:53 +0000308auto
309__invoke(_F&& __f, _A0&& __a0)
310 -> decltype(_STD::forward<_A0>(__a0).*__f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000311{
Howard Hinnantbd89e4b2011-05-20 22:02:53 +0000312 return _STD::forward<_A0>(__a0).*__f;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000313}
314
Howard Hinnantbd89e4b2011-05-20 22:02:53 +0000315template <class _F, class _A0>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000316inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbd89e4b2011-05-20 22:02:53 +0000317auto
318__invoke(_F&& __f, _A0&& __a0)
319 -> decltype((*_STD::forward<_A0>(__a0)).*__f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000320{
Howard Hinnantbd89e4b2011-05-20 22:02:53 +0000321 return (*_STD::forward<_A0>(__a0)).*__f;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000322}
323
Howard Hinnantbd89e4b2011-05-20 22:02:53 +0000324// bullet 5
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000325
Howard Hinnantbd89e4b2011-05-20 22:02:53 +0000326template <class _F, class ..._Args>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000327inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbd89e4b2011-05-20 22:02:53 +0000328auto
329__invoke(_F&& __f, _Args&& ...__args)
330 -> decltype(_STD::forward<_F>(__f)(_STD::forward<_Args>(__args)...))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000331{
Howard Hinnantbd89e4b2011-05-20 22:02:53 +0000332 return _STD::forward<_F>(__f)(_STD::forward<_Args>(__args)...);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000333}
334
335template <class _Tp, class ..._Args>
336struct __invoke_return
337{
338 typedef decltype(__invoke(_STD::declval<_Tp>(), _STD::declval<_Args>()...)) type;
339};
340
341template <class _Tp>
Howard Hinnant99acc502010-09-21 17:32:39 +0000342class _LIBCPP_VISIBLE reference_wrapper
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000343 : public __weak_result_type<_Tp>
344{
345public:
346 // types
347 typedef _Tp type;
348private:
349 type* __f_;
350
351public:
352 // construct/copy/destroy
Howard Hinnant603d2c02011-05-28 17:59:48 +0000353 _LIBCPP_INLINE_VISIBILITY reference_wrapper(type& __f) _NOEXCEPT : __f_(&__f) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000354#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000355 private: reference_wrapper(type&&); public: // = delete; // do not bind to temps
356#endif
357
358 // access
Howard Hinnant603d2c02011-05-28 17:59:48 +0000359 _LIBCPP_INLINE_VISIBILITY operator type& () const _NOEXCEPT {return *__f_;}
360 _LIBCPP_INLINE_VISIBILITY type& get() const _NOEXCEPT {return *__f_;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000361
362 // invoke
363 template <class... _ArgTypes>
Howard Hinnant99acc502010-09-21 17:32:39 +0000364 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant57cff292011-05-19 15:05:04 +0000365 typename __invoke_of<type&, _ArgTypes...>::type
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000366 operator() (_ArgTypes&&... __args) const
367 {
368 return __invoke(get(), _STD::forward<_ArgTypes>(__args)...);
369 }
370};
371
372template <class _Tp> struct ____is_reference_wrapper : public false_type {};
373template <class _Tp> struct ____is_reference_wrapper<reference_wrapper<_Tp> > : public true_type {};
374template <class _Tp> struct __is_reference_wrapper
375 : public ____is_reference_wrapper<typename remove_cv<_Tp>::type> {};
376
377template <class _Tp>
378inline _LIBCPP_INLINE_VISIBILITY
379reference_wrapper<_Tp>
Howard Hinnant603d2c02011-05-28 17:59:48 +0000380ref(_Tp& __t) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000381{
382 return reference_wrapper<_Tp>(__t);
383}
384
385template <class _Tp>
386inline _LIBCPP_INLINE_VISIBILITY
387reference_wrapper<_Tp>
Howard Hinnant603d2c02011-05-28 17:59:48 +0000388ref(reference_wrapper<_Tp> __t) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000389{
390 return ref(__t.get());
391}
392
393template <class _Tp>
394inline _LIBCPP_INLINE_VISIBILITY
395reference_wrapper<const _Tp>
Howard Hinnant603d2c02011-05-28 17:59:48 +0000396cref(const _Tp& __t) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000397{
398 return reference_wrapper<const _Tp>(__t);
399}
400
401template <class _Tp>
402inline _LIBCPP_INLINE_VISIBILITY
403reference_wrapper<const _Tp>
Howard Hinnant603d2c02011-05-28 17:59:48 +0000404cref(reference_wrapper<_Tp> __t) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000405{
406 return cref(__t.get());
407}
408
Howard Hinnant73d21a42010-09-04 23:28:19 +0000409#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
410#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
411
412template <class _Tp> void ref(const _Tp&& __t) = delete;
413template <class _Tp> void cref(const _Tp&& __t) = delete;
414
415#else // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
416
417template <class _Tp> void ref(const _Tp&& __t);// = delete;
418template <class _Tp> void cref(const _Tp&& __t);// = delete;
419
420#endif // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
421
422#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000423
424#endif // _LIBCPP_HAS_NO_VARIADICS
425
426_LIBCPP_END_NAMESPACE_STD
427
428#endif // _LIBCPP_FUNCTIONAL_BASE