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 function(__f).swap(*this); 604 return *this; 605 } 606 607 template<class _Rp> 608 function<_Rp()>& 609 function<_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 619 template<class _Rp> 620 template <class _Fp> 621 typename enable_if 622 < 623 !is_integral<_Fp>::value, 624 function<_Rp()>& 625 >::type 626 function<_Rp()>::operator=(_Fp __f) 627 { 628 function(_VSTD::move(__f)).swap(*this); 629 return *this; 630 } 631 632 template<class _Rp> 633 function<_Rp()>::~function() 634 { 635 if (__f_ == (__base*)&__buf_) 636 __f_->destroy(); 637 else if (__f_) 638 __f_->destroy_deallocate(); 639 } 640 641 template<class _Rp> 642 void 643 function<_Rp()>::swap(function& __f) 644 { 645 if (_VSTD::addressof(__f) == this) 646 return; 647 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) 648 { 649 typename aligned_storage<sizeof(__buf_)>::type __tempbuf; 650 __base* __t = (__base*)&__tempbuf; 651 __f_->__clone(__t); 652 __f_->destroy(); 653 __f_ = 0; 654 __f.__f_->__clone((__base*)&__buf_); 655 __f.__f_->destroy(); 656 __f.__f_ = 0; 657 __f_ = (__base*)&__buf_; 658 __t->__clone((__base*)&__f.__buf_); 659 __t->destroy(); 660 __f.__f_ = (__base*)&__f.__buf_; 661 } 662 else if (__f_ == (__base*)&__buf_) 663 { 664 __f_->__clone((__base*)&__f.__buf_); 665 __f_->destroy(); 666 __f_ = __f.__f_; 667 __f.__f_ = (__base*)&__f.__buf_; 668 } 669 else if (__f.__f_ == (__base*)&__f.__buf_) 670 { 671 __f.__f_->__clone((__base*)&__buf_); 672 __f.__f_->destroy(); 673 __f.__f_ = __f_; 674 __f_ = (__base*)&__buf_; 675 } 676 else 677 _VSTD::swap(__f_, __f.__f_); 678 } 679 680 template<class _Rp> 681 _Rp 682 function<_Rp()>::operator()() const 683 { 684 if (__f_ == 0) 685 __throw_bad_function_call(); 686 return (*__f_)(); 687 } 688 689 #ifndef _LIBCPP_NO_RTTI 690 691 template<class _Rp> 692 const std::type_info& 693 function<_Rp()>::target_type() const 694 { 695 if (__f_ == 0) 696 return typeid(void); 697 return __f_->target_type(); 698 } 699 700 template<class _Rp> 701 template <typename _Tp> 702 _Tp* 703 function<_Rp()>::target() 704 { 705 if (__f_ == 0) 706 return (_Tp*)0; 707 return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp))); 708 } 709 710 template<class _Rp> 711 template <typename _Tp> 712 const _Tp* 713 function<_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 722 template<class _Rp, class _A0> 723 class _LIBCPP_TEMPLATE_VIS 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 730 public: 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 775 private: 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; 781 public: 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 793 template<class _Rp, class _A0> 794 function<_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 807 template<class _Rp, class _A0> 808 template<class _Alloc> 809 function<_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 822 template<class _Rp, class _A0> 823 template <class _Fp> 824 function<_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 848 template<class _Rp, class _A0> 849 template <class _Fp, class _Alloc> 850 function<_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 875 template<class _Rp, class _A0> 876 function<_Rp(_A0)>& 877 function<_Rp(_A0)>::operator=(const function& __f) 878 { 879 function(__f).swap(*this); 880 return *this; 881 } 882 883 template<class _Rp, class _A0> 884 function<_Rp(_A0)>& 885 function<_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 895 template<class _Rp, class _A0> 896 template <class _Fp> 897 typename enable_if 898 < 899 !is_integral<_Fp>::value, 900 function<_Rp(_A0)>& 901 >::type 902 function<_Rp(_A0)>::operator=(_Fp __f) 903 { 904 function(_VSTD::move(__f)).swap(*this); 905 return *this; 906 } 907 908 template<class _Rp, class _A0> 909 function<_Rp(_A0)>::~function() 910 { 911 if (__f_ == (__base*)&__buf_) 912 __f_->destroy(); 913 else if (__f_) 914 __f_->destroy_deallocate(); 915 } 916 917 template<class _Rp, class _A0> 918 void 919 function<_Rp(_A0)>::swap(function& __f) 920 { 921 if (_VSTD::addressof(__f) == this) 922 return; 923 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) 924 { 925 typename aligned_storage<sizeof(__buf_)>::type __tempbuf; 926 __base* __t = (__base*)&__tempbuf; 927 __f_->__clone(__t); 928 __f_->destroy(); 929 __f_ = 0; 930 __f.__f_->__clone((__base*)&__buf_); 931 __f.__f_->destroy(); 932 __f.__f_ = 0; 933 __f_ = (__base*)&__buf_; 934 __t->__clone((__base*)&__f.__buf_); 935 __t->destroy(); 936 __f.__f_ = (__base*)&__f.__buf_; 937 } 938 else if (__f_ == (__base*)&__buf_) 939 { 940 __f_->__clone((__base*)&__f.__buf_); 941 __f_->destroy(); 942 __f_ = __f.__f_; 943 __f.__f_ = (__base*)&__f.__buf_; 944 } 945 else if (__f.__f_ == (__base*)&__f.__buf_) 946 { 947 __f.__f_->__clone((__base*)&__buf_); 948 __f.__f_->destroy(); 949 __f.__f_ = __f_; 950 __f_ = (__base*)&__buf_; 951 } 952 else 953 _VSTD::swap(__f_, __f.__f_); 954 } 955 956 template<class _Rp, class _A0> 957 _Rp 958 function<_Rp(_A0)>::operator()(_A0 __a0) const 959 { 960 if (__f_ == 0) 961 __throw_bad_function_call(); 962 return (*__f_)(__a0); 963 } 964 965 #ifndef _LIBCPP_NO_RTTI 966 967 template<class _Rp, class _A0> 968 const std::type_info& 969 function<_Rp(_A0)>::target_type() const 970 { 971 if (__f_ == 0) 972 return typeid(void); 973 return __f_->target_type(); 974 } 975 976 template<class _Rp, class _A0> 977 template <typename _Tp> 978 _Tp* 979 function<_Rp(_A0)>::target() 980 { 981 if (__f_ == 0) 982 return (_Tp*)0; 983 return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp))); 984 } 985 986 template<class _Rp, class _A0> 987 template <typename _Tp> 988 const _Tp* 989 function<_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 998 template<class _Rp, class _A0, class _A1> 999 class _LIBCPP_TEMPLATE_VIS 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 1006 public: 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 1051 private: 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; 1057 public: 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 1069 template<class _Rp, class _A0, class _A1> 1070 function<_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 1083 template<class _Rp, class _A0, class _A1> 1084 template<class _Alloc> 1085 function<_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 1098 template<class _Rp, class _A0, class _A1> 1099 template <class _Fp> 1100 function<_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 1124 template<class _Rp, class _A0, class _A1> 1125 template <class _Fp, class _Alloc> 1126 function<_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 1151 template<class _Rp, class _A0, class _A1> 1152 function<_Rp(_A0, _A1)>& 1153 function<_Rp(_A0, _A1)>::operator=(const function& __f) 1154 { 1155 function(__f).swap(*this); 1156 return *this; 1157 } 1158 1159 template<class _Rp, class _A0, class _A1> 1160 function<_Rp(_A0, _A1)>& 1161 function<_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 1171 template<class _Rp, class _A0, class _A1> 1172 template <class _Fp> 1173 typename enable_if 1174 < 1175 !is_integral<_Fp>::value, 1176 function<_Rp(_A0, _A1)>& 1177 >::type 1178 function<_Rp(_A0, _A1)>::operator=(_Fp __f) 1179 { 1180 function(_VSTD::move(__f)).swap(*this); 1181 return *this; 1182 } 1183 1184 template<class _Rp, class _A0, class _A1> 1185 function<_Rp(_A0, _A1)>::~function() 1186 { 1187 if (__f_ == (__base*)&__buf_) 1188 __f_->destroy(); 1189 else if (__f_) 1190 __f_->destroy_deallocate(); 1191 } 1192 1193 template<class _Rp, class _A0, class _A1> 1194 void 1195 function<_Rp(_A0, _A1)>::swap(function& __f) 1196 { 1197 if (_VSTD::addressof(__f) == this) 1198 return; 1199 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) 1200 { 1201 typename aligned_storage<sizeof(__buf_)>::type __tempbuf; 1202 __base* __t = (__base*)&__tempbuf; 1203 __f_->__clone(__t); 1204 __f_->destroy(); 1205 __f_ = 0; 1206 __f.__f_->__clone((__base*)&__buf_); 1207 __f.__f_->destroy(); 1208 __f.__f_ = 0; 1209 __f_ = (__base*)&__buf_; 1210 __t->__clone((__base*)&__f.__buf_); 1211 __t->destroy(); 1212 __f.__f_ = (__base*)&__f.__buf_; 1213 } 1214 else if (__f_ == (__base*)&__buf_) 1215 { 1216 __f_->__clone((__base*)&__f.__buf_); 1217 __f_->destroy(); 1218 __f_ = __f.__f_; 1219 __f.__f_ = (__base*)&__f.__buf_; 1220 } 1221 else if (__f.__f_ == (__base*)&__f.__buf_) 1222 { 1223 __f.__f_->__clone((__base*)&__buf_); 1224 __f.__f_->destroy(); 1225 __f.__f_ = __f_; 1226 __f_ = (__base*)&__buf_; 1227 } 1228 else 1229 _VSTD::swap(__f_, __f.__f_); 1230 } 1231 1232 template<class _Rp, class _A0, class _A1> 1233 _Rp 1234 function<_Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) const 1235 { 1236 if (__f_ == 0) 1237 __throw_bad_function_call(); 1238 return (*__f_)(__a0, __a1); 1239 } 1240 1241 #ifndef _LIBCPP_NO_RTTI 1242 1243 template<class _Rp, class _A0, class _A1> 1244 const std::type_info& 1245 function<_Rp(_A0, _A1)>::target_type() const 1246 { 1247 if (__f_ == 0) 1248 return typeid(void); 1249 return __f_->target_type(); 1250 } 1251 1252 template<class _Rp, class _A0, class _A1> 1253 template <typename _Tp> 1254 _Tp* 1255 function<_Rp(_A0, _A1)>::target() 1256 { 1257 if (__f_ == 0) 1258 return (_Tp*)0; 1259 return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp))); 1260 } 1261 1262 template<class _Rp, class _A0, class _A1> 1263 template <typename _Tp> 1264 const _Tp* 1265 function<_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 1274 template<class _Rp, class _A0, class _A1, class _A2> 1275 class _LIBCPP_TEMPLATE_VIS 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 1281 public: 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 1326 private: 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; 1332 public: 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 1344 template<class _Rp, class _A0, class _A1, class _A2> 1345 function<_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 1358 template<class _Rp, class _A0, class _A1, class _A2> 1359 template<class _Alloc> 1360 function<_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 1374 template<class _Rp, class _A0, class _A1, class _A2> 1375 template <class _Fp> 1376 function<_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 1400 template<class _Rp, class _A0, class _A1, class _A2> 1401 template <class _Fp, class _Alloc> 1402 function<_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 1427 template<class _Rp, class _A0, class _A1, class _A2> 1428 function<_Rp(_A0, _A1, _A2)>& 1429 function<_Rp(_A0, _A1, _A2)>::operator=(const function& __f) 1430 { 1431 function(__f).swap(*this); 1432 return *this; 1433 } 1434 1435 template<class _Rp, class _A0, class _A1, class _A2> 1436 function<_Rp(_A0, _A1, _A2)>& 1437 function<_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 1447 template<class _Rp, class _A0, class _A1, class _A2> 1448 template <class _Fp> 1449 typename enable_if 1450 < 1451 !is_integral<_Fp>::value, 1452 function<_Rp(_A0, _A1, _A2)>& 1453 >::type 1454 function<_Rp(_A0, _A1, _A2)>::operator=(_Fp __f) 1455 { 1456 function(_VSTD::move(__f)).swap(*this); 1457 return *this; 1458 } 1459 1460 template<class _Rp, class _A0, class _A1, class _A2> 1461 function<_Rp(_A0, _A1, _A2)>::~function() 1462 { 1463 if (__f_ == (__base*)&__buf_) 1464 __f_->destroy(); 1465 else if (__f_) 1466 __f_->destroy_deallocate(); 1467 } 1468 1469 template<class _Rp, class _A0, class _A1, class _A2> 1470 void 1471 function<_Rp(_A0, _A1, _A2)>::swap(function& __f) 1472 { 1473 if (_VSTD::addressof(__f) == this) 1474 return; 1475 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) 1476 { 1477 typename aligned_storage<sizeof(__buf_)>::type __tempbuf; 1478 __base* __t = (__base*)&__tempbuf; 1479 __f_->__clone(__t); 1480 __f_->destroy(); 1481 __f_ = 0; 1482 __f.__f_->__clone((__base*)&__buf_); 1483 __f.__f_->destroy(); 1484 __f.__f_ = 0; 1485 __f_ = (__base*)&__buf_; 1486 __t->__clone((__base*)&__f.__buf_); 1487 __t->destroy(); 1488 __f.__f_ = (__base*)&__f.__buf_; 1489 } 1490 else if (__f_ == (__base*)&__buf_) 1491 { 1492 __f_->__clone((__base*)&__f.__buf_); 1493 __f_->destroy(); 1494 __f_ = __f.__f_; 1495 __f.__f_ = (__base*)&__f.__buf_; 1496 } 1497 else if (__f.__f_ == (__base*)&__f.__buf_) 1498 { 1499 __f.__f_->__clone((__base*)&__buf_); 1500 __f.__f_->destroy(); 1501 __f.__f_ = __f_; 1502 __f_ = (__base*)&__buf_; 1503 } 1504 else 1505 _VSTD::swap(__f_, __f.__f_); 1506 } 1507 1508 template<class _Rp, class _A0, class _A1, class _A2> 1509 _Rp 1510 function<_Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) const 1511 { 1512 if (__f_ == 0) 1513 __throw_bad_function_call(); 1514 return (*__f_)(__a0, __a1, __a2); 1515 } 1516 1517 #ifndef _LIBCPP_NO_RTTI 1518 1519 template<class _Rp, class _A0, class _A1, class _A2> 1520 const std::type_info& 1521 function<_Rp(_A0, _A1, _A2)>::target_type() const 1522 { 1523 if (__f_ == 0) 1524 return typeid(void); 1525 return __f_->target_type(); 1526 } 1527 1528 template<class _Rp, class _A0, class _A1, class _A2> 1529 template <typename _Tp> 1530 _Tp* 1531 function<_Rp(_A0, _A1, _A2)>::target() 1532 { 1533 if (__f_ == 0) 1534 return (_Tp*)0; 1535 return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp))); 1536 } 1537 1538 template<class _Rp, class _A0, class _A1, class _A2> 1539 template <typename _Tp> 1540 const _Tp* 1541 function<_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 1550 template <class _Fp> 1551 inline _LIBCPP_INLINE_VISIBILITY 1552 bool 1553 operator==(const function<_Fp>& __f, nullptr_t) {return !__f;} 1554 1555 template <class _Fp> 1556 inline _LIBCPP_INLINE_VISIBILITY 1557 bool 1558 operator==(nullptr_t, const function<_Fp>& __f) {return !__f;} 1559 1560 template <class _Fp> 1561 inline _LIBCPP_INLINE_VISIBILITY 1562 bool 1563 operator!=(const function<_Fp>& __f, nullptr_t) {return (bool)__f;} 1564 1565 template <class _Fp> 1566 inline _LIBCPP_INLINE_VISIBILITY 1567 bool 1568 operator!=(nullptr_t, const function<_Fp>& __f) {return (bool)__f;} 1569 1570 template <class _Fp> 1571 inline _LIBCPP_INLINE_VISIBILITY 1572 void 1573 swap(function<_Fp>& __x, function<_Fp>& __y) 1574 {return __x.swap(__y);} 1575 1576 #endif // _LIBCPP_FUNCTIONAL_03 1577