xref: /freebsd-src/contrib/llvm-project/libcxx/include/__functional/function.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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 
1381ad6265SDimitry Andric #include <__assert>
14fe6060f1SDimitry Andric #include <__config>
1506c3fb27SDimitry Andric #include <__exception/exception.h>
16fe6060f1SDimitry Andric #include <__functional/binary_function.h>
17fe6060f1SDimitry Andric #include <__functional/invoke.h>
18fe6060f1SDimitry Andric #include <__functional/unary_function.h>
19fe6060f1SDimitry Andric #include <__iterator/iterator_traits.h>
2004eeddc0SDimitry Andric #include <__memory/addressof.h>
21bdd1243dSDimitry Andric #include <__memory/allocator.h>
22bdd1243dSDimitry Andric #include <__memory/allocator_destructor.h>
23fe6060f1SDimitry Andric #include <__memory/allocator_traits.h>
24bdd1243dSDimitry Andric #include <__memory/builtin_new_allocator.h>
25fe6060f1SDimitry Andric #include <__memory/compressed_pair.h>
26bdd1243dSDimitry Andric #include <__memory/unique_ptr.h>
2706c3fb27SDimitry Andric #include <__type_traits/aligned_storage.h>
2806c3fb27SDimitry Andric #include <__type_traits/decay.h>
2906c3fb27SDimitry Andric #include <__type_traits/is_core_convertible.h>
3006c3fb27SDimitry Andric #include <__type_traits/is_scalar.h>
31*0fca6ea1SDimitry Andric #include <__type_traits/is_trivially_constructible.h>
3206c3fb27SDimitry Andric #include <__type_traits/is_trivially_destructible.h>
3306c3fb27SDimitry Andric #include <__type_traits/is_void.h>
34bdd1243dSDimitry Andric #include <__type_traits/strip_signature.h>
3581ad6265SDimitry Andric #include <__utility/forward.h>
3681ad6265SDimitry Andric #include <__utility/move.h>
37bdd1243dSDimitry Andric #include <__utility/piecewise_construct.h>
3881ad6265SDimitry Andric #include <__utility/swap.h>
3906c3fb27SDimitry Andric #include <__verbose_abort>
40bdd1243dSDimitry Andric #include <new>
41bdd1243dSDimitry Andric #include <tuple>
42bdd1243dSDimitry Andric #include <typeinfo>
43fe6060f1SDimitry Andric 
44fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
45fe6060f1SDimitry Andric #  pragma GCC system_header
46fe6060f1SDimitry Andric #endif
47fe6060f1SDimitry Andric 
48b3edf446SDimitry Andric _LIBCPP_PUSH_MACROS
49b3edf446SDimitry Andric #include <__undef_macros>
50b3edf446SDimitry Andric 
51bdd1243dSDimitry Andric #ifndef _LIBCPP_CXX03_LANG
52bdd1243dSDimitry Andric 
53fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
54fe6060f1SDimitry Andric 
55fe6060f1SDimitry Andric // bad_function_call
56fe6060f1SDimitry Andric 
5781ad6265SDimitry Andric _LIBCPP_DIAGNOSTIC_PUSH
58*0fca6ea1SDimitry Andric #  if !_LIBCPP_AVAILABILITY_HAS_BAD_FUNCTION_CALL_KEY_FUNCTION
5981ad6265SDimitry Andric _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables")
60*0fca6ea1SDimitry Andric #  endif
61cb14a3feSDimitry Andric class _LIBCPP_EXPORTED_FROM_ABI bad_function_call : public exception {
62fe6060f1SDimitry Andric public:
635f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bad_function_call() _NOEXCEPT                                    = default;
645f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bad_function_call(const bad_function_call&) _NOEXCEPT            = default;
655f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bad_function_call& operator=(const bad_function_call&) _NOEXCEPT = default;
66349cc55cSDimitry Andric // Note that when a key function is not used, every translation unit that uses
67349cc55cSDimitry Andric // bad_function_call will end up containing a weak definition of the vtable and
68349cc55cSDimitry Andric // typeinfo.
69*0fca6ea1SDimitry Andric #  if _LIBCPP_AVAILABILITY_HAS_BAD_FUNCTION_CALL_KEY_FUNCTION
70bdd1243dSDimitry Andric   ~bad_function_call() _NOEXCEPT override;
71349cc55cSDimitry Andric #  else
7206c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~bad_function_call() _NOEXCEPT override {}
73349cc55cSDimitry Andric #  endif
74fe6060f1SDimitry Andric 
75349cc55cSDimitry Andric #  ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE
76bdd1243dSDimitry Andric   const char* what() const _NOEXCEPT override;
77fe6060f1SDimitry Andric #  endif
78fe6060f1SDimitry Andric };
7981ad6265SDimitry Andric _LIBCPP_DIAGNOSTIC_POP
80fe6060f1SDimitry Andric 
81cb14a3feSDimitry Andric _LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void __throw_bad_function_call() {
8206c3fb27SDimitry Andric #  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
83fe6060f1SDimitry Andric   throw bad_function_call();
84fe6060f1SDimitry Andric #  else
8506c3fb27SDimitry Andric   _LIBCPP_VERBOSE_ABORT("bad_function_call was thrown in -fno-exceptions mode");
86fe6060f1SDimitry Andric #  endif
87fe6060f1SDimitry Andric }
88fe6060f1SDimitry Andric 
89cb14a3feSDimitry Andric template <class _Fp>
90cb14a3feSDimitry Andric class _LIBCPP_TEMPLATE_VIS function; // undefined
91fe6060f1SDimitry Andric 
92cb14a3feSDimitry Andric namespace __function {
93fe6060f1SDimitry Andric 
94fe6060f1SDimitry Andric template <class _Rp>
95cb14a3feSDimitry Andric struct __maybe_derive_from_unary_function {};
96fe6060f1SDimitry Andric 
97fe6060f1SDimitry Andric template <class _Rp, class _A1>
98cb14a3feSDimitry Andric struct __maybe_derive_from_unary_function<_Rp(_A1)> : public __unary_function<_A1, _Rp> {};
99fe6060f1SDimitry Andric 
100fe6060f1SDimitry Andric template <class _Rp>
101cb14a3feSDimitry Andric struct __maybe_derive_from_binary_function {};
102fe6060f1SDimitry Andric 
103fe6060f1SDimitry Andric template <class _Rp, class _A1, class _A2>
104cb14a3feSDimitry Andric struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)> : public __binary_function<_A1, _A2, _Rp> {};
105fe6060f1SDimitry Andric 
106fe6060f1SDimitry Andric template <class _Fp>
107cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __not_null(_Fp const&) {
108cb14a3feSDimitry Andric   return true;
109cb14a3feSDimitry Andric }
110fe6060f1SDimitry Andric 
111fe6060f1SDimitry Andric template <class _Fp>
112cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __not_null(_Fp* __ptr) {
113cb14a3feSDimitry Andric   return __ptr;
114cb14a3feSDimitry Andric }
115fe6060f1SDimitry Andric 
116fe6060f1SDimitry Andric template <class _Ret, class _Class>
117cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __not_null(_Ret _Class::*__ptr) {
118cb14a3feSDimitry Andric   return __ptr;
119cb14a3feSDimitry Andric }
120fe6060f1SDimitry Andric 
121fe6060f1SDimitry Andric template <class _Fp>
122cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __not_null(function<_Fp> const& __f) {
123cb14a3feSDimitry Andric   return !!__f;
124cb14a3feSDimitry Andric }
125fe6060f1SDimitry Andric 
126fe6060f1SDimitry Andric #  ifdef _LIBCPP_HAS_EXTENSION_BLOCKS
127fe6060f1SDimitry Andric template <class _Rp, class... _Args>
128cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __not_null(_Rp (^__p)(_Args...)) {
129cb14a3feSDimitry Andric   return __p;
130cb14a3feSDimitry Andric }
131fe6060f1SDimitry Andric #  endif
132fe6060f1SDimitry Andric 
133fe6060f1SDimitry Andric } // namespace __function
134fe6060f1SDimitry Andric 
135fe6060f1SDimitry Andric namespace __function {
136fe6060f1SDimitry Andric 
137fe6060f1SDimitry Andric // __alloc_func holds a functor and an allocator.
138fe6060f1SDimitry Andric 
139cb14a3feSDimitry Andric template <class _Fp, class _Ap, class _FB>
140cb14a3feSDimitry Andric class __alloc_func;
141fe6060f1SDimitry Andric template <class _Fp, class _FB>
142fe6060f1SDimitry Andric class __default_alloc_func;
143fe6060f1SDimitry Andric 
144fe6060f1SDimitry Andric template <class _Fp, class _Ap, class _Rp, class... _ArgTypes>
145cb14a3feSDimitry Andric class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)> {
146fe6060f1SDimitry Andric   __compressed_pair<_Fp, _Ap> __f_;
147fe6060f1SDimitry Andric 
148fe6060f1SDimitry Andric public:
149349cc55cSDimitry Andric   typedef _LIBCPP_NODEBUG _Fp _Target;
150349cc55cSDimitry Andric   typedef _LIBCPP_NODEBUG _Ap _Alloc;
151fe6060f1SDimitry Andric 
152cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI const _Target& __target() const { return __f_.first(); }
153fe6060f1SDimitry Andric 
154fe6060f1SDimitry Andric   // WIN32 APIs may define __allocator, so use __get_allocator instead.
155cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI const _Alloc& __get_allocator() const { return __f_.second(); }
156fe6060f1SDimitry Andric 
157cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit __alloc_func(_Target&& __f)
158cb14a3feSDimitry Andric       : __f_(piecewise_construct, std::forward_as_tuple(std::move(__f)), std::forward_as_tuple()) {}
159fe6060f1SDimitry Andric 
160cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit __alloc_func(const _Target& __f, const _Alloc& __a)
161cb14a3feSDimitry Andric       : __f_(piecewise_construct, std::forward_as_tuple(__f), std::forward_as_tuple(__a)) {}
162fe6060f1SDimitry Andric 
163cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit __alloc_func(const _Target& __f, _Alloc&& __a)
164cb14a3feSDimitry Andric       : __f_(piecewise_construct, std::forward_as_tuple(__f), std::forward_as_tuple(std::move(__a))) {}
165fe6060f1SDimitry Andric 
166cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit __alloc_func(_Target&& __f, _Alloc&& __a)
167cb14a3feSDimitry Andric       : __f_(piecewise_construct, std::forward_as_tuple(std::move(__f)), std::forward_as_tuple(std::move(__a))) {}
168fe6060f1SDimitry Andric 
169cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __arg) {
170fe6060f1SDimitry Andric     typedef __invoke_void_return_wrapper<_Rp> _Invoker;
171cb14a3feSDimitry Andric     return _Invoker::__call(__f_.first(), std::forward<_ArgTypes>(__arg)...);
172fe6060f1SDimitry Andric   }
173fe6060f1SDimitry Andric 
174cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __alloc_func* __clone() const {
175fe6060f1SDimitry Andric     typedef allocator_traits<_Alloc> __alloc_traits;
176bdd1243dSDimitry Andric     typedef __rebind_alloc<__alloc_traits, __alloc_func> _AA;
177fe6060f1SDimitry Andric     _AA __a(__f_.second());
178fe6060f1SDimitry Andric     typedef __allocator_destructor<_AA> _Dp;
179fe6060f1SDimitry Andric     unique_ptr<__alloc_func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
180fe6060f1SDimitry Andric     ::new ((void*)__hold.get()) __alloc_func(__f_.first(), _Alloc(__a));
181fe6060f1SDimitry Andric     return __hold.release();
182fe6060f1SDimitry Andric   }
183fe6060f1SDimitry Andric 
184cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI void destroy() _NOEXCEPT { __f_.~__compressed_pair<_Target, _Alloc>(); }
185fe6060f1SDimitry Andric 
18606c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI static void __destroy_and_delete(__alloc_func* __f) {
187fe6060f1SDimitry Andric     typedef allocator_traits<_Alloc> __alloc_traits;
188bdd1243dSDimitry Andric     typedef __rebind_alloc<__alloc_traits, __alloc_func> _FunAlloc;
189fe6060f1SDimitry Andric     _FunAlloc __a(__f->__get_allocator());
190fe6060f1SDimitry Andric     __f->destroy();
191fe6060f1SDimitry Andric     __a.deallocate(__f, 1);
192fe6060f1SDimitry Andric   }
193fe6060f1SDimitry Andric };
194fe6060f1SDimitry Andric 
195fe6060f1SDimitry Andric template <class _Fp, class _Rp, class... _ArgTypes>
196fe6060f1SDimitry Andric class __default_alloc_func<_Fp, _Rp(_ArgTypes...)> {
197fe6060f1SDimitry Andric   _Fp __f_;
198fe6060f1SDimitry Andric 
199fe6060f1SDimitry Andric public:
200349cc55cSDimitry Andric   typedef _LIBCPP_NODEBUG _Fp _Target;
201fe6060f1SDimitry Andric 
202cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI const _Target& __target() const { return __f_; }
203fe6060f1SDimitry Andric 
204cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit __default_alloc_func(_Target&& __f) : __f_(std::move(__f)) {}
205fe6060f1SDimitry Andric 
206cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit __default_alloc_func(const _Target& __f) : __f_(__f) {}
207fe6060f1SDimitry Andric 
208cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __arg) {
209fe6060f1SDimitry Andric     typedef __invoke_void_return_wrapper<_Rp> _Invoker;
2105f757f3fSDimitry Andric     return _Invoker::__call(__f_, std::forward<_ArgTypes>(__arg)...);
211fe6060f1SDimitry Andric   }
212fe6060f1SDimitry Andric 
213cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __default_alloc_func* __clone() const {
214cb14a3feSDimitry Andric     __builtin_new_allocator::__holder_t __hold = __builtin_new_allocator::__allocate_type<__default_alloc_func>(1);
215cb14a3feSDimitry Andric     __default_alloc_func* __res                = ::new ((void*)__hold.get()) __default_alloc_func(__f_);
216fe6060f1SDimitry Andric     (void)__hold.release();
217fe6060f1SDimitry Andric     return __res;
218fe6060f1SDimitry Andric   }
219fe6060f1SDimitry Andric 
220cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI void destroy() _NOEXCEPT { __f_.~_Target(); }
221fe6060f1SDimitry Andric 
22206c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI static void __destroy_and_delete(__default_alloc_func* __f) {
223fe6060f1SDimitry Andric     __f->destroy();
224fe6060f1SDimitry Andric     __builtin_new_allocator::__deallocate_type<__default_alloc_func>(__f, 1);
225fe6060f1SDimitry Andric   }
226fe6060f1SDimitry Andric };
227fe6060f1SDimitry Andric 
228fe6060f1SDimitry Andric // __base provides an abstract interface for copyable functors.
229fe6060f1SDimitry Andric 
230cb14a3feSDimitry Andric template <class _Fp>
231cb14a3feSDimitry Andric class _LIBCPP_TEMPLATE_VIS __base;
232fe6060f1SDimitry Andric 
233fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
234cb14a3feSDimitry Andric class __base<_Rp(_ArgTypes...)> {
235fe6060f1SDimitry Andric public:
236*0fca6ea1SDimitry Andric   __base(const __base&)            = delete;
237*0fca6ea1SDimitry Andric   __base& operator=(const __base&) = delete;
238*0fca6ea1SDimitry Andric 
2395f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __base() {}
240bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual ~__base() {}
241fe6060f1SDimitry Andric   virtual __base* __clone() const             = 0;
242fe6060f1SDimitry Andric   virtual void __clone(__base*) const         = 0;
243fe6060f1SDimitry Andric   virtual void destroy() _NOEXCEPT            = 0;
244fe6060f1SDimitry Andric   virtual void destroy_deallocate() _NOEXCEPT = 0;
245fe6060f1SDimitry Andric   virtual _Rp operator()(_ArgTypes&&...)      = 0;
2461ac55f4cSDimitry Andric #  ifndef _LIBCPP_HAS_NO_RTTI
247fe6060f1SDimitry Andric   virtual const void* target(const type_info&) const _NOEXCEPT = 0;
248fe6060f1SDimitry Andric   virtual const std::type_info& target_type() const _NOEXCEPT  = 0;
2491ac55f4cSDimitry Andric #  endif // _LIBCPP_HAS_NO_RTTI
250fe6060f1SDimitry Andric };
251fe6060f1SDimitry Andric 
252fe6060f1SDimitry Andric // __func implements __base for a given functor type.
253fe6060f1SDimitry Andric 
254cb14a3feSDimitry Andric template <class _FD, class _Alloc, class _FB>
255cb14a3feSDimitry Andric class __func;
256fe6060f1SDimitry Andric 
257fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
258cb14a3feSDimitry Andric class __func<_Fp, _Alloc, _Rp(_ArgTypes...)> : public __base<_Rp(_ArgTypes...)> {
259fe6060f1SDimitry Andric   __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> __f_;
260cb14a3feSDimitry Andric 
261fe6060f1SDimitry Andric public:
262cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit __func(_Fp&& __f) : __f_(std::move(__f)) {}
263fe6060f1SDimitry Andric 
264cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit __func(const _Fp& __f, const _Alloc& __a) : __f_(__f, __a) {}
265fe6060f1SDimitry Andric 
266cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit __func(const _Fp& __f, _Alloc&& __a) : __f_(__f, std::move(__a)) {}
267fe6060f1SDimitry Andric 
268cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit __func(_Fp&& __f, _Alloc&& __a) : __f_(std::move(__f), std::move(__a)) {}
269fe6060f1SDimitry Andric 
27006c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual __base<_Rp(_ArgTypes...)>* __clone() const;
27106c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __clone(__base<_Rp(_ArgTypes...)>*) const;
27206c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy() _NOEXCEPT;
27306c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate() _NOEXCEPT;
27406c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&&... __arg);
2751ac55f4cSDimitry Andric #  ifndef _LIBCPP_HAS_NO_RTTI
27606c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const void* target(const type_info&) const _NOEXCEPT;
27706c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const std::type_info& target_type() const _NOEXCEPT;
2781ac55f4cSDimitry Andric #  endif // _LIBCPP_HAS_NO_RTTI
279fe6060f1SDimitry Andric };
280fe6060f1SDimitry Andric 
281fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
282cb14a3feSDimitry Andric __base<_Rp(_ArgTypes...)>* __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const {
283fe6060f1SDimitry Andric   typedef allocator_traits<_Alloc> __alloc_traits;
284bdd1243dSDimitry Andric   typedef __rebind_alloc<__alloc_traits, __func> _Ap;
285fe6060f1SDimitry Andric   _Ap __a(__f_.__get_allocator());
286fe6060f1SDimitry Andric   typedef __allocator_destructor<_Ap> _Dp;
287fe6060f1SDimitry Andric   unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
288fe6060f1SDimitry Andric   ::new ((void*)__hold.get()) __func(__f_.__target(), _Alloc(__a));
289fe6060f1SDimitry Andric   return __hold.release();
290fe6060f1SDimitry Andric }
291fe6060f1SDimitry Andric 
292fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
293cb14a3feSDimitry Andric void __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const {
294fe6060f1SDimitry Andric   ::new ((void*)__p) __func(__f_.__target(), __f_.__get_allocator());
295fe6060f1SDimitry Andric }
296fe6060f1SDimitry Andric 
297fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
298cb14a3feSDimitry Andric void __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() _NOEXCEPT {
299fe6060f1SDimitry Andric   __f_.destroy();
300fe6060f1SDimitry Andric }
301fe6060f1SDimitry Andric 
302fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
303cb14a3feSDimitry Andric void __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT {
304fe6060f1SDimitry Andric   typedef allocator_traits<_Alloc> __alloc_traits;
305bdd1243dSDimitry Andric   typedef __rebind_alloc<__alloc_traits, __func> _Ap;
306fe6060f1SDimitry Andric   _Ap __a(__f_.__get_allocator());
307fe6060f1SDimitry Andric   __f_.destroy();
308fe6060f1SDimitry Andric   __a.deallocate(this, 1);
309fe6060f1SDimitry Andric }
310fe6060f1SDimitry Andric 
311fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
312cb14a3feSDimitry Andric _Rp __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&&... __arg) {
3135f757f3fSDimitry Andric   return __f_(std::forward<_ArgTypes>(__arg)...);
314fe6060f1SDimitry Andric }
315fe6060f1SDimitry Andric 
3161ac55f4cSDimitry Andric #  ifndef _LIBCPP_HAS_NO_RTTI
317fe6060f1SDimitry Andric 
318fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
319cb14a3feSDimitry Andric const void* __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT {
320fe6060f1SDimitry Andric   if (__ti == typeid(_Fp))
3215f757f3fSDimitry Andric     return std::addressof(__f_.__target());
322fe6060f1SDimitry Andric   return nullptr;
323fe6060f1SDimitry Andric }
324fe6060f1SDimitry Andric 
325fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
326cb14a3feSDimitry Andric const std::type_info& __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT {
327fe6060f1SDimitry Andric   return typeid(_Fp);
328fe6060f1SDimitry Andric }
329fe6060f1SDimitry Andric 
3301ac55f4cSDimitry Andric #  endif // _LIBCPP_HAS_NO_RTTI
331fe6060f1SDimitry Andric 
332fe6060f1SDimitry Andric // __value_func creates a value-type from a __func.
333fe6060f1SDimitry Andric 
334cb14a3feSDimitry Andric template <class _Fp>
335cb14a3feSDimitry Andric class __value_func;
336fe6060f1SDimitry Andric 
337cb14a3feSDimitry Andric template <class _Rp, class... _ArgTypes>
338cb14a3feSDimitry Andric class __value_func<_Rp(_ArgTypes...)> {
339bdd1243dSDimitry Andric   _LIBCPP_SUPPRESS_DEPRECATED_PUSH
340fe6060f1SDimitry Andric   typename aligned_storage<3 * sizeof(void*)>::type __buf_;
341bdd1243dSDimitry Andric   _LIBCPP_SUPPRESS_DEPRECATED_POP
342fe6060f1SDimitry Andric 
343fe6060f1SDimitry Andric   typedef __base<_Rp(_ArgTypes...)> __func;
344fe6060f1SDimitry Andric   __func* __f_;
345fe6060f1SDimitry Andric 
346cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI static __func* __as_base(void* __p) { return reinterpret_cast<__func*>(__p); }
347fe6060f1SDimitry Andric 
348fe6060f1SDimitry Andric public:
349cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __value_func() _NOEXCEPT : __f_(nullptr) {}
350fe6060f1SDimitry Andric 
351fe6060f1SDimitry Andric   template <class _Fp, class _Alloc>
352cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __value_func(_Fp&& __f, const _Alloc& __a) : __f_(nullptr) {
353fe6060f1SDimitry Andric     typedef allocator_traits<_Alloc> __alloc_traits;
354fe6060f1SDimitry Andric     typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun;
355bdd1243dSDimitry Andric     typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc;
356fe6060f1SDimitry Andric 
357cb14a3feSDimitry Andric     if (__function::__not_null(__f)) {
358fe6060f1SDimitry Andric       _FunAlloc __af(__a);
359cb14a3feSDimitry Andric       if (sizeof(_Fun) <= sizeof(__buf_) && is_nothrow_copy_constructible<_Fp>::value &&
360cb14a3feSDimitry Andric           is_nothrow_copy_constructible<_FunAlloc>::value) {
361cb14a3feSDimitry Andric         __f_ = ::new ((void*)&__buf_) _Fun(std::move(__f), _Alloc(__af));
362cb14a3feSDimitry Andric       } else {
363fe6060f1SDimitry Andric         typedef __allocator_destructor<_FunAlloc> _Dp;
364fe6060f1SDimitry Andric         unique_ptr<__func, _Dp> __hold(__af.allocate(1), _Dp(__af, 1));
3655f757f3fSDimitry Andric         ::new ((void*)__hold.get()) _Fun(std::move(__f), _Alloc(__a));
366fe6060f1SDimitry Andric         __f_ = __hold.release();
367fe6060f1SDimitry Andric       }
368fe6060f1SDimitry Andric     }
369fe6060f1SDimitry Andric   }
370fe6060f1SDimitry Andric 
3715f757f3fSDimitry Andric   template <class _Fp, __enable_if_t<!is_same<__decay_t<_Fp>, __value_func>::value, int> = 0>
372cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit __value_func(_Fp&& __f) : __value_func(std::forward<_Fp>(__f), allocator<_Fp>()) {}
373fe6060f1SDimitry Andric 
374cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __value_func(const __value_func& __f) {
375fe6060f1SDimitry Andric     if (__f.__f_ == nullptr)
376fe6060f1SDimitry Andric       __f_ = nullptr;
377cb14a3feSDimitry Andric     else if ((void*)__f.__f_ == &__f.__buf_) {
378fe6060f1SDimitry Andric       __f_ = __as_base(&__buf_);
379fe6060f1SDimitry Andric       __f.__f_->__clone(__f_);
380cb14a3feSDimitry Andric     } else
381fe6060f1SDimitry Andric       __f_ = __f.__f_->__clone();
382fe6060f1SDimitry Andric   }
383fe6060f1SDimitry Andric 
384cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __value_func(__value_func&& __f) _NOEXCEPT {
385fe6060f1SDimitry Andric     if (__f.__f_ == nullptr)
386fe6060f1SDimitry Andric       __f_ = nullptr;
387cb14a3feSDimitry Andric     else if ((void*)__f.__f_ == &__f.__buf_) {
388fe6060f1SDimitry Andric       __f_ = __as_base(&__buf_);
389fe6060f1SDimitry Andric       __f.__f_->__clone(__f_);
390cb14a3feSDimitry Andric     } else {
391fe6060f1SDimitry Andric       __f_     = __f.__f_;
392fe6060f1SDimitry Andric       __f.__f_ = nullptr;
393fe6060f1SDimitry Andric     }
394fe6060f1SDimitry Andric   }
395fe6060f1SDimitry Andric 
396cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI ~__value_func() {
397fe6060f1SDimitry Andric     if ((void*)__f_ == &__buf_)
398fe6060f1SDimitry Andric       __f_->destroy();
399fe6060f1SDimitry Andric     else if (__f_)
400fe6060f1SDimitry Andric       __f_->destroy_deallocate();
401fe6060f1SDimitry Andric   }
402fe6060f1SDimitry Andric 
403cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __value_func& operator=(__value_func&& __f) {
404fe6060f1SDimitry Andric     *this = nullptr;
405fe6060f1SDimitry Andric     if (__f.__f_ == nullptr)
406fe6060f1SDimitry Andric       __f_ = nullptr;
407cb14a3feSDimitry Andric     else if ((void*)__f.__f_ == &__f.__buf_) {
408fe6060f1SDimitry Andric       __f_ = __as_base(&__buf_);
409fe6060f1SDimitry Andric       __f.__f_->__clone(__f_);
410cb14a3feSDimitry Andric     } else {
411fe6060f1SDimitry Andric       __f_     = __f.__f_;
412fe6060f1SDimitry Andric       __f.__f_ = nullptr;
413fe6060f1SDimitry Andric     }
414fe6060f1SDimitry Andric     return *this;
415fe6060f1SDimitry Andric   }
416fe6060f1SDimitry Andric 
417cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __value_func& operator=(nullptr_t) {
418fe6060f1SDimitry Andric     __func* __f = __f_;
419fe6060f1SDimitry Andric     __f_        = nullptr;
420fe6060f1SDimitry Andric     if ((void*)__f == &__buf_)
421fe6060f1SDimitry Andric       __f->destroy();
422fe6060f1SDimitry Andric     else if (__f)
423fe6060f1SDimitry Andric       __f->destroy_deallocate();
424fe6060f1SDimitry Andric     return *this;
425fe6060f1SDimitry Andric   }
426fe6060f1SDimitry Andric 
427cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __args) const {
428fe6060f1SDimitry Andric     if (__f_ == nullptr)
429fe6060f1SDimitry Andric       __throw_bad_function_call();
4305f757f3fSDimitry Andric     return (*__f_)(std::forward<_ArgTypes>(__args)...);
431fe6060f1SDimitry Andric   }
432fe6060f1SDimitry Andric 
433cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI void swap(__value_func& __f) _NOEXCEPT {
434fe6060f1SDimitry Andric     if (&__f == this)
435fe6060f1SDimitry Andric       return;
436cb14a3feSDimitry Andric     if ((void*)__f_ == &__buf_ && (void*)__f.__f_ == &__f.__buf_) {
437bdd1243dSDimitry Andric       _LIBCPP_SUPPRESS_DEPRECATED_PUSH
438fe6060f1SDimitry Andric       typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
439bdd1243dSDimitry Andric       _LIBCPP_SUPPRESS_DEPRECATED_POP
440fe6060f1SDimitry Andric       __func* __t = __as_base(&__tempbuf);
441fe6060f1SDimitry Andric       __f_->__clone(__t);
442fe6060f1SDimitry Andric       __f_->destroy();
443fe6060f1SDimitry Andric       __f_ = nullptr;
444fe6060f1SDimitry Andric       __f.__f_->__clone(__as_base(&__buf_));
445fe6060f1SDimitry Andric       __f.__f_->destroy();
446fe6060f1SDimitry Andric       __f.__f_ = nullptr;
447fe6060f1SDimitry Andric       __f_     = __as_base(&__buf_);
448fe6060f1SDimitry Andric       __t->__clone(__as_base(&__f.__buf_));
449fe6060f1SDimitry Andric       __t->destroy();
450fe6060f1SDimitry Andric       __f.__f_ = __as_base(&__f.__buf_);
451cb14a3feSDimitry Andric     } else if ((void*)__f_ == &__buf_) {
452fe6060f1SDimitry Andric       __f_->__clone(__as_base(&__f.__buf_));
453fe6060f1SDimitry Andric       __f_->destroy();
454fe6060f1SDimitry Andric       __f_     = __f.__f_;
455fe6060f1SDimitry Andric       __f.__f_ = __as_base(&__f.__buf_);
456cb14a3feSDimitry Andric     } else if ((void*)__f.__f_ == &__f.__buf_) {
457fe6060f1SDimitry Andric       __f.__f_->__clone(__as_base(&__buf_));
458fe6060f1SDimitry Andric       __f.__f_->destroy();
459fe6060f1SDimitry Andric       __f.__f_ = __f_;
460fe6060f1SDimitry Andric       __f_     = __as_base(&__buf_);
461cb14a3feSDimitry Andric     } else
4625f757f3fSDimitry Andric       std::swap(__f_, __f.__f_);
463fe6060f1SDimitry Andric   }
464fe6060f1SDimitry Andric 
465cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __f_ != nullptr; }
466fe6060f1SDimitry Andric 
4671ac55f4cSDimitry Andric #  ifndef _LIBCPP_HAS_NO_RTTI
468cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT {
469fe6060f1SDimitry Andric     if (__f_ == nullptr)
470fe6060f1SDimitry Andric       return typeid(void);
471fe6060f1SDimitry Andric     return __f_->target_type();
472fe6060f1SDimitry Andric   }
473fe6060f1SDimitry Andric 
474fe6060f1SDimitry Andric   template <typename _Tp>
475cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT {
476fe6060f1SDimitry Andric     if (__f_ == nullptr)
477fe6060f1SDimitry Andric       return nullptr;
478fe6060f1SDimitry Andric     return (const _Tp*)__f_->target(typeid(_Tp));
479fe6060f1SDimitry Andric   }
4801ac55f4cSDimitry Andric #  endif // _LIBCPP_HAS_NO_RTTI
481fe6060f1SDimitry Andric };
482fe6060f1SDimitry Andric 
483fe6060f1SDimitry Andric // Storage for a functor object, to be used with __policy to manage copy and
484fe6060f1SDimitry Andric // destruction.
485cb14a3feSDimitry Andric union __policy_storage {
486fe6060f1SDimitry Andric   mutable char __small[sizeof(void*) * 2];
487fe6060f1SDimitry Andric   void* __large;
488fe6060f1SDimitry Andric };
489fe6060f1SDimitry Andric 
490fe6060f1SDimitry Andric // True if _Fun can safely be held in __policy_storage.__small.
491fe6060f1SDimitry Andric template <typename _Fun>
492fe6060f1SDimitry Andric struct __use_small_storage
493fe6060f1SDimitry Andric     : public integral_constant<
494cb14a3feSDimitry Andric           bool,
495cb14a3feSDimitry Andric           sizeof(_Fun) <= sizeof(__policy_storage)&& _LIBCPP_ALIGNOF(_Fun) <= _LIBCPP_ALIGNOF(__policy_storage) &&
496cb14a3feSDimitry Andric               is_trivially_copy_constructible<_Fun>::value && is_trivially_destructible<_Fun>::value> {};
497fe6060f1SDimitry Andric 
498fe6060f1SDimitry Andric // Policy contains information about how to copy, destroy, and move the
499fe6060f1SDimitry Andric // underlying functor. You can think of it as a vtable of sorts.
500cb14a3feSDimitry Andric struct __policy {
501fe6060f1SDimitry Andric   // Used to copy or destroy __large values. null for trivial objects.
502fe6060f1SDimitry Andric   void* (*const __clone)(const void*);
503fe6060f1SDimitry Andric   void (*const __destroy)(void*);
504fe6060f1SDimitry Andric 
505fe6060f1SDimitry Andric   // True if this is the null policy (no value).
506fe6060f1SDimitry Andric   const bool __is_null;
507fe6060f1SDimitry Andric 
508fe6060f1SDimitry Andric   // The target type. May be null if RTTI is disabled.
509fe6060f1SDimitry Andric   const std::type_info* const __type_info;
510fe6060f1SDimitry Andric 
511fe6060f1SDimitry Andric   // Returns a pointer to a static policy object suitable for the functor
512fe6060f1SDimitry Andric   // type.
513fe6060f1SDimitry Andric   template <typename _Fun>
514cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI static const __policy* __create() {
515fe6060f1SDimitry Andric     return __choose_policy<_Fun>(__use_small_storage<_Fun>());
516fe6060f1SDimitry Andric   }
517fe6060f1SDimitry Andric 
518cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI static const __policy* __create_empty() {
519*0fca6ea1SDimitry Andric     static constexpr __policy __policy = {
520cb14a3feSDimitry Andric         nullptr,
521cb14a3feSDimitry Andric         nullptr,
522fe6060f1SDimitry Andric         true,
5231ac55f4cSDimitry Andric #  ifndef _LIBCPP_HAS_NO_RTTI
524fe6060f1SDimitry Andric         &typeid(void)
525fe6060f1SDimitry Andric #  else
526fe6060f1SDimitry Andric         nullptr
527fe6060f1SDimitry Andric #  endif
528fe6060f1SDimitry Andric     };
52906c3fb27SDimitry Andric     return &__policy;
530fe6060f1SDimitry Andric   }
531fe6060f1SDimitry Andric 
532fe6060f1SDimitry Andric private:
53306c3fb27SDimitry Andric   template <typename _Fun>
534cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI static void* __large_clone(const void* __s) {
535fe6060f1SDimitry Andric     const _Fun* __f = static_cast<const _Fun*>(__s);
536fe6060f1SDimitry Andric     return __f->__clone();
537fe6060f1SDimitry Andric   }
538fe6060f1SDimitry Andric 
539fe6060f1SDimitry Andric   template <typename _Fun>
54006c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI static void __large_destroy(void* __s) {
541fe6060f1SDimitry Andric     _Fun::__destroy_and_delete(static_cast<_Fun*>(__s));
542fe6060f1SDimitry Andric   }
543fe6060f1SDimitry Andric 
544fe6060f1SDimitry Andric   template <typename _Fun>
545cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI static const __policy* __choose_policy(/* is_small = */ false_type) {
546*0fca6ea1SDimitry Andric     static constexpr __policy __policy = {
547cb14a3feSDimitry Andric         &__large_clone<_Fun>,
548cb14a3feSDimitry Andric         &__large_destroy<_Fun>,
549cb14a3feSDimitry Andric         false,
5501ac55f4cSDimitry Andric #  ifndef _LIBCPP_HAS_NO_RTTI
551fe6060f1SDimitry Andric         &typeid(typename _Fun::_Target)
552fe6060f1SDimitry Andric #  else
553fe6060f1SDimitry Andric         nullptr
554fe6060f1SDimitry Andric #  endif
555fe6060f1SDimitry Andric     };
55606c3fb27SDimitry Andric     return &__policy;
557fe6060f1SDimitry Andric   }
558fe6060f1SDimitry Andric 
559fe6060f1SDimitry Andric   template <typename _Fun>
560cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI static const __policy* __choose_policy(/* is_small = */ true_type) {
561*0fca6ea1SDimitry Andric     static constexpr __policy __policy = {
562cb14a3feSDimitry Andric         nullptr,
563cb14a3feSDimitry Andric         nullptr,
564cb14a3feSDimitry Andric         false,
5651ac55f4cSDimitry Andric #  ifndef _LIBCPP_HAS_NO_RTTI
566fe6060f1SDimitry Andric         &typeid(typename _Fun::_Target)
567fe6060f1SDimitry Andric #  else
568fe6060f1SDimitry Andric         nullptr
569fe6060f1SDimitry Andric #  endif
570fe6060f1SDimitry Andric     };
57106c3fb27SDimitry Andric     return &__policy;
572fe6060f1SDimitry Andric   }
573fe6060f1SDimitry Andric };
574fe6060f1SDimitry Andric 
575fe6060f1SDimitry Andric // Used to choose between perfect forwarding or pass-by-value. Pass-by-value is
576fe6060f1SDimitry Andric // faster for types that can be passed in registers.
577fe6060f1SDimitry Andric template <typename _Tp>
578bdd1243dSDimitry Andric using __fast_forward = __conditional_t<is_scalar<_Tp>::value, _Tp, _Tp&&>;
579fe6060f1SDimitry Andric 
580fe6060f1SDimitry Andric // __policy_invoker calls an instance of __alloc_func held in __policy_storage.
581fe6060f1SDimitry Andric 
582cb14a3feSDimitry Andric template <class _Fp>
583cb14a3feSDimitry Andric struct __policy_invoker;
584fe6060f1SDimitry Andric 
585fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
586cb14a3feSDimitry Andric struct __policy_invoker<_Rp(_ArgTypes...)> {
587cb14a3feSDimitry Andric   typedef _Rp (*__Call)(const __policy_storage*, __fast_forward<_ArgTypes>...);
588fe6060f1SDimitry Andric 
589fe6060f1SDimitry Andric   __Call __call_;
590fe6060f1SDimitry Andric 
591fe6060f1SDimitry Andric   // Creates an invoker that throws bad_function_call.
592cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __policy_invoker() : __call_(&__call_empty) {}
593fe6060f1SDimitry Andric 
594fe6060f1SDimitry Andric   // Creates an invoker that calls the given instance of __func.
595fe6060f1SDimitry Andric   template <typename _Fun>
596cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI static __policy_invoker __create() {
597fe6060f1SDimitry Andric     return __policy_invoker(&__call_impl<_Fun>);
598fe6060f1SDimitry Andric   }
599fe6060f1SDimitry Andric 
600fe6060f1SDimitry Andric private:
601cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit __policy_invoker(__Call __c) : __call_(__c) {}
602fe6060f1SDimitry Andric 
603cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI static _Rp __call_empty(const __policy_storage*, __fast_forward<_ArgTypes>...) {
604fe6060f1SDimitry Andric     __throw_bad_function_call();
605fe6060f1SDimitry Andric   }
606fe6060f1SDimitry Andric 
607fe6060f1SDimitry Andric   template <typename _Fun>
608cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI static _Rp __call_impl(const __policy_storage* __buf, __fast_forward<_ArgTypes>... __args) {
609cb14a3feSDimitry Andric     _Fun* __f = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value ? &__buf->__small : __buf->__large);
6105f757f3fSDimitry Andric     return (*__f)(std::forward<_ArgTypes>(__args)...);
611fe6060f1SDimitry Andric   }
612fe6060f1SDimitry Andric };
613fe6060f1SDimitry Andric 
614fe6060f1SDimitry Andric // __policy_func uses a __policy and __policy_invoker to create a type-erased,
615fe6060f1SDimitry Andric // copyable functor.
616fe6060f1SDimitry Andric 
617cb14a3feSDimitry Andric template <class _Fp>
618cb14a3feSDimitry Andric class __policy_func;
619fe6060f1SDimitry Andric 
620cb14a3feSDimitry Andric template <class _Rp, class... _ArgTypes>
621cb14a3feSDimitry Andric class __policy_func<_Rp(_ArgTypes...)> {
622fe6060f1SDimitry Andric   // Inline storage for small objects.
623fe6060f1SDimitry Andric   __policy_storage __buf_;
624fe6060f1SDimitry Andric 
625fe6060f1SDimitry Andric   // Calls the value stored in __buf_. This could technically be part of
626fe6060f1SDimitry Andric   // policy, but storing it here eliminates a level of indirection inside
627fe6060f1SDimitry Andric   // operator().
628fe6060f1SDimitry Andric   typedef __function::__policy_invoker<_Rp(_ArgTypes...)> __invoker;
629fe6060f1SDimitry Andric   __invoker __invoker_;
630fe6060f1SDimitry Andric 
631fe6060f1SDimitry Andric   // The policy that describes how to move / copy / destroy __buf_. Never
632fe6060f1SDimitry Andric   // null, even if the function is empty.
633fe6060f1SDimitry Andric   const __policy* __policy_;
634fe6060f1SDimitry Andric 
635fe6060f1SDimitry Andric public:
636cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __policy_func() : __policy_(__policy::__create_empty()) {}
637fe6060f1SDimitry Andric 
638fe6060f1SDimitry Andric   template <class _Fp, class _Alloc>
639cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __policy_func(_Fp&& __f, const _Alloc& __a) : __policy_(__policy::__create_empty()) {
640fe6060f1SDimitry Andric     typedef __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun;
641fe6060f1SDimitry Andric     typedef allocator_traits<_Alloc> __alloc_traits;
642bdd1243dSDimitry Andric     typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc;
643fe6060f1SDimitry Andric 
644cb14a3feSDimitry Andric     if (__function::__not_null(__f)) {
645fe6060f1SDimitry Andric       __invoker_ = __invoker::template __create<_Fun>();
646fe6060f1SDimitry Andric       __policy_  = __policy::__create<_Fun>();
647fe6060f1SDimitry Andric 
648fe6060f1SDimitry Andric       _FunAlloc __af(__a);
649cb14a3feSDimitry Andric       if (__use_small_storage<_Fun>()) {
650cb14a3feSDimitry Andric         ::new ((void*)&__buf_.__small) _Fun(std::move(__f), _Alloc(__af));
651cb14a3feSDimitry Andric       } else {
652fe6060f1SDimitry Andric         typedef __allocator_destructor<_FunAlloc> _Dp;
653fe6060f1SDimitry Andric         unique_ptr<_Fun, _Dp> __hold(__af.allocate(1), _Dp(__af, 1));
654cb14a3feSDimitry Andric         ::new ((void*)__hold.get()) _Fun(std::move(__f), _Alloc(__af));
655fe6060f1SDimitry Andric         __buf_.__large = __hold.release();
656fe6060f1SDimitry Andric       }
657fe6060f1SDimitry Andric     }
658fe6060f1SDimitry Andric   }
659fe6060f1SDimitry Andric 
6605f757f3fSDimitry Andric   template <class _Fp, __enable_if_t<!is_same<__decay_t<_Fp>, __policy_func>::value, int> = 0>
661cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit __policy_func(_Fp&& __f) : __policy_(__policy::__create_empty()) {
662fe6060f1SDimitry Andric     typedef __default_alloc_func<_Fp, _Rp(_ArgTypes...)> _Fun;
663fe6060f1SDimitry Andric 
664fe6060f1SDimitry Andric     if (__function::__not_null(__f)) {
665fe6060f1SDimitry Andric       __invoker_ = __invoker::template __create<_Fun>();
666fe6060f1SDimitry Andric       __policy_  = __policy::__create<_Fun>();
667fe6060f1SDimitry Andric       if (__use_small_storage<_Fun>()) {
6685f757f3fSDimitry Andric         ::new ((void*)&__buf_.__small) _Fun(std::move(__f));
669fe6060f1SDimitry Andric       } else {
670cb14a3feSDimitry Andric         __builtin_new_allocator::__holder_t __hold = __builtin_new_allocator::__allocate_type<_Fun>(1);
6715f757f3fSDimitry Andric         __buf_.__large                             = ::new ((void*)__hold.get()) _Fun(std::move(__f));
672fe6060f1SDimitry Andric         (void)__hold.release();
673fe6060f1SDimitry Andric       }
674fe6060f1SDimitry Andric     }
675fe6060f1SDimitry Andric   }
676fe6060f1SDimitry Andric 
677cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __policy_func(const __policy_func& __f)
678cb14a3feSDimitry Andric       : __buf_(__f.__buf_), __invoker_(__f.__invoker_), __policy_(__f.__policy_) {
679fe6060f1SDimitry Andric     if (__policy_->__clone)
680fe6060f1SDimitry Andric       __buf_.__large = __policy_->__clone(__f.__buf_.__large);
681fe6060f1SDimitry Andric   }
682fe6060f1SDimitry Andric 
683cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __policy_func(__policy_func&& __f)
684cb14a3feSDimitry Andric       : __buf_(__f.__buf_), __invoker_(__f.__invoker_), __policy_(__f.__policy_) {
685cb14a3feSDimitry Andric     if (__policy_->__destroy) {
686fe6060f1SDimitry Andric       __f.__policy_  = __policy::__create_empty();
687fe6060f1SDimitry Andric       __f.__invoker_ = __invoker();
688fe6060f1SDimitry Andric     }
689fe6060f1SDimitry Andric   }
690fe6060f1SDimitry Andric 
691cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI ~__policy_func() {
692fe6060f1SDimitry Andric     if (__policy_->__destroy)
693fe6060f1SDimitry Andric       __policy_->__destroy(__buf_.__large);
694fe6060f1SDimitry Andric   }
695fe6060f1SDimitry Andric 
696cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __policy_func& operator=(__policy_func&& __f) {
697fe6060f1SDimitry Andric     *this          = nullptr;
698fe6060f1SDimitry Andric     __buf_         = __f.__buf_;
699fe6060f1SDimitry Andric     __invoker_     = __f.__invoker_;
700fe6060f1SDimitry Andric     __policy_      = __f.__policy_;
701fe6060f1SDimitry Andric     __f.__policy_  = __policy::__create_empty();
702fe6060f1SDimitry Andric     __f.__invoker_ = __invoker();
703fe6060f1SDimitry Andric     return *this;
704fe6060f1SDimitry Andric   }
705fe6060f1SDimitry Andric 
706cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __policy_func& operator=(nullptr_t) {
707fe6060f1SDimitry Andric     const __policy* __p = __policy_;
708fe6060f1SDimitry Andric     __policy_           = __policy::__create_empty();
709fe6060f1SDimitry Andric     __invoker_          = __invoker();
710fe6060f1SDimitry Andric     if (__p->__destroy)
711fe6060f1SDimitry Andric       __p->__destroy(__buf_.__large);
712fe6060f1SDimitry Andric     return *this;
713fe6060f1SDimitry Andric   }
714fe6060f1SDimitry Andric 
715cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __args) const {
716cb14a3feSDimitry Andric     return __invoker_.__call_(std::addressof(__buf_), std::forward<_ArgTypes>(__args)...);
717fe6060f1SDimitry Andric   }
718fe6060f1SDimitry Andric 
719cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI void swap(__policy_func& __f) {
7205f757f3fSDimitry Andric     std::swap(__invoker_, __f.__invoker_);
7215f757f3fSDimitry Andric     std::swap(__policy_, __f.__policy_);
7225f757f3fSDimitry Andric     std::swap(__buf_, __f.__buf_);
723fe6060f1SDimitry Andric   }
724fe6060f1SDimitry Andric 
725cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return !__policy_->__is_null; }
726fe6060f1SDimitry Andric 
7271ac55f4cSDimitry Andric #  ifndef _LIBCPP_HAS_NO_RTTI
728cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT { return *__policy_->__type_info; }
729fe6060f1SDimitry Andric 
730fe6060f1SDimitry Andric   template <typename _Tp>
731cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT {
732fe6060f1SDimitry Andric     if (__policy_->__is_null || typeid(_Tp) != *__policy_->__type_info)
733fe6060f1SDimitry Andric       return nullptr;
734fe6060f1SDimitry Andric     if (__policy_->__clone) // Out of line storage.
735fe6060f1SDimitry Andric       return reinterpret_cast<const _Tp*>(__buf_.__large);
736fe6060f1SDimitry Andric     else
737fe6060f1SDimitry Andric       return reinterpret_cast<const _Tp*>(&__buf_.__small);
738fe6060f1SDimitry Andric   }
7391ac55f4cSDimitry Andric #  endif // _LIBCPP_HAS_NO_RTTI
740fe6060f1SDimitry Andric };
741fe6060f1SDimitry Andric 
742f3fd488fSDimitry Andric #  if defined(_LIBCPP_HAS_BLOCKS_RUNTIME)
743fe6060f1SDimitry Andric 
744fe6060f1SDimitry Andric extern "C" void* _Block_copy(const void*);
745fe6060f1SDimitry Andric extern "C" void _Block_release(const void*);
746fe6060f1SDimitry Andric 
747fe6060f1SDimitry Andric template <class _Rp1, class... _ArgTypes1, class _Alloc, class _Rp, class... _ArgTypes>
748cb14a3feSDimitry Andric class __func<_Rp1 (^)(_ArgTypes1...), _Alloc, _Rp(_ArgTypes...)> : public __base<_Rp(_ArgTypes...)> {
749fe6060f1SDimitry Andric   typedef _Rp1 (^__block_type)(_ArgTypes1...);
750fe6060f1SDimitry Andric   __block_type __f_;
751fe6060f1SDimitry Andric 
752fe6060f1SDimitry Andric public:
753cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit __func(__block_type const& __f)
754f3fd488fSDimitry Andric #    ifdef _LIBCPP_HAS_OBJC_ARC
755f3fd488fSDimitry Andric       : __f_(__f)
756f3fd488fSDimitry Andric #    else
757fe6060f1SDimitry Andric       : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr))
758f3fd488fSDimitry Andric #    endif
759cb14a3feSDimitry Andric   {
760cb14a3feSDimitry Andric   }
761fe6060f1SDimitry Andric 
762fe6060f1SDimitry Andric   // [TODO] add && to save on a retain
763fe6060f1SDimitry Andric 
764cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit __func(__block_type __f, const _Alloc& /* unused */)
765f3fd488fSDimitry Andric #    ifdef _LIBCPP_HAS_OBJC_ARC
766f3fd488fSDimitry Andric       : __f_(__f)
767f3fd488fSDimitry Andric #    else
768fe6060f1SDimitry Andric       : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr))
769f3fd488fSDimitry Andric #    endif
770cb14a3feSDimitry Andric   {
771cb14a3feSDimitry Andric   }
772fe6060f1SDimitry Andric 
773*0fca6ea1SDimitry Andric   _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual __base<_Rp(_ArgTypes...)>* __clone() const {
774cb14a3feSDimitry Andric     _LIBCPP_ASSERT_INTERNAL(
775cb14a3feSDimitry Andric         false,
776fe6060f1SDimitry Andric         "Block pointers are just pointers, so they should always fit into "
777fe6060f1SDimitry Andric         "std::function's small buffer optimization. This function should "
778fe6060f1SDimitry Andric         "never be invoked.");
779fe6060f1SDimitry Andric     return nullptr;
780fe6060f1SDimitry Andric   }
781fe6060f1SDimitry Andric 
782*0fca6ea1SDimitry Andric   _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __clone(__base<_Rp(_ArgTypes...)>* __p) const {
783*0fca6ea1SDimitry Andric     ::new ((void*)__p) __func(__f_);
784*0fca6ea1SDimitry Andric   }
785fe6060f1SDimitry Andric 
786*0fca6ea1SDimitry Andric   _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy() _NOEXCEPT {
787f3fd488fSDimitry Andric #    ifndef _LIBCPP_HAS_OBJC_ARC
788fe6060f1SDimitry Andric     if (__f_)
789fe6060f1SDimitry Andric       _Block_release(__f_);
790f3fd488fSDimitry Andric #    endif
791fe6060f1SDimitry Andric     __f_ = 0;
792fe6060f1SDimitry Andric   }
793fe6060f1SDimitry Andric 
794*0fca6ea1SDimitry Andric   _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate() _NOEXCEPT {
795cb14a3feSDimitry Andric     _LIBCPP_ASSERT_INTERNAL(
796cb14a3feSDimitry Andric         false,
797fe6060f1SDimitry Andric         "Block pointers are just pointers, so they should always fit into "
798fe6060f1SDimitry Andric         "std::function's small buffer optimization. This function should "
799fe6060f1SDimitry Andric         "never be invoked.");
800fe6060f1SDimitry Andric   }
801fe6060f1SDimitry Andric 
802*0fca6ea1SDimitry Andric   _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&&... __arg) {
803*0fca6ea1SDimitry Andric     return std::__invoke(__f_, std::forward<_ArgTypes>(__arg)...);
804*0fca6ea1SDimitry Andric   }
805fe6060f1SDimitry Andric 
8061ac55f4cSDimitry Andric #    ifndef _LIBCPP_HAS_NO_RTTI
807*0fca6ea1SDimitry Andric   _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const void* target(type_info const& __ti) const _NOEXCEPT {
808fe6060f1SDimitry Andric     if (__ti == typeid(__func::__block_type))
809fe6060f1SDimitry Andric       return &__f_;
810fe6060f1SDimitry Andric     return (const void*)nullptr;
811fe6060f1SDimitry Andric   }
812fe6060f1SDimitry Andric 
813*0fca6ea1SDimitry Andric   _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const std::type_info& target_type() const _NOEXCEPT {
814*0fca6ea1SDimitry Andric     return typeid(__func::__block_type);
815*0fca6ea1SDimitry Andric   }
8161ac55f4cSDimitry Andric #    endif // _LIBCPP_HAS_NO_RTTI
817fe6060f1SDimitry Andric };
818fe6060f1SDimitry Andric 
819f3fd488fSDimitry Andric #  endif // _LIBCPP_HAS_EXTENSION_BLOCKS
820fe6060f1SDimitry Andric 
8210eae32dcSDimitry Andric } // namespace __function
822fe6060f1SDimitry Andric 
823fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
824fe6060f1SDimitry Andric class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)>
825fe6060f1SDimitry Andric     : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>,
826cb14a3feSDimitry Andric       public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)> {
827fe6060f1SDimitry Andric #  ifndef _LIBCPP_ABI_OPTIMIZED_FUNCTION
828fe6060f1SDimitry Andric   typedef __function::__value_func<_Rp(_ArgTypes...)> __func;
829fe6060f1SDimitry Andric #  else
830fe6060f1SDimitry Andric   typedef __function::__policy_func<_Rp(_ArgTypes...)> __func;
831fe6060f1SDimitry Andric #  endif
832fe6060f1SDimitry Andric 
833fe6060f1SDimitry Andric   __func __f_;
834fe6060f1SDimitry Andric 
835cb14a3feSDimitry Andric   template <class _Fp,
836cb14a3feSDimitry Andric             bool = _And< _IsNotSame<__remove_cvref_t<_Fp>, function>, __invokable<_Fp, _ArgTypes...> >::value>
837fe6060f1SDimitry Andric   struct __callable;
838fe6060f1SDimitry Andric   template <class _Fp>
839cb14a3feSDimitry Andric   struct __callable<_Fp, true> {
840cb14a3feSDimitry Andric     static const bool value =
841cb14a3feSDimitry Andric         is_void<_Rp>::value || __is_core_convertible<typename __invoke_of<_Fp, _ArgTypes...>::type, _Rp>::value;
842fe6060f1SDimitry Andric   };
843fe6060f1SDimitry Andric   template <class _Fp>
844cb14a3feSDimitry Andric   struct __callable<_Fp, false> {
845fe6060f1SDimitry Andric     static const bool value = false;
846fe6060f1SDimitry Andric   };
847fe6060f1SDimitry Andric 
848fe6060f1SDimitry Andric   template <class _Fp>
8495f757f3fSDimitry Andric   using _EnableIfLValueCallable = __enable_if_t<__callable<_Fp&>::value>;
850cb14a3feSDimitry Andric 
851fe6060f1SDimitry Andric public:
852fe6060f1SDimitry Andric   typedef _Rp result_type;
853fe6060f1SDimitry Andric 
854fe6060f1SDimitry Andric   // construct/copy/destroy:
855cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI function() _NOEXCEPT {}
856cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI function(nullptr_t) _NOEXCEPT {}
85706c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI function(const function&);
85806c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI function(function&&) _NOEXCEPT;
859fe6060f1SDimitry Andric   template <class _Fp, class = _EnableIfLValueCallable<_Fp>>
86006c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI function(_Fp);
861fe6060f1SDimitry Andric 
862fe6060f1SDimitry Andric #  if _LIBCPP_STD_VER <= 14
863fe6060f1SDimitry Andric   template <class _Alloc>
864cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
865fe6060f1SDimitry Andric   template <class _Alloc>
866cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {}
867fe6060f1SDimitry Andric   template <class _Alloc>
86806c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, const function&);
869fe6060f1SDimitry Andric   template <class _Alloc>
87006c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, function&&);
871fe6060f1SDimitry Andric   template <class _Fp, class _Alloc, class = _EnableIfLValueCallable<_Fp>>
87206c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc& __a, _Fp __f);
873fe6060f1SDimitry Andric #  endif
874fe6060f1SDimitry Andric 
87506c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI function& operator=(const function&);
87606c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI function& operator=(function&&) _NOEXCEPT;
87706c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI function& operator=(nullptr_t) _NOEXCEPT;
87806c3fb27SDimitry Andric   template <class _Fp, class = _EnableIfLValueCallable<__decay_t<_Fp>>>
87906c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI function& operator=(_Fp&&);
880fe6060f1SDimitry Andric 
88106c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI ~function();
882fe6060f1SDimitry Andric 
883fe6060f1SDimitry Andric   // function modifiers:
88406c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI void swap(function&) _NOEXCEPT;
885fe6060f1SDimitry Andric 
886fe6060f1SDimitry Andric #  if _LIBCPP_STD_VER <= 14
887fe6060f1SDimitry Andric   template <class _Fp, class _Alloc>
888cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI void assign(_Fp&& __f, const _Alloc& __a) {
889cb14a3feSDimitry Andric     function(allocator_arg, __a, std::forward<_Fp>(__f)).swap(*this);
890cb14a3feSDimitry Andric   }
891fe6060f1SDimitry Andric #  endif
892fe6060f1SDimitry Andric 
893fe6060f1SDimitry Andric   // function capacity:
894cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return static_cast<bool>(__f_); }
895fe6060f1SDimitry Andric 
896fe6060f1SDimitry Andric   // deleted overloads close possible hole in the type system
897fe6060f1SDimitry Andric   template <class _R2, class... _ArgTypes2>
898fe6060f1SDimitry Andric   bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete;
89906c3fb27SDimitry Andric #  if _LIBCPP_STD_VER <= 17
900fe6060f1SDimitry Andric   template <class _R2, class... _ArgTypes2>
901fe6060f1SDimitry Andric   bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete;
90206c3fb27SDimitry Andric #  endif
903cb14a3feSDimitry Andric 
904fe6060f1SDimitry Andric public:
905fe6060f1SDimitry Andric   // function invocation:
90606c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes...) const;
907fe6060f1SDimitry Andric 
9081ac55f4cSDimitry Andric #  ifndef _LIBCPP_HAS_NO_RTTI
909fe6060f1SDimitry Andric   // function target access:
91006c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT;
91106c3fb27SDimitry Andric   template <typename _Tp>
91206c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp* target() _NOEXCEPT;
91306c3fb27SDimitry Andric   template <typename _Tp>
91406c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT;
9151ac55f4cSDimitry Andric #  endif // _LIBCPP_HAS_NO_RTTI
916fe6060f1SDimitry Andric };
917fe6060f1SDimitry Andric 
918349cc55cSDimitry Andric #  if _LIBCPP_STD_VER >= 17
919fe6060f1SDimitry Andric template <class _Rp, class... _Ap>
920fe6060f1SDimitry Andric function(_Rp (*)(_Ap...)) -> function<_Rp(_Ap...)>;
921fe6060f1SDimitry Andric 
922fe6060f1SDimitry Andric template <class _Fp, class _Stripped = typename __strip_signature<decltype(&_Fp::operator())>::type>
923fe6060f1SDimitry Andric function(_Fp) -> function<_Stripped>;
924349cc55cSDimitry Andric #  endif // _LIBCPP_STD_VER >= 17
925fe6060f1SDimitry Andric 
926fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
927fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(const function& __f) : __f_(__f.__f_) {}
928fe6060f1SDimitry Andric 
929fe6060f1SDimitry Andric #  if _LIBCPP_STD_VER <= 14
930fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
931fe6060f1SDimitry Andric template <class _Alloc>
932cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, const function& __f) : __f_(__f.__f_) {}
933fe6060f1SDimitry Andric #  endif
934fe6060f1SDimitry Andric 
935fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
936cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT : __f_(std::move(__f.__f_)) {}
937fe6060f1SDimitry Andric 
938fe6060f1SDimitry Andric #  if _LIBCPP_STD_VER <= 14
939fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
940fe6060f1SDimitry Andric template <class _Alloc>
941cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, function&& __f) : __f_(std::move(__f.__f_)) {}
942fe6060f1SDimitry Andric #  endif
943fe6060f1SDimitry Andric 
944fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
945fe6060f1SDimitry Andric template <class _Fp, class>
9465f757f3fSDimitry Andric function<_Rp(_ArgTypes...)>::function(_Fp __f) : __f_(std::move(__f)) {}
947fe6060f1SDimitry Andric 
948fe6060f1SDimitry Andric #  if _LIBCPP_STD_VER <= 14
949fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
950fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class>
951cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a, _Fp __f) : __f_(std::move(__f), __a) {}
952fe6060f1SDimitry Andric #  endif
953fe6060f1SDimitry Andric 
954fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
955cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(const function& __f) {
956fe6060f1SDimitry Andric   function(__f).swap(*this);
957fe6060f1SDimitry Andric   return *this;
958fe6060f1SDimitry Andric }
959fe6060f1SDimitry Andric 
960fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
961cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT {
9625f757f3fSDimitry Andric   __f_ = std::move(__f.__f_);
963fe6060f1SDimitry Andric   return *this;
964fe6060f1SDimitry Andric }
965fe6060f1SDimitry Andric 
966fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
967cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT {
968fe6060f1SDimitry Andric   __f_ = nullptr;
969fe6060f1SDimitry Andric   return *this;
970fe6060f1SDimitry Andric }
971fe6060f1SDimitry Andric 
972fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
973fe6060f1SDimitry Andric template <class _Fp, class>
974cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f) {
9755f757f3fSDimitry Andric   function(std::forward<_Fp>(__f)).swap(*this);
976fe6060f1SDimitry Andric   return *this;
977fe6060f1SDimitry Andric }
978fe6060f1SDimitry Andric 
979fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
980fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::~function() {}
981fe6060f1SDimitry Andric 
982fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
983cb14a3feSDimitry Andric void function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT {
984fe6060f1SDimitry Andric   __f_.swap(__f.__f_);
985fe6060f1SDimitry Andric }
986fe6060f1SDimitry Andric 
987fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
988cb14a3feSDimitry Andric _Rp function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const {
9895f757f3fSDimitry Andric   return __f_(std::forward<_ArgTypes>(__arg)...);
990fe6060f1SDimitry Andric }
991fe6060f1SDimitry Andric 
9921ac55f4cSDimitry Andric #  ifndef _LIBCPP_HAS_NO_RTTI
993fe6060f1SDimitry Andric 
994fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
995cb14a3feSDimitry Andric const std::type_info& function<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT {
996fe6060f1SDimitry Andric   return __f_.target_type();
997fe6060f1SDimitry Andric }
998fe6060f1SDimitry Andric 
999fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1000fe6060f1SDimitry Andric template <typename _Tp>
1001cb14a3feSDimitry Andric _Tp* function<_Rp(_ArgTypes...)>::target() _NOEXCEPT {
1002fe6060f1SDimitry Andric   return (_Tp*)(__f_.template target<_Tp>());
1003fe6060f1SDimitry Andric }
1004fe6060f1SDimitry Andric 
1005fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1006fe6060f1SDimitry Andric template <typename _Tp>
1007cb14a3feSDimitry Andric const _Tp* function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT {
1008fe6060f1SDimitry Andric   return __f_.template target<_Tp>();
1009fe6060f1SDimitry Andric }
1010fe6060f1SDimitry Andric 
10111ac55f4cSDimitry Andric #  endif // _LIBCPP_HAS_NO_RTTI
1012fe6060f1SDimitry Andric 
1013fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1014cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {
1015cb14a3feSDimitry Andric   return !__f;
1016cb14a3feSDimitry Andric }
1017fe6060f1SDimitry Andric 
101806c3fb27SDimitry Andric #  if _LIBCPP_STD_VER <= 17
101906c3fb27SDimitry Andric 
1020fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1021cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator==(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {
1022cb14a3feSDimitry Andric   return !__f;
1023cb14a3feSDimitry Andric }
1024fe6060f1SDimitry Andric 
1025fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1026cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {
1027cb14a3feSDimitry Andric   return (bool)__f;
1028cb14a3feSDimitry Andric }
1029fe6060f1SDimitry Andric 
1030fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1031cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {
1032cb14a3feSDimitry Andric   return (bool)__f;
1033cb14a3feSDimitry Andric }
1034fe6060f1SDimitry Andric 
103506c3fb27SDimitry Andric #  endif // _LIBCPP_STD_VER <= 17
103606c3fb27SDimitry Andric 
1037fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1038cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI void swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCEPT {
1039cb14a3feSDimitry Andric   return __x.swap(__y);
1040cb14a3feSDimitry Andric }
1041fe6060f1SDimitry Andric 
1042bdd1243dSDimitry Andric _LIBCPP_END_NAMESPACE_STD
1043fe6060f1SDimitry Andric 
104481ad6265SDimitry Andric #endif // _LIBCPP_CXX03_LANG
1045fe6060f1SDimitry Andric 
1046b3edf446SDimitry Andric _LIBCPP_POP_MACROS
1047b3edf446SDimitry Andric 
1048fe6060f1SDimitry Andric #endif // _LIBCPP___FUNCTIONAL_FUNCTION_H
1049