xref: /freebsd-src/contrib/llvm-project/libcxx/include/__functional/function.h (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
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>
15*06c3fb27SDimitry 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>
27*06c3fb27SDimitry Andric #include <__type_traits/aligned_storage.h>
28*06c3fb27SDimitry Andric #include <__type_traits/decay.h>
29*06c3fb27SDimitry Andric #include <__type_traits/is_core_convertible.h>
30*06c3fb27SDimitry Andric #include <__type_traits/is_scalar.h>
31*06c3fb27SDimitry Andric #include <__type_traits/is_trivially_copy_constructible.h>
32*06c3fb27SDimitry Andric #include <__type_traits/is_trivially_destructible.h>
33*06c3fb27SDimitry 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>
39*06c3fb27SDimitry 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*06c3fb27SDimitry Andric class _LIBCPP_EXPORTED_FROM_ABI bad_function_call
57fe6060f1SDimitry Andric     : public exception
58fe6060f1SDimitry Andric {
59fe6060f1SDimitry Andric public:
60349cc55cSDimitry Andric // Note that when a key function is not used, every translation unit that uses
61349cc55cSDimitry Andric // bad_function_call will end up containing a weak definition of the vtable and
62349cc55cSDimitry Andric // typeinfo.
63349cc55cSDimitry Andric #ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
64bdd1243dSDimitry Andric     ~bad_function_call() _NOEXCEPT override;
65349cc55cSDimitry Andric #else
66*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~bad_function_call() _NOEXCEPT override {}
67349cc55cSDimitry Andric #endif
68fe6060f1SDimitry Andric 
69349cc55cSDimitry Andric #ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE
70bdd1243dSDimitry Andric     const char* what() const _NOEXCEPT override;
71fe6060f1SDimitry Andric #endif
72fe6060f1SDimitry Andric };
7381ad6265SDimitry Andric _LIBCPP_DIAGNOSTIC_POP
74fe6060f1SDimitry Andric 
75fe6060f1SDimitry Andric _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
76fe6060f1SDimitry Andric void __throw_bad_function_call()
77fe6060f1SDimitry Andric {
78*06c3fb27SDimitry Andric #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
79fe6060f1SDimitry Andric     throw bad_function_call();
80fe6060f1SDimitry Andric #else
81*06c3fb27SDimitry Andric     _LIBCPP_VERBOSE_ABORT("bad_function_call was thrown in -fno-exceptions mode");
82fe6060f1SDimitry Andric #endif
83fe6060f1SDimitry Andric }
84fe6060f1SDimitry Andric 
85bdd1243dSDimitry Andric template<class _Fp> class _LIBCPP_TEMPLATE_VIS function; // undefined
86fe6060f1SDimitry Andric 
87fe6060f1SDimitry Andric namespace __function
88fe6060f1SDimitry Andric {
89fe6060f1SDimitry Andric 
90fe6060f1SDimitry Andric template<class _Rp>
91fe6060f1SDimitry Andric struct __maybe_derive_from_unary_function
92fe6060f1SDimitry Andric {
93fe6060f1SDimitry Andric };
94fe6060f1SDimitry Andric 
95fe6060f1SDimitry Andric template<class _Rp, class _A1>
96fe6060f1SDimitry Andric struct __maybe_derive_from_unary_function<_Rp(_A1)>
9781ad6265SDimitry Andric     : public __unary_function<_A1, _Rp>
98fe6060f1SDimitry Andric {
99fe6060f1SDimitry Andric };
100fe6060f1SDimitry Andric 
101fe6060f1SDimitry Andric template<class _Rp>
102fe6060f1SDimitry Andric struct __maybe_derive_from_binary_function
103fe6060f1SDimitry Andric {
104fe6060f1SDimitry Andric };
105fe6060f1SDimitry Andric 
106fe6060f1SDimitry Andric template<class _Rp, class _A1, class _A2>
107fe6060f1SDimitry Andric struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)>
10881ad6265SDimitry Andric     : public __binary_function<_A1, _A2, _Rp>
109fe6060f1SDimitry Andric {
110fe6060f1SDimitry Andric };
111fe6060f1SDimitry Andric 
112fe6060f1SDimitry Andric template <class _Fp>
113fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY
114fe6060f1SDimitry Andric bool __not_null(_Fp const&) { return true; }
115fe6060f1SDimitry Andric 
116fe6060f1SDimitry Andric template <class _Fp>
117fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY
118fe6060f1SDimitry Andric bool __not_null(_Fp* __ptr) { return __ptr; }
119fe6060f1SDimitry Andric 
120fe6060f1SDimitry Andric template <class _Ret, class _Class>
121fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY
122fe6060f1SDimitry Andric bool __not_null(_Ret _Class::*__ptr) { return __ptr; }
123fe6060f1SDimitry Andric 
124fe6060f1SDimitry Andric template <class _Fp>
125fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY
126fe6060f1SDimitry Andric bool __not_null(function<_Fp> const& __f) { return !!__f; }
127fe6060f1SDimitry Andric 
128fe6060f1SDimitry Andric #ifdef _LIBCPP_HAS_EXTENSION_BLOCKS
129fe6060f1SDimitry Andric template <class _Rp, class ..._Args>
130fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY
131fe6060f1SDimitry Andric bool __not_null(_Rp (^__p)(_Args...)) { return __p; }
132fe6060f1SDimitry Andric #endif
133fe6060f1SDimitry Andric 
134fe6060f1SDimitry Andric } // namespace __function
135fe6060f1SDimitry Andric 
136fe6060f1SDimitry Andric namespace __function {
137fe6060f1SDimitry Andric 
138fe6060f1SDimitry Andric // __alloc_func holds a functor and an allocator.
139fe6060f1SDimitry Andric 
140fe6060f1SDimitry Andric template <class _Fp, class _Ap, class _FB> 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>
145fe6060f1SDimitry Andric class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)>
146fe6060f1SDimitry Andric {
147fe6060f1SDimitry Andric     __compressed_pair<_Fp, _Ap> __f_;
148fe6060f1SDimitry Andric 
149fe6060f1SDimitry Andric   public:
150349cc55cSDimitry Andric     typedef _LIBCPP_NODEBUG _Fp _Target;
151349cc55cSDimitry Andric     typedef _LIBCPP_NODEBUG _Ap _Alloc;
152fe6060f1SDimitry Andric 
153fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
154fe6060f1SDimitry Andric     const _Target& __target() const { return __f_.first(); }
155fe6060f1SDimitry Andric 
156fe6060f1SDimitry Andric     // WIN32 APIs may define __allocator, so use __get_allocator instead.
157fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
158fe6060f1SDimitry Andric     const _Alloc& __get_allocator() const { return __f_.second(); }
159fe6060f1SDimitry Andric 
160fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
161fe6060f1SDimitry Andric     explicit __alloc_func(_Target&& __f)
162fe6060f1SDimitry Andric         : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)),
163fe6060f1SDimitry Andric                _VSTD::forward_as_tuple())
164fe6060f1SDimitry Andric     {
165fe6060f1SDimitry Andric     }
166fe6060f1SDimitry Andric 
167fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
168fe6060f1SDimitry Andric     explicit __alloc_func(const _Target& __f, const _Alloc& __a)
169fe6060f1SDimitry Andric         : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f),
170fe6060f1SDimitry Andric                _VSTD::forward_as_tuple(__a))
171fe6060f1SDimitry Andric     {
172fe6060f1SDimitry Andric     }
173fe6060f1SDimitry Andric 
174fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
175fe6060f1SDimitry Andric     explicit __alloc_func(const _Target& __f, _Alloc&& __a)
176fe6060f1SDimitry Andric         : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f),
177fe6060f1SDimitry Andric                _VSTD::forward_as_tuple(_VSTD::move(__a)))
178fe6060f1SDimitry Andric     {
179fe6060f1SDimitry Andric     }
180fe6060f1SDimitry Andric 
181fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
182fe6060f1SDimitry Andric     explicit __alloc_func(_Target&& __f, _Alloc&& __a)
183fe6060f1SDimitry Andric         : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)),
184fe6060f1SDimitry Andric                _VSTD::forward_as_tuple(_VSTD::move(__a)))
185fe6060f1SDimitry Andric     {
186fe6060f1SDimitry Andric     }
187fe6060f1SDimitry Andric 
188fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
189fe6060f1SDimitry Andric     _Rp operator()(_ArgTypes&&... __arg)
190fe6060f1SDimitry Andric     {
191fe6060f1SDimitry Andric         typedef __invoke_void_return_wrapper<_Rp> _Invoker;
192fe6060f1SDimitry Andric         return _Invoker::__call(__f_.first(),
193fe6060f1SDimitry Andric                                 _VSTD::forward<_ArgTypes>(__arg)...);
194fe6060f1SDimitry Andric     }
195fe6060f1SDimitry Andric 
196fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
197fe6060f1SDimitry Andric     __alloc_func* __clone() const
198fe6060f1SDimitry Andric     {
199fe6060f1SDimitry Andric         typedef allocator_traits<_Alloc> __alloc_traits;
200bdd1243dSDimitry Andric         typedef __rebind_alloc<__alloc_traits, __alloc_func> _AA;
201fe6060f1SDimitry Andric         _AA __a(__f_.second());
202fe6060f1SDimitry Andric         typedef __allocator_destructor<_AA> _Dp;
203fe6060f1SDimitry Andric         unique_ptr<__alloc_func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
204fe6060f1SDimitry Andric         ::new ((void*)__hold.get()) __alloc_func(__f_.first(), _Alloc(__a));
205fe6060f1SDimitry Andric         return __hold.release();
206fe6060f1SDimitry Andric     }
207fe6060f1SDimitry Andric 
208fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
209fe6060f1SDimitry Andric     void destroy() _NOEXCEPT { __f_.~__compressed_pair<_Target, _Alloc>(); }
210fe6060f1SDimitry Andric 
211*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI static void __destroy_and_delete(__alloc_func* __f) {
212fe6060f1SDimitry Andric       typedef allocator_traits<_Alloc> __alloc_traits;
213bdd1243dSDimitry Andric       typedef __rebind_alloc<__alloc_traits, __alloc_func> _FunAlloc;
214fe6060f1SDimitry Andric       _FunAlloc __a(__f->__get_allocator());
215fe6060f1SDimitry Andric       __f->destroy();
216fe6060f1SDimitry Andric       __a.deallocate(__f, 1);
217fe6060f1SDimitry Andric     }
218fe6060f1SDimitry Andric };
219fe6060f1SDimitry Andric 
220fe6060f1SDimitry Andric template <class _Fp, class _Rp, class... _ArgTypes>
221fe6060f1SDimitry Andric class __default_alloc_func<_Fp, _Rp(_ArgTypes...)> {
222fe6060f1SDimitry Andric   _Fp __f_;
223fe6060f1SDimitry Andric 
224fe6060f1SDimitry Andric public:
225349cc55cSDimitry Andric   typedef _LIBCPP_NODEBUG _Fp _Target;
226fe6060f1SDimitry Andric 
227fe6060f1SDimitry Andric   _LIBCPP_INLINE_VISIBILITY
228fe6060f1SDimitry Andric   const _Target& __target() const { return __f_; }
229fe6060f1SDimitry Andric 
230fe6060f1SDimitry Andric   _LIBCPP_INLINE_VISIBILITY
231fe6060f1SDimitry Andric   explicit __default_alloc_func(_Target&& __f) : __f_(_VSTD::move(__f)) {}
232fe6060f1SDimitry Andric 
233fe6060f1SDimitry Andric   _LIBCPP_INLINE_VISIBILITY
234fe6060f1SDimitry Andric   explicit __default_alloc_func(const _Target& __f) : __f_(__f) {}
235fe6060f1SDimitry Andric 
236fe6060f1SDimitry Andric   _LIBCPP_INLINE_VISIBILITY
237fe6060f1SDimitry Andric   _Rp operator()(_ArgTypes&&... __arg) {
238fe6060f1SDimitry Andric     typedef __invoke_void_return_wrapper<_Rp> _Invoker;
239fe6060f1SDimitry Andric     return _Invoker::__call(__f_, _VSTD::forward<_ArgTypes>(__arg)...);
240fe6060f1SDimitry Andric   }
241fe6060f1SDimitry Andric 
242fe6060f1SDimitry Andric   _LIBCPP_INLINE_VISIBILITY
243fe6060f1SDimitry Andric   __default_alloc_func* __clone() const {
244fe6060f1SDimitry Andric       __builtin_new_allocator::__holder_t __hold =
245fe6060f1SDimitry Andric         __builtin_new_allocator::__allocate_type<__default_alloc_func>(1);
246fe6060f1SDimitry Andric     __default_alloc_func* __res =
247fe6060f1SDimitry Andric         ::new ((void*)__hold.get()) __default_alloc_func(__f_);
248fe6060f1SDimitry Andric     (void)__hold.release();
249fe6060f1SDimitry Andric     return __res;
250fe6060f1SDimitry Andric   }
251fe6060f1SDimitry Andric 
252fe6060f1SDimitry Andric   _LIBCPP_INLINE_VISIBILITY
253fe6060f1SDimitry Andric   void destroy() _NOEXCEPT { __f_.~_Target(); }
254fe6060f1SDimitry Andric 
255*06c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI static void __destroy_and_delete(__default_alloc_func* __f) {
256fe6060f1SDimitry Andric     __f->destroy();
257fe6060f1SDimitry Andric       __builtin_new_allocator::__deallocate_type<__default_alloc_func>(__f, 1);
258fe6060f1SDimitry Andric   }
259fe6060f1SDimitry Andric };
260fe6060f1SDimitry Andric 
261fe6060f1SDimitry Andric // __base provides an abstract interface for copyable functors.
262fe6060f1SDimitry Andric 
263fe6060f1SDimitry Andric template<class _Fp> class _LIBCPP_TEMPLATE_VIS __base;
264fe6060f1SDimitry Andric 
265fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
266fe6060f1SDimitry Andric class __base<_Rp(_ArgTypes...)>
267fe6060f1SDimitry Andric {
268fe6060f1SDimitry Andric     __base(const __base&);
269fe6060f1SDimitry Andric     __base& operator=(const __base&);
270fe6060f1SDimitry Andric public:
271fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY __base() {}
272bdd1243dSDimitry Andric     _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual ~__base() {}
273fe6060f1SDimitry Andric     virtual __base* __clone() const = 0;
274fe6060f1SDimitry Andric     virtual void __clone(__base*) const = 0;
275fe6060f1SDimitry Andric     virtual void destroy() _NOEXCEPT = 0;
276fe6060f1SDimitry Andric     virtual void destroy_deallocate() _NOEXCEPT = 0;
277fe6060f1SDimitry Andric     virtual _Rp operator()(_ArgTypes&& ...) = 0;
2781ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI
279fe6060f1SDimitry Andric     virtual const void* target(const type_info&) const _NOEXCEPT = 0;
280fe6060f1SDimitry Andric     virtual const std::type_info& target_type() const _NOEXCEPT = 0;
2811ac55f4cSDimitry Andric #endif // _LIBCPP_HAS_NO_RTTI
282fe6060f1SDimitry Andric };
283fe6060f1SDimitry Andric 
284fe6060f1SDimitry Andric // __func implements __base for a given functor type.
285fe6060f1SDimitry Andric 
286fe6060f1SDimitry Andric template<class _FD, class _Alloc, class _FB> class __func;
287fe6060f1SDimitry Andric 
288fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
289fe6060f1SDimitry Andric class __func<_Fp, _Alloc, _Rp(_ArgTypes...)>
290fe6060f1SDimitry Andric     : public  __base<_Rp(_ArgTypes...)>
291fe6060f1SDimitry Andric {
292fe6060f1SDimitry Andric     __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> __f_;
293fe6060f1SDimitry Andric public:
294fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
295fe6060f1SDimitry Andric     explicit __func(_Fp&& __f)
296fe6060f1SDimitry Andric         : __f_(_VSTD::move(__f)) {}
297fe6060f1SDimitry Andric 
298fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
299fe6060f1SDimitry Andric     explicit __func(const _Fp& __f, const _Alloc& __a)
300fe6060f1SDimitry Andric         : __f_(__f, __a) {}
301fe6060f1SDimitry Andric 
302fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
303fe6060f1SDimitry Andric     explicit __func(const _Fp& __f, _Alloc&& __a)
304fe6060f1SDimitry Andric         : __f_(__f, _VSTD::move(__a)) {}
305fe6060f1SDimitry Andric 
306fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
307fe6060f1SDimitry Andric     explicit __func(_Fp&& __f, _Alloc&& __a)
308fe6060f1SDimitry Andric         : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
309fe6060f1SDimitry Andric 
310*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual __base<_Rp(_ArgTypes...)>* __clone() const;
311*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __clone(__base<_Rp(_ArgTypes...)>*) const;
312*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy() _NOEXCEPT;
313*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate() _NOEXCEPT;
314*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&&... __arg);
3151ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI
316*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const void* target(const type_info&) const _NOEXCEPT;
317*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const std::type_info& target_type() const _NOEXCEPT;
3181ac55f4cSDimitry Andric #endif // _LIBCPP_HAS_NO_RTTI
319fe6060f1SDimitry Andric };
320fe6060f1SDimitry Andric 
321fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
322fe6060f1SDimitry Andric __base<_Rp(_ArgTypes...)>*
323fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const
324fe6060f1SDimitry Andric {
325fe6060f1SDimitry Andric     typedef allocator_traits<_Alloc> __alloc_traits;
326bdd1243dSDimitry Andric     typedef __rebind_alloc<__alloc_traits, __func> _Ap;
327fe6060f1SDimitry Andric     _Ap __a(__f_.__get_allocator());
328fe6060f1SDimitry Andric     typedef __allocator_destructor<_Ap> _Dp;
329fe6060f1SDimitry Andric     unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
330fe6060f1SDimitry Andric     ::new ((void*)__hold.get()) __func(__f_.__target(), _Alloc(__a));
331fe6060f1SDimitry Andric     return __hold.release();
332fe6060f1SDimitry Andric }
333fe6060f1SDimitry Andric 
334fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
335fe6060f1SDimitry Andric void
336fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const
337fe6060f1SDimitry Andric {
338fe6060f1SDimitry Andric     ::new ((void*)__p) __func(__f_.__target(), __f_.__get_allocator());
339fe6060f1SDimitry Andric }
340fe6060f1SDimitry Andric 
341fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
342fe6060f1SDimitry Andric void
343fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() _NOEXCEPT
344fe6060f1SDimitry Andric {
345fe6060f1SDimitry Andric     __f_.destroy();
346fe6060f1SDimitry Andric }
347fe6060f1SDimitry Andric 
348fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
349fe6060f1SDimitry Andric void
350fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT
351fe6060f1SDimitry Andric {
352fe6060f1SDimitry Andric     typedef allocator_traits<_Alloc> __alloc_traits;
353bdd1243dSDimitry Andric     typedef __rebind_alloc<__alloc_traits, __func> _Ap;
354fe6060f1SDimitry Andric     _Ap __a(__f_.__get_allocator());
355fe6060f1SDimitry Andric     __f_.destroy();
356fe6060f1SDimitry Andric     __a.deallocate(this, 1);
357fe6060f1SDimitry Andric }
358fe6060f1SDimitry Andric 
359fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
360fe6060f1SDimitry Andric _Rp
361fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
362fe6060f1SDimitry Andric {
363fe6060f1SDimitry Andric     return __f_(_VSTD::forward<_ArgTypes>(__arg)...);
364fe6060f1SDimitry Andric }
365fe6060f1SDimitry Andric 
3661ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI
367fe6060f1SDimitry Andric 
368fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
369fe6060f1SDimitry Andric const void*
370fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT
371fe6060f1SDimitry Andric {
372fe6060f1SDimitry Andric     if (__ti == typeid(_Fp))
37304eeddc0SDimitry Andric         return _VSTD::addressof(__f_.__target());
374fe6060f1SDimitry Andric     return nullptr;
375fe6060f1SDimitry Andric }
376fe6060f1SDimitry Andric 
377fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
378fe6060f1SDimitry Andric const std::type_info&
379fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT
380fe6060f1SDimitry Andric {
381fe6060f1SDimitry Andric     return typeid(_Fp);
382fe6060f1SDimitry Andric }
383fe6060f1SDimitry Andric 
3841ac55f4cSDimitry Andric #endif // _LIBCPP_HAS_NO_RTTI
385fe6060f1SDimitry Andric 
386fe6060f1SDimitry Andric // __value_func creates a value-type from a __func.
387fe6060f1SDimitry Andric 
388fe6060f1SDimitry Andric template <class _Fp> class __value_func;
389fe6060f1SDimitry Andric 
390fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> class __value_func<_Rp(_ArgTypes...)>
391fe6060f1SDimitry Andric {
392bdd1243dSDimitry Andric     _LIBCPP_SUPPRESS_DEPRECATED_PUSH
393fe6060f1SDimitry Andric     typename aligned_storage<3 * sizeof(void*)>::type __buf_;
394bdd1243dSDimitry Andric     _LIBCPP_SUPPRESS_DEPRECATED_POP
395fe6060f1SDimitry Andric 
396fe6060f1SDimitry Andric     typedef __base<_Rp(_ArgTypes...)> __func;
397fe6060f1SDimitry Andric     __func* __f_;
398fe6060f1SDimitry Andric 
399*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI static __func* __as_base(void* __p)
400fe6060f1SDimitry Andric     {
401753f127fSDimitry Andric         return reinterpret_cast<__func*>(__p);
402fe6060f1SDimitry Andric     }
403fe6060f1SDimitry Andric 
404fe6060f1SDimitry Andric   public:
405fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
406fe6060f1SDimitry Andric     __value_func() _NOEXCEPT : __f_(nullptr) {}
407fe6060f1SDimitry Andric 
408fe6060f1SDimitry Andric     template <class _Fp, class _Alloc>
409fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY __value_func(_Fp&& __f, const _Alloc& __a)
410fe6060f1SDimitry Andric         : __f_(nullptr)
411fe6060f1SDimitry Andric     {
412fe6060f1SDimitry Andric         typedef allocator_traits<_Alloc> __alloc_traits;
413fe6060f1SDimitry Andric         typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun;
414bdd1243dSDimitry Andric         typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc;
415fe6060f1SDimitry Andric 
416fe6060f1SDimitry Andric         if (__function::__not_null(__f))
417fe6060f1SDimitry Andric         {
418fe6060f1SDimitry Andric             _FunAlloc __af(__a);
419fe6060f1SDimitry Andric             if (sizeof(_Fun) <= sizeof(__buf_) &&
420fe6060f1SDimitry Andric                 is_nothrow_copy_constructible<_Fp>::value &&
421fe6060f1SDimitry Andric                 is_nothrow_copy_constructible<_FunAlloc>::value)
422fe6060f1SDimitry Andric             {
423fe6060f1SDimitry Andric                 __f_ =
424fe6060f1SDimitry Andric                     ::new ((void*)&__buf_) _Fun(_VSTD::move(__f), _Alloc(__af));
425fe6060f1SDimitry Andric             }
426fe6060f1SDimitry Andric             else
427fe6060f1SDimitry Andric             {
428fe6060f1SDimitry Andric                 typedef __allocator_destructor<_FunAlloc> _Dp;
429fe6060f1SDimitry Andric                 unique_ptr<__func, _Dp> __hold(__af.allocate(1), _Dp(__af, 1));
430fe6060f1SDimitry Andric                 ::new ((void*)__hold.get()) _Fun(_VSTD::move(__f), _Alloc(__a));
431fe6060f1SDimitry Andric                 __f_ = __hold.release();
432fe6060f1SDimitry Andric             }
433fe6060f1SDimitry Andric         }
434fe6060f1SDimitry Andric     }
435fe6060f1SDimitry Andric 
436fe6060f1SDimitry Andric     template <class _Fp,
437*06c3fb27SDimitry Andric         class = typename enable_if<!is_same<__decay_t<_Fp>, __value_func>::value>::type>
438fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY explicit __value_func(_Fp&& __f)
439fe6060f1SDimitry Andric         : __value_func(_VSTD::forward<_Fp>(__f), allocator<_Fp>()) {}
440fe6060f1SDimitry Andric 
441fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
442fe6060f1SDimitry Andric     __value_func(const __value_func& __f)
443fe6060f1SDimitry Andric     {
444fe6060f1SDimitry Andric         if (__f.__f_ == nullptr)
445fe6060f1SDimitry Andric             __f_ = nullptr;
446fe6060f1SDimitry Andric         else if ((void*)__f.__f_ == &__f.__buf_)
447fe6060f1SDimitry Andric         {
448fe6060f1SDimitry Andric             __f_ = __as_base(&__buf_);
449fe6060f1SDimitry Andric             __f.__f_->__clone(__f_);
450fe6060f1SDimitry Andric         }
451fe6060f1SDimitry Andric         else
452fe6060f1SDimitry Andric             __f_ = __f.__f_->__clone();
453fe6060f1SDimitry Andric     }
454fe6060f1SDimitry Andric 
455fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
456fe6060f1SDimitry Andric     __value_func(__value_func&& __f) _NOEXCEPT
457fe6060f1SDimitry Andric     {
458fe6060f1SDimitry Andric         if (__f.__f_ == nullptr)
459fe6060f1SDimitry Andric             __f_ = nullptr;
460fe6060f1SDimitry Andric         else if ((void*)__f.__f_ == &__f.__buf_)
461fe6060f1SDimitry Andric         {
462fe6060f1SDimitry Andric             __f_ = __as_base(&__buf_);
463fe6060f1SDimitry Andric             __f.__f_->__clone(__f_);
464fe6060f1SDimitry Andric         }
465fe6060f1SDimitry Andric         else
466fe6060f1SDimitry Andric         {
467fe6060f1SDimitry Andric             __f_ = __f.__f_;
468fe6060f1SDimitry Andric             __f.__f_ = nullptr;
469fe6060f1SDimitry Andric         }
470fe6060f1SDimitry Andric     }
471fe6060f1SDimitry Andric 
472fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
473fe6060f1SDimitry Andric     ~__value_func()
474fe6060f1SDimitry Andric     {
475fe6060f1SDimitry Andric         if ((void*)__f_ == &__buf_)
476fe6060f1SDimitry Andric             __f_->destroy();
477fe6060f1SDimitry Andric         else if (__f_)
478fe6060f1SDimitry Andric             __f_->destroy_deallocate();
479fe6060f1SDimitry Andric     }
480fe6060f1SDimitry Andric 
481fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
482fe6060f1SDimitry Andric     __value_func& operator=(__value_func&& __f)
483fe6060f1SDimitry Andric     {
484fe6060f1SDimitry Andric         *this = nullptr;
485fe6060f1SDimitry Andric         if (__f.__f_ == nullptr)
486fe6060f1SDimitry Andric             __f_ = nullptr;
487fe6060f1SDimitry Andric         else if ((void*)__f.__f_ == &__f.__buf_)
488fe6060f1SDimitry Andric         {
489fe6060f1SDimitry Andric             __f_ = __as_base(&__buf_);
490fe6060f1SDimitry Andric             __f.__f_->__clone(__f_);
491fe6060f1SDimitry Andric         }
492fe6060f1SDimitry Andric         else
493fe6060f1SDimitry Andric         {
494fe6060f1SDimitry Andric             __f_ = __f.__f_;
495fe6060f1SDimitry Andric             __f.__f_ = nullptr;
496fe6060f1SDimitry Andric         }
497fe6060f1SDimitry Andric         return *this;
498fe6060f1SDimitry Andric     }
499fe6060f1SDimitry Andric 
500fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
501fe6060f1SDimitry Andric     __value_func& operator=(nullptr_t)
502fe6060f1SDimitry Andric     {
503fe6060f1SDimitry Andric         __func* __f = __f_;
504fe6060f1SDimitry Andric         __f_ = nullptr;
505fe6060f1SDimitry Andric         if ((void*)__f == &__buf_)
506fe6060f1SDimitry Andric             __f->destroy();
507fe6060f1SDimitry Andric         else if (__f)
508fe6060f1SDimitry Andric             __f->destroy_deallocate();
509fe6060f1SDimitry Andric         return *this;
510fe6060f1SDimitry Andric     }
511fe6060f1SDimitry Andric 
512fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
513fe6060f1SDimitry Andric     _Rp operator()(_ArgTypes&&... __args) const
514fe6060f1SDimitry Andric     {
515fe6060f1SDimitry Andric         if (__f_ == nullptr)
516fe6060f1SDimitry Andric             __throw_bad_function_call();
517fe6060f1SDimitry Andric         return (*__f_)(_VSTD::forward<_ArgTypes>(__args)...);
518fe6060f1SDimitry Andric     }
519fe6060f1SDimitry Andric 
520fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
521fe6060f1SDimitry Andric     void swap(__value_func& __f) _NOEXCEPT
522fe6060f1SDimitry Andric     {
523fe6060f1SDimitry Andric         if (&__f == this)
524fe6060f1SDimitry Andric             return;
525fe6060f1SDimitry Andric         if ((void*)__f_ == &__buf_ && (void*)__f.__f_ == &__f.__buf_)
526fe6060f1SDimitry Andric         {
527bdd1243dSDimitry Andric             _LIBCPP_SUPPRESS_DEPRECATED_PUSH
528fe6060f1SDimitry Andric             typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
529bdd1243dSDimitry Andric             _LIBCPP_SUPPRESS_DEPRECATED_POP
530fe6060f1SDimitry Andric             __func* __t = __as_base(&__tempbuf);
531fe6060f1SDimitry Andric             __f_->__clone(__t);
532fe6060f1SDimitry Andric             __f_->destroy();
533fe6060f1SDimitry Andric             __f_ = nullptr;
534fe6060f1SDimitry Andric             __f.__f_->__clone(__as_base(&__buf_));
535fe6060f1SDimitry Andric             __f.__f_->destroy();
536fe6060f1SDimitry Andric             __f.__f_ = nullptr;
537fe6060f1SDimitry Andric             __f_ = __as_base(&__buf_);
538fe6060f1SDimitry Andric             __t->__clone(__as_base(&__f.__buf_));
539fe6060f1SDimitry Andric             __t->destroy();
540fe6060f1SDimitry Andric             __f.__f_ = __as_base(&__f.__buf_);
541fe6060f1SDimitry Andric         }
542fe6060f1SDimitry Andric         else if ((void*)__f_ == &__buf_)
543fe6060f1SDimitry Andric         {
544fe6060f1SDimitry Andric             __f_->__clone(__as_base(&__f.__buf_));
545fe6060f1SDimitry Andric             __f_->destroy();
546fe6060f1SDimitry Andric             __f_ = __f.__f_;
547fe6060f1SDimitry Andric             __f.__f_ = __as_base(&__f.__buf_);
548fe6060f1SDimitry Andric         }
549fe6060f1SDimitry Andric         else if ((void*)__f.__f_ == &__f.__buf_)
550fe6060f1SDimitry Andric         {
551fe6060f1SDimitry Andric             __f.__f_->__clone(__as_base(&__buf_));
552fe6060f1SDimitry Andric             __f.__f_->destroy();
553fe6060f1SDimitry Andric             __f.__f_ = __f_;
554fe6060f1SDimitry Andric             __f_ = __as_base(&__buf_);
555fe6060f1SDimitry Andric         }
556fe6060f1SDimitry Andric         else
557fe6060f1SDimitry Andric             _VSTD::swap(__f_, __f.__f_);
558fe6060f1SDimitry Andric     }
559fe6060f1SDimitry Andric 
560fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
561fe6060f1SDimitry Andric     explicit operator bool() const _NOEXCEPT { return __f_ != nullptr; }
562fe6060f1SDimitry Andric 
5631ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI
564fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
565fe6060f1SDimitry Andric     const std::type_info& target_type() const _NOEXCEPT
566fe6060f1SDimitry Andric     {
567fe6060f1SDimitry Andric         if (__f_ == nullptr)
568fe6060f1SDimitry Andric             return typeid(void);
569fe6060f1SDimitry Andric         return __f_->target_type();
570fe6060f1SDimitry Andric     }
571fe6060f1SDimitry Andric 
572fe6060f1SDimitry Andric     template <typename _Tp>
573fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT
574fe6060f1SDimitry Andric     {
575fe6060f1SDimitry Andric         if (__f_ == nullptr)
576fe6060f1SDimitry Andric             return nullptr;
577fe6060f1SDimitry Andric         return (const _Tp*)__f_->target(typeid(_Tp));
578fe6060f1SDimitry Andric     }
5791ac55f4cSDimitry Andric #endif // _LIBCPP_HAS_NO_RTTI
580fe6060f1SDimitry Andric };
581fe6060f1SDimitry Andric 
582fe6060f1SDimitry Andric // Storage for a functor object, to be used with __policy to manage copy and
583fe6060f1SDimitry Andric // destruction.
584fe6060f1SDimitry Andric union __policy_storage
585fe6060f1SDimitry Andric {
586fe6060f1SDimitry Andric     mutable char __small[sizeof(void*) * 2];
587fe6060f1SDimitry Andric     void* __large;
588fe6060f1SDimitry Andric };
589fe6060f1SDimitry Andric 
590fe6060f1SDimitry Andric // True if _Fun can safely be held in __policy_storage.__small.
591fe6060f1SDimitry Andric template <typename _Fun>
592fe6060f1SDimitry Andric struct __use_small_storage
593fe6060f1SDimitry Andric     : public integral_constant<
594fe6060f1SDimitry Andric           bool, sizeof(_Fun) <= sizeof(__policy_storage) &&
595fe6060f1SDimitry Andric                     _LIBCPP_ALIGNOF(_Fun) <= _LIBCPP_ALIGNOF(__policy_storage) &&
596fe6060f1SDimitry Andric                     is_trivially_copy_constructible<_Fun>::value &&
597fe6060f1SDimitry Andric                     is_trivially_destructible<_Fun>::value> {};
598fe6060f1SDimitry Andric 
599fe6060f1SDimitry Andric // Policy contains information about how to copy, destroy, and move the
600fe6060f1SDimitry Andric // underlying functor. You can think of it as a vtable of sorts.
601fe6060f1SDimitry Andric struct __policy
602fe6060f1SDimitry Andric {
603fe6060f1SDimitry Andric     // Used to copy or destroy __large values. null for trivial objects.
604fe6060f1SDimitry Andric     void* (*const __clone)(const void*);
605fe6060f1SDimitry Andric     void (*const __destroy)(void*);
606fe6060f1SDimitry Andric 
607fe6060f1SDimitry Andric     // True if this is the null policy (no value).
608fe6060f1SDimitry Andric     const bool __is_null;
609fe6060f1SDimitry Andric 
610fe6060f1SDimitry Andric     // The target type. May be null if RTTI is disabled.
611fe6060f1SDimitry Andric     const std::type_info* const __type_info;
612fe6060f1SDimitry Andric 
613fe6060f1SDimitry Andric     // Returns a pointer to a static policy object suitable for the functor
614fe6060f1SDimitry Andric     // type.
615fe6060f1SDimitry Andric     template <typename _Fun>
616fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY static const __policy* __create()
617fe6060f1SDimitry Andric     {
618fe6060f1SDimitry Andric         return __choose_policy<_Fun>(__use_small_storage<_Fun>());
619fe6060f1SDimitry Andric     }
620fe6060f1SDimitry Andric 
621fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
622fe6060f1SDimitry Andric     static const __policy* __create_empty()
623fe6060f1SDimitry Andric     {
624*06c3fb27SDimitry Andric         static const _LIBCPP_CONSTEXPR __policy __policy = {nullptr, nullptr,
625fe6060f1SDimitry Andric                                                             true,
6261ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI
627fe6060f1SDimitry Andric                                                             &typeid(void)
628fe6060f1SDimitry Andric #else
629fe6060f1SDimitry Andric                                                             nullptr
630fe6060f1SDimitry Andric #endif
631fe6060f1SDimitry Andric         };
632*06c3fb27SDimitry Andric         return &__policy;
633fe6060f1SDimitry Andric     }
634fe6060f1SDimitry Andric 
635fe6060f1SDimitry Andric   private:
636*06c3fb27SDimitry Andric     template <typename _Fun>
637*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI static void* __large_clone(const void* __s)
638fe6060f1SDimitry Andric     {
639fe6060f1SDimitry Andric         const _Fun* __f = static_cast<const _Fun*>(__s);
640fe6060f1SDimitry Andric         return __f->__clone();
641fe6060f1SDimitry Andric     }
642fe6060f1SDimitry Andric 
643fe6060f1SDimitry Andric     template <typename _Fun>
644*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI static void __large_destroy(void* __s) {
645fe6060f1SDimitry Andric       _Fun::__destroy_and_delete(static_cast<_Fun*>(__s));
646fe6060f1SDimitry Andric     }
647fe6060f1SDimitry Andric 
648fe6060f1SDimitry Andric     template <typename _Fun>
649fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY static const __policy*
650fe6060f1SDimitry Andric     __choose_policy(/* is_small = */ false_type) {
651*06c3fb27SDimitry Andric       static const _LIBCPP_CONSTEXPR __policy __policy = {
652fe6060f1SDimitry Andric           &__large_clone<_Fun>, &__large_destroy<_Fun>, false,
6531ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI
654fe6060f1SDimitry Andric           &typeid(typename _Fun::_Target)
655fe6060f1SDimitry Andric #else
656fe6060f1SDimitry Andric           nullptr
657fe6060f1SDimitry Andric #endif
658fe6060f1SDimitry Andric       };
659*06c3fb27SDimitry Andric         return &__policy;
660fe6060f1SDimitry Andric     }
661fe6060f1SDimitry Andric 
662fe6060f1SDimitry Andric     template <typename _Fun>
663fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY static const __policy*
664fe6060f1SDimitry Andric         __choose_policy(/* is_small = */ true_type)
665fe6060f1SDimitry Andric     {
666*06c3fb27SDimitry Andric         static const _LIBCPP_CONSTEXPR __policy __policy = {
667fe6060f1SDimitry Andric             nullptr, nullptr, false,
6681ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI
669fe6060f1SDimitry Andric             &typeid(typename _Fun::_Target)
670fe6060f1SDimitry Andric #else
671fe6060f1SDimitry Andric             nullptr
672fe6060f1SDimitry Andric #endif
673fe6060f1SDimitry Andric         };
674*06c3fb27SDimitry Andric         return &__policy;
675fe6060f1SDimitry Andric     }
676fe6060f1SDimitry Andric };
677fe6060f1SDimitry Andric 
678fe6060f1SDimitry Andric // Used to choose between perfect forwarding or pass-by-value. Pass-by-value is
679fe6060f1SDimitry Andric // faster for types that can be passed in registers.
680fe6060f1SDimitry Andric template <typename _Tp>
681bdd1243dSDimitry Andric using __fast_forward = __conditional_t<is_scalar<_Tp>::value, _Tp, _Tp&&>;
682fe6060f1SDimitry Andric 
683fe6060f1SDimitry Andric // __policy_invoker calls an instance of __alloc_func held in __policy_storage.
684fe6060f1SDimitry Andric 
685fe6060f1SDimitry Andric template <class _Fp> struct __policy_invoker;
686fe6060f1SDimitry Andric 
687fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
688fe6060f1SDimitry Andric struct __policy_invoker<_Rp(_ArgTypes...)>
689fe6060f1SDimitry Andric {
690fe6060f1SDimitry Andric     typedef _Rp (*__Call)(const __policy_storage*,
691fe6060f1SDimitry Andric                           __fast_forward<_ArgTypes>...);
692fe6060f1SDimitry Andric 
693fe6060f1SDimitry Andric     __Call __call_;
694fe6060f1SDimitry Andric 
695fe6060f1SDimitry Andric     // Creates an invoker that throws bad_function_call.
696fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
697fe6060f1SDimitry Andric     __policy_invoker() : __call_(&__call_empty) {}
698fe6060f1SDimitry Andric 
699fe6060f1SDimitry Andric     // Creates an invoker that calls the given instance of __func.
700fe6060f1SDimitry Andric     template <typename _Fun>
701fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY static __policy_invoker __create()
702fe6060f1SDimitry Andric     {
703fe6060f1SDimitry Andric         return __policy_invoker(&__call_impl<_Fun>);
704fe6060f1SDimitry Andric     }
705fe6060f1SDimitry Andric 
706fe6060f1SDimitry Andric   private:
707fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
708fe6060f1SDimitry Andric     explicit __policy_invoker(__Call __c) : __call_(__c) {}
709fe6060f1SDimitry Andric 
710*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI static _Rp __call_empty(const __policy_storage*,
711fe6060f1SDimitry Andric                             __fast_forward<_ArgTypes>...)
712fe6060f1SDimitry Andric     {
713fe6060f1SDimitry Andric         __throw_bad_function_call();
714fe6060f1SDimitry Andric     }
715fe6060f1SDimitry Andric 
716fe6060f1SDimitry Andric     template <typename _Fun>
717*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI static _Rp __call_impl(const __policy_storage* __buf,
718fe6060f1SDimitry Andric                            __fast_forward<_ArgTypes>... __args)
719fe6060f1SDimitry Andric     {
720fe6060f1SDimitry Andric         _Fun* __f = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value
721fe6060f1SDimitry Andric                                                 ? &__buf->__small
722fe6060f1SDimitry Andric                                                 : __buf->__large);
723fe6060f1SDimitry Andric         return (*__f)(_VSTD::forward<_ArgTypes>(__args)...);
724fe6060f1SDimitry Andric     }
725fe6060f1SDimitry Andric };
726fe6060f1SDimitry Andric 
727fe6060f1SDimitry Andric // __policy_func uses a __policy and __policy_invoker to create a type-erased,
728fe6060f1SDimitry Andric // copyable functor.
729fe6060f1SDimitry Andric 
730fe6060f1SDimitry Andric template <class _Fp> class __policy_func;
731fe6060f1SDimitry Andric 
732fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> class __policy_func<_Rp(_ArgTypes...)>
733fe6060f1SDimitry Andric {
734fe6060f1SDimitry Andric     // Inline storage for small objects.
735fe6060f1SDimitry Andric     __policy_storage __buf_;
736fe6060f1SDimitry Andric 
737fe6060f1SDimitry Andric     // Calls the value stored in __buf_. This could technically be part of
738fe6060f1SDimitry Andric     // policy, but storing it here eliminates a level of indirection inside
739fe6060f1SDimitry Andric     // operator().
740fe6060f1SDimitry Andric     typedef __function::__policy_invoker<_Rp(_ArgTypes...)> __invoker;
741fe6060f1SDimitry Andric     __invoker __invoker_;
742fe6060f1SDimitry Andric 
743fe6060f1SDimitry Andric     // The policy that describes how to move / copy / destroy __buf_. Never
744fe6060f1SDimitry Andric     // null, even if the function is empty.
745fe6060f1SDimitry Andric     const __policy* __policy_;
746fe6060f1SDimitry Andric 
747fe6060f1SDimitry Andric   public:
748fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
749fe6060f1SDimitry Andric     __policy_func() : __policy_(__policy::__create_empty()) {}
750fe6060f1SDimitry Andric 
751fe6060f1SDimitry Andric     template <class _Fp, class _Alloc>
752fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY __policy_func(_Fp&& __f, const _Alloc& __a)
753fe6060f1SDimitry Andric         : __policy_(__policy::__create_empty())
754fe6060f1SDimitry Andric     {
755fe6060f1SDimitry Andric         typedef __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun;
756fe6060f1SDimitry Andric         typedef allocator_traits<_Alloc> __alloc_traits;
757bdd1243dSDimitry Andric         typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc;
758fe6060f1SDimitry Andric 
759fe6060f1SDimitry Andric         if (__function::__not_null(__f))
760fe6060f1SDimitry Andric         {
761fe6060f1SDimitry Andric             __invoker_ = __invoker::template __create<_Fun>();
762fe6060f1SDimitry Andric             __policy_ = __policy::__create<_Fun>();
763fe6060f1SDimitry Andric 
764fe6060f1SDimitry Andric             _FunAlloc __af(__a);
765fe6060f1SDimitry Andric             if (__use_small_storage<_Fun>())
766fe6060f1SDimitry Andric             {
767fe6060f1SDimitry Andric                 ::new ((void*)&__buf_.__small)
768fe6060f1SDimitry Andric                     _Fun(_VSTD::move(__f), _Alloc(__af));
769fe6060f1SDimitry Andric             }
770fe6060f1SDimitry Andric             else
771fe6060f1SDimitry Andric             {
772fe6060f1SDimitry Andric                 typedef __allocator_destructor<_FunAlloc> _Dp;
773fe6060f1SDimitry Andric                 unique_ptr<_Fun, _Dp> __hold(__af.allocate(1), _Dp(__af, 1));
774fe6060f1SDimitry Andric                 ::new ((void*)__hold.get())
775fe6060f1SDimitry Andric                     _Fun(_VSTD::move(__f), _Alloc(__af));
776fe6060f1SDimitry Andric                 __buf_.__large = __hold.release();
777fe6060f1SDimitry Andric             }
778fe6060f1SDimitry Andric         }
779fe6060f1SDimitry Andric     }
780fe6060f1SDimitry Andric 
781*06c3fb27SDimitry Andric     template <class _Fp, class = typename enable_if<!is_same<__decay_t<_Fp>, __policy_func>::value>::type>
782fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY explicit __policy_func(_Fp&& __f)
783fe6060f1SDimitry Andric         : __policy_(__policy::__create_empty()) {
784fe6060f1SDimitry Andric       typedef __default_alloc_func<_Fp, _Rp(_ArgTypes...)> _Fun;
785fe6060f1SDimitry Andric 
786fe6060f1SDimitry Andric       if (__function::__not_null(__f)) {
787fe6060f1SDimitry Andric         __invoker_ = __invoker::template __create<_Fun>();
788fe6060f1SDimitry Andric         __policy_ = __policy::__create<_Fun>();
789fe6060f1SDimitry Andric         if (__use_small_storage<_Fun>()) {
790fe6060f1SDimitry Andric           ::new ((void*)&__buf_.__small) _Fun(_VSTD::move(__f));
791fe6060f1SDimitry Andric         } else {
792fe6060f1SDimitry Andric           __builtin_new_allocator::__holder_t __hold =
793fe6060f1SDimitry Andric               __builtin_new_allocator::__allocate_type<_Fun>(1);
794fe6060f1SDimitry Andric           __buf_.__large = ::new ((void*)__hold.get()) _Fun(_VSTD::move(__f));
795fe6060f1SDimitry Andric           (void)__hold.release();
796fe6060f1SDimitry Andric         }
797fe6060f1SDimitry Andric       }
798fe6060f1SDimitry Andric     }
799fe6060f1SDimitry Andric 
800fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
801fe6060f1SDimitry Andric     __policy_func(const __policy_func& __f)
802fe6060f1SDimitry Andric         : __buf_(__f.__buf_), __invoker_(__f.__invoker_),
803fe6060f1SDimitry Andric           __policy_(__f.__policy_)
804fe6060f1SDimitry Andric     {
805fe6060f1SDimitry Andric         if (__policy_->__clone)
806fe6060f1SDimitry Andric             __buf_.__large = __policy_->__clone(__f.__buf_.__large);
807fe6060f1SDimitry Andric     }
808fe6060f1SDimitry Andric 
809fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
810fe6060f1SDimitry Andric     __policy_func(__policy_func&& __f)
811fe6060f1SDimitry Andric         : __buf_(__f.__buf_), __invoker_(__f.__invoker_),
812fe6060f1SDimitry Andric           __policy_(__f.__policy_)
813fe6060f1SDimitry Andric     {
814fe6060f1SDimitry Andric         if (__policy_->__destroy)
815fe6060f1SDimitry Andric         {
816fe6060f1SDimitry Andric             __f.__policy_ = __policy::__create_empty();
817fe6060f1SDimitry Andric             __f.__invoker_ = __invoker();
818fe6060f1SDimitry Andric         }
819fe6060f1SDimitry Andric     }
820fe6060f1SDimitry Andric 
821fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
822fe6060f1SDimitry Andric     ~__policy_func()
823fe6060f1SDimitry Andric     {
824fe6060f1SDimitry Andric         if (__policy_->__destroy)
825fe6060f1SDimitry Andric             __policy_->__destroy(__buf_.__large);
826fe6060f1SDimitry Andric     }
827fe6060f1SDimitry Andric 
828fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
829fe6060f1SDimitry Andric     __policy_func& operator=(__policy_func&& __f)
830fe6060f1SDimitry Andric     {
831fe6060f1SDimitry Andric         *this = nullptr;
832fe6060f1SDimitry Andric         __buf_ = __f.__buf_;
833fe6060f1SDimitry Andric         __invoker_ = __f.__invoker_;
834fe6060f1SDimitry Andric         __policy_ = __f.__policy_;
835fe6060f1SDimitry Andric         __f.__policy_ = __policy::__create_empty();
836fe6060f1SDimitry Andric         __f.__invoker_ = __invoker();
837fe6060f1SDimitry Andric         return *this;
838fe6060f1SDimitry Andric     }
839fe6060f1SDimitry Andric 
840fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
841fe6060f1SDimitry Andric     __policy_func& operator=(nullptr_t)
842fe6060f1SDimitry Andric     {
843fe6060f1SDimitry Andric         const __policy* __p = __policy_;
844fe6060f1SDimitry Andric         __policy_ = __policy::__create_empty();
845fe6060f1SDimitry Andric         __invoker_ = __invoker();
846fe6060f1SDimitry Andric         if (__p->__destroy)
847fe6060f1SDimitry Andric             __p->__destroy(__buf_.__large);
848fe6060f1SDimitry Andric         return *this;
849fe6060f1SDimitry Andric     }
850fe6060f1SDimitry Andric 
851fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
852fe6060f1SDimitry Andric     _Rp operator()(_ArgTypes&&... __args) const
853fe6060f1SDimitry Andric     {
854fe6060f1SDimitry Andric         return __invoker_.__call_(_VSTD::addressof(__buf_),
855fe6060f1SDimitry Andric                                   _VSTD::forward<_ArgTypes>(__args)...);
856fe6060f1SDimitry Andric     }
857fe6060f1SDimitry Andric 
858fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
859fe6060f1SDimitry Andric     void swap(__policy_func& __f)
860fe6060f1SDimitry Andric     {
861fe6060f1SDimitry Andric         _VSTD::swap(__invoker_, __f.__invoker_);
862fe6060f1SDimitry Andric         _VSTD::swap(__policy_, __f.__policy_);
863fe6060f1SDimitry Andric         _VSTD::swap(__buf_, __f.__buf_);
864fe6060f1SDimitry Andric     }
865fe6060f1SDimitry Andric 
866fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
867fe6060f1SDimitry Andric     explicit operator bool() const _NOEXCEPT
868fe6060f1SDimitry Andric     {
869fe6060f1SDimitry Andric         return !__policy_->__is_null;
870fe6060f1SDimitry Andric     }
871fe6060f1SDimitry Andric 
8721ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI
873fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
874fe6060f1SDimitry Andric     const std::type_info& target_type() const _NOEXCEPT
875fe6060f1SDimitry Andric     {
876fe6060f1SDimitry Andric         return *__policy_->__type_info;
877fe6060f1SDimitry Andric     }
878fe6060f1SDimitry Andric 
879fe6060f1SDimitry Andric     template <typename _Tp>
880fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT
881fe6060f1SDimitry Andric     {
882fe6060f1SDimitry Andric         if (__policy_->__is_null || typeid(_Tp) != *__policy_->__type_info)
883fe6060f1SDimitry Andric             return nullptr;
884fe6060f1SDimitry Andric         if (__policy_->__clone) // Out of line storage.
885fe6060f1SDimitry Andric             return reinterpret_cast<const _Tp*>(__buf_.__large);
886fe6060f1SDimitry Andric         else
887fe6060f1SDimitry Andric             return reinterpret_cast<const _Tp*>(&__buf_.__small);
888fe6060f1SDimitry Andric     }
8891ac55f4cSDimitry Andric #endif // _LIBCPP_HAS_NO_RTTI
890fe6060f1SDimitry Andric };
891fe6060f1SDimitry Andric 
892f3fd488fSDimitry Andric #if defined(_LIBCPP_HAS_BLOCKS_RUNTIME)
893fe6060f1SDimitry Andric 
894fe6060f1SDimitry Andric extern "C" void *_Block_copy(const void *);
895fe6060f1SDimitry Andric extern "C" void _Block_release(const void *);
896fe6060f1SDimitry Andric 
897fe6060f1SDimitry Andric template<class _Rp1, class ..._ArgTypes1, class _Alloc, class _Rp, class ..._ArgTypes>
898fe6060f1SDimitry Andric class __func<_Rp1(^)(_ArgTypes1...), _Alloc, _Rp(_ArgTypes...)>
899fe6060f1SDimitry Andric     : public  __base<_Rp(_ArgTypes...)>
900fe6060f1SDimitry Andric {
901fe6060f1SDimitry Andric     typedef _Rp1(^__block_type)(_ArgTypes1...);
902fe6060f1SDimitry Andric     __block_type __f_;
903fe6060f1SDimitry Andric 
904fe6060f1SDimitry Andric public:
905fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
906fe6060f1SDimitry Andric     explicit __func(__block_type const& __f)
907f3fd488fSDimitry Andric #ifdef _LIBCPP_HAS_OBJC_ARC
908f3fd488fSDimitry Andric         : __f_(__f)
909f3fd488fSDimitry Andric #else
910fe6060f1SDimitry Andric         : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr))
911f3fd488fSDimitry Andric #endif
912fe6060f1SDimitry Andric     { }
913fe6060f1SDimitry Andric 
914fe6060f1SDimitry Andric     // [TODO] add && to save on a retain
915fe6060f1SDimitry Andric 
916fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
917fe6060f1SDimitry Andric     explicit __func(__block_type __f, const _Alloc& /* unused */)
918f3fd488fSDimitry Andric #ifdef _LIBCPP_HAS_OBJC_ARC
919f3fd488fSDimitry Andric         : __f_(__f)
920f3fd488fSDimitry Andric #else
921fe6060f1SDimitry Andric         : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr))
922f3fd488fSDimitry Andric #endif
923fe6060f1SDimitry Andric     { }
924fe6060f1SDimitry Andric 
925fe6060f1SDimitry Andric     virtual __base<_Rp(_ArgTypes...)>* __clone() const {
926*06c3fb27SDimitry Andric         _LIBCPP_ASSERT_INTERNAL(false,
927fe6060f1SDimitry Andric             "Block pointers are just pointers, so they should always fit into "
928fe6060f1SDimitry Andric             "std::function's small buffer optimization. This function should "
929fe6060f1SDimitry Andric             "never be invoked.");
930fe6060f1SDimitry Andric         return nullptr;
931fe6060f1SDimitry Andric     }
932fe6060f1SDimitry Andric 
933fe6060f1SDimitry Andric     virtual void __clone(__base<_Rp(_ArgTypes...)>* __p) const {
934fe6060f1SDimitry Andric         ::new ((void*)__p) __func(__f_);
935fe6060f1SDimitry Andric     }
936fe6060f1SDimitry Andric 
937fe6060f1SDimitry Andric     virtual void destroy() _NOEXCEPT {
938f3fd488fSDimitry Andric #ifndef _LIBCPP_HAS_OBJC_ARC
939fe6060f1SDimitry Andric         if (__f_)
940fe6060f1SDimitry Andric             _Block_release(__f_);
941f3fd488fSDimitry Andric #endif
942fe6060f1SDimitry Andric         __f_ = 0;
943fe6060f1SDimitry Andric     }
944fe6060f1SDimitry Andric 
945fe6060f1SDimitry Andric     virtual void destroy_deallocate() _NOEXCEPT {
946*06c3fb27SDimitry Andric         _LIBCPP_ASSERT_INTERNAL(false,
947fe6060f1SDimitry Andric             "Block pointers are just pointers, so they should always fit into "
948fe6060f1SDimitry Andric             "std::function's small buffer optimization. This function should "
949fe6060f1SDimitry Andric             "never be invoked.");
950fe6060f1SDimitry Andric     }
951fe6060f1SDimitry Andric 
952fe6060f1SDimitry Andric     virtual _Rp operator()(_ArgTypes&& ... __arg) {
953fe6060f1SDimitry Andric         return _VSTD::__invoke(__f_, _VSTD::forward<_ArgTypes>(__arg)...);
954fe6060f1SDimitry Andric     }
955fe6060f1SDimitry Andric 
9561ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI
957fe6060f1SDimitry Andric     virtual const void* target(type_info const& __ti) const _NOEXCEPT {
958fe6060f1SDimitry Andric         if (__ti == typeid(__func::__block_type))
959fe6060f1SDimitry Andric             return &__f_;
960fe6060f1SDimitry Andric         return (const void*)nullptr;
961fe6060f1SDimitry Andric     }
962fe6060f1SDimitry Andric 
963fe6060f1SDimitry Andric     virtual const std::type_info& target_type() const _NOEXCEPT {
964fe6060f1SDimitry Andric         return typeid(__func::__block_type);
965fe6060f1SDimitry Andric     }
9661ac55f4cSDimitry Andric #endif // _LIBCPP_HAS_NO_RTTI
967fe6060f1SDimitry Andric };
968fe6060f1SDimitry Andric 
969f3fd488fSDimitry Andric #endif // _LIBCPP_HAS_EXTENSION_BLOCKS
970fe6060f1SDimitry Andric 
9710eae32dcSDimitry Andric } // namespace __function
972fe6060f1SDimitry Andric 
973fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
974fe6060f1SDimitry Andric class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)>
975fe6060f1SDimitry Andric     : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>,
976fe6060f1SDimitry Andric       public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)>
977fe6060f1SDimitry Andric {
978fe6060f1SDimitry Andric #ifndef _LIBCPP_ABI_OPTIMIZED_FUNCTION
979fe6060f1SDimitry Andric     typedef __function::__value_func<_Rp(_ArgTypes...)> __func;
980fe6060f1SDimitry Andric #else
981fe6060f1SDimitry Andric     typedef __function::__policy_func<_Rp(_ArgTypes...)> __func;
982fe6060f1SDimitry Andric #endif
983fe6060f1SDimitry Andric 
984fe6060f1SDimitry Andric     __func __f_;
985fe6060f1SDimitry Andric 
986fe6060f1SDimitry Andric     template <class _Fp, bool = _And<
987bdd1243dSDimitry Andric         _IsNotSame<__remove_cvref_t<_Fp>, function>,
988fe6060f1SDimitry Andric         __invokable<_Fp, _ArgTypes...>
989fe6060f1SDimitry Andric     >::value>
990fe6060f1SDimitry Andric     struct __callable;
991fe6060f1SDimitry Andric     template <class _Fp>
992fe6060f1SDimitry Andric         struct __callable<_Fp, true>
993fe6060f1SDimitry Andric         {
994fe6060f1SDimitry Andric             static const bool value = is_void<_Rp>::value ||
995fe6060f1SDimitry Andric                 __is_core_convertible<typename __invoke_of<_Fp, _ArgTypes...>::type,
996fe6060f1SDimitry Andric                                       _Rp>::value;
997fe6060f1SDimitry Andric         };
998fe6060f1SDimitry Andric     template <class _Fp>
999fe6060f1SDimitry Andric         struct __callable<_Fp, false>
1000fe6060f1SDimitry Andric         {
1001fe6060f1SDimitry Andric             static const bool value = false;
1002fe6060f1SDimitry Andric         };
1003fe6060f1SDimitry Andric 
1004fe6060f1SDimitry Andric   template <class _Fp>
1005fe6060f1SDimitry Andric   using _EnableIfLValueCallable = typename enable_if<__callable<_Fp&>::value>::type;
1006fe6060f1SDimitry Andric public:
1007fe6060f1SDimitry Andric     typedef _Rp result_type;
1008fe6060f1SDimitry Andric 
1009fe6060f1SDimitry Andric     // construct/copy/destroy:
1010fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
1011fe6060f1SDimitry Andric     function() _NOEXCEPT { }
1012fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
1013*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI function(nullptr_t) _NOEXCEPT {}
1014*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI function(const function&);
1015*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI function(function&&) _NOEXCEPT;
1016fe6060f1SDimitry Andric     template<class _Fp, class = _EnableIfLValueCallable<_Fp>>
1017*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI function(_Fp);
1018fe6060f1SDimitry Andric 
1019fe6060f1SDimitry Andric #if _LIBCPP_STD_VER <= 14
1020fe6060f1SDimitry Andric     template<class _Alloc>
1021fe6060f1SDimitry Andric       _LIBCPP_INLINE_VISIBILITY
1022fe6060f1SDimitry Andric       function(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
1023fe6060f1SDimitry Andric     template<class _Alloc>
1024fe6060f1SDimitry Andric       _LIBCPP_INLINE_VISIBILITY
1025fe6060f1SDimitry Andric       function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {}
1026fe6060f1SDimitry Andric     template<class _Alloc>
1027*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, const function&);
1028fe6060f1SDimitry Andric     template<class _Alloc>
1029*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, function&&);
1030fe6060f1SDimitry Andric     template<class _Fp, class _Alloc, class = _EnableIfLValueCallable<_Fp>>
1031*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc& __a, _Fp __f);
1032fe6060f1SDimitry Andric #endif
1033fe6060f1SDimitry Andric 
1034*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI function& operator=(const function&);
1035*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI function& operator=(function&&) _NOEXCEPT;
1036*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI function& operator=(nullptr_t) _NOEXCEPT;
1037*06c3fb27SDimitry Andric     template<class _Fp, class = _EnableIfLValueCallable<__decay_t<_Fp>>>
1038*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI function& operator=(_Fp&&);
1039fe6060f1SDimitry Andric 
1040*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI ~function();
1041fe6060f1SDimitry Andric 
1042fe6060f1SDimitry Andric     // function modifiers:
1043*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI void swap(function&) _NOEXCEPT;
1044fe6060f1SDimitry Andric 
1045fe6060f1SDimitry Andric #if _LIBCPP_STD_VER <= 14
1046fe6060f1SDimitry Andric     template<class _Fp, class _Alloc>
1047fe6060f1SDimitry Andric       _LIBCPP_INLINE_VISIBILITY
1048fe6060f1SDimitry Andric       void assign(_Fp&& __f, const _Alloc& __a)
1049fe6060f1SDimitry Andric         {function(allocator_arg, __a, _VSTD::forward<_Fp>(__f)).swap(*this);}
1050fe6060f1SDimitry Andric #endif
1051fe6060f1SDimitry Andric 
1052fe6060f1SDimitry Andric     // function capacity:
1053fe6060f1SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
1054fe6060f1SDimitry Andric     explicit operator bool() const _NOEXCEPT {
1055fe6060f1SDimitry Andric       return static_cast<bool>(__f_);
1056fe6060f1SDimitry Andric     }
1057fe6060f1SDimitry Andric 
1058fe6060f1SDimitry Andric     // deleted overloads close possible hole in the type system
1059fe6060f1SDimitry Andric     template<class _R2, class... _ArgTypes2>
1060fe6060f1SDimitry Andric       bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete;
1061*06c3fb27SDimitry Andric #if _LIBCPP_STD_VER <= 17
1062fe6060f1SDimitry Andric     template<class _R2, class... _ArgTypes2>
1063fe6060f1SDimitry Andric       bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete;
1064*06c3fb27SDimitry Andric #endif
1065fe6060f1SDimitry Andric public:
1066fe6060f1SDimitry Andric     // function invocation:
1067*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes...) const;
1068fe6060f1SDimitry Andric 
10691ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI
1070fe6060f1SDimitry Andric     // function target access:
1071*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT;
1072*06c3fb27SDimitry Andric     template <typename _Tp>
1073*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _Tp* target() _NOEXCEPT;
1074*06c3fb27SDimitry Andric     template <typename _Tp>
1075*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT;
10761ac55f4cSDimitry Andric #endif // _LIBCPP_HAS_NO_RTTI
1077fe6060f1SDimitry Andric };
1078fe6060f1SDimitry Andric 
1079349cc55cSDimitry Andric #if _LIBCPP_STD_VER >= 17
1080fe6060f1SDimitry Andric template<class _Rp, class ..._Ap>
1081fe6060f1SDimitry Andric function(_Rp(*)(_Ap...)) -> function<_Rp(_Ap...)>;
1082fe6060f1SDimitry Andric 
1083fe6060f1SDimitry Andric template<class _Fp, class _Stripped = typename __strip_signature<decltype(&_Fp::operator())>::type>
1084fe6060f1SDimitry Andric function(_Fp) -> function<_Stripped>;
1085349cc55cSDimitry Andric #endif // _LIBCPP_STD_VER >= 17
1086fe6060f1SDimitry Andric 
1087fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1088fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(const function& __f) : __f_(__f.__f_) {}
1089fe6060f1SDimitry Andric 
1090fe6060f1SDimitry Andric #if _LIBCPP_STD_VER <= 14
1091fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1092fe6060f1SDimitry Andric template <class _Alloc>
1093fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&,
1094fe6060f1SDimitry Andric                                      const function& __f) : __f_(__f.__f_) {}
1095fe6060f1SDimitry Andric #endif
1096fe6060f1SDimitry Andric 
1097fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1098fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT
1099fe6060f1SDimitry Andric     : __f_(_VSTD::move(__f.__f_)) {}
1100fe6060f1SDimitry Andric 
1101fe6060f1SDimitry Andric #if _LIBCPP_STD_VER <= 14
1102fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1103fe6060f1SDimitry Andric template <class _Alloc>
1104fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&,
1105fe6060f1SDimitry Andric                                       function&& __f)
1106fe6060f1SDimitry Andric     : __f_(_VSTD::move(__f.__f_)) {}
1107fe6060f1SDimitry Andric #endif
1108fe6060f1SDimitry Andric 
1109fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1110fe6060f1SDimitry Andric template <class _Fp, class>
1111fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(_Fp __f) : __f_(_VSTD::move(__f)) {}
1112fe6060f1SDimitry Andric 
1113fe6060f1SDimitry Andric #if _LIBCPP_STD_VER <= 14
1114fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1115fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class>
1116fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a,
1117fe6060f1SDimitry Andric                                       _Fp __f)
1118fe6060f1SDimitry Andric     : __f_(_VSTD::move(__f), __a) {}
1119fe6060f1SDimitry Andric #endif
1120fe6060f1SDimitry Andric 
1121fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1122fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>&
1123fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::operator=(const function& __f)
1124fe6060f1SDimitry Andric {
1125fe6060f1SDimitry Andric     function(__f).swap(*this);
1126fe6060f1SDimitry Andric     return *this;
1127fe6060f1SDimitry Andric }
1128fe6060f1SDimitry Andric 
1129fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1130fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>&
1131fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT
1132fe6060f1SDimitry Andric {
1133fe6060f1SDimitry Andric     __f_ = _VSTD::move(__f.__f_);
1134fe6060f1SDimitry Andric     return *this;
1135fe6060f1SDimitry Andric }
1136fe6060f1SDimitry Andric 
1137fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1138fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>&
1139fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT
1140fe6060f1SDimitry Andric {
1141fe6060f1SDimitry Andric     __f_ = nullptr;
1142fe6060f1SDimitry Andric     return *this;
1143fe6060f1SDimitry Andric }
1144fe6060f1SDimitry Andric 
1145fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1146fe6060f1SDimitry Andric template <class _Fp, class>
1147fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>&
1148fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f)
1149fe6060f1SDimitry Andric {
1150fe6060f1SDimitry Andric     function(_VSTD::forward<_Fp>(__f)).swap(*this);
1151fe6060f1SDimitry Andric     return *this;
1152fe6060f1SDimitry Andric }
1153fe6060f1SDimitry Andric 
1154fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1155fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::~function() {}
1156fe6060f1SDimitry Andric 
1157fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1158fe6060f1SDimitry Andric void
1159fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT
1160fe6060f1SDimitry Andric {
1161fe6060f1SDimitry Andric     __f_.swap(__f.__f_);
1162fe6060f1SDimitry Andric }
1163fe6060f1SDimitry Andric 
1164fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1165fe6060f1SDimitry Andric _Rp
1166fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
1167fe6060f1SDimitry Andric {
1168fe6060f1SDimitry Andric     return __f_(_VSTD::forward<_ArgTypes>(__arg)...);
1169fe6060f1SDimitry Andric }
1170fe6060f1SDimitry Andric 
11711ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI
1172fe6060f1SDimitry Andric 
1173fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1174fe6060f1SDimitry Andric const std::type_info&
1175fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT
1176fe6060f1SDimitry Andric {
1177fe6060f1SDimitry Andric     return __f_.target_type();
1178fe6060f1SDimitry Andric }
1179fe6060f1SDimitry Andric 
1180fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1181fe6060f1SDimitry Andric template <typename _Tp>
1182fe6060f1SDimitry Andric _Tp*
1183fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::target() _NOEXCEPT
1184fe6060f1SDimitry Andric {
1185fe6060f1SDimitry Andric     return (_Tp*)(__f_.template target<_Tp>());
1186fe6060f1SDimitry Andric }
1187fe6060f1SDimitry Andric 
1188fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1189fe6060f1SDimitry Andric template <typename _Tp>
1190fe6060f1SDimitry Andric const _Tp*
1191fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT
1192fe6060f1SDimitry Andric {
1193fe6060f1SDimitry Andric     return __f_.template target<_Tp>();
1194fe6060f1SDimitry Andric }
1195fe6060f1SDimitry Andric 
11961ac55f4cSDimitry Andric #endif // _LIBCPP_HAS_NO_RTTI
1197fe6060f1SDimitry Andric 
1198fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1199fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY
1200fe6060f1SDimitry Andric bool
1201fe6060f1SDimitry Andric operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return !__f;}
1202fe6060f1SDimitry Andric 
1203*06c3fb27SDimitry Andric #if _LIBCPP_STD_VER <= 17
1204*06c3fb27SDimitry Andric 
1205fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1206fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY
1207fe6060f1SDimitry Andric bool
1208fe6060f1SDimitry Andric operator==(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return !__f;}
1209fe6060f1SDimitry Andric 
1210fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1211fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY
1212fe6060f1SDimitry Andric bool
1213fe6060f1SDimitry Andric operator!=(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return (bool)__f;}
1214fe6060f1SDimitry Andric 
1215fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1216fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY
1217fe6060f1SDimitry Andric bool
1218fe6060f1SDimitry Andric operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return (bool)__f;}
1219fe6060f1SDimitry Andric 
1220*06c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER <= 17
1221*06c3fb27SDimitry Andric 
1222fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1223fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY
1224fe6060f1SDimitry Andric void
1225fe6060f1SDimitry Andric swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCEPT
1226fe6060f1SDimitry Andric {return __x.swap(__y);}
1227fe6060f1SDimitry Andric 
1228bdd1243dSDimitry Andric _LIBCPP_END_NAMESPACE_STD
1229fe6060f1SDimitry Andric 
123081ad6265SDimitry Andric #endif // _LIBCPP_CXX03_LANG
1231fe6060f1SDimitry Andric 
1232fe6060f1SDimitry Andric #endif // _LIBCPP___FUNCTIONAL_FUNCTION_H
1233