xref: /freebsd-src/contrib/llvm-project/libcxx/include/__functional/function.h (revision fe6060f10f634930ff71b7c50291ddc610da2475)
1*fe6060f1SDimitry Andric // -*- C++ -*-
2*fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
3*fe6060f1SDimitry Andric //
4*fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5*fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
6*fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7*fe6060f1SDimitry Andric //
8*fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
9*fe6060f1SDimitry Andric 
10*fe6060f1SDimitry Andric #ifndef _LIBCPP___FUNCTIONAL_FUNCTION_H
11*fe6060f1SDimitry Andric #define _LIBCPP___FUNCTIONAL_FUNCTION_H
12*fe6060f1SDimitry Andric 
13*fe6060f1SDimitry Andric #include <__config>
14*fe6060f1SDimitry Andric #include <__functional/binary_function.h>
15*fe6060f1SDimitry Andric #include <__functional/invoke.h>
16*fe6060f1SDimitry Andric #include <__functional/unary_function.h>
17*fe6060f1SDimitry Andric #include <__iterator/iterator_traits.h>
18*fe6060f1SDimitry Andric #include <__memory/allocator_traits.h>
19*fe6060f1SDimitry Andric #include <__memory/compressed_pair.h>
20*fe6060f1SDimitry Andric #include <__memory/shared_ptr.h>
21*fe6060f1SDimitry Andric #include <exception>
22*fe6060f1SDimitry Andric #include <memory> // TODO: replace with <__memory/__builtin_new_allocator.h>
23*fe6060f1SDimitry Andric #include <type_traits>
24*fe6060f1SDimitry Andric #include <utility>
25*fe6060f1SDimitry Andric 
26*fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
27*fe6060f1SDimitry Andric #pragma GCC system_header
28*fe6060f1SDimitry Andric #endif
29*fe6060f1SDimitry Andric 
30*fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
31*fe6060f1SDimitry Andric 
32*fe6060f1SDimitry Andric // bad_function_call
33*fe6060f1SDimitry Andric 
34*fe6060f1SDimitry Andric class _LIBCPP_EXCEPTION_ABI bad_function_call
35*fe6060f1SDimitry Andric     : public exception
36*fe6060f1SDimitry Andric {
37*fe6060f1SDimitry Andric #ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
38*fe6060f1SDimitry Andric public:
39*fe6060f1SDimitry Andric     virtual ~bad_function_call() _NOEXCEPT;
40*fe6060f1SDimitry Andric 
41*fe6060f1SDimitry Andric     virtual const char* what() const _NOEXCEPT;
42*fe6060f1SDimitry Andric #endif
43*fe6060f1SDimitry Andric };
44*fe6060f1SDimitry Andric 
45*fe6060f1SDimitry Andric _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
46*fe6060f1SDimitry Andric void __throw_bad_function_call()
47*fe6060f1SDimitry Andric {
48*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
49*fe6060f1SDimitry Andric     throw bad_function_call();
50*fe6060f1SDimitry Andric #else
51*fe6060f1SDimitry Andric     _VSTD::abort();
52*fe6060f1SDimitry Andric #endif
53*fe6060f1SDimitry Andric }
54*fe6060f1SDimitry Andric 
55*fe6060f1SDimitry Andric #if defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS) && __has_attribute(deprecated)
56*fe6060f1SDimitry Andric #   define _LIBCPP_DEPRECATED_CXX03_FUNCTION \
57*fe6060f1SDimitry Andric         __attribute__((deprecated("Using std::function in C++03 is not supported anymore. Please upgrade to C++11 or later, or use a different type")))
58*fe6060f1SDimitry Andric #else
59*fe6060f1SDimitry Andric #   define _LIBCPP_DEPRECATED_CXX03_FUNCTION /* nothing */
60*fe6060f1SDimitry Andric #endif
61*fe6060f1SDimitry Andric 
62*fe6060f1SDimitry Andric template<class _Fp> class _LIBCPP_DEPRECATED_CXX03_FUNCTION _LIBCPP_TEMPLATE_VIS function; // undefined
63*fe6060f1SDimitry Andric 
64*fe6060f1SDimitry Andric namespace __function
65*fe6060f1SDimitry Andric {
66*fe6060f1SDimitry Andric 
67*fe6060f1SDimitry Andric template<class _Rp>
68*fe6060f1SDimitry Andric struct __maybe_derive_from_unary_function
69*fe6060f1SDimitry Andric {
70*fe6060f1SDimitry Andric };
71*fe6060f1SDimitry Andric 
72*fe6060f1SDimitry Andric template<class _Rp, class _A1>
73*fe6060f1SDimitry Andric struct __maybe_derive_from_unary_function<_Rp(_A1)>
74*fe6060f1SDimitry Andric     : public unary_function<_A1, _Rp>
75*fe6060f1SDimitry Andric {
76*fe6060f1SDimitry Andric };
77*fe6060f1SDimitry Andric 
78*fe6060f1SDimitry Andric template<class _Rp>
79*fe6060f1SDimitry Andric struct __maybe_derive_from_binary_function
80*fe6060f1SDimitry Andric {
81*fe6060f1SDimitry Andric };
82*fe6060f1SDimitry Andric 
83*fe6060f1SDimitry Andric template<class _Rp, class _A1, class _A2>
84*fe6060f1SDimitry Andric struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)>
85*fe6060f1SDimitry Andric     : public binary_function<_A1, _A2, _Rp>
86*fe6060f1SDimitry Andric {
87*fe6060f1SDimitry Andric };
88*fe6060f1SDimitry Andric 
89*fe6060f1SDimitry Andric template <class _Fp>
90*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY
91*fe6060f1SDimitry Andric bool __not_null(_Fp const&) { return true; }
92*fe6060f1SDimitry Andric 
93*fe6060f1SDimitry Andric template <class _Fp>
94*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY
95*fe6060f1SDimitry Andric bool __not_null(_Fp* __ptr) { return __ptr; }
96*fe6060f1SDimitry Andric 
97*fe6060f1SDimitry Andric template <class _Ret, class _Class>
98*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY
99*fe6060f1SDimitry Andric bool __not_null(_Ret _Class::*__ptr) { return __ptr; }
100*fe6060f1SDimitry Andric 
101*fe6060f1SDimitry Andric template <class _Fp>
102*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY
103*fe6060f1SDimitry Andric bool __not_null(function<_Fp> const& __f) { return !!__f; }
104*fe6060f1SDimitry Andric 
105*fe6060f1SDimitry Andric #ifdef _LIBCPP_HAS_EXTENSION_BLOCKS
106*fe6060f1SDimitry Andric template <class _Rp, class ..._Args>
107*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY
108*fe6060f1SDimitry Andric bool __not_null(_Rp (^__p)(_Args...)) { return __p; }
109*fe6060f1SDimitry Andric #endif
110*fe6060f1SDimitry Andric 
111*fe6060f1SDimitry Andric } // namespace __function
112*fe6060f1SDimitry Andric 
113*fe6060f1SDimitry Andric #ifndef _LIBCPP_CXX03_LANG
114*fe6060f1SDimitry Andric 
115*fe6060f1SDimitry Andric namespace __function {
116*fe6060f1SDimitry Andric 
117*fe6060f1SDimitry Andric // __alloc_func holds a functor and an allocator.
118*fe6060f1SDimitry Andric 
119*fe6060f1SDimitry Andric template <class _Fp, class _Ap, class _FB> class __alloc_func;
120*fe6060f1SDimitry Andric template <class _Fp, class _FB>
121*fe6060f1SDimitry Andric class __default_alloc_func;
122*fe6060f1SDimitry Andric 
123*fe6060f1SDimitry Andric template <class _Fp, class _Ap, class _Rp, class... _ArgTypes>
124*fe6060f1SDimitry Andric class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)>
125*fe6060f1SDimitry Andric {
126*fe6060f1SDimitry Andric     __compressed_pair<_Fp, _Ap> __f_;
127*fe6060f1SDimitry Andric 
128*fe6060f1SDimitry Andric   public:
129*fe6060f1SDimitry Andric     typedef _LIBCPP_NODEBUG_TYPE _Fp _Target;
130*fe6060f1SDimitry Andric     typedef _LIBCPP_NODEBUG_TYPE _Ap _Alloc;
131*fe6060f1SDimitry Andric 
132*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
133*fe6060f1SDimitry Andric     const _Target& __target() const { return __f_.first(); }
134*fe6060f1SDimitry Andric 
135*fe6060f1SDimitry Andric     // WIN32 APIs may define __allocator, so use __get_allocator instead.
136*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
137*fe6060f1SDimitry Andric     const _Alloc& __get_allocator() const { return __f_.second(); }
138*fe6060f1SDimitry Andric 
139*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
140*fe6060f1SDimitry Andric     explicit __alloc_func(_Target&& __f)
141*fe6060f1SDimitry Andric         : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)),
142*fe6060f1SDimitry Andric                _VSTD::forward_as_tuple())
143*fe6060f1SDimitry Andric     {
144*fe6060f1SDimitry Andric     }
145*fe6060f1SDimitry Andric 
146*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
147*fe6060f1SDimitry Andric     explicit __alloc_func(const _Target& __f, const _Alloc& __a)
148*fe6060f1SDimitry Andric         : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f),
149*fe6060f1SDimitry Andric                _VSTD::forward_as_tuple(__a))
150*fe6060f1SDimitry Andric     {
151*fe6060f1SDimitry Andric     }
152*fe6060f1SDimitry Andric 
153*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
154*fe6060f1SDimitry Andric     explicit __alloc_func(const _Target& __f, _Alloc&& __a)
155*fe6060f1SDimitry Andric         : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f),
156*fe6060f1SDimitry Andric                _VSTD::forward_as_tuple(_VSTD::move(__a)))
157*fe6060f1SDimitry Andric     {
158*fe6060f1SDimitry Andric     }
159*fe6060f1SDimitry Andric 
160*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
161*fe6060f1SDimitry Andric     explicit __alloc_func(_Target&& __f, _Alloc&& __a)
162*fe6060f1SDimitry Andric         : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)),
163*fe6060f1SDimitry Andric                _VSTD::forward_as_tuple(_VSTD::move(__a)))
164*fe6060f1SDimitry Andric     {
165*fe6060f1SDimitry Andric     }
166*fe6060f1SDimitry Andric 
167*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
168*fe6060f1SDimitry Andric     _Rp operator()(_ArgTypes&&... __arg)
169*fe6060f1SDimitry Andric     {
170*fe6060f1SDimitry Andric         typedef __invoke_void_return_wrapper<_Rp> _Invoker;
171*fe6060f1SDimitry Andric         return _Invoker::__call(__f_.first(),
172*fe6060f1SDimitry Andric                                 _VSTD::forward<_ArgTypes>(__arg)...);
173*fe6060f1SDimitry Andric     }
174*fe6060f1SDimitry Andric 
175*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
176*fe6060f1SDimitry Andric     __alloc_func* __clone() const
177*fe6060f1SDimitry Andric     {
178*fe6060f1SDimitry Andric         typedef allocator_traits<_Alloc> __alloc_traits;
179*fe6060f1SDimitry Andric         typedef
180*fe6060f1SDimitry Andric             typename __rebind_alloc_helper<__alloc_traits, __alloc_func>::type
181*fe6060f1SDimitry Andric                 _AA;
182*fe6060f1SDimitry Andric         _AA __a(__f_.second());
183*fe6060f1SDimitry Andric         typedef __allocator_destructor<_AA> _Dp;
184*fe6060f1SDimitry Andric         unique_ptr<__alloc_func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
185*fe6060f1SDimitry Andric         ::new ((void*)__hold.get()) __alloc_func(__f_.first(), _Alloc(__a));
186*fe6060f1SDimitry Andric         return __hold.release();
187*fe6060f1SDimitry Andric     }
188*fe6060f1SDimitry Andric 
189*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
190*fe6060f1SDimitry Andric     void destroy() _NOEXCEPT { __f_.~__compressed_pair<_Target, _Alloc>(); }
191*fe6060f1SDimitry Andric 
192*fe6060f1SDimitry Andric     static void __destroy_and_delete(__alloc_func* __f) {
193*fe6060f1SDimitry Andric       typedef allocator_traits<_Alloc> __alloc_traits;
194*fe6060f1SDimitry Andric       typedef typename __rebind_alloc_helper<__alloc_traits, __alloc_func>::type
195*fe6060f1SDimitry Andric           _FunAlloc;
196*fe6060f1SDimitry Andric       _FunAlloc __a(__f->__get_allocator());
197*fe6060f1SDimitry Andric       __f->destroy();
198*fe6060f1SDimitry Andric       __a.deallocate(__f, 1);
199*fe6060f1SDimitry Andric     }
200*fe6060f1SDimitry Andric };
201*fe6060f1SDimitry Andric 
202*fe6060f1SDimitry Andric template <class _Fp, class _Rp, class... _ArgTypes>
203*fe6060f1SDimitry Andric class __default_alloc_func<_Fp, _Rp(_ArgTypes...)> {
204*fe6060f1SDimitry Andric   _Fp __f_;
205*fe6060f1SDimitry Andric 
206*fe6060f1SDimitry Andric public:
207*fe6060f1SDimitry Andric   typedef _LIBCPP_NODEBUG_TYPE _Fp _Target;
208*fe6060f1SDimitry Andric 
209*fe6060f1SDimitry Andric   _LIBCPP_INLINE_VISIBILITY
210*fe6060f1SDimitry Andric   const _Target& __target() const { return __f_; }
211*fe6060f1SDimitry Andric 
212*fe6060f1SDimitry Andric   _LIBCPP_INLINE_VISIBILITY
213*fe6060f1SDimitry Andric   explicit __default_alloc_func(_Target&& __f) : __f_(_VSTD::move(__f)) {}
214*fe6060f1SDimitry Andric 
215*fe6060f1SDimitry Andric   _LIBCPP_INLINE_VISIBILITY
216*fe6060f1SDimitry Andric   explicit __default_alloc_func(const _Target& __f) : __f_(__f) {}
217*fe6060f1SDimitry Andric 
218*fe6060f1SDimitry Andric   _LIBCPP_INLINE_VISIBILITY
219*fe6060f1SDimitry Andric   _Rp operator()(_ArgTypes&&... __arg) {
220*fe6060f1SDimitry Andric     typedef __invoke_void_return_wrapper<_Rp> _Invoker;
221*fe6060f1SDimitry Andric     return _Invoker::__call(__f_, _VSTD::forward<_ArgTypes>(__arg)...);
222*fe6060f1SDimitry Andric   }
223*fe6060f1SDimitry Andric 
224*fe6060f1SDimitry Andric   _LIBCPP_INLINE_VISIBILITY
225*fe6060f1SDimitry Andric   __default_alloc_func* __clone() const {
226*fe6060f1SDimitry Andric       __builtin_new_allocator::__holder_t __hold =
227*fe6060f1SDimitry Andric         __builtin_new_allocator::__allocate_type<__default_alloc_func>(1);
228*fe6060f1SDimitry Andric     __default_alloc_func* __res =
229*fe6060f1SDimitry Andric         ::new ((void*)__hold.get()) __default_alloc_func(__f_);
230*fe6060f1SDimitry Andric     (void)__hold.release();
231*fe6060f1SDimitry Andric     return __res;
232*fe6060f1SDimitry Andric   }
233*fe6060f1SDimitry Andric 
234*fe6060f1SDimitry Andric   _LIBCPP_INLINE_VISIBILITY
235*fe6060f1SDimitry Andric   void destroy() _NOEXCEPT { __f_.~_Target(); }
236*fe6060f1SDimitry Andric 
237*fe6060f1SDimitry Andric   static void __destroy_and_delete(__default_alloc_func* __f) {
238*fe6060f1SDimitry Andric     __f->destroy();
239*fe6060f1SDimitry Andric       __builtin_new_allocator::__deallocate_type<__default_alloc_func>(__f, 1);
240*fe6060f1SDimitry Andric   }
241*fe6060f1SDimitry Andric };
242*fe6060f1SDimitry Andric 
243*fe6060f1SDimitry Andric // __base provides an abstract interface for copyable functors.
244*fe6060f1SDimitry Andric 
245*fe6060f1SDimitry Andric template<class _Fp> class _LIBCPP_TEMPLATE_VIS __base;
246*fe6060f1SDimitry Andric 
247*fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
248*fe6060f1SDimitry Andric class __base<_Rp(_ArgTypes...)>
249*fe6060f1SDimitry Andric {
250*fe6060f1SDimitry Andric     __base(const __base&);
251*fe6060f1SDimitry Andric     __base& operator=(const __base&);
252*fe6060f1SDimitry Andric public:
253*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY __base() {}
254*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY virtual ~__base() {}
255*fe6060f1SDimitry Andric     virtual __base* __clone() const = 0;
256*fe6060f1SDimitry Andric     virtual void __clone(__base*) const = 0;
257*fe6060f1SDimitry Andric     virtual void destroy() _NOEXCEPT = 0;
258*fe6060f1SDimitry Andric     virtual void destroy_deallocate() _NOEXCEPT = 0;
259*fe6060f1SDimitry Andric     virtual _Rp operator()(_ArgTypes&& ...) = 0;
260*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI
261*fe6060f1SDimitry Andric     virtual const void* target(const type_info&) const _NOEXCEPT = 0;
262*fe6060f1SDimitry Andric     virtual const std::type_info& target_type() const _NOEXCEPT = 0;
263*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI
264*fe6060f1SDimitry Andric };
265*fe6060f1SDimitry Andric 
266*fe6060f1SDimitry Andric // __func implements __base for a given functor type.
267*fe6060f1SDimitry Andric 
268*fe6060f1SDimitry Andric template<class _FD, class _Alloc, class _FB> class __func;
269*fe6060f1SDimitry Andric 
270*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
271*fe6060f1SDimitry Andric class __func<_Fp, _Alloc, _Rp(_ArgTypes...)>
272*fe6060f1SDimitry Andric     : public  __base<_Rp(_ArgTypes...)>
273*fe6060f1SDimitry Andric {
274*fe6060f1SDimitry Andric     __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> __f_;
275*fe6060f1SDimitry Andric public:
276*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
277*fe6060f1SDimitry Andric     explicit __func(_Fp&& __f)
278*fe6060f1SDimitry Andric         : __f_(_VSTD::move(__f)) {}
279*fe6060f1SDimitry Andric 
280*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
281*fe6060f1SDimitry Andric     explicit __func(const _Fp& __f, const _Alloc& __a)
282*fe6060f1SDimitry Andric         : __f_(__f, __a) {}
283*fe6060f1SDimitry Andric 
284*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
285*fe6060f1SDimitry Andric     explicit __func(const _Fp& __f, _Alloc&& __a)
286*fe6060f1SDimitry Andric         : __f_(__f, _VSTD::move(__a)) {}
287*fe6060f1SDimitry Andric 
288*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
289*fe6060f1SDimitry Andric     explicit __func(_Fp&& __f, _Alloc&& __a)
290*fe6060f1SDimitry Andric         : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
291*fe6060f1SDimitry Andric 
292*fe6060f1SDimitry Andric     virtual __base<_Rp(_ArgTypes...)>* __clone() const;
293*fe6060f1SDimitry Andric     virtual void __clone(__base<_Rp(_ArgTypes...)>*) const;
294*fe6060f1SDimitry Andric     virtual void destroy() _NOEXCEPT;
295*fe6060f1SDimitry Andric     virtual void destroy_deallocate() _NOEXCEPT;
296*fe6060f1SDimitry Andric     virtual _Rp operator()(_ArgTypes&&... __arg);
297*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI
298*fe6060f1SDimitry Andric     virtual const void* target(const type_info&) const _NOEXCEPT;
299*fe6060f1SDimitry Andric     virtual const std::type_info& target_type() const _NOEXCEPT;
300*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI
301*fe6060f1SDimitry Andric };
302*fe6060f1SDimitry Andric 
303*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
304*fe6060f1SDimitry Andric __base<_Rp(_ArgTypes...)>*
305*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const
306*fe6060f1SDimitry Andric {
307*fe6060f1SDimitry Andric     typedef allocator_traits<_Alloc> __alloc_traits;
308*fe6060f1SDimitry Andric     typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
309*fe6060f1SDimitry Andric     _Ap __a(__f_.__get_allocator());
310*fe6060f1SDimitry Andric     typedef __allocator_destructor<_Ap> _Dp;
311*fe6060f1SDimitry Andric     unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
312*fe6060f1SDimitry Andric     ::new ((void*)__hold.get()) __func(__f_.__target(), _Alloc(__a));
313*fe6060f1SDimitry Andric     return __hold.release();
314*fe6060f1SDimitry Andric }
315*fe6060f1SDimitry Andric 
316*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
317*fe6060f1SDimitry Andric void
318*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const
319*fe6060f1SDimitry Andric {
320*fe6060f1SDimitry Andric     ::new ((void*)__p) __func(__f_.__target(), __f_.__get_allocator());
321*fe6060f1SDimitry Andric }
322*fe6060f1SDimitry Andric 
323*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
324*fe6060f1SDimitry Andric void
325*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() _NOEXCEPT
326*fe6060f1SDimitry Andric {
327*fe6060f1SDimitry Andric     __f_.destroy();
328*fe6060f1SDimitry Andric }
329*fe6060f1SDimitry Andric 
330*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
331*fe6060f1SDimitry Andric void
332*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT
333*fe6060f1SDimitry Andric {
334*fe6060f1SDimitry Andric     typedef allocator_traits<_Alloc> __alloc_traits;
335*fe6060f1SDimitry Andric     typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
336*fe6060f1SDimitry Andric     _Ap __a(__f_.__get_allocator());
337*fe6060f1SDimitry Andric     __f_.destroy();
338*fe6060f1SDimitry Andric     __a.deallocate(this, 1);
339*fe6060f1SDimitry Andric }
340*fe6060f1SDimitry Andric 
341*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
342*fe6060f1SDimitry Andric _Rp
343*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
344*fe6060f1SDimitry Andric {
345*fe6060f1SDimitry Andric     return __f_(_VSTD::forward<_ArgTypes>(__arg)...);
346*fe6060f1SDimitry Andric }
347*fe6060f1SDimitry Andric 
348*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI
349*fe6060f1SDimitry Andric 
350*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
351*fe6060f1SDimitry Andric const void*
352*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT
353*fe6060f1SDimitry Andric {
354*fe6060f1SDimitry Andric     if (__ti == typeid(_Fp))
355*fe6060f1SDimitry Andric         return &__f_.__target();
356*fe6060f1SDimitry Andric     return nullptr;
357*fe6060f1SDimitry Andric }
358*fe6060f1SDimitry Andric 
359*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
360*fe6060f1SDimitry Andric const std::type_info&
361*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT
362*fe6060f1SDimitry Andric {
363*fe6060f1SDimitry Andric     return typeid(_Fp);
364*fe6060f1SDimitry Andric }
365*fe6060f1SDimitry Andric 
366*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI
367*fe6060f1SDimitry Andric 
368*fe6060f1SDimitry Andric // __value_func creates a value-type from a __func.
369*fe6060f1SDimitry Andric 
370*fe6060f1SDimitry Andric template <class _Fp> class __value_func;
371*fe6060f1SDimitry Andric 
372*fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> class __value_func<_Rp(_ArgTypes...)>
373*fe6060f1SDimitry Andric {
374*fe6060f1SDimitry Andric     typename aligned_storage<3 * sizeof(void*)>::type __buf_;
375*fe6060f1SDimitry Andric 
376*fe6060f1SDimitry Andric     typedef __base<_Rp(_ArgTypes...)> __func;
377*fe6060f1SDimitry Andric     __func* __f_;
378*fe6060f1SDimitry Andric 
379*fe6060f1SDimitry Andric     _LIBCPP_NO_CFI static __func* __as_base(void* p)
380*fe6060f1SDimitry Andric     {
381*fe6060f1SDimitry Andric         return reinterpret_cast<__func*>(p);
382*fe6060f1SDimitry Andric     }
383*fe6060f1SDimitry Andric 
384*fe6060f1SDimitry Andric   public:
385*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
386*fe6060f1SDimitry Andric     __value_func() _NOEXCEPT : __f_(nullptr) {}
387*fe6060f1SDimitry Andric 
388*fe6060f1SDimitry Andric     template <class _Fp, class _Alloc>
389*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY __value_func(_Fp&& __f, const _Alloc& __a)
390*fe6060f1SDimitry Andric         : __f_(nullptr)
391*fe6060f1SDimitry Andric     {
392*fe6060f1SDimitry Andric         typedef allocator_traits<_Alloc> __alloc_traits;
393*fe6060f1SDimitry Andric         typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun;
394*fe6060f1SDimitry Andric         typedef typename __rebind_alloc_helper<__alloc_traits, _Fun>::type
395*fe6060f1SDimitry Andric             _FunAlloc;
396*fe6060f1SDimitry Andric 
397*fe6060f1SDimitry Andric         if (__function::__not_null(__f))
398*fe6060f1SDimitry Andric         {
399*fe6060f1SDimitry Andric             _FunAlloc __af(__a);
400*fe6060f1SDimitry Andric             if (sizeof(_Fun) <= sizeof(__buf_) &&
401*fe6060f1SDimitry Andric                 is_nothrow_copy_constructible<_Fp>::value &&
402*fe6060f1SDimitry Andric                 is_nothrow_copy_constructible<_FunAlloc>::value)
403*fe6060f1SDimitry Andric             {
404*fe6060f1SDimitry Andric                 __f_ =
405*fe6060f1SDimitry Andric                     ::new ((void*)&__buf_) _Fun(_VSTD::move(__f), _Alloc(__af));
406*fe6060f1SDimitry Andric             }
407*fe6060f1SDimitry Andric             else
408*fe6060f1SDimitry Andric             {
409*fe6060f1SDimitry Andric                 typedef __allocator_destructor<_FunAlloc> _Dp;
410*fe6060f1SDimitry Andric                 unique_ptr<__func, _Dp> __hold(__af.allocate(1), _Dp(__af, 1));
411*fe6060f1SDimitry Andric                 ::new ((void*)__hold.get()) _Fun(_VSTD::move(__f), _Alloc(__a));
412*fe6060f1SDimitry Andric                 __f_ = __hold.release();
413*fe6060f1SDimitry Andric             }
414*fe6060f1SDimitry Andric         }
415*fe6060f1SDimitry Andric     }
416*fe6060f1SDimitry Andric 
417*fe6060f1SDimitry Andric     template <class _Fp,
418*fe6060f1SDimitry Andric         class = typename enable_if<!is_same<typename decay<_Fp>::type, __value_func>::value>::type>
419*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY explicit __value_func(_Fp&& __f)
420*fe6060f1SDimitry Andric         : __value_func(_VSTD::forward<_Fp>(__f), allocator<_Fp>()) {}
421*fe6060f1SDimitry Andric 
422*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
423*fe6060f1SDimitry Andric     __value_func(const __value_func& __f)
424*fe6060f1SDimitry Andric     {
425*fe6060f1SDimitry Andric         if (__f.__f_ == nullptr)
426*fe6060f1SDimitry Andric             __f_ = nullptr;
427*fe6060f1SDimitry Andric         else if ((void*)__f.__f_ == &__f.__buf_)
428*fe6060f1SDimitry Andric         {
429*fe6060f1SDimitry Andric             __f_ = __as_base(&__buf_);
430*fe6060f1SDimitry Andric             __f.__f_->__clone(__f_);
431*fe6060f1SDimitry Andric         }
432*fe6060f1SDimitry Andric         else
433*fe6060f1SDimitry Andric             __f_ = __f.__f_->__clone();
434*fe6060f1SDimitry Andric     }
435*fe6060f1SDimitry Andric 
436*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
437*fe6060f1SDimitry Andric     __value_func(__value_func&& __f) _NOEXCEPT
438*fe6060f1SDimitry Andric     {
439*fe6060f1SDimitry Andric         if (__f.__f_ == nullptr)
440*fe6060f1SDimitry Andric             __f_ = nullptr;
441*fe6060f1SDimitry Andric         else if ((void*)__f.__f_ == &__f.__buf_)
442*fe6060f1SDimitry Andric         {
443*fe6060f1SDimitry Andric             __f_ = __as_base(&__buf_);
444*fe6060f1SDimitry Andric             __f.__f_->__clone(__f_);
445*fe6060f1SDimitry Andric         }
446*fe6060f1SDimitry Andric         else
447*fe6060f1SDimitry Andric         {
448*fe6060f1SDimitry Andric             __f_ = __f.__f_;
449*fe6060f1SDimitry Andric             __f.__f_ = nullptr;
450*fe6060f1SDimitry Andric         }
451*fe6060f1SDimitry Andric     }
452*fe6060f1SDimitry Andric 
453*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
454*fe6060f1SDimitry Andric     ~__value_func()
455*fe6060f1SDimitry Andric     {
456*fe6060f1SDimitry Andric         if ((void*)__f_ == &__buf_)
457*fe6060f1SDimitry Andric             __f_->destroy();
458*fe6060f1SDimitry Andric         else if (__f_)
459*fe6060f1SDimitry Andric             __f_->destroy_deallocate();
460*fe6060f1SDimitry Andric     }
461*fe6060f1SDimitry Andric 
462*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
463*fe6060f1SDimitry Andric     __value_func& operator=(__value_func&& __f)
464*fe6060f1SDimitry Andric     {
465*fe6060f1SDimitry Andric         *this = nullptr;
466*fe6060f1SDimitry Andric         if (__f.__f_ == nullptr)
467*fe6060f1SDimitry Andric             __f_ = nullptr;
468*fe6060f1SDimitry Andric         else if ((void*)__f.__f_ == &__f.__buf_)
469*fe6060f1SDimitry Andric         {
470*fe6060f1SDimitry Andric             __f_ = __as_base(&__buf_);
471*fe6060f1SDimitry Andric             __f.__f_->__clone(__f_);
472*fe6060f1SDimitry Andric         }
473*fe6060f1SDimitry Andric         else
474*fe6060f1SDimitry Andric         {
475*fe6060f1SDimitry Andric             __f_ = __f.__f_;
476*fe6060f1SDimitry Andric             __f.__f_ = nullptr;
477*fe6060f1SDimitry Andric         }
478*fe6060f1SDimitry Andric         return *this;
479*fe6060f1SDimitry Andric     }
480*fe6060f1SDimitry Andric 
481*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
482*fe6060f1SDimitry Andric     __value_func& operator=(nullptr_t)
483*fe6060f1SDimitry Andric     {
484*fe6060f1SDimitry Andric         __func* __f = __f_;
485*fe6060f1SDimitry Andric         __f_ = nullptr;
486*fe6060f1SDimitry Andric         if ((void*)__f == &__buf_)
487*fe6060f1SDimitry Andric             __f->destroy();
488*fe6060f1SDimitry Andric         else if (__f)
489*fe6060f1SDimitry Andric             __f->destroy_deallocate();
490*fe6060f1SDimitry Andric         return *this;
491*fe6060f1SDimitry Andric     }
492*fe6060f1SDimitry Andric 
493*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
494*fe6060f1SDimitry Andric     _Rp operator()(_ArgTypes&&... __args) const
495*fe6060f1SDimitry Andric     {
496*fe6060f1SDimitry Andric         if (__f_ == nullptr)
497*fe6060f1SDimitry Andric             __throw_bad_function_call();
498*fe6060f1SDimitry Andric         return (*__f_)(_VSTD::forward<_ArgTypes>(__args)...);
499*fe6060f1SDimitry Andric     }
500*fe6060f1SDimitry Andric 
501*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
502*fe6060f1SDimitry Andric     void swap(__value_func& __f) _NOEXCEPT
503*fe6060f1SDimitry Andric     {
504*fe6060f1SDimitry Andric         if (&__f == this)
505*fe6060f1SDimitry Andric             return;
506*fe6060f1SDimitry Andric         if ((void*)__f_ == &__buf_ && (void*)__f.__f_ == &__f.__buf_)
507*fe6060f1SDimitry Andric         {
508*fe6060f1SDimitry Andric             typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
509*fe6060f1SDimitry Andric             __func* __t = __as_base(&__tempbuf);
510*fe6060f1SDimitry Andric             __f_->__clone(__t);
511*fe6060f1SDimitry Andric             __f_->destroy();
512*fe6060f1SDimitry Andric             __f_ = nullptr;
513*fe6060f1SDimitry Andric             __f.__f_->__clone(__as_base(&__buf_));
514*fe6060f1SDimitry Andric             __f.__f_->destroy();
515*fe6060f1SDimitry Andric             __f.__f_ = nullptr;
516*fe6060f1SDimitry Andric             __f_ = __as_base(&__buf_);
517*fe6060f1SDimitry Andric             __t->__clone(__as_base(&__f.__buf_));
518*fe6060f1SDimitry Andric             __t->destroy();
519*fe6060f1SDimitry Andric             __f.__f_ = __as_base(&__f.__buf_);
520*fe6060f1SDimitry Andric         }
521*fe6060f1SDimitry Andric         else if ((void*)__f_ == &__buf_)
522*fe6060f1SDimitry Andric         {
523*fe6060f1SDimitry Andric             __f_->__clone(__as_base(&__f.__buf_));
524*fe6060f1SDimitry Andric             __f_->destroy();
525*fe6060f1SDimitry Andric             __f_ = __f.__f_;
526*fe6060f1SDimitry Andric             __f.__f_ = __as_base(&__f.__buf_);
527*fe6060f1SDimitry Andric         }
528*fe6060f1SDimitry Andric         else if ((void*)__f.__f_ == &__f.__buf_)
529*fe6060f1SDimitry Andric         {
530*fe6060f1SDimitry Andric             __f.__f_->__clone(__as_base(&__buf_));
531*fe6060f1SDimitry Andric             __f.__f_->destroy();
532*fe6060f1SDimitry Andric             __f.__f_ = __f_;
533*fe6060f1SDimitry Andric             __f_ = __as_base(&__buf_);
534*fe6060f1SDimitry Andric         }
535*fe6060f1SDimitry Andric         else
536*fe6060f1SDimitry Andric             _VSTD::swap(__f_, __f.__f_);
537*fe6060f1SDimitry Andric     }
538*fe6060f1SDimitry Andric 
539*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
540*fe6060f1SDimitry Andric     explicit operator bool() const _NOEXCEPT { return __f_ != nullptr; }
541*fe6060f1SDimitry Andric 
542*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI
543*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
544*fe6060f1SDimitry Andric     const std::type_info& target_type() const _NOEXCEPT
545*fe6060f1SDimitry Andric     {
546*fe6060f1SDimitry Andric         if (__f_ == nullptr)
547*fe6060f1SDimitry Andric             return typeid(void);
548*fe6060f1SDimitry Andric         return __f_->target_type();
549*fe6060f1SDimitry Andric     }
550*fe6060f1SDimitry Andric 
551*fe6060f1SDimitry Andric     template <typename _Tp>
552*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT
553*fe6060f1SDimitry Andric     {
554*fe6060f1SDimitry Andric         if (__f_ == nullptr)
555*fe6060f1SDimitry Andric             return nullptr;
556*fe6060f1SDimitry Andric         return (const _Tp*)__f_->target(typeid(_Tp));
557*fe6060f1SDimitry Andric     }
558*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI
559*fe6060f1SDimitry Andric };
560*fe6060f1SDimitry Andric 
561*fe6060f1SDimitry Andric // Storage for a functor object, to be used with __policy to manage copy and
562*fe6060f1SDimitry Andric // destruction.
563*fe6060f1SDimitry Andric union __policy_storage
564*fe6060f1SDimitry Andric {
565*fe6060f1SDimitry Andric     mutable char __small[sizeof(void*) * 2];
566*fe6060f1SDimitry Andric     void* __large;
567*fe6060f1SDimitry Andric };
568*fe6060f1SDimitry Andric 
569*fe6060f1SDimitry Andric // True if _Fun can safely be held in __policy_storage.__small.
570*fe6060f1SDimitry Andric template <typename _Fun>
571*fe6060f1SDimitry Andric struct __use_small_storage
572*fe6060f1SDimitry Andric     : public integral_constant<
573*fe6060f1SDimitry Andric           bool, sizeof(_Fun) <= sizeof(__policy_storage) &&
574*fe6060f1SDimitry Andric                     _LIBCPP_ALIGNOF(_Fun) <= _LIBCPP_ALIGNOF(__policy_storage) &&
575*fe6060f1SDimitry Andric                     is_trivially_copy_constructible<_Fun>::value &&
576*fe6060f1SDimitry Andric                     is_trivially_destructible<_Fun>::value> {};
577*fe6060f1SDimitry Andric 
578*fe6060f1SDimitry Andric // Policy contains information about how to copy, destroy, and move the
579*fe6060f1SDimitry Andric // underlying functor. You can think of it as a vtable of sorts.
580*fe6060f1SDimitry Andric struct __policy
581*fe6060f1SDimitry Andric {
582*fe6060f1SDimitry Andric     // Used to copy or destroy __large values. null for trivial objects.
583*fe6060f1SDimitry Andric     void* (*const __clone)(const void*);
584*fe6060f1SDimitry Andric     void (*const __destroy)(void*);
585*fe6060f1SDimitry Andric 
586*fe6060f1SDimitry Andric     // True if this is the null policy (no value).
587*fe6060f1SDimitry Andric     const bool __is_null;
588*fe6060f1SDimitry Andric 
589*fe6060f1SDimitry Andric     // The target type. May be null if RTTI is disabled.
590*fe6060f1SDimitry Andric     const std::type_info* const __type_info;
591*fe6060f1SDimitry Andric 
592*fe6060f1SDimitry Andric     // Returns a pointer to a static policy object suitable for the functor
593*fe6060f1SDimitry Andric     // type.
594*fe6060f1SDimitry Andric     template <typename _Fun>
595*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY static const __policy* __create()
596*fe6060f1SDimitry Andric     {
597*fe6060f1SDimitry Andric         return __choose_policy<_Fun>(__use_small_storage<_Fun>());
598*fe6060f1SDimitry Andric     }
599*fe6060f1SDimitry Andric 
600*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
601*fe6060f1SDimitry Andric     static const __policy* __create_empty()
602*fe6060f1SDimitry Andric     {
603*fe6060f1SDimitry Andric         static const _LIBCPP_CONSTEXPR __policy __policy_ = {nullptr, nullptr,
604*fe6060f1SDimitry Andric                                                              true,
605*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI
606*fe6060f1SDimitry Andric                                                              &typeid(void)
607*fe6060f1SDimitry Andric #else
608*fe6060f1SDimitry Andric                                                              nullptr
609*fe6060f1SDimitry Andric #endif
610*fe6060f1SDimitry Andric         };
611*fe6060f1SDimitry Andric         return &__policy_;
612*fe6060f1SDimitry Andric     }
613*fe6060f1SDimitry Andric 
614*fe6060f1SDimitry Andric   private:
615*fe6060f1SDimitry Andric     template <typename _Fun> static void* __large_clone(const void* __s)
616*fe6060f1SDimitry Andric     {
617*fe6060f1SDimitry Andric         const _Fun* __f = static_cast<const _Fun*>(__s);
618*fe6060f1SDimitry Andric         return __f->__clone();
619*fe6060f1SDimitry Andric     }
620*fe6060f1SDimitry Andric 
621*fe6060f1SDimitry Andric     template <typename _Fun>
622*fe6060f1SDimitry Andric     static void __large_destroy(void* __s) {
623*fe6060f1SDimitry Andric       _Fun::__destroy_and_delete(static_cast<_Fun*>(__s));
624*fe6060f1SDimitry Andric     }
625*fe6060f1SDimitry Andric 
626*fe6060f1SDimitry Andric     template <typename _Fun>
627*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY static const __policy*
628*fe6060f1SDimitry Andric     __choose_policy(/* is_small = */ false_type) {
629*fe6060f1SDimitry Andric       static const _LIBCPP_CONSTEXPR __policy __policy_ = {
630*fe6060f1SDimitry Andric           &__large_clone<_Fun>, &__large_destroy<_Fun>, false,
631*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI
632*fe6060f1SDimitry Andric           &typeid(typename _Fun::_Target)
633*fe6060f1SDimitry Andric #else
634*fe6060f1SDimitry Andric           nullptr
635*fe6060f1SDimitry Andric #endif
636*fe6060f1SDimitry Andric       };
637*fe6060f1SDimitry Andric         return &__policy_;
638*fe6060f1SDimitry Andric     }
639*fe6060f1SDimitry Andric 
640*fe6060f1SDimitry Andric     template <typename _Fun>
641*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY static const __policy*
642*fe6060f1SDimitry Andric         __choose_policy(/* is_small = */ true_type)
643*fe6060f1SDimitry Andric     {
644*fe6060f1SDimitry Andric         static const _LIBCPP_CONSTEXPR __policy __policy_ = {
645*fe6060f1SDimitry Andric             nullptr, nullptr, false,
646*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI
647*fe6060f1SDimitry Andric             &typeid(typename _Fun::_Target)
648*fe6060f1SDimitry Andric #else
649*fe6060f1SDimitry Andric             nullptr
650*fe6060f1SDimitry Andric #endif
651*fe6060f1SDimitry Andric         };
652*fe6060f1SDimitry Andric         return &__policy_;
653*fe6060f1SDimitry Andric     }
654*fe6060f1SDimitry Andric };
655*fe6060f1SDimitry Andric 
656*fe6060f1SDimitry Andric // Used to choose between perfect forwarding or pass-by-value. Pass-by-value is
657*fe6060f1SDimitry Andric // faster for types that can be passed in registers.
658*fe6060f1SDimitry Andric template <typename _Tp>
659*fe6060f1SDimitry Andric using __fast_forward =
660*fe6060f1SDimitry Andric     typename conditional<is_scalar<_Tp>::value, _Tp, _Tp&&>::type;
661*fe6060f1SDimitry Andric 
662*fe6060f1SDimitry Andric // __policy_invoker calls an instance of __alloc_func held in __policy_storage.
663*fe6060f1SDimitry Andric 
664*fe6060f1SDimitry Andric template <class _Fp> struct __policy_invoker;
665*fe6060f1SDimitry Andric 
666*fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
667*fe6060f1SDimitry Andric struct __policy_invoker<_Rp(_ArgTypes...)>
668*fe6060f1SDimitry Andric {
669*fe6060f1SDimitry Andric     typedef _Rp (*__Call)(const __policy_storage*,
670*fe6060f1SDimitry Andric                           __fast_forward<_ArgTypes>...);
671*fe6060f1SDimitry Andric 
672*fe6060f1SDimitry Andric     __Call __call_;
673*fe6060f1SDimitry Andric 
674*fe6060f1SDimitry Andric     // Creates an invoker that throws bad_function_call.
675*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
676*fe6060f1SDimitry Andric     __policy_invoker() : __call_(&__call_empty) {}
677*fe6060f1SDimitry Andric 
678*fe6060f1SDimitry Andric     // Creates an invoker that calls the given instance of __func.
679*fe6060f1SDimitry Andric     template <typename _Fun>
680*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY static __policy_invoker __create()
681*fe6060f1SDimitry Andric     {
682*fe6060f1SDimitry Andric         return __policy_invoker(&__call_impl<_Fun>);
683*fe6060f1SDimitry Andric     }
684*fe6060f1SDimitry Andric 
685*fe6060f1SDimitry Andric   private:
686*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
687*fe6060f1SDimitry Andric     explicit __policy_invoker(__Call __c) : __call_(__c) {}
688*fe6060f1SDimitry Andric 
689*fe6060f1SDimitry Andric     static _Rp __call_empty(const __policy_storage*,
690*fe6060f1SDimitry Andric                             __fast_forward<_ArgTypes>...)
691*fe6060f1SDimitry Andric     {
692*fe6060f1SDimitry Andric         __throw_bad_function_call();
693*fe6060f1SDimitry Andric     }
694*fe6060f1SDimitry Andric 
695*fe6060f1SDimitry Andric     template <typename _Fun>
696*fe6060f1SDimitry Andric     static _Rp __call_impl(const __policy_storage* __buf,
697*fe6060f1SDimitry Andric                            __fast_forward<_ArgTypes>... __args)
698*fe6060f1SDimitry Andric     {
699*fe6060f1SDimitry Andric         _Fun* __f = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value
700*fe6060f1SDimitry Andric                                                 ? &__buf->__small
701*fe6060f1SDimitry Andric                                                 : __buf->__large);
702*fe6060f1SDimitry Andric         return (*__f)(_VSTD::forward<_ArgTypes>(__args)...);
703*fe6060f1SDimitry Andric     }
704*fe6060f1SDimitry Andric };
705*fe6060f1SDimitry Andric 
706*fe6060f1SDimitry Andric // __policy_func uses a __policy and __policy_invoker to create a type-erased,
707*fe6060f1SDimitry Andric // copyable functor.
708*fe6060f1SDimitry Andric 
709*fe6060f1SDimitry Andric template <class _Fp> class __policy_func;
710*fe6060f1SDimitry Andric 
711*fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> class __policy_func<_Rp(_ArgTypes...)>
712*fe6060f1SDimitry Andric {
713*fe6060f1SDimitry Andric     // Inline storage for small objects.
714*fe6060f1SDimitry Andric     __policy_storage __buf_;
715*fe6060f1SDimitry Andric 
716*fe6060f1SDimitry Andric     // Calls the value stored in __buf_. This could technically be part of
717*fe6060f1SDimitry Andric     // policy, but storing it here eliminates a level of indirection inside
718*fe6060f1SDimitry Andric     // operator().
719*fe6060f1SDimitry Andric     typedef __function::__policy_invoker<_Rp(_ArgTypes...)> __invoker;
720*fe6060f1SDimitry Andric     __invoker __invoker_;
721*fe6060f1SDimitry Andric 
722*fe6060f1SDimitry Andric     // The policy that describes how to move / copy / destroy __buf_. Never
723*fe6060f1SDimitry Andric     // null, even if the function is empty.
724*fe6060f1SDimitry Andric     const __policy* __policy_;
725*fe6060f1SDimitry Andric 
726*fe6060f1SDimitry Andric   public:
727*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
728*fe6060f1SDimitry Andric     __policy_func() : __policy_(__policy::__create_empty()) {}
729*fe6060f1SDimitry Andric 
730*fe6060f1SDimitry Andric     template <class _Fp, class _Alloc>
731*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY __policy_func(_Fp&& __f, const _Alloc& __a)
732*fe6060f1SDimitry Andric         : __policy_(__policy::__create_empty())
733*fe6060f1SDimitry Andric     {
734*fe6060f1SDimitry Andric         typedef __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun;
735*fe6060f1SDimitry Andric         typedef allocator_traits<_Alloc> __alloc_traits;
736*fe6060f1SDimitry Andric         typedef typename __rebind_alloc_helper<__alloc_traits, _Fun>::type
737*fe6060f1SDimitry Andric             _FunAlloc;
738*fe6060f1SDimitry Andric 
739*fe6060f1SDimitry Andric         if (__function::__not_null(__f))
740*fe6060f1SDimitry Andric         {
741*fe6060f1SDimitry Andric             __invoker_ = __invoker::template __create<_Fun>();
742*fe6060f1SDimitry Andric             __policy_ = __policy::__create<_Fun>();
743*fe6060f1SDimitry Andric 
744*fe6060f1SDimitry Andric             _FunAlloc __af(__a);
745*fe6060f1SDimitry Andric             if (__use_small_storage<_Fun>())
746*fe6060f1SDimitry Andric             {
747*fe6060f1SDimitry Andric                 ::new ((void*)&__buf_.__small)
748*fe6060f1SDimitry Andric                     _Fun(_VSTD::move(__f), _Alloc(__af));
749*fe6060f1SDimitry Andric             }
750*fe6060f1SDimitry Andric             else
751*fe6060f1SDimitry Andric             {
752*fe6060f1SDimitry Andric                 typedef __allocator_destructor<_FunAlloc> _Dp;
753*fe6060f1SDimitry Andric                 unique_ptr<_Fun, _Dp> __hold(__af.allocate(1), _Dp(__af, 1));
754*fe6060f1SDimitry Andric                 ::new ((void*)__hold.get())
755*fe6060f1SDimitry Andric                     _Fun(_VSTD::move(__f), _Alloc(__af));
756*fe6060f1SDimitry Andric                 __buf_.__large = __hold.release();
757*fe6060f1SDimitry Andric             }
758*fe6060f1SDimitry Andric         }
759*fe6060f1SDimitry Andric     }
760*fe6060f1SDimitry Andric 
761*fe6060f1SDimitry Andric     template <class _Fp, class = typename enable_if<!is_same<typename decay<_Fp>::type, __policy_func>::value>::type>
762*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY explicit __policy_func(_Fp&& __f)
763*fe6060f1SDimitry Andric         : __policy_(__policy::__create_empty()) {
764*fe6060f1SDimitry Andric       typedef __default_alloc_func<_Fp, _Rp(_ArgTypes...)> _Fun;
765*fe6060f1SDimitry Andric 
766*fe6060f1SDimitry Andric       if (__function::__not_null(__f)) {
767*fe6060f1SDimitry Andric         __invoker_ = __invoker::template __create<_Fun>();
768*fe6060f1SDimitry Andric         __policy_ = __policy::__create<_Fun>();
769*fe6060f1SDimitry Andric         if (__use_small_storage<_Fun>()) {
770*fe6060f1SDimitry Andric           ::new ((void*)&__buf_.__small) _Fun(_VSTD::move(__f));
771*fe6060f1SDimitry Andric         } else {
772*fe6060f1SDimitry Andric           __builtin_new_allocator::__holder_t __hold =
773*fe6060f1SDimitry Andric               __builtin_new_allocator::__allocate_type<_Fun>(1);
774*fe6060f1SDimitry Andric           __buf_.__large = ::new ((void*)__hold.get()) _Fun(_VSTD::move(__f));
775*fe6060f1SDimitry Andric           (void)__hold.release();
776*fe6060f1SDimitry Andric         }
777*fe6060f1SDimitry Andric       }
778*fe6060f1SDimitry Andric     }
779*fe6060f1SDimitry Andric 
780*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
781*fe6060f1SDimitry Andric     __policy_func(const __policy_func& __f)
782*fe6060f1SDimitry Andric         : __buf_(__f.__buf_), __invoker_(__f.__invoker_),
783*fe6060f1SDimitry Andric           __policy_(__f.__policy_)
784*fe6060f1SDimitry Andric     {
785*fe6060f1SDimitry Andric         if (__policy_->__clone)
786*fe6060f1SDimitry Andric             __buf_.__large = __policy_->__clone(__f.__buf_.__large);
787*fe6060f1SDimitry Andric     }
788*fe6060f1SDimitry Andric 
789*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
790*fe6060f1SDimitry Andric     __policy_func(__policy_func&& __f)
791*fe6060f1SDimitry Andric         : __buf_(__f.__buf_), __invoker_(__f.__invoker_),
792*fe6060f1SDimitry Andric           __policy_(__f.__policy_)
793*fe6060f1SDimitry Andric     {
794*fe6060f1SDimitry Andric         if (__policy_->__destroy)
795*fe6060f1SDimitry Andric         {
796*fe6060f1SDimitry Andric             __f.__policy_ = __policy::__create_empty();
797*fe6060f1SDimitry Andric             __f.__invoker_ = __invoker();
798*fe6060f1SDimitry Andric         }
799*fe6060f1SDimitry Andric     }
800*fe6060f1SDimitry Andric 
801*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
802*fe6060f1SDimitry Andric     ~__policy_func()
803*fe6060f1SDimitry Andric     {
804*fe6060f1SDimitry Andric         if (__policy_->__destroy)
805*fe6060f1SDimitry Andric             __policy_->__destroy(__buf_.__large);
806*fe6060f1SDimitry Andric     }
807*fe6060f1SDimitry Andric 
808*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
809*fe6060f1SDimitry Andric     __policy_func& operator=(__policy_func&& __f)
810*fe6060f1SDimitry Andric     {
811*fe6060f1SDimitry Andric         *this = nullptr;
812*fe6060f1SDimitry Andric         __buf_ = __f.__buf_;
813*fe6060f1SDimitry Andric         __invoker_ = __f.__invoker_;
814*fe6060f1SDimitry Andric         __policy_ = __f.__policy_;
815*fe6060f1SDimitry Andric         __f.__policy_ = __policy::__create_empty();
816*fe6060f1SDimitry Andric         __f.__invoker_ = __invoker();
817*fe6060f1SDimitry Andric         return *this;
818*fe6060f1SDimitry Andric     }
819*fe6060f1SDimitry Andric 
820*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
821*fe6060f1SDimitry Andric     __policy_func& operator=(nullptr_t)
822*fe6060f1SDimitry Andric     {
823*fe6060f1SDimitry Andric         const __policy* __p = __policy_;
824*fe6060f1SDimitry Andric         __policy_ = __policy::__create_empty();
825*fe6060f1SDimitry Andric         __invoker_ = __invoker();
826*fe6060f1SDimitry Andric         if (__p->__destroy)
827*fe6060f1SDimitry Andric             __p->__destroy(__buf_.__large);
828*fe6060f1SDimitry Andric         return *this;
829*fe6060f1SDimitry Andric     }
830*fe6060f1SDimitry Andric 
831*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
832*fe6060f1SDimitry Andric     _Rp operator()(_ArgTypes&&... __args) const
833*fe6060f1SDimitry Andric     {
834*fe6060f1SDimitry Andric         return __invoker_.__call_(_VSTD::addressof(__buf_),
835*fe6060f1SDimitry Andric                                   _VSTD::forward<_ArgTypes>(__args)...);
836*fe6060f1SDimitry Andric     }
837*fe6060f1SDimitry Andric 
838*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
839*fe6060f1SDimitry Andric     void swap(__policy_func& __f)
840*fe6060f1SDimitry Andric     {
841*fe6060f1SDimitry Andric         _VSTD::swap(__invoker_, __f.__invoker_);
842*fe6060f1SDimitry Andric         _VSTD::swap(__policy_, __f.__policy_);
843*fe6060f1SDimitry Andric         _VSTD::swap(__buf_, __f.__buf_);
844*fe6060f1SDimitry Andric     }
845*fe6060f1SDimitry Andric 
846*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
847*fe6060f1SDimitry Andric     explicit operator bool() const _NOEXCEPT
848*fe6060f1SDimitry Andric     {
849*fe6060f1SDimitry Andric         return !__policy_->__is_null;
850*fe6060f1SDimitry Andric     }
851*fe6060f1SDimitry Andric 
852*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI
853*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
854*fe6060f1SDimitry Andric     const std::type_info& target_type() const _NOEXCEPT
855*fe6060f1SDimitry Andric     {
856*fe6060f1SDimitry Andric         return *__policy_->__type_info;
857*fe6060f1SDimitry Andric     }
858*fe6060f1SDimitry Andric 
859*fe6060f1SDimitry Andric     template <typename _Tp>
860*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT
861*fe6060f1SDimitry Andric     {
862*fe6060f1SDimitry Andric         if (__policy_->__is_null || typeid(_Tp) != *__policy_->__type_info)
863*fe6060f1SDimitry Andric             return nullptr;
864*fe6060f1SDimitry Andric         if (__policy_->__clone) // Out of line storage.
865*fe6060f1SDimitry Andric             return reinterpret_cast<const _Tp*>(__buf_.__large);
866*fe6060f1SDimitry Andric         else
867*fe6060f1SDimitry Andric             return reinterpret_cast<const _Tp*>(&__buf_.__small);
868*fe6060f1SDimitry Andric     }
869*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI
870*fe6060f1SDimitry Andric };
871*fe6060f1SDimitry Andric 
872*fe6060f1SDimitry Andric #if defined(_LIBCPP_HAS_BLOCKS_RUNTIME) && !defined(_LIBCPP_HAS_OBJC_ARC)
873*fe6060f1SDimitry Andric 
874*fe6060f1SDimitry Andric extern "C" void *_Block_copy(const void *);
875*fe6060f1SDimitry Andric extern "C" void _Block_release(const void *);
876*fe6060f1SDimitry Andric 
877*fe6060f1SDimitry Andric template<class _Rp1, class ..._ArgTypes1, class _Alloc, class _Rp, class ..._ArgTypes>
878*fe6060f1SDimitry Andric class __func<_Rp1(^)(_ArgTypes1...), _Alloc, _Rp(_ArgTypes...)>
879*fe6060f1SDimitry Andric     : public  __base<_Rp(_ArgTypes...)>
880*fe6060f1SDimitry Andric {
881*fe6060f1SDimitry Andric     typedef _Rp1(^__block_type)(_ArgTypes1...);
882*fe6060f1SDimitry Andric     __block_type __f_;
883*fe6060f1SDimitry Andric 
884*fe6060f1SDimitry Andric public:
885*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
886*fe6060f1SDimitry Andric     explicit __func(__block_type const& __f)
887*fe6060f1SDimitry Andric         : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr))
888*fe6060f1SDimitry Andric     { }
889*fe6060f1SDimitry Andric 
890*fe6060f1SDimitry Andric     // [TODO] add && to save on a retain
891*fe6060f1SDimitry Andric 
892*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
893*fe6060f1SDimitry Andric     explicit __func(__block_type __f, const _Alloc& /* unused */)
894*fe6060f1SDimitry Andric         : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr))
895*fe6060f1SDimitry Andric     { }
896*fe6060f1SDimitry Andric 
897*fe6060f1SDimitry Andric     virtual __base<_Rp(_ArgTypes...)>* __clone() const {
898*fe6060f1SDimitry Andric         _LIBCPP_ASSERT(false,
899*fe6060f1SDimitry Andric             "Block pointers are just pointers, so they should always fit into "
900*fe6060f1SDimitry Andric             "std::function's small buffer optimization. This function should "
901*fe6060f1SDimitry Andric             "never be invoked.");
902*fe6060f1SDimitry Andric         return nullptr;
903*fe6060f1SDimitry Andric     }
904*fe6060f1SDimitry Andric 
905*fe6060f1SDimitry Andric     virtual void __clone(__base<_Rp(_ArgTypes...)>* __p) const {
906*fe6060f1SDimitry Andric         ::new ((void*)__p) __func(__f_);
907*fe6060f1SDimitry Andric     }
908*fe6060f1SDimitry Andric 
909*fe6060f1SDimitry Andric     virtual void destroy() _NOEXCEPT {
910*fe6060f1SDimitry Andric         if (__f_)
911*fe6060f1SDimitry Andric             _Block_release(__f_);
912*fe6060f1SDimitry Andric         __f_ = 0;
913*fe6060f1SDimitry Andric     }
914*fe6060f1SDimitry Andric 
915*fe6060f1SDimitry Andric     virtual void destroy_deallocate() _NOEXCEPT {
916*fe6060f1SDimitry Andric         _LIBCPP_ASSERT(false,
917*fe6060f1SDimitry Andric             "Block pointers are just pointers, so they should always fit into "
918*fe6060f1SDimitry Andric             "std::function's small buffer optimization. This function should "
919*fe6060f1SDimitry Andric             "never be invoked.");
920*fe6060f1SDimitry Andric     }
921*fe6060f1SDimitry Andric 
922*fe6060f1SDimitry Andric     virtual _Rp operator()(_ArgTypes&& ... __arg) {
923*fe6060f1SDimitry Andric         return _VSTD::__invoke(__f_, _VSTD::forward<_ArgTypes>(__arg)...);
924*fe6060f1SDimitry Andric     }
925*fe6060f1SDimitry Andric 
926*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI
927*fe6060f1SDimitry Andric     virtual const void* target(type_info const& __ti) const _NOEXCEPT {
928*fe6060f1SDimitry Andric         if (__ti == typeid(__func::__block_type))
929*fe6060f1SDimitry Andric             return &__f_;
930*fe6060f1SDimitry Andric         return (const void*)nullptr;
931*fe6060f1SDimitry Andric     }
932*fe6060f1SDimitry Andric 
933*fe6060f1SDimitry Andric     virtual const std::type_info& target_type() const _NOEXCEPT {
934*fe6060f1SDimitry Andric         return typeid(__func::__block_type);
935*fe6060f1SDimitry Andric     }
936*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI
937*fe6060f1SDimitry Andric };
938*fe6060f1SDimitry Andric 
939*fe6060f1SDimitry Andric #endif // _LIBCPP_HAS_EXTENSION_BLOCKS && !_LIBCPP_HAS_OBJC_ARC
940*fe6060f1SDimitry Andric 
941*fe6060f1SDimitry Andric }  // __function
942*fe6060f1SDimitry Andric 
943*fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
944*fe6060f1SDimitry Andric class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)>
945*fe6060f1SDimitry Andric #if _LIBCPP_STD_VER <= 17 || !defined(_LIBCPP_ABI_NO_BINDER_BASES)
946*fe6060f1SDimitry Andric     : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>,
947*fe6060f1SDimitry Andric       public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)>
948*fe6060f1SDimitry Andric #endif
949*fe6060f1SDimitry Andric {
950*fe6060f1SDimitry Andric #ifndef _LIBCPP_ABI_OPTIMIZED_FUNCTION
951*fe6060f1SDimitry Andric     typedef __function::__value_func<_Rp(_ArgTypes...)> __func;
952*fe6060f1SDimitry Andric #else
953*fe6060f1SDimitry Andric     typedef __function::__policy_func<_Rp(_ArgTypes...)> __func;
954*fe6060f1SDimitry Andric #endif
955*fe6060f1SDimitry Andric 
956*fe6060f1SDimitry Andric     __func __f_;
957*fe6060f1SDimitry Andric 
958*fe6060f1SDimitry Andric     template <class _Fp, bool = _And<
959*fe6060f1SDimitry Andric         _IsNotSame<__uncvref_t<_Fp>, function>,
960*fe6060f1SDimitry Andric         __invokable<_Fp, _ArgTypes...>
961*fe6060f1SDimitry Andric     >::value>
962*fe6060f1SDimitry Andric     struct __callable;
963*fe6060f1SDimitry Andric     template <class _Fp>
964*fe6060f1SDimitry Andric         struct __callable<_Fp, true>
965*fe6060f1SDimitry Andric         {
966*fe6060f1SDimitry Andric             static const bool value = is_void<_Rp>::value ||
967*fe6060f1SDimitry Andric                 __is_core_convertible<typename __invoke_of<_Fp, _ArgTypes...>::type,
968*fe6060f1SDimitry Andric                                       _Rp>::value;
969*fe6060f1SDimitry Andric         };
970*fe6060f1SDimitry Andric     template <class _Fp>
971*fe6060f1SDimitry Andric         struct __callable<_Fp, false>
972*fe6060f1SDimitry Andric         {
973*fe6060f1SDimitry Andric             static const bool value = false;
974*fe6060f1SDimitry Andric         };
975*fe6060f1SDimitry Andric 
976*fe6060f1SDimitry Andric   template <class _Fp>
977*fe6060f1SDimitry Andric   using _EnableIfLValueCallable = typename enable_if<__callable<_Fp&>::value>::type;
978*fe6060f1SDimitry Andric public:
979*fe6060f1SDimitry Andric     typedef _Rp result_type;
980*fe6060f1SDimitry Andric 
981*fe6060f1SDimitry Andric     // construct/copy/destroy:
982*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
983*fe6060f1SDimitry Andric     function() _NOEXCEPT { }
984*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
985*fe6060f1SDimitry Andric     function(nullptr_t) _NOEXCEPT {}
986*fe6060f1SDimitry Andric     function(const function&);
987*fe6060f1SDimitry Andric     function(function&&) _NOEXCEPT;
988*fe6060f1SDimitry Andric     template<class _Fp, class = _EnableIfLValueCallable<_Fp>>
989*fe6060f1SDimitry Andric     function(_Fp);
990*fe6060f1SDimitry Andric 
991*fe6060f1SDimitry Andric #if _LIBCPP_STD_VER <= 14
992*fe6060f1SDimitry Andric     template<class _Alloc>
993*fe6060f1SDimitry Andric       _LIBCPP_INLINE_VISIBILITY
994*fe6060f1SDimitry Andric       function(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
995*fe6060f1SDimitry Andric     template<class _Alloc>
996*fe6060f1SDimitry Andric       _LIBCPP_INLINE_VISIBILITY
997*fe6060f1SDimitry Andric       function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {}
998*fe6060f1SDimitry Andric     template<class _Alloc>
999*fe6060f1SDimitry Andric       function(allocator_arg_t, const _Alloc&, const function&);
1000*fe6060f1SDimitry Andric     template<class _Alloc>
1001*fe6060f1SDimitry Andric       function(allocator_arg_t, const _Alloc&, function&&);
1002*fe6060f1SDimitry Andric     template<class _Fp, class _Alloc, class = _EnableIfLValueCallable<_Fp>>
1003*fe6060f1SDimitry Andric       function(allocator_arg_t, const _Alloc& __a, _Fp __f);
1004*fe6060f1SDimitry Andric #endif
1005*fe6060f1SDimitry Andric 
1006*fe6060f1SDimitry Andric     function& operator=(const function&);
1007*fe6060f1SDimitry Andric     function& operator=(function&&) _NOEXCEPT;
1008*fe6060f1SDimitry Andric     function& operator=(nullptr_t) _NOEXCEPT;
1009*fe6060f1SDimitry Andric     template<class _Fp, class = _EnableIfLValueCallable<typename decay<_Fp>::type>>
1010*fe6060f1SDimitry Andric     function& operator=(_Fp&&);
1011*fe6060f1SDimitry Andric 
1012*fe6060f1SDimitry Andric     ~function();
1013*fe6060f1SDimitry Andric 
1014*fe6060f1SDimitry Andric     // function modifiers:
1015*fe6060f1SDimitry Andric     void swap(function&) _NOEXCEPT;
1016*fe6060f1SDimitry Andric 
1017*fe6060f1SDimitry Andric #if _LIBCPP_STD_VER <= 14
1018*fe6060f1SDimitry Andric     template<class _Fp, class _Alloc>
1019*fe6060f1SDimitry Andric       _LIBCPP_INLINE_VISIBILITY
1020*fe6060f1SDimitry Andric       void assign(_Fp&& __f, const _Alloc& __a)
1021*fe6060f1SDimitry Andric         {function(allocator_arg, __a, _VSTD::forward<_Fp>(__f)).swap(*this);}
1022*fe6060f1SDimitry Andric #endif
1023*fe6060f1SDimitry Andric 
1024*fe6060f1SDimitry Andric     // function capacity:
1025*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
1026*fe6060f1SDimitry Andric     explicit operator bool() const _NOEXCEPT {
1027*fe6060f1SDimitry Andric       return static_cast<bool>(__f_);
1028*fe6060f1SDimitry Andric     }
1029*fe6060f1SDimitry Andric 
1030*fe6060f1SDimitry Andric     // deleted overloads close possible hole in the type system
1031*fe6060f1SDimitry Andric     template<class _R2, class... _ArgTypes2>
1032*fe6060f1SDimitry Andric       bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete;
1033*fe6060f1SDimitry Andric     template<class _R2, class... _ArgTypes2>
1034*fe6060f1SDimitry Andric       bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete;
1035*fe6060f1SDimitry Andric public:
1036*fe6060f1SDimitry Andric     // function invocation:
1037*fe6060f1SDimitry Andric     _Rp operator()(_ArgTypes...) const;
1038*fe6060f1SDimitry Andric 
1039*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI
1040*fe6060f1SDimitry Andric     // function target access:
1041*fe6060f1SDimitry Andric     const std::type_info& target_type() const _NOEXCEPT;
1042*fe6060f1SDimitry Andric     template <typename _Tp> _Tp* target() _NOEXCEPT;
1043*fe6060f1SDimitry Andric     template <typename _Tp> const _Tp* target() const _NOEXCEPT;
1044*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI
1045*fe6060f1SDimitry Andric };
1046*fe6060f1SDimitry Andric 
1047*fe6060f1SDimitry Andric #ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
1048*fe6060f1SDimitry Andric template<class _Rp, class ..._Ap>
1049*fe6060f1SDimitry Andric function(_Rp(*)(_Ap...)) -> function<_Rp(_Ap...)>;
1050*fe6060f1SDimitry Andric 
1051*fe6060f1SDimitry Andric template<class _Fp>
1052*fe6060f1SDimitry Andric struct __strip_signature;
1053*fe6060f1SDimitry Andric 
1054*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap>
1055*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...)> { using type = _Rp(_Ap...); };
1056*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap>
1057*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...) const> { using type = _Rp(_Ap...); };
1058*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap>
1059*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile> { using type = _Rp(_Ap...); };
1060*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap>
1061*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile> { using type = _Rp(_Ap...); };
1062*fe6060f1SDimitry Andric 
1063*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap>
1064*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...) &> { using type = _Rp(_Ap...); };
1065*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap>
1066*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...) const &> { using type = _Rp(_Ap...); };
1067*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap>
1068*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile &> { using type = _Rp(_Ap...); };
1069*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap>
1070*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile &> { using type = _Rp(_Ap...); };
1071*fe6060f1SDimitry Andric 
1072*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap>
1073*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...) noexcept> { using type = _Rp(_Ap...); };
1074*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap>
1075*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...) const noexcept> { using type = _Rp(_Ap...); };
1076*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap>
1077*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile noexcept> { using type = _Rp(_Ap...); };
1078*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap>
1079*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile noexcept> { using type = _Rp(_Ap...); };
1080*fe6060f1SDimitry Andric 
1081*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap>
1082*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...) & noexcept> { using type = _Rp(_Ap...); };
1083*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap>
1084*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...) const & noexcept> { using type = _Rp(_Ap...); };
1085*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap>
1086*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile & noexcept> { using type = _Rp(_Ap...); };
1087*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap>
1088*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile & noexcept> { using type = _Rp(_Ap...); };
1089*fe6060f1SDimitry Andric 
1090*fe6060f1SDimitry Andric template<class _Fp, class _Stripped = typename __strip_signature<decltype(&_Fp::operator())>::type>
1091*fe6060f1SDimitry Andric function(_Fp) -> function<_Stripped>;
1092*fe6060f1SDimitry Andric #endif // !_LIBCPP_HAS_NO_DEDUCTION_GUIDES
1093*fe6060f1SDimitry Andric 
1094*fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1095*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(const function& __f) : __f_(__f.__f_) {}
1096*fe6060f1SDimitry Andric 
1097*fe6060f1SDimitry Andric #if _LIBCPP_STD_VER <= 14
1098*fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1099*fe6060f1SDimitry Andric template <class _Alloc>
1100*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&,
1101*fe6060f1SDimitry Andric                                      const function& __f) : __f_(__f.__f_) {}
1102*fe6060f1SDimitry Andric #endif
1103*fe6060f1SDimitry Andric 
1104*fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1105*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT
1106*fe6060f1SDimitry Andric     : __f_(_VSTD::move(__f.__f_)) {}
1107*fe6060f1SDimitry Andric 
1108*fe6060f1SDimitry Andric #if _LIBCPP_STD_VER <= 14
1109*fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1110*fe6060f1SDimitry Andric template <class _Alloc>
1111*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&,
1112*fe6060f1SDimitry Andric                                       function&& __f)
1113*fe6060f1SDimitry Andric     : __f_(_VSTD::move(__f.__f_)) {}
1114*fe6060f1SDimitry Andric #endif
1115*fe6060f1SDimitry Andric 
1116*fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1117*fe6060f1SDimitry Andric template <class _Fp, class>
1118*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(_Fp __f) : __f_(_VSTD::move(__f)) {}
1119*fe6060f1SDimitry Andric 
1120*fe6060f1SDimitry Andric #if _LIBCPP_STD_VER <= 14
1121*fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1122*fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class>
1123*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a,
1124*fe6060f1SDimitry Andric                                       _Fp __f)
1125*fe6060f1SDimitry Andric     : __f_(_VSTD::move(__f), __a) {}
1126*fe6060f1SDimitry Andric #endif
1127*fe6060f1SDimitry Andric 
1128*fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1129*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>&
1130*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::operator=(const function& __f)
1131*fe6060f1SDimitry Andric {
1132*fe6060f1SDimitry Andric     function(__f).swap(*this);
1133*fe6060f1SDimitry Andric     return *this;
1134*fe6060f1SDimitry Andric }
1135*fe6060f1SDimitry Andric 
1136*fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1137*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>&
1138*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT
1139*fe6060f1SDimitry Andric {
1140*fe6060f1SDimitry Andric     __f_ = _VSTD::move(__f.__f_);
1141*fe6060f1SDimitry Andric     return *this;
1142*fe6060f1SDimitry Andric }
1143*fe6060f1SDimitry Andric 
1144*fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1145*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>&
1146*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT
1147*fe6060f1SDimitry Andric {
1148*fe6060f1SDimitry Andric     __f_ = nullptr;
1149*fe6060f1SDimitry Andric     return *this;
1150*fe6060f1SDimitry Andric }
1151*fe6060f1SDimitry Andric 
1152*fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1153*fe6060f1SDimitry Andric template <class _Fp, class>
1154*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>&
1155*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f)
1156*fe6060f1SDimitry Andric {
1157*fe6060f1SDimitry Andric     function(_VSTD::forward<_Fp>(__f)).swap(*this);
1158*fe6060f1SDimitry Andric     return *this;
1159*fe6060f1SDimitry Andric }
1160*fe6060f1SDimitry Andric 
1161*fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1162*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::~function() {}
1163*fe6060f1SDimitry Andric 
1164*fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1165*fe6060f1SDimitry Andric void
1166*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT
1167*fe6060f1SDimitry Andric {
1168*fe6060f1SDimitry Andric     __f_.swap(__f.__f_);
1169*fe6060f1SDimitry Andric }
1170*fe6060f1SDimitry Andric 
1171*fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1172*fe6060f1SDimitry Andric _Rp
1173*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
1174*fe6060f1SDimitry Andric {
1175*fe6060f1SDimitry Andric     return __f_(_VSTD::forward<_ArgTypes>(__arg)...);
1176*fe6060f1SDimitry Andric }
1177*fe6060f1SDimitry Andric 
1178*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI
1179*fe6060f1SDimitry Andric 
1180*fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1181*fe6060f1SDimitry Andric const std::type_info&
1182*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT
1183*fe6060f1SDimitry Andric {
1184*fe6060f1SDimitry Andric     return __f_.target_type();
1185*fe6060f1SDimitry Andric }
1186*fe6060f1SDimitry Andric 
1187*fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1188*fe6060f1SDimitry Andric template <typename _Tp>
1189*fe6060f1SDimitry Andric _Tp*
1190*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::target() _NOEXCEPT
1191*fe6060f1SDimitry Andric {
1192*fe6060f1SDimitry Andric     return (_Tp*)(__f_.template target<_Tp>());
1193*fe6060f1SDimitry Andric }
1194*fe6060f1SDimitry Andric 
1195*fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1196*fe6060f1SDimitry Andric template <typename _Tp>
1197*fe6060f1SDimitry Andric const _Tp*
1198*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT
1199*fe6060f1SDimitry Andric {
1200*fe6060f1SDimitry Andric     return __f_.template target<_Tp>();
1201*fe6060f1SDimitry Andric }
1202*fe6060f1SDimitry Andric 
1203*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI
1204*fe6060f1SDimitry Andric 
1205*fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1206*fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY
1207*fe6060f1SDimitry Andric bool
1208*fe6060f1SDimitry Andric operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return !__f;}
1209*fe6060f1SDimitry Andric 
1210*fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1211*fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY
1212*fe6060f1SDimitry Andric bool
1213*fe6060f1SDimitry Andric operator==(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return !__f;}
1214*fe6060f1SDimitry Andric 
1215*fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1216*fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY
1217*fe6060f1SDimitry Andric bool
1218*fe6060f1SDimitry Andric operator!=(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return (bool)__f;}
1219*fe6060f1SDimitry Andric 
1220*fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1221*fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY
1222*fe6060f1SDimitry Andric bool
1223*fe6060f1SDimitry Andric operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return (bool)__f;}
1224*fe6060f1SDimitry Andric 
1225*fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1226*fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY
1227*fe6060f1SDimitry Andric void
1228*fe6060f1SDimitry Andric swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCEPT
1229*fe6060f1SDimitry Andric {return __x.swap(__y);}
1230*fe6060f1SDimitry Andric 
1231*fe6060f1SDimitry Andric #else // _LIBCPP_CXX03_LANG
1232*fe6060f1SDimitry Andric 
1233*fe6060f1SDimitry Andric namespace __function {
1234*fe6060f1SDimitry Andric 
1235*fe6060f1SDimitry Andric template<class _Fp> class __base;
1236*fe6060f1SDimitry Andric 
1237*fe6060f1SDimitry Andric template<class _Rp>
1238*fe6060f1SDimitry Andric class __base<_Rp()>
1239*fe6060f1SDimitry Andric {
1240*fe6060f1SDimitry Andric     __base(const __base&);
1241*fe6060f1SDimitry Andric     __base& operator=(const __base&);
1242*fe6060f1SDimitry Andric public:
1243*fe6060f1SDimitry Andric     __base() {}
1244*fe6060f1SDimitry Andric     virtual ~__base() {}
1245*fe6060f1SDimitry Andric     virtual __base* __clone() const = 0;
1246*fe6060f1SDimitry Andric     virtual void __clone(__base*) const = 0;
1247*fe6060f1SDimitry Andric     virtual void destroy() = 0;
1248*fe6060f1SDimitry Andric     virtual void destroy_deallocate() = 0;
1249*fe6060f1SDimitry Andric     virtual _Rp operator()() = 0;
1250*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI
1251*fe6060f1SDimitry Andric     virtual const void* target(const type_info&) const = 0;
1252*fe6060f1SDimitry Andric     virtual const std::type_info& target_type() const = 0;
1253*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI
1254*fe6060f1SDimitry Andric };
1255*fe6060f1SDimitry Andric 
1256*fe6060f1SDimitry Andric template<class _Rp, class _A0>
1257*fe6060f1SDimitry Andric class __base<_Rp(_A0)>
1258*fe6060f1SDimitry Andric {
1259*fe6060f1SDimitry Andric     __base(const __base&);
1260*fe6060f1SDimitry Andric     __base& operator=(const __base&);
1261*fe6060f1SDimitry Andric public:
1262*fe6060f1SDimitry Andric     __base() {}
1263*fe6060f1SDimitry Andric     virtual ~__base() {}
1264*fe6060f1SDimitry Andric     virtual __base* __clone() const = 0;
1265*fe6060f1SDimitry Andric     virtual void __clone(__base*) const = 0;
1266*fe6060f1SDimitry Andric     virtual void destroy() = 0;
1267*fe6060f1SDimitry Andric     virtual void destroy_deallocate() = 0;
1268*fe6060f1SDimitry Andric     virtual _Rp operator()(_A0) = 0;
1269*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI
1270*fe6060f1SDimitry Andric     virtual const void* target(const type_info&) const = 0;
1271*fe6060f1SDimitry Andric     virtual const std::type_info& target_type() const = 0;
1272*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI
1273*fe6060f1SDimitry Andric };
1274*fe6060f1SDimitry Andric 
1275*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1>
1276*fe6060f1SDimitry Andric class __base<_Rp(_A0, _A1)>
1277*fe6060f1SDimitry Andric {
1278*fe6060f1SDimitry Andric     __base(const __base&);
1279*fe6060f1SDimitry Andric     __base& operator=(const __base&);
1280*fe6060f1SDimitry Andric public:
1281*fe6060f1SDimitry Andric     __base() {}
1282*fe6060f1SDimitry Andric     virtual ~__base() {}
1283*fe6060f1SDimitry Andric     virtual __base* __clone() const = 0;
1284*fe6060f1SDimitry Andric     virtual void __clone(__base*) const = 0;
1285*fe6060f1SDimitry Andric     virtual void destroy() = 0;
1286*fe6060f1SDimitry Andric     virtual void destroy_deallocate() = 0;
1287*fe6060f1SDimitry Andric     virtual _Rp operator()(_A0, _A1) = 0;
1288*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI
1289*fe6060f1SDimitry Andric     virtual const void* target(const type_info&) const = 0;
1290*fe6060f1SDimitry Andric     virtual const std::type_info& target_type() const = 0;
1291*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI
1292*fe6060f1SDimitry Andric };
1293*fe6060f1SDimitry Andric 
1294*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1, class _A2>
1295*fe6060f1SDimitry Andric class __base<_Rp(_A0, _A1, _A2)>
1296*fe6060f1SDimitry Andric {
1297*fe6060f1SDimitry Andric     __base(const __base&);
1298*fe6060f1SDimitry Andric     __base& operator=(const __base&);
1299*fe6060f1SDimitry Andric public:
1300*fe6060f1SDimitry Andric     __base() {}
1301*fe6060f1SDimitry Andric     virtual ~__base() {}
1302*fe6060f1SDimitry Andric     virtual __base* __clone() const = 0;
1303*fe6060f1SDimitry Andric     virtual void __clone(__base*) const = 0;
1304*fe6060f1SDimitry Andric     virtual void destroy() = 0;
1305*fe6060f1SDimitry Andric     virtual void destroy_deallocate() = 0;
1306*fe6060f1SDimitry Andric     virtual _Rp operator()(_A0, _A1, _A2) = 0;
1307*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI
1308*fe6060f1SDimitry Andric     virtual const void* target(const type_info&) const = 0;
1309*fe6060f1SDimitry Andric     virtual const std::type_info& target_type() const = 0;
1310*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI
1311*fe6060f1SDimitry Andric };
1312*fe6060f1SDimitry Andric 
1313*fe6060f1SDimitry Andric template<class _FD, class _Alloc, class _FB> class __func;
1314*fe6060f1SDimitry Andric 
1315*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp>
1316*fe6060f1SDimitry Andric class __func<_Fp, _Alloc, _Rp()>
1317*fe6060f1SDimitry Andric     : public  __base<_Rp()>
1318*fe6060f1SDimitry Andric {
1319*fe6060f1SDimitry Andric     __compressed_pair<_Fp, _Alloc> __f_;
1320*fe6060f1SDimitry Andric public:
1321*fe6060f1SDimitry Andric     explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {}
1322*fe6060f1SDimitry Andric     explicit __func(_Fp __f, _Alloc __a) : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
1323*fe6060f1SDimitry Andric     virtual __base<_Rp()>* __clone() const;
1324*fe6060f1SDimitry Andric     virtual void __clone(__base<_Rp()>*) const;
1325*fe6060f1SDimitry Andric     virtual void destroy();
1326*fe6060f1SDimitry Andric     virtual void destroy_deallocate();
1327*fe6060f1SDimitry Andric     virtual _Rp operator()();
1328*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI
1329*fe6060f1SDimitry Andric     virtual const void* target(const type_info&) const;
1330*fe6060f1SDimitry Andric     virtual const std::type_info& target_type() const;
1331*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI
1332*fe6060f1SDimitry Andric };
1333*fe6060f1SDimitry Andric 
1334*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp>
1335*fe6060f1SDimitry Andric __base<_Rp()>*
1336*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp()>::__clone() const
1337*fe6060f1SDimitry Andric {
1338*fe6060f1SDimitry Andric     typedef allocator_traits<_Alloc> __alloc_traits;
1339*fe6060f1SDimitry Andric     typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
1340*fe6060f1SDimitry Andric     _Ap __a(__f_.second());
1341*fe6060f1SDimitry Andric     typedef __allocator_destructor<_Ap> _Dp;
1342*fe6060f1SDimitry Andric     unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1343*fe6060f1SDimitry Andric     ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a));
1344*fe6060f1SDimitry Andric     return __hold.release();
1345*fe6060f1SDimitry Andric }
1346*fe6060f1SDimitry Andric 
1347*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp>
1348*fe6060f1SDimitry Andric void
1349*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp()>::__clone(__base<_Rp()>* __p) const
1350*fe6060f1SDimitry Andric {
1351*fe6060f1SDimitry Andric     ::new ((void*)__p) __func(__f_.first(), __f_.second());
1352*fe6060f1SDimitry Andric }
1353*fe6060f1SDimitry Andric 
1354*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp>
1355*fe6060f1SDimitry Andric void
1356*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp()>::destroy()
1357*fe6060f1SDimitry Andric {
1358*fe6060f1SDimitry Andric     __f_.~__compressed_pair<_Fp, _Alloc>();
1359*fe6060f1SDimitry Andric }
1360*fe6060f1SDimitry Andric 
1361*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp>
1362*fe6060f1SDimitry Andric void
1363*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp()>::destroy_deallocate()
1364*fe6060f1SDimitry Andric {
1365*fe6060f1SDimitry Andric     typedef allocator_traits<_Alloc> __alloc_traits;
1366*fe6060f1SDimitry Andric     typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
1367*fe6060f1SDimitry Andric     _Ap __a(__f_.second());
1368*fe6060f1SDimitry Andric     __f_.~__compressed_pair<_Fp, _Alloc>();
1369*fe6060f1SDimitry Andric     __a.deallocate(this, 1);
1370*fe6060f1SDimitry Andric }
1371*fe6060f1SDimitry Andric 
1372*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp>
1373*fe6060f1SDimitry Andric _Rp
1374*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp()>::operator()()
1375*fe6060f1SDimitry Andric {
1376*fe6060f1SDimitry Andric     typedef __invoke_void_return_wrapper<_Rp> _Invoker;
1377*fe6060f1SDimitry Andric     return _Invoker::__call(__f_.first());
1378*fe6060f1SDimitry Andric }
1379*fe6060f1SDimitry Andric 
1380*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI
1381*fe6060f1SDimitry Andric 
1382*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp>
1383*fe6060f1SDimitry Andric const void*
1384*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp()>::target(const type_info& __ti) const
1385*fe6060f1SDimitry Andric {
1386*fe6060f1SDimitry Andric     if (__ti == typeid(_Fp))
1387*fe6060f1SDimitry Andric         return &__f_.first();
1388*fe6060f1SDimitry Andric     return (const void*)0;
1389*fe6060f1SDimitry Andric }
1390*fe6060f1SDimitry Andric 
1391*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp>
1392*fe6060f1SDimitry Andric const std::type_info&
1393*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp()>::target_type() const
1394*fe6060f1SDimitry Andric {
1395*fe6060f1SDimitry Andric     return typeid(_Fp);
1396*fe6060f1SDimitry Andric }
1397*fe6060f1SDimitry Andric 
1398*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI
1399*fe6060f1SDimitry Andric 
1400*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0>
1401*fe6060f1SDimitry Andric class __func<_Fp, _Alloc, _Rp(_A0)>
1402*fe6060f1SDimitry Andric     : public  __base<_Rp(_A0)>
1403*fe6060f1SDimitry Andric {
1404*fe6060f1SDimitry Andric     __compressed_pair<_Fp, _Alloc> __f_;
1405*fe6060f1SDimitry Andric public:
1406*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {}
1407*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
1408*fe6060f1SDimitry Andric         : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
1409*fe6060f1SDimitry Andric     virtual __base<_Rp(_A0)>* __clone() const;
1410*fe6060f1SDimitry Andric     virtual void __clone(__base<_Rp(_A0)>*) const;
1411*fe6060f1SDimitry Andric     virtual void destroy();
1412*fe6060f1SDimitry Andric     virtual void destroy_deallocate();
1413*fe6060f1SDimitry Andric     virtual _Rp operator()(_A0);
1414*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI
1415*fe6060f1SDimitry Andric     virtual const void* target(const type_info&) const;
1416*fe6060f1SDimitry Andric     virtual const std::type_info& target_type() const;
1417*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI
1418*fe6060f1SDimitry Andric };
1419*fe6060f1SDimitry Andric 
1420*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0>
1421*fe6060f1SDimitry Andric __base<_Rp(_A0)>*
1422*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0)>::__clone() const
1423*fe6060f1SDimitry Andric {
1424*fe6060f1SDimitry Andric     typedef allocator_traits<_Alloc> __alloc_traits;
1425*fe6060f1SDimitry Andric     typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
1426*fe6060f1SDimitry Andric     _Ap __a(__f_.second());
1427*fe6060f1SDimitry Andric     typedef __allocator_destructor<_Ap> _Dp;
1428*fe6060f1SDimitry Andric     unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1429*fe6060f1SDimitry Andric     ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a));
1430*fe6060f1SDimitry Andric     return __hold.release();
1431*fe6060f1SDimitry Andric }
1432*fe6060f1SDimitry Andric 
1433*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0>
1434*fe6060f1SDimitry Andric void
1435*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0)>::__clone(__base<_Rp(_A0)>* __p) const
1436*fe6060f1SDimitry Andric {
1437*fe6060f1SDimitry Andric     ::new ((void*)__p) __func(__f_.first(), __f_.second());
1438*fe6060f1SDimitry Andric }
1439*fe6060f1SDimitry Andric 
1440*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0>
1441*fe6060f1SDimitry Andric void
1442*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0)>::destroy()
1443*fe6060f1SDimitry Andric {
1444*fe6060f1SDimitry Andric     __f_.~__compressed_pair<_Fp, _Alloc>();
1445*fe6060f1SDimitry Andric }
1446*fe6060f1SDimitry Andric 
1447*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0>
1448*fe6060f1SDimitry Andric void
1449*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0)>::destroy_deallocate()
1450*fe6060f1SDimitry Andric {
1451*fe6060f1SDimitry Andric     typedef allocator_traits<_Alloc> __alloc_traits;
1452*fe6060f1SDimitry Andric     typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
1453*fe6060f1SDimitry Andric     _Ap __a(__f_.second());
1454*fe6060f1SDimitry Andric     __f_.~__compressed_pair<_Fp, _Alloc>();
1455*fe6060f1SDimitry Andric     __a.deallocate(this, 1);
1456*fe6060f1SDimitry Andric }
1457*fe6060f1SDimitry Andric 
1458*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0>
1459*fe6060f1SDimitry Andric _Rp
1460*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0)>::operator()(_A0 __a0)
1461*fe6060f1SDimitry Andric {
1462*fe6060f1SDimitry Andric     typedef __invoke_void_return_wrapper<_Rp> _Invoker;
1463*fe6060f1SDimitry Andric     return _Invoker::__call(__f_.first(), __a0);
1464*fe6060f1SDimitry Andric }
1465*fe6060f1SDimitry Andric 
1466*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI
1467*fe6060f1SDimitry Andric 
1468*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0>
1469*fe6060f1SDimitry Andric const void*
1470*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0)>::target(const type_info& __ti) const
1471*fe6060f1SDimitry Andric {
1472*fe6060f1SDimitry Andric     if (__ti == typeid(_Fp))
1473*fe6060f1SDimitry Andric         return &__f_.first();
1474*fe6060f1SDimitry Andric     return (const void*)0;
1475*fe6060f1SDimitry Andric }
1476*fe6060f1SDimitry Andric 
1477*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0>
1478*fe6060f1SDimitry Andric const std::type_info&
1479*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0)>::target_type() const
1480*fe6060f1SDimitry Andric {
1481*fe6060f1SDimitry Andric     return typeid(_Fp);
1482*fe6060f1SDimitry Andric }
1483*fe6060f1SDimitry Andric 
1484*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI
1485*fe6060f1SDimitry Andric 
1486*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
1487*fe6060f1SDimitry Andric class __func<_Fp, _Alloc, _Rp(_A0, _A1)>
1488*fe6060f1SDimitry Andric     : public  __base<_Rp(_A0, _A1)>
1489*fe6060f1SDimitry Andric {
1490*fe6060f1SDimitry Andric     __compressed_pair<_Fp, _Alloc> __f_;
1491*fe6060f1SDimitry Andric public:
1492*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {}
1493*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
1494*fe6060f1SDimitry Andric         : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
1495*fe6060f1SDimitry Andric     virtual __base<_Rp(_A0, _A1)>* __clone() const;
1496*fe6060f1SDimitry Andric     virtual void __clone(__base<_Rp(_A0, _A1)>*) const;
1497*fe6060f1SDimitry Andric     virtual void destroy();
1498*fe6060f1SDimitry Andric     virtual void destroy_deallocate();
1499*fe6060f1SDimitry Andric     virtual _Rp operator()(_A0, _A1);
1500*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI
1501*fe6060f1SDimitry Andric     virtual const void* target(const type_info&) const;
1502*fe6060f1SDimitry Andric     virtual const std::type_info& target_type() const;
1503*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI
1504*fe6060f1SDimitry Andric };
1505*fe6060f1SDimitry Andric 
1506*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
1507*fe6060f1SDimitry Andric __base<_Rp(_A0, _A1)>*
1508*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone() const
1509*fe6060f1SDimitry Andric {
1510*fe6060f1SDimitry Andric     typedef allocator_traits<_Alloc> __alloc_traits;
1511*fe6060f1SDimitry Andric     typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
1512*fe6060f1SDimitry Andric     _Ap __a(__f_.second());
1513*fe6060f1SDimitry Andric     typedef __allocator_destructor<_Ap> _Dp;
1514*fe6060f1SDimitry Andric     unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1515*fe6060f1SDimitry Andric     ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a));
1516*fe6060f1SDimitry Andric     return __hold.release();
1517*fe6060f1SDimitry Andric }
1518*fe6060f1SDimitry Andric 
1519*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
1520*fe6060f1SDimitry Andric void
1521*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone(__base<_Rp(_A0, _A1)>* __p) const
1522*fe6060f1SDimitry Andric {
1523*fe6060f1SDimitry Andric     ::new ((void*)__p) __func(__f_.first(), __f_.second());
1524*fe6060f1SDimitry Andric }
1525*fe6060f1SDimitry Andric 
1526*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
1527*fe6060f1SDimitry Andric void
1528*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy()
1529*fe6060f1SDimitry Andric {
1530*fe6060f1SDimitry Andric     __f_.~__compressed_pair<_Fp, _Alloc>();
1531*fe6060f1SDimitry Andric }
1532*fe6060f1SDimitry Andric 
1533*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
1534*fe6060f1SDimitry Andric void
1535*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy_deallocate()
1536*fe6060f1SDimitry Andric {
1537*fe6060f1SDimitry Andric     typedef allocator_traits<_Alloc> __alloc_traits;
1538*fe6060f1SDimitry Andric     typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
1539*fe6060f1SDimitry Andric     _Ap __a(__f_.second());
1540*fe6060f1SDimitry Andric     __f_.~__compressed_pair<_Fp, _Alloc>();
1541*fe6060f1SDimitry Andric     __a.deallocate(this, 1);
1542*fe6060f1SDimitry Andric }
1543*fe6060f1SDimitry Andric 
1544*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
1545*fe6060f1SDimitry Andric _Rp
1546*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1)
1547*fe6060f1SDimitry Andric {
1548*fe6060f1SDimitry Andric     typedef __invoke_void_return_wrapper<_Rp> _Invoker;
1549*fe6060f1SDimitry Andric     return _Invoker::__call(__f_.first(), __a0, __a1);
1550*fe6060f1SDimitry Andric }
1551*fe6060f1SDimitry Andric 
1552*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI
1553*fe6060f1SDimitry Andric 
1554*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
1555*fe6060f1SDimitry Andric const void*
1556*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0, _A1)>::target(const type_info& __ti) const
1557*fe6060f1SDimitry Andric {
1558*fe6060f1SDimitry Andric     if (__ti == typeid(_Fp))
1559*fe6060f1SDimitry Andric         return &__f_.first();
1560*fe6060f1SDimitry Andric     return (const void*)0;
1561*fe6060f1SDimitry Andric }
1562*fe6060f1SDimitry Andric 
1563*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
1564*fe6060f1SDimitry Andric const std::type_info&
1565*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0, _A1)>::target_type() const
1566*fe6060f1SDimitry Andric {
1567*fe6060f1SDimitry Andric     return typeid(_Fp);
1568*fe6060f1SDimitry Andric }
1569*fe6060f1SDimitry Andric 
1570*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI
1571*fe6060f1SDimitry Andric 
1572*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
1573*fe6060f1SDimitry Andric class __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>
1574*fe6060f1SDimitry Andric     : public  __base<_Rp(_A0, _A1, _A2)>
1575*fe6060f1SDimitry Andric {
1576*fe6060f1SDimitry Andric     __compressed_pair<_Fp, _Alloc> __f_;
1577*fe6060f1SDimitry Andric public:
1578*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {}
1579*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
1580*fe6060f1SDimitry Andric         : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
1581*fe6060f1SDimitry Andric     virtual __base<_Rp(_A0, _A1, _A2)>* __clone() const;
1582*fe6060f1SDimitry Andric     virtual void __clone(__base<_Rp(_A0, _A1, _A2)>*) const;
1583*fe6060f1SDimitry Andric     virtual void destroy();
1584*fe6060f1SDimitry Andric     virtual void destroy_deallocate();
1585*fe6060f1SDimitry Andric     virtual _Rp operator()(_A0, _A1, _A2);
1586*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI
1587*fe6060f1SDimitry Andric     virtual const void* target(const type_info&) const;
1588*fe6060f1SDimitry Andric     virtual const std::type_info& target_type() const;
1589*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI
1590*fe6060f1SDimitry Andric };
1591*fe6060f1SDimitry Andric 
1592*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
1593*fe6060f1SDimitry Andric __base<_Rp(_A0, _A1, _A2)>*
1594*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone() const
1595*fe6060f1SDimitry Andric {
1596*fe6060f1SDimitry Andric     typedef allocator_traits<_Alloc> __alloc_traits;
1597*fe6060f1SDimitry Andric     typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
1598*fe6060f1SDimitry Andric     _Ap __a(__f_.second());
1599*fe6060f1SDimitry Andric     typedef __allocator_destructor<_Ap> _Dp;
1600*fe6060f1SDimitry Andric     unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1601*fe6060f1SDimitry Andric     ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a));
1602*fe6060f1SDimitry Andric     return __hold.release();
1603*fe6060f1SDimitry Andric }
1604*fe6060f1SDimitry Andric 
1605*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
1606*fe6060f1SDimitry Andric void
1607*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone(__base<_Rp(_A0, _A1, _A2)>* __p) const
1608*fe6060f1SDimitry Andric {
1609*fe6060f1SDimitry Andric     ::new ((void*)__p) __func(__f_.first(), __f_.second());
1610*fe6060f1SDimitry Andric }
1611*fe6060f1SDimitry Andric 
1612*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
1613*fe6060f1SDimitry Andric void
1614*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy()
1615*fe6060f1SDimitry Andric {
1616*fe6060f1SDimitry Andric     __f_.~__compressed_pair<_Fp, _Alloc>();
1617*fe6060f1SDimitry Andric }
1618*fe6060f1SDimitry Andric 
1619*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
1620*fe6060f1SDimitry Andric void
1621*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy_deallocate()
1622*fe6060f1SDimitry Andric {
1623*fe6060f1SDimitry Andric     typedef allocator_traits<_Alloc> __alloc_traits;
1624*fe6060f1SDimitry Andric     typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
1625*fe6060f1SDimitry Andric     _Ap __a(__f_.second());
1626*fe6060f1SDimitry Andric     __f_.~__compressed_pair<_Fp, _Alloc>();
1627*fe6060f1SDimitry Andric     __a.deallocate(this, 1);
1628*fe6060f1SDimitry Andric }
1629*fe6060f1SDimitry Andric 
1630*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
1631*fe6060f1SDimitry Andric _Rp
1632*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2)
1633*fe6060f1SDimitry Andric {
1634*fe6060f1SDimitry Andric     typedef __invoke_void_return_wrapper<_Rp> _Invoker;
1635*fe6060f1SDimitry Andric     return _Invoker::__call(__f_.first(), __a0, __a1, __a2);
1636*fe6060f1SDimitry Andric }
1637*fe6060f1SDimitry Andric 
1638*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI
1639*fe6060f1SDimitry Andric 
1640*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
1641*fe6060f1SDimitry Andric const void*
1642*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target(const type_info& __ti) const
1643*fe6060f1SDimitry Andric {
1644*fe6060f1SDimitry Andric     if (__ti == typeid(_Fp))
1645*fe6060f1SDimitry Andric         return &__f_.first();
1646*fe6060f1SDimitry Andric     return (const void*)0;
1647*fe6060f1SDimitry Andric }
1648*fe6060f1SDimitry Andric 
1649*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
1650*fe6060f1SDimitry Andric const std::type_info&
1651*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target_type() const
1652*fe6060f1SDimitry Andric {
1653*fe6060f1SDimitry Andric     return typeid(_Fp);
1654*fe6060f1SDimitry Andric }
1655*fe6060f1SDimitry Andric 
1656*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI
1657*fe6060f1SDimitry Andric 
1658*fe6060f1SDimitry Andric }  // __function
1659*fe6060f1SDimitry Andric 
1660*fe6060f1SDimitry Andric template<class _Rp>
1661*fe6060f1SDimitry Andric class _LIBCPP_TEMPLATE_VIS function<_Rp()>
1662*fe6060f1SDimitry Andric {
1663*fe6060f1SDimitry Andric     typedef __function::__base<_Rp()> __base;
1664*fe6060f1SDimitry Andric     aligned_storage<3*sizeof(void*)>::type __buf_;
1665*fe6060f1SDimitry Andric     __base* __f_;
1666*fe6060f1SDimitry Andric 
1667*fe6060f1SDimitry Andric public:
1668*fe6060f1SDimitry Andric     typedef _Rp result_type;
1669*fe6060f1SDimitry Andric 
1670*fe6060f1SDimitry Andric     // 20.7.16.2.1, construct/copy/destroy:
1671*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
1672*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
1673*fe6060f1SDimitry Andric     function(const function&);
1674*fe6060f1SDimitry Andric     template<class _Fp>
1675*fe6060f1SDimitry Andric       function(_Fp,
1676*fe6060f1SDimitry Andric                typename enable_if<!is_integral<_Fp>::value>::type* = 0);
1677*fe6060f1SDimitry Andric 
1678*fe6060f1SDimitry Andric     template<class _Alloc>
1679*fe6060f1SDimitry Andric       _LIBCPP_INLINE_VISIBILITY
1680*fe6060f1SDimitry Andric       function(allocator_arg_t, const _Alloc&) : __f_(0) {}
1681*fe6060f1SDimitry Andric     template<class _Alloc>
1682*fe6060f1SDimitry Andric       _LIBCPP_INLINE_VISIBILITY
1683*fe6060f1SDimitry Andric       function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
1684*fe6060f1SDimitry Andric     template<class _Alloc>
1685*fe6060f1SDimitry Andric       function(allocator_arg_t, const _Alloc&, const function&);
1686*fe6060f1SDimitry Andric     template<class _Fp, class _Alloc>
1687*fe6060f1SDimitry Andric       function(allocator_arg_t, const _Alloc& __a, _Fp __f,
1688*fe6060f1SDimitry Andric                typename enable_if<!is_integral<_Fp>::value>::type* = 0);
1689*fe6060f1SDimitry Andric 
1690*fe6060f1SDimitry Andric     function& operator=(const function&);
1691*fe6060f1SDimitry Andric     function& operator=(nullptr_t);
1692*fe6060f1SDimitry Andric     template<class _Fp>
1693*fe6060f1SDimitry Andric       typename enable_if
1694*fe6060f1SDimitry Andric       <
1695*fe6060f1SDimitry Andric         !is_integral<_Fp>::value,
1696*fe6060f1SDimitry Andric         function&
1697*fe6060f1SDimitry Andric       >::type
1698*fe6060f1SDimitry Andric       operator=(_Fp);
1699*fe6060f1SDimitry Andric 
1700*fe6060f1SDimitry Andric     ~function();
1701*fe6060f1SDimitry Andric 
1702*fe6060f1SDimitry Andric     // 20.7.16.2.2, function modifiers:
1703*fe6060f1SDimitry Andric     void swap(function&);
1704*fe6060f1SDimitry Andric     template<class _Fp, class _Alloc>
1705*fe6060f1SDimitry Andric       _LIBCPP_INLINE_VISIBILITY
1706*fe6060f1SDimitry Andric       void assign(_Fp __f, const _Alloc& __a)
1707*fe6060f1SDimitry Andric         {function(allocator_arg, __a, __f).swap(*this);}
1708*fe6060f1SDimitry Andric 
1709*fe6060f1SDimitry Andric     // 20.7.16.2.3, function capacity:
1710*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;}
1711*fe6060f1SDimitry Andric 
1712*fe6060f1SDimitry Andric private:
1713*fe6060f1SDimitry Andric     // deleted overloads close possible hole in the type system
1714*fe6060f1SDimitry Andric     template<class _R2>
1715*fe6060f1SDimitry Andric       bool operator==(const function<_R2()>&) const;// = delete;
1716*fe6060f1SDimitry Andric     template<class _R2>
1717*fe6060f1SDimitry Andric       bool operator!=(const function<_R2()>&) const;// = delete;
1718*fe6060f1SDimitry Andric public:
1719*fe6060f1SDimitry Andric     // 20.7.16.2.4, function invocation:
1720*fe6060f1SDimitry Andric     _Rp operator()() const;
1721*fe6060f1SDimitry Andric 
1722*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI
1723*fe6060f1SDimitry Andric     // 20.7.16.2.5, function target access:
1724*fe6060f1SDimitry Andric     const std::type_info& target_type() const;
1725*fe6060f1SDimitry Andric     template <typename _Tp> _Tp* target();
1726*fe6060f1SDimitry Andric     template <typename _Tp> const _Tp* target() const;
1727*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI
1728*fe6060f1SDimitry Andric };
1729*fe6060f1SDimitry Andric 
1730*fe6060f1SDimitry Andric template<class _Rp>
1731*fe6060f1SDimitry Andric function<_Rp()>::function(const function& __f)
1732*fe6060f1SDimitry Andric {
1733*fe6060f1SDimitry Andric     if (__f.__f_ == 0)
1734*fe6060f1SDimitry Andric         __f_ = 0;
1735*fe6060f1SDimitry Andric     else if (__f.__f_ == (const __base*)&__f.__buf_)
1736*fe6060f1SDimitry Andric     {
1737*fe6060f1SDimitry Andric         __f_ = (__base*)&__buf_;
1738*fe6060f1SDimitry Andric         __f.__f_->__clone(__f_);
1739*fe6060f1SDimitry Andric     }
1740*fe6060f1SDimitry Andric     else
1741*fe6060f1SDimitry Andric         __f_ = __f.__f_->__clone();
1742*fe6060f1SDimitry Andric }
1743*fe6060f1SDimitry Andric 
1744*fe6060f1SDimitry Andric template<class _Rp>
1745*fe6060f1SDimitry Andric template<class _Alloc>
1746*fe6060f1SDimitry Andric function<_Rp()>::function(allocator_arg_t, const _Alloc&, const function& __f)
1747*fe6060f1SDimitry Andric {
1748*fe6060f1SDimitry Andric     if (__f.__f_ == 0)
1749*fe6060f1SDimitry Andric         __f_ = 0;
1750*fe6060f1SDimitry Andric     else if (__f.__f_ == (const __base*)&__f.__buf_)
1751*fe6060f1SDimitry Andric     {
1752*fe6060f1SDimitry Andric         __f_ = (__base*)&__buf_;
1753*fe6060f1SDimitry Andric         __f.__f_->__clone(__f_);
1754*fe6060f1SDimitry Andric     }
1755*fe6060f1SDimitry Andric     else
1756*fe6060f1SDimitry Andric         __f_ = __f.__f_->__clone();
1757*fe6060f1SDimitry Andric }
1758*fe6060f1SDimitry Andric 
1759*fe6060f1SDimitry Andric template<class _Rp>
1760*fe6060f1SDimitry Andric template <class _Fp>
1761*fe6060f1SDimitry Andric function<_Rp()>::function(_Fp __f,
1762*fe6060f1SDimitry Andric                                      typename enable_if<!is_integral<_Fp>::value>::type*)
1763*fe6060f1SDimitry Andric     : __f_(0)
1764*fe6060f1SDimitry Andric {
1765*fe6060f1SDimitry Andric     if (__function::__not_null(__f))
1766*fe6060f1SDimitry Andric     {
1767*fe6060f1SDimitry Andric         typedef __function::__func<_Fp, allocator<_Fp>, _Rp()> _FF;
1768*fe6060f1SDimitry Andric         if (sizeof(_FF) <= sizeof(__buf_))
1769*fe6060f1SDimitry Andric         {
1770*fe6060f1SDimitry Andric             __f_ = (__base*)&__buf_;
1771*fe6060f1SDimitry Andric             ::new ((void*)__f_) _FF(__f);
1772*fe6060f1SDimitry Andric         }
1773*fe6060f1SDimitry Andric         else
1774*fe6060f1SDimitry Andric         {
1775*fe6060f1SDimitry Andric             typedef allocator<_FF> _Ap;
1776*fe6060f1SDimitry Andric             _Ap __a;
1777*fe6060f1SDimitry Andric             typedef __allocator_destructor<_Ap> _Dp;
1778*fe6060f1SDimitry Andric             unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1779*fe6060f1SDimitry Andric             ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a));
1780*fe6060f1SDimitry Andric             __f_ = __hold.release();
1781*fe6060f1SDimitry Andric         }
1782*fe6060f1SDimitry Andric     }
1783*fe6060f1SDimitry Andric }
1784*fe6060f1SDimitry Andric 
1785*fe6060f1SDimitry Andric template<class _Rp>
1786*fe6060f1SDimitry Andric template <class _Fp, class _Alloc>
1787*fe6060f1SDimitry Andric function<_Rp()>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
1788*fe6060f1SDimitry Andric                                      typename enable_if<!is_integral<_Fp>::value>::type*)
1789*fe6060f1SDimitry Andric     : __f_(0)
1790*fe6060f1SDimitry Andric {
1791*fe6060f1SDimitry Andric     typedef allocator_traits<_Alloc> __alloc_traits;
1792*fe6060f1SDimitry Andric     if (__function::__not_null(__f))
1793*fe6060f1SDimitry Andric     {
1794*fe6060f1SDimitry Andric         typedef __function::__func<_Fp, _Alloc, _Rp()> _FF;
1795*fe6060f1SDimitry Andric         if (sizeof(_FF) <= sizeof(__buf_))
1796*fe6060f1SDimitry Andric         {
1797*fe6060f1SDimitry Andric             __f_ = (__base*)&__buf_;
1798*fe6060f1SDimitry Andric             ::new ((void*)__f_) _FF(__f, __a0);
1799*fe6060f1SDimitry Andric         }
1800*fe6060f1SDimitry Andric         else
1801*fe6060f1SDimitry Andric         {
1802*fe6060f1SDimitry Andric             typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
1803*fe6060f1SDimitry Andric             _Ap __a(__a0);
1804*fe6060f1SDimitry Andric             typedef __allocator_destructor<_Ap> _Dp;
1805*fe6060f1SDimitry Andric             unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1806*fe6060f1SDimitry Andric             ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a));
1807*fe6060f1SDimitry Andric             __f_ = __hold.release();
1808*fe6060f1SDimitry Andric         }
1809*fe6060f1SDimitry Andric     }
1810*fe6060f1SDimitry Andric }
1811*fe6060f1SDimitry Andric 
1812*fe6060f1SDimitry Andric template<class _Rp>
1813*fe6060f1SDimitry Andric function<_Rp()>&
1814*fe6060f1SDimitry Andric function<_Rp()>::operator=(const function& __f)
1815*fe6060f1SDimitry Andric {
1816*fe6060f1SDimitry Andric     if (__f)
1817*fe6060f1SDimitry Andric         function(__f).swap(*this);
1818*fe6060f1SDimitry Andric     else
1819*fe6060f1SDimitry Andric         *this = nullptr;
1820*fe6060f1SDimitry Andric     return *this;
1821*fe6060f1SDimitry Andric }
1822*fe6060f1SDimitry Andric 
1823*fe6060f1SDimitry Andric template<class _Rp>
1824*fe6060f1SDimitry Andric function<_Rp()>&
1825*fe6060f1SDimitry Andric function<_Rp()>::operator=(nullptr_t)
1826*fe6060f1SDimitry Andric {
1827*fe6060f1SDimitry Andric     __base* __t = __f_;
1828*fe6060f1SDimitry Andric     __f_ = 0;
1829*fe6060f1SDimitry Andric     if (__t == (__base*)&__buf_)
1830*fe6060f1SDimitry Andric         __t->destroy();
1831*fe6060f1SDimitry Andric     else if (__t)
1832*fe6060f1SDimitry Andric         __t->destroy_deallocate();
1833*fe6060f1SDimitry Andric     return *this;
1834*fe6060f1SDimitry Andric }
1835*fe6060f1SDimitry Andric 
1836*fe6060f1SDimitry Andric template<class _Rp>
1837*fe6060f1SDimitry Andric template <class _Fp>
1838*fe6060f1SDimitry Andric typename enable_if
1839*fe6060f1SDimitry Andric <
1840*fe6060f1SDimitry Andric     !is_integral<_Fp>::value,
1841*fe6060f1SDimitry Andric     function<_Rp()>&
1842*fe6060f1SDimitry Andric >::type
1843*fe6060f1SDimitry Andric function<_Rp()>::operator=(_Fp __f)
1844*fe6060f1SDimitry Andric {
1845*fe6060f1SDimitry Andric     function(_VSTD::move(__f)).swap(*this);
1846*fe6060f1SDimitry Andric     return *this;
1847*fe6060f1SDimitry Andric }
1848*fe6060f1SDimitry Andric 
1849*fe6060f1SDimitry Andric template<class _Rp>
1850*fe6060f1SDimitry Andric function<_Rp()>::~function()
1851*fe6060f1SDimitry Andric {
1852*fe6060f1SDimitry Andric     if (__f_ == (__base*)&__buf_)
1853*fe6060f1SDimitry Andric         __f_->destroy();
1854*fe6060f1SDimitry Andric     else if (__f_)
1855*fe6060f1SDimitry Andric         __f_->destroy_deallocate();
1856*fe6060f1SDimitry Andric }
1857*fe6060f1SDimitry Andric 
1858*fe6060f1SDimitry Andric template<class _Rp>
1859*fe6060f1SDimitry Andric void
1860*fe6060f1SDimitry Andric function<_Rp()>::swap(function& __f)
1861*fe6060f1SDimitry Andric {
1862*fe6060f1SDimitry Andric     if (_VSTD::addressof(__f) == this)
1863*fe6060f1SDimitry Andric       return;
1864*fe6060f1SDimitry Andric     if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1865*fe6060f1SDimitry Andric     {
1866*fe6060f1SDimitry Andric         typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1867*fe6060f1SDimitry Andric         __base* __t = (__base*)&__tempbuf;
1868*fe6060f1SDimitry Andric         __f_->__clone(__t);
1869*fe6060f1SDimitry Andric         __f_->destroy();
1870*fe6060f1SDimitry Andric         __f_ = 0;
1871*fe6060f1SDimitry Andric         __f.__f_->__clone((__base*)&__buf_);
1872*fe6060f1SDimitry Andric         __f.__f_->destroy();
1873*fe6060f1SDimitry Andric         __f.__f_ = 0;
1874*fe6060f1SDimitry Andric         __f_ = (__base*)&__buf_;
1875*fe6060f1SDimitry Andric         __t->__clone((__base*)&__f.__buf_);
1876*fe6060f1SDimitry Andric         __t->destroy();
1877*fe6060f1SDimitry Andric         __f.__f_ = (__base*)&__f.__buf_;
1878*fe6060f1SDimitry Andric     }
1879*fe6060f1SDimitry Andric     else if (__f_ == (__base*)&__buf_)
1880*fe6060f1SDimitry Andric     {
1881*fe6060f1SDimitry Andric         __f_->__clone((__base*)&__f.__buf_);
1882*fe6060f1SDimitry Andric         __f_->destroy();
1883*fe6060f1SDimitry Andric         __f_ = __f.__f_;
1884*fe6060f1SDimitry Andric         __f.__f_ = (__base*)&__f.__buf_;
1885*fe6060f1SDimitry Andric     }
1886*fe6060f1SDimitry Andric     else if (__f.__f_ == (__base*)&__f.__buf_)
1887*fe6060f1SDimitry Andric     {
1888*fe6060f1SDimitry Andric         __f.__f_->__clone((__base*)&__buf_);
1889*fe6060f1SDimitry Andric         __f.__f_->destroy();
1890*fe6060f1SDimitry Andric         __f.__f_ = __f_;
1891*fe6060f1SDimitry Andric         __f_ = (__base*)&__buf_;
1892*fe6060f1SDimitry Andric     }
1893*fe6060f1SDimitry Andric     else
1894*fe6060f1SDimitry Andric         _VSTD::swap(__f_, __f.__f_);
1895*fe6060f1SDimitry Andric }
1896*fe6060f1SDimitry Andric 
1897*fe6060f1SDimitry Andric template<class _Rp>
1898*fe6060f1SDimitry Andric _Rp
1899*fe6060f1SDimitry Andric function<_Rp()>::operator()() const
1900*fe6060f1SDimitry Andric {
1901*fe6060f1SDimitry Andric     if (__f_ == 0)
1902*fe6060f1SDimitry Andric         __throw_bad_function_call();
1903*fe6060f1SDimitry Andric     return (*__f_)();
1904*fe6060f1SDimitry Andric }
1905*fe6060f1SDimitry Andric 
1906*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI
1907*fe6060f1SDimitry Andric 
1908*fe6060f1SDimitry Andric template<class _Rp>
1909*fe6060f1SDimitry Andric const std::type_info&
1910*fe6060f1SDimitry Andric function<_Rp()>::target_type() const
1911*fe6060f1SDimitry Andric {
1912*fe6060f1SDimitry Andric     if (__f_ == 0)
1913*fe6060f1SDimitry Andric         return typeid(void);
1914*fe6060f1SDimitry Andric     return __f_->target_type();
1915*fe6060f1SDimitry Andric }
1916*fe6060f1SDimitry Andric 
1917*fe6060f1SDimitry Andric template<class _Rp>
1918*fe6060f1SDimitry Andric template <typename _Tp>
1919*fe6060f1SDimitry Andric _Tp*
1920*fe6060f1SDimitry Andric function<_Rp()>::target()
1921*fe6060f1SDimitry Andric {
1922*fe6060f1SDimitry Andric     if (__f_ == 0)
1923*fe6060f1SDimitry Andric         return (_Tp*)0;
1924*fe6060f1SDimitry Andric     return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
1925*fe6060f1SDimitry Andric }
1926*fe6060f1SDimitry Andric 
1927*fe6060f1SDimitry Andric template<class _Rp>
1928*fe6060f1SDimitry Andric template <typename _Tp>
1929*fe6060f1SDimitry Andric const _Tp*
1930*fe6060f1SDimitry Andric function<_Rp()>::target() const
1931*fe6060f1SDimitry Andric {
1932*fe6060f1SDimitry Andric     if (__f_ == 0)
1933*fe6060f1SDimitry Andric         return (const _Tp*)0;
1934*fe6060f1SDimitry Andric     return (const _Tp*)__f_->target(typeid(_Tp));
1935*fe6060f1SDimitry Andric }
1936*fe6060f1SDimitry Andric 
1937*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI
1938*fe6060f1SDimitry Andric 
1939*fe6060f1SDimitry Andric template<class _Rp, class _A0>
1940*fe6060f1SDimitry Andric class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0)>
1941*fe6060f1SDimitry Andric     : public unary_function<_A0, _Rp>
1942*fe6060f1SDimitry Andric {
1943*fe6060f1SDimitry Andric     typedef __function::__base<_Rp(_A0)> __base;
1944*fe6060f1SDimitry Andric     aligned_storage<3*sizeof(void*)>::type __buf_;
1945*fe6060f1SDimitry Andric     __base* __f_;
1946*fe6060f1SDimitry Andric 
1947*fe6060f1SDimitry Andric public:
1948*fe6060f1SDimitry Andric     typedef _Rp result_type;
1949*fe6060f1SDimitry Andric 
1950*fe6060f1SDimitry Andric     // 20.7.16.2.1, construct/copy/destroy:
1951*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
1952*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
1953*fe6060f1SDimitry Andric     function(const function&);
1954*fe6060f1SDimitry Andric     template<class _Fp>
1955*fe6060f1SDimitry Andric       function(_Fp,
1956*fe6060f1SDimitry Andric                typename enable_if<!is_integral<_Fp>::value>::type* = 0);
1957*fe6060f1SDimitry Andric 
1958*fe6060f1SDimitry Andric     template<class _Alloc>
1959*fe6060f1SDimitry Andric       _LIBCPP_INLINE_VISIBILITY
1960*fe6060f1SDimitry Andric       function(allocator_arg_t, const _Alloc&) : __f_(0) {}
1961*fe6060f1SDimitry Andric     template<class _Alloc>
1962*fe6060f1SDimitry Andric       _LIBCPP_INLINE_VISIBILITY
1963*fe6060f1SDimitry Andric       function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
1964*fe6060f1SDimitry Andric     template<class _Alloc>
1965*fe6060f1SDimitry Andric       function(allocator_arg_t, const _Alloc&, const function&);
1966*fe6060f1SDimitry Andric     template<class _Fp, class _Alloc>
1967*fe6060f1SDimitry Andric       function(allocator_arg_t, const _Alloc& __a, _Fp __f,
1968*fe6060f1SDimitry Andric                typename enable_if<!is_integral<_Fp>::value>::type* = 0);
1969*fe6060f1SDimitry Andric 
1970*fe6060f1SDimitry Andric     function& operator=(const function&);
1971*fe6060f1SDimitry Andric     function& operator=(nullptr_t);
1972*fe6060f1SDimitry Andric     template<class _Fp>
1973*fe6060f1SDimitry Andric       typename enable_if
1974*fe6060f1SDimitry Andric       <
1975*fe6060f1SDimitry Andric         !is_integral<_Fp>::value,
1976*fe6060f1SDimitry Andric         function&
1977*fe6060f1SDimitry Andric       >::type
1978*fe6060f1SDimitry Andric       operator=(_Fp);
1979*fe6060f1SDimitry Andric 
1980*fe6060f1SDimitry Andric     ~function();
1981*fe6060f1SDimitry Andric 
1982*fe6060f1SDimitry Andric     // 20.7.16.2.2, function modifiers:
1983*fe6060f1SDimitry Andric     void swap(function&);
1984*fe6060f1SDimitry Andric     template<class _Fp, class _Alloc>
1985*fe6060f1SDimitry Andric       _LIBCPP_INLINE_VISIBILITY
1986*fe6060f1SDimitry Andric       void assign(_Fp __f, const _Alloc& __a)
1987*fe6060f1SDimitry Andric         {function(allocator_arg, __a, __f).swap(*this);}
1988*fe6060f1SDimitry Andric 
1989*fe6060f1SDimitry Andric     // 20.7.16.2.3, function capacity:
1990*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;}
1991*fe6060f1SDimitry Andric 
1992*fe6060f1SDimitry Andric private:
1993*fe6060f1SDimitry Andric     // deleted overloads close possible hole in the type system
1994*fe6060f1SDimitry Andric     template<class _R2, class _B0>
1995*fe6060f1SDimitry Andric       bool operator==(const function<_R2(_B0)>&) const;// = delete;
1996*fe6060f1SDimitry Andric     template<class _R2, class _B0>
1997*fe6060f1SDimitry Andric       bool operator!=(const function<_R2(_B0)>&) const;// = delete;
1998*fe6060f1SDimitry Andric public:
1999*fe6060f1SDimitry Andric     // 20.7.16.2.4, function invocation:
2000*fe6060f1SDimitry Andric     _Rp operator()(_A0) const;
2001*fe6060f1SDimitry Andric 
2002*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI
2003*fe6060f1SDimitry Andric     // 20.7.16.2.5, function target access:
2004*fe6060f1SDimitry Andric     const std::type_info& target_type() const;
2005*fe6060f1SDimitry Andric     template <typename _Tp> _Tp* target();
2006*fe6060f1SDimitry Andric     template <typename _Tp> const _Tp* target() const;
2007*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI
2008*fe6060f1SDimitry Andric };
2009*fe6060f1SDimitry Andric 
2010*fe6060f1SDimitry Andric template<class _Rp, class _A0>
2011*fe6060f1SDimitry Andric function<_Rp(_A0)>::function(const function& __f)
2012*fe6060f1SDimitry Andric {
2013*fe6060f1SDimitry Andric     if (__f.__f_ == 0)
2014*fe6060f1SDimitry Andric         __f_ = 0;
2015*fe6060f1SDimitry Andric     else if (__f.__f_ == (const __base*)&__f.__buf_)
2016*fe6060f1SDimitry Andric     {
2017*fe6060f1SDimitry Andric         __f_ = (__base*)&__buf_;
2018*fe6060f1SDimitry Andric         __f.__f_->__clone(__f_);
2019*fe6060f1SDimitry Andric     }
2020*fe6060f1SDimitry Andric     else
2021*fe6060f1SDimitry Andric         __f_ = __f.__f_->__clone();
2022*fe6060f1SDimitry Andric }
2023*fe6060f1SDimitry Andric 
2024*fe6060f1SDimitry Andric template<class _Rp, class _A0>
2025*fe6060f1SDimitry Andric template<class _Alloc>
2026*fe6060f1SDimitry Andric function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc&, const function& __f)
2027*fe6060f1SDimitry Andric {
2028*fe6060f1SDimitry Andric     if (__f.__f_ == 0)
2029*fe6060f1SDimitry Andric         __f_ = 0;
2030*fe6060f1SDimitry Andric     else if (__f.__f_ == (const __base*)&__f.__buf_)
2031*fe6060f1SDimitry Andric     {
2032*fe6060f1SDimitry Andric         __f_ = (__base*)&__buf_;
2033*fe6060f1SDimitry Andric         __f.__f_->__clone(__f_);
2034*fe6060f1SDimitry Andric     }
2035*fe6060f1SDimitry Andric     else
2036*fe6060f1SDimitry Andric         __f_ = __f.__f_->__clone();
2037*fe6060f1SDimitry Andric }
2038*fe6060f1SDimitry Andric 
2039*fe6060f1SDimitry Andric template<class _Rp, class _A0>
2040*fe6060f1SDimitry Andric template <class _Fp>
2041*fe6060f1SDimitry Andric function<_Rp(_A0)>::function(_Fp __f,
2042*fe6060f1SDimitry Andric                                      typename enable_if<!is_integral<_Fp>::value>::type*)
2043*fe6060f1SDimitry Andric     : __f_(0)
2044*fe6060f1SDimitry Andric {
2045*fe6060f1SDimitry Andric     if (__function::__not_null(__f))
2046*fe6060f1SDimitry Andric     {
2047*fe6060f1SDimitry Andric         typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0)> _FF;
2048*fe6060f1SDimitry Andric         if (sizeof(_FF) <= sizeof(__buf_))
2049*fe6060f1SDimitry Andric         {
2050*fe6060f1SDimitry Andric             __f_ = (__base*)&__buf_;
2051*fe6060f1SDimitry Andric             ::new ((void*)__f_) _FF(__f);
2052*fe6060f1SDimitry Andric         }
2053*fe6060f1SDimitry Andric         else
2054*fe6060f1SDimitry Andric         {
2055*fe6060f1SDimitry Andric             typedef allocator<_FF> _Ap;
2056*fe6060f1SDimitry Andric             _Ap __a;
2057*fe6060f1SDimitry Andric             typedef __allocator_destructor<_Ap> _Dp;
2058*fe6060f1SDimitry Andric             unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
2059*fe6060f1SDimitry Andric             ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a));
2060*fe6060f1SDimitry Andric             __f_ = __hold.release();
2061*fe6060f1SDimitry Andric         }
2062*fe6060f1SDimitry Andric     }
2063*fe6060f1SDimitry Andric }
2064*fe6060f1SDimitry Andric 
2065*fe6060f1SDimitry Andric template<class _Rp, class _A0>
2066*fe6060f1SDimitry Andric template <class _Fp, class _Alloc>
2067*fe6060f1SDimitry Andric function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
2068*fe6060f1SDimitry Andric                                      typename enable_if<!is_integral<_Fp>::value>::type*)
2069*fe6060f1SDimitry Andric     : __f_(0)
2070*fe6060f1SDimitry Andric {
2071*fe6060f1SDimitry Andric     typedef allocator_traits<_Alloc> __alloc_traits;
2072*fe6060f1SDimitry Andric     if (__function::__not_null(__f))
2073*fe6060f1SDimitry Andric     {
2074*fe6060f1SDimitry Andric         typedef __function::__func<_Fp, _Alloc, _Rp(_A0)> _FF;
2075*fe6060f1SDimitry Andric         if (sizeof(_FF) <= sizeof(__buf_))
2076*fe6060f1SDimitry Andric         {
2077*fe6060f1SDimitry Andric             __f_ = (__base*)&__buf_;
2078*fe6060f1SDimitry Andric             ::new ((void*)__f_) _FF(__f, __a0);
2079*fe6060f1SDimitry Andric         }
2080*fe6060f1SDimitry Andric         else
2081*fe6060f1SDimitry Andric         {
2082*fe6060f1SDimitry Andric             typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
2083*fe6060f1SDimitry Andric             _Ap __a(__a0);
2084*fe6060f1SDimitry Andric             typedef __allocator_destructor<_Ap> _Dp;
2085*fe6060f1SDimitry Andric             unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
2086*fe6060f1SDimitry Andric             ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a));
2087*fe6060f1SDimitry Andric             __f_ = __hold.release();
2088*fe6060f1SDimitry Andric         }
2089*fe6060f1SDimitry Andric     }
2090*fe6060f1SDimitry Andric }
2091*fe6060f1SDimitry Andric 
2092*fe6060f1SDimitry Andric template<class _Rp, class _A0>
2093*fe6060f1SDimitry Andric function<_Rp(_A0)>&
2094*fe6060f1SDimitry Andric function<_Rp(_A0)>::operator=(const function& __f)
2095*fe6060f1SDimitry Andric {
2096*fe6060f1SDimitry Andric     if (__f)
2097*fe6060f1SDimitry Andric         function(__f).swap(*this);
2098*fe6060f1SDimitry Andric     else
2099*fe6060f1SDimitry Andric         *this = nullptr;
2100*fe6060f1SDimitry Andric     return *this;
2101*fe6060f1SDimitry Andric }
2102*fe6060f1SDimitry Andric 
2103*fe6060f1SDimitry Andric template<class _Rp, class _A0>
2104*fe6060f1SDimitry Andric function<_Rp(_A0)>&
2105*fe6060f1SDimitry Andric function<_Rp(_A0)>::operator=(nullptr_t)
2106*fe6060f1SDimitry Andric {
2107*fe6060f1SDimitry Andric     __base* __t = __f_;
2108*fe6060f1SDimitry Andric     __f_ = 0;
2109*fe6060f1SDimitry Andric     if (__t == (__base*)&__buf_)
2110*fe6060f1SDimitry Andric         __t->destroy();
2111*fe6060f1SDimitry Andric     else if (__t)
2112*fe6060f1SDimitry Andric         __t->destroy_deallocate();
2113*fe6060f1SDimitry Andric     return *this;
2114*fe6060f1SDimitry Andric }
2115*fe6060f1SDimitry Andric 
2116*fe6060f1SDimitry Andric template<class _Rp, class _A0>
2117*fe6060f1SDimitry Andric template <class _Fp>
2118*fe6060f1SDimitry Andric typename enable_if
2119*fe6060f1SDimitry Andric <
2120*fe6060f1SDimitry Andric     !is_integral<_Fp>::value,
2121*fe6060f1SDimitry Andric     function<_Rp(_A0)>&
2122*fe6060f1SDimitry Andric >::type
2123*fe6060f1SDimitry Andric function<_Rp(_A0)>::operator=(_Fp __f)
2124*fe6060f1SDimitry Andric {
2125*fe6060f1SDimitry Andric     function(_VSTD::move(__f)).swap(*this);
2126*fe6060f1SDimitry Andric     return *this;
2127*fe6060f1SDimitry Andric }
2128*fe6060f1SDimitry Andric 
2129*fe6060f1SDimitry Andric template<class _Rp, class _A0>
2130*fe6060f1SDimitry Andric function<_Rp(_A0)>::~function()
2131*fe6060f1SDimitry Andric {
2132*fe6060f1SDimitry Andric     if (__f_ == (__base*)&__buf_)
2133*fe6060f1SDimitry Andric         __f_->destroy();
2134*fe6060f1SDimitry Andric     else if (__f_)
2135*fe6060f1SDimitry Andric         __f_->destroy_deallocate();
2136*fe6060f1SDimitry Andric }
2137*fe6060f1SDimitry Andric 
2138*fe6060f1SDimitry Andric template<class _Rp, class _A0>
2139*fe6060f1SDimitry Andric void
2140*fe6060f1SDimitry Andric function<_Rp(_A0)>::swap(function& __f)
2141*fe6060f1SDimitry Andric {
2142*fe6060f1SDimitry Andric     if (_VSTD::addressof(__f) == this)
2143*fe6060f1SDimitry Andric       return;
2144*fe6060f1SDimitry Andric     if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
2145*fe6060f1SDimitry Andric     {
2146*fe6060f1SDimitry Andric         typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
2147*fe6060f1SDimitry Andric         __base* __t = (__base*)&__tempbuf;
2148*fe6060f1SDimitry Andric         __f_->__clone(__t);
2149*fe6060f1SDimitry Andric         __f_->destroy();
2150*fe6060f1SDimitry Andric         __f_ = 0;
2151*fe6060f1SDimitry Andric         __f.__f_->__clone((__base*)&__buf_);
2152*fe6060f1SDimitry Andric         __f.__f_->destroy();
2153*fe6060f1SDimitry Andric         __f.__f_ = 0;
2154*fe6060f1SDimitry Andric         __f_ = (__base*)&__buf_;
2155*fe6060f1SDimitry Andric         __t->__clone((__base*)&__f.__buf_);
2156*fe6060f1SDimitry Andric         __t->destroy();
2157*fe6060f1SDimitry Andric         __f.__f_ = (__base*)&__f.__buf_;
2158*fe6060f1SDimitry Andric     }
2159*fe6060f1SDimitry Andric     else if (__f_ == (__base*)&__buf_)
2160*fe6060f1SDimitry Andric     {
2161*fe6060f1SDimitry Andric         __f_->__clone((__base*)&__f.__buf_);
2162*fe6060f1SDimitry Andric         __f_->destroy();
2163*fe6060f1SDimitry Andric         __f_ = __f.__f_;
2164*fe6060f1SDimitry Andric         __f.__f_ = (__base*)&__f.__buf_;
2165*fe6060f1SDimitry Andric     }
2166*fe6060f1SDimitry Andric     else if (__f.__f_ == (__base*)&__f.__buf_)
2167*fe6060f1SDimitry Andric     {
2168*fe6060f1SDimitry Andric         __f.__f_->__clone((__base*)&__buf_);
2169*fe6060f1SDimitry Andric         __f.__f_->destroy();
2170*fe6060f1SDimitry Andric         __f.__f_ = __f_;
2171*fe6060f1SDimitry Andric         __f_ = (__base*)&__buf_;
2172*fe6060f1SDimitry Andric     }
2173*fe6060f1SDimitry Andric     else
2174*fe6060f1SDimitry Andric         _VSTD::swap(__f_, __f.__f_);
2175*fe6060f1SDimitry Andric }
2176*fe6060f1SDimitry Andric 
2177*fe6060f1SDimitry Andric template<class _Rp, class _A0>
2178*fe6060f1SDimitry Andric _Rp
2179*fe6060f1SDimitry Andric function<_Rp(_A0)>::operator()(_A0 __a0) const
2180*fe6060f1SDimitry Andric {
2181*fe6060f1SDimitry Andric     if (__f_ == 0)
2182*fe6060f1SDimitry Andric         __throw_bad_function_call();
2183*fe6060f1SDimitry Andric     return (*__f_)(__a0);
2184*fe6060f1SDimitry Andric }
2185*fe6060f1SDimitry Andric 
2186*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI
2187*fe6060f1SDimitry Andric 
2188*fe6060f1SDimitry Andric template<class _Rp, class _A0>
2189*fe6060f1SDimitry Andric const std::type_info&
2190*fe6060f1SDimitry Andric function<_Rp(_A0)>::target_type() const
2191*fe6060f1SDimitry Andric {
2192*fe6060f1SDimitry Andric     if (__f_ == 0)
2193*fe6060f1SDimitry Andric         return typeid(void);
2194*fe6060f1SDimitry Andric     return __f_->target_type();
2195*fe6060f1SDimitry Andric }
2196*fe6060f1SDimitry Andric 
2197*fe6060f1SDimitry Andric template<class _Rp, class _A0>
2198*fe6060f1SDimitry Andric template <typename _Tp>
2199*fe6060f1SDimitry Andric _Tp*
2200*fe6060f1SDimitry Andric function<_Rp(_A0)>::target()
2201*fe6060f1SDimitry Andric {
2202*fe6060f1SDimitry Andric     if (__f_ == 0)
2203*fe6060f1SDimitry Andric         return (_Tp*)0;
2204*fe6060f1SDimitry Andric     return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
2205*fe6060f1SDimitry Andric }
2206*fe6060f1SDimitry Andric 
2207*fe6060f1SDimitry Andric template<class _Rp, class _A0>
2208*fe6060f1SDimitry Andric template <typename _Tp>
2209*fe6060f1SDimitry Andric const _Tp*
2210*fe6060f1SDimitry Andric function<_Rp(_A0)>::target() const
2211*fe6060f1SDimitry Andric {
2212*fe6060f1SDimitry Andric     if (__f_ == 0)
2213*fe6060f1SDimitry Andric         return (const _Tp*)0;
2214*fe6060f1SDimitry Andric     return (const _Tp*)__f_->target(typeid(_Tp));
2215*fe6060f1SDimitry Andric }
2216*fe6060f1SDimitry Andric 
2217*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI
2218*fe6060f1SDimitry Andric 
2219*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1>
2220*fe6060f1SDimitry Andric class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1)>
2221*fe6060f1SDimitry Andric     : public binary_function<_A0, _A1, _Rp>
2222*fe6060f1SDimitry Andric {
2223*fe6060f1SDimitry Andric     typedef __function::__base<_Rp(_A0, _A1)> __base;
2224*fe6060f1SDimitry Andric     aligned_storage<3*sizeof(void*)>::type __buf_;
2225*fe6060f1SDimitry Andric     __base* __f_;
2226*fe6060f1SDimitry Andric 
2227*fe6060f1SDimitry Andric public:
2228*fe6060f1SDimitry Andric     typedef _Rp result_type;
2229*fe6060f1SDimitry Andric 
2230*fe6060f1SDimitry Andric     // 20.7.16.2.1, construct/copy/destroy:
2231*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
2232*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
2233*fe6060f1SDimitry Andric     function(const function&);
2234*fe6060f1SDimitry Andric     template<class _Fp>
2235*fe6060f1SDimitry Andric       function(_Fp,
2236*fe6060f1SDimitry Andric                typename enable_if<!is_integral<_Fp>::value>::type* = 0);
2237*fe6060f1SDimitry Andric 
2238*fe6060f1SDimitry Andric     template<class _Alloc>
2239*fe6060f1SDimitry Andric       _LIBCPP_INLINE_VISIBILITY
2240*fe6060f1SDimitry Andric       function(allocator_arg_t, const _Alloc&) : __f_(0) {}
2241*fe6060f1SDimitry Andric     template<class _Alloc>
2242*fe6060f1SDimitry Andric       _LIBCPP_INLINE_VISIBILITY
2243*fe6060f1SDimitry Andric       function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
2244*fe6060f1SDimitry Andric     template<class _Alloc>
2245*fe6060f1SDimitry Andric       function(allocator_arg_t, const _Alloc&, const function&);
2246*fe6060f1SDimitry Andric     template<class _Fp, class _Alloc>
2247*fe6060f1SDimitry Andric       function(allocator_arg_t, const _Alloc& __a, _Fp __f,
2248*fe6060f1SDimitry Andric                typename enable_if<!is_integral<_Fp>::value>::type* = 0);
2249*fe6060f1SDimitry Andric 
2250*fe6060f1SDimitry Andric     function& operator=(const function&);
2251*fe6060f1SDimitry Andric     function& operator=(nullptr_t);
2252*fe6060f1SDimitry Andric     template<class _Fp>
2253*fe6060f1SDimitry Andric       typename enable_if
2254*fe6060f1SDimitry Andric       <
2255*fe6060f1SDimitry Andric         !is_integral<_Fp>::value,
2256*fe6060f1SDimitry Andric         function&
2257*fe6060f1SDimitry Andric       >::type
2258*fe6060f1SDimitry Andric       operator=(_Fp);
2259*fe6060f1SDimitry Andric 
2260*fe6060f1SDimitry Andric     ~function();
2261*fe6060f1SDimitry Andric 
2262*fe6060f1SDimitry Andric     // 20.7.16.2.2, function modifiers:
2263*fe6060f1SDimitry Andric     void swap(function&);
2264*fe6060f1SDimitry Andric     template<class _Fp, class _Alloc>
2265*fe6060f1SDimitry Andric       _LIBCPP_INLINE_VISIBILITY
2266*fe6060f1SDimitry Andric       void assign(_Fp __f, const _Alloc& __a)
2267*fe6060f1SDimitry Andric         {function(allocator_arg, __a, __f).swap(*this);}
2268*fe6060f1SDimitry Andric 
2269*fe6060f1SDimitry Andric     // 20.7.16.2.3, function capacity:
2270*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;}
2271*fe6060f1SDimitry Andric 
2272*fe6060f1SDimitry Andric private:
2273*fe6060f1SDimitry Andric     // deleted overloads close possible hole in the type system
2274*fe6060f1SDimitry Andric     template<class _R2, class _B0, class _B1>
2275*fe6060f1SDimitry Andric       bool operator==(const function<_R2(_B0, _B1)>&) const;// = delete;
2276*fe6060f1SDimitry Andric     template<class _R2, class _B0, class _B1>
2277*fe6060f1SDimitry Andric       bool operator!=(const function<_R2(_B0, _B1)>&) const;// = delete;
2278*fe6060f1SDimitry Andric public:
2279*fe6060f1SDimitry Andric     // 20.7.16.2.4, function invocation:
2280*fe6060f1SDimitry Andric     _Rp operator()(_A0, _A1) const;
2281*fe6060f1SDimitry Andric 
2282*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI
2283*fe6060f1SDimitry Andric     // 20.7.16.2.5, function target access:
2284*fe6060f1SDimitry Andric     const std::type_info& target_type() const;
2285*fe6060f1SDimitry Andric     template <typename _Tp> _Tp* target();
2286*fe6060f1SDimitry Andric     template <typename _Tp> const _Tp* target() const;
2287*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI
2288*fe6060f1SDimitry Andric };
2289*fe6060f1SDimitry Andric 
2290*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1>
2291*fe6060f1SDimitry Andric function<_Rp(_A0, _A1)>::function(const function& __f)
2292*fe6060f1SDimitry Andric {
2293*fe6060f1SDimitry Andric     if (__f.__f_ == 0)
2294*fe6060f1SDimitry Andric         __f_ = 0;
2295*fe6060f1SDimitry Andric     else if (__f.__f_ == (const __base*)&__f.__buf_)
2296*fe6060f1SDimitry Andric     {
2297*fe6060f1SDimitry Andric         __f_ = (__base*)&__buf_;
2298*fe6060f1SDimitry Andric         __f.__f_->__clone(__f_);
2299*fe6060f1SDimitry Andric     }
2300*fe6060f1SDimitry Andric     else
2301*fe6060f1SDimitry Andric         __f_ = __f.__f_->__clone();
2302*fe6060f1SDimitry Andric }
2303*fe6060f1SDimitry Andric 
2304*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1>
2305*fe6060f1SDimitry Andric template<class _Alloc>
2306*fe6060f1SDimitry Andric function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc&, const function& __f)
2307*fe6060f1SDimitry Andric {
2308*fe6060f1SDimitry Andric     if (__f.__f_ == 0)
2309*fe6060f1SDimitry Andric         __f_ = 0;
2310*fe6060f1SDimitry Andric     else if (__f.__f_ == (const __base*)&__f.__buf_)
2311*fe6060f1SDimitry Andric     {
2312*fe6060f1SDimitry Andric         __f_ = (__base*)&__buf_;
2313*fe6060f1SDimitry Andric         __f.__f_->__clone(__f_);
2314*fe6060f1SDimitry Andric     }
2315*fe6060f1SDimitry Andric     else
2316*fe6060f1SDimitry Andric         __f_ = __f.__f_->__clone();
2317*fe6060f1SDimitry Andric }
2318*fe6060f1SDimitry Andric 
2319*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1>
2320*fe6060f1SDimitry Andric template <class _Fp>
2321*fe6060f1SDimitry Andric function<_Rp(_A0, _A1)>::function(_Fp __f,
2322*fe6060f1SDimitry Andric                                  typename enable_if<!is_integral<_Fp>::value>::type*)
2323*fe6060f1SDimitry Andric     : __f_(0)
2324*fe6060f1SDimitry Andric {
2325*fe6060f1SDimitry Andric     if (__function::__not_null(__f))
2326*fe6060f1SDimitry Andric     {
2327*fe6060f1SDimitry Andric         typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1)> _FF;
2328*fe6060f1SDimitry Andric         if (sizeof(_FF) <= sizeof(__buf_))
2329*fe6060f1SDimitry Andric         {
2330*fe6060f1SDimitry Andric             __f_ = (__base*)&__buf_;
2331*fe6060f1SDimitry Andric             ::new ((void*)__f_) _FF(__f);
2332*fe6060f1SDimitry Andric         }
2333*fe6060f1SDimitry Andric         else
2334*fe6060f1SDimitry Andric         {
2335*fe6060f1SDimitry Andric             typedef allocator<_FF> _Ap;
2336*fe6060f1SDimitry Andric             _Ap __a;
2337*fe6060f1SDimitry Andric             typedef __allocator_destructor<_Ap> _Dp;
2338*fe6060f1SDimitry Andric             unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
2339*fe6060f1SDimitry Andric             ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a));
2340*fe6060f1SDimitry Andric             __f_ = __hold.release();
2341*fe6060f1SDimitry Andric         }
2342*fe6060f1SDimitry Andric     }
2343*fe6060f1SDimitry Andric }
2344*fe6060f1SDimitry Andric 
2345*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1>
2346*fe6060f1SDimitry Andric template <class _Fp, class _Alloc>
2347*fe6060f1SDimitry Andric function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
2348*fe6060f1SDimitry Andric                                  typename enable_if<!is_integral<_Fp>::value>::type*)
2349*fe6060f1SDimitry Andric     : __f_(0)
2350*fe6060f1SDimitry Andric {
2351*fe6060f1SDimitry Andric     typedef allocator_traits<_Alloc> __alloc_traits;
2352*fe6060f1SDimitry Andric     if (__function::__not_null(__f))
2353*fe6060f1SDimitry Andric     {
2354*fe6060f1SDimitry Andric         typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1)> _FF;
2355*fe6060f1SDimitry Andric         if (sizeof(_FF) <= sizeof(__buf_))
2356*fe6060f1SDimitry Andric         {
2357*fe6060f1SDimitry Andric             __f_ = (__base*)&__buf_;
2358*fe6060f1SDimitry Andric             ::new ((void*)__f_) _FF(__f, __a0);
2359*fe6060f1SDimitry Andric         }
2360*fe6060f1SDimitry Andric         else
2361*fe6060f1SDimitry Andric         {
2362*fe6060f1SDimitry Andric             typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
2363*fe6060f1SDimitry Andric             _Ap __a(__a0);
2364*fe6060f1SDimitry Andric             typedef __allocator_destructor<_Ap> _Dp;
2365*fe6060f1SDimitry Andric             unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
2366*fe6060f1SDimitry Andric             ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a));
2367*fe6060f1SDimitry Andric             __f_ = __hold.release();
2368*fe6060f1SDimitry Andric         }
2369*fe6060f1SDimitry Andric     }
2370*fe6060f1SDimitry Andric }
2371*fe6060f1SDimitry Andric 
2372*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1>
2373*fe6060f1SDimitry Andric function<_Rp(_A0, _A1)>&
2374*fe6060f1SDimitry Andric function<_Rp(_A0, _A1)>::operator=(const function& __f)
2375*fe6060f1SDimitry Andric {
2376*fe6060f1SDimitry Andric     if (__f)
2377*fe6060f1SDimitry Andric         function(__f).swap(*this);
2378*fe6060f1SDimitry Andric     else
2379*fe6060f1SDimitry Andric         *this = nullptr;
2380*fe6060f1SDimitry Andric     return *this;
2381*fe6060f1SDimitry Andric }
2382*fe6060f1SDimitry Andric 
2383*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1>
2384*fe6060f1SDimitry Andric function<_Rp(_A0, _A1)>&
2385*fe6060f1SDimitry Andric function<_Rp(_A0, _A1)>::operator=(nullptr_t)
2386*fe6060f1SDimitry Andric {
2387*fe6060f1SDimitry Andric     __base* __t = __f_;
2388*fe6060f1SDimitry Andric     __f_ = 0;
2389*fe6060f1SDimitry Andric     if (__t == (__base*)&__buf_)
2390*fe6060f1SDimitry Andric         __t->destroy();
2391*fe6060f1SDimitry Andric     else if (__t)
2392*fe6060f1SDimitry Andric         __t->destroy_deallocate();
2393*fe6060f1SDimitry Andric     return *this;
2394*fe6060f1SDimitry Andric }
2395*fe6060f1SDimitry Andric 
2396*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1>
2397*fe6060f1SDimitry Andric template <class _Fp>
2398*fe6060f1SDimitry Andric typename enable_if
2399*fe6060f1SDimitry Andric <
2400*fe6060f1SDimitry Andric     !is_integral<_Fp>::value,
2401*fe6060f1SDimitry Andric     function<_Rp(_A0, _A1)>&
2402*fe6060f1SDimitry Andric >::type
2403*fe6060f1SDimitry Andric function<_Rp(_A0, _A1)>::operator=(_Fp __f)
2404*fe6060f1SDimitry Andric {
2405*fe6060f1SDimitry Andric     function(_VSTD::move(__f)).swap(*this);
2406*fe6060f1SDimitry Andric     return *this;
2407*fe6060f1SDimitry Andric }
2408*fe6060f1SDimitry Andric 
2409*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1>
2410*fe6060f1SDimitry Andric function<_Rp(_A0, _A1)>::~function()
2411*fe6060f1SDimitry Andric {
2412*fe6060f1SDimitry Andric     if (__f_ == (__base*)&__buf_)
2413*fe6060f1SDimitry Andric         __f_->destroy();
2414*fe6060f1SDimitry Andric     else if (__f_)
2415*fe6060f1SDimitry Andric         __f_->destroy_deallocate();
2416*fe6060f1SDimitry Andric }
2417*fe6060f1SDimitry Andric 
2418*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1>
2419*fe6060f1SDimitry Andric void
2420*fe6060f1SDimitry Andric function<_Rp(_A0, _A1)>::swap(function& __f)
2421*fe6060f1SDimitry Andric {
2422*fe6060f1SDimitry Andric     if (_VSTD::addressof(__f) == this)
2423*fe6060f1SDimitry Andric       return;
2424*fe6060f1SDimitry Andric     if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
2425*fe6060f1SDimitry Andric     {
2426*fe6060f1SDimitry Andric         typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
2427*fe6060f1SDimitry Andric         __base* __t = (__base*)&__tempbuf;
2428*fe6060f1SDimitry Andric         __f_->__clone(__t);
2429*fe6060f1SDimitry Andric         __f_->destroy();
2430*fe6060f1SDimitry Andric         __f_ = 0;
2431*fe6060f1SDimitry Andric         __f.__f_->__clone((__base*)&__buf_);
2432*fe6060f1SDimitry Andric         __f.__f_->destroy();
2433*fe6060f1SDimitry Andric         __f.__f_ = 0;
2434*fe6060f1SDimitry Andric         __f_ = (__base*)&__buf_;
2435*fe6060f1SDimitry Andric         __t->__clone((__base*)&__f.__buf_);
2436*fe6060f1SDimitry Andric         __t->destroy();
2437*fe6060f1SDimitry Andric         __f.__f_ = (__base*)&__f.__buf_;
2438*fe6060f1SDimitry Andric     }
2439*fe6060f1SDimitry Andric     else if (__f_ == (__base*)&__buf_)
2440*fe6060f1SDimitry Andric     {
2441*fe6060f1SDimitry Andric         __f_->__clone((__base*)&__f.__buf_);
2442*fe6060f1SDimitry Andric         __f_->destroy();
2443*fe6060f1SDimitry Andric         __f_ = __f.__f_;
2444*fe6060f1SDimitry Andric         __f.__f_ = (__base*)&__f.__buf_;
2445*fe6060f1SDimitry Andric     }
2446*fe6060f1SDimitry Andric     else if (__f.__f_ == (__base*)&__f.__buf_)
2447*fe6060f1SDimitry Andric     {
2448*fe6060f1SDimitry Andric         __f.__f_->__clone((__base*)&__buf_);
2449*fe6060f1SDimitry Andric         __f.__f_->destroy();
2450*fe6060f1SDimitry Andric         __f.__f_ = __f_;
2451*fe6060f1SDimitry Andric         __f_ = (__base*)&__buf_;
2452*fe6060f1SDimitry Andric     }
2453*fe6060f1SDimitry Andric     else
2454*fe6060f1SDimitry Andric         _VSTD::swap(__f_, __f.__f_);
2455*fe6060f1SDimitry Andric }
2456*fe6060f1SDimitry Andric 
2457*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1>
2458*fe6060f1SDimitry Andric _Rp
2459*fe6060f1SDimitry Andric function<_Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) const
2460*fe6060f1SDimitry Andric {
2461*fe6060f1SDimitry Andric     if (__f_ == 0)
2462*fe6060f1SDimitry Andric         __throw_bad_function_call();
2463*fe6060f1SDimitry Andric     return (*__f_)(__a0, __a1);
2464*fe6060f1SDimitry Andric }
2465*fe6060f1SDimitry Andric 
2466*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI
2467*fe6060f1SDimitry Andric 
2468*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1>
2469*fe6060f1SDimitry Andric const std::type_info&
2470*fe6060f1SDimitry Andric function<_Rp(_A0, _A1)>::target_type() const
2471*fe6060f1SDimitry Andric {
2472*fe6060f1SDimitry Andric     if (__f_ == 0)
2473*fe6060f1SDimitry Andric         return typeid(void);
2474*fe6060f1SDimitry Andric     return __f_->target_type();
2475*fe6060f1SDimitry Andric }
2476*fe6060f1SDimitry Andric 
2477*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1>
2478*fe6060f1SDimitry Andric template <typename _Tp>
2479*fe6060f1SDimitry Andric _Tp*
2480*fe6060f1SDimitry Andric function<_Rp(_A0, _A1)>::target()
2481*fe6060f1SDimitry Andric {
2482*fe6060f1SDimitry Andric     if (__f_ == 0)
2483*fe6060f1SDimitry Andric         return (_Tp*)0;
2484*fe6060f1SDimitry Andric     return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
2485*fe6060f1SDimitry Andric }
2486*fe6060f1SDimitry Andric 
2487*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1>
2488*fe6060f1SDimitry Andric template <typename _Tp>
2489*fe6060f1SDimitry Andric const _Tp*
2490*fe6060f1SDimitry Andric function<_Rp(_A0, _A1)>::target() const
2491*fe6060f1SDimitry Andric {
2492*fe6060f1SDimitry Andric     if (__f_ == 0)
2493*fe6060f1SDimitry Andric         return (const _Tp*)0;
2494*fe6060f1SDimitry Andric     return (const _Tp*)__f_->target(typeid(_Tp));
2495*fe6060f1SDimitry Andric }
2496*fe6060f1SDimitry Andric 
2497*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI
2498*fe6060f1SDimitry Andric 
2499*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1, class _A2>
2500*fe6060f1SDimitry Andric class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1, _A2)>
2501*fe6060f1SDimitry Andric {
2502*fe6060f1SDimitry Andric     typedef __function::__base<_Rp(_A0, _A1, _A2)> __base;
2503*fe6060f1SDimitry Andric     aligned_storage<3*sizeof(void*)>::type __buf_;
2504*fe6060f1SDimitry Andric     __base* __f_;
2505*fe6060f1SDimitry Andric 
2506*fe6060f1SDimitry Andric public:
2507*fe6060f1SDimitry Andric     typedef _Rp result_type;
2508*fe6060f1SDimitry Andric 
2509*fe6060f1SDimitry Andric     // 20.7.16.2.1, construct/copy/destroy:
2510*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
2511*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
2512*fe6060f1SDimitry Andric     function(const function&);
2513*fe6060f1SDimitry Andric     template<class _Fp>
2514*fe6060f1SDimitry Andric       function(_Fp,
2515*fe6060f1SDimitry Andric                typename enable_if<!is_integral<_Fp>::value>::type* = 0);
2516*fe6060f1SDimitry Andric 
2517*fe6060f1SDimitry Andric     template<class _Alloc>
2518*fe6060f1SDimitry Andric       _LIBCPP_INLINE_VISIBILITY
2519*fe6060f1SDimitry Andric       function(allocator_arg_t, const _Alloc&) : __f_(0) {}
2520*fe6060f1SDimitry Andric     template<class _Alloc>
2521*fe6060f1SDimitry Andric       _LIBCPP_INLINE_VISIBILITY
2522*fe6060f1SDimitry Andric       function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
2523*fe6060f1SDimitry Andric     template<class _Alloc>
2524*fe6060f1SDimitry Andric       function(allocator_arg_t, const _Alloc&, const function&);
2525*fe6060f1SDimitry Andric     template<class _Fp, class _Alloc>
2526*fe6060f1SDimitry Andric       function(allocator_arg_t, const _Alloc& __a, _Fp __f,
2527*fe6060f1SDimitry Andric                typename enable_if<!is_integral<_Fp>::value>::type* = 0);
2528*fe6060f1SDimitry Andric 
2529*fe6060f1SDimitry Andric     function& operator=(const function&);
2530*fe6060f1SDimitry Andric     function& operator=(nullptr_t);
2531*fe6060f1SDimitry Andric     template<class _Fp>
2532*fe6060f1SDimitry Andric       typename enable_if
2533*fe6060f1SDimitry Andric       <
2534*fe6060f1SDimitry Andric         !is_integral<_Fp>::value,
2535*fe6060f1SDimitry Andric         function&
2536*fe6060f1SDimitry Andric       >::type
2537*fe6060f1SDimitry Andric       operator=(_Fp);
2538*fe6060f1SDimitry Andric 
2539*fe6060f1SDimitry Andric     ~function();
2540*fe6060f1SDimitry Andric 
2541*fe6060f1SDimitry Andric     // 20.7.16.2.2, function modifiers:
2542*fe6060f1SDimitry Andric     void swap(function&);
2543*fe6060f1SDimitry Andric     template<class _Fp, class _Alloc>
2544*fe6060f1SDimitry Andric       _LIBCPP_INLINE_VISIBILITY
2545*fe6060f1SDimitry Andric       void assign(_Fp __f, const _Alloc& __a)
2546*fe6060f1SDimitry Andric         {function(allocator_arg, __a, __f).swap(*this);}
2547*fe6060f1SDimitry Andric 
2548*fe6060f1SDimitry Andric     // 20.7.16.2.3, function capacity:
2549*fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;}
2550*fe6060f1SDimitry Andric 
2551*fe6060f1SDimitry Andric private:
2552*fe6060f1SDimitry Andric     // deleted overloads close possible hole in the type system
2553*fe6060f1SDimitry Andric     template<class _R2, class _B0, class _B1, class _B2>
2554*fe6060f1SDimitry Andric       bool operator==(const function<_R2(_B0, _B1, _B2)>&) const;// = delete;
2555*fe6060f1SDimitry Andric     template<class _R2, class _B0, class _B1, class _B2>
2556*fe6060f1SDimitry Andric       bool operator!=(const function<_R2(_B0, _B1, _B2)>&) const;// = delete;
2557*fe6060f1SDimitry Andric public:
2558*fe6060f1SDimitry Andric     // 20.7.16.2.4, function invocation:
2559*fe6060f1SDimitry Andric     _Rp operator()(_A0, _A1, _A2) const;
2560*fe6060f1SDimitry Andric 
2561*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI
2562*fe6060f1SDimitry Andric     // 20.7.16.2.5, function target access:
2563*fe6060f1SDimitry Andric     const std::type_info& target_type() const;
2564*fe6060f1SDimitry Andric     template <typename _Tp> _Tp* target();
2565*fe6060f1SDimitry Andric     template <typename _Tp> const _Tp* target() const;
2566*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI
2567*fe6060f1SDimitry Andric };
2568*fe6060f1SDimitry Andric 
2569*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1, class _A2>
2570*fe6060f1SDimitry Andric function<_Rp(_A0, _A1, _A2)>::function(const function& __f)
2571*fe6060f1SDimitry Andric {
2572*fe6060f1SDimitry Andric     if (__f.__f_ == 0)
2573*fe6060f1SDimitry Andric         __f_ = 0;
2574*fe6060f1SDimitry Andric     else if (__f.__f_ == (const __base*)&__f.__buf_)
2575*fe6060f1SDimitry Andric     {
2576*fe6060f1SDimitry Andric         __f_ = (__base*)&__buf_;
2577*fe6060f1SDimitry Andric         __f.__f_->__clone(__f_);
2578*fe6060f1SDimitry Andric     }
2579*fe6060f1SDimitry Andric     else
2580*fe6060f1SDimitry Andric         __f_ = __f.__f_->__clone();
2581*fe6060f1SDimitry Andric }
2582*fe6060f1SDimitry Andric 
2583*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1, class _A2>
2584*fe6060f1SDimitry Andric template<class _Alloc>
2585*fe6060f1SDimitry Andric function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc&,
2586*fe6060f1SDimitry Andric                                       const function& __f)
2587*fe6060f1SDimitry Andric {
2588*fe6060f1SDimitry Andric     if (__f.__f_ == 0)
2589*fe6060f1SDimitry Andric         __f_ = 0;
2590*fe6060f1SDimitry Andric     else if (__f.__f_ == (const __base*)&__f.__buf_)
2591*fe6060f1SDimitry Andric     {
2592*fe6060f1SDimitry Andric         __f_ = (__base*)&__buf_;
2593*fe6060f1SDimitry Andric         __f.__f_->__clone(__f_);
2594*fe6060f1SDimitry Andric     }
2595*fe6060f1SDimitry Andric     else
2596*fe6060f1SDimitry Andric         __f_ = __f.__f_->__clone();
2597*fe6060f1SDimitry Andric }
2598*fe6060f1SDimitry Andric 
2599*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1, class _A2>
2600*fe6060f1SDimitry Andric template <class _Fp>
2601*fe6060f1SDimitry Andric function<_Rp(_A0, _A1, _A2)>::function(_Fp __f,
2602*fe6060f1SDimitry Andric                                      typename enable_if<!is_integral<_Fp>::value>::type*)
2603*fe6060f1SDimitry Andric     : __f_(0)
2604*fe6060f1SDimitry Andric {
2605*fe6060f1SDimitry Andric     if (__function::__not_null(__f))
2606*fe6060f1SDimitry Andric     {
2607*fe6060f1SDimitry Andric         typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1, _A2)> _FF;
2608*fe6060f1SDimitry Andric         if (sizeof(_FF) <= sizeof(__buf_))
2609*fe6060f1SDimitry Andric         {
2610*fe6060f1SDimitry Andric             __f_ = (__base*)&__buf_;
2611*fe6060f1SDimitry Andric             ::new ((void*)__f_) _FF(__f);
2612*fe6060f1SDimitry Andric         }
2613*fe6060f1SDimitry Andric         else
2614*fe6060f1SDimitry Andric         {
2615*fe6060f1SDimitry Andric             typedef allocator<_FF> _Ap;
2616*fe6060f1SDimitry Andric             _Ap __a;
2617*fe6060f1SDimitry Andric             typedef __allocator_destructor<_Ap> _Dp;
2618*fe6060f1SDimitry Andric             unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
2619*fe6060f1SDimitry Andric             ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a));
2620*fe6060f1SDimitry Andric             __f_ = __hold.release();
2621*fe6060f1SDimitry Andric         }
2622*fe6060f1SDimitry Andric     }
2623*fe6060f1SDimitry Andric }
2624*fe6060f1SDimitry Andric 
2625*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1, class _A2>
2626*fe6060f1SDimitry Andric template <class _Fp, class _Alloc>
2627*fe6060f1SDimitry Andric function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
2628*fe6060f1SDimitry Andric                                      typename enable_if<!is_integral<_Fp>::value>::type*)
2629*fe6060f1SDimitry Andric     : __f_(0)
2630*fe6060f1SDimitry Andric {
2631*fe6060f1SDimitry Andric     typedef allocator_traits<_Alloc> __alloc_traits;
2632*fe6060f1SDimitry Andric     if (__function::__not_null(__f))
2633*fe6060f1SDimitry Andric     {
2634*fe6060f1SDimitry Andric         typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> _FF;
2635*fe6060f1SDimitry Andric         if (sizeof(_FF) <= sizeof(__buf_))
2636*fe6060f1SDimitry Andric         {
2637*fe6060f1SDimitry Andric             __f_ = (__base*)&__buf_;
2638*fe6060f1SDimitry Andric             ::new ((void*)__f_) _FF(__f, __a0);
2639*fe6060f1SDimitry Andric         }
2640*fe6060f1SDimitry Andric         else
2641*fe6060f1SDimitry Andric         {
2642*fe6060f1SDimitry Andric             typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
2643*fe6060f1SDimitry Andric             _Ap __a(__a0);
2644*fe6060f1SDimitry Andric             typedef __allocator_destructor<_Ap> _Dp;
2645*fe6060f1SDimitry Andric             unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
2646*fe6060f1SDimitry Andric             ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a));
2647*fe6060f1SDimitry Andric             __f_ = __hold.release();
2648*fe6060f1SDimitry Andric         }
2649*fe6060f1SDimitry Andric     }
2650*fe6060f1SDimitry Andric }
2651*fe6060f1SDimitry Andric 
2652*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1, class _A2>
2653*fe6060f1SDimitry Andric function<_Rp(_A0, _A1, _A2)>&
2654*fe6060f1SDimitry Andric function<_Rp(_A0, _A1, _A2)>::operator=(const function& __f)
2655*fe6060f1SDimitry Andric {
2656*fe6060f1SDimitry Andric     if (__f)
2657*fe6060f1SDimitry Andric         function(__f).swap(*this);
2658*fe6060f1SDimitry Andric     else
2659*fe6060f1SDimitry Andric         *this = nullptr;
2660*fe6060f1SDimitry Andric     return *this;
2661*fe6060f1SDimitry Andric }
2662*fe6060f1SDimitry Andric 
2663*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1, class _A2>
2664*fe6060f1SDimitry Andric function<_Rp(_A0, _A1, _A2)>&
2665*fe6060f1SDimitry Andric function<_Rp(_A0, _A1, _A2)>::operator=(nullptr_t)
2666*fe6060f1SDimitry Andric {
2667*fe6060f1SDimitry Andric     __base* __t = __f_;
2668*fe6060f1SDimitry Andric     __f_ = 0;
2669*fe6060f1SDimitry Andric     if (__t == (__base*)&__buf_)
2670*fe6060f1SDimitry Andric         __t->destroy();
2671*fe6060f1SDimitry Andric     else if (__t)
2672*fe6060f1SDimitry Andric         __t->destroy_deallocate();
2673*fe6060f1SDimitry Andric     return *this;
2674*fe6060f1SDimitry Andric }
2675*fe6060f1SDimitry Andric 
2676*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1, class _A2>
2677*fe6060f1SDimitry Andric template <class _Fp>
2678*fe6060f1SDimitry Andric typename enable_if
2679*fe6060f1SDimitry Andric <
2680*fe6060f1SDimitry Andric     !is_integral<_Fp>::value,
2681*fe6060f1SDimitry Andric     function<_Rp(_A0, _A1, _A2)>&
2682*fe6060f1SDimitry Andric >::type
2683*fe6060f1SDimitry Andric function<_Rp(_A0, _A1, _A2)>::operator=(_Fp __f)
2684*fe6060f1SDimitry Andric {
2685*fe6060f1SDimitry Andric     function(_VSTD::move(__f)).swap(*this);
2686*fe6060f1SDimitry Andric     return *this;
2687*fe6060f1SDimitry Andric }
2688*fe6060f1SDimitry Andric 
2689*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1, class _A2>
2690*fe6060f1SDimitry Andric function<_Rp(_A0, _A1, _A2)>::~function()
2691*fe6060f1SDimitry Andric {
2692*fe6060f1SDimitry Andric     if (__f_ == (__base*)&__buf_)
2693*fe6060f1SDimitry Andric         __f_->destroy();
2694*fe6060f1SDimitry Andric     else if (__f_)
2695*fe6060f1SDimitry Andric         __f_->destroy_deallocate();
2696*fe6060f1SDimitry Andric }
2697*fe6060f1SDimitry Andric 
2698*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1, class _A2>
2699*fe6060f1SDimitry Andric void
2700*fe6060f1SDimitry Andric function<_Rp(_A0, _A1, _A2)>::swap(function& __f)
2701*fe6060f1SDimitry Andric {
2702*fe6060f1SDimitry Andric     if (_VSTD::addressof(__f) == this)
2703*fe6060f1SDimitry Andric       return;
2704*fe6060f1SDimitry Andric     if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
2705*fe6060f1SDimitry Andric     {
2706*fe6060f1SDimitry Andric         typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
2707*fe6060f1SDimitry Andric         __base* __t = (__base*)&__tempbuf;
2708*fe6060f1SDimitry Andric         __f_->__clone(__t);
2709*fe6060f1SDimitry Andric         __f_->destroy();
2710*fe6060f1SDimitry Andric         __f_ = 0;
2711*fe6060f1SDimitry Andric         __f.__f_->__clone((__base*)&__buf_);
2712*fe6060f1SDimitry Andric         __f.__f_->destroy();
2713*fe6060f1SDimitry Andric         __f.__f_ = 0;
2714*fe6060f1SDimitry Andric         __f_ = (__base*)&__buf_;
2715*fe6060f1SDimitry Andric         __t->__clone((__base*)&__f.__buf_);
2716*fe6060f1SDimitry Andric         __t->destroy();
2717*fe6060f1SDimitry Andric         __f.__f_ = (__base*)&__f.__buf_;
2718*fe6060f1SDimitry Andric     }
2719*fe6060f1SDimitry Andric     else if (__f_ == (__base*)&__buf_)
2720*fe6060f1SDimitry Andric     {
2721*fe6060f1SDimitry Andric         __f_->__clone((__base*)&__f.__buf_);
2722*fe6060f1SDimitry Andric         __f_->destroy();
2723*fe6060f1SDimitry Andric         __f_ = __f.__f_;
2724*fe6060f1SDimitry Andric         __f.__f_ = (__base*)&__f.__buf_;
2725*fe6060f1SDimitry Andric     }
2726*fe6060f1SDimitry Andric     else if (__f.__f_ == (__base*)&__f.__buf_)
2727*fe6060f1SDimitry Andric     {
2728*fe6060f1SDimitry Andric         __f.__f_->__clone((__base*)&__buf_);
2729*fe6060f1SDimitry Andric         __f.__f_->destroy();
2730*fe6060f1SDimitry Andric         __f.__f_ = __f_;
2731*fe6060f1SDimitry Andric         __f_ = (__base*)&__buf_;
2732*fe6060f1SDimitry Andric     }
2733*fe6060f1SDimitry Andric     else
2734*fe6060f1SDimitry Andric         _VSTD::swap(__f_, __f.__f_);
2735*fe6060f1SDimitry Andric }
2736*fe6060f1SDimitry Andric 
2737*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1, class _A2>
2738*fe6060f1SDimitry Andric _Rp
2739*fe6060f1SDimitry Andric function<_Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) const
2740*fe6060f1SDimitry Andric {
2741*fe6060f1SDimitry Andric     if (__f_ == 0)
2742*fe6060f1SDimitry Andric         __throw_bad_function_call();
2743*fe6060f1SDimitry Andric     return (*__f_)(__a0, __a1, __a2);
2744*fe6060f1SDimitry Andric }
2745*fe6060f1SDimitry Andric 
2746*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI
2747*fe6060f1SDimitry Andric 
2748*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1, class _A2>
2749*fe6060f1SDimitry Andric const std::type_info&
2750*fe6060f1SDimitry Andric function<_Rp(_A0, _A1, _A2)>::target_type() const
2751*fe6060f1SDimitry Andric {
2752*fe6060f1SDimitry Andric     if (__f_ == 0)
2753*fe6060f1SDimitry Andric         return typeid(void);
2754*fe6060f1SDimitry Andric     return __f_->target_type();
2755*fe6060f1SDimitry Andric }
2756*fe6060f1SDimitry Andric 
2757*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1, class _A2>
2758*fe6060f1SDimitry Andric template <typename _Tp>
2759*fe6060f1SDimitry Andric _Tp*
2760*fe6060f1SDimitry Andric function<_Rp(_A0, _A1, _A2)>::target()
2761*fe6060f1SDimitry Andric {
2762*fe6060f1SDimitry Andric     if (__f_ == 0)
2763*fe6060f1SDimitry Andric         return (_Tp*)0;
2764*fe6060f1SDimitry Andric     return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
2765*fe6060f1SDimitry Andric }
2766*fe6060f1SDimitry Andric 
2767*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1, class _A2>
2768*fe6060f1SDimitry Andric template <typename _Tp>
2769*fe6060f1SDimitry Andric const _Tp*
2770*fe6060f1SDimitry Andric function<_Rp(_A0, _A1, _A2)>::target() const
2771*fe6060f1SDimitry Andric {
2772*fe6060f1SDimitry Andric     if (__f_ == 0)
2773*fe6060f1SDimitry Andric         return (const _Tp*)0;
2774*fe6060f1SDimitry Andric     return (const _Tp*)__f_->target(typeid(_Tp));
2775*fe6060f1SDimitry Andric }
2776*fe6060f1SDimitry Andric 
2777*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI
2778*fe6060f1SDimitry Andric 
2779*fe6060f1SDimitry Andric template <class _Fp>
2780*fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY
2781*fe6060f1SDimitry Andric bool
2782*fe6060f1SDimitry Andric operator==(const function<_Fp>& __f, nullptr_t) {return !__f;}
2783*fe6060f1SDimitry Andric 
2784*fe6060f1SDimitry Andric template <class _Fp>
2785*fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY
2786*fe6060f1SDimitry Andric bool
2787*fe6060f1SDimitry Andric operator==(nullptr_t, const function<_Fp>& __f) {return !__f;}
2788*fe6060f1SDimitry Andric 
2789*fe6060f1SDimitry Andric template <class _Fp>
2790*fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY
2791*fe6060f1SDimitry Andric bool
2792*fe6060f1SDimitry Andric operator!=(const function<_Fp>& __f, nullptr_t) {return (bool)__f;}
2793*fe6060f1SDimitry Andric 
2794*fe6060f1SDimitry Andric template <class _Fp>
2795*fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY
2796*fe6060f1SDimitry Andric bool
2797*fe6060f1SDimitry Andric operator!=(nullptr_t, const function<_Fp>& __f) {return (bool)__f;}
2798*fe6060f1SDimitry Andric 
2799*fe6060f1SDimitry Andric template <class _Fp>
2800*fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY
2801*fe6060f1SDimitry Andric void
2802*fe6060f1SDimitry Andric swap(function<_Fp>& __x, function<_Fp>& __y)
2803*fe6060f1SDimitry Andric {return __x.swap(__y);}
2804*fe6060f1SDimitry Andric 
2805*fe6060f1SDimitry Andric #endif
2806*fe6060f1SDimitry Andric 
2807*fe6060f1SDimitry Andric _LIBCPP_END_NAMESPACE_STD
2808*fe6060f1SDimitry Andric 
2809*fe6060f1SDimitry Andric #endif // _LIBCPP___FUNCTIONAL_FUNCTION_H
2810