blob: 518c9b7afe6ad323815c31cb1a53f3d5fd63deba [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
284// first bullet
285
286template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
287inline _LIBCPP_INLINE_VISIBILITY
288typename enable_if
289<
290 sizeof...(_Param) == sizeof...(_Arg) &&
291 is_base_of<_T, typename remove_reference<_T1>::type>::value,
292 _R
293>::type
294__invoke(_R (_T::*__f)(_Param...), _T1&& __t1, _Arg&& ...__arg)
295{
296 return (_STD::forward<_T>(__t1).*__f)(_STD::forward<_Arg>(__arg)...);
297}
298
299template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
300inline _LIBCPP_INLINE_VISIBILITY
301typename enable_if
302<
303 sizeof...(_Param) == sizeof...(_Arg) &&
304 is_base_of<_T, typename remove_reference<_T1>::type>::value,
305 _R
306>::type
307__invoke(_R (_T::*__f)(_Param...) const, _T1&& __t1, _Arg&& ...__arg)
308{
Howard Hinnantfdc5a0f2010-09-11 15:09:37 +0000309 return (_STD::forward<const _T>(__t1).*__f)(_STD::forward<_Arg>(__arg)...);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000310}
311
312template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
313inline _LIBCPP_INLINE_VISIBILITY
314typename enable_if
315<
316 sizeof...(_Param) == sizeof...(_Arg) &&
317 is_base_of<_T, typename remove_reference<_T1>::type>::value,
318 _R
319>::type
320__invoke(_R (_T::*__f)(_Param...) volatile, _T1&& __t1, _Arg&& ...__arg)
321{
Howard Hinnantfdc5a0f2010-09-11 15:09:37 +0000322 return (_STD::forward<volatile _T>(__t1).*__f)(_STD::forward<_Arg>(__arg)...);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000323}
324
325template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
326inline _LIBCPP_INLINE_VISIBILITY
327typename enable_if
328<
329 sizeof...(_Param) == sizeof...(_Arg) &&
330 is_base_of<_T, typename remove_reference<_T1>::type>::value,
331 _R
332>::type
333__invoke(_R (_T::*__f)(_Param...) const volatile, _T1&& __t1, _Arg&& ...__arg)
334{
Howard Hinnantfdc5a0f2010-09-11 15:09:37 +0000335 return (_STD::forward<const volatile _T>(__t1).*__f)(_STD::forward<_Arg>(__arg)...);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000336}
337
338// second bullet
339
340template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
341inline _LIBCPP_INLINE_VISIBILITY
342typename enable_if
343<
344 sizeof...(_Param) == sizeof...(_Arg) &&
345 !is_base_of<_T, typename remove_reference<_T1>::type>::value,
346 _R
347>::type
348__invoke(_R (_T::*__f)(_Param...), _T1&& __t1, _Arg&& ...__arg)
349{
350 return ((*_STD::forward<_T1>(__t1)).*__f)(_STD::forward<_Arg>(__arg)...);
351}
352
353template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
354inline _LIBCPP_INLINE_VISIBILITY
355typename enable_if
356<
357 sizeof...(_Param) == sizeof...(_Arg) &&
358 !is_base_of<_T, typename remove_reference<_T1>::type>::value,
359 _R
360>::type
361__invoke(_R (_T::*__f)(_Param...) const, _T1&& __t1, _Arg&& ...__arg)
362{
363 return ((*_STD::forward<_T1>(__t1)).*__f)(_STD::forward<_Arg>(__arg)...);
364}
365
366template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
367inline _LIBCPP_INLINE_VISIBILITY
368typename enable_if
369<
370 sizeof...(_Param) == sizeof...(_Arg) &&
371 !is_base_of<_T, typename remove_reference<_T1>::type>::value,
372 _R
373>::type
374__invoke(_R (_T::*__f)(_Param...) volatile, _T1&& __t1, _Arg&& ...__arg)
375{
376 return ((*_STD::forward<_T1>(__t1)).*__f)(_STD::forward<_Arg>(__arg)...);
377}
378
379template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
380inline _LIBCPP_INLINE_VISIBILITY
381typename enable_if
382<
383 sizeof...(_Param) == sizeof...(_Arg) &&
384 !is_base_of<_T, typename remove_reference<_T1>::type>::value,
385 _R
386>::type
387__invoke(_R (_T::*__f)(_Param...) const volatile, _T1&& __t1, _Arg&& ...__arg)
388{
389 return ((*_STD::forward<_T1>(__t1)).*__f)(_STD::forward<_Arg>(__arg)...);
390}
391
392// third bullet
393
394template <class _R, class _T, class _T1>
395inline _LIBCPP_INLINE_VISIBILITY
396typename enable_if
397<
398 is_base_of<_T, typename remove_reference<_T1>::type>::value,
399 typename __apply_cv<_T1, _R>::type&&
400>::type
401__invoke(_R _T::* __f, _T1&& __t1)
402{
403 return _STD::forward<_T1>(__t1).*__f;
404}
405
406// forth bullet
407
408template <class _T1, class _R, bool>
409struct __4th_helper
410{
411};
412
413template <class _T1, class _R>
414struct __4th_helper<_T1, _R, true>
415{
416 typedef typename __apply_cv<decltype(*_STD::declval<_T1>()), _R>::type type;
417};
418
419template <class _R, class _T, class _T1>
420inline _LIBCPP_INLINE_VISIBILITY
421typename __4th_helper<_T1, _R,
422 !is_base_of<_T,
423 typename remove_reference<_T1>::type
424 >::value
425 >::type&&
426__invoke(_R _T::* __f, _T1&& __t1)
427{
428 return (*_STD::forward<_T1>(__t1)).*__f;
429}
430
431// fifth bullet
432
Howard Hinnant941138f2011-05-16 16:20:21 +0000433template <class _R, class ..._Param, class ..._Args>
434inline _LIBCPP_INLINE_VISIBILITY
435_R
436__invoke(_R (*__f)(_Param...), _Args&& ...__args)
437{
438 return __f(_STD::forward<_Args>(__args)...);
439}
440
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000441template <class _F, class ..._T>
442inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant57cff292011-05-19 15:05:04 +0000443typename __invoke_of<_F, _T...>::type
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000444__invoke(_F&& __f, _T&& ...__t)
445{
446 return _STD::forward<_F>(__f)(_STD::forward<_T>(__t)...);
447}
448
449template <class _Tp, class ..._Args>
450struct __invoke_return
451{
452 typedef decltype(__invoke(_STD::declval<_Tp>(), _STD::declval<_Args>()...)) type;
453};
454
455template <class _Tp>
Howard Hinnant99acc502010-09-21 17:32:39 +0000456class _LIBCPP_VISIBLE reference_wrapper
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000457 : public __weak_result_type<_Tp>
458{
459public:
460 // types
461 typedef _Tp type;
462private:
463 type* __f_;
464
465public:
466 // construct/copy/destroy
467 _LIBCPP_INLINE_VISIBILITY reference_wrapper(type& __f) : __f_(&__f) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000468#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000469 private: reference_wrapper(type&&); public: // = delete; // do not bind to temps
470#endif
471
472 // access
473 _LIBCPP_INLINE_VISIBILITY operator type& () const {return *__f_;}
474 _LIBCPP_INLINE_VISIBILITY type& get() const {return *__f_;}
475
476 // invoke
477 template <class... _ArgTypes>
Howard Hinnant99acc502010-09-21 17:32:39 +0000478 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant57cff292011-05-19 15:05:04 +0000479 typename __invoke_of<type&, _ArgTypes...>::type
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000480 operator() (_ArgTypes&&... __args) const
481 {
482 return __invoke(get(), _STD::forward<_ArgTypes>(__args)...);
483 }
484};
485
486template <class _Tp> struct ____is_reference_wrapper : public false_type {};
487template <class _Tp> struct ____is_reference_wrapper<reference_wrapper<_Tp> > : public true_type {};
488template <class _Tp> struct __is_reference_wrapper
489 : public ____is_reference_wrapper<typename remove_cv<_Tp>::type> {};
490
491template <class _Tp>
492inline _LIBCPP_INLINE_VISIBILITY
493reference_wrapper<_Tp>
494ref(_Tp& __t)
495{
496 return reference_wrapper<_Tp>(__t);
497}
498
499template <class _Tp>
500inline _LIBCPP_INLINE_VISIBILITY
501reference_wrapper<_Tp>
502ref(reference_wrapper<_Tp> __t)
503{
504 return ref(__t.get());
505}
506
507template <class _Tp>
508inline _LIBCPP_INLINE_VISIBILITY
509reference_wrapper<const _Tp>
510cref(const _Tp& __t)
511{
512 return reference_wrapper<const _Tp>(__t);
513}
514
515template <class _Tp>
516inline _LIBCPP_INLINE_VISIBILITY
517reference_wrapper<const _Tp>
518cref(reference_wrapper<_Tp> __t)
519{
520 return cref(__t.get());
521}
522
Howard Hinnant73d21a42010-09-04 23:28:19 +0000523#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
524#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
525
526template <class _Tp> void ref(const _Tp&& __t) = delete;
527template <class _Tp> void cref(const _Tp&& __t) = delete;
528
529#else // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
530
531template <class _Tp> void ref(const _Tp&& __t);// = delete;
532template <class _Tp> void cref(const _Tp&& __t);// = delete;
533
534#endif // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
535
536#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000537
538#endif // _LIBCPP_HAS_NO_VARIADICS
539
540_LIBCPP_END_NAMESPACE_STD
541
542#endif // _LIBCPP_FUNCTIONAL_BASE