__functional_03 revision 360784
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_FUNCTIONAL_03
11#define _LIBCPP_FUNCTIONAL_03
12
13// manual variadic expansion for <functional>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16#pragma GCC system_header
17#endif
18
19namespace __function {
20
21template<class _Fp> class __base;
22
23template<class _Rp>
24class __base<_Rp()>
25{
26    __base(const __base&);
27    __base& operator=(const __base&);
28public:
29    __base() {}
30    virtual ~__base() {}
31    virtual __base* __clone() const = 0;
32    virtual void __clone(__base*) const = 0;
33    virtual void destroy() = 0;
34    virtual void destroy_deallocate() = 0;
35    virtual _Rp operator()() = 0;
36#ifndef _LIBCPP_NO_RTTI
37    virtual const void* target(const type_info&) const = 0;
38    virtual const std::type_info& target_type() const = 0;
39#endif  // _LIBCPP_NO_RTTI
40};
41
42template<class _Rp, class _A0>
43class __base<_Rp(_A0)>
44{
45    __base(const __base&);
46    __base& operator=(const __base&);
47public:
48    __base() {}
49    virtual ~__base() {}
50    virtual __base* __clone() const = 0;
51    virtual void __clone(__base*) const = 0;
52    virtual void destroy() = 0;
53    virtual void destroy_deallocate() = 0;
54    virtual _Rp operator()(_A0) = 0;
55#ifndef _LIBCPP_NO_RTTI
56    virtual const void* target(const type_info&) const = 0;
57    virtual const std::type_info& target_type() const = 0;
58#endif  // _LIBCPP_NO_RTTI
59};
60
61template<class _Rp, class _A0, class _A1>
62class __base<_Rp(_A0, _A1)>
63{
64    __base(const __base&);
65    __base& operator=(const __base&);
66public:
67    __base() {}
68    virtual ~__base() {}
69    virtual __base* __clone() const = 0;
70    virtual void __clone(__base*) const = 0;
71    virtual void destroy() = 0;
72    virtual void destroy_deallocate() = 0;
73    virtual _Rp operator()(_A0, _A1) = 0;
74#ifndef _LIBCPP_NO_RTTI
75    virtual const void* target(const type_info&) const = 0;
76    virtual const std::type_info& target_type() const = 0;
77#endif  // _LIBCPP_NO_RTTI
78};
79
80template<class _Rp, class _A0, class _A1, class _A2>
81class __base<_Rp(_A0, _A1, _A2)>
82{
83    __base(const __base&);
84    __base& operator=(const __base&);
85public:
86    __base() {}
87    virtual ~__base() {}
88    virtual __base* __clone() const = 0;
89    virtual void __clone(__base*) const = 0;
90    virtual void destroy() = 0;
91    virtual void destroy_deallocate() = 0;
92    virtual _Rp operator()(_A0, _A1, _A2) = 0;
93#ifndef _LIBCPP_NO_RTTI
94    virtual const void* target(const type_info&) const = 0;
95    virtual const std::type_info& target_type() const = 0;
96#endif  // _LIBCPP_NO_RTTI
97};
98
99template<class _FD, class _Alloc, class _FB> class __func;
100
101template<class _Fp, class _Alloc, class _Rp>
102class __func<_Fp, _Alloc, _Rp()>
103    : public  __base<_Rp()>
104{
105    __compressed_pair<_Fp, _Alloc> __f_;
106public:
107    explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {}
108    explicit __func(_Fp __f, _Alloc __a) : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
109    virtual __base<_Rp()>* __clone() const;
110    virtual void __clone(__base<_Rp()>*) const;
111    virtual void destroy();
112    virtual void destroy_deallocate();
113    virtual _Rp operator()();
114#ifndef _LIBCPP_NO_RTTI
115    virtual const void* target(const type_info&) const;
116    virtual const std::type_info& target_type() const;
117#endif  // _LIBCPP_NO_RTTI
118};
119
120template<class _Fp, class _Alloc, class _Rp>
121__base<_Rp()>*
122__func<_Fp, _Alloc, _Rp()>::__clone() const
123{
124    typedef allocator_traits<_Alloc> __alloc_traits;
125    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
126    _Ap __a(__f_.second());
127    typedef __allocator_destructor<_Ap> _Dp;
128    unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
129    ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
130    return __hold.release();
131}
132
133template<class _Fp, class _Alloc, class _Rp>
134void
135__func<_Fp, _Alloc, _Rp()>::__clone(__base<_Rp()>* __p) const
136{
137    ::new (__p) __func(__f_.first(), __f_.second());
138}
139
140template<class _Fp, class _Alloc, class _Rp>
141void
142__func<_Fp, _Alloc, _Rp()>::destroy()
143{
144    __f_.~__compressed_pair<_Fp, _Alloc>();
145}
146
147template<class _Fp, class _Alloc, class _Rp>
148void
149__func<_Fp, _Alloc, _Rp()>::destroy_deallocate()
150{
151    typedef allocator_traits<_Alloc> __alloc_traits;
152    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
153    _Ap __a(__f_.second());
154    __f_.~__compressed_pair<_Fp, _Alloc>();
155    __a.deallocate(this, 1);
156}
157
158template<class _Fp, class _Alloc, class _Rp>
159_Rp
160__func<_Fp, _Alloc, _Rp()>::operator()()
161{
162    typedef __invoke_void_return_wrapper<_Rp> _Invoker;
163    return _Invoker::__call(__f_.first());
164}
165
166#ifndef _LIBCPP_NO_RTTI
167
168template<class _Fp, class _Alloc, class _Rp>
169const void*
170__func<_Fp, _Alloc, _Rp()>::target(const type_info& __ti) const
171{
172    if (__ti == typeid(_Fp))
173        return &__f_.first();
174    return (const void*)0;
175}
176
177template<class _Fp, class _Alloc, class _Rp>
178const std::type_info&
179__func<_Fp, _Alloc, _Rp()>::target_type() const
180{
181    return typeid(_Fp);
182}
183
184#endif  // _LIBCPP_NO_RTTI
185
186template<class _Fp, class _Alloc, class _Rp, class _A0>
187class __func<_Fp, _Alloc, _Rp(_A0)>
188    : public  __base<_Rp(_A0)>
189{
190    __compressed_pair<_Fp, _Alloc> __f_;
191public:
192    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {}
193    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
194        : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
195    virtual __base<_Rp(_A0)>* __clone() const;
196    virtual void __clone(__base<_Rp(_A0)>*) const;
197    virtual void destroy();
198    virtual void destroy_deallocate();
199    virtual _Rp operator()(_A0);
200#ifndef _LIBCPP_NO_RTTI
201    virtual const void* target(const type_info&) const;
202    virtual const std::type_info& target_type() const;
203#endif  // _LIBCPP_NO_RTTI
204};
205
206template<class _Fp, class _Alloc, class _Rp, class _A0>
207__base<_Rp(_A0)>*
208__func<_Fp, _Alloc, _Rp(_A0)>::__clone() const
209{
210    typedef allocator_traits<_Alloc> __alloc_traits;
211    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
212    _Ap __a(__f_.second());
213    typedef __allocator_destructor<_Ap> _Dp;
214    unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
215    ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
216    return __hold.release();
217}
218
219template<class _Fp, class _Alloc, class _Rp, class _A0>
220void
221__func<_Fp, _Alloc, _Rp(_A0)>::__clone(__base<_Rp(_A0)>* __p) const
222{
223    ::new (__p) __func(__f_.first(), __f_.second());
224}
225
226template<class _Fp, class _Alloc, class _Rp, class _A0>
227void
228__func<_Fp, _Alloc, _Rp(_A0)>::destroy()
229{
230    __f_.~__compressed_pair<_Fp, _Alloc>();
231}
232
233template<class _Fp, class _Alloc, class _Rp, class _A0>
234void
235__func<_Fp, _Alloc, _Rp(_A0)>::destroy_deallocate()
236{
237    typedef allocator_traits<_Alloc> __alloc_traits;
238    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
239    _Ap __a(__f_.second());
240    __f_.~__compressed_pair<_Fp, _Alloc>();
241    __a.deallocate(this, 1);
242}
243
244template<class _Fp, class _Alloc, class _Rp, class _A0>
245_Rp
246__func<_Fp, _Alloc, _Rp(_A0)>::operator()(_A0 __a0)
247{
248    typedef __invoke_void_return_wrapper<_Rp> _Invoker;
249    return _Invoker::__call(__f_.first(), __a0);
250}
251
252#ifndef _LIBCPP_NO_RTTI
253
254template<class _Fp, class _Alloc, class _Rp, class _A0>
255const void*
256__func<_Fp, _Alloc, _Rp(_A0)>::target(const type_info& __ti) const
257{
258    if (__ti == typeid(_Fp))
259        return &__f_.first();
260    return (const void*)0;
261}
262
263template<class _Fp, class _Alloc, class _Rp, class _A0>
264const std::type_info&
265__func<_Fp, _Alloc, _Rp(_A0)>::target_type() const
266{
267    return typeid(_Fp);
268}
269
270#endif  // _LIBCPP_NO_RTTI
271
272template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
273class __func<_Fp, _Alloc, _Rp(_A0, _A1)>
274    : public  __base<_Rp(_A0, _A1)>
275{
276    __compressed_pair<_Fp, _Alloc> __f_;
277public:
278    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {}
279    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
280        : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
281    virtual __base<_Rp(_A0, _A1)>* __clone() const;
282    virtual void __clone(__base<_Rp(_A0, _A1)>*) const;
283    virtual void destroy();
284    virtual void destroy_deallocate();
285    virtual _Rp operator()(_A0, _A1);
286#ifndef _LIBCPP_NO_RTTI
287    virtual const void* target(const type_info&) const;
288    virtual const std::type_info& target_type() const;
289#endif  // _LIBCPP_NO_RTTI
290};
291
292template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
293__base<_Rp(_A0, _A1)>*
294__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone() const
295{
296    typedef allocator_traits<_Alloc> __alloc_traits;
297    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
298    _Ap __a(__f_.second());
299    typedef __allocator_destructor<_Ap> _Dp;
300    unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
301    ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
302    return __hold.release();
303}
304
305template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
306void
307__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone(__base<_Rp(_A0, _A1)>* __p) const
308{
309    ::new (__p) __func(__f_.first(), __f_.second());
310}
311
312template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
313void
314__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy()
315{
316    __f_.~__compressed_pair<_Fp, _Alloc>();
317}
318
319template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
320void
321__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy_deallocate()
322{
323    typedef allocator_traits<_Alloc> __alloc_traits;
324    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
325    _Ap __a(__f_.second());
326    __f_.~__compressed_pair<_Fp, _Alloc>();
327    __a.deallocate(this, 1);
328}
329
330template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
331_Rp
332__func<_Fp, _Alloc, _Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1)
333{
334    typedef __invoke_void_return_wrapper<_Rp> _Invoker;
335    return _Invoker::__call(__f_.first(), __a0, __a1);
336}
337
338#ifndef _LIBCPP_NO_RTTI
339
340template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
341const void*
342__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target(const type_info& __ti) const
343{
344    if (__ti == typeid(_Fp))
345        return &__f_.first();
346    return (const void*)0;
347}
348
349template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
350const std::type_info&
351__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target_type() const
352{
353    return typeid(_Fp);
354}
355
356#endif  // _LIBCPP_NO_RTTI
357
358template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
359class __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>
360    : public  __base<_Rp(_A0, _A1, _A2)>
361{
362    __compressed_pair<_Fp, _Alloc> __f_;
363public:
364    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {}
365    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
366        : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
367    virtual __base<_Rp(_A0, _A1, _A2)>* __clone() const;
368    virtual void __clone(__base<_Rp(_A0, _A1, _A2)>*) const;
369    virtual void destroy();
370    virtual void destroy_deallocate();
371    virtual _Rp operator()(_A0, _A1, _A2);
372#ifndef _LIBCPP_NO_RTTI
373    virtual const void* target(const type_info&) const;
374    virtual const std::type_info& target_type() const;
375#endif  // _LIBCPP_NO_RTTI
376};
377
378template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
379__base<_Rp(_A0, _A1, _A2)>*
380__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone() const
381{
382    typedef allocator_traits<_Alloc> __alloc_traits;
383    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
384    _Ap __a(__f_.second());
385    typedef __allocator_destructor<_Ap> _Dp;
386    unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
387    ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
388    return __hold.release();
389}
390
391template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
392void
393__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone(__base<_Rp(_A0, _A1, _A2)>* __p) const
394{
395    ::new (__p) __func(__f_.first(), __f_.second());
396}
397
398template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
399void
400__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy()
401{
402    __f_.~__compressed_pair<_Fp, _Alloc>();
403}
404
405template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
406void
407__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy_deallocate()
408{
409    typedef allocator_traits<_Alloc> __alloc_traits;
410    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
411    _Ap __a(__f_.second());
412    __f_.~__compressed_pair<_Fp, _Alloc>();
413    __a.deallocate(this, 1);
414}
415
416template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
417_Rp
418__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2)
419{
420    typedef __invoke_void_return_wrapper<_Rp> _Invoker;
421    return _Invoker::__call(__f_.first(), __a0, __a1, __a2);
422}
423
424#ifndef _LIBCPP_NO_RTTI
425
426template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
427const void*
428__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target(const type_info& __ti) const
429{
430    if (__ti == typeid(_Fp))
431        return &__f_.first();
432    return (const void*)0;
433}
434
435template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
436const std::type_info&
437__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target_type() const
438{
439    return typeid(_Fp);
440}
441
442#endif  // _LIBCPP_NO_RTTI
443
444}  // __function
445
446template<class _Rp>
447class _LIBCPP_TEMPLATE_VIS function<_Rp()>
448{
449    typedef __function::__base<_Rp()> __base;
450    aligned_storage<3*sizeof(void*)>::type __buf_;
451    __base* __f_;
452
453public:
454    typedef _Rp result_type;
455
456    // 20.7.16.2.1, construct/copy/destroy:
457    _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
458    _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
459    function(const function&);
460    template<class _Fp>
461      function(_Fp,
462               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
463
464    template<class _Alloc>
465      _LIBCPP_INLINE_VISIBILITY
466      function(allocator_arg_t, const _Alloc&) : __f_(0) {}
467    template<class _Alloc>
468      _LIBCPP_INLINE_VISIBILITY
469      function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
470    template<class _Alloc>
471      function(allocator_arg_t, const _Alloc&, const function&);
472    template<class _Fp, class _Alloc>
473      function(allocator_arg_t, const _Alloc& __a, _Fp __f,
474               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
475
476    function& operator=(const function&);
477    function& operator=(nullptr_t);
478    template<class _Fp>
479      typename enable_if
480      <
481        !is_integral<_Fp>::value,
482        function&
483      >::type
484      operator=(_Fp);
485
486    ~function();
487
488    // 20.7.16.2.2, function modifiers:
489    void swap(function&);
490    template<class _Fp, class _Alloc>
491      _LIBCPP_INLINE_VISIBILITY
492      void assign(_Fp __f, const _Alloc& __a)
493        {function(allocator_arg, __a, __f).swap(*this);}
494
495    // 20.7.16.2.3, function capacity:
496    _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}
497
498private:
499    // deleted overloads close possible hole in the type system
500    template<class _R2>
501      bool operator==(const function<_R2()>&) const;// = delete;
502    template<class _R2>
503      bool operator!=(const function<_R2()>&) const;// = delete;
504public:
505    // 20.7.16.2.4, function invocation:
506    _Rp operator()() const;
507
508#ifndef _LIBCPP_NO_RTTI
509    // 20.7.16.2.5, function target access:
510    const std::type_info& target_type() const;
511    template <typename _Tp> _Tp* target();
512    template <typename _Tp> const _Tp* target() const;
513#endif  // _LIBCPP_NO_RTTI
514};
515
516template<class _Rp>
517function<_Rp()>::function(const function& __f)
518{
519    if (__f.__f_ == 0)
520        __f_ = 0;
521    else if (__f.__f_ == (const __base*)&__f.__buf_)
522    {
523        __f_ = (__base*)&__buf_;
524        __f.__f_->__clone(__f_);
525    }
526    else
527        __f_ = __f.__f_->__clone();
528}
529
530template<class _Rp>
531template<class _Alloc>
532function<_Rp()>::function(allocator_arg_t, const _Alloc&, const function& __f)
533{
534    if (__f.__f_ == 0)
535        __f_ = 0;
536    else if (__f.__f_ == (const __base*)&__f.__buf_)
537    {
538        __f_ = (__base*)&__buf_;
539        __f.__f_->__clone(__f_);
540    }
541    else
542        __f_ = __f.__f_->__clone();
543}
544
545template<class _Rp>
546template <class _Fp>
547function<_Rp()>::function(_Fp __f,
548                                     typename enable_if<!is_integral<_Fp>::value>::type*)
549    : __f_(0)
550{
551    if (__function::__not_null(__f))
552    {
553        typedef __function::__func<_Fp, allocator<_Fp>, _Rp()> _FF;
554        if (sizeof(_FF) <= sizeof(__buf_))
555        {
556            __f_ = (__base*)&__buf_;
557            ::new (__f_) _FF(__f);
558        }
559        else
560        {
561            typedef allocator<_FF> _Ap;
562            _Ap __a;
563            typedef __allocator_destructor<_Ap> _Dp;
564            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
565            ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a));
566            __f_ = __hold.release();
567        }
568    }
569}
570
571template<class _Rp>
572template <class _Fp, class _Alloc>
573function<_Rp()>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
574                                     typename enable_if<!is_integral<_Fp>::value>::type*)
575    : __f_(0)
576{
577    typedef allocator_traits<_Alloc> __alloc_traits;
578    if (__function::__not_null(__f))
579    {
580        typedef __function::__func<_Fp, _Alloc, _Rp()> _FF;
581        if (sizeof(_FF) <= sizeof(__buf_))
582        {
583            __f_ = (__base*)&__buf_;
584            ::new (__f_) _FF(__f, __a0);
585        }
586        else
587        {
588            typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
589            _Ap __a(__a0);
590            typedef __allocator_destructor<_Ap> _Dp;
591            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
592            ::new (__hold.get()) _FF(__f, _Alloc(__a));
593            __f_ = __hold.release();
594        }
595    }
596}
597
598template<class _Rp>
599function<_Rp()>&
600function<_Rp()>::operator=(const function& __f)
601{
602    if (__f)
603        function(__f).swap(*this);
604    else
605        *this = nullptr;
606    return *this;
607}
608
609template<class _Rp>
610function<_Rp()>&
611function<_Rp()>::operator=(nullptr_t)
612{
613    __base* __t = __f_;
614    __f_ = 0;
615    if (__t == (__base*)&__buf_)
616        __t->destroy();
617    else if (__t)
618        __t->destroy_deallocate();
619    return *this;
620}
621
622template<class _Rp>
623template <class _Fp>
624typename enable_if
625<
626    !is_integral<_Fp>::value,
627    function<_Rp()>&
628>::type
629function<_Rp()>::operator=(_Fp __f)
630{
631    function(_VSTD::move(__f)).swap(*this);
632    return *this;
633}
634
635template<class _Rp>
636function<_Rp()>::~function()
637{
638    if (__f_ == (__base*)&__buf_)
639        __f_->destroy();
640    else if (__f_)
641        __f_->destroy_deallocate();
642}
643
644template<class _Rp>
645void
646function<_Rp()>::swap(function& __f)
647{
648    if (_VSTD::addressof(__f) == this)
649      return;
650    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
651    {
652        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
653        __base* __t = (__base*)&__tempbuf;
654        __f_->__clone(__t);
655        __f_->destroy();
656        __f_ = 0;
657        __f.__f_->__clone((__base*)&__buf_);
658        __f.__f_->destroy();
659        __f.__f_ = 0;
660        __f_ = (__base*)&__buf_;
661        __t->__clone((__base*)&__f.__buf_);
662        __t->destroy();
663        __f.__f_ = (__base*)&__f.__buf_;
664    }
665    else if (__f_ == (__base*)&__buf_)
666    {
667        __f_->__clone((__base*)&__f.__buf_);
668        __f_->destroy();
669        __f_ = __f.__f_;
670        __f.__f_ = (__base*)&__f.__buf_;
671    }
672    else if (__f.__f_ == (__base*)&__f.__buf_)
673    {
674        __f.__f_->__clone((__base*)&__buf_);
675        __f.__f_->destroy();
676        __f.__f_ = __f_;
677        __f_ = (__base*)&__buf_;
678    }
679    else
680        _VSTD::swap(__f_, __f.__f_);
681}
682
683template<class _Rp>
684_Rp
685function<_Rp()>::operator()() const
686{
687    if (__f_ == 0)
688        __throw_bad_function_call();
689    return (*__f_)();
690}
691
692#ifndef _LIBCPP_NO_RTTI
693
694template<class _Rp>
695const std::type_info&
696function<_Rp()>::target_type() const
697{
698    if (__f_ == 0)
699        return typeid(void);
700    return __f_->target_type();
701}
702
703template<class _Rp>
704template <typename _Tp>
705_Tp*
706function<_Rp()>::target()
707{
708    if (__f_ == 0)
709        return (_Tp*)0;
710    return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
711}
712
713template<class _Rp>
714template <typename _Tp>
715const _Tp*
716function<_Rp()>::target() const
717{
718    if (__f_ == 0)
719        return (const _Tp*)0;
720    return (const _Tp*)__f_->target(typeid(_Tp));
721}
722
723#endif  // _LIBCPP_NO_RTTI
724
725template<class _Rp, class _A0>
726class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0)>
727    : public unary_function<_A0, _Rp>
728{
729    typedef __function::__base<_Rp(_A0)> __base;
730    aligned_storage<3*sizeof(void*)>::type __buf_;
731    __base* __f_;
732
733public:
734    typedef _Rp result_type;
735
736    // 20.7.16.2.1, construct/copy/destroy:
737    _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
738    _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
739    function(const function&);
740    template<class _Fp>
741      function(_Fp,
742               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
743
744    template<class _Alloc>
745      _LIBCPP_INLINE_VISIBILITY
746      function(allocator_arg_t, const _Alloc&) : __f_(0) {}
747    template<class _Alloc>
748      _LIBCPP_INLINE_VISIBILITY
749      function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
750    template<class _Alloc>
751      function(allocator_arg_t, const _Alloc&, const function&);
752    template<class _Fp, class _Alloc>
753      function(allocator_arg_t, const _Alloc& __a, _Fp __f,
754               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
755
756    function& operator=(const function&);
757    function& operator=(nullptr_t);
758    template<class _Fp>
759      typename enable_if
760      <
761        !is_integral<_Fp>::value,
762        function&
763      >::type
764      operator=(_Fp);
765
766    ~function();
767
768    // 20.7.16.2.2, function modifiers:
769    void swap(function&);
770    template<class _Fp, class _Alloc>
771      _LIBCPP_INLINE_VISIBILITY
772      void assign(_Fp __f, const _Alloc& __a)
773        {function(allocator_arg, __a, __f).swap(*this);}
774
775    // 20.7.16.2.3, function capacity:
776    _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}
777
778private:
779    // deleted overloads close possible hole in the type system
780    template<class _R2, class _B0>
781      bool operator==(const function<_R2(_B0)>&) const;// = delete;
782    template<class _R2, class _B0>
783      bool operator!=(const function<_R2(_B0)>&) const;// = delete;
784public:
785    // 20.7.16.2.4, function invocation:
786    _Rp operator()(_A0) const;
787
788#ifndef _LIBCPP_NO_RTTI
789    // 20.7.16.2.5, function target access:
790    const std::type_info& target_type() const;
791    template <typename _Tp> _Tp* target();
792    template <typename _Tp> const _Tp* target() const;
793#endif  // _LIBCPP_NO_RTTI
794};
795
796template<class _Rp, class _A0>
797function<_Rp(_A0)>::function(const function& __f)
798{
799    if (__f.__f_ == 0)
800        __f_ = 0;
801    else if (__f.__f_ == (const __base*)&__f.__buf_)
802    {
803        __f_ = (__base*)&__buf_;
804        __f.__f_->__clone(__f_);
805    }
806    else
807        __f_ = __f.__f_->__clone();
808}
809
810template<class _Rp, class _A0>
811template<class _Alloc>
812function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc&, const function& __f)
813{
814    if (__f.__f_ == 0)
815        __f_ = 0;
816    else if (__f.__f_ == (const __base*)&__f.__buf_)
817    {
818        __f_ = (__base*)&__buf_;
819        __f.__f_->__clone(__f_);
820    }
821    else
822        __f_ = __f.__f_->__clone();
823}
824
825template<class _Rp, class _A0>
826template <class _Fp>
827function<_Rp(_A0)>::function(_Fp __f,
828                                     typename enable_if<!is_integral<_Fp>::value>::type*)
829    : __f_(0)
830{
831    if (__function::__not_null(__f))
832    {
833        typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0)> _FF;
834        if (sizeof(_FF) <= sizeof(__buf_))
835        {
836            __f_ = (__base*)&__buf_;
837            ::new (__f_) _FF(__f);
838        }
839        else
840        {
841            typedef allocator<_FF> _Ap;
842            _Ap __a;
843            typedef __allocator_destructor<_Ap> _Dp;
844            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
845            ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a));
846            __f_ = __hold.release();
847        }
848    }
849}
850
851template<class _Rp, class _A0>
852template <class _Fp, class _Alloc>
853function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
854                                     typename enable_if<!is_integral<_Fp>::value>::type*)
855    : __f_(0)
856{
857    typedef allocator_traits<_Alloc> __alloc_traits;
858    if (__function::__not_null(__f))
859    {
860        typedef __function::__func<_Fp, _Alloc, _Rp(_A0)> _FF;
861        if (sizeof(_FF) <= sizeof(__buf_))
862        {
863            __f_ = (__base*)&__buf_;
864            ::new (__f_) _FF(__f, __a0);
865        }
866        else
867        {
868            typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
869            _Ap __a(__a0);
870            typedef __allocator_destructor<_Ap> _Dp;
871            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
872            ::new (__hold.get()) _FF(__f, _Alloc(__a));
873            __f_ = __hold.release();
874        }
875    }
876}
877
878template<class _Rp, class _A0>
879function<_Rp(_A0)>&
880function<_Rp(_A0)>::operator=(const function& __f)
881{
882    if (__f)
883        function(__f).swap(*this);
884    else
885        *this = nullptr;
886    return *this;
887}
888
889template<class _Rp, class _A0>
890function<_Rp(_A0)>&
891function<_Rp(_A0)>::operator=(nullptr_t)
892{
893    __base* __t = __f_;
894    __f_ = 0;
895    if (__t == (__base*)&__buf_)
896        __t->destroy();
897    else if (__t)
898        __t->destroy_deallocate();
899    return *this;
900}
901
902template<class _Rp, class _A0>
903template <class _Fp>
904typename enable_if
905<
906    !is_integral<_Fp>::value,
907    function<_Rp(_A0)>&
908>::type
909function<_Rp(_A0)>::operator=(_Fp __f)
910{
911    function(_VSTD::move(__f)).swap(*this);
912    return *this;
913}
914
915template<class _Rp, class _A0>
916function<_Rp(_A0)>::~function()
917{
918    if (__f_ == (__base*)&__buf_)
919        __f_->destroy();
920    else if (__f_)
921        __f_->destroy_deallocate();
922}
923
924template<class _Rp, class _A0>
925void
926function<_Rp(_A0)>::swap(function& __f)
927{
928    if (_VSTD::addressof(__f) == this)
929      return;
930    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
931    {
932        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
933        __base* __t = (__base*)&__tempbuf;
934        __f_->__clone(__t);
935        __f_->destroy();
936        __f_ = 0;
937        __f.__f_->__clone((__base*)&__buf_);
938        __f.__f_->destroy();
939        __f.__f_ = 0;
940        __f_ = (__base*)&__buf_;
941        __t->__clone((__base*)&__f.__buf_);
942        __t->destroy();
943        __f.__f_ = (__base*)&__f.__buf_;
944    }
945    else if (__f_ == (__base*)&__buf_)
946    {
947        __f_->__clone((__base*)&__f.__buf_);
948        __f_->destroy();
949        __f_ = __f.__f_;
950        __f.__f_ = (__base*)&__f.__buf_;
951    }
952    else if (__f.__f_ == (__base*)&__f.__buf_)
953    {
954        __f.__f_->__clone((__base*)&__buf_);
955        __f.__f_->destroy();
956        __f.__f_ = __f_;
957        __f_ = (__base*)&__buf_;
958    }
959    else
960        _VSTD::swap(__f_, __f.__f_);
961}
962
963template<class _Rp, class _A0>
964_Rp
965function<_Rp(_A0)>::operator()(_A0 __a0) const
966{
967    if (__f_ == 0)
968        __throw_bad_function_call();
969    return (*__f_)(__a0);
970}
971
972#ifndef _LIBCPP_NO_RTTI
973
974template<class _Rp, class _A0>
975const std::type_info&
976function<_Rp(_A0)>::target_type() const
977{
978    if (__f_ == 0)
979        return typeid(void);
980    return __f_->target_type();
981}
982
983template<class _Rp, class _A0>
984template <typename _Tp>
985_Tp*
986function<_Rp(_A0)>::target()
987{
988    if (__f_ == 0)
989        return (_Tp*)0;
990    return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
991}
992
993template<class _Rp, class _A0>
994template <typename _Tp>
995const _Tp*
996function<_Rp(_A0)>::target() const
997{
998    if (__f_ == 0)
999        return (const _Tp*)0;
1000    return (const _Tp*)__f_->target(typeid(_Tp));
1001}
1002
1003#endif  // _LIBCPP_NO_RTTI
1004
1005template<class _Rp, class _A0, class _A1>
1006class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1)>
1007    : public binary_function<_A0, _A1, _Rp>
1008{
1009    typedef __function::__base<_Rp(_A0, _A1)> __base;
1010    aligned_storage<3*sizeof(void*)>::type __buf_;
1011    __base* __f_;
1012
1013public:
1014    typedef _Rp result_type;
1015
1016    // 20.7.16.2.1, construct/copy/destroy:
1017    _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
1018    _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
1019    function(const function&);
1020    template<class _Fp>
1021      function(_Fp,
1022               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
1023
1024    template<class _Alloc>
1025      _LIBCPP_INLINE_VISIBILITY
1026      function(allocator_arg_t, const _Alloc&) : __f_(0) {}
1027    template<class _Alloc>
1028      _LIBCPP_INLINE_VISIBILITY
1029      function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
1030    template<class _Alloc>
1031      function(allocator_arg_t, const _Alloc&, const function&);
1032    template<class _Fp, class _Alloc>
1033      function(allocator_arg_t, const _Alloc& __a, _Fp __f,
1034               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
1035
1036    function& operator=(const function&);
1037    function& operator=(nullptr_t);
1038    template<class _Fp>
1039      typename enable_if
1040      <
1041        !is_integral<_Fp>::value,
1042        function&
1043      >::type
1044      operator=(_Fp);
1045
1046    ~function();
1047
1048    // 20.7.16.2.2, function modifiers:
1049    void swap(function&);
1050    template<class _Fp, class _Alloc>
1051      _LIBCPP_INLINE_VISIBILITY
1052      void assign(_Fp __f, const _Alloc& __a)
1053        {function(allocator_arg, __a, __f).swap(*this);}
1054
1055    // 20.7.16.2.3, function capacity:
1056    operator bool() const {return __f_;}
1057
1058private:
1059    // deleted overloads close possible hole in the type system
1060    template<class _R2, class _B0, class _B1>
1061      bool operator==(const function<_R2(_B0, _B1)>&) const;// = delete;
1062    template<class _R2, class _B0, class _B1>
1063      bool operator!=(const function<_R2(_B0, _B1)>&) const;// = delete;
1064public:
1065    // 20.7.16.2.4, function invocation:
1066    _Rp operator()(_A0, _A1) const;
1067
1068#ifndef _LIBCPP_NO_RTTI
1069    // 20.7.16.2.5, function target access:
1070    const std::type_info& target_type() const;
1071    template <typename _Tp> _Tp* target();
1072    template <typename _Tp> const _Tp* target() const;
1073#endif  // _LIBCPP_NO_RTTI
1074};
1075
1076template<class _Rp, class _A0, class _A1>
1077function<_Rp(_A0, _A1)>::function(const function& __f)
1078{
1079    if (__f.__f_ == 0)
1080        __f_ = 0;
1081    else if (__f.__f_ == (const __base*)&__f.__buf_)
1082    {
1083        __f_ = (__base*)&__buf_;
1084        __f.__f_->__clone(__f_);
1085    }
1086    else
1087        __f_ = __f.__f_->__clone();
1088}
1089
1090template<class _Rp, class _A0, class _A1>
1091template<class _Alloc>
1092function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc&, const function& __f)
1093{
1094    if (__f.__f_ == 0)
1095        __f_ = 0;
1096    else if (__f.__f_ == (const __base*)&__f.__buf_)
1097    {
1098        __f_ = (__base*)&__buf_;
1099        __f.__f_->__clone(__f_);
1100    }
1101    else
1102        __f_ = __f.__f_->__clone();
1103}
1104
1105template<class _Rp, class _A0, class _A1>
1106template <class _Fp>
1107function<_Rp(_A0, _A1)>::function(_Fp __f,
1108                                 typename enable_if<!is_integral<_Fp>::value>::type*)
1109    : __f_(0)
1110{
1111    if (__function::__not_null(__f))
1112    {
1113        typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1)> _FF;
1114        if (sizeof(_FF) <= sizeof(__buf_))
1115        {
1116            __f_ = (__base*)&__buf_;
1117            ::new (__f_) _FF(__f);
1118        }
1119        else
1120        {
1121            typedef allocator<_FF> _Ap;
1122            _Ap __a;
1123            typedef __allocator_destructor<_Ap> _Dp;
1124            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1125            ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a));
1126            __f_ = __hold.release();
1127        }
1128    }
1129}
1130
1131template<class _Rp, class _A0, class _A1>
1132template <class _Fp, class _Alloc>
1133function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
1134                                 typename enable_if<!is_integral<_Fp>::value>::type*)
1135    : __f_(0)
1136{
1137    typedef allocator_traits<_Alloc> __alloc_traits;
1138    if (__function::__not_null(__f))
1139    {
1140        typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1)> _FF;
1141        if (sizeof(_FF) <= sizeof(__buf_))
1142        {
1143            __f_ = (__base*)&__buf_;
1144            ::new (__f_) _FF(__f, __a0);
1145        }
1146        else
1147        {
1148            typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
1149            _Ap __a(__a0);
1150            typedef __allocator_destructor<_Ap> _Dp;
1151            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1152            ::new (__hold.get()) _FF(__f, _Alloc(__a));
1153            __f_ = __hold.release();
1154        }
1155    }
1156}
1157
1158template<class _Rp, class _A0, class _A1>
1159function<_Rp(_A0, _A1)>&
1160function<_Rp(_A0, _A1)>::operator=(const function& __f)
1161{
1162    if (__f)
1163        function(__f).swap(*this);
1164    else
1165        *this = nullptr;
1166    return *this;
1167}
1168
1169template<class _Rp, class _A0, class _A1>
1170function<_Rp(_A0, _A1)>&
1171function<_Rp(_A0, _A1)>::operator=(nullptr_t)
1172{
1173    __base* __t = __f_;
1174    __f_ = 0;
1175    if (__t == (__base*)&__buf_)
1176        __t->destroy();
1177    else if (__t)
1178        __t->destroy_deallocate();
1179    return *this;
1180}
1181
1182template<class _Rp, class _A0, class _A1>
1183template <class _Fp>
1184typename enable_if
1185<
1186    !is_integral<_Fp>::value,
1187    function<_Rp(_A0, _A1)>&
1188>::type
1189function<_Rp(_A0, _A1)>::operator=(_Fp __f)
1190{
1191    function(_VSTD::move(__f)).swap(*this);
1192    return *this;
1193}
1194
1195template<class _Rp, class _A0, class _A1>
1196function<_Rp(_A0, _A1)>::~function()
1197{
1198    if (__f_ == (__base*)&__buf_)
1199        __f_->destroy();
1200    else if (__f_)
1201        __f_->destroy_deallocate();
1202}
1203
1204template<class _Rp, class _A0, class _A1>
1205void
1206function<_Rp(_A0, _A1)>::swap(function& __f)
1207{
1208    if (_VSTD::addressof(__f) == this)
1209      return;
1210    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1211    {
1212        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1213        __base* __t = (__base*)&__tempbuf;
1214        __f_->__clone(__t);
1215        __f_->destroy();
1216        __f_ = 0;
1217        __f.__f_->__clone((__base*)&__buf_);
1218        __f.__f_->destroy();
1219        __f.__f_ = 0;
1220        __f_ = (__base*)&__buf_;
1221        __t->__clone((__base*)&__f.__buf_);
1222        __t->destroy();
1223        __f.__f_ = (__base*)&__f.__buf_;
1224    }
1225    else if (__f_ == (__base*)&__buf_)
1226    {
1227        __f_->__clone((__base*)&__f.__buf_);
1228        __f_->destroy();
1229        __f_ = __f.__f_;
1230        __f.__f_ = (__base*)&__f.__buf_;
1231    }
1232    else if (__f.__f_ == (__base*)&__f.__buf_)
1233    {
1234        __f.__f_->__clone((__base*)&__buf_);
1235        __f.__f_->destroy();
1236        __f.__f_ = __f_;
1237        __f_ = (__base*)&__buf_;
1238    }
1239    else
1240        _VSTD::swap(__f_, __f.__f_);
1241}
1242
1243template<class _Rp, class _A0, class _A1>
1244_Rp
1245function<_Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) const
1246{
1247    if (__f_ == 0)
1248        __throw_bad_function_call();
1249    return (*__f_)(__a0, __a1);
1250}
1251
1252#ifndef _LIBCPP_NO_RTTI
1253
1254template<class _Rp, class _A0, class _A1>
1255const std::type_info&
1256function<_Rp(_A0, _A1)>::target_type() const
1257{
1258    if (__f_ == 0)
1259        return typeid(void);
1260    return __f_->target_type();
1261}
1262
1263template<class _Rp, class _A0, class _A1>
1264template <typename _Tp>
1265_Tp*
1266function<_Rp(_A0, _A1)>::target()
1267{
1268    if (__f_ == 0)
1269        return (_Tp*)0;
1270    return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
1271}
1272
1273template<class _Rp, class _A0, class _A1>
1274template <typename _Tp>
1275const _Tp*
1276function<_Rp(_A0, _A1)>::target() const
1277{
1278    if (__f_ == 0)
1279        return (const _Tp*)0;
1280    return (const _Tp*)__f_->target(typeid(_Tp));
1281}
1282
1283#endif  // _LIBCPP_NO_RTTI
1284
1285template<class _Rp, class _A0, class _A1, class _A2>
1286class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1, _A2)>
1287{
1288    typedef __function::__base<_Rp(_A0, _A1, _A2)> __base;
1289    aligned_storage<3*sizeof(void*)>::type __buf_;
1290    __base* __f_;
1291
1292public:
1293    typedef _Rp result_type;
1294
1295    // 20.7.16.2.1, construct/copy/destroy:
1296    _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
1297    _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
1298    function(const function&);
1299    template<class _Fp>
1300      function(_Fp,
1301               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
1302
1303    template<class _Alloc>
1304      _LIBCPP_INLINE_VISIBILITY
1305      function(allocator_arg_t, const _Alloc&) : __f_(0) {}
1306    template<class _Alloc>
1307      _LIBCPP_INLINE_VISIBILITY
1308      function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
1309    template<class _Alloc>
1310      function(allocator_arg_t, const _Alloc&, const function&);
1311    template<class _Fp, class _Alloc>
1312      function(allocator_arg_t, const _Alloc& __a, _Fp __f,
1313               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
1314
1315    function& operator=(const function&);
1316    function& operator=(nullptr_t);
1317    template<class _Fp>
1318      typename enable_if
1319      <
1320        !is_integral<_Fp>::value,
1321        function&
1322      >::type
1323      operator=(_Fp);
1324
1325    ~function();
1326
1327    // 20.7.16.2.2, function modifiers:
1328    void swap(function&);
1329    template<class _Fp, class _Alloc>
1330      _LIBCPP_INLINE_VISIBILITY
1331      void assign(_Fp __f, const _Alloc& __a)
1332        {function(allocator_arg, __a, __f).swap(*this);}
1333
1334    // 20.7.16.2.3, function capacity:
1335    _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}
1336
1337private:
1338    // deleted overloads close possible hole in the type system
1339    template<class _R2, class _B0, class _B1, class _B2>
1340      bool operator==(const function<_R2(_B0, _B1, _B2)>&) const;// = delete;
1341    template<class _R2, class _B0, class _B1, class _B2>
1342      bool operator!=(const function<_R2(_B0, _B1, _B2)>&) const;// = delete;
1343public:
1344    // 20.7.16.2.4, function invocation:
1345    _Rp operator()(_A0, _A1, _A2) const;
1346
1347#ifndef _LIBCPP_NO_RTTI
1348    // 20.7.16.2.5, function target access:
1349    const std::type_info& target_type() const;
1350    template <typename _Tp> _Tp* target();
1351    template <typename _Tp> const _Tp* target() const;
1352#endif  // _LIBCPP_NO_RTTI
1353};
1354
1355template<class _Rp, class _A0, class _A1, class _A2>
1356function<_Rp(_A0, _A1, _A2)>::function(const function& __f)
1357{
1358    if (__f.__f_ == 0)
1359        __f_ = 0;
1360    else if (__f.__f_ == (const __base*)&__f.__buf_)
1361    {
1362        __f_ = (__base*)&__buf_;
1363        __f.__f_->__clone(__f_);
1364    }
1365    else
1366        __f_ = __f.__f_->__clone();
1367}
1368
1369template<class _Rp, class _A0, class _A1, class _A2>
1370template<class _Alloc>
1371function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc&,
1372                                      const function& __f)
1373{
1374    if (__f.__f_ == 0)
1375        __f_ = 0;
1376    else if (__f.__f_ == (const __base*)&__f.__buf_)
1377    {
1378        __f_ = (__base*)&__buf_;
1379        __f.__f_->__clone(__f_);
1380    }
1381    else
1382        __f_ = __f.__f_->__clone();
1383}
1384
1385template<class _Rp, class _A0, class _A1, class _A2>
1386template <class _Fp>
1387function<_Rp(_A0, _A1, _A2)>::function(_Fp __f,
1388                                     typename enable_if<!is_integral<_Fp>::value>::type*)
1389    : __f_(0)
1390{
1391    if (__function::__not_null(__f))
1392    {
1393        typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1, _A2)> _FF;
1394        if (sizeof(_FF) <= sizeof(__buf_))
1395        {
1396            __f_ = (__base*)&__buf_;
1397            ::new (__f_) _FF(__f);
1398        }
1399        else
1400        {
1401            typedef allocator<_FF> _Ap;
1402            _Ap __a;
1403            typedef __allocator_destructor<_Ap> _Dp;
1404            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1405            ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a));
1406            __f_ = __hold.release();
1407        }
1408    }
1409}
1410
1411template<class _Rp, class _A0, class _A1, class _A2>
1412template <class _Fp, class _Alloc>
1413function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
1414                                     typename enable_if<!is_integral<_Fp>::value>::type*)
1415    : __f_(0)
1416{
1417    typedef allocator_traits<_Alloc> __alloc_traits;
1418    if (__function::__not_null(__f))
1419    {
1420        typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> _FF;
1421        if (sizeof(_FF) <= sizeof(__buf_))
1422        {
1423            __f_ = (__base*)&__buf_;
1424            ::new (__f_) _FF(__f, __a0);
1425        }
1426        else
1427        {
1428            typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
1429            _Ap __a(__a0);
1430            typedef __allocator_destructor<_Ap> _Dp;
1431            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1432            ::new (__hold.get()) _FF(__f, _Alloc(__a));
1433            __f_ = __hold.release();
1434        }
1435    }
1436}
1437
1438template<class _Rp, class _A0, class _A1, class _A2>
1439function<_Rp(_A0, _A1, _A2)>&
1440function<_Rp(_A0, _A1, _A2)>::operator=(const function& __f)
1441{
1442    if (__f)
1443        function(__f).swap(*this);
1444    else
1445        *this = nullptr;
1446    return *this;
1447}
1448
1449template<class _Rp, class _A0, class _A1, class _A2>
1450function<_Rp(_A0, _A1, _A2)>&
1451function<_Rp(_A0, _A1, _A2)>::operator=(nullptr_t)
1452{
1453    __base* __t = __f_;
1454    __f_ = 0;
1455    if (__t == (__base*)&__buf_)
1456        __t->destroy();
1457    else if (__t)
1458        __t->destroy_deallocate();
1459    return *this;
1460}
1461
1462template<class _Rp, class _A0, class _A1, class _A2>
1463template <class _Fp>
1464typename enable_if
1465<
1466    !is_integral<_Fp>::value,
1467    function<_Rp(_A0, _A1, _A2)>&
1468>::type
1469function<_Rp(_A0, _A1, _A2)>::operator=(_Fp __f)
1470{
1471    function(_VSTD::move(__f)).swap(*this);
1472    return *this;
1473}
1474
1475template<class _Rp, class _A0, class _A1, class _A2>
1476function<_Rp(_A0, _A1, _A2)>::~function()
1477{
1478    if (__f_ == (__base*)&__buf_)
1479        __f_->destroy();
1480    else if (__f_)
1481        __f_->destroy_deallocate();
1482}
1483
1484template<class _Rp, class _A0, class _A1, class _A2>
1485void
1486function<_Rp(_A0, _A1, _A2)>::swap(function& __f)
1487{
1488    if (_VSTD::addressof(__f) == this)
1489      return;
1490    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1491    {
1492        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1493        __base* __t = (__base*)&__tempbuf;
1494        __f_->__clone(__t);
1495        __f_->destroy();
1496        __f_ = 0;
1497        __f.__f_->__clone((__base*)&__buf_);
1498        __f.__f_->destroy();
1499        __f.__f_ = 0;
1500        __f_ = (__base*)&__buf_;
1501        __t->__clone((__base*)&__f.__buf_);
1502        __t->destroy();
1503        __f.__f_ = (__base*)&__f.__buf_;
1504    }
1505    else if (__f_ == (__base*)&__buf_)
1506    {
1507        __f_->__clone((__base*)&__f.__buf_);
1508        __f_->destroy();
1509        __f_ = __f.__f_;
1510        __f.__f_ = (__base*)&__f.__buf_;
1511    }
1512    else if (__f.__f_ == (__base*)&__f.__buf_)
1513    {
1514        __f.__f_->__clone((__base*)&__buf_);
1515        __f.__f_->destroy();
1516        __f.__f_ = __f_;
1517        __f_ = (__base*)&__buf_;
1518    }
1519    else
1520        _VSTD::swap(__f_, __f.__f_);
1521}
1522
1523template<class _Rp, class _A0, class _A1, class _A2>
1524_Rp
1525function<_Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) const
1526{
1527    if (__f_ == 0)
1528        __throw_bad_function_call();
1529    return (*__f_)(__a0, __a1, __a2);
1530}
1531
1532#ifndef _LIBCPP_NO_RTTI
1533
1534template<class _Rp, class _A0, class _A1, class _A2>
1535const std::type_info&
1536function<_Rp(_A0, _A1, _A2)>::target_type() const
1537{
1538    if (__f_ == 0)
1539        return typeid(void);
1540    return __f_->target_type();
1541}
1542
1543template<class _Rp, class _A0, class _A1, class _A2>
1544template <typename _Tp>
1545_Tp*
1546function<_Rp(_A0, _A1, _A2)>::target()
1547{
1548    if (__f_ == 0)
1549        return (_Tp*)0;
1550    return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
1551}
1552
1553template<class _Rp, class _A0, class _A1, class _A2>
1554template <typename _Tp>
1555const _Tp*
1556function<_Rp(_A0, _A1, _A2)>::target() const
1557{
1558    if (__f_ == 0)
1559        return (const _Tp*)0;
1560    return (const _Tp*)__f_->target(typeid(_Tp));
1561}
1562
1563#endif  // _LIBCPP_NO_RTTI
1564
1565template <class _Fp>
1566inline _LIBCPP_INLINE_VISIBILITY
1567bool
1568operator==(const function<_Fp>& __f, nullptr_t) {return !__f;}
1569
1570template <class _Fp>
1571inline _LIBCPP_INLINE_VISIBILITY
1572bool
1573operator==(nullptr_t, const function<_Fp>& __f) {return !__f;}
1574
1575template <class _Fp>
1576inline _LIBCPP_INLINE_VISIBILITY
1577bool
1578operator!=(const function<_Fp>& __f, nullptr_t) {return (bool)__f;}
1579
1580template <class _Fp>
1581inline _LIBCPP_INLINE_VISIBILITY
1582bool
1583operator!=(nullptr_t, const function<_Fp>& __f) {return (bool)__f;}
1584
1585template <class _Fp>
1586inline _LIBCPP_INLINE_VISIBILITY
1587void
1588swap(function<_Fp>& __x, function<_Fp>& __y)
1589{return __x.swap(__y);}
1590
1591#endif  // _LIBCPP_FUNCTIONAL_03
1592