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#include <new>
19
20#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21#pragma GCC system_header
22#endif
23
24_LIBCPP_BEGIN_NAMESPACE_STD
25
26template <class _Arg, class _Result>
27struct _LIBCPP_TEMPLATE_VIS unary_function
28{
29    typedef _Arg    argument_type;
30    typedef _Result result_type;
31};
32
33template <class _Arg1, class _Arg2, class _Result>
34struct _LIBCPP_TEMPLATE_VIS binary_function
35{
36    typedef _Arg1   first_argument_type;
37    typedef _Arg2   second_argument_type;
38    typedef _Result result_type;
39};
40
41template <class _Tp>
42struct __has_result_type
43{
44private:
45    struct __two {char __lx; char __lxx;};
46    template <class _Up> static __two __test(...);
47    template <class _Up> static char __test(typename _Up::result_type* = 0);
48public:
49    static const bool value = sizeof(__test<_Tp>(0)) == 1;
50};
51
52#if _LIBCPP_STD_VER > 11
53template <class _Tp = void>
54#else
55template <class _Tp>
56#endif
57struct _LIBCPP_TEMPLATE_VIS less : binary_function<_Tp, _Tp, bool>
58{
59    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
60    bool operator()(const _Tp& __x, const _Tp& __y) const
61        {return __x < __y;}
62};
63
64#if _LIBCPP_STD_VER > 11
65template <>
66struct _LIBCPP_TEMPLATE_VIS less<void>
67{
68    template <class _T1, class _T2>
69    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
70    auto operator()(_T1&& __t, _T2&& __u) const
71    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u)))
72    -> decltype        (_VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u))
73        { return        _VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u); }
74    typedef void is_transparent;
75};
76#endif
77
78// __weak_result_type
79
80template <class _Tp>
81struct __derives_from_unary_function
82{
83private:
84    struct __two {char __lx; char __lxx;};
85    static __two __test(...);
86    template <class _Ap, class _Rp>
87        static unary_function<_Ap, _Rp>
88        __test(const volatile unary_function<_Ap, _Rp>*);
89public:
90    static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
91    typedef decltype(__test((_Tp*)0)) type;
92};
93
94template <class _Tp>
95struct __derives_from_binary_function
96{
97private:
98    struct __two {char __lx; char __lxx;};
99    static __two __test(...);
100    template <class _A1, class _A2, class _Rp>
101        static binary_function<_A1, _A2, _Rp>
102        __test(const volatile binary_function<_A1, _A2, _Rp>*);
103public:
104    static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
105    typedef decltype(__test((_Tp*)0)) type;
106};
107
108template <class _Tp, bool = __derives_from_unary_function<_Tp>::value>
109struct __maybe_derive_from_unary_function  // bool is true
110    : public __derives_from_unary_function<_Tp>::type
111{
112};
113
114template <class _Tp>
115struct __maybe_derive_from_unary_function<_Tp, false>
116{
117};
118
119template <class _Tp, bool = __derives_from_binary_function<_Tp>::value>
120struct __maybe_derive_from_binary_function  // bool is true
121    : public __derives_from_binary_function<_Tp>::type
122{
123};
124
125template <class _Tp>
126struct __maybe_derive_from_binary_function<_Tp, false>
127{
128};
129
130template <class _Tp, bool = __has_result_type<_Tp>::value>
131struct __weak_result_type_imp // bool is true
132    : public __maybe_derive_from_unary_function<_Tp>,
133      public __maybe_derive_from_binary_function<_Tp>
134{
135    typedef typename _Tp::result_type result_type;
136};
137
138template <class _Tp>
139struct __weak_result_type_imp<_Tp, false>
140    : public __maybe_derive_from_unary_function<_Tp>,
141      public __maybe_derive_from_binary_function<_Tp>
142{
143};
144
145template <class _Tp>
146struct __weak_result_type
147    : public __weak_result_type_imp<_Tp>
148{
149};
150
151// 0 argument case
152
153template <class _Rp>
154struct __weak_result_type<_Rp ()>
155{
156    typedef _Rp result_type;
157};
158
159template <class _Rp>
160struct __weak_result_type<_Rp (&)()>
161{
162    typedef _Rp result_type;
163};
164
165template <class _Rp>
166struct __weak_result_type<_Rp (*)()>
167{
168    typedef _Rp result_type;
169};
170
171// 1 argument case
172
173template <class _Rp, class _A1>
174struct __weak_result_type<_Rp (_A1)>
175    : public unary_function<_A1, _Rp>
176{
177};
178
179template <class _Rp, class _A1>
180struct __weak_result_type<_Rp (&)(_A1)>
181    : public unary_function<_A1, _Rp>
182{
183};
184
185template <class _Rp, class _A1>
186struct __weak_result_type<_Rp (*)(_A1)>
187    : public unary_function<_A1, _Rp>
188{
189};
190
191template <class _Rp, class _Cp>
192struct __weak_result_type<_Rp (_Cp::*)()>
193    : public unary_function<_Cp*, _Rp>
194{
195};
196
197template <class _Rp, class _Cp>
198struct __weak_result_type<_Rp (_Cp::*)() const>
199    : public unary_function<const _Cp*, _Rp>
200{
201};
202
203template <class _Rp, class _Cp>
204struct __weak_result_type<_Rp (_Cp::*)() volatile>
205    : public unary_function<volatile _Cp*, _Rp>
206{
207};
208
209template <class _Rp, class _Cp>
210struct __weak_result_type<_Rp (_Cp::*)() const volatile>
211    : public unary_function<const volatile _Cp*, _Rp>
212{
213};
214
215// 2 argument case
216
217template <class _Rp, class _A1, class _A2>
218struct __weak_result_type<_Rp (_A1, _A2)>
219    : public binary_function<_A1, _A2, _Rp>
220{
221};
222
223template <class _Rp, class _A1, class _A2>
224struct __weak_result_type<_Rp (*)(_A1, _A2)>
225    : public binary_function<_A1, _A2, _Rp>
226{
227};
228
229template <class _Rp, class _A1, class _A2>
230struct __weak_result_type<_Rp (&)(_A1, _A2)>
231    : public binary_function<_A1, _A2, _Rp>
232{
233};
234
235template <class _Rp, class _Cp, class _A1>
236struct __weak_result_type<_Rp (_Cp::*)(_A1)>
237    : public binary_function<_Cp*, _A1, _Rp>
238{
239};
240
241template <class _Rp, class _Cp, class _A1>
242struct __weak_result_type<_Rp (_Cp::*)(_A1) const>
243    : public binary_function<const _Cp*, _A1, _Rp>
244{
245};
246
247template <class _Rp, class _Cp, class _A1>
248struct __weak_result_type<_Rp (_Cp::*)(_A1) volatile>
249    : public binary_function<volatile _Cp*, _A1, _Rp>
250{
251};
252
253template <class _Rp, class _Cp, class _A1>
254struct __weak_result_type<_Rp (_Cp::*)(_A1) const volatile>
255    : public binary_function<const volatile _Cp*, _A1, _Rp>
256{
257};
258
259
260#ifndef _LIBCPP_HAS_NO_VARIADICS
261// 3 or more arguments
262
263template <class _Rp, class _A1, class _A2, class _A3, class ..._A4>
264struct __weak_result_type<_Rp (_A1, _A2, _A3, _A4...)>
265{
266    typedef _Rp result_type;
267};
268
269template <class _Rp, class _A1, class _A2, class _A3, class ..._A4>
270struct __weak_result_type<_Rp (&)(_A1, _A2, _A3, _A4...)>
271{
272    typedef _Rp result_type;
273};
274
275template <class _Rp, class _A1, class _A2, class _A3, class ..._A4>
276struct __weak_result_type<_Rp (*)(_A1, _A2, _A3, _A4...)>
277{
278    typedef _Rp result_type;
279};
280
281template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
282struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...)>
283{
284    typedef _Rp result_type;
285};
286
287template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
288struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const>
289{
290    typedef _Rp result_type;
291};
292
293template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
294struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) volatile>
295{
296    typedef _Rp result_type;
297};
298
299template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
300struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile>
301{
302    typedef _Rp result_type;
303};
304
305#endif // _LIBCPP_HAS_NO_VARIADICS
306
307#ifndef _LIBCPP_CXX03_LANG
308
309template <class _Tp, class ..._Args>
310struct __invoke_return
311{
312    typedef decltype(__invoke(_VSTD::declval<_Tp>(), _VSTD::declval<_Args>()...)) type;
313};
314
315#else // defined(_LIBCPP_CXX03_LANG)
316
317#include <__functional_base_03>
318
319#endif  // !defined(_LIBCPP_CXX03_LANG)
320
321
322template <class _Ret>
323struct __invoke_void_return_wrapper
324{
325#ifndef _LIBCPP_HAS_NO_VARIADICS
326    template <class ..._Args>
327    static _Ret __call(_Args&&... __args) {
328        return __invoke(_VSTD::forward<_Args>(__args)...);
329    }
330#else
331    template <class _Fn>
332    static _Ret __call(_Fn __f) {
333        return __invoke(__f);
334    }
335
336    template <class _Fn, class _A0>
337    static _Ret __call(_Fn __f, _A0& __a0) {
338        return __invoke(__f, __a0);
339    }
340
341    template <class _Fn, class _A0, class _A1>
342    static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1) {
343        return __invoke(__f, __a0, __a1);
344    }
345
346    template <class _Fn, class _A0, class _A1, class _A2>
347    static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2){
348        return __invoke(__f, __a0, __a1, __a2);
349    }
350#endif
351};
352
353template <>
354struct __invoke_void_return_wrapper<void>
355{
356#ifndef _LIBCPP_HAS_NO_VARIADICS
357    template <class ..._Args>
358    static void __call(_Args&&... __args) {
359        __invoke(_VSTD::forward<_Args>(__args)...);
360    }
361#else
362    template <class _Fn>
363    static void __call(_Fn __f) {
364        __invoke(__f);
365    }
366
367    template <class _Fn, class _A0>
368    static void __call(_Fn __f, _A0& __a0) {
369        __invoke(__f, __a0);
370    }
371
372    template <class _Fn, class _A0, class _A1>
373    static void __call(_Fn __f, _A0& __a0, _A1& __a1) {
374        __invoke(__f, __a0, __a1);
375    }
376
377    template <class _Fn, class _A0, class _A1, class _A2>
378    static void __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2) {
379        __invoke(__f, __a0, __a1, __a2);
380    }
381#endif
382};
383
384template <class _Tp>
385class _LIBCPP_TEMPLATE_VIS reference_wrapper
386    : public __weak_result_type<_Tp>
387{
388public:
389    // types
390    typedef _Tp type;
391private:
392    type* __f_;
393
394public:
395    // construct/copy/destroy
396    _LIBCPP_INLINE_VISIBILITY reference_wrapper(type& __f) _NOEXCEPT
397        : __f_(_VSTD::addressof(__f)) {}
398#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
399    private: reference_wrapper(type&&); public: // = delete; // do not bind to temps
400#endif
401
402    // access
403    _LIBCPP_INLINE_VISIBILITY operator type&    () const _NOEXCEPT {return *__f_;}
404    _LIBCPP_INLINE_VISIBILITY          type& get() const _NOEXCEPT {return *__f_;}
405
406#ifndef _LIBCPP_HAS_NO_VARIADICS
407    // invoke
408    template <class... _ArgTypes>
409    _LIBCPP_INLINE_VISIBILITY
410    typename __invoke_of<type&, _ArgTypes...>::type
411    operator() (_ArgTypes&&... __args) const {
412        return __invoke(get(), _VSTD::forward<_ArgTypes>(__args)...);
413    }
414#else
415
416    _LIBCPP_INLINE_VISIBILITY
417    typename __invoke_return<type>::type
418    operator() () const {
419        return __invoke(get());
420    }
421
422    template <class _A0>
423    _LIBCPP_INLINE_VISIBILITY
424    typename __invoke_return0<type, _A0>::type
425    operator() (_A0& __a0) const {
426        return __invoke(get(), __a0);
427    }
428
429    template <class _A0>
430    _LIBCPP_INLINE_VISIBILITY
431    typename __invoke_return0<type, _A0 const>::type
432    operator() (_A0 const& __a0) const {
433        return __invoke(get(), __a0);
434    }
435
436    template <class _A0, class _A1>
437    _LIBCPP_INLINE_VISIBILITY
438    typename __invoke_return1<type, _A0, _A1>::type
439    operator() (_A0& __a0, _A1& __a1) const {
440        return __invoke(get(), __a0, __a1);
441    }
442
443    template <class _A0, class _A1>
444    _LIBCPP_INLINE_VISIBILITY
445    typename __invoke_return1<type, _A0 const, _A1>::type
446    operator() (_A0 const& __a0, _A1& __a1) const {
447        return __invoke(get(), __a0, __a1);
448    }
449
450    template <class _A0, class _A1>
451    _LIBCPP_INLINE_VISIBILITY
452    typename __invoke_return1<type, _A0, _A1 const>::type
453    operator() (_A0& __a0, _A1 const& __a1) const {
454        return __invoke(get(), __a0, __a1);
455    }
456
457    template <class _A0, class _A1>
458    _LIBCPP_INLINE_VISIBILITY
459    typename __invoke_return1<type, _A0 const, _A1 const>::type
460    operator() (_A0 const& __a0, _A1 const& __a1) const {
461        return __invoke(get(), __a0, __a1);
462    }
463
464    template <class _A0, class _A1, class _A2>
465    _LIBCPP_INLINE_VISIBILITY
466    typename __invoke_return2<type, _A0, _A1, _A2>::type
467    operator() (_A0& __a0, _A1& __a1, _A2& __a2) const {
468        return __invoke(get(), __a0, __a1, __a2);
469    }
470
471    template <class _A0, class _A1, class _A2>
472    _LIBCPP_INLINE_VISIBILITY
473    typename __invoke_return2<type, _A0 const, _A1, _A2>::type
474    operator() (_A0 const& __a0, _A1& __a1, _A2& __a2) const {
475        return __invoke(get(), __a0, __a1, __a2);
476    }
477
478    template <class _A0, class _A1, class _A2>
479    _LIBCPP_INLINE_VISIBILITY
480    typename __invoke_return2<type, _A0, _A1 const, _A2>::type
481    operator() (_A0& __a0, _A1 const& __a1, _A2& __a2) const {
482        return __invoke(get(), __a0, __a1, __a2);
483    }
484
485    template <class _A0, class _A1, class _A2>
486    _LIBCPP_INLINE_VISIBILITY
487    typename __invoke_return2<type, _A0, _A1, _A2 const>::type
488    operator() (_A0& __a0, _A1& __a1, _A2 const& __a2) const {
489        return __invoke(get(), __a0, __a1, __a2);
490    }
491
492    template <class _A0, class _A1, class _A2>
493    _LIBCPP_INLINE_VISIBILITY
494    typename __invoke_return2<type, _A0 const, _A1 const, _A2>::type
495    operator() (_A0 const& __a0, _A1 const& __a1, _A2& __a2) const {
496        return __invoke(get(), __a0, __a1, __a2);
497    }
498
499    template <class _A0, class _A1, class _A2>
500    _LIBCPP_INLINE_VISIBILITY
501    typename __invoke_return2<type, _A0 const, _A1, _A2 const>::type
502    operator() (_A0 const& __a0, _A1& __a1, _A2 const& __a2) const {
503        return __invoke(get(), __a0, __a1, __a2);
504    }
505
506    template <class _A0, class _A1, class _A2>
507    _LIBCPP_INLINE_VISIBILITY
508    typename __invoke_return2<type, _A0, _A1 const, _A2 const>::type
509    operator() (_A0& __a0, _A1 const& __a1, _A2 const& __a2) const {
510        return __invoke(get(), __a0, __a1, __a2);
511    }
512
513    template <class _A0, class _A1, class _A2>
514    _LIBCPP_INLINE_VISIBILITY
515    typename __invoke_return2<type, _A0 const, _A1 const, _A2 const>::type
516    operator() (_A0 const& __a0, _A1 const& __a1, _A2 const& __a2) const {
517        return __invoke(get(), __a0, __a1, __a2);
518    }
519#endif // _LIBCPP_HAS_NO_VARIADICS
520};
521
522
523template <class _Tp>
524inline _LIBCPP_INLINE_VISIBILITY
525reference_wrapper<_Tp>
526ref(_Tp& __t) _NOEXCEPT
527{
528    return reference_wrapper<_Tp>(__t);
529}
530
531template <class _Tp>
532inline _LIBCPP_INLINE_VISIBILITY
533reference_wrapper<_Tp>
534ref(reference_wrapper<_Tp> __t) _NOEXCEPT
535{
536    return ref(__t.get());
537}
538
539template <class _Tp>
540inline _LIBCPP_INLINE_VISIBILITY
541reference_wrapper<const _Tp>
542cref(const _Tp& __t) _NOEXCEPT
543{
544    return reference_wrapper<const _Tp>(__t);
545}
546
547template <class _Tp>
548inline _LIBCPP_INLINE_VISIBILITY
549reference_wrapper<const _Tp>
550cref(reference_wrapper<_Tp> __t) _NOEXCEPT
551{
552    return cref(__t.get());
553}
554
555#ifndef _LIBCPP_CXX03_LANG
556template <class _Tp> void ref(const _Tp&&) = delete;
557template <class _Tp> void cref(const _Tp&&) = delete;
558#endif
559
560#if _LIBCPP_STD_VER > 11
561template <class _Tp1, class _Tp2 = void>
562struct __is_transparent
563{
564private:
565    struct __two {char __lx; char __lxx;};
566    template <class _Up> static __two __test(...);
567    template <class _Up> static char __test(typename _Up::is_transparent* = 0);
568public:
569    static const bool value = sizeof(__test<_Tp1>(0)) == 1;
570};
571#endif
572
573// allocator_arg_t
574
575struct _LIBCPP_TEMPLATE_VIS allocator_arg_t { };
576
577#if defined(_LIBCPP_HAS_NO_CONSTEXPR) || defined(_LIBCPP_BUILDING_MEMORY)
578extern const allocator_arg_t allocator_arg;
579#else
580constexpr allocator_arg_t allocator_arg = allocator_arg_t();
581#endif
582
583// uses_allocator
584
585template <class _Tp>
586struct __has_allocator_type
587{
588private:
589    struct __two {char __lx; char __lxx;};
590    template <class _Up> static __two __test(...);
591    template <class _Up> static char __test(typename _Up::allocator_type* = 0);
592public:
593    static const bool value = sizeof(__test<_Tp>(0)) == 1;
594};
595
596template <class _Tp, class _Alloc, bool = __has_allocator_type<_Tp>::value>
597struct __uses_allocator
598    : public integral_constant<bool,
599        is_convertible<_Alloc, typename _Tp::allocator_type>::value>
600{
601};
602
603template <class _Tp, class _Alloc>
604struct __uses_allocator<_Tp, _Alloc, false>
605    : public false_type
606{
607};
608
609template <class _Tp, class _Alloc>
610struct _LIBCPP_TEMPLATE_VIS uses_allocator
611    : public __uses_allocator<_Tp, _Alloc>
612{
613};
614
615#if _LIBCPP_STD_VER > 14
616template <class _Tp, class _Alloc>
617constexpr size_t uses_allocator_v = uses_allocator<_Tp, _Alloc>::value;
618#endif
619
620#ifndef _LIBCPP_HAS_NO_VARIADICS
621
622// allocator construction
623
624template <class _Tp, class _Alloc, class ..._Args>
625struct __uses_alloc_ctor_imp
626{
627    typedef typename __uncvref<_Alloc>::type _RawAlloc;
628    static const bool __ua = uses_allocator<_Tp, _RawAlloc>::value;
629    static const bool __ic =
630        is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value;
631    static const int value = __ua ? 2 - __ic : 0;
632};
633
634template <class _Tp, class _Alloc, class ..._Args>
635struct __uses_alloc_ctor
636    : integral_constant<int, __uses_alloc_ctor_imp<_Tp, _Alloc, _Args...>::value>
637    {};
638
639template <class _Tp, class _Allocator, class... _Args>
640inline _LIBCPP_INLINE_VISIBILITY
641void __user_alloc_construct_impl (integral_constant<int, 0>, _Tp *__storage, const _Allocator &, _Args &&... __args )
642{
643    new (__storage) _Tp (_VSTD::forward<_Args>(__args)...);
644}
645
646// FIXME: This should have a version which takes a non-const alloc.
647template <class _Tp, class _Allocator, class... _Args>
648inline _LIBCPP_INLINE_VISIBILITY
649void __user_alloc_construct_impl (integral_constant<int, 1>, _Tp *__storage, const _Allocator &__a, _Args &&... __args )
650{
651    new (__storage) _Tp (allocator_arg, __a, _VSTD::forward<_Args>(__args)...);
652}
653
654// FIXME: This should have a version which takes a non-const alloc.
655template <class _Tp, class _Allocator, class... _Args>
656inline _LIBCPP_INLINE_VISIBILITY
657void __user_alloc_construct_impl (integral_constant<int, 2>, _Tp *__storage, const _Allocator &__a, _Args &&... __args )
658{
659    new (__storage) _Tp (_VSTD::forward<_Args>(__args)..., __a);
660}
661
662// FIXME: Theis should have a version which takes a non-const alloc.
663template <class _Tp, class _Allocator, class... _Args>
664inline _LIBCPP_INLINE_VISIBILITY
665void __user_alloc_construct (_Tp *__storage, const _Allocator &__a, _Args &&... __args)
666{
667    __user_alloc_construct_impl(
668             __uses_alloc_ctor<_Tp, _Allocator>(),
669             __storage, __a, _VSTD::forward<_Args>(__args)...
670        );
671}
672#endif  // _LIBCPP_HAS_NO_VARIADICS
673
674_LIBCPP_END_NAMESPACE_STD
675
676#endif  // _LIBCPP_FUNCTIONAL_BASE
677