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