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