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