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 20 namespace __function { 21 22 template<class _Fp> class __base; 23 24 template<class _Rp> 25 class __base<_Rp()> 26 { 27 __base(const __base&); 28 __base& operator=(const __base&); 29 public: 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 43 template<class _Rp, class _A0> 44 class __base<_Rp(_A0)> 45 { 46 __base(const __base&); 47 __base& operator=(const __base&); 48 public: 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 62 template<class _Rp, class _A0, class _A1> 63 class __base<_Rp(_A0, _A1)> 64 { 65 __base(const __base&); 66 __base& operator=(const __base&); 67 public: 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 81 template<class _Rp, class _A0, class _A1, class _A2> 82 class __base<_Rp(_A0, _A1, _A2)> 83 { 84 __base(const __base&); 85 __base& operator=(const __base&); 86 public: 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 100 template<class _FD, class _Alloc, class _FB> class __func; 101 102 template<class _Fp, class _Alloc, class _Rp> 103 class __func<_Fp, _Alloc, _Rp()> 104 : public __base<_Rp()> 105 { 106 __compressed_pair<_Fp, _Alloc> __f_; 107 public: 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 121 template<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 134 template<class _Fp, class _Alloc, class _Rp> 135 void 136 __func<_Fp, _Alloc, _Rp()>::__clone(__base<_Rp()>* __p) const 137 { 138 ::new (__p) __func(__f_.first(), __f_.second()); 139 } 140 141 template<class _Fp, class _Alloc, class _Rp> 142 void 143 __func<_Fp, _Alloc, _Rp()>::destroy() 144 { 145 __f_.~__compressed_pair<_Fp, _Alloc>(); 146 } 147 148 template<class _Fp, class _Alloc, class _Rp> 149 void 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 159 template<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 169 template<class _Fp, class _Alloc, class _Rp> 170 const 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 178 template<class _Fp, class _Alloc, class _Rp> 179 const std::type_info& 180 __func<_Fp, _Alloc, _Rp()>::target_type() const 181 { 182 return typeid(_Fp); 183 } 184 185 #endif // _LIBCPP_NO_RTTI 186 187 template<class _Fp, class _Alloc, class _Rp, class _A0> 188 class __func<_Fp, _Alloc, _Rp(_A0)> 189 : public __base<_Rp(_A0)> 190 { 191 __compressed_pair<_Fp, _Alloc> __f_; 192 public: 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 207 template<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 220 template<class _Fp, class _Alloc, class _Rp, class _A0> 221 void 222 __func<_Fp, _Alloc, _Rp(_A0)>::__clone(__base<_Rp(_A0)>* __p) const 223 { 224 ::new (__p) __func(__f_.first(), __f_.second()); 225 } 226 227 template<class _Fp, class _Alloc, class _Rp, class _A0> 228 void 229 __func<_Fp, _Alloc, _Rp(_A0)>::destroy() 230 { 231 __f_.~__compressed_pair<_Fp, _Alloc>(); 232 } 233 234 template<class _Fp, class _Alloc, class _Rp, class _A0> 235 void 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 245 template<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 255 template<class _Fp, class _Alloc, class _Rp, class _A0> 256 const 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 264 template<class _Fp, class _Alloc, class _Rp, class _A0> 265 const 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 273 template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1> 274 class __func<_Fp, _Alloc, _Rp(_A0, _A1)> 275 : public __base<_Rp(_A0, _A1)> 276 { 277 __compressed_pair<_Fp, _Alloc> __f_; 278 public: 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 293 template<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 306 template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1> 307 void 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 313 template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1> 314 void 315 __func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy() 316 { 317 __f_.~__compressed_pair<_Fp, _Alloc>(); 318 } 319 320 template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1> 321 void 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 331 template<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 341 template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1> 342 const 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 350 template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1> 351 const 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 359 template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2> 360 class __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> 361 : public __base<_Rp(_A0, _A1, _A2)> 362 { 363 __compressed_pair<_Fp, _Alloc> __f_; 364 public: 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 379 template<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 392 template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2> 393 void 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 399 template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2> 400 void 401 __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy() 402 { 403 __f_.~__compressed_pair<_Fp, _Alloc>(); 404 } 405 406 template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2> 407 void 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 417 template<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 427 template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2> 428 const 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 436 template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2> 437 const 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 447 template<class _Rp> 448 class _LIBCPP_TEMPLATE_VIS function<_Rp()> 449 { 450 typedef __function::__base<_Rp()> __base; 451 aligned_storage<3*sizeof(void*)>::type __buf_; 452 __base* __f_; 453 454 public: 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 499 private: 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; 505 public: 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 517 template<class _Rp> 518 function<_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 531 template<class _Rp> 532 template<class _Alloc> 533 function<_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 546 template<class _Rp> 547 template <class _Fp> 548 function<_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 572 template<class _Rp> 573 template <class _Fp, class _Alloc> 574 function<_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 599 template<class _Rp> 600 function<_Rp()>& 601 function<_Rp()>::operator=(const function& __f) 602 { 603 if (__f) 604 function(__f).swap(*this); 605 else 606 *this = nullptr; 607 return *this; 608 } 609 610 template<class _Rp> 611 function<_Rp()>& 612 function<_Rp()>::operator=(nullptr_t) 613 { 614 __base* __t = __f_; 615 __f_ = 0; 616 if (__t == (__base*)&__buf_) 617 __t->destroy(); 618 else if (__t) 619 __t->destroy_deallocate(); 620 return *this; 621 } 622 623 template<class _Rp> 624 template <class _Fp> 625 typename enable_if 626 < 627 !is_integral<_Fp>::value, 628 function<_Rp()>& 629 >::type 630 function<_Rp()>::operator=(_Fp __f) 631 { 632 function(_VSTD::move(__f)).swap(*this); 633 return *this; 634 } 635 636 template<class _Rp> 637 function<_Rp()>::~function() 638 { 639 if (__f_ == (__base*)&__buf_) 640 __f_->destroy(); 641 else if (__f_) 642 __f_->destroy_deallocate(); 643 } 644 645 template<class _Rp> 646 void 647 function<_Rp()>::swap(function& __f) 648 { 649 if (_VSTD::addressof(__f) == this) 650 return; 651 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) 652 { 653 typename aligned_storage<sizeof(__buf_)>::type __tempbuf; 654 __base* __t = (__base*)&__tempbuf; 655 __f_->__clone(__t); 656 __f_->destroy(); 657 __f_ = 0; 658 __f.__f_->__clone((__base*)&__buf_); 659 __f.__f_->destroy(); 660 __f.__f_ = 0; 661 __f_ = (__base*)&__buf_; 662 __t->__clone((__base*)&__f.__buf_); 663 __t->destroy(); 664 __f.__f_ = (__base*)&__f.__buf_; 665 } 666 else if (__f_ == (__base*)&__buf_) 667 { 668 __f_->__clone((__base*)&__f.__buf_); 669 __f_->destroy(); 670 __f_ = __f.__f_; 671 __f.__f_ = (__base*)&__f.__buf_; 672 } 673 else if (__f.__f_ == (__base*)&__f.__buf_) 674 { 675 __f.__f_->__clone((__base*)&__buf_); 676 __f.__f_->destroy(); 677 __f.__f_ = __f_; 678 __f_ = (__base*)&__buf_; 679 } 680 else 681 _VSTD::swap(__f_, __f.__f_); 682 } 683 684 template<class _Rp> 685 _Rp 686 function<_Rp()>::operator()() const 687 { 688 if (__f_ == 0) 689 __throw_bad_function_call(); 690 return (*__f_)(); 691 } 692 693 #ifndef _LIBCPP_NO_RTTI 694 695 template<class _Rp> 696 const std::type_info& 697 function<_Rp()>::target_type() const 698 { 699 if (__f_ == 0) 700 return typeid(void); 701 return __f_->target_type(); 702 } 703 704 template<class _Rp> 705 template <typename _Tp> 706 _Tp* 707 function<_Rp()>::target() 708 { 709 if (__f_ == 0) 710 return (_Tp*)0; 711 return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp))); 712 } 713 714 template<class _Rp> 715 template <typename _Tp> 716 const _Tp* 717 function<_Rp()>::target() const 718 { 719 if (__f_ == 0) 720 return (const _Tp*)0; 721 return (const _Tp*)__f_->target(typeid(_Tp)); 722 } 723 724 #endif // _LIBCPP_NO_RTTI 725 726 template<class _Rp, class _A0> 727 class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0)> 728 : public unary_function<_A0, _Rp> 729 { 730 typedef __function::__base<_Rp(_A0)> __base; 731 aligned_storage<3*sizeof(void*)>::type __buf_; 732 __base* __f_; 733 734 public: 735 typedef _Rp result_type; 736 737 // 20.7.16.2.1, construct/copy/destroy: 738 _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} 739 _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} 740 function(const function&); 741 template<class _Fp> 742 function(_Fp, 743 typename enable_if<!is_integral<_Fp>::value>::type* = 0); 744 745 template<class _Alloc> 746 _LIBCPP_INLINE_VISIBILITY 747 function(allocator_arg_t, const _Alloc&) : __f_(0) {} 748 template<class _Alloc> 749 _LIBCPP_INLINE_VISIBILITY 750 function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} 751 template<class _Alloc> 752 function(allocator_arg_t, const _Alloc&, const function&); 753 template<class _Fp, class _Alloc> 754 function(allocator_arg_t, const _Alloc& __a, _Fp __f, 755 typename enable_if<!is_integral<_Fp>::value>::type* = 0); 756 757 function& operator=(const function&); 758 function& operator=(nullptr_t); 759 template<class _Fp> 760 typename enable_if 761 < 762 !is_integral<_Fp>::value, 763 function& 764 >::type 765 operator=(_Fp); 766 767 ~function(); 768 769 // 20.7.16.2.2, function modifiers: 770 void swap(function&); 771 template<class _Fp, class _Alloc> 772 _LIBCPP_INLINE_VISIBILITY 773 void assign(_Fp __f, const _Alloc& __a) 774 {function(allocator_arg, __a, __f).swap(*this);} 775 776 // 20.7.16.2.3, function capacity: 777 _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;} 778 779 private: 780 // deleted overloads close possible hole in the type system 781 template<class _R2, class _B0> 782 bool operator==(const function<_R2(_B0)>&) const;// = delete; 783 template<class _R2, class _B0> 784 bool operator!=(const function<_R2(_B0)>&) const;// = delete; 785 public: 786 // 20.7.16.2.4, function invocation: 787 _Rp operator()(_A0) const; 788 789 #ifndef _LIBCPP_NO_RTTI 790 // 20.7.16.2.5, function target access: 791 const std::type_info& target_type() const; 792 template <typename _Tp> _Tp* target(); 793 template <typename _Tp> const _Tp* target() const; 794 #endif // _LIBCPP_NO_RTTI 795 }; 796 797 template<class _Rp, class _A0> 798 function<_Rp(_A0)>::function(const function& __f) 799 { 800 if (__f.__f_ == 0) 801 __f_ = 0; 802 else if (__f.__f_ == (const __base*)&__f.__buf_) 803 { 804 __f_ = (__base*)&__buf_; 805 __f.__f_->__clone(__f_); 806 } 807 else 808 __f_ = __f.__f_->__clone(); 809 } 810 811 template<class _Rp, class _A0> 812 template<class _Alloc> 813 function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc&, const function& __f) 814 { 815 if (__f.__f_ == 0) 816 __f_ = 0; 817 else if (__f.__f_ == (const __base*)&__f.__buf_) 818 { 819 __f_ = (__base*)&__buf_; 820 __f.__f_->__clone(__f_); 821 } 822 else 823 __f_ = __f.__f_->__clone(); 824 } 825 826 template<class _Rp, class _A0> 827 template <class _Fp> 828 function<_Rp(_A0)>::function(_Fp __f, 829 typename enable_if<!is_integral<_Fp>::value>::type*) 830 : __f_(0) 831 { 832 if (__function::__not_null(__f)) 833 { 834 typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0)> _FF; 835 if (sizeof(_FF) <= sizeof(__buf_)) 836 { 837 __f_ = (__base*)&__buf_; 838 ::new (__f_) _FF(__f); 839 } 840 else 841 { 842 typedef allocator<_FF> _Ap; 843 _Ap __a; 844 typedef __allocator_destructor<_Ap> _Dp; 845 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 846 ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a)); 847 __f_ = __hold.release(); 848 } 849 } 850 } 851 852 template<class _Rp, class _A0> 853 template <class _Fp, class _Alloc> 854 function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, 855 typename enable_if<!is_integral<_Fp>::value>::type*) 856 : __f_(0) 857 { 858 typedef allocator_traits<_Alloc> __alloc_traits; 859 if (__function::__not_null(__f)) 860 { 861 typedef __function::__func<_Fp, _Alloc, _Rp(_A0)> _FF; 862 if (sizeof(_FF) <= sizeof(__buf_)) 863 { 864 __f_ = (__base*)&__buf_; 865 ::new (__f_) _FF(__f, __a0); 866 } 867 else 868 { 869 typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; 870 _Ap __a(__a0); 871 typedef __allocator_destructor<_Ap> _Dp; 872 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 873 ::new (__hold.get()) _FF(__f, _Alloc(__a)); 874 __f_ = __hold.release(); 875 } 876 } 877 } 878 879 template<class _Rp, class _A0> 880 function<_Rp(_A0)>& 881 function<_Rp(_A0)>::operator=(const function& __f) 882 { 883 if (__f) 884 function(__f).swap(*this); 885 else 886 *this = nullptr; 887 return *this; 888 } 889 890 template<class _Rp, class _A0> 891 function<_Rp(_A0)>& 892 function<_Rp(_A0)>::operator=(nullptr_t) 893 { 894 __base* __t = __f_; 895 __f_ = 0; 896 if (__t == (__base*)&__buf_) 897 __t->destroy(); 898 else if (__t) 899 __t->destroy_deallocate(); 900 return *this; 901 } 902 903 template<class _Rp, class _A0> 904 template <class _Fp> 905 typename enable_if 906 < 907 !is_integral<_Fp>::value, 908 function<_Rp(_A0)>& 909 >::type 910 function<_Rp(_A0)>::operator=(_Fp __f) 911 { 912 function(_VSTD::move(__f)).swap(*this); 913 return *this; 914 } 915 916 template<class _Rp, class _A0> 917 function<_Rp(_A0)>::~function() 918 { 919 if (__f_ == (__base*)&__buf_) 920 __f_->destroy(); 921 else if (__f_) 922 __f_->destroy_deallocate(); 923 } 924 925 template<class _Rp, class _A0> 926 void 927 function<_Rp(_A0)>::swap(function& __f) 928 { 929 if (_VSTD::addressof(__f) == this) 930 return; 931 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) 932 { 933 typename aligned_storage<sizeof(__buf_)>::type __tempbuf; 934 __base* __t = (__base*)&__tempbuf; 935 __f_->__clone(__t); 936 __f_->destroy(); 937 __f_ = 0; 938 __f.__f_->__clone((__base*)&__buf_); 939 __f.__f_->destroy(); 940 __f.__f_ = 0; 941 __f_ = (__base*)&__buf_; 942 __t->__clone((__base*)&__f.__buf_); 943 __t->destroy(); 944 __f.__f_ = (__base*)&__f.__buf_; 945 } 946 else if (__f_ == (__base*)&__buf_) 947 { 948 __f_->__clone((__base*)&__f.__buf_); 949 __f_->destroy(); 950 __f_ = __f.__f_; 951 __f.__f_ = (__base*)&__f.__buf_; 952 } 953 else if (__f.__f_ == (__base*)&__f.__buf_) 954 { 955 __f.__f_->__clone((__base*)&__buf_); 956 __f.__f_->destroy(); 957 __f.__f_ = __f_; 958 __f_ = (__base*)&__buf_; 959 } 960 else 961 _VSTD::swap(__f_, __f.__f_); 962 } 963 964 template<class _Rp, class _A0> 965 _Rp 966 function<_Rp(_A0)>::operator()(_A0 __a0) const 967 { 968 if (__f_ == 0) 969 __throw_bad_function_call(); 970 return (*__f_)(__a0); 971 } 972 973 #ifndef _LIBCPP_NO_RTTI 974 975 template<class _Rp, class _A0> 976 const std::type_info& 977 function<_Rp(_A0)>::target_type() const 978 { 979 if (__f_ == 0) 980 return typeid(void); 981 return __f_->target_type(); 982 } 983 984 template<class _Rp, class _A0> 985 template <typename _Tp> 986 _Tp* 987 function<_Rp(_A0)>::target() 988 { 989 if (__f_ == 0) 990 return (_Tp*)0; 991 return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp))); 992 } 993 994 template<class _Rp, class _A0> 995 template <typename _Tp> 996 const _Tp* 997 function<_Rp(_A0)>::target() const 998 { 999 if (__f_ == 0) 1000 return (const _Tp*)0; 1001 return (const _Tp*)__f_->target(typeid(_Tp)); 1002 } 1003 1004 #endif // _LIBCPP_NO_RTTI 1005 1006 template<class _Rp, class _A0, class _A1> 1007 class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1)> 1008 : public binary_function<_A0, _A1, _Rp> 1009 { 1010 typedef __function::__base<_Rp(_A0, _A1)> __base; 1011 aligned_storage<3*sizeof(void*)>::type __buf_; 1012 __base* __f_; 1013 1014 public: 1015 typedef _Rp result_type; 1016 1017 // 20.7.16.2.1, construct/copy/destroy: 1018 _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} 1019 _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} 1020 function(const function&); 1021 template<class _Fp> 1022 function(_Fp, 1023 typename enable_if<!is_integral<_Fp>::value>::type* = 0); 1024 1025 template<class _Alloc> 1026 _LIBCPP_INLINE_VISIBILITY 1027 function(allocator_arg_t, const _Alloc&) : __f_(0) {} 1028 template<class _Alloc> 1029 _LIBCPP_INLINE_VISIBILITY 1030 function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} 1031 template<class _Alloc> 1032 function(allocator_arg_t, const _Alloc&, const function&); 1033 template<class _Fp, class _Alloc> 1034 function(allocator_arg_t, const _Alloc& __a, _Fp __f, 1035 typename enable_if<!is_integral<_Fp>::value>::type* = 0); 1036 1037 function& operator=(const function&); 1038 function& operator=(nullptr_t); 1039 template<class _Fp> 1040 typename enable_if 1041 < 1042 !is_integral<_Fp>::value, 1043 function& 1044 >::type 1045 operator=(_Fp); 1046 1047 ~function(); 1048 1049 // 20.7.16.2.2, function modifiers: 1050 void swap(function&); 1051 template<class _Fp, class _Alloc> 1052 _LIBCPP_INLINE_VISIBILITY 1053 void assign(_Fp __f, const _Alloc& __a) 1054 {function(allocator_arg, __a, __f).swap(*this);} 1055 1056 // 20.7.16.2.3, function capacity: 1057 operator bool() const {return __f_;} 1058 1059 private: 1060 // deleted overloads close possible hole in the type system 1061 template<class _R2, class _B0, class _B1> 1062 bool operator==(const function<_R2(_B0, _B1)>&) const;// = delete; 1063 template<class _R2, class _B0, class _B1> 1064 bool operator!=(const function<_R2(_B0, _B1)>&) const;// = delete; 1065 public: 1066 // 20.7.16.2.4, function invocation: 1067 _Rp operator()(_A0, _A1) const; 1068 1069 #ifndef _LIBCPP_NO_RTTI 1070 // 20.7.16.2.5, function target access: 1071 const std::type_info& target_type() const; 1072 template <typename _Tp> _Tp* target(); 1073 template <typename _Tp> const _Tp* target() const; 1074 #endif // _LIBCPP_NO_RTTI 1075 }; 1076 1077 template<class _Rp, class _A0, class _A1> 1078 function<_Rp(_A0, _A1)>::function(const function& __f) 1079 { 1080 if (__f.__f_ == 0) 1081 __f_ = 0; 1082 else if (__f.__f_ == (const __base*)&__f.__buf_) 1083 { 1084 __f_ = (__base*)&__buf_; 1085 __f.__f_->__clone(__f_); 1086 } 1087 else 1088 __f_ = __f.__f_->__clone(); 1089 } 1090 1091 template<class _Rp, class _A0, class _A1> 1092 template<class _Alloc> 1093 function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc&, const function& __f) 1094 { 1095 if (__f.__f_ == 0) 1096 __f_ = 0; 1097 else if (__f.__f_ == (const __base*)&__f.__buf_) 1098 { 1099 __f_ = (__base*)&__buf_; 1100 __f.__f_->__clone(__f_); 1101 } 1102 else 1103 __f_ = __f.__f_->__clone(); 1104 } 1105 1106 template<class _Rp, class _A0, class _A1> 1107 template <class _Fp> 1108 function<_Rp(_A0, _A1)>::function(_Fp __f, 1109 typename enable_if<!is_integral<_Fp>::value>::type*) 1110 : __f_(0) 1111 { 1112 if (__function::__not_null(__f)) 1113 { 1114 typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1)> _FF; 1115 if (sizeof(_FF) <= sizeof(__buf_)) 1116 { 1117 __f_ = (__base*)&__buf_; 1118 ::new (__f_) _FF(__f); 1119 } 1120 else 1121 { 1122 typedef allocator<_FF> _Ap; 1123 _Ap __a; 1124 typedef __allocator_destructor<_Ap> _Dp; 1125 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 1126 ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a)); 1127 __f_ = __hold.release(); 1128 } 1129 } 1130 } 1131 1132 template<class _Rp, class _A0, class _A1> 1133 template <class _Fp, class _Alloc> 1134 function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, 1135 typename enable_if<!is_integral<_Fp>::value>::type*) 1136 : __f_(0) 1137 { 1138 typedef allocator_traits<_Alloc> __alloc_traits; 1139 if (__function::__not_null(__f)) 1140 { 1141 typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1)> _FF; 1142 if (sizeof(_FF) <= sizeof(__buf_)) 1143 { 1144 __f_ = (__base*)&__buf_; 1145 ::new (__f_) _FF(__f, __a0); 1146 } 1147 else 1148 { 1149 typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; 1150 _Ap __a(__a0); 1151 typedef __allocator_destructor<_Ap> _Dp; 1152 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 1153 ::new (__hold.get()) _FF(__f, _Alloc(__a)); 1154 __f_ = __hold.release(); 1155 } 1156 } 1157 } 1158 1159 template<class _Rp, class _A0, class _A1> 1160 function<_Rp(_A0, _A1)>& 1161 function<_Rp(_A0, _A1)>::operator=(const function& __f) 1162 { 1163 if (__f) 1164 function(__f).swap(*this); 1165 else 1166 *this = nullptr; 1167 return *this; 1168 } 1169 1170 template<class _Rp, class _A0, class _A1> 1171 function<_Rp(_A0, _A1)>& 1172 function<_Rp(_A0, _A1)>::operator=(nullptr_t) 1173 { 1174 __base* __t = __f_; 1175 __f_ = 0; 1176 if (__t == (__base*)&__buf_) 1177 __t->destroy(); 1178 else if (__t) 1179 __t->destroy_deallocate(); 1180 return *this; 1181 } 1182 1183 template<class _Rp, class _A0, class _A1> 1184 template <class _Fp> 1185 typename enable_if 1186 < 1187 !is_integral<_Fp>::value, 1188 function<_Rp(_A0, _A1)>& 1189 >::type 1190 function<_Rp(_A0, _A1)>::operator=(_Fp __f) 1191 { 1192 function(_VSTD::move(__f)).swap(*this); 1193 return *this; 1194 } 1195 1196 template<class _Rp, class _A0, class _A1> 1197 function<_Rp(_A0, _A1)>::~function() 1198 { 1199 if (__f_ == (__base*)&__buf_) 1200 __f_->destroy(); 1201 else if (__f_) 1202 __f_->destroy_deallocate(); 1203 } 1204 1205 template<class _Rp, class _A0, class _A1> 1206 void 1207 function<_Rp(_A0, _A1)>::swap(function& __f) 1208 { 1209 if (_VSTD::addressof(__f) == this) 1210 return; 1211 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) 1212 { 1213 typename aligned_storage<sizeof(__buf_)>::type __tempbuf; 1214 __base* __t = (__base*)&__tempbuf; 1215 __f_->__clone(__t); 1216 __f_->destroy(); 1217 __f_ = 0; 1218 __f.__f_->__clone((__base*)&__buf_); 1219 __f.__f_->destroy(); 1220 __f.__f_ = 0; 1221 __f_ = (__base*)&__buf_; 1222 __t->__clone((__base*)&__f.__buf_); 1223 __t->destroy(); 1224 __f.__f_ = (__base*)&__f.__buf_; 1225 } 1226 else if (__f_ == (__base*)&__buf_) 1227 { 1228 __f_->__clone((__base*)&__f.__buf_); 1229 __f_->destroy(); 1230 __f_ = __f.__f_; 1231 __f.__f_ = (__base*)&__f.__buf_; 1232 } 1233 else if (__f.__f_ == (__base*)&__f.__buf_) 1234 { 1235 __f.__f_->__clone((__base*)&__buf_); 1236 __f.__f_->destroy(); 1237 __f.__f_ = __f_; 1238 __f_ = (__base*)&__buf_; 1239 } 1240 else 1241 _VSTD::swap(__f_, __f.__f_); 1242 } 1243 1244 template<class _Rp, class _A0, class _A1> 1245 _Rp 1246 function<_Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) const 1247 { 1248 if (__f_ == 0) 1249 __throw_bad_function_call(); 1250 return (*__f_)(__a0, __a1); 1251 } 1252 1253 #ifndef _LIBCPP_NO_RTTI 1254 1255 template<class _Rp, class _A0, class _A1> 1256 const std::type_info& 1257 function<_Rp(_A0, _A1)>::target_type() const 1258 { 1259 if (__f_ == 0) 1260 return typeid(void); 1261 return __f_->target_type(); 1262 } 1263 1264 template<class _Rp, class _A0, class _A1> 1265 template <typename _Tp> 1266 _Tp* 1267 function<_Rp(_A0, _A1)>::target() 1268 { 1269 if (__f_ == 0) 1270 return (_Tp*)0; 1271 return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp))); 1272 } 1273 1274 template<class _Rp, class _A0, class _A1> 1275 template <typename _Tp> 1276 const _Tp* 1277 function<_Rp(_A0, _A1)>::target() const 1278 { 1279 if (__f_ == 0) 1280 return (const _Tp*)0; 1281 return (const _Tp*)__f_->target(typeid(_Tp)); 1282 } 1283 1284 #endif // _LIBCPP_NO_RTTI 1285 1286 template<class _Rp, class _A0, class _A1, class _A2> 1287 class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1, _A2)> 1288 { 1289 typedef __function::__base<_Rp(_A0, _A1, _A2)> __base; 1290 aligned_storage<3*sizeof(void*)>::type __buf_; 1291 __base* __f_; 1292 1293 public: 1294 typedef _Rp result_type; 1295 1296 // 20.7.16.2.1, construct/copy/destroy: 1297 _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} 1298 _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} 1299 function(const function&); 1300 template<class _Fp> 1301 function(_Fp, 1302 typename enable_if<!is_integral<_Fp>::value>::type* = 0); 1303 1304 template<class _Alloc> 1305 _LIBCPP_INLINE_VISIBILITY 1306 function(allocator_arg_t, const _Alloc&) : __f_(0) {} 1307 template<class _Alloc> 1308 _LIBCPP_INLINE_VISIBILITY 1309 function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} 1310 template<class _Alloc> 1311 function(allocator_arg_t, const _Alloc&, const function&); 1312 template<class _Fp, class _Alloc> 1313 function(allocator_arg_t, const _Alloc& __a, _Fp __f, 1314 typename enable_if<!is_integral<_Fp>::value>::type* = 0); 1315 1316 function& operator=(const function&); 1317 function& operator=(nullptr_t); 1318 template<class _Fp> 1319 typename enable_if 1320 < 1321 !is_integral<_Fp>::value, 1322 function& 1323 >::type 1324 operator=(_Fp); 1325 1326 ~function(); 1327 1328 // 20.7.16.2.2, function modifiers: 1329 void swap(function&); 1330 template<class _Fp, class _Alloc> 1331 _LIBCPP_INLINE_VISIBILITY 1332 void assign(_Fp __f, const _Alloc& __a) 1333 {function(allocator_arg, __a, __f).swap(*this);} 1334 1335 // 20.7.16.2.3, function capacity: 1336 _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;} 1337 1338 private: 1339 // deleted overloads close possible hole in the type system 1340 template<class _R2, class _B0, class _B1, class _B2> 1341 bool operator==(const function<_R2(_B0, _B1, _B2)>&) const;// = delete; 1342 template<class _R2, class _B0, class _B1, class _B2> 1343 bool operator!=(const function<_R2(_B0, _B1, _B2)>&) const;// = delete; 1344 public: 1345 // 20.7.16.2.4, function invocation: 1346 _Rp operator()(_A0, _A1, _A2) const; 1347 1348 #ifndef _LIBCPP_NO_RTTI 1349 // 20.7.16.2.5, function target access: 1350 const std::type_info& target_type() const; 1351 template <typename _Tp> _Tp* target(); 1352 template <typename _Tp> const _Tp* target() const; 1353 #endif // _LIBCPP_NO_RTTI 1354 }; 1355 1356 template<class _Rp, class _A0, class _A1, class _A2> 1357 function<_Rp(_A0, _A1, _A2)>::function(const function& __f) 1358 { 1359 if (__f.__f_ == 0) 1360 __f_ = 0; 1361 else if (__f.__f_ == (const __base*)&__f.__buf_) 1362 { 1363 __f_ = (__base*)&__buf_; 1364 __f.__f_->__clone(__f_); 1365 } 1366 else 1367 __f_ = __f.__f_->__clone(); 1368 } 1369 1370 template<class _Rp, class _A0, class _A1, class _A2> 1371 template<class _Alloc> 1372 function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc&, 1373 const function& __f) 1374 { 1375 if (__f.__f_ == 0) 1376 __f_ = 0; 1377 else if (__f.__f_ == (const __base*)&__f.__buf_) 1378 { 1379 __f_ = (__base*)&__buf_; 1380 __f.__f_->__clone(__f_); 1381 } 1382 else 1383 __f_ = __f.__f_->__clone(); 1384 } 1385 1386 template<class _Rp, class _A0, class _A1, class _A2> 1387 template <class _Fp> 1388 function<_Rp(_A0, _A1, _A2)>::function(_Fp __f, 1389 typename enable_if<!is_integral<_Fp>::value>::type*) 1390 : __f_(0) 1391 { 1392 if (__function::__not_null(__f)) 1393 { 1394 typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1, _A2)> _FF; 1395 if (sizeof(_FF) <= sizeof(__buf_)) 1396 { 1397 __f_ = (__base*)&__buf_; 1398 ::new (__f_) _FF(__f); 1399 } 1400 else 1401 { 1402 typedef allocator<_FF> _Ap; 1403 _Ap __a; 1404 typedef __allocator_destructor<_Ap> _Dp; 1405 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 1406 ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a)); 1407 __f_ = __hold.release(); 1408 } 1409 } 1410 } 1411 1412 template<class _Rp, class _A0, class _A1, class _A2> 1413 template <class _Fp, class _Alloc> 1414 function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, 1415 typename enable_if<!is_integral<_Fp>::value>::type*) 1416 : __f_(0) 1417 { 1418 typedef allocator_traits<_Alloc> __alloc_traits; 1419 if (__function::__not_null(__f)) 1420 { 1421 typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> _FF; 1422 if (sizeof(_FF) <= sizeof(__buf_)) 1423 { 1424 __f_ = (__base*)&__buf_; 1425 ::new (__f_) _FF(__f, __a0); 1426 } 1427 else 1428 { 1429 typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; 1430 _Ap __a(__a0); 1431 typedef __allocator_destructor<_Ap> _Dp; 1432 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 1433 ::new (__hold.get()) _FF(__f, _Alloc(__a)); 1434 __f_ = __hold.release(); 1435 } 1436 } 1437 } 1438 1439 template<class _Rp, class _A0, class _A1, class _A2> 1440 function<_Rp(_A0, _A1, _A2)>& 1441 function<_Rp(_A0, _A1, _A2)>::operator=(const function& __f) 1442 { 1443 if (__f) 1444 function(__f).swap(*this); 1445 else 1446 *this = nullptr; 1447 return *this; 1448 } 1449 1450 template<class _Rp, class _A0, class _A1, class _A2> 1451 function<_Rp(_A0, _A1, _A2)>& 1452 function<_Rp(_A0, _A1, _A2)>::operator=(nullptr_t) 1453 { 1454 __base* __t = __f_; 1455 __f_ = 0; 1456 if (__t == (__base*)&__buf_) 1457 __t->destroy(); 1458 else if (__t) 1459 __t->destroy_deallocate(); 1460 return *this; 1461 } 1462 1463 template<class _Rp, class _A0, class _A1, class _A2> 1464 template <class _Fp> 1465 typename enable_if 1466 < 1467 !is_integral<_Fp>::value, 1468 function<_Rp(_A0, _A1, _A2)>& 1469 >::type 1470 function<_Rp(_A0, _A1, _A2)>::operator=(_Fp __f) 1471 { 1472 function(_VSTD::move(__f)).swap(*this); 1473 return *this; 1474 } 1475 1476 template<class _Rp, class _A0, class _A1, class _A2> 1477 function<_Rp(_A0, _A1, _A2)>::~function() 1478 { 1479 if (__f_ == (__base*)&__buf_) 1480 __f_->destroy(); 1481 else if (__f_) 1482 __f_->destroy_deallocate(); 1483 } 1484 1485 template<class _Rp, class _A0, class _A1, class _A2> 1486 void 1487 function<_Rp(_A0, _A1, _A2)>::swap(function& __f) 1488 { 1489 if (_VSTD::addressof(__f) == this) 1490 return; 1491 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) 1492 { 1493 typename aligned_storage<sizeof(__buf_)>::type __tempbuf; 1494 __base* __t = (__base*)&__tempbuf; 1495 __f_->__clone(__t); 1496 __f_->destroy(); 1497 __f_ = 0; 1498 __f.__f_->__clone((__base*)&__buf_); 1499 __f.__f_->destroy(); 1500 __f.__f_ = 0; 1501 __f_ = (__base*)&__buf_; 1502 __t->__clone((__base*)&__f.__buf_); 1503 __t->destroy(); 1504 __f.__f_ = (__base*)&__f.__buf_; 1505 } 1506 else if (__f_ == (__base*)&__buf_) 1507 { 1508 __f_->__clone((__base*)&__f.__buf_); 1509 __f_->destroy(); 1510 __f_ = __f.__f_; 1511 __f.__f_ = (__base*)&__f.__buf_; 1512 } 1513 else if (__f.__f_ == (__base*)&__f.__buf_) 1514 { 1515 __f.__f_->__clone((__base*)&__buf_); 1516 __f.__f_->destroy(); 1517 __f.__f_ = __f_; 1518 __f_ = (__base*)&__buf_; 1519 } 1520 else 1521 _VSTD::swap(__f_, __f.__f_); 1522 } 1523 1524 template<class _Rp, class _A0, class _A1, class _A2> 1525 _Rp 1526 function<_Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) const 1527 { 1528 if (__f_ == 0) 1529 __throw_bad_function_call(); 1530 return (*__f_)(__a0, __a1, __a2); 1531 } 1532 1533 #ifndef _LIBCPP_NO_RTTI 1534 1535 template<class _Rp, class _A0, class _A1, class _A2> 1536 const std::type_info& 1537 function<_Rp(_A0, _A1, _A2)>::target_type() const 1538 { 1539 if (__f_ == 0) 1540 return typeid(void); 1541 return __f_->target_type(); 1542 } 1543 1544 template<class _Rp, class _A0, class _A1, class _A2> 1545 template <typename _Tp> 1546 _Tp* 1547 function<_Rp(_A0, _A1, _A2)>::target() 1548 { 1549 if (__f_ == 0) 1550 return (_Tp*)0; 1551 return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp))); 1552 } 1553 1554 template<class _Rp, class _A0, class _A1, class _A2> 1555 template <typename _Tp> 1556 const _Tp* 1557 function<_Rp(_A0, _A1, _A2)>::target() const 1558 { 1559 if (__f_ == 0) 1560 return (const _Tp*)0; 1561 return (const _Tp*)__f_->target(typeid(_Tp)); 1562 } 1563 1564 #endif // _LIBCPP_NO_RTTI 1565 1566 template <class _Fp> 1567 inline _LIBCPP_INLINE_VISIBILITY 1568 bool 1569 operator==(const function<_Fp>& __f, nullptr_t) {return !__f;} 1570 1571 template <class _Fp> 1572 inline _LIBCPP_INLINE_VISIBILITY 1573 bool 1574 operator==(nullptr_t, const function<_Fp>& __f) {return !__f;} 1575 1576 template <class _Fp> 1577 inline _LIBCPP_INLINE_VISIBILITY 1578 bool 1579 operator!=(const function<_Fp>& __f, nullptr_t) {return (bool)__f;} 1580 1581 template <class _Fp> 1582 inline _LIBCPP_INLINE_VISIBILITY 1583 bool 1584 operator!=(nullptr_t, const function<_Fp>& __f) {return (bool)__f;} 1585 1586 template <class _Fp> 1587 inline _LIBCPP_INLINE_VISIBILITY 1588 void 1589 swap(function<_Fp>& __x, function<_Fp>& __y) 1590 {return __x.swap(__y);} 1591 1592 #endif // _LIBCPP_FUNCTIONAL_03 1593