xref: /freebsd-src/contrib/llvm-project/libcxx/include/__functional/function.h (revision cb14a3fe5122c879eae1fb480ed7ce82a699ddb6)
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>
3106c3fb27SDimitry Andric #include <__type_traits/is_trivially_copy_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 
48bdd1243dSDimitry Andric #ifndef _LIBCPP_CXX03_LANG
49bdd1243dSDimitry Andric 
50fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
51fe6060f1SDimitry Andric 
52fe6060f1SDimitry Andric // bad_function_call
53fe6060f1SDimitry Andric 
5481ad6265SDimitry Andric _LIBCPP_DIAGNOSTIC_PUSH
5581ad6265SDimitry Andric _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables")
56*cb14a3feSDimitry Andric class _LIBCPP_EXPORTED_FROM_ABI bad_function_call : public exception {
57fe6060f1SDimitry Andric public:
585f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bad_function_call() _NOEXCEPT                                    = default;
595f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bad_function_call(const bad_function_call&) _NOEXCEPT            = default;
605f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bad_function_call& operator=(const bad_function_call&) _NOEXCEPT = default;
61349cc55cSDimitry Andric // Note that when a key function is not used, every translation unit that uses
62349cc55cSDimitry Andric // bad_function_call will end up containing a weak definition of the vtable and
63349cc55cSDimitry Andric // typeinfo.
64349cc55cSDimitry Andric #  ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
65bdd1243dSDimitry Andric   ~bad_function_call() _NOEXCEPT override;
66349cc55cSDimitry Andric #  else
6706c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~bad_function_call() _NOEXCEPT override {}
68349cc55cSDimitry Andric #  endif
69fe6060f1SDimitry Andric 
70349cc55cSDimitry Andric #  ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE
71bdd1243dSDimitry Andric   const char* what() const _NOEXCEPT override;
72fe6060f1SDimitry Andric #  endif
73fe6060f1SDimitry Andric };
7481ad6265SDimitry Andric _LIBCPP_DIAGNOSTIC_POP
75fe6060f1SDimitry Andric 
76*cb14a3feSDimitry Andric _LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void __throw_bad_function_call() {
7706c3fb27SDimitry Andric #  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
78fe6060f1SDimitry Andric   throw bad_function_call();
79fe6060f1SDimitry Andric #  else
8006c3fb27SDimitry Andric   _LIBCPP_VERBOSE_ABORT("bad_function_call was thrown in -fno-exceptions mode");
81fe6060f1SDimitry Andric #  endif
82fe6060f1SDimitry Andric }
83fe6060f1SDimitry Andric 
84*cb14a3feSDimitry Andric template <class _Fp>
85*cb14a3feSDimitry Andric class _LIBCPP_TEMPLATE_VIS function; // undefined
86fe6060f1SDimitry Andric 
87*cb14a3feSDimitry Andric namespace __function {
88fe6060f1SDimitry Andric 
89fe6060f1SDimitry Andric template <class _Rp>
90*cb14a3feSDimitry Andric struct __maybe_derive_from_unary_function {};
91fe6060f1SDimitry Andric 
92fe6060f1SDimitry Andric template <class _Rp, class _A1>
93*cb14a3feSDimitry Andric struct __maybe_derive_from_unary_function<_Rp(_A1)> : public __unary_function<_A1, _Rp> {};
94fe6060f1SDimitry Andric 
95fe6060f1SDimitry Andric template <class _Rp>
96*cb14a3feSDimitry Andric struct __maybe_derive_from_binary_function {};
97fe6060f1SDimitry Andric 
98fe6060f1SDimitry Andric template <class _Rp, class _A1, class _A2>
99*cb14a3feSDimitry Andric struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)> : public __binary_function<_A1, _A2, _Rp> {};
100fe6060f1SDimitry Andric 
101fe6060f1SDimitry Andric template <class _Fp>
102*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __not_null(_Fp const&) {
103*cb14a3feSDimitry Andric   return true;
104*cb14a3feSDimitry Andric }
105fe6060f1SDimitry Andric 
106fe6060f1SDimitry Andric template <class _Fp>
107*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __not_null(_Fp* __ptr) {
108*cb14a3feSDimitry Andric   return __ptr;
109*cb14a3feSDimitry Andric }
110fe6060f1SDimitry Andric 
111fe6060f1SDimitry Andric template <class _Ret, class _Class>
112*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __not_null(_Ret _Class::*__ptr) {
113*cb14a3feSDimitry Andric   return __ptr;
114*cb14a3feSDimitry Andric }
115fe6060f1SDimitry Andric 
116fe6060f1SDimitry Andric template <class _Fp>
117*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __not_null(function<_Fp> const& __f) {
118*cb14a3feSDimitry Andric   return !!__f;
119*cb14a3feSDimitry Andric }
120fe6060f1SDimitry Andric 
121fe6060f1SDimitry Andric #  ifdef _LIBCPP_HAS_EXTENSION_BLOCKS
122fe6060f1SDimitry Andric template <class _Rp, class... _Args>
123*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __not_null(_Rp (^__p)(_Args...)) {
124*cb14a3feSDimitry Andric   return __p;
125*cb14a3feSDimitry Andric }
126fe6060f1SDimitry Andric #  endif
127fe6060f1SDimitry Andric 
128fe6060f1SDimitry Andric } // namespace __function
129fe6060f1SDimitry Andric 
130fe6060f1SDimitry Andric namespace __function {
131fe6060f1SDimitry Andric 
132fe6060f1SDimitry Andric // __alloc_func holds a functor and an allocator.
133fe6060f1SDimitry Andric 
134*cb14a3feSDimitry Andric template <class _Fp, class _Ap, class _FB>
135*cb14a3feSDimitry Andric class __alloc_func;
136fe6060f1SDimitry Andric template <class _Fp, class _FB>
137fe6060f1SDimitry Andric class __default_alloc_func;
138fe6060f1SDimitry Andric 
139fe6060f1SDimitry Andric template <class _Fp, class _Ap, class _Rp, class... _ArgTypes>
140*cb14a3feSDimitry Andric class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)> {
141fe6060f1SDimitry Andric   __compressed_pair<_Fp, _Ap> __f_;
142fe6060f1SDimitry Andric 
143fe6060f1SDimitry Andric public:
144349cc55cSDimitry Andric   typedef _LIBCPP_NODEBUG _Fp _Target;
145349cc55cSDimitry Andric   typedef _LIBCPP_NODEBUG _Ap _Alloc;
146fe6060f1SDimitry Andric 
147*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI const _Target& __target() const { return __f_.first(); }
148fe6060f1SDimitry Andric 
149fe6060f1SDimitry Andric   // WIN32 APIs may define __allocator, so use __get_allocator instead.
150*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI const _Alloc& __get_allocator() const { return __f_.second(); }
151fe6060f1SDimitry Andric 
152*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit __alloc_func(_Target&& __f)
153*cb14a3feSDimitry Andric       : __f_(piecewise_construct, std::forward_as_tuple(std::move(__f)), std::forward_as_tuple()) {}
154fe6060f1SDimitry Andric 
155*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit __alloc_func(const _Target& __f, const _Alloc& __a)
156*cb14a3feSDimitry Andric       : __f_(piecewise_construct, std::forward_as_tuple(__f), std::forward_as_tuple(__a)) {}
157fe6060f1SDimitry Andric 
158*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit __alloc_func(const _Target& __f, _Alloc&& __a)
159*cb14a3feSDimitry Andric       : __f_(piecewise_construct, std::forward_as_tuple(__f), std::forward_as_tuple(std::move(__a))) {}
160fe6060f1SDimitry Andric 
161*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit __alloc_func(_Target&& __f, _Alloc&& __a)
162*cb14a3feSDimitry Andric       : __f_(piecewise_construct, std::forward_as_tuple(std::move(__f)), std::forward_as_tuple(std::move(__a))) {}
163fe6060f1SDimitry Andric 
164*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __arg) {
165fe6060f1SDimitry Andric     typedef __invoke_void_return_wrapper<_Rp> _Invoker;
166*cb14a3feSDimitry Andric     return _Invoker::__call(__f_.first(), std::forward<_ArgTypes>(__arg)...);
167fe6060f1SDimitry Andric   }
168fe6060f1SDimitry Andric 
169*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __alloc_func* __clone() const {
170fe6060f1SDimitry Andric     typedef allocator_traits<_Alloc> __alloc_traits;
171bdd1243dSDimitry Andric     typedef __rebind_alloc<__alloc_traits, __alloc_func> _AA;
172fe6060f1SDimitry Andric     _AA __a(__f_.second());
173fe6060f1SDimitry Andric     typedef __allocator_destructor<_AA> _Dp;
174fe6060f1SDimitry Andric     unique_ptr<__alloc_func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
175fe6060f1SDimitry Andric     ::new ((void*)__hold.get()) __alloc_func(__f_.first(), _Alloc(__a));
176fe6060f1SDimitry Andric     return __hold.release();
177fe6060f1SDimitry Andric   }
178fe6060f1SDimitry Andric 
179*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI void destroy() _NOEXCEPT { __f_.~__compressed_pair<_Target, _Alloc>(); }
180fe6060f1SDimitry Andric 
18106c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI static void __destroy_and_delete(__alloc_func* __f) {
182fe6060f1SDimitry Andric     typedef allocator_traits<_Alloc> __alloc_traits;
183bdd1243dSDimitry Andric     typedef __rebind_alloc<__alloc_traits, __alloc_func> _FunAlloc;
184fe6060f1SDimitry Andric     _FunAlloc __a(__f->__get_allocator());
185fe6060f1SDimitry Andric     __f->destroy();
186fe6060f1SDimitry Andric     __a.deallocate(__f, 1);
187fe6060f1SDimitry Andric   }
188fe6060f1SDimitry Andric };
189fe6060f1SDimitry Andric 
190fe6060f1SDimitry Andric template <class _Fp, class _Rp, class... _ArgTypes>
191fe6060f1SDimitry Andric class __default_alloc_func<_Fp, _Rp(_ArgTypes...)> {
192fe6060f1SDimitry Andric   _Fp __f_;
193fe6060f1SDimitry Andric 
194fe6060f1SDimitry Andric public:
195349cc55cSDimitry Andric   typedef _LIBCPP_NODEBUG _Fp _Target;
196fe6060f1SDimitry Andric 
197*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI const _Target& __target() const { return __f_; }
198fe6060f1SDimitry Andric 
199*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit __default_alloc_func(_Target&& __f) : __f_(std::move(__f)) {}
200fe6060f1SDimitry Andric 
201*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit __default_alloc_func(const _Target& __f) : __f_(__f) {}
202fe6060f1SDimitry Andric 
203*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __arg) {
204fe6060f1SDimitry Andric     typedef __invoke_void_return_wrapper<_Rp> _Invoker;
2055f757f3fSDimitry Andric     return _Invoker::__call(__f_, std::forward<_ArgTypes>(__arg)...);
206fe6060f1SDimitry Andric   }
207fe6060f1SDimitry Andric 
208*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __default_alloc_func* __clone() const {
209*cb14a3feSDimitry Andric     __builtin_new_allocator::__holder_t __hold = __builtin_new_allocator::__allocate_type<__default_alloc_func>(1);
210*cb14a3feSDimitry Andric     __default_alloc_func* __res                = ::new ((void*)__hold.get()) __default_alloc_func(__f_);
211fe6060f1SDimitry Andric     (void)__hold.release();
212fe6060f1SDimitry Andric     return __res;
213fe6060f1SDimitry Andric   }
214fe6060f1SDimitry Andric 
215*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI void destroy() _NOEXCEPT { __f_.~_Target(); }
216fe6060f1SDimitry Andric 
21706c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI static void __destroy_and_delete(__default_alloc_func* __f) {
218fe6060f1SDimitry Andric     __f->destroy();
219fe6060f1SDimitry Andric     __builtin_new_allocator::__deallocate_type<__default_alloc_func>(__f, 1);
220fe6060f1SDimitry Andric   }
221fe6060f1SDimitry Andric };
222fe6060f1SDimitry Andric 
223fe6060f1SDimitry Andric // __base provides an abstract interface for copyable functors.
224fe6060f1SDimitry Andric 
225*cb14a3feSDimitry Andric template <class _Fp>
226*cb14a3feSDimitry Andric class _LIBCPP_TEMPLATE_VIS __base;
227fe6060f1SDimitry Andric 
228fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
229*cb14a3feSDimitry Andric class __base<_Rp(_ArgTypes...)> {
230fe6060f1SDimitry Andric   __base(const __base&);
231fe6060f1SDimitry Andric   __base& operator=(const __base&);
232*cb14a3feSDimitry Andric 
233fe6060f1SDimitry Andric public:
2345f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __base() {}
235bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual ~__base() {}
236fe6060f1SDimitry Andric   virtual __base* __clone() const             = 0;
237fe6060f1SDimitry Andric   virtual void __clone(__base*) const         = 0;
238fe6060f1SDimitry Andric   virtual void destroy() _NOEXCEPT            = 0;
239fe6060f1SDimitry Andric   virtual void destroy_deallocate() _NOEXCEPT = 0;
240fe6060f1SDimitry Andric   virtual _Rp operator()(_ArgTypes&&...)      = 0;
2411ac55f4cSDimitry Andric #  ifndef _LIBCPP_HAS_NO_RTTI
242fe6060f1SDimitry Andric   virtual const void* target(const type_info&) const _NOEXCEPT = 0;
243fe6060f1SDimitry Andric   virtual const std::type_info& target_type() const _NOEXCEPT  = 0;
2441ac55f4cSDimitry Andric #  endif // _LIBCPP_HAS_NO_RTTI
245fe6060f1SDimitry Andric };
246fe6060f1SDimitry Andric 
247fe6060f1SDimitry Andric // __func implements __base for a given functor type.
248fe6060f1SDimitry Andric 
249*cb14a3feSDimitry Andric template <class _FD, class _Alloc, class _FB>
250*cb14a3feSDimitry Andric class __func;
251fe6060f1SDimitry Andric 
252fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
253*cb14a3feSDimitry Andric class __func<_Fp, _Alloc, _Rp(_ArgTypes...)> : public __base<_Rp(_ArgTypes...)> {
254fe6060f1SDimitry Andric   __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> __f_;
255*cb14a3feSDimitry Andric 
256fe6060f1SDimitry Andric public:
257*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit __func(_Fp&& __f) : __f_(std::move(__f)) {}
258fe6060f1SDimitry Andric 
259*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit __func(const _Fp& __f, const _Alloc& __a) : __f_(__f, __a) {}
260fe6060f1SDimitry Andric 
261*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit __func(const _Fp& __f, _Alloc&& __a) : __f_(__f, std::move(__a)) {}
262fe6060f1SDimitry Andric 
263*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit __func(_Fp&& __f, _Alloc&& __a) : __f_(std::move(__f), std::move(__a)) {}
264fe6060f1SDimitry Andric 
26506c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual __base<_Rp(_ArgTypes...)>* __clone() const;
26606c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __clone(__base<_Rp(_ArgTypes...)>*) const;
26706c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy() _NOEXCEPT;
26806c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate() _NOEXCEPT;
26906c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&&... __arg);
2701ac55f4cSDimitry Andric #  ifndef _LIBCPP_HAS_NO_RTTI
27106c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const void* target(const type_info&) const _NOEXCEPT;
27206c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const std::type_info& target_type() const _NOEXCEPT;
2731ac55f4cSDimitry Andric #  endif // _LIBCPP_HAS_NO_RTTI
274fe6060f1SDimitry Andric };
275fe6060f1SDimitry Andric 
276fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
277*cb14a3feSDimitry Andric __base<_Rp(_ArgTypes...)>* __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const {
278fe6060f1SDimitry Andric   typedef allocator_traits<_Alloc> __alloc_traits;
279bdd1243dSDimitry Andric   typedef __rebind_alloc<__alloc_traits, __func> _Ap;
280fe6060f1SDimitry Andric   _Ap __a(__f_.__get_allocator());
281fe6060f1SDimitry Andric   typedef __allocator_destructor<_Ap> _Dp;
282fe6060f1SDimitry Andric   unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
283fe6060f1SDimitry Andric   ::new ((void*)__hold.get()) __func(__f_.__target(), _Alloc(__a));
284fe6060f1SDimitry Andric   return __hold.release();
285fe6060f1SDimitry Andric }
286fe6060f1SDimitry Andric 
287fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
288*cb14a3feSDimitry Andric void __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const {
289fe6060f1SDimitry Andric   ::new ((void*)__p) __func(__f_.__target(), __f_.__get_allocator());
290fe6060f1SDimitry Andric }
291fe6060f1SDimitry Andric 
292fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
293*cb14a3feSDimitry Andric void __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() _NOEXCEPT {
294fe6060f1SDimitry Andric   __f_.destroy();
295fe6060f1SDimitry Andric }
296fe6060f1SDimitry Andric 
297fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
298*cb14a3feSDimitry Andric void __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT {
299fe6060f1SDimitry Andric   typedef allocator_traits<_Alloc> __alloc_traits;
300bdd1243dSDimitry Andric   typedef __rebind_alloc<__alloc_traits, __func> _Ap;
301fe6060f1SDimitry Andric   _Ap __a(__f_.__get_allocator());
302fe6060f1SDimitry Andric   __f_.destroy();
303fe6060f1SDimitry Andric   __a.deallocate(this, 1);
304fe6060f1SDimitry Andric }
305fe6060f1SDimitry Andric 
306fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
307*cb14a3feSDimitry Andric _Rp __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&&... __arg) {
3085f757f3fSDimitry Andric   return __f_(std::forward<_ArgTypes>(__arg)...);
309fe6060f1SDimitry Andric }
310fe6060f1SDimitry Andric 
3111ac55f4cSDimitry Andric #  ifndef _LIBCPP_HAS_NO_RTTI
312fe6060f1SDimitry Andric 
313fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
314*cb14a3feSDimitry Andric const void* __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT {
315fe6060f1SDimitry Andric   if (__ti == typeid(_Fp))
3165f757f3fSDimitry Andric     return std::addressof(__f_.__target());
317fe6060f1SDimitry Andric   return nullptr;
318fe6060f1SDimitry Andric }
319fe6060f1SDimitry Andric 
320fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
321*cb14a3feSDimitry Andric const std::type_info& __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT {
322fe6060f1SDimitry Andric   return typeid(_Fp);
323fe6060f1SDimitry Andric }
324fe6060f1SDimitry Andric 
3251ac55f4cSDimitry Andric #  endif // _LIBCPP_HAS_NO_RTTI
326fe6060f1SDimitry Andric 
327fe6060f1SDimitry Andric // __value_func creates a value-type from a __func.
328fe6060f1SDimitry Andric 
329*cb14a3feSDimitry Andric template <class _Fp>
330*cb14a3feSDimitry Andric class __value_func;
331fe6060f1SDimitry Andric 
332*cb14a3feSDimitry Andric template <class _Rp, class... _ArgTypes>
333*cb14a3feSDimitry Andric class __value_func<_Rp(_ArgTypes...)> {
334bdd1243dSDimitry Andric   _LIBCPP_SUPPRESS_DEPRECATED_PUSH
335fe6060f1SDimitry Andric   typename aligned_storage<3 * sizeof(void*)>::type __buf_;
336bdd1243dSDimitry Andric   _LIBCPP_SUPPRESS_DEPRECATED_POP
337fe6060f1SDimitry Andric 
338fe6060f1SDimitry Andric   typedef __base<_Rp(_ArgTypes...)> __func;
339fe6060f1SDimitry Andric   __func* __f_;
340fe6060f1SDimitry Andric 
341*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI static __func* __as_base(void* __p) { return reinterpret_cast<__func*>(__p); }
342fe6060f1SDimitry Andric 
343fe6060f1SDimitry Andric public:
344*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __value_func() _NOEXCEPT : __f_(nullptr) {}
345fe6060f1SDimitry Andric 
346fe6060f1SDimitry Andric   template <class _Fp, class _Alloc>
347*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __value_func(_Fp&& __f, const _Alloc& __a) : __f_(nullptr) {
348fe6060f1SDimitry Andric     typedef allocator_traits<_Alloc> __alloc_traits;
349fe6060f1SDimitry Andric     typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun;
350bdd1243dSDimitry Andric     typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc;
351fe6060f1SDimitry Andric 
352*cb14a3feSDimitry Andric     if (__function::__not_null(__f)) {
353fe6060f1SDimitry Andric       _FunAlloc __af(__a);
354*cb14a3feSDimitry Andric       if (sizeof(_Fun) <= sizeof(__buf_) && is_nothrow_copy_constructible<_Fp>::value &&
355*cb14a3feSDimitry Andric           is_nothrow_copy_constructible<_FunAlloc>::value) {
356*cb14a3feSDimitry Andric         __f_ = ::new ((void*)&__buf_) _Fun(std::move(__f), _Alloc(__af));
357*cb14a3feSDimitry Andric       } else {
358fe6060f1SDimitry Andric         typedef __allocator_destructor<_FunAlloc> _Dp;
359fe6060f1SDimitry Andric         unique_ptr<__func, _Dp> __hold(__af.allocate(1), _Dp(__af, 1));
3605f757f3fSDimitry Andric         ::new ((void*)__hold.get()) _Fun(std::move(__f), _Alloc(__a));
361fe6060f1SDimitry Andric         __f_ = __hold.release();
362fe6060f1SDimitry Andric       }
363fe6060f1SDimitry Andric     }
364fe6060f1SDimitry Andric   }
365fe6060f1SDimitry Andric 
3665f757f3fSDimitry Andric   template <class _Fp, __enable_if_t<!is_same<__decay_t<_Fp>, __value_func>::value, int> = 0>
367*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit __value_func(_Fp&& __f) : __value_func(std::forward<_Fp>(__f), allocator<_Fp>()) {}
368fe6060f1SDimitry Andric 
369*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __value_func(const __value_func& __f) {
370fe6060f1SDimitry Andric     if (__f.__f_ == nullptr)
371fe6060f1SDimitry Andric       __f_ = nullptr;
372*cb14a3feSDimitry Andric     else if ((void*)__f.__f_ == &__f.__buf_) {
373fe6060f1SDimitry Andric       __f_ = __as_base(&__buf_);
374fe6060f1SDimitry Andric       __f.__f_->__clone(__f_);
375*cb14a3feSDimitry Andric     } else
376fe6060f1SDimitry Andric       __f_ = __f.__f_->__clone();
377fe6060f1SDimitry Andric   }
378fe6060f1SDimitry Andric 
379*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __value_func(__value_func&& __f) _NOEXCEPT {
380fe6060f1SDimitry Andric     if (__f.__f_ == nullptr)
381fe6060f1SDimitry Andric       __f_ = nullptr;
382*cb14a3feSDimitry Andric     else if ((void*)__f.__f_ == &__f.__buf_) {
383fe6060f1SDimitry Andric       __f_ = __as_base(&__buf_);
384fe6060f1SDimitry Andric       __f.__f_->__clone(__f_);
385*cb14a3feSDimitry Andric     } else {
386fe6060f1SDimitry Andric       __f_     = __f.__f_;
387fe6060f1SDimitry Andric       __f.__f_ = nullptr;
388fe6060f1SDimitry Andric     }
389fe6060f1SDimitry Andric   }
390fe6060f1SDimitry Andric 
391*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI ~__value_func() {
392fe6060f1SDimitry Andric     if ((void*)__f_ == &__buf_)
393fe6060f1SDimitry Andric       __f_->destroy();
394fe6060f1SDimitry Andric     else if (__f_)
395fe6060f1SDimitry Andric       __f_->destroy_deallocate();
396fe6060f1SDimitry Andric   }
397fe6060f1SDimitry Andric 
398*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __value_func& operator=(__value_func&& __f) {
399fe6060f1SDimitry Andric     *this = nullptr;
400fe6060f1SDimitry Andric     if (__f.__f_ == nullptr)
401fe6060f1SDimitry Andric       __f_ = nullptr;
402*cb14a3feSDimitry Andric     else if ((void*)__f.__f_ == &__f.__buf_) {
403fe6060f1SDimitry Andric       __f_ = __as_base(&__buf_);
404fe6060f1SDimitry Andric       __f.__f_->__clone(__f_);
405*cb14a3feSDimitry Andric     } else {
406fe6060f1SDimitry Andric       __f_     = __f.__f_;
407fe6060f1SDimitry Andric       __f.__f_ = nullptr;
408fe6060f1SDimitry Andric     }
409fe6060f1SDimitry Andric     return *this;
410fe6060f1SDimitry Andric   }
411fe6060f1SDimitry Andric 
412*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __value_func& operator=(nullptr_t) {
413fe6060f1SDimitry Andric     __func* __f = __f_;
414fe6060f1SDimitry Andric     __f_        = nullptr;
415fe6060f1SDimitry Andric     if ((void*)__f == &__buf_)
416fe6060f1SDimitry Andric       __f->destroy();
417fe6060f1SDimitry Andric     else if (__f)
418fe6060f1SDimitry Andric       __f->destroy_deallocate();
419fe6060f1SDimitry Andric     return *this;
420fe6060f1SDimitry Andric   }
421fe6060f1SDimitry Andric 
422*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __args) const {
423fe6060f1SDimitry Andric     if (__f_ == nullptr)
424fe6060f1SDimitry Andric       __throw_bad_function_call();
4255f757f3fSDimitry Andric     return (*__f_)(std::forward<_ArgTypes>(__args)...);
426fe6060f1SDimitry Andric   }
427fe6060f1SDimitry Andric 
428*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI void swap(__value_func& __f) _NOEXCEPT {
429fe6060f1SDimitry Andric     if (&__f == this)
430fe6060f1SDimitry Andric       return;
431*cb14a3feSDimitry Andric     if ((void*)__f_ == &__buf_ && (void*)__f.__f_ == &__f.__buf_) {
432bdd1243dSDimitry Andric       _LIBCPP_SUPPRESS_DEPRECATED_PUSH
433fe6060f1SDimitry Andric       typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
434bdd1243dSDimitry Andric       _LIBCPP_SUPPRESS_DEPRECATED_POP
435fe6060f1SDimitry Andric       __func* __t = __as_base(&__tempbuf);
436fe6060f1SDimitry Andric       __f_->__clone(__t);
437fe6060f1SDimitry Andric       __f_->destroy();
438fe6060f1SDimitry Andric       __f_ = nullptr;
439fe6060f1SDimitry Andric       __f.__f_->__clone(__as_base(&__buf_));
440fe6060f1SDimitry Andric       __f.__f_->destroy();
441fe6060f1SDimitry Andric       __f.__f_ = nullptr;
442fe6060f1SDimitry Andric       __f_     = __as_base(&__buf_);
443fe6060f1SDimitry Andric       __t->__clone(__as_base(&__f.__buf_));
444fe6060f1SDimitry Andric       __t->destroy();
445fe6060f1SDimitry Andric       __f.__f_ = __as_base(&__f.__buf_);
446*cb14a3feSDimitry Andric     } else if ((void*)__f_ == &__buf_) {
447fe6060f1SDimitry Andric       __f_->__clone(__as_base(&__f.__buf_));
448fe6060f1SDimitry Andric       __f_->destroy();
449fe6060f1SDimitry Andric       __f_     = __f.__f_;
450fe6060f1SDimitry Andric       __f.__f_ = __as_base(&__f.__buf_);
451*cb14a3feSDimitry Andric     } else if ((void*)__f.__f_ == &__f.__buf_) {
452fe6060f1SDimitry Andric       __f.__f_->__clone(__as_base(&__buf_));
453fe6060f1SDimitry Andric       __f.__f_->destroy();
454fe6060f1SDimitry Andric       __f.__f_ = __f_;
455fe6060f1SDimitry Andric       __f_     = __as_base(&__buf_);
456*cb14a3feSDimitry Andric     } else
4575f757f3fSDimitry Andric       std::swap(__f_, __f.__f_);
458fe6060f1SDimitry Andric   }
459fe6060f1SDimitry Andric 
460*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __f_ != nullptr; }
461fe6060f1SDimitry Andric 
4621ac55f4cSDimitry Andric #  ifndef _LIBCPP_HAS_NO_RTTI
463*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT {
464fe6060f1SDimitry Andric     if (__f_ == nullptr)
465fe6060f1SDimitry Andric       return typeid(void);
466fe6060f1SDimitry Andric     return __f_->target_type();
467fe6060f1SDimitry Andric   }
468fe6060f1SDimitry Andric 
469fe6060f1SDimitry Andric   template <typename _Tp>
470*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT {
471fe6060f1SDimitry Andric     if (__f_ == nullptr)
472fe6060f1SDimitry Andric       return nullptr;
473fe6060f1SDimitry Andric     return (const _Tp*)__f_->target(typeid(_Tp));
474fe6060f1SDimitry Andric   }
4751ac55f4cSDimitry Andric #  endif // _LIBCPP_HAS_NO_RTTI
476fe6060f1SDimitry Andric };
477fe6060f1SDimitry Andric 
478fe6060f1SDimitry Andric // Storage for a functor object, to be used with __policy to manage copy and
479fe6060f1SDimitry Andric // destruction.
480*cb14a3feSDimitry Andric union __policy_storage {
481fe6060f1SDimitry Andric   mutable char __small[sizeof(void*) * 2];
482fe6060f1SDimitry Andric   void* __large;
483fe6060f1SDimitry Andric };
484fe6060f1SDimitry Andric 
485fe6060f1SDimitry Andric // True if _Fun can safely be held in __policy_storage.__small.
486fe6060f1SDimitry Andric template <typename _Fun>
487fe6060f1SDimitry Andric struct __use_small_storage
488fe6060f1SDimitry Andric     : public integral_constant<
489*cb14a3feSDimitry Andric           bool,
490*cb14a3feSDimitry Andric           sizeof(_Fun) <= sizeof(__policy_storage)&& _LIBCPP_ALIGNOF(_Fun) <= _LIBCPP_ALIGNOF(__policy_storage) &&
491*cb14a3feSDimitry Andric               is_trivially_copy_constructible<_Fun>::value && is_trivially_destructible<_Fun>::value> {};
492fe6060f1SDimitry Andric 
493fe6060f1SDimitry Andric // Policy contains information about how to copy, destroy, and move the
494fe6060f1SDimitry Andric // underlying functor. You can think of it as a vtable of sorts.
495*cb14a3feSDimitry Andric struct __policy {
496fe6060f1SDimitry Andric   // Used to copy or destroy __large values. null for trivial objects.
497fe6060f1SDimitry Andric   void* (*const __clone)(const void*);
498fe6060f1SDimitry Andric   void (*const __destroy)(void*);
499fe6060f1SDimitry Andric 
500fe6060f1SDimitry Andric   // True if this is the null policy (no value).
501fe6060f1SDimitry Andric   const bool __is_null;
502fe6060f1SDimitry Andric 
503fe6060f1SDimitry Andric   // The target type. May be null if RTTI is disabled.
504fe6060f1SDimitry Andric   const std::type_info* const __type_info;
505fe6060f1SDimitry Andric 
506fe6060f1SDimitry Andric   // Returns a pointer to a static policy object suitable for the functor
507fe6060f1SDimitry Andric   // type.
508fe6060f1SDimitry Andric   template <typename _Fun>
509*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI static const __policy* __create() {
510fe6060f1SDimitry Andric     return __choose_policy<_Fun>(__use_small_storage<_Fun>());
511fe6060f1SDimitry Andric   }
512fe6060f1SDimitry Andric 
513*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI static const __policy* __create_empty() {
514*cb14a3feSDimitry Andric     static const _LIBCPP_CONSTEXPR __policy __policy = {
515*cb14a3feSDimitry Andric         nullptr,
516*cb14a3feSDimitry Andric         nullptr,
517fe6060f1SDimitry Andric         true,
5181ac55f4cSDimitry Andric #  ifndef _LIBCPP_HAS_NO_RTTI
519fe6060f1SDimitry Andric         &typeid(void)
520fe6060f1SDimitry Andric #  else
521fe6060f1SDimitry Andric         nullptr
522fe6060f1SDimitry Andric #  endif
523fe6060f1SDimitry Andric     };
52406c3fb27SDimitry Andric     return &__policy;
525fe6060f1SDimitry Andric   }
526fe6060f1SDimitry Andric 
527fe6060f1SDimitry Andric private:
52806c3fb27SDimitry Andric   template <typename _Fun>
529*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI static void* __large_clone(const void* __s) {
530fe6060f1SDimitry Andric     const _Fun* __f = static_cast<const _Fun*>(__s);
531fe6060f1SDimitry Andric     return __f->__clone();
532fe6060f1SDimitry Andric   }
533fe6060f1SDimitry Andric 
534fe6060f1SDimitry Andric   template <typename _Fun>
53506c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI static void __large_destroy(void* __s) {
536fe6060f1SDimitry Andric     _Fun::__destroy_and_delete(static_cast<_Fun*>(__s));
537fe6060f1SDimitry Andric   }
538fe6060f1SDimitry Andric 
539fe6060f1SDimitry Andric   template <typename _Fun>
540*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI static const __policy* __choose_policy(/* is_small = */ false_type) {
54106c3fb27SDimitry Andric     static const _LIBCPP_CONSTEXPR __policy __policy = {
542*cb14a3feSDimitry Andric         &__large_clone<_Fun>,
543*cb14a3feSDimitry Andric         &__large_destroy<_Fun>,
544*cb14a3feSDimitry Andric         false,
5451ac55f4cSDimitry Andric #  ifndef _LIBCPP_HAS_NO_RTTI
546fe6060f1SDimitry Andric         &typeid(typename _Fun::_Target)
547fe6060f1SDimitry Andric #  else
548fe6060f1SDimitry Andric         nullptr
549fe6060f1SDimitry Andric #  endif
550fe6060f1SDimitry Andric     };
55106c3fb27SDimitry Andric     return &__policy;
552fe6060f1SDimitry Andric   }
553fe6060f1SDimitry Andric 
554fe6060f1SDimitry Andric   template <typename _Fun>
555*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI static const __policy* __choose_policy(/* is_small = */ true_type) {
55606c3fb27SDimitry Andric     static const _LIBCPP_CONSTEXPR __policy __policy = {
557*cb14a3feSDimitry Andric         nullptr,
558*cb14a3feSDimitry Andric         nullptr,
559*cb14a3feSDimitry Andric         false,
5601ac55f4cSDimitry Andric #  ifndef _LIBCPP_HAS_NO_RTTI
561fe6060f1SDimitry Andric         &typeid(typename _Fun::_Target)
562fe6060f1SDimitry Andric #  else
563fe6060f1SDimitry Andric         nullptr
564fe6060f1SDimitry Andric #  endif
565fe6060f1SDimitry Andric     };
56606c3fb27SDimitry Andric     return &__policy;
567fe6060f1SDimitry Andric   }
568fe6060f1SDimitry Andric };
569fe6060f1SDimitry Andric 
570fe6060f1SDimitry Andric // Used to choose between perfect forwarding or pass-by-value. Pass-by-value is
571fe6060f1SDimitry Andric // faster for types that can be passed in registers.
572fe6060f1SDimitry Andric template <typename _Tp>
573bdd1243dSDimitry Andric using __fast_forward = __conditional_t<is_scalar<_Tp>::value, _Tp, _Tp&&>;
574fe6060f1SDimitry Andric 
575fe6060f1SDimitry Andric // __policy_invoker calls an instance of __alloc_func held in __policy_storage.
576fe6060f1SDimitry Andric 
577*cb14a3feSDimitry Andric template <class _Fp>
578*cb14a3feSDimitry Andric struct __policy_invoker;
579fe6060f1SDimitry Andric 
580fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
581*cb14a3feSDimitry Andric struct __policy_invoker<_Rp(_ArgTypes...)> {
582*cb14a3feSDimitry Andric   typedef _Rp (*__Call)(const __policy_storage*, __fast_forward<_ArgTypes>...);
583fe6060f1SDimitry Andric 
584fe6060f1SDimitry Andric   __Call __call_;
585fe6060f1SDimitry Andric 
586fe6060f1SDimitry Andric   // Creates an invoker that throws bad_function_call.
587*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __policy_invoker() : __call_(&__call_empty) {}
588fe6060f1SDimitry Andric 
589fe6060f1SDimitry Andric   // Creates an invoker that calls the given instance of __func.
590fe6060f1SDimitry Andric   template <typename _Fun>
591*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI static __policy_invoker __create() {
592fe6060f1SDimitry Andric     return __policy_invoker(&__call_impl<_Fun>);
593fe6060f1SDimitry Andric   }
594fe6060f1SDimitry Andric 
595fe6060f1SDimitry Andric private:
596*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit __policy_invoker(__Call __c) : __call_(__c) {}
597fe6060f1SDimitry Andric 
598*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI static _Rp __call_empty(const __policy_storage*, __fast_forward<_ArgTypes>...) {
599fe6060f1SDimitry Andric     __throw_bad_function_call();
600fe6060f1SDimitry Andric   }
601fe6060f1SDimitry Andric 
602fe6060f1SDimitry Andric   template <typename _Fun>
603*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI static _Rp __call_impl(const __policy_storage* __buf, __fast_forward<_ArgTypes>... __args) {
604*cb14a3feSDimitry Andric     _Fun* __f = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value ? &__buf->__small : __buf->__large);
6055f757f3fSDimitry Andric     return (*__f)(std::forward<_ArgTypes>(__args)...);
606fe6060f1SDimitry Andric   }
607fe6060f1SDimitry Andric };
608fe6060f1SDimitry Andric 
609fe6060f1SDimitry Andric // __policy_func uses a __policy and __policy_invoker to create a type-erased,
610fe6060f1SDimitry Andric // copyable functor.
611fe6060f1SDimitry Andric 
612*cb14a3feSDimitry Andric template <class _Fp>
613*cb14a3feSDimitry Andric class __policy_func;
614fe6060f1SDimitry Andric 
615*cb14a3feSDimitry Andric template <class _Rp, class... _ArgTypes>
616*cb14a3feSDimitry Andric class __policy_func<_Rp(_ArgTypes...)> {
617fe6060f1SDimitry Andric   // Inline storage for small objects.
618fe6060f1SDimitry Andric   __policy_storage __buf_;
619fe6060f1SDimitry Andric 
620fe6060f1SDimitry Andric   // Calls the value stored in __buf_. This could technically be part of
621fe6060f1SDimitry Andric   // policy, but storing it here eliminates a level of indirection inside
622fe6060f1SDimitry Andric   // operator().
623fe6060f1SDimitry Andric   typedef __function::__policy_invoker<_Rp(_ArgTypes...)> __invoker;
624fe6060f1SDimitry Andric   __invoker __invoker_;
625fe6060f1SDimitry Andric 
626fe6060f1SDimitry Andric   // The policy that describes how to move / copy / destroy __buf_. Never
627fe6060f1SDimitry Andric   // null, even if the function is empty.
628fe6060f1SDimitry Andric   const __policy* __policy_;
629fe6060f1SDimitry Andric 
630fe6060f1SDimitry Andric public:
631*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __policy_func() : __policy_(__policy::__create_empty()) {}
632fe6060f1SDimitry Andric 
633fe6060f1SDimitry Andric   template <class _Fp, class _Alloc>
634*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __policy_func(_Fp&& __f, const _Alloc& __a) : __policy_(__policy::__create_empty()) {
635fe6060f1SDimitry Andric     typedef __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun;
636fe6060f1SDimitry Andric     typedef allocator_traits<_Alloc> __alloc_traits;
637bdd1243dSDimitry Andric     typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc;
638fe6060f1SDimitry Andric 
639*cb14a3feSDimitry Andric     if (__function::__not_null(__f)) {
640fe6060f1SDimitry Andric       __invoker_ = __invoker::template __create<_Fun>();
641fe6060f1SDimitry Andric       __policy_  = __policy::__create<_Fun>();
642fe6060f1SDimitry Andric 
643fe6060f1SDimitry Andric       _FunAlloc __af(__a);
644*cb14a3feSDimitry Andric       if (__use_small_storage<_Fun>()) {
645*cb14a3feSDimitry Andric         ::new ((void*)&__buf_.__small) _Fun(std::move(__f), _Alloc(__af));
646*cb14a3feSDimitry Andric       } else {
647fe6060f1SDimitry Andric         typedef __allocator_destructor<_FunAlloc> _Dp;
648fe6060f1SDimitry Andric         unique_ptr<_Fun, _Dp> __hold(__af.allocate(1), _Dp(__af, 1));
649*cb14a3feSDimitry Andric         ::new ((void*)__hold.get()) _Fun(std::move(__f), _Alloc(__af));
650fe6060f1SDimitry Andric         __buf_.__large = __hold.release();
651fe6060f1SDimitry Andric       }
652fe6060f1SDimitry Andric     }
653fe6060f1SDimitry Andric   }
654fe6060f1SDimitry Andric 
6555f757f3fSDimitry Andric   template <class _Fp, __enable_if_t<!is_same<__decay_t<_Fp>, __policy_func>::value, int> = 0>
656*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit __policy_func(_Fp&& __f) : __policy_(__policy::__create_empty()) {
657fe6060f1SDimitry Andric     typedef __default_alloc_func<_Fp, _Rp(_ArgTypes...)> _Fun;
658fe6060f1SDimitry Andric 
659fe6060f1SDimitry Andric     if (__function::__not_null(__f)) {
660fe6060f1SDimitry Andric       __invoker_ = __invoker::template __create<_Fun>();
661fe6060f1SDimitry Andric       __policy_  = __policy::__create<_Fun>();
662fe6060f1SDimitry Andric       if (__use_small_storage<_Fun>()) {
6635f757f3fSDimitry Andric         ::new ((void*)&__buf_.__small) _Fun(std::move(__f));
664fe6060f1SDimitry Andric       } else {
665*cb14a3feSDimitry Andric         __builtin_new_allocator::__holder_t __hold = __builtin_new_allocator::__allocate_type<_Fun>(1);
6665f757f3fSDimitry Andric         __buf_.__large                             = ::new ((void*)__hold.get()) _Fun(std::move(__f));
667fe6060f1SDimitry Andric         (void)__hold.release();
668fe6060f1SDimitry Andric       }
669fe6060f1SDimitry Andric     }
670fe6060f1SDimitry Andric   }
671fe6060f1SDimitry Andric 
672*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __policy_func(const __policy_func& __f)
673*cb14a3feSDimitry Andric       : __buf_(__f.__buf_), __invoker_(__f.__invoker_), __policy_(__f.__policy_) {
674fe6060f1SDimitry Andric     if (__policy_->__clone)
675fe6060f1SDimitry Andric       __buf_.__large = __policy_->__clone(__f.__buf_.__large);
676fe6060f1SDimitry Andric   }
677fe6060f1SDimitry Andric 
678*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __policy_func(__policy_func&& __f)
679*cb14a3feSDimitry Andric       : __buf_(__f.__buf_), __invoker_(__f.__invoker_), __policy_(__f.__policy_) {
680*cb14a3feSDimitry Andric     if (__policy_->__destroy) {
681fe6060f1SDimitry Andric       __f.__policy_  = __policy::__create_empty();
682fe6060f1SDimitry Andric       __f.__invoker_ = __invoker();
683fe6060f1SDimitry Andric     }
684fe6060f1SDimitry Andric   }
685fe6060f1SDimitry Andric 
686*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI ~__policy_func() {
687fe6060f1SDimitry Andric     if (__policy_->__destroy)
688fe6060f1SDimitry Andric       __policy_->__destroy(__buf_.__large);
689fe6060f1SDimitry Andric   }
690fe6060f1SDimitry Andric 
691*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __policy_func& operator=(__policy_func&& __f) {
692fe6060f1SDimitry Andric     *this          = nullptr;
693fe6060f1SDimitry Andric     __buf_         = __f.__buf_;
694fe6060f1SDimitry Andric     __invoker_     = __f.__invoker_;
695fe6060f1SDimitry Andric     __policy_      = __f.__policy_;
696fe6060f1SDimitry Andric     __f.__policy_  = __policy::__create_empty();
697fe6060f1SDimitry Andric     __f.__invoker_ = __invoker();
698fe6060f1SDimitry Andric     return *this;
699fe6060f1SDimitry Andric   }
700fe6060f1SDimitry Andric 
701*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI __policy_func& operator=(nullptr_t) {
702fe6060f1SDimitry Andric     const __policy* __p = __policy_;
703fe6060f1SDimitry Andric     __policy_           = __policy::__create_empty();
704fe6060f1SDimitry Andric     __invoker_          = __invoker();
705fe6060f1SDimitry Andric     if (__p->__destroy)
706fe6060f1SDimitry Andric       __p->__destroy(__buf_.__large);
707fe6060f1SDimitry Andric     return *this;
708fe6060f1SDimitry Andric   }
709fe6060f1SDimitry Andric 
710*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __args) const {
711*cb14a3feSDimitry Andric     return __invoker_.__call_(std::addressof(__buf_), std::forward<_ArgTypes>(__args)...);
712fe6060f1SDimitry Andric   }
713fe6060f1SDimitry Andric 
714*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI void swap(__policy_func& __f) {
7155f757f3fSDimitry Andric     std::swap(__invoker_, __f.__invoker_);
7165f757f3fSDimitry Andric     std::swap(__policy_, __f.__policy_);
7175f757f3fSDimitry Andric     std::swap(__buf_, __f.__buf_);
718fe6060f1SDimitry Andric   }
719fe6060f1SDimitry Andric 
720*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return !__policy_->__is_null; }
721fe6060f1SDimitry Andric 
7221ac55f4cSDimitry Andric #  ifndef _LIBCPP_HAS_NO_RTTI
723*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT { return *__policy_->__type_info; }
724fe6060f1SDimitry Andric 
725fe6060f1SDimitry Andric   template <typename _Tp>
726*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT {
727fe6060f1SDimitry Andric     if (__policy_->__is_null || typeid(_Tp) != *__policy_->__type_info)
728fe6060f1SDimitry Andric       return nullptr;
729fe6060f1SDimitry Andric     if (__policy_->__clone) // Out of line storage.
730fe6060f1SDimitry Andric       return reinterpret_cast<const _Tp*>(__buf_.__large);
731fe6060f1SDimitry Andric     else
732fe6060f1SDimitry Andric       return reinterpret_cast<const _Tp*>(&__buf_.__small);
733fe6060f1SDimitry Andric   }
7341ac55f4cSDimitry Andric #  endif // _LIBCPP_HAS_NO_RTTI
735fe6060f1SDimitry Andric };
736fe6060f1SDimitry Andric 
737f3fd488fSDimitry Andric #  if defined(_LIBCPP_HAS_BLOCKS_RUNTIME)
738fe6060f1SDimitry Andric 
739fe6060f1SDimitry Andric extern "C" void* _Block_copy(const void*);
740fe6060f1SDimitry Andric extern "C" void _Block_release(const void*);
741fe6060f1SDimitry Andric 
742fe6060f1SDimitry Andric template <class _Rp1, class... _ArgTypes1, class _Alloc, class _Rp, class... _ArgTypes>
743*cb14a3feSDimitry Andric class __func<_Rp1 (^)(_ArgTypes1...), _Alloc, _Rp(_ArgTypes...)> : public __base<_Rp(_ArgTypes...)> {
744fe6060f1SDimitry Andric   typedef _Rp1 (^__block_type)(_ArgTypes1...);
745fe6060f1SDimitry Andric   __block_type __f_;
746fe6060f1SDimitry Andric 
747fe6060f1SDimitry Andric public:
748*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit __func(__block_type const& __f)
749f3fd488fSDimitry Andric #    ifdef _LIBCPP_HAS_OBJC_ARC
750f3fd488fSDimitry Andric       : __f_(__f)
751f3fd488fSDimitry Andric #    else
752fe6060f1SDimitry Andric       : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr))
753f3fd488fSDimitry Andric #    endif
754*cb14a3feSDimitry Andric   {
755*cb14a3feSDimitry Andric   }
756fe6060f1SDimitry Andric 
757fe6060f1SDimitry Andric   // [TODO] add && to save on a retain
758fe6060f1SDimitry Andric 
759*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit __func(__block_type __f, const _Alloc& /* unused */)
760f3fd488fSDimitry Andric #    ifdef _LIBCPP_HAS_OBJC_ARC
761f3fd488fSDimitry Andric       : __f_(__f)
762f3fd488fSDimitry Andric #    else
763fe6060f1SDimitry Andric       : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr))
764f3fd488fSDimitry Andric #    endif
765*cb14a3feSDimitry Andric   {
766*cb14a3feSDimitry Andric   }
767fe6060f1SDimitry Andric 
768fe6060f1SDimitry Andric   virtual __base<_Rp(_ArgTypes...)>* __clone() const {
769*cb14a3feSDimitry Andric     _LIBCPP_ASSERT_INTERNAL(
770*cb14a3feSDimitry Andric         false,
771fe6060f1SDimitry Andric         "Block pointers are just pointers, so they should always fit into "
772fe6060f1SDimitry Andric         "std::function's small buffer optimization. This function should "
773fe6060f1SDimitry Andric         "never be invoked.");
774fe6060f1SDimitry Andric     return nullptr;
775fe6060f1SDimitry Andric   }
776fe6060f1SDimitry Andric 
777*cb14a3feSDimitry Andric   virtual void __clone(__base<_Rp(_ArgTypes...)>* __p) const { ::new ((void*)__p) __func(__f_); }
778fe6060f1SDimitry Andric 
779fe6060f1SDimitry Andric   virtual void destroy() _NOEXCEPT {
780f3fd488fSDimitry Andric #    ifndef _LIBCPP_HAS_OBJC_ARC
781fe6060f1SDimitry Andric     if (__f_)
782fe6060f1SDimitry Andric       _Block_release(__f_);
783f3fd488fSDimitry Andric #    endif
784fe6060f1SDimitry Andric     __f_ = 0;
785fe6060f1SDimitry Andric   }
786fe6060f1SDimitry Andric 
787fe6060f1SDimitry Andric   virtual void destroy_deallocate() _NOEXCEPT {
788*cb14a3feSDimitry Andric     _LIBCPP_ASSERT_INTERNAL(
789*cb14a3feSDimitry Andric         false,
790fe6060f1SDimitry Andric         "Block pointers are just pointers, so they should always fit into "
791fe6060f1SDimitry Andric         "std::function's small buffer optimization. This function should "
792fe6060f1SDimitry Andric         "never be invoked.");
793fe6060f1SDimitry Andric   }
794fe6060f1SDimitry Andric 
795*cb14a3feSDimitry Andric   virtual _Rp operator()(_ArgTypes&&... __arg) { return std::__invoke(__f_, std::forward<_ArgTypes>(__arg)...); }
796fe6060f1SDimitry Andric 
7971ac55f4cSDimitry Andric #    ifndef _LIBCPP_HAS_NO_RTTI
798fe6060f1SDimitry Andric   virtual const void* target(type_info const& __ti) const _NOEXCEPT {
799fe6060f1SDimitry Andric     if (__ti == typeid(__func::__block_type))
800fe6060f1SDimitry Andric       return &__f_;
801fe6060f1SDimitry Andric     return (const void*)nullptr;
802fe6060f1SDimitry Andric   }
803fe6060f1SDimitry Andric 
804*cb14a3feSDimitry Andric   virtual const std::type_info& target_type() const _NOEXCEPT { return typeid(__func::__block_type); }
8051ac55f4cSDimitry Andric #    endif // _LIBCPP_HAS_NO_RTTI
806fe6060f1SDimitry Andric };
807fe6060f1SDimitry Andric 
808f3fd488fSDimitry Andric #  endif // _LIBCPP_HAS_EXTENSION_BLOCKS
809fe6060f1SDimitry Andric 
8100eae32dcSDimitry Andric } // namespace __function
811fe6060f1SDimitry Andric 
812fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
813fe6060f1SDimitry Andric class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)>
814fe6060f1SDimitry Andric     : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>,
815*cb14a3feSDimitry Andric       public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)> {
816fe6060f1SDimitry Andric #  ifndef _LIBCPP_ABI_OPTIMIZED_FUNCTION
817fe6060f1SDimitry Andric   typedef __function::__value_func<_Rp(_ArgTypes...)> __func;
818fe6060f1SDimitry Andric #  else
819fe6060f1SDimitry Andric   typedef __function::__policy_func<_Rp(_ArgTypes...)> __func;
820fe6060f1SDimitry Andric #  endif
821fe6060f1SDimitry Andric 
822fe6060f1SDimitry Andric   __func __f_;
823fe6060f1SDimitry Andric 
824*cb14a3feSDimitry Andric   template <class _Fp,
825*cb14a3feSDimitry Andric             bool = _And< _IsNotSame<__remove_cvref_t<_Fp>, function>, __invokable<_Fp, _ArgTypes...> >::value>
826fe6060f1SDimitry Andric   struct __callable;
827fe6060f1SDimitry Andric   template <class _Fp>
828*cb14a3feSDimitry Andric   struct __callable<_Fp, true> {
829*cb14a3feSDimitry Andric     static const bool value =
830*cb14a3feSDimitry Andric         is_void<_Rp>::value || __is_core_convertible<typename __invoke_of<_Fp, _ArgTypes...>::type, _Rp>::value;
831fe6060f1SDimitry Andric   };
832fe6060f1SDimitry Andric   template <class _Fp>
833*cb14a3feSDimitry Andric   struct __callable<_Fp, false> {
834fe6060f1SDimitry Andric     static const bool value = false;
835fe6060f1SDimitry Andric   };
836fe6060f1SDimitry Andric 
837fe6060f1SDimitry Andric   template <class _Fp>
8385f757f3fSDimitry Andric   using _EnableIfLValueCallable = __enable_if_t<__callable<_Fp&>::value>;
839*cb14a3feSDimitry Andric 
840fe6060f1SDimitry Andric public:
841fe6060f1SDimitry Andric   typedef _Rp result_type;
842fe6060f1SDimitry Andric 
843fe6060f1SDimitry Andric   // construct/copy/destroy:
844*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI function() _NOEXCEPT {}
845*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI function(nullptr_t) _NOEXCEPT {}
84606c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI function(const function&);
84706c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI function(function&&) _NOEXCEPT;
848fe6060f1SDimitry Andric   template <class _Fp, class = _EnableIfLValueCallable<_Fp>>
84906c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI function(_Fp);
850fe6060f1SDimitry Andric 
851fe6060f1SDimitry Andric #  if _LIBCPP_STD_VER <= 14
852fe6060f1SDimitry Andric   template <class _Alloc>
853*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
854fe6060f1SDimitry Andric   template <class _Alloc>
855*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {}
856fe6060f1SDimitry Andric   template <class _Alloc>
85706c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, const function&);
858fe6060f1SDimitry Andric   template <class _Alloc>
85906c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, function&&);
860fe6060f1SDimitry Andric   template <class _Fp, class _Alloc, class = _EnableIfLValueCallable<_Fp>>
86106c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc& __a, _Fp __f);
862fe6060f1SDimitry Andric #  endif
863fe6060f1SDimitry Andric 
86406c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI function& operator=(const function&);
86506c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI function& operator=(function&&) _NOEXCEPT;
86606c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI function& operator=(nullptr_t) _NOEXCEPT;
86706c3fb27SDimitry Andric   template <class _Fp, class = _EnableIfLValueCallable<__decay_t<_Fp>>>
86806c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI function& operator=(_Fp&&);
869fe6060f1SDimitry Andric 
87006c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI ~function();
871fe6060f1SDimitry Andric 
872fe6060f1SDimitry Andric   // function modifiers:
87306c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI void swap(function&) _NOEXCEPT;
874fe6060f1SDimitry Andric 
875fe6060f1SDimitry Andric #  if _LIBCPP_STD_VER <= 14
876fe6060f1SDimitry Andric   template <class _Fp, class _Alloc>
877*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI void assign(_Fp&& __f, const _Alloc& __a) {
878*cb14a3feSDimitry Andric     function(allocator_arg, __a, std::forward<_Fp>(__f)).swap(*this);
879*cb14a3feSDimitry Andric   }
880fe6060f1SDimitry Andric #  endif
881fe6060f1SDimitry Andric 
882fe6060f1SDimitry Andric   // function capacity:
883*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return static_cast<bool>(__f_); }
884fe6060f1SDimitry Andric 
885fe6060f1SDimitry Andric   // deleted overloads close possible hole in the type system
886fe6060f1SDimitry Andric   template <class _R2, class... _ArgTypes2>
887fe6060f1SDimitry Andric   bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete;
88806c3fb27SDimitry Andric #  if _LIBCPP_STD_VER <= 17
889fe6060f1SDimitry Andric   template <class _R2, class... _ArgTypes2>
890fe6060f1SDimitry Andric   bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete;
89106c3fb27SDimitry Andric #  endif
892*cb14a3feSDimitry Andric 
893fe6060f1SDimitry Andric public:
894fe6060f1SDimitry Andric   // function invocation:
89506c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes...) const;
896fe6060f1SDimitry Andric 
8971ac55f4cSDimitry Andric #  ifndef _LIBCPP_HAS_NO_RTTI
898fe6060f1SDimitry Andric   // function target access:
89906c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT;
90006c3fb27SDimitry Andric   template <typename _Tp>
90106c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp* target() _NOEXCEPT;
90206c3fb27SDimitry Andric   template <typename _Tp>
90306c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT;
9041ac55f4cSDimitry Andric #  endif // _LIBCPP_HAS_NO_RTTI
905fe6060f1SDimitry Andric };
906fe6060f1SDimitry Andric 
907349cc55cSDimitry Andric #  if _LIBCPP_STD_VER >= 17
908fe6060f1SDimitry Andric template <class _Rp, class... _Ap>
909fe6060f1SDimitry Andric function(_Rp (*)(_Ap...)) -> function<_Rp(_Ap...)>;
910fe6060f1SDimitry Andric 
911fe6060f1SDimitry Andric template <class _Fp, class _Stripped = typename __strip_signature<decltype(&_Fp::operator())>::type>
912fe6060f1SDimitry Andric function(_Fp) -> function<_Stripped>;
913349cc55cSDimitry Andric #  endif // _LIBCPP_STD_VER >= 17
914fe6060f1SDimitry Andric 
915fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
916fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(const function& __f) : __f_(__f.__f_) {}
917fe6060f1SDimitry Andric 
918fe6060f1SDimitry Andric #  if _LIBCPP_STD_VER <= 14
919fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
920fe6060f1SDimitry Andric template <class _Alloc>
921*cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, const function& __f) : __f_(__f.__f_) {}
922fe6060f1SDimitry Andric #  endif
923fe6060f1SDimitry Andric 
924fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
925*cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT : __f_(std::move(__f.__f_)) {}
926fe6060f1SDimitry Andric 
927fe6060f1SDimitry Andric #  if _LIBCPP_STD_VER <= 14
928fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
929fe6060f1SDimitry Andric template <class _Alloc>
930*cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, function&& __f) : __f_(std::move(__f.__f_)) {}
931fe6060f1SDimitry Andric #  endif
932fe6060f1SDimitry Andric 
933fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
934fe6060f1SDimitry Andric template <class _Fp, class>
9355f757f3fSDimitry Andric function<_Rp(_ArgTypes...)>::function(_Fp __f) : __f_(std::move(__f)) {}
936fe6060f1SDimitry Andric 
937fe6060f1SDimitry Andric #  if _LIBCPP_STD_VER <= 14
938fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
939fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class>
940*cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a, _Fp __f) : __f_(std::move(__f), __a) {}
941fe6060f1SDimitry Andric #  endif
942fe6060f1SDimitry Andric 
943fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
944*cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(const function& __f) {
945fe6060f1SDimitry Andric   function(__f).swap(*this);
946fe6060f1SDimitry Andric   return *this;
947fe6060f1SDimitry Andric }
948fe6060f1SDimitry Andric 
949fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
950*cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT {
9515f757f3fSDimitry Andric   __f_ = std::move(__f.__f_);
952fe6060f1SDimitry Andric   return *this;
953fe6060f1SDimitry Andric }
954fe6060f1SDimitry Andric 
955fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
956*cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT {
957fe6060f1SDimitry Andric   __f_ = nullptr;
958fe6060f1SDimitry Andric   return *this;
959fe6060f1SDimitry Andric }
960fe6060f1SDimitry Andric 
961fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
962fe6060f1SDimitry Andric template <class _Fp, class>
963*cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f) {
9645f757f3fSDimitry Andric   function(std::forward<_Fp>(__f)).swap(*this);
965fe6060f1SDimitry Andric   return *this;
966fe6060f1SDimitry Andric }
967fe6060f1SDimitry Andric 
968fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
969fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::~function() {}
970fe6060f1SDimitry Andric 
971fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
972*cb14a3feSDimitry Andric void function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT {
973fe6060f1SDimitry Andric   __f_.swap(__f.__f_);
974fe6060f1SDimitry Andric }
975fe6060f1SDimitry Andric 
976fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
977*cb14a3feSDimitry Andric _Rp function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const {
9785f757f3fSDimitry Andric   return __f_(std::forward<_ArgTypes>(__arg)...);
979fe6060f1SDimitry Andric }
980fe6060f1SDimitry Andric 
9811ac55f4cSDimitry Andric #  ifndef _LIBCPP_HAS_NO_RTTI
982fe6060f1SDimitry Andric 
983fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
984*cb14a3feSDimitry Andric const std::type_info& function<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT {
985fe6060f1SDimitry Andric   return __f_.target_type();
986fe6060f1SDimitry Andric }
987fe6060f1SDimitry Andric 
988fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
989fe6060f1SDimitry Andric template <typename _Tp>
990*cb14a3feSDimitry Andric _Tp* function<_Rp(_ArgTypes...)>::target() _NOEXCEPT {
991fe6060f1SDimitry Andric   return (_Tp*)(__f_.template target<_Tp>());
992fe6060f1SDimitry Andric }
993fe6060f1SDimitry Andric 
994fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
995fe6060f1SDimitry Andric template <typename _Tp>
996*cb14a3feSDimitry Andric const _Tp* function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT {
997fe6060f1SDimitry Andric   return __f_.template target<_Tp>();
998fe6060f1SDimitry Andric }
999fe6060f1SDimitry Andric 
10001ac55f4cSDimitry Andric #  endif // _LIBCPP_HAS_NO_RTTI
1001fe6060f1SDimitry Andric 
1002fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1003*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {
1004*cb14a3feSDimitry Andric   return !__f;
1005*cb14a3feSDimitry Andric }
1006fe6060f1SDimitry Andric 
100706c3fb27SDimitry Andric #  if _LIBCPP_STD_VER <= 17
100806c3fb27SDimitry Andric 
1009fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1010*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator==(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {
1011*cb14a3feSDimitry Andric   return !__f;
1012*cb14a3feSDimitry Andric }
1013fe6060f1SDimitry Andric 
1014fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1015*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {
1016*cb14a3feSDimitry Andric   return (bool)__f;
1017*cb14a3feSDimitry Andric }
1018fe6060f1SDimitry Andric 
1019fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1020*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {
1021*cb14a3feSDimitry Andric   return (bool)__f;
1022*cb14a3feSDimitry Andric }
1023fe6060f1SDimitry Andric 
102406c3fb27SDimitry Andric #  endif // _LIBCPP_STD_VER <= 17
102506c3fb27SDimitry Andric 
1026fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1027*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI void swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCEPT {
1028*cb14a3feSDimitry Andric   return __x.swap(__y);
1029*cb14a3feSDimitry Andric }
1030fe6060f1SDimitry Andric 
1031bdd1243dSDimitry Andric _LIBCPP_END_NAMESPACE_STD
1032fe6060f1SDimitry Andric 
103381ad6265SDimitry Andric #endif // _LIBCPP_CXX03_LANG
1034fe6060f1SDimitry Andric 
1035fe6060f1SDimitry Andric #endif // _LIBCPP___FUNCTIONAL_FUNCTION_H
1036