blob: 56a84753af3715abcf52fcb046a85cb0682752d6 [file] [log] [blame]
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
Howard Hinnantf5256e12010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005//
Howard Hinnantb64f8b02010-11-16 22:09:02 +00006// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00008//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_FUNCTIONAL_03
12#define _LIBCPP_FUNCTIONAL_03
13
14// manual variadic expansion for <functional>
15
Howard Hinnant08e17472011-10-17 20:05:10 +000016#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000017#pragma GCC system_header
Howard Hinnant08e17472011-10-17 20:05:10 +000018#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000019
Eric Fiselier45f63bc2015-07-22 04:14:38 +000020namespace __function {
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000021
22template<class _Fp> class __base;
23
Howard Hinnant99968442011-11-29 18:15:50 +000024template<class _Rp>
25class __base<_Rp()>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000026{
27 __base(const __base&);
28 __base& operator=(const __base&);
29public:
30 __base() {}
31 virtual ~__base() {}
32 virtual __base* __clone() const = 0;
33 virtual void __clone(__base*) const = 0;
34 virtual void destroy() = 0;
35 virtual void destroy_deallocate() = 0;
Howard Hinnant99968442011-11-29 18:15:50 +000036 virtual _Rp operator()() = 0;
Howard Hinnantd4444702010-08-11 17:04:31 +000037#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000038 virtual const void* target(const type_info&) const = 0;
39 virtual const std::type_info& target_type() const = 0;
Howard Hinnant324bb032010-08-22 00:02:43 +000040#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000041};
42
Howard Hinnant99968442011-11-29 18:15:50 +000043template<class _Rp, class _A0>
44class __base<_Rp(_A0)>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000045{
46 __base(const __base&);
47 __base& operator=(const __base&);
48public:
49 __base() {}
50 virtual ~__base() {}
51 virtual __base* __clone() const = 0;
52 virtual void __clone(__base*) const = 0;
53 virtual void destroy() = 0;
54 virtual void destroy_deallocate() = 0;
Howard Hinnant99968442011-11-29 18:15:50 +000055 virtual _Rp operator()(_A0) = 0;
Howard Hinnantd4444702010-08-11 17:04:31 +000056#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000057 virtual const void* target(const type_info&) const = 0;
58 virtual const std::type_info& target_type() const = 0;
Howard Hinnant324bb032010-08-22 00:02:43 +000059#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000060};
61
Howard Hinnant99968442011-11-29 18:15:50 +000062template<class _Rp, class _A0, class _A1>
63class __base<_Rp(_A0, _A1)>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000064{
65 __base(const __base&);
66 __base& operator=(const __base&);
67public:
68 __base() {}
69 virtual ~__base() {}
70 virtual __base* __clone() const = 0;
71 virtual void __clone(__base*) const = 0;
72 virtual void destroy() = 0;
73 virtual void destroy_deallocate() = 0;
Howard Hinnant99968442011-11-29 18:15:50 +000074 virtual _Rp operator()(_A0, _A1) = 0;
Howard Hinnantd4444702010-08-11 17:04:31 +000075#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000076 virtual const void* target(const type_info&) const = 0;
77 virtual const std::type_info& target_type() const = 0;
Howard Hinnant324bb032010-08-22 00:02:43 +000078#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000079};
80
Howard Hinnant99968442011-11-29 18:15:50 +000081template<class _Rp, class _A0, class _A1, class _A2>
82class __base<_Rp(_A0, _A1, _A2)>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000083{
84 __base(const __base&);
85 __base& operator=(const __base&);
86public:
87 __base() {}
88 virtual ~__base() {}
89 virtual __base* __clone() const = 0;
90 virtual void __clone(__base*) const = 0;
91 virtual void destroy() = 0;
92 virtual void destroy_deallocate() = 0;
Howard Hinnant99968442011-11-29 18:15:50 +000093 virtual _Rp operator()(_A0, _A1, _A2) = 0;
Howard Hinnantd4444702010-08-11 17:04:31 +000094#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000095 virtual const void* target(const type_info&) const = 0;
96 virtual const std::type_info& target_type() const = 0;
Howard Hinnant324bb032010-08-22 00:02:43 +000097#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000098};
99
100template<class _FD, class _Alloc, class _FB> class __func;
101
Howard Hinnant99968442011-11-29 18:15:50 +0000102template<class _Fp, class _Alloc, class _Rp>
103class __func<_Fp, _Alloc, _Rp()>
104 : public __base<_Rp()>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000105{
Howard Hinnant99968442011-11-29 18:15:50 +0000106 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000107public:
Howard Hinnant99968442011-11-29 18:15:50 +0000108 explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {}
109 explicit __func(_Fp __f, _Alloc __a) : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
110 virtual __base<_Rp()>* __clone() const;
111 virtual void __clone(__base<_Rp()>*) const;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000112 virtual void destroy();
113 virtual void destroy_deallocate();
Howard Hinnant99968442011-11-29 18:15:50 +0000114 virtual _Rp operator()();
Howard Hinnantd4444702010-08-11 17:04:31 +0000115#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000116 virtual const void* target(const type_info&) const;
117 virtual const std::type_info& target_type() const;
Howard Hinnant324bb032010-08-22 00:02:43 +0000118#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000119};
120
Howard Hinnant99968442011-11-29 18:15:50 +0000121template<class _Fp, class _Alloc, class _Rp>
122__base<_Rp()>*
123__func<_Fp, _Alloc, _Rp()>::__clone() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000124{
Eric Fiselierb05f0592015-06-14 23:30:09 +0000125 typedef allocator_traits<_Alloc> __alloc_traits;
126 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
Howard Hinnant99968442011-11-29 18:15:50 +0000127 _Ap __a(__f_.second());
128 typedef __allocator_destructor<_Ap> _Dp;
129 unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000130 ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
131 return __hold.release();
132}
133
Howard Hinnant99968442011-11-29 18:15:50 +0000134template<class _Fp, class _Alloc, class _Rp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000135void
Howard Hinnant99968442011-11-29 18:15:50 +0000136__func<_Fp, _Alloc, _Rp()>::__clone(__base<_Rp()>* __p) const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000137{
138 ::new (__p) __func(__f_.first(), __f_.second());
139}
140
Howard Hinnant99968442011-11-29 18:15:50 +0000141template<class _Fp, class _Alloc, class _Rp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000142void
Howard Hinnant99968442011-11-29 18:15:50 +0000143__func<_Fp, _Alloc, _Rp()>::destroy()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000144{
Howard Hinnant99968442011-11-29 18:15:50 +0000145 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000146}
147
Howard Hinnant99968442011-11-29 18:15:50 +0000148template<class _Fp, class _Alloc, class _Rp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000149void
Howard Hinnant99968442011-11-29 18:15:50 +0000150__func<_Fp, _Alloc, _Rp()>::destroy_deallocate()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000151{
Eric Fiselierb05f0592015-06-14 23:30:09 +0000152 typedef allocator_traits<_Alloc> __alloc_traits;
153 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
Howard Hinnant99968442011-11-29 18:15:50 +0000154 _Ap __a(__f_.second());
155 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000156 __a.deallocate(this, 1);
157}
158
Howard Hinnant99968442011-11-29 18:15:50 +0000159template<class _Fp, class _Alloc, class _Rp>
160_Rp
161__func<_Fp, _Alloc, _Rp()>::operator()()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000162{
Eric Fiselierc3231d22015-02-10 16:48:45 +0000163 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
164 return _Invoker::__call(__f_.first());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000165}
166
Howard Hinnantd4444702010-08-11 17:04:31 +0000167#ifndef _LIBCPP_NO_RTTI
168
Howard Hinnant99968442011-11-29 18:15:50 +0000169template<class _Fp, class _Alloc, class _Rp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000170const void*
Howard Hinnant99968442011-11-29 18:15:50 +0000171__func<_Fp, _Alloc, _Rp()>::target(const type_info& __ti) const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000172{
Howard Hinnant99968442011-11-29 18:15:50 +0000173 if (__ti == typeid(_Fp))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000174 return &__f_.first();
175 return (const void*)0;
176}
177
Howard Hinnant99968442011-11-29 18:15:50 +0000178template<class _Fp, class _Alloc, class _Rp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000179const std::type_info&
Howard Hinnant99968442011-11-29 18:15:50 +0000180__func<_Fp, _Alloc, _Rp()>::target_type() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000181{
Howard Hinnant99968442011-11-29 18:15:50 +0000182 return typeid(_Fp);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000183}
184
Howard Hinnant324bb032010-08-22 00:02:43 +0000185#endif // _LIBCPP_NO_RTTI
Howard Hinnantd4444702010-08-11 17:04:31 +0000186
Howard Hinnant99968442011-11-29 18:15:50 +0000187template<class _Fp, class _Alloc, class _Rp, class _A0>
188class __func<_Fp, _Alloc, _Rp(_A0)>
189 : public __base<_Rp(_A0)>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000190{
Howard Hinnant99968442011-11-29 18:15:50 +0000191 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000192public:
Howard Hinnant99968442011-11-29 18:15:50 +0000193 _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {}
194 _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000195 : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
Howard Hinnant99968442011-11-29 18:15:50 +0000196 virtual __base<_Rp(_A0)>* __clone() const;
197 virtual void __clone(__base<_Rp(_A0)>*) const;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000198 virtual void destroy();
199 virtual void destroy_deallocate();
Howard Hinnant99968442011-11-29 18:15:50 +0000200 virtual _Rp operator()(_A0);
Howard Hinnantd4444702010-08-11 17:04:31 +0000201#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000202 virtual const void* target(const type_info&) const;
203 virtual const std::type_info& target_type() const;
Howard Hinnant324bb032010-08-22 00:02:43 +0000204#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000205};
206
Howard Hinnant99968442011-11-29 18:15:50 +0000207template<class _Fp, class _Alloc, class _Rp, class _A0>
208__base<_Rp(_A0)>*
209__func<_Fp, _Alloc, _Rp(_A0)>::__clone() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000210{
Eric Fiselierb05f0592015-06-14 23:30:09 +0000211 typedef allocator_traits<_Alloc> __alloc_traits;
212 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
Howard Hinnant99968442011-11-29 18:15:50 +0000213 _Ap __a(__f_.second());
214 typedef __allocator_destructor<_Ap> _Dp;
215 unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000216 ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
217 return __hold.release();
218}
219
Howard Hinnant99968442011-11-29 18:15:50 +0000220template<class _Fp, class _Alloc, class _Rp, class _A0>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000221void
Howard Hinnant99968442011-11-29 18:15:50 +0000222__func<_Fp, _Alloc, _Rp(_A0)>::__clone(__base<_Rp(_A0)>* __p) const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000223{
224 ::new (__p) __func(__f_.first(), __f_.second());
225}
226
Howard Hinnant99968442011-11-29 18:15:50 +0000227template<class _Fp, class _Alloc, class _Rp, class _A0>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000228void
Howard Hinnant99968442011-11-29 18:15:50 +0000229__func<_Fp, _Alloc, _Rp(_A0)>::destroy()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000230{
Howard Hinnant99968442011-11-29 18:15:50 +0000231 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000232}
233
Howard Hinnant99968442011-11-29 18:15:50 +0000234template<class _Fp, class _Alloc, class _Rp, class _A0>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000235void
Howard Hinnant99968442011-11-29 18:15:50 +0000236__func<_Fp, _Alloc, _Rp(_A0)>::destroy_deallocate()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000237{
Eric Fiselierb05f0592015-06-14 23:30:09 +0000238 typedef allocator_traits<_Alloc> __alloc_traits;
239 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
Howard Hinnant99968442011-11-29 18:15:50 +0000240 _Ap __a(__f_.second());
241 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000242 __a.deallocate(this, 1);
243}
244
Howard Hinnant99968442011-11-29 18:15:50 +0000245template<class _Fp, class _Alloc, class _Rp, class _A0>
246_Rp
247__func<_Fp, _Alloc, _Rp(_A0)>::operator()(_A0 __a0)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000248{
Eric Fiselierc3231d22015-02-10 16:48:45 +0000249 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
250 return _Invoker::__call(__f_.first(), __a0);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000251}
252
Howard Hinnantd4444702010-08-11 17:04:31 +0000253#ifndef _LIBCPP_NO_RTTI
254
Howard Hinnant99968442011-11-29 18:15:50 +0000255template<class _Fp, class _Alloc, class _Rp, class _A0>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000256const void*
Howard Hinnant99968442011-11-29 18:15:50 +0000257__func<_Fp, _Alloc, _Rp(_A0)>::target(const type_info& __ti) const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000258{
Howard Hinnant99968442011-11-29 18:15:50 +0000259 if (__ti == typeid(_Fp))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000260 return &__f_.first();
261 return (const void*)0;
262}
263
Howard Hinnant99968442011-11-29 18:15:50 +0000264template<class _Fp, class _Alloc, class _Rp, class _A0>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000265const std::type_info&
Howard Hinnant99968442011-11-29 18:15:50 +0000266__func<_Fp, _Alloc, _Rp(_A0)>::target_type() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000267{
Howard Hinnant99968442011-11-29 18:15:50 +0000268 return typeid(_Fp);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000269}
270
Howard Hinnant324bb032010-08-22 00:02:43 +0000271#endif // _LIBCPP_NO_RTTI
Howard Hinnantd4444702010-08-11 17:04:31 +0000272
Howard Hinnant99968442011-11-29 18:15:50 +0000273template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
274class __func<_Fp, _Alloc, _Rp(_A0, _A1)>
275 : public __base<_Rp(_A0, _A1)>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000276{
Howard Hinnant99968442011-11-29 18:15:50 +0000277 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000278public:
Howard Hinnant99968442011-11-29 18:15:50 +0000279 _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {}
280 _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000281 : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
Howard Hinnant99968442011-11-29 18:15:50 +0000282 virtual __base<_Rp(_A0, _A1)>* __clone() const;
283 virtual void __clone(__base<_Rp(_A0, _A1)>*) const;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000284 virtual void destroy();
285 virtual void destroy_deallocate();
Howard Hinnant99968442011-11-29 18:15:50 +0000286 virtual _Rp operator()(_A0, _A1);
Howard Hinnantd4444702010-08-11 17:04:31 +0000287#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000288 virtual const void* target(const type_info&) const;
289 virtual const std::type_info& target_type() const;
Howard Hinnant324bb032010-08-22 00:02:43 +0000290#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000291};
292
Howard Hinnant99968442011-11-29 18:15:50 +0000293template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
294__base<_Rp(_A0, _A1)>*
295__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000296{
Eric Fiselierb05f0592015-06-14 23:30:09 +0000297 typedef allocator_traits<_Alloc> __alloc_traits;
298 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
Howard Hinnant99968442011-11-29 18:15:50 +0000299 _Ap __a(__f_.second());
300 typedef __allocator_destructor<_Ap> _Dp;
301 unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000302 ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
303 return __hold.release();
304}
305
Howard Hinnant99968442011-11-29 18:15:50 +0000306template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000307void
Howard Hinnant99968442011-11-29 18:15:50 +0000308__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone(__base<_Rp(_A0, _A1)>* __p) const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000309{
310 ::new (__p) __func(__f_.first(), __f_.second());
311}
312
Howard Hinnant99968442011-11-29 18:15:50 +0000313template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000314void
Howard Hinnant99968442011-11-29 18:15:50 +0000315__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000316{
Howard Hinnant99968442011-11-29 18:15:50 +0000317 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000318}
319
Howard Hinnant99968442011-11-29 18:15:50 +0000320template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000321void
Howard Hinnant99968442011-11-29 18:15:50 +0000322__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy_deallocate()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000323{
Eric Fiselierb05f0592015-06-14 23:30:09 +0000324 typedef allocator_traits<_Alloc> __alloc_traits;
325 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
Howard Hinnant99968442011-11-29 18:15:50 +0000326 _Ap __a(__f_.second());
327 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000328 __a.deallocate(this, 1);
329}
330
Howard Hinnant99968442011-11-29 18:15:50 +0000331template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
332_Rp
333__func<_Fp, _Alloc, _Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000334{
Eric Fiselierc3231d22015-02-10 16:48:45 +0000335 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
336 return _Invoker::__call(__f_.first(), __a0, __a1);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000337}
338
Howard Hinnantd4444702010-08-11 17:04:31 +0000339#ifndef _LIBCPP_NO_RTTI
340
Howard Hinnant99968442011-11-29 18:15:50 +0000341template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000342const void*
Howard Hinnant99968442011-11-29 18:15:50 +0000343__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target(const type_info& __ti) const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000344{
Howard Hinnant99968442011-11-29 18:15:50 +0000345 if (__ti == typeid(_Fp))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000346 return &__f_.first();
347 return (const void*)0;
348}
349
Howard Hinnant99968442011-11-29 18:15:50 +0000350template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000351const std::type_info&
Howard Hinnant99968442011-11-29 18:15:50 +0000352__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target_type() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000353{
Howard Hinnant99968442011-11-29 18:15:50 +0000354 return typeid(_Fp);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000355}
356
Howard Hinnant324bb032010-08-22 00:02:43 +0000357#endif // _LIBCPP_NO_RTTI
Howard Hinnantd4444702010-08-11 17:04:31 +0000358
Howard Hinnant99968442011-11-29 18:15:50 +0000359template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
360class __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>
361 : public __base<_Rp(_A0, _A1, _A2)>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000362{
Howard Hinnant99968442011-11-29 18:15:50 +0000363 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000364public:
Howard Hinnant99968442011-11-29 18:15:50 +0000365 _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {}
366 _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000367 : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
Howard Hinnant99968442011-11-29 18:15:50 +0000368 virtual __base<_Rp(_A0, _A1, _A2)>* __clone() const;
369 virtual void __clone(__base<_Rp(_A0, _A1, _A2)>*) const;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000370 virtual void destroy();
371 virtual void destroy_deallocate();
Howard Hinnant99968442011-11-29 18:15:50 +0000372 virtual _Rp operator()(_A0, _A1, _A2);
Howard Hinnantd4444702010-08-11 17:04:31 +0000373#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000374 virtual const void* target(const type_info&) const;
375 virtual const std::type_info& target_type() const;
Howard Hinnant324bb032010-08-22 00:02:43 +0000376#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000377};
378
Howard Hinnant99968442011-11-29 18:15:50 +0000379template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
380__base<_Rp(_A0, _A1, _A2)>*
381__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000382{
Eric Fiselierb05f0592015-06-14 23:30:09 +0000383 typedef allocator_traits<_Alloc> __alloc_traits;
384 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
Howard Hinnant99968442011-11-29 18:15:50 +0000385 _Ap __a(__f_.second());
386 typedef __allocator_destructor<_Ap> _Dp;
387 unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000388 ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
389 return __hold.release();
390}
391
Howard Hinnant99968442011-11-29 18:15:50 +0000392template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000393void
Howard Hinnant99968442011-11-29 18:15:50 +0000394__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone(__base<_Rp(_A0, _A1, _A2)>* __p) const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000395{
396 ::new (__p) __func(__f_.first(), __f_.second());
397}
398
Howard Hinnant99968442011-11-29 18:15:50 +0000399template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000400void
Howard Hinnant99968442011-11-29 18:15:50 +0000401__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000402{
Howard Hinnant99968442011-11-29 18:15:50 +0000403 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000404}
405
Howard Hinnant99968442011-11-29 18:15:50 +0000406template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000407void
Howard Hinnant99968442011-11-29 18:15:50 +0000408__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy_deallocate()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000409{
Eric Fiselierb05f0592015-06-14 23:30:09 +0000410 typedef allocator_traits<_Alloc> __alloc_traits;
411 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
Howard Hinnant99968442011-11-29 18:15:50 +0000412 _Ap __a(__f_.second());
413 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000414 __a.deallocate(this, 1);
415}
416
Howard Hinnant99968442011-11-29 18:15:50 +0000417template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
418_Rp
419__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000420{
Eric Fiselierc3231d22015-02-10 16:48:45 +0000421 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
422 return _Invoker::__call(__f_.first(), __a0, __a1, __a2);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000423}
424
Howard Hinnantd4444702010-08-11 17:04:31 +0000425#ifndef _LIBCPP_NO_RTTI
426
Howard Hinnant99968442011-11-29 18:15:50 +0000427template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000428const void*
Howard Hinnant99968442011-11-29 18:15:50 +0000429__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target(const type_info& __ti) const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000430{
Howard Hinnant99968442011-11-29 18:15:50 +0000431 if (__ti == typeid(_Fp))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000432 return &__f_.first();
433 return (const void*)0;
434}
435
Howard Hinnant99968442011-11-29 18:15:50 +0000436template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000437const std::type_info&
Howard Hinnant99968442011-11-29 18:15:50 +0000438__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target_type() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000439{
Howard Hinnant99968442011-11-29 18:15:50 +0000440 return typeid(_Fp);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000441}
442
Howard Hinnant324bb032010-08-22 00:02:43 +0000443#endif // _LIBCPP_NO_RTTI
Howard Hinnantd4444702010-08-11 17:04:31 +0000444
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000445} // __function
446
Howard Hinnant99968442011-11-29 18:15:50 +0000447template<class _Rp>
Howard Hinnant0f678bd2013-08-12 18:38:34 +0000448class _LIBCPP_TYPE_VIS_ONLY function<_Rp()>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000449{
Howard Hinnant99968442011-11-29 18:15:50 +0000450 typedef __function::__base<_Rp()> __base;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000451 aligned_storage<3*sizeof(void*)>::type __buf_;
452 __base* __f_;
453
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700454 template <class _Fp>
455 _LIBCPP_INLINE_VISIBILITY
456 static bool __not_null(const _Fp&) {return true;}
457 template <class _R2>
458 _LIBCPP_INLINE_VISIBILITY
459 static bool __not_null(_R2 (*__p)()) {return __p;}
460 template <class _R2>
461 _LIBCPP_INLINE_VISIBILITY
462 static bool __not_null(const function<_R2()>& __p) {return __p;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000463public:
Howard Hinnant99968442011-11-29 18:15:50 +0000464 typedef _Rp result_type;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000465
466 // 20.7.16.2.1, construct/copy/destroy:
Howard Hinnant99acc502010-09-21 17:32:39 +0000467 _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
468 _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000469 function(const function&);
Howard Hinnant99968442011-11-29 18:15:50 +0000470 template<class _Fp>
471 function(_Fp,
472 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000473
Howard Hinnant72552802010-08-20 19:36:46 +0000474 template<class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +0000475 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant72552802010-08-20 19:36:46 +0000476 function(allocator_arg_t, const _Alloc&) : __f_(0) {}
477 template<class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +0000478 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant72552802010-08-20 19:36:46 +0000479 function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
480 template<class _Alloc>
481 function(allocator_arg_t, const _Alloc&, const function&);
Howard Hinnant99968442011-11-29 18:15:50 +0000482 template<class _Fp, class _Alloc>
483 function(allocator_arg_t, const _Alloc& __a, _Fp __f,
484 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000485
486 function& operator=(const function&);
487 function& operator=(nullptr_t);
Howard Hinnant99968442011-11-29 18:15:50 +0000488 template<class _Fp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000489 typename enable_if
490 <
Howard Hinnant99968442011-11-29 18:15:50 +0000491 !is_integral<_Fp>::value,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000492 function&
493 >::type
Howard Hinnant99968442011-11-29 18:15:50 +0000494 operator=(_Fp);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000495
496 ~function();
497
498 // 20.7.16.2.2, function modifiers:
499 void swap(function&);
Howard Hinnant99968442011-11-29 18:15:50 +0000500 template<class _Fp, class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +0000501 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000502 void assign(_Fp __f, const _Alloc& __a)
Howard Hinnant72552802010-08-20 19:36:46 +0000503 {function(allocator_arg, __a, __f).swap(*this);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000504
505 // 20.7.16.2.3, function capacity:
Howard Hinnant99acc502010-09-21 17:32:39 +0000506 _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000507
508private:
509 // deleted overloads close possible hole in the type system
510 template<class _R2>
Howard Hinnant99acc502010-09-21 17:32:39 +0000511 bool operator==(const function<_R2()>&) const;// = delete;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000512 template<class _R2>
Howard Hinnant99acc502010-09-21 17:32:39 +0000513 bool operator!=(const function<_R2()>&) const;// = delete;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000514public:
515 // 20.7.16.2.4, function invocation:
Howard Hinnant99968442011-11-29 18:15:50 +0000516 _Rp operator()() const;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000517
Howard Hinnantd4444702010-08-11 17:04:31 +0000518#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000519 // 20.7.16.2.5, function target access:
520 const std::type_info& target_type() const;
Howard Hinnant99968442011-11-29 18:15:50 +0000521 template <typename _Tp> _Tp* target();
522 template <typename _Tp> const _Tp* target() const;
Howard Hinnant324bb032010-08-22 00:02:43 +0000523#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000524};
525
Howard Hinnant99968442011-11-29 18:15:50 +0000526template<class _Rp>
527function<_Rp()>::function(const function& __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000528{
529 if (__f.__f_ == 0)
530 __f_ = 0;
531 else if (__f.__f_ == (const __base*)&__f.__buf_)
532 {
533 __f_ = (__base*)&__buf_;
534 __f.__f_->__clone(__f_);
535 }
536 else
537 __f_ = __f.__f_->__clone();
538}
539
Howard Hinnant99968442011-11-29 18:15:50 +0000540template<class _Rp>
Howard Hinnant72552802010-08-20 19:36:46 +0000541template<class _Alloc>
Howard Hinnant99968442011-11-29 18:15:50 +0000542function<_Rp()>::function(allocator_arg_t, const _Alloc&, const function& __f)
Howard Hinnant72552802010-08-20 19:36:46 +0000543{
544 if (__f.__f_ == 0)
545 __f_ = 0;
546 else if (__f.__f_ == (const __base*)&__f.__buf_)
547 {
548 __f_ = (__base*)&__buf_;
549 __f.__f_->__clone(__f_);
550 }
551 else
552 __f_ = __f.__f_->__clone();
553}
554
Howard Hinnant99968442011-11-29 18:15:50 +0000555template<class _Rp>
556template <class _Fp>
557function<_Rp()>::function(_Fp __f,
558 typename enable_if<!is_integral<_Fp>::value>::type*)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000559 : __f_(0)
560{
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700561 if (__not_null(__f))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000562 {
Howard Hinnant99968442011-11-29 18:15:50 +0000563 typedef __function::__func<_Fp, allocator<_Fp>, _Rp()> _FF;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000564 if (sizeof(_FF) <= sizeof(__buf_))
565 {
566 __f_ = (__base*)&__buf_;
567 ::new (__f_) _FF(__f);
568 }
569 else
570 {
Howard Hinnant99968442011-11-29 18:15:50 +0000571 typedef allocator<_FF> _Ap;
572 _Ap __a;
573 typedef __allocator_destructor<_Ap> _Dp;
574 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
575 ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000576 __f_ = __hold.release();
577 }
578 }
579}
580
Howard Hinnant99968442011-11-29 18:15:50 +0000581template<class _Rp>
582template <class _Fp, class _Alloc>
583function<_Rp()>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
584 typename enable_if<!is_integral<_Fp>::value>::type*)
Howard Hinnant72552802010-08-20 19:36:46 +0000585 : __f_(0)
586{
587 typedef allocator_traits<_Alloc> __alloc_traits;
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700588 if (__not_null(__f))
Howard Hinnant72552802010-08-20 19:36:46 +0000589 {
Howard Hinnant99968442011-11-29 18:15:50 +0000590 typedef __function::__func<_Fp, _Alloc, _Rp()> _FF;
Howard Hinnant72552802010-08-20 19:36:46 +0000591 if (sizeof(_FF) <= sizeof(__buf_))
592 {
593 __f_ = (__base*)&__buf_;
Eric Fiselierb05f0592015-06-14 23:30:09 +0000594 ::new (__f_) _FF(__f, __a0);
Howard Hinnant72552802010-08-20 19:36:46 +0000595 }
596 else
597 {
Marshall Clow66302c62015-04-07 05:21:38 +0000598 typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
Howard Hinnant99968442011-11-29 18:15:50 +0000599 _Ap __a(__a0);
600 typedef __allocator_destructor<_Ap> _Dp;
601 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Howard Hinnant72552802010-08-20 19:36:46 +0000602 ::new (__hold.get()) _FF(__f, _Alloc(__a));
603 __f_ = __hold.release();
604 }
605 }
606}
607
Howard Hinnant99968442011-11-29 18:15:50 +0000608template<class _Rp>
609function<_Rp()>&
610function<_Rp()>::operator=(const function& __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000611{
612 function(__f).swap(*this);
613 return *this;
614}
615
Howard Hinnant99968442011-11-29 18:15:50 +0000616template<class _Rp>
617function<_Rp()>&
618function<_Rp()>::operator=(nullptr_t)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000619{
620 if (__f_ == (__base*)&__buf_)
621 __f_->destroy();
622 else if (__f_)
623 __f_->destroy_deallocate();
624 __f_ = 0;
Eric Fiselierfa97c2e2015-06-02 01:31:33 +0000625 return *this;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000626}
627
Howard Hinnant99968442011-11-29 18:15:50 +0000628template<class _Rp>
629template <class _Fp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000630typename enable_if
631<
Howard Hinnant99968442011-11-29 18:15:50 +0000632 !is_integral<_Fp>::value,
633 function<_Rp()>&
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000634>::type
Howard Hinnant99968442011-11-29 18:15:50 +0000635function<_Rp()>::operator=(_Fp __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000636{
Howard Hinnant0949eed2011-06-30 21:18:19 +0000637 function(_VSTD::move(__f)).swap(*this);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000638 return *this;
639}
640
Howard Hinnant99968442011-11-29 18:15:50 +0000641template<class _Rp>
642function<_Rp()>::~function()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000643{
644 if (__f_ == (__base*)&__buf_)
645 __f_->destroy();
646 else if (__f_)
647 __f_->destroy_deallocate();
648}
649
Howard Hinnant99968442011-11-29 18:15:50 +0000650template<class _Rp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000651void
Howard Hinnant99968442011-11-29 18:15:50 +0000652function<_Rp()>::swap(function& __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000653{
654 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
655 {
656 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
657 __base* __t = (__base*)&__tempbuf;
658 __f_->__clone(__t);
659 __f_->destroy();
660 __f_ = 0;
661 __f.__f_->__clone((__base*)&__buf_);
662 __f.__f_->destroy();
663 __f.__f_ = 0;
664 __f_ = (__base*)&__buf_;
665 __t->__clone((__base*)&__f.__buf_);
666 __t->destroy();
667 __f.__f_ = (__base*)&__f.__buf_;
668 }
669 else if (__f_ == (__base*)&__buf_)
670 {
671 __f_->__clone((__base*)&__f.__buf_);
672 __f_->destroy();
673 __f_ = __f.__f_;
674 __f.__f_ = (__base*)&__f.__buf_;
675 }
676 else if (__f.__f_ == (__base*)&__f.__buf_)
677 {
678 __f.__f_->__clone((__base*)&__buf_);
679 __f.__f_->destroy();
680 __f.__f_ = __f_;
681 __f_ = (__base*)&__buf_;
682 }
683 else
Howard Hinnant0949eed2011-06-30 21:18:19 +0000684 _VSTD::swap(__f_, __f.__f_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000685}
686
Howard Hinnant99968442011-11-29 18:15:50 +0000687template<class _Rp>
688_Rp
689function<_Rp()>::operator()() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000690{
Howard Hinnantd4444702010-08-11 17:04:31 +0000691#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000692 if (__f_ == 0)
693 throw bad_function_call();
Howard Hinnant324bb032010-08-22 00:02:43 +0000694#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000695 return (*__f_)();
696}
697
Howard Hinnantd4444702010-08-11 17:04:31 +0000698#ifndef _LIBCPP_NO_RTTI
699
Howard Hinnant99968442011-11-29 18:15:50 +0000700template<class _Rp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000701const std::type_info&
Howard Hinnant99968442011-11-29 18:15:50 +0000702function<_Rp()>::target_type() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000703{
704 if (__f_ == 0)
705 return typeid(void);
706 return __f_->target_type();
707}
708
Howard Hinnant99968442011-11-29 18:15:50 +0000709template<class _Rp>
710template <typename _Tp>
711_Tp*
712function<_Rp()>::target()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000713{
714 if (__f_ == 0)
Howard Hinnant99968442011-11-29 18:15:50 +0000715 return (_Tp*)0;
716 return (_Tp*)__f_->target(typeid(_Tp));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000717}
718
Howard Hinnant99968442011-11-29 18:15:50 +0000719template<class _Rp>
720template <typename _Tp>
721const _Tp*
722function<_Rp()>::target() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000723{
724 if (__f_ == 0)
Howard Hinnant99968442011-11-29 18:15:50 +0000725 return (const _Tp*)0;
726 return (const _Tp*)__f_->target(typeid(_Tp));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000727}
728
Howard Hinnant324bb032010-08-22 00:02:43 +0000729#endif // _LIBCPP_NO_RTTI
Howard Hinnantd4444702010-08-11 17:04:31 +0000730
Howard Hinnant99968442011-11-29 18:15:50 +0000731template<class _Rp, class _A0>
Howard Hinnant0f678bd2013-08-12 18:38:34 +0000732class _LIBCPP_TYPE_VIS_ONLY function<_Rp(_A0)>
Howard Hinnant99968442011-11-29 18:15:50 +0000733 : public unary_function<_A0, _Rp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000734{
Howard Hinnant99968442011-11-29 18:15:50 +0000735 typedef __function::__base<_Rp(_A0)> __base;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000736 aligned_storage<3*sizeof(void*)>::type __buf_;
737 __base* __f_;
738
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700739 template <class _Fp>
740 _LIBCPP_INLINE_VISIBILITY
741 static bool __not_null(const _Fp&) {return true;}
742 template <class _R2, class _B0>
743 _LIBCPP_INLINE_VISIBILITY
744 static bool __not_null(_R2 (*__p)(_B0)) {return __p;}
745 template <class _R2, class _Cp>
746 _LIBCPP_INLINE_VISIBILITY
747 static bool __not_null(_R2 (_Cp::*__p)()) {return __p;}
748 template <class _R2, class _Cp>
749 _LIBCPP_INLINE_VISIBILITY
750 static bool __not_null(_R2 (_Cp::*__p)() const) {return __p;}
751 template <class _R2, class _Cp>
752 _LIBCPP_INLINE_VISIBILITY
753 static bool __not_null(_R2 (_Cp::*__p)() volatile) {return __p;}
754 template <class _R2, class _Cp>
755 _LIBCPP_INLINE_VISIBILITY
756 static bool __not_null(_R2 (_Cp::*__p)() const volatile) {return __p;}
757 template <class _R2, class _B0>
758 _LIBCPP_INLINE_VISIBILITY
759 static bool __not_null(const function<_R2(_B0)>& __p) {return __p;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000760public:
Howard Hinnant99968442011-11-29 18:15:50 +0000761 typedef _Rp result_type;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000762
763 // 20.7.16.2.1, construct/copy/destroy:
Howard Hinnant99acc502010-09-21 17:32:39 +0000764 _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
765 _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000766 function(const function&);
Howard Hinnant99968442011-11-29 18:15:50 +0000767 template<class _Fp>
768 function(_Fp,
769 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000770
Howard Hinnant72552802010-08-20 19:36:46 +0000771 template<class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +0000772 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant72552802010-08-20 19:36:46 +0000773 function(allocator_arg_t, const _Alloc&) : __f_(0) {}
774 template<class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +0000775 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant72552802010-08-20 19:36:46 +0000776 function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
777 template<class _Alloc>
778 function(allocator_arg_t, const _Alloc&, const function&);
Howard Hinnant99968442011-11-29 18:15:50 +0000779 template<class _Fp, class _Alloc>
780 function(allocator_arg_t, const _Alloc& __a, _Fp __f,
781 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000782
783 function& operator=(const function&);
784 function& operator=(nullptr_t);
Howard Hinnant99968442011-11-29 18:15:50 +0000785 template<class _Fp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000786 typename enable_if
787 <
Howard Hinnant99968442011-11-29 18:15:50 +0000788 !is_integral<_Fp>::value,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000789 function&
790 >::type
Howard Hinnant99968442011-11-29 18:15:50 +0000791 operator=(_Fp);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000792
793 ~function();
794
795 // 20.7.16.2.2, function modifiers:
796 void swap(function&);
Howard Hinnant99968442011-11-29 18:15:50 +0000797 template<class _Fp, class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +0000798 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000799 void assign(_Fp __f, const _Alloc& __a)
Howard Hinnant72552802010-08-20 19:36:46 +0000800 {function(allocator_arg, __a, __f).swap(*this);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000801
802 // 20.7.16.2.3, function capacity:
Howard Hinnant99acc502010-09-21 17:32:39 +0000803 _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000804
805private:
806 // deleted overloads close possible hole in the type system
807 template<class _R2, class _B0>
Howard Hinnant99acc502010-09-21 17:32:39 +0000808 bool operator==(const function<_R2(_B0)>&) const;// = delete;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000809 template<class _R2, class _B0>
Howard Hinnant99acc502010-09-21 17:32:39 +0000810 bool operator!=(const function<_R2(_B0)>&) const;// = delete;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000811public:
812 // 20.7.16.2.4, function invocation:
Howard Hinnant99968442011-11-29 18:15:50 +0000813 _Rp operator()(_A0) const;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000814
Howard Hinnantd4444702010-08-11 17:04:31 +0000815#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000816 // 20.7.16.2.5, function target access:
817 const std::type_info& target_type() const;
Howard Hinnant99968442011-11-29 18:15:50 +0000818 template <typename _Tp> _Tp* target();
819 template <typename _Tp> const _Tp* target() const;
Howard Hinnant324bb032010-08-22 00:02:43 +0000820#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000821};
822
Howard Hinnant99968442011-11-29 18:15:50 +0000823template<class _Rp, class _A0>
824function<_Rp(_A0)>::function(const function& __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000825{
826 if (__f.__f_ == 0)
827 __f_ = 0;
828 else if (__f.__f_ == (const __base*)&__f.__buf_)
829 {
830 __f_ = (__base*)&__buf_;
831 __f.__f_->__clone(__f_);
832 }
833 else
834 __f_ = __f.__f_->__clone();
835}
836
Howard Hinnant99968442011-11-29 18:15:50 +0000837template<class _Rp, class _A0>
Howard Hinnant72552802010-08-20 19:36:46 +0000838template<class _Alloc>
Howard Hinnant99968442011-11-29 18:15:50 +0000839function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc&, const function& __f)
Howard Hinnant72552802010-08-20 19:36:46 +0000840{
841 if (__f.__f_ == 0)
842 __f_ = 0;
843 else if (__f.__f_ == (const __base*)&__f.__buf_)
844 {
845 __f_ = (__base*)&__buf_;
846 __f.__f_->__clone(__f_);
847 }
848 else
849 __f_ = __f.__f_->__clone();
850}
851
Howard Hinnant99968442011-11-29 18:15:50 +0000852template<class _Rp, class _A0>
853template <class _Fp>
854function<_Rp(_A0)>::function(_Fp __f,
855 typename enable_if<!is_integral<_Fp>::value>::type*)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000856 : __f_(0)
857{
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700858 if (__not_null(__f))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000859 {
Howard Hinnant99968442011-11-29 18:15:50 +0000860 typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0)> _FF;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000861 if (sizeof(_FF) <= sizeof(__buf_))
862 {
863 __f_ = (__base*)&__buf_;
864 ::new (__f_) _FF(__f);
865 }
866 else
867 {
Howard Hinnant99968442011-11-29 18:15:50 +0000868 typedef allocator<_FF> _Ap;
869 _Ap __a;
870 typedef __allocator_destructor<_Ap> _Dp;
871 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
872 ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000873 __f_ = __hold.release();
874 }
875 }
876}
877
Howard Hinnant99968442011-11-29 18:15:50 +0000878template<class _Rp, class _A0>
879template <class _Fp, class _Alloc>
880function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
881 typename enable_if<!is_integral<_Fp>::value>::type*)
Howard Hinnant72552802010-08-20 19:36:46 +0000882 : __f_(0)
883{
884 typedef allocator_traits<_Alloc> __alloc_traits;
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700885 if (__not_null(__f))
Howard Hinnant72552802010-08-20 19:36:46 +0000886 {
Howard Hinnant99968442011-11-29 18:15:50 +0000887 typedef __function::__func<_Fp, _Alloc, _Rp(_A0)> _FF;
Howard Hinnant72552802010-08-20 19:36:46 +0000888 if (sizeof(_FF) <= sizeof(__buf_))
889 {
890 __f_ = (__base*)&__buf_;
Eric Fiselierb05f0592015-06-14 23:30:09 +0000891 ::new (__f_) _FF(__f, __a0);
Howard Hinnant72552802010-08-20 19:36:46 +0000892 }
893 else
894 {
Marshall Clow66302c62015-04-07 05:21:38 +0000895 typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
Howard Hinnant99968442011-11-29 18:15:50 +0000896 _Ap __a(__a0);
897 typedef __allocator_destructor<_Ap> _Dp;
898 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Howard Hinnant72552802010-08-20 19:36:46 +0000899 ::new (__hold.get()) _FF(__f, _Alloc(__a));
900 __f_ = __hold.release();
901 }
902 }
903}
904
Howard Hinnant99968442011-11-29 18:15:50 +0000905template<class _Rp, class _A0>
906function<_Rp(_A0)>&
907function<_Rp(_A0)>::operator=(const function& __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000908{
909 function(__f).swap(*this);
910 return *this;
911}
912
Howard Hinnant99968442011-11-29 18:15:50 +0000913template<class _Rp, class _A0>
914function<_Rp(_A0)>&
915function<_Rp(_A0)>::operator=(nullptr_t)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000916{
917 if (__f_ == (__base*)&__buf_)
918 __f_->destroy();
919 else if (__f_)
920 __f_->destroy_deallocate();
921 __f_ = 0;
Eric Fiselierfa97c2e2015-06-02 01:31:33 +0000922 return *this;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000923}
924
Howard Hinnant99968442011-11-29 18:15:50 +0000925template<class _Rp, class _A0>
926template <class _Fp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000927typename enable_if
928<
Howard Hinnant99968442011-11-29 18:15:50 +0000929 !is_integral<_Fp>::value,
930 function<_Rp(_A0)>&
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000931>::type
Howard Hinnant99968442011-11-29 18:15:50 +0000932function<_Rp(_A0)>::operator=(_Fp __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000933{
Howard Hinnant0949eed2011-06-30 21:18:19 +0000934 function(_VSTD::move(__f)).swap(*this);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000935 return *this;
936}
937
Howard Hinnant99968442011-11-29 18:15:50 +0000938template<class _Rp, class _A0>
939function<_Rp(_A0)>::~function()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000940{
941 if (__f_ == (__base*)&__buf_)
942 __f_->destroy();
943 else if (__f_)
944 __f_->destroy_deallocate();
945}
946
Howard Hinnant99968442011-11-29 18:15:50 +0000947template<class _Rp, class _A0>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000948void
Howard Hinnant99968442011-11-29 18:15:50 +0000949function<_Rp(_A0)>::swap(function& __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000950{
951 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
952 {
953 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
954 __base* __t = (__base*)&__tempbuf;
955 __f_->__clone(__t);
956 __f_->destroy();
957 __f_ = 0;
958 __f.__f_->__clone((__base*)&__buf_);
959 __f.__f_->destroy();
960 __f.__f_ = 0;
961 __f_ = (__base*)&__buf_;
962 __t->__clone((__base*)&__f.__buf_);
963 __t->destroy();
964 __f.__f_ = (__base*)&__f.__buf_;
965 }
966 else if (__f_ == (__base*)&__buf_)
967 {
968 __f_->__clone((__base*)&__f.__buf_);
969 __f_->destroy();
970 __f_ = __f.__f_;
971 __f.__f_ = (__base*)&__f.__buf_;
972 }
973 else if (__f.__f_ == (__base*)&__f.__buf_)
974 {
975 __f.__f_->__clone((__base*)&__buf_);
976 __f.__f_->destroy();
977 __f.__f_ = __f_;
978 __f_ = (__base*)&__buf_;
979 }
980 else
Howard Hinnant0949eed2011-06-30 21:18:19 +0000981 _VSTD::swap(__f_, __f.__f_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000982}
983
Howard Hinnant99968442011-11-29 18:15:50 +0000984template<class _Rp, class _A0>
985_Rp
986function<_Rp(_A0)>::operator()(_A0 __a0) const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000987{
Howard Hinnantd4444702010-08-11 17:04:31 +0000988#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000989 if (__f_ == 0)
990 throw bad_function_call();
Howard Hinnant324bb032010-08-22 00:02:43 +0000991#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000992 return (*__f_)(__a0);
993}
994
Howard Hinnantd4444702010-08-11 17:04:31 +0000995#ifndef _LIBCPP_NO_RTTI
996
Howard Hinnant99968442011-11-29 18:15:50 +0000997template<class _Rp, class _A0>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000998const std::type_info&
Howard Hinnant99968442011-11-29 18:15:50 +0000999function<_Rp(_A0)>::target_type() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001000{
1001 if (__f_ == 0)
1002 return typeid(void);
1003 return __f_->target_type();
1004}
1005
Howard Hinnant99968442011-11-29 18:15:50 +00001006template<class _Rp, class _A0>
1007template <typename _Tp>
1008_Tp*
1009function<_Rp(_A0)>::target()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001010{
1011 if (__f_ == 0)
Howard Hinnant99968442011-11-29 18:15:50 +00001012 return (_Tp*)0;
1013 return (_Tp*)__f_->target(typeid(_Tp));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001014}
1015
Howard Hinnant99968442011-11-29 18:15:50 +00001016template<class _Rp, class _A0>
1017template <typename _Tp>
1018const _Tp*
1019function<_Rp(_A0)>::target() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001020{
1021 if (__f_ == 0)
Howard Hinnant99968442011-11-29 18:15:50 +00001022 return (const _Tp*)0;
1023 return (const _Tp*)__f_->target(typeid(_Tp));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001024}
1025
Howard Hinnant324bb032010-08-22 00:02:43 +00001026#endif // _LIBCPP_NO_RTTI
Howard Hinnantd4444702010-08-11 17:04:31 +00001027
Howard Hinnant99968442011-11-29 18:15:50 +00001028template<class _Rp, class _A0, class _A1>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00001029class _LIBCPP_TYPE_VIS_ONLY function<_Rp(_A0, _A1)>
Howard Hinnant99968442011-11-29 18:15:50 +00001030 : public binary_function<_A0, _A1, _Rp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001031{
Howard Hinnant99968442011-11-29 18:15:50 +00001032 typedef __function::__base<_Rp(_A0, _A1)> __base;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001033 aligned_storage<3*sizeof(void*)>::type __buf_;
1034 __base* __f_;
1035
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001036 template <class _Fp>
1037 _LIBCPP_INLINE_VISIBILITY
1038 static bool __not_null(const _Fp&) {return true;}
1039 template <class _R2, class _B0, class _B1>
1040 _LIBCPP_INLINE_VISIBILITY
1041 static bool __not_null(_R2 (*__p)(_B0, _B1)) {return __p;}
1042 template <class _R2, class _Cp, class _B1>
1043 _LIBCPP_INLINE_VISIBILITY
1044 static bool __not_null(_R2 (_Cp::*__p)(_B1)) {return __p;}
1045 template <class _R2, class _Cp, class _B1>
1046 _LIBCPP_INLINE_VISIBILITY
1047 static bool __not_null(_R2 (_Cp::*__p)(_B1) const) {return __p;}
1048 template <class _R2, class _Cp, class _B1>
1049 _LIBCPP_INLINE_VISIBILITY
1050 static bool __not_null(_R2 (_Cp::*__p)(_B1) volatile) {return __p;}
1051 template <class _R2, class _Cp, class _B1>
1052 _LIBCPP_INLINE_VISIBILITY
1053 static bool __not_null(_R2 (_Cp::*__p)(_B1) const volatile) {return __p;}
1054 template <class _R2, class _B0, class _B1>
1055 _LIBCPP_INLINE_VISIBILITY
1056 static bool __not_null(const function<_R2(_B0, _B1)>& __p) {return __p;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001057public:
Howard Hinnant99968442011-11-29 18:15:50 +00001058 typedef _Rp result_type;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001059
1060 // 20.7.16.2.1, construct/copy/destroy:
Howard Hinnant99acc502010-09-21 17:32:39 +00001061 _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
1062 _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001063 function(const function&);
Howard Hinnant99968442011-11-29 18:15:50 +00001064 template<class _Fp>
1065 function(_Fp,
1066 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001067
Howard Hinnant72552802010-08-20 19:36:46 +00001068 template<class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +00001069 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant72552802010-08-20 19:36:46 +00001070 function(allocator_arg_t, const _Alloc&) : __f_(0) {}
1071 template<class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +00001072 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant72552802010-08-20 19:36:46 +00001073 function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
1074 template<class _Alloc>
1075 function(allocator_arg_t, const _Alloc&, const function&);
Howard Hinnant99968442011-11-29 18:15:50 +00001076 template<class _Fp, class _Alloc>
1077 function(allocator_arg_t, const _Alloc& __a, _Fp __f,
1078 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001079
1080 function& operator=(const function&);
1081 function& operator=(nullptr_t);
Howard Hinnant99968442011-11-29 18:15:50 +00001082 template<class _Fp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001083 typename enable_if
1084 <
Howard Hinnant99968442011-11-29 18:15:50 +00001085 !is_integral<_Fp>::value,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001086 function&
1087 >::type
Howard Hinnant99968442011-11-29 18:15:50 +00001088 operator=(_Fp);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001089
1090 ~function();
1091
1092 // 20.7.16.2.2, function modifiers:
1093 void swap(function&);
Howard Hinnant99968442011-11-29 18:15:50 +00001094 template<class _Fp, class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +00001095 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001096 void assign(_Fp __f, const _Alloc& __a)
Howard Hinnant72552802010-08-20 19:36:46 +00001097 {function(allocator_arg, __a, __f).swap(*this);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001098
1099 // 20.7.16.2.3, function capacity:
1100 operator bool() const {return __f_;}
1101
1102private:
1103 // deleted overloads close possible hole in the type system
1104 template<class _R2, class _B0, class _B1>
Howard Hinnant99acc502010-09-21 17:32:39 +00001105 bool operator==(const function<_R2(_B0, _B1)>&) const;// = delete;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001106 template<class _R2, class _B0, class _B1>
Howard Hinnant99acc502010-09-21 17:32:39 +00001107 bool operator!=(const function<_R2(_B0, _B1)>&) const;// = delete;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001108public:
1109 // 20.7.16.2.4, function invocation:
Howard Hinnant99968442011-11-29 18:15:50 +00001110 _Rp operator()(_A0, _A1) const;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001111
Howard Hinnantd4444702010-08-11 17:04:31 +00001112#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001113 // 20.7.16.2.5, function target access:
1114 const std::type_info& target_type() const;
Howard Hinnant99968442011-11-29 18:15:50 +00001115 template <typename _Tp> _Tp* target();
1116 template <typename _Tp> const _Tp* target() const;
Howard Hinnant324bb032010-08-22 00:02:43 +00001117#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001118};
1119
Howard Hinnant99968442011-11-29 18:15:50 +00001120template<class _Rp, class _A0, class _A1>
1121function<_Rp(_A0, _A1)>::function(const function& __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001122{
1123 if (__f.__f_ == 0)
1124 __f_ = 0;
1125 else if (__f.__f_ == (const __base*)&__f.__buf_)
1126 {
1127 __f_ = (__base*)&__buf_;
1128 __f.__f_->__clone(__f_);
1129 }
1130 else
1131 __f_ = __f.__f_->__clone();
1132}
1133
Howard Hinnant99968442011-11-29 18:15:50 +00001134template<class _Rp, class _A0, class _A1>
Howard Hinnant72552802010-08-20 19:36:46 +00001135template<class _Alloc>
Howard Hinnant99968442011-11-29 18:15:50 +00001136function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc&, const function& __f)
Howard Hinnant72552802010-08-20 19:36:46 +00001137{
1138 if (__f.__f_ == 0)
1139 __f_ = 0;
1140 else if (__f.__f_ == (const __base*)&__f.__buf_)
1141 {
1142 __f_ = (__base*)&__buf_;
1143 __f.__f_->__clone(__f_);
1144 }
1145 else
1146 __f_ = __f.__f_->__clone();
1147}
1148
Howard Hinnant99968442011-11-29 18:15:50 +00001149template<class _Rp, class _A0, class _A1>
1150template <class _Fp>
1151function<_Rp(_A0, _A1)>::function(_Fp __f,
1152 typename enable_if<!is_integral<_Fp>::value>::type*)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001153 : __f_(0)
1154{
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001155 if (__not_null(__f))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001156 {
Howard Hinnant99968442011-11-29 18:15:50 +00001157 typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1)> _FF;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001158 if (sizeof(_FF) <= sizeof(__buf_))
1159 {
1160 __f_ = (__base*)&__buf_;
1161 ::new (__f_) _FF(__f);
1162 }
1163 else
1164 {
Howard Hinnant99968442011-11-29 18:15:50 +00001165 typedef allocator<_FF> _Ap;
1166 _Ap __a;
1167 typedef __allocator_destructor<_Ap> _Dp;
1168 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1169 ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001170 __f_ = __hold.release();
1171 }
1172 }
1173}
1174
Howard Hinnant99968442011-11-29 18:15:50 +00001175template<class _Rp, class _A0, class _A1>
1176template <class _Fp, class _Alloc>
1177function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
1178 typename enable_if<!is_integral<_Fp>::value>::type*)
Howard Hinnant72552802010-08-20 19:36:46 +00001179 : __f_(0)
1180{
1181 typedef allocator_traits<_Alloc> __alloc_traits;
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001182 if (__not_null(__f))
Howard Hinnant72552802010-08-20 19:36:46 +00001183 {
Howard Hinnant99968442011-11-29 18:15:50 +00001184 typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1)> _FF;
Howard Hinnant72552802010-08-20 19:36:46 +00001185 if (sizeof(_FF) <= sizeof(__buf_))
1186 {
1187 __f_ = (__base*)&__buf_;
Eric Fiselierb05f0592015-06-14 23:30:09 +00001188 ::new (__f_) _FF(__f, __a0);
Howard Hinnant72552802010-08-20 19:36:46 +00001189 }
1190 else
1191 {
Marshall Clow66302c62015-04-07 05:21:38 +00001192 typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
Howard Hinnant99968442011-11-29 18:15:50 +00001193 _Ap __a(__a0);
1194 typedef __allocator_destructor<_Ap> _Dp;
1195 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Howard Hinnant72552802010-08-20 19:36:46 +00001196 ::new (__hold.get()) _FF(__f, _Alloc(__a));
1197 __f_ = __hold.release();
1198 }
1199 }
1200}
1201
Howard Hinnant99968442011-11-29 18:15:50 +00001202template<class _Rp, class _A0, class _A1>
1203function<_Rp(_A0, _A1)>&
1204function<_Rp(_A0, _A1)>::operator=(const function& __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001205{
1206 function(__f).swap(*this);
1207 return *this;
1208}
1209
Howard Hinnant99968442011-11-29 18:15:50 +00001210template<class _Rp, class _A0, class _A1>
1211function<_Rp(_A0, _A1)>&
1212function<_Rp(_A0, _A1)>::operator=(nullptr_t)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001213{
1214 if (__f_ == (__base*)&__buf_)
1215 __f_->destroy();
1216 else if (__f_)
1217 __f_->destroy_deallocate();
1218 __f_ = 0;
Eric Fiselierfa97c2e2015-06-02 01:31:33 +00001219 return *this;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001220}
1221
Howard Hinnant99968442011-11-29 18:15:50 +00001222template<class _Rp, class _A0, class _A1>
1223template <class _Fp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001224typename enable_if
1225<
Howard Hinnant99968442011-11-29 18:15:50 +00001226 !is_integral<_Fp>::value,
1227 function<_Rp(_A0, _A1)>&
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001228>::type
Howard Hinnant99968442011-11-29 18:15:50 +00001229function<_Rp(_A0, _A1)>::operator=(_Fp __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001230{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001231 function(_VSTD::move(__f)).swap(*this);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001232 return *this;
1233}
1234
Howard Hinnant99968442011-11-29 18:15:50 +00001235template<class _Rp, class _A0, class _A1>
1236function<_Rp(_A0, _A1)>::~function()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001237{
1238 if (__f_ == (__base*)&__buf_)
1239 __f_->destroy();
1240 else if (__f_)
1241 __f_->destroy_deallocate();
1242}
1243
Howard Hinnant99968442011-11-29 18:15:50 +00001244template<class _Rp, class _A0, class _A1>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001245void
Howard Hinnant99968442011-11-29 18:15:50 +00001246function<_Rp(_A0, _A1)>::swap(function& __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001247{
1248 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1249 {
1250 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1251 __base* __t = (__base*)&__tempbuf;
1252 __f_->__clone(__t);
1253 __f_->destroy();
1254 __f_ = 0;
1255 __f.__f_->__clone((__base*)&__buf_);
1256 __f.__f_->destroy();
1257 __f.__f_ = 0;
1258 __f_ = (__base*)&__buf_;
1259 __t->__clone((__base*)&__f.__buf_);
1260 __t->destroy();
1261 __f.__f_ = (__base*)&__f.__buf_;
1262 }
1263 else if (__f_ == (__base*)&__buf_)
1264 {
1265 __f_->__clone((__base*)&__f.__buf_);
1266 __f_->destroy();
1267 __f_ = __f.__f_;
1268 __f.__f_ = (__base*)&__f.__buf_;
1269 }
1270 else if (__f.__f_ == (__base*)&__f.__buf_)
1271 {
1272 __f.__f_->__clone((__base*)&__buf_);
1273 __f.__f_->destroy();
1274 __f.__f_ = __f_;
1275 __f_ = (__base*)&__buf_;
1276 }
1277 else
Howard Hinnant0949eed2011-06-30 21:18:19 +00001278 _VSTD::swap(__f_, __f.__f_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001279}
1280
Howard Hinnant99968442011-11-29 18:15:50 +00001281template<class _Rp, class _A0, class _A1>
1282_Rp
1283function<_Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001284{
Howard Hinnantd4444702010-08-11 17:04:31 +00001285#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001286 if (__f_ == 0)
1287 throw bad_function_call();
Howard Hinnant324bb032010-08-22 00:02:43 +00001288#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001289 return (*__f_)(__a0, __a1);
1290}
1291
Howard Hinnantd4444702010-08-11 17:04:31 +00001292#ifndef _LIBCPP_NO_RTTI
1293
Howard Hinnant99968442011-11-29 18:15:50 +00001294template<class _Rp, class _A0, class _A1>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001295const std::type_info&
Howard Hinnant99968442011-11-29 18:15:50 +00001296function<_Rp(_A0, _A1)>::target_type() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001297{
1298 if (__f_ == 0)
1299 return typeid(void);
1300 return __f_->target_type();
1301}
1302
Howard Hinnant99968442011-11-29 18:15:50 +00001303template<class _Rp, class _A0, class _A1>
1304template <typename _Tp>
1305_Tp*
1306function<_Rp(_A0, _A1)>::target()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001307{
1308 if (__f_ == 0)
Howard Hinnant99968442011-11-29 18:15:50 +00001309 return (_Tp*)0;
1310 return (_Tp*)__f_->target(typeid(_Tp));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001311}
1312
Howard Hinnant99968442011-11-29 18:15:50 +00001313template<class _Rp, class _A0, class _A1>
1314template <typename _Tp>
1315const _Tp*
1316function<_Rp(_A0, _A1)>::target() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001317{
1318 if (__f_ == 0)
Howard Hinnant99968442011-11-29 18:15:50 +00001319 return (const _Tp*)0;
1320 return (const _Tp*)__f_->target(typeid(_Tp));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001321}
1322
Howard Hinnant324bb032010-08-22 00:02:43 +00001323#endif // _LIBCPP_NO_RTTI
Howard Hinnantd4444702010-08-11 17:04:31 +00001324
Howard Hinnant99968442011-11-29 18:15:50 +00001325template<class _Rp, class _A0, class _A1, class _A2>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00001326class _LIBCPP_TYPE_VIS_ONLY function<_Rp(_A0, _A1, _A2)>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001327{
Howard Hinnant99968442011-11-29 18:15:50 +00001328 typedef __function::__base<_Rp(_A0, _A1, _A2)> __base;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001329 aligned_storage<3*sizeof(void*)>::type __buf_;
1330 __base* __f_;
1331
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001332 template <class _Fp>
1333 _LIBCPP_INLINE_VISIBILITY
1334 static bool __not_null(const _Fp&) {return true;}
1335 template <class _R2, class _B0, class _B1, class _B2>
1336 _LIBCPP_INLINE_VISIBILITY
1337 static bool __not_null(_R2 (*__p)(_B0, _B1, _B2)) {return __p;}
1338 template <class _R2, class _Cp, class _B1, class _B2>
1339 _LIBCPP_INLINE_VISIBILITY
1340 static bool __not_null(_R2 (_Cp::*__p)(_B1, _B2)) {return __p;}
1341 template <class _R2, class _Cp, class _B1, class _B2>
1342 _LIBCPP_INLINE_VISIBILITY
1343 static bool __not_null(_R2 (_Cp::*__p)(_B1, _B2) const) {return __p;}
1344 template <class _R2, class _Cp, class _B1, class _B2>
1345 _LIBCPP_INLINE_VISIBILITY
1346 static bool __not_null(_R2 (_Cp::*__p)(_B1, _B2) volatile) {return __p;}
1347 template <class _R2, class _Cp, class _B1, class _B2>
1348 _LIBCPP_INLINE_VISIBILITY
1349 static bool __not_null(_R2 (_Cp::*__p)(_B1, _B2) const volatile) {return __p;}
1350 template <class _R2, class _B0, class _B1, class _B2>
1351 _LIBCPP_INLINE_VISIBILITY
1352 static bool __not_null(const function<_R2(_B0, _B1, _B2)>& __p) {return __p;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001353public:
Howard Hinnant99968442011-11-29 18:15:50 +00001354 typedef _Rp result_type;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001355
1356 // 20.7.16.2.1, construct/copy/destroy:
Howard Hinnant99acc502010-09-21 17:32:39 +00001357 _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
1358 _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001359 function(const function&);
Howard Hinnant99968442011-11-29 18:15:50 +00001360 template<class _Fp>
1361 function(_Fp,
1362 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001363
Howard Hinnant72552802010-08-20 19:36:46 +00001364 template<class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +00001365 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant72552802010-08-20 19:36:46 +00001366 function(allocator_arg_t, const _Alloc&) : __f_(0) {}
1367 template<class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +00001368 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant72552802010-08-20 19:36:46 +00001369 function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
1370 template<class _Alloc>
1371 function(allocator_arg_t, const _Alloc&, const function&);
Howard Hinnant99968442011-11-29 18:15:50 +00001372 template<class _Fp, class _Alloc>
1373 function(allocator_arg_t, const _Alloc& __a, _Fp __f,
1374 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001375
1376 function& operator=(const function&);
1377 function& operator=(nullptr_t);
Howard Hinnant99968442011-11-29 18:15:50 +00001378 template<class _Fp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001379 typename enable_if
1380 <
Howard Hinnant99968442011-11-29 18:15:50 +00001381 !is_integral<_Fp>::value,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001382 function&
1383 >::type
Howard Hinnant99968442011-11-29 18:15:50 +00001384 operator=(_Fp);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001385
1386 ~function();
1387
1388 // 20.7.16.2.2, function modifiers:
1389 void swap(function&);
Howard Hinnant99968442011-11-29 18:15:50 +00001390 template<class _Fp, class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +00001391 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001392 void assign(_Fp __f, const _Alloc& __a)
Howard Hinnant72552802010-08-20 19:36:46 +00001393 {function(allocator_arg, __a, __f).swap(*this);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001394
1395 // 20.7.16.2.3, function capacity:
Howard Hinnant99acc502010-09-21 17:32:39 +00001396 _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001397
1398private:
1399 // deleted overloads close possible hole in the type system
1400 template<class _R2, class _B0, class _B1, class _B2>
Howard Hinnant99acc502010-09-21 17:32:39 +00001401 bool operator==(const function<_R2(_B0, _B1, _B2)>&) const;// = delete;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001402 template<class _R2, class _B0, class _B1, class _B2>
Howard Hinnant99acc502010-09-21 17:32:39 +00001403 bool operator!=(const function<_R2(_B0, _B1, _B2)>&) const;// = delete;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001404public:
1405 // 20.7.16.2.4, function invocation:
Howard Hinnant99968442011-11-29 18:15:50 +00001406 _Rp operator()(_A0, _A1, _A2) const;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001407
Howard Hinnantd4444702010-08-11 17:04:31 +00001408#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001409 // 20.7.16.2.5, function target access:
1410 const std::type_info& target_type() const;
Howard Hinnant99968442011-11-29 18:15:50 +00001411 template <typename _Tp> _Tp* target();
1412 template <typename _Tp> const _Tp* target() const;
Howard Hinnant324bb032010-08-22 00:02:43 +00001413#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001414};
1415
Howard Hinnant99968442011-11-29 18:15:50 +00001416template<class _Rp, class _A0, class _A1, class _A2>
1417function<_Rp(_A0, _A1, _A2)>::function(const function& __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001418{
1419 if (__f.__f_ == 0)
1420 __f_ = 0;
1421 else if (__f.__f_ == (const __base*)&__f.__buf_)
1422 {
1423 __f_ = (__base*)&__buf_;
1424 __f.__f_->__clone(__f_);
1425 }
1426 else
1427 __f_ = __f.__f_->__clone();
1428}
1429
Howard Hinnant99968442011-11-29 18:15:50 +00001430template<class _Rp, class _A0, class _A1, class _A2>
Howard Hinnant72552802010-08-20 19:36:46 +00001431template<class _Alloc>
Howard Hinnant99968442011-11-29 18:15:50 +00001432function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc&,
Howard Hinnant72552802010-08-20 19:36:46 +00001433 const function& __f)
1434{
1435 if (__f.__f_ == 0)
1436 __f_ = 0;
1437 else if (__f.__f_ == (const __base*)&__f.__buf_)
1438 {
1439 __f_ = (__base*)&__buf_;
1440 __f.__f_->__clone(__f_);
1441 }
1442 else
1443 __f_ = __f.__f_->__clone();
1444}
1445
Howard Hinnant99968442011-11-29 18:15:50 +00001446template<class _Rp, class _A0, class _A1, class _A2>
1447template <class _Fp>
1448function<_Rp(_A0, _A1, _A2)>::function(_Fp __f,
1449 typename enable_if<!is_integral<_Fp>::value>::type*)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001450 : __f_(0)
1451{
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001452 if (__not_null(__f))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001453 {
Howard Hinnant99968442011-11-29 18:15:50 +00001454 typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1, _A2)> _FF;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001455 if (sizeof(_FF) <= sizeof(__buf_))
1456 {
1457 __f_ = (__base*)&__buf_;
1458 ::new (__f_) _FF(__f);
1459 }
1460 else
1461 {
Howard Hinnant99968442011-11-29 18:15:50 +00001462 typedef allocator<_FF> _Ap;
1463 _Ap __a;
1464 typedef __allocator_destructor<_Ap> _Dp;
1465 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1466 ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001467 __f_ = __hold.release();
1468 }
1469 }
1470}
1471
Howard Hinnant99968442011-11-29 18:15:50 +00001472template<class _Rp, class _A0, class _A1, class _A2>
1473template <class _Fp, class _Alloc>
1474function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
1475 typename enable_if<!is_integral<_Fp>::value>::type*)
Howard Hinnant72552802010-08-20 19:36:46 +00001476 : __f_(0)
1477{
1478 typedef allocator_traits<_Alloc> __alloc_traits;
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001479 if (__not_null(__f))
Howard Hinnant72552802010-08-20 19:36:46 +00001480 {
Howard Hinnant99968442011-11-29 18:15:50 +00001481 typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> _FF;
Howard Hinnant72552802010-08-20 19:36:46 +00001482 if (sizeof(_FF) <= sizeof(__buf_))
1483 {
1484 __f_ = (__base*)&__buf_;
Eric Fiselierb05f0592015-06-14 23:30:09 +00001485 ::new (__f_) _FF(__f, __a0);
Howard Hinnant72552802010-08-20 19:36:46 +00001486 }
1487 else
1488 {
Marshall Clow66302c62015-04-07 05:21:38 +00001489 typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
Howard Hinnant99968442011-11-29 18:15:50 +00001490 _Ap __a(__a0);
1491 typedef __allocator_destructor<_Ap> _Dp;
1492 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Howard Hinnant72552802010-08-20 19:36:46 +00001493 ::new (__hold.get()) _FF(__f, _Alloc(__a));
1494 __f_ = __hold.release();
1495 }
1496 }
1497}
1498
Howard Hinnant99968442011-11-29 18:15:50 +00001499template<class _Rp, class _A0, class _A1, class _A2>
1500function<_Rp(_A0, _A1, _A2)>&
1501function<_Rp(_A0, _A1, _A2)>::operator=(const function& __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001502{
1503 function(__f).swap(*this);
1504 return *this;
1505}
1506
Howard Hinnant99968442011-11-29 18:15:50 +00001507template<class _Rp, class _A0, class _A1, class _A2>
1508function<_Rp(_A0, _A1, _A2)>&
1509function<_Rp(_A0, _A1, _A2)>::operator=(nullptr_t)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001510{
1511 if (__f_ == (__base*)&__buf_)
1512 __f_->destroy();
1513 else if (__f_)
1514 __f_->destroy_deallocate();
1515 __f_ = 0;
Eric Fiselierfa97c2e2015-06-02 01:31:33 +00001516 return *this;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001517}
1518
Howard Hinnant99968442011-11-29 18:15:50 +00001519template<class _Rp, class _A0, class _A1, class _A2>
1520template <class _Fp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001521typename enable_if
1522<
Howard Hinnant99968442011-11-29 18:15:50 +00001523 !is_integral<_Fp>::value,
1524 function<_Rp(_A0, _A1, _A2)>&
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001525>::type
Howard Hinnant99968442011-11-29 18:15:50 +00001526function<_Rp(_A0, _A1, _A2)>::operator=(_Fp __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001527{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001528 function(_VSTD::move(__f)).swap(*this);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001529 return *this;
1530}
1531
Howard Hinnant99968442011-11-29 18:15:50 +00001532template<class _Rp, class _A0, class _A1, class _A2>
1533function<_Rp(_A0, _A1, _A2)>::~function()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001534{
1535 if (__f_ == (__base*)&__buf_)
1536 __f_->destroy();
1537 else if (__f_)
1538 __f_->destroy_deallocate();
1539}
1540
Howard Hinnant99968442011-11-29 18:15:50 +00001541template<class _Rp, class _A0, class _A1, class _A2>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001542void
Howard Hinnant99968442011-11-29 18:15:50 +00001543function<_Rp(_A0, _A1, _A2)>::swap(function& __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001544{
1545 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1546 {
1547 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1548 __base* __t = (__base*)&__tempbuf;
1549 __f_->__clone(__t);
1550 __f_->destroy();
1551 __f_ = 0;
1552 __f.__f_->__clone((__base*)&__buf_);
1553 __f.__f_->destroy();
1554 __f.__f_ = 0;
1555 __f_ = (__base*)&__buf_;
1556 __t->__clone((__base*)&__f.__buf_);
1557 __t->destroy();
1558 __f.__f_ = (__base*)&__f.__buf_;
1559 }
1560 else if (__f_ == (__base*)&__buf_)
1561 {
1562 __f_->__clone((__base*)&__f.__buf_);
1563 __f_->destroy();
1564 __f_ = __f.__f_;
1565 __f.__f_ = (__base*)&__f.__buf_;
1566 }
1567 else if (__f.__f_ == (__base*)&__f.__buf_)
1568 {
1569 __f.__f_->__clone((__base*)&__buf_);
1570 __f.__f_->destroy();
1571 __f.__f_ = __f_;
1572 __f_ = (__base*)&__buf_;
1573 }
1574 else
Howard Hinnant0949eed2011-06-30 21:18:19 +00001575 _VSTD::swap(__f_, __f.__f_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001576}
1577
Howard Hinnant99968442011-11-29 18:15:50 +00001578template<class _Rp, class _A0, class _A1, class _A2>
1579_Rp
1580function<_Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001581{
Howard Hinnantd4444702010-08-11 17:04:31 +00001582#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001583 if (__f_ == 0)
1584 throw bad_function_call();
Howard Hinnant324bb032010-08-22 00:02:43 +00001585#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001586 return (*__f_)(__a0, __a1, __a2);
1587}
1588
Howard Hinnantd4444702010-08-11 17:04:31 +00001589#ifndef _LIBCPP_NO_RTTI
1590
Howard Hinnant99968442011-11-29 18:15:50 +00001591template<class _Rp, class _A0, class _A1, class _A2>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001592const std::type_info&
Howard Hinnant99968442011-11-29 18:15:50 +00001593function<_Rp(_A0, _A1, _A2)>::target_type() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001594{
1595 if (__f_ == 0)
1596 return typeid(void);
1597 return __f_->target_type();
1598}
1599
Howard Hinnant99968442011-11-29 18:15:50 +00001600template<class _Rp, class _A0, class _A1, class _A2>
1601template <typename _Tp>
1602_Tp*
1603function<_Rp(_A0, _A1, _A2)>::target()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001604{
1605 if (__f_ == 0)
Howard Hinnant99968442011-11-29 18:15:50 +00001606 return (_Tp*)0;
1607 return (_Tp*)__f_->target(typeid(_Tp));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001608}
1609
Howard Hinnant99968442011-11-29 18:15:50 +00001610template<class _Rp, class _A0, class _A1, class _A2>
1611template <typename _Tp>
1612const _Tp*
1613function<_Rp(_A0, _A1, _A2)>::target() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001614{
1615 if (__f_ == 0)
Howard Hinnant99968442011-11-29 18:15:50 +00001616 return (const _Tp*)0;
1617 return (const _Tp*)__f_->target(typeid(_Tp));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001618}
1619
Howard Hinnant324bb032010-08-22 00:02:43 +00001620#endif // _LIBCPP_NO_RTTI
Howard Hinnantd4444702010-08-11 17:04:31 +00001621
Howard Hinnant99968442011-11-29 18:15:50 +00001622template <class _Fp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001623inline _LIBCPP_INLINE_VISIBILITY
1624bool
Howard Hinnant99968442011-11-29 18:15:50 +00001625operator==(const function<_Fp>& __f, nullptr_t) {return !__f;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001626
Howard Hinnant99968442011-11-29 18:15:50 +00001627template <class _Fp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001628inline _LIBCPP_INLINE_VISIBILITY
1629bool
Howard Hinnant99968442011-11-29 18:15:50 +00001630operator==(nullptr_t, const function<_Fp>& __f) {return !__f;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001631
Howard Hinnant99968442011-11-29 18:15:50 +00001632template <class _Fp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001633inline _LIBCPP_INLINE_VISIBILITY
1634bool
Howard Hinnant99968442011-11-29 18:15:50 +00001635operator!=(const function<_Fp>& __f, nullptr_t) {return (bool)__f;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001636
Howard Hinnant99968442011-11-29 18:15:50 +00001637template <class _Fp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001638inline _LIBCPP_INLINE_VISIBILITY
1639bool
Howard Hinnant99968442011-11-29 18:15:50 +00001640operator!=(nullptr_t, const function<_Fp>& __f) {return (bool)__f;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001641
Howard Hinnant99968442011-11-29 18:15:50 +00001642template <class _Fp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001643inline _LIBCPP_INLINE_VISIBILITY
1644void
Howard Hinnant99968442011-11-29 18:15:50 +00001645swap(function<_Fp>& __x, function<_Fp>& __y)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001646{return __x.swap(__y);}
1647
Howard Hinnant324bb032010-08-22 00:02:43 +00001648#endif // _LIBCPP_FUNCTIONAL_03