17a984708SDavid Chisnall// -*- C++ -*-
27a984708SDavid Chisnall//===----------------------------------------------------------------------===//
37a984708SDavid Chisnall//
47a984708SDavid Chisnall//                     The LLVM Compiler Infrastructure
57a984708SDavid Chisnall//
67a984708SDavid Chisnall// This file is dual licensed under the MIT and the University of Illinois Open
77a984708SDavid Chisnall// Source Licenses. See LICENSE.TXT for details.
87a984708SDavid Chisnall//
97a984708SDavid Chisnall//===----------------------------------------------------------------------===//
107a984708SDavid Chisnall
117a984708SDavid Chisnall#ifndef _LIBCPP_FUNCTIONAL_BASE
127a984708SDavid Chisnall#define _LIBCPP_FUNCTIONAL_BASE
137a984708SDavid Chisnall
147a984708SDavid Chisnall#include <__config>
157a984708SDavid Chisnall#include <type_traits>
167a984708SDavid Chisnall#include <typeinfo>
177a984708SDavid Chisnall#include <exception>
184f7ab58eSDimitry Andric#include <new>
19540d2a8bSDimitry Andric#include <utility>
207a984708SDavid Chisnall
217a984708SDavid Chisnall#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
227a984708SDavid Chisnall#pragma GCC system_header
237a984708SDavid Chisnall#endif
247a984708SDavid Chisnall
257a984708SDavid Chisnall_LIBCPP_BEGIN_NAMESPACE_STD
267a984708SDavid Chisnall
277a984708SDavid Chisnalltemplate <class _Arg1, class _Arg2, class _Result>
28aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS binary_function
297a984708SDavid Chisnall{
307a984708SDavid Chisnall    typedef _Arg1   first_argument_type;
317a984708SDavid Chisnall    typedef _Arg2   second_argument_type;
327a984708SDavid Chisnall    typedef _Result result_type;
337a984708SDavid Chisnall};
347a984708SDavid Chisnall
357a984708SDavid Chisnalltemplate <class _Tp>
367a984708SDavid Chisnallstruct __has_result_type
377a984708SDavid Chisnall{
387a984708SDavid Chisnallprivate:
391e0896acSDavid Chisnall    struct __two {char __lx; char __lxx;};
407a984708SDavid Chisnall    template <class _Up> static __two __test(...);
417a984708SDavid Chisnall    template <class _Up> static char __test(typename _Up::result_type* = 0);
427a984708SDavid Chisnallpublic:
437a984708SDavid Chisnall    static const bool value = sizeof(__test<_Tp>(0)) == 1;
447a984708SDavid Chisnall};
457a984708SDavid Chisnall
464f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
474f7ab58eSDimitry Andrictemplate <class _Tp = void>
484f7ab58eSDimitry Andric#else
4994e3ee44SDavid Chisnalltemplate <class _Tp>
504f7ab58eSDimitry Andric#endif
51aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS less : binary_function<_Tp, _Tp, bool>
5294e3ee44SDavid Chisnall{
534f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
544f7ab58eSDimitry Andric    bool operator()(const _Tp& __x, const _Tp& __y) const
5594e3ee44SDavid Chisnall        {return __x < __y;}
5694e3ee44SDavid Chisnall};
5794e3ee44SDavid Chisnall
584f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
594f7ab58eSDimitry Andrictemplate <>
60aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS less<void>
614f7ab58eSDimitry Andric{
624f7ab58eSDimitry Andric    template <class _T1, class _T2>
634f7ab58eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
644f7ab58eSDimitry Andric    auto operator()(_T1&& __t, _T2&& __u) const
65854fa44bSDimitry Andric    _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u)))
66854fa44bSDimitry Andric    -> decltype        (_VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u))
674f7ab58eSDimitry Andric        { return        _VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u); }
684f7ab58eSDimitry Andric    typedef void is_transparent;
694f7ab58eSDimitry Andric};
704f7ab58eSDimitry Andric#endif
714f7ab58eSDimitry Andric
727a984708SDavid Chisnall// __weak_result_type
737a984708SDavid Chisnall
747a984708SDavid Chisnalltemplate <class _Tp>
757a984708SDavid Chisnallstruct __derives_from_unary_function
767a984708SDavid Chisnall{
777a984708SDavid Chisnallprivate:
781e0896acSDavid Chisnall    struct __two {char __lx; char __lxx;};
797a984708SDavid Chisnall    static __two __test(...);
8094e3ee44SDavid Chisnall    template <class _Ap, class _Rp>
8194e3ee44SDavid Chisnall        static unary_function<_Ap, _Rp>
8294e3ee44SDavid Chisnall        __test(const volatile unary_function<_Ap, _Rp>*);
837a984708SDavid Chisnallpublic:
847a984708SDavid Chisnall    static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
857a984708SDavid Chisnall    typedef decltype(__test((_Tp*)0)) type;
867a984708SDavid Chisnall};
877a984708SDavid Chisnall
887a984708SDavid Chisnalltemplate <class _Tp>
897a984708SDavid Chisnallstruct __derives_from_binary_function
907a984708SDavid Chisnall{
917a984708SDavid Chisnallprivate:
921e0896acSDavid Chisnall    struct __two {char __lx; char __lxx;};
937a984708SDavid Chisnall    static __two __test(...);
9494e3ee44SDavid Chisnall    template <class _A1, class _A2, class _Rp>
9594e3ee44SDavid Chisnall        static binary_function<_A1, _A2, _Rp>
9694e3ee44SDavid Chisnall        __test(const volatile binary_function<_A1, _A2, _Rp>*);
977a984708SDavid Chisnallpublic:
987a984708SDavid Chisnall    static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
997a984708SDavid Chisnall    typedef decltype(__test((_Tp*)0)) type;
1007a984708SDavid Chisnall};
1017a984708SDavid Chisnall
1027a984708SDavid Chisnalltemplate <class _Tp, bool = __derives_from_unary_function<_Tp>::value>
1037a984708SDavid Chisnallstruct __maybe_derive_from_unary_function  // bool is true
1047a984708SDavid Chisnall    : public __derives_from_unary_function<_Tp>::type
1057a984708SDavid Chisnall{
1067a984708SDavid Chisnall};
1077a984708SDavid Chisnall
1087a984708SDavid Chisnalltemplate <class _Tp>
1097a984708SDavid Chisnallstruct __maybe_derive_from_unary_function<_Tp, false>
1107a984708SDavid Chisnall{
1117a984708SDavid Chisnall};
1127a984708SDavid Chisnall
1137a984708SDavid Chisnalltemplate <class _Tp, bool = __derives_from_binary_function<_Tp>::value>
1147a984708SDavid Chisnallstruct __maybe_derive_from_binary_function  // bool is true
1157a984708SDavid Chisnall    : public __derives_from_binary_function<_Tp>::type
1167a984708SDavid Chisnall{
1177a984708SDavid Chisnall};
1187a984708SDavid Chisnall
1197a984708SDavid Chisnalltemplate <class _Tp>
1207a984708SDavid Chisnallstruct __maybe_derive_from_binary_function<_Tp, false>
1217a984708SDavid Chisnall{
1227a984708SDavid Chisnall};
1237a984708SDavid Chisnall
1247a984708SDavid Chisnalltemplate <class _Tp, bool = __has_result_type<_Tp>::value>
1257a984708SDavid Chisnallstruct __weak_result_type_imp // bool is true
1267a984708SDavid Chisnall    : public __maybe_derive_from_unary_function<_Tp>,
1277a984708SDavid Chisnall      public __maybe_derive_from_binary_function<_Tp>
1287a984708SDavid Chisnall{
1297a984708SDavid Chisnall    typedef typename _Tp::result_type result_type;
1307a984708SDavid Chisnall};
1317a984708SDavid Chisnall
1327a984708SDavid Chisnalltemplate <class _Tp>
1337a984708SDavid Chisnallstruct __weak_result_type_imp<_Tp, false>
1347a984708SDavid Chisnall    : public __maybe_derive_from_unary_function<_Tp>,
1357a984708SDavid Chisnall      public __maybe_derive_from_binary_function<_Tp>
1367a984708SDavid Chisnall{
1377a984708SDavid Chisnall};
1387a984708SDavid Chisnall
1397a984708SDavid Chisnalltemplate <class _Tp>
1407a984708SDavid Chisnallstruct __weak_result_type
1417a984708SDavid Chisnall    : public __weak_result_type_imp<_Tp>
1427a984708SDavid Chisnall{
1437a984708SDavid Chisnall};
1447a984708SDavid Chisnall
1457a984708SDavid Chisnall// 0 argument case
1467a984708SDavid Chisnall
14794e3ee44SDavid Chisnalltemplate <class _Rp>
14894e3ee44SDavid Chisnallstruct __weak_result_type<_Rp ()>
1497a984708SDavid Chisnall{
15094e3ee44SDavid Chisnall    typedef _Rp result_type;
1517a984708SDavid Chisnall};
1527a984708SDavid Chisnall
15394e3ee44SDavid Chisnalltemplate <class _Rp>
15494e3ee44SDavid Chisnallstruct __weak_result_type<_Rp (&)()>
1557a984708SDavid Chisnall{
15694e3ee44SDavid Chisnall    typedef _Rp result_type;
1577a984708SDavid Chisnall};
1587a984708SDavid Chisnall
15994e3ee44SDavid Chisnalltemplate <class _Rp>
16094e3ee44SDavid Chisnallstruct __weak_result_type<_Rp (*)()>
1617a984708SDavid Chisnall{
16294e3ee44SDavid Chisnall    typedef _Rp result_type;
1637a984708SDavid Chisnall};
1647a984708SDavid Chisnall
1657a984708SDavid Chisnall// 1 argument case
1667a984708SDavid Chisnall
16794e3ee44SDavid Chisnalltemplate <class _Rp, class _A1>
16894e3ee44SDavid Chisnallstruct __weak_result_type<_Rp (_A1)>
16994e3ee44SDavid Chisnall    : public unary_function<_A1, _Rp>
1707a984708SDavid Chisnall{
1717a984708SDavid Chisnall};
1727a984708SDavid Chisnall
17394e3ee44SDavid Chisnalltemplate <class _Rp, class _A1>
17494e3ee44SDavid Chisnallstruct __weak_result_type<_Rp (&)(_A1)>
17594e3ee44SDavid Chisnall    : public unary_function<_A1, _Rp>
1767a984708SDavid Chisnall{
1777a984708SDavid Chisnall};
1787a984708SDavid Chisnall
17994e3ee44SDavid Chisnalltemplate <class _Rp, class _A1>
18094e3ee44SDavid Chisnallstruct __weak_result_type<_Rp (*)(_A1)>
18194e3ee44SDavid Chisnall    : public unary_function<_A1, _Rp>
1827a984708SDavid Chisnall{
1837a984708SDavid Chisnall};
1847a984708SDavid Chisnall
18594e3ee44SDavid Chisnalltemplate <class _Rp, class _Cp>
18694e3ee44SDavid Chisnallstruct __weak_result_type<_Rp (_Cp::*)()>
18794e3ee44SDavid Chisnall    : public unary_function<_Cp*, _Rp>
1887a984708SDavid Chisnall{
1897a984708SDavid Chisnall};
1907a984708SDavid Chisnall
19194e3ee44SDavid Chisnalltemplate <class _Rp, class _Cp>
19294e3ee44SDavid Chisnallstruct __weak_result_type<_Rp (_Cp::*)() const>
19394e3ee44SDavid Chisnall    : public unary_function<const _Cp*, _Rp>
1947a984708SDavid Chisnall{
1957a984708SDavid Chisnall};
1967a984708SDavid Chisnall
19794e3ee44SDavid Chisnalltemplate <class _Rp, class _Cp>
19894e3ee44SDavid Chisnallstruct __weak_result_type<_Rp (_Cp::*)() volatile>
19994e3ee44SDavid Chisnall    : public unary_function<volatile _Cp*, _Rp>
2007a984708SDavid Chisnall{
2017a984708SDavid Chisnall};
2027a984708SDavid Chisnall
20394e3ee44SDavid Chisnalltemplate <class _Rp, class _Cp>
20494e3ee44SDavid Chisnallstruct __weak_result_type<_Rp (_Cp::*)() const volatile>
20594e3ee44SDavid Chisnall    : public unary_function<const volatile _Cp*, _Rp>
2067a984708SDavid Chisnall{
2077a984708SDavid Chisnall};
2087a984708SDavid Chisnall
2097a984708SDavid Chisnall// 2 argument case
2107a984708SDavid Chisnall
21194e3ee44SDavid Chisnalltemplate <class _Rp, class _A1, class _A2>
21294e3ee44SDavid Chisnallstruct __weak_result_type<_Rp (_A1, _A2)>
21394e3ee44SDavid Chisnall    : public binary_function<_A1, _A2, _Rp>
2147a984708SDavid Chisnall{
2157a984708SDavid Chisnall};
2167a984708SDavid Chisnall
21794e3ee44SDavid Chisnalltemplate <class _Rp, class _A1, class _A2>
21894e3ee44SDavid Chisnallstruct __weak_result_type<_Rp (*)(_A1, _A2)>
21994e3ee44SDavid Chisnall    : public binary_function<_A1, _A2, _Rp>
2207a984708SDavid Chisnall{
2217a984708SDavid Chisnall};
2227a984708SDavid Chisnall
22394e3ee44SDavid Chisnalltemplate <class _Rp, class _A1, class _A2>
22494e3ee44SDavid Chisnallstruct __weak_result_type<_Rp (&)(_A1, _A2)>
22594e3ee44SDavid Chisnall    : public binary_function<_A1, _A2, _Rp>
2267a984708SDavid Chisnall{
2277a984708SDavid Chisnall};
2287a984708SDavid Chisnall
22994e3ee44SDavid Chisnalltemplate <class _Rp, class _Cp, class _A1>
23094e3ee44SDavid Chisnallstruct __weak_result_type<_Rp (_Cp::*)(_A1)>
23194e3ee44SDavid Chisnall    : public binary_function<_Cp*, _A1, _Rp>
2327a984708SDavid Chisnall{
2337a984708SDavid Chisnall};
2347a984708SDavid Chisnall
23594e3ee44SDavid Chisnalltemplate <class _Rp, class _Cp, class _A1>
23694e3ee44SDavid Chisnallstruct __weak_result_type<_Rp (_Cp::*)(_A1) const>
23794e3ee44SDavid Chisnall    : public binary_function<const _Cp*, _A1, _Rp>
2387a984708SDavid Chisnall{
2397a984708SDavid Chisnall};
2407a984708SDavid Chisnall
24194e3ee44SDavid Chisnalltemplate <class _Rp, class _Cp, class _A1>
24294e3ee44SDavid Chisnallstruct __weak_result_type<_Rp (_Cp::*)(_A1) volatile>
24394e3ee44SDavid Chisnall    : public binary_function<volatile _Cp*, _A1, _Rp>
2447a984708SDavid Chisnall{
2457a984708SDavid Chisnall};
2467a984708SDavid Chisnall
24794e3ee44SDavid Chisnalltemplate <class _Rp, class _Cp, class _A1>
24894e3ee44SDavid Chisnallstruct __weak_result_type<_Rp (_Cp::*)(_A1) const volatile>
24994e3ee44SDavid Chisnall    : public binary_function<const volatile _Cp*, _A1, _Rp>
2507a984708SDavid Chisnall{
2517a984708SDavid Chisnall};
2527a984708SDavid Chisnall
2539729cf09SDimitry Andric
254540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
2557a984708SDavid Chisnall// 3 or more arguments
2567a984708SDavid Chisnall
25794e3ee44SDavid Chisnalltemplate <class _Rp, class _A1, class _A2, class _A3, class ..._A4>
25894e3ee44SDavid Chisnallstruct __weak_result_type<_Rp (_A1, _A2, _A3, _A4...)>
2597a984708SDavid Chisnall{
26094e3ee44SDavid Chisnall    typedef _Rp result_type;
2617a984708SDavid Chisnall};
2627a984708SDavid Chisnall
26394e3ee44SDavid Chisnalltemplate <class _Rp, class _A1, class _A2, class _A3, class ..._A4>
26494e3ee44SDavid Chisnallstruct __weak_result_type<_Rp (&)(_A1, _A2, _A3, _A4...)>
2657a984708SDavid Chisnall{
26694e3ee44SDavid Chisnall    typedef _Rp result_type;
2677a984708SDavid Chisnall};
2687a984708SDavid Chisnall
26994e3ee44SDavid Chisnalltemplate <class _Rp, class _A1, class _A2, class _A3, class ..._A4>
27094e3ee44SDavid Chisnallstruct __weak_result_type<_Rp (*)(_A1, _A2, _A3, _A4...)>
2717a984708SDavid Chisnall{
27294e3ee44SDavid Chisnall    typedef _Rp result_type;
2737a984708SDavid Chisnall};
2747a984708SDavid Chisnall
27594e3ee44SDavid Chisnalltemplate <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
27694e3ee44SDavid Chisnallstruct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...)>
2777a984708SDavid Chisnall{
27894e3ee44SDavid Chisnall    typedef _Rp result_type;
2797a984708SDavid Chisnall};
2807a984708SDavid Chisnall
28194e3ee44SDavid Chisnalltemplate <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
28294e3ee44SDavid Chisnallstruct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const>
2837a984708SDavid Chisnall{
28494e3ee44SDavid Chisnall    typedef _Rp result_type;
2857a984708SDavid Chisnall};
2867a984708SDavid Chisnall
28794e3ee44SDavid Chisnalltemplate <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
28894e3ee44SDavid Chisnallstruct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) volatile>
2897a984708SDavid Chisnall{
29094e3ee44SDavid Chisnall    typedef _Rp result_type;
2917a984708SDavid Chisnall};
2927a984708SDavid Chisnall
29394e3ee44SDavid Chisnalltemplate <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
29494e3ee44SDavid Chisnallstruct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile>
2957a984708SDavid Chisnall{
29694e3ee44SDavid Chisnall    typedef _Rp result_type;
2977a984708SDavid Chisnall};
2987a984708SDavid Chisnall
2997a984708SDavid Chisnalltemplate <class _Tp, class ..._Args>
3007a984708SDavid Chisnallstruct __invoke_return
3017a984708SDavid Chisnall{
3027a984708SDavid Chisnall    typedef decltype(__invoke(_VSTD::declval<_Tp>(), _VSTD::declval<_Args>()...)) type;
3037a984708SDavid Chisnall};
3047a984708SDavid Chisnall
3057c82a1ecSDimitry Andric#else // defined(_LIBCPP_CXX03_LANG)
3069729cf09SDimitry Andric
3079729cf09SDimitry Andric#include <__functional_base_03>
3089729cf09SDimitry Andric
3097c82a1ecSDimitry Andric#endif  // !defined(_LIBCPP_CXX03_LANG)
3109729cf09SDimitry Andric
3119729cf09SDimitry Andric
312854fa44bSDimitry Andrictemplate <class _Ret>
313854fa44bSDimitry Andricstruct __invoke_void_return_wrapper
314854fa44bSDimitry Andric{
315540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
316854fa44bSDimitry Andric    template <class ..._Args>
3179729cf09SDimitry Andric    static _Ret __call(_Args&&... __args) {
318854fa44bSDimitry Andric        return __invoke(_VSTD::forward<_Args>(__args)...);
319854fa44bSDimitry Andric    }
3209729cf09SDimitry Andric#else
3219729cf09SDimitry Andric    template <class _Fn>
3229729cf09SDimitry Andric    static _Ret __call(_Fn __f) {
3239729cf09SDimitry Andric        return __invoke(__f);
3249729cf09SDimitry Andric    }
3259729cf09SDimitry Andric
3269729cf09SDimitry Andric    template <class _Fn, class _A0>
3279729cf09SDimitry Andric    static _Ret __call(_Fn __f, _A0& __a0) {
3289729cf09SDimitry Andric        return __invoke(__f, __a0);
3299729cf09SDimitry Andric    }
3309729cf09SDimitry Andric
3319729cf09SDimitry Andric    template <class _Fn, class _A0, class _A1>
3329729cf09SDimitry Andric    static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1) {
3339729cf09SDimitry Andric        return __invoke(__f, __a0, __a1);
3349729cf09SDimitry Andric    }
3359729cf09SDimitry Andric
3369729cf09SDimitry Andric    template <class _Fn, class _A0, class _A1, class _A2>
3379729cf09SDimitry Andric    static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2){
3389729cf09SDimitry Andric        return __invoke(__f, __a0, __a1, __a2);
3399729cf09SDimitry Andric    }
3409729cf09SDimitry Andric#endif
341854fa44bSDimitry Andric};
342854fa44bSDimitry Andric
343854fa44bSDimitry Andrictemplate <>
344854fa44bSDimitry Andricstruct __invoke_void_return_wrapper<void>
345854fa44bSDimitry Andric{
346540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
347854fa44bSDimitry Andric    template <class ..._Args>
3489729cf09SDimitry Andric    static void __call(_Args&&... __args) {
349854fa44bSDimitry Andric        __invoke(_VSTD::forward<_Args>(__args)...);
350854fa44bSDimitry Andric    }
3519729cf09SDimitry Andric#else
3529729cf09SDimitry Andric    template <class _Fn>
3539729cf09SDimitry Andric    static void __call(_Fn __f) {
3549729cf09SDimitry Andric        __invoke(__f);
3559729cf09SDimitry Andric    }
3569729cf09SDimitry Andric
3579729cf09SDimitry Andric    template <class _Fn, class _A0>
3589729cf09SDimitry Andric    static void __call(_Fn __f, _A0& __a0) {
3599729cf09SDimitry Andric        __invoke(__f, __a0);
3609729cf09SDimitry Andric    }
3619729cf09SDimitry Andric
3629729cf09SDimitry Andric    template <class _Fn, class _A0, class _A1>
3639729cf09SDimitry Andric    static void __call(_Fn __f, _A0& __a0, _A1& __a1) {
3649729cf09SDimitry Andric        __invoke(__f, __a0, __a1);
3659729cf09SDimitry Andric    }
3669729cf09SDimitry Andric
3679729cf09SDimitry Andric    template <class _Fn, class _A0, class _A1, class _A2>
3689729cf09SDimitry Andric    static void __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2) {
3699729cf09SDimitry Andric        __invoke(__f, __a0, __a1, __a2);
3709729cf09SDimitry Andric    }
3719729cf09SDimitry Andric#endif
372854fa44bSDimitry Andric};
373854fa44bSDimitry Andric
3747a984708SDavid Chisnalltemplate <class _Tp>
375aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS reference_wrapper
3767a984708SDavid Chisnall    : public __weak_result_type<_Tp>
3777a984708SDavid Chisnall{
3787a984708SDavid Chisnallpublic:
3797a984708SDavid Chisnall    // types
3807a984708SDavid Chisnall    typedef _Tp type;
3817a984708SDavid Chisnallprivate:
3827a984708SDavid Chisnall    type* __f_;
3837a984708SDavid Chisnall
3847a984708SDavid Chisnallpublic:
3857a984708SDavid Chisnall    // construct/copy/destroy
3864f7ab58eSDimitry Andric    _LIBCPP_INLINE_VISIBILITY reference_wrapper(type& __f) _NOEXCEPT
3874f7ab58eSDimitry Andric        : __f_(_VSTD::addressof(__f)) {}
388540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
3897a984708SDavid Chisnall    private: reference_wrapper(type&&); public: // = delete; // do not bind to temps
3907a984708SDavid Chisnall#endif
3917a984708SDavid Chisnall
3927a984708SDavid Chisnall    // access
3937a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY operator type&    () const _NOEXCEPT {return *__f_;}
3947a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY          type& get() const _NOEXCEPT {return *__f_;}
3957a984708SDavid Chisnall
396540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
3977a984708SDavid Chisnall    // invoke
3987a984708SDavid Chisnall    template <class... _ArgTypes>
3997a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
4007a984708SDavid Chisnall    typename __invoke_of<type&, _ArgTypes...>::type
4019729cf09SDimitry Andric    operator() (_ArgTypes&&... __args) const {
4027a984708SDavid Chisnall        return __invoke(get(), _VSTD::forward<_ArgTypes>(__args)...);
4037a984708SDavid Chisnall    }
4049729cf09SDimitry Andric#else
4059729cf09SDimitry Andric
4069729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4079729cf09SDimitry Andric    typename __invoke_return<type>::type
4089729cf09SDimitry Andric    operator() () const {
4099729cf09SDimitry Andric        return __invoke(get());
4109729cf09SDimitry Andric    }
4119729cf09SDimitry Andric
4129729cf09SDimitry Andric    template <class _A0>
4139729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4149729cf09SDimitry Andric    typename __invoke_return0<type, _A0>::type
4159729cf09SDimitry Andric    operator() (_A0& __a0) const {
4169729cf09SDimitry Andric        return __invoke(get(), __a0);
4179729cf09SDimitry Andric    }
4189729cf09SDimitry Andric
4199729cf09SDimitry Andric    template <class _A0>
4209729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4219729cf09SDimitry Andric    typename __invoke_return0<type, _A0 const>::type
4229729cf09SDimitry Andric    operator() (_A0 const& __a0) const {
4239729cf09SDimitry Andric        return __invoke(get(), __a0);
4249729cf09SDimitry Andric    }
4259729cf09SDimitry Andric
4269729cf09SDimitry Andric    template <class _A0, class _A1>
4279729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4289729cf09SDimitry Andric    typename __invoke_return1<type, _A0, _A1>::type
4299729cf09SDimitry Andric    operator() (_A0& __a0, _A1& __a1) const {
4309729cf09SDimitry Andric        return __invoke(get(), __a0, __a1);
4319729cf09SDimitry Andric    }
4329729cf09SDimitry Andric
4339729cf09SDimitry Andric    template <class _A0, class _A1>
4349729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4359729cf09SDimitry Andric    typename __invoke_return1<type, _A0 const, _A1>::type
4369729cf09SDimitry Andric    operator() (_A0 const& __a0, _A1& __a1) const {
4379729cf09SDimitry Andric        return __invoke(get(), __a0, __a1);
4389729cf09SDimitry Andric    }
4399729cf09SDimitry Andric
4409729cf09SDimitry Andric    template <class _A0, class _A1>
4419729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4429729cf09SDimitry Andric    typename __invoke_return1<type, _A0, _A1 const>::type
4439729cf09SDimitry Andric    operator() (_A0& __a0, _A1 const& __a1) const {
4449729cf09SDimitry Andric        return __invoke(get(), __a0, __a1);
4459729cf09SDimitry Andric    }
4469729cf09SDimitry Andric
4479729cf09SDimitry Andric    template <class _A0, class _A1>
4489729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4499729cf09SDimitry Andric    typename __invoke_return1<type, _A0 const, _A1 const>::type
4509729cf09SDimitry Andric    operator() (_A0 const& __a0, _A1 const& __a1) const {
4519729cf09SDimitry Andric        return __invoke(get(), __a0, __a1);
4529729cf09SDimitry Andric    }
4539729cf09SDimitry Andric
4549729cf09SDimitry Andric    template <class _A0, class _A1, class _A2>
4559729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4569729cf09SDimitry Andric    typename __invoke_return2<type, _A0, _A1, _A2>::type
4579729cf09SDimitry Andric    operator() (_A0& __a0, _A1& __a1, _A2& __a2) const {
4589729cf09SDimitry Andric        return __invoke(get(), __a0, __a1, __a2);
4599729cf09SDimitry Andric    }
4609729cf09SDimitry Andric
4619729cf09SDimitry Andric    template <class _A0, class _A1, class _A2>
4629729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4639729cf09SDimitry Andric    typename __invoke_return2<type, _A0 const, _A1, _A2>::type
4649729cf09SDimitry Andric    operator() (_A0 const& __a0, _A1& __a1, _A2& __a2) const {
4659729cf09SDimitry Andric        return __invoke(get(), __a0, __a1, __a2);
4669729cf09SDimitry Andric    }
4679729cf09SDimitry Andric
4689729cf09SDimitry Andric    template <class _A0, class _A1, class _A2>
4699729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4709729cf09SDimitry Andric    typename __invoke_return2<type, _A0, _A1 const, _A2>::type
4719729cf09SDimitry Andric    operator() (_A0& __a0, _A1 const& __a1, _A2& __a2) const {
4729729cf09SDimitry Andric        return __invoke(get(), __a0, __a1, __a2);
4739729cf09SDimitry Andric    }
4749729cf09SDimitry Andric
4759729cf09SDimitry Andric    template <class _A0, class _A1, class _A2>
4769729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4779729cf09SDimitry Andric    typename __invoke_return2<type, _A0, _A1, _A2 const>::type
4789729cf09SDimitry Andric    operator() (_A0& __a0, _A1& __a1, _A2 const& __a2) const {
4799729cf09SDimitry Andric        return __invoke(get(), __a0, __a1, __a2);
4809729cf09SDimitry Andric    }
4819729cf09SDimitry Andric
4829729cf09SDimitry Andric    template <class _A0, class _A1, class _A2>
4839729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4849729cf09SDimitry Andric    typename __invoke_return2<type, _A0 const, _A1 const, _A2>::type
4859729cf09SDimitry Andric    operator() (_A0 const& __a0, _A1 const& __a1, _A2& __a2) const {
4869729cf09SDimitry Andric        return __invoke(get(), __a0, __a1, __a2);
4879729cf09SDimitry Andric    }
4889729cf09SDimitry Andric
4899729cf09SDimitry Andric    template <class _A0, class _A1, class _A2>
4909729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4919729cf09SDimitry Andric    typename __invoke_return2<type, _A0 const, _A1, _A2 const>::type
4929729cf09SDimitry Andric    operator() (_A0 const& __a0, _A1& __a1, _A2 const& __a2) const {
4939729cf09SDimitry Andric        return __invoke(get(), __a0, __a1, __a2);
4949729cf09SDimitry Andric    }
4959729cf09SDimitry Andric
4969729cf09SDimitry Andric    template <class _A0, class _A1, class _A2>
4979729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4989729cf09SDimitry Andric    typename __invoke_return2<type, _A0, _A1 const, _A2 const>::type
4999729cf09SDimitry Andric    operator() (_A0& __a0, _A1 const& __a1, _A2 const& __a2) const {
5009729cf09SDimitry Andric        return __invoke(get(), __a0, __a1, __a2);
5019729cf09SDimitry Andric    }
5029729cf09SDimitry Andric
5039729cf09SDimitry Andric    template <class _A0, class _A1, class _A2>
5049729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
5059729cf09SDimitry Andric    typename __invoke_return2<type, _A0 const, _A1 const, _A2 const>::type
5069729cf09SDimitry Andric    operator() (_A0 const& __a0, _A1 const& __a1, _A2 const& __a2) const {
5079729cf09SDimitry Andric        return __invoke(get(), __a0, __a1, __a2);
5089729cf09SDimitry Andric    }
509540d2a8bSDimitry Andric#endif // _LIBCPP_CXX03_LANG
5107a984708SDavid Chisnall};
5117a984708SDavid Chisnall
5127a984708SDavid Chisnall
5137a984708SDavid Chisnalltemplate <class _Tp>
5147a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
5157a984708SDavid Chisnallreference_wrapper<_Tp>
5167a984708SDavid Chisnallref(_Tp& __t) _NOEXCEPT
5177a984708SDavid Chisnall{
5187a984708SDavid Chisnall    return reference_wrapper<_Tp>(__t);
5197a984708SDavid Chisnall}
5207a984708SDavid Chisnall
5217a984708SDavid Chisnalltemplate <class _Tp>
5227a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
5237a984708SDavid Chisnallreference_wrapper<_Tp>
5247a984708SDavid Chisnallref(reference_wrapper<_Tp> __t) _NOEXCEPT
5257a984708SDavid Chisnall{
5267a984708SDavid Chisnall    return ref(__t.get());
5277a984708SDavid Chisnall}
5287a984708SDavid Chisnall
5297a984708SDavid Chisnalltemplate <class _Tp>
5307a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
5317a984708SDavid Chisnallreference_wrapper<const _Tp>
5327a984708SDavid Chisnallcref(const _Tp& __t) _NOEXCEPT
5337a984708SDavid Chisnall{
5347a984708SDavid Chisnall    return reference_wrapper<const _Tp>(__t);
5357a984708SDavid Chisnall}
5367a984708SDavid Chisnall
5377a984708SDavid Chisnalltemplate <class _Tp>
5387a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
5397a984708SDavid Chisnallreference_wrapper<const _Tp>
5407a984708SDavid Chisnallcref(reference_wrapper<_Tp> __t) _NOEXCEPT
5417a984708SDavid Chisnall{
5427a984708SDavid Chisnall    return cref(__t.get());
5437a984708SDavid Chisnall}
5447a984708SDavid Chisnall
54580779b37SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
54694e3ee44SDavid Chisnalltemplate <class _Tp> void ref(const _Tp&&) = delete;
54794e3ee44SDavid Chisnalltemplate <class _Tp> void cref(const _Tp&&) = delete;
54880779b37SDimitry Andric#endif
5497a984708SDavid Chisnall
5504f7ab58eSDimitry Andric#if _LIBCPP_STD_VER > 11
55124d58133SDimitry Andrictemplate <class _Tp, class, class = void>
55224d58133SDimitry Andricstruct __is_transparent : false_type {};
55324d58133SDimitry Andric
55424d58133SDimitry Andrictemplate <class _Tp, class _Up>
55524d58133SDimitry Andricstruct __is_transparent<_Tp, _Up,
55624d58133SDimitry Andric                        typename __void_t<typename _Tp::is_transparent>::type>
55724d58133SDimitry Andric   : true_type {};
5584f7ab58eSDimitry Andric#endif
5594f7ab58eSDimitry Andric
5604f7ab58eSDimitry Andric// allocator_arg_t
5614f7ab58eSDimitry Andric
562aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS allocator_arg_t { };
5634f7ab58eSDimitry Andric
5644ba319b5SDimitry Andric#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
565*b5893f02SDimitry Andricextern _LIBCPP_EXPORTED_FROM_ABI const allocator_arg_t allocator_arg;
5664f7ab58eSDimitry Andric#else
56730785c0eSDimitry Andric/* _LIBCPP_INLINE_VAR */ constexpr allocator_arg_t allocator_arg = allocator_arg_t();
5684f7ab58eSDimitry Andric#endif
5694f7ab58eSDimitry Andric
5704f7ab58eSDimitry Andric// uses_allocator
5714f7ab58eSDimitry Andric
5724f7ab58eSDimitry Andrictemplate <class _Tp>
5734f7ab58eSDimitry Andricstruct __has_allocator_type
5744f7ab58eSDimitry Andric{
5754f7ab58eSDimitry Andricprivate:
5764f7ab58eSDimitry Andric    struct __two {char __lx; char __lxx;};
5774f7ab58eSDimitry Andric    template <class _Up> static __two __test(...);
5784f7ab58eSDimitry Andric    template <class _Up> static char __test(typename _Up::allocator_type* = 0);
5794f7ab58eSDimitry Andricpublic:
5804f7ab58eSDimitry Andric    static const bool value = sizeof(__test<_Tp>(0)) == 1;
5814f7ab58eSDimitry Andric};
5824f7ab58eSDimitry Andric
5834f7ab58eSDimitry Andrictemplate <class _Tp, class _Alloc, bool = __has_allocator_type<_Tp>::value>
5844f7ab58eSDimitry Andricstruct __uses_allocator
5854f7ab58eSDimitry Andric    : public integral_constant<bool,
5864f7ab58eSDimitry Andric        is_convertible<_Alloc, typename _Tp::allocator_type>::value>
5874f7ab58eSDimitry Andric{
5884f7ab58eSDimitry Andric};
5894f7ab58eSDimitry Andric
5904f7ab58eSDimitry Andrictemplate <class _Tp, class _Alloc>
5914f7ab58eSDimitry Andricstruct __uses_allocator<_Tp, _Alloc, false>
5924f7ab58eSDimitry Andric    : public false_type
5934f7ab58eSDimitry Andric{
5944f7ab58eSDimitry Andric};
5954f7ab58eSDimitry Andric
5964f7ab58eSDimitry Andrictemplate <class _Tp, class _Alloc>
597aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS uses_allocator
5984f7ab58eSDimitry Andric    : public __uses_allocator<_Tp, _Alloc>
5994f7ab58eSDimitry Andric{
6004f7ab58eSDimitry Andric};
6014f7ab58eSDimitry Andric
602aed8d94eSDimitry Andric#if _LIBCPP_STD_VER > 14
603aed8d94eSDimitry Andrictemplate <class _Tp, class _Alloc>
60430785c0eSDimitry Andric_LIBCPP_INLINE_VAR constexpr size_t uses_allocator_v = uses_allocator<_Tp, _Alloc>::value;
605aed8d94eSDimitry Andric#endif
606aed8d94eSDimitry Andric
607540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
6084f7ab58eSDimitry Andric
6094f7ab58eSDimitry Andric// allocator construction
6104f7ab58eSDimitry Andric
6114f7ab58eSDimitry Andrictemplate <class _Tp, class _Alloc, class ..._Args>
6124f7ab58eSDimitry Andricstruct __uses_alloc_ctor_imp
6134f7ab58eSDimitry Andric{
614aed8d94eSDimitry Andric    typedef typename __uncvref<_Alloc>::type _RawAlloc;
615aed8d94eSDimitry Andric    static const bool __ua = uses_allocator<_Tp, _RawAlloc>::value;
6164f7ab58eSDimitry Andric    static const bool __ic =
6174f7ab58eSDimitry Andric        is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value;
6184f7ab58eSDimitry Andric    static const int value = __ua ? 2 - __ic : 0;
6194f7ab58eSDimitry Andric};
6204f7ab58eSDimitry Andric
6214f7ab58eSDimitry Andrictemplate <class _Tp, class _Alloc, class ..._Args>
6224f7ab58eSDimitry Andricstruct __uses_alloc_ctor
6234f7ab58eSDimitry Andric    : integral_constant<int, __uses_alloc_ctor_imp<_Tp, _Alloc, _Args...>::value>
6244f7ab58eSDimitry Andric    {};
6254f7ab58eSDimitry Andric
6264f7ab58eSDimitry Andrictemplate <class _Tp, class _Allocator, class... _Args>
6274f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
6284f7ab58eSDimitry Andricvoid __user_alloc_construct_impl (integral_constant<int, 0>, _Tp *__storage, const _Allocator &, _Args &&... __args )
6294f7ab58eSDimitry Andric{
6304f7ab58eSDimitry Andric    new (__storage) _Tp (_VSTD::forward<_Args>(__args)...);
6314f7ab58eSDimitry Andric}
6324f7ab58eSDimitry Andric
633aed8d94eSDimitry Andric// FIXME: This should have a version which takes a non-const alloc.
6344f7ab58eSDimitry Andrictemplate <class _Tp, class _Allocator, class... _Args>
6354f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
6364f7ab58eSDimitry Andricvoid __user_alloc_construct_impl (integral_constant<int, 1>, _Tp *__storage, const _Allocator &__a, _Args &&... __args )
6374f7ab58eSDimitry Andric{
6384f7ab58eSDimitry Andric    new (__storage) _Tp (allocator_arg, __a, _VSTD::forward<_Args>(__args)...);
6394f7ab58eSDimitry Andric}
6404f7ab58eSDimitry Andric
641aed8d94eSDimitry Andric// FIXME: This should have a version which takes a non-const alloc.
6424f7ab58eSDimitry Andrictemplate <class _Tp, class _Allocator, class... _Args>
6434f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
6444f7ab58eSDimitry Andricvoid __user_alloc_construct_impl (integral_constant<int, 2>, _Tp *__storage, const _Allocator &__a, _Args &&... __args )
6454f7ab58eSDimitry Andric{
6464f7ab58eSDimitry Andric    new (__storage) _Tp (_VSTD::forward<_Args>(__args)..., __a);
6474f7ab58eSDimitry Andric}
6484f7ab58eSDimitry Andric
649540d2a8bSDimitry Andric#endif  // _LIBCPP_CXX03_LANG
6504f7ab58eSDimitry Andric
6517a984708SDavid Chisnall_LIBCPP_END_NAMESPACE_STD
6527a984708SDavid Chisnall
6537a984708SDavid Chisnall#endif  // _LIBCPP_FUNCTIONAL_BASE
654