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