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