1 // -*- C++ -*- 2 //===------------------------ functional ----------------------------------===// 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 // STL common functionality 12 // 13 // Some aspects of STL are core language concepts that should be used from all C++ code, regardless 14 // of whether exceptions are enabled in the component. Common library code that expects to be used 15 // from exception-free components want these concepts, but including STL headers directly introduces 16 // friction as it requires components not using STL to declare their STL version. Doing so creates 17 // ambiguity around whether STL use is safe in a particular component and implicitly brings in 18 // a long list of headers (including <new>) which can create further ambiguity around throwing new 19 // support (some routines pulled in may expect it). Secondarily, pulling in these headers also has 20 // the potential to create naming conflicts or other implied dependencies. 21 // 22 // To promote the use of these core language concepts outside of STL-based binaries, this file is 23 // selectively pulling those concepts *directly* from corresponding STL headers. The corresponding 24 // "std::" namespace STL functions and types should be preferred over these in code that is bound to 25 // STL. The implementation and naming of all functions are taken directly from STL, instead using 26 // "wistd" (Windows Implementation std) as the namespace. 27 // 28 // Routines in this namespace should always be considered a reflection of the *current* STL implementation 29 // of those routines. Updates from STL should be taken, but no "bugs" should be fixed here. 30 // 31 // New, exception-based code should not use this namespace, but instead should prefer the std:: implementation. 32 // Only code that is not exception-based and libraries that expect to be utilized across both exception 33 // and non-exception based code should utilize this functionality. 34 35 #ifndef _WISTD_FUNCTIONAL_H_ 36 #define _WISTD_FUNCTIONAL_H_ 37 38 // DO NOT add *any* additional includes to this file -- there should be no dependencies from its usage 39 #include "wistd_memory.h" 40 #include <intrin.h> // For __fastfail 41 #include <new.h> // For placement new 42 43 #if !defined(__WI_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 44 #pragma GCC system_header 45 #endif 46 47 #pragma warning(push) 48 #pragma warning(disable: 4324) 49 50 /// @cond 51 namespace wistd // ("Windows Implementation" std) 52 { 53 // wistd::function 54 // 55 // All of the code below is in direct support of wistd::function. This class is identical to std::function 56 // with the following exceptions: 57 // 58 // 1) It never allocates and is safe to use from exception-free code (custom allocators are not supported) 59 // 2) It's slightly bigger on the stack (64 bytes, rather than 24 for 32bit) 60 // 3) There is an explicit static-assert if a lambda becomes too large to hold in the internal buffer (rather than an allocation) 61 62 template <class _Ret> 63 struct __invoke_void_return_wrapper 64 { 65 #ifndef __WI_LIBCPP_CXX03_LANG 66 template <class ..._Args> __call__invoke_void_return_wrapper67 static _Ret __call(_Args&&... __args) { 68 return __invoke(wistd::forward<_Args>(__args)...); 69 } 70 #else 71 template <class _Fn> 72 static _Ret __call(_Fn __f) { 73 return __invoke(__f); 74 } 75 76 template <class _Fn, class _A0> 77 static _Ret __call(_Fn __f, _A0& __a0) { 78 return __invoke(__f, __a0); 79 } 80 81 template <class _Fn, class _A0, class _A1> 82 static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1) { 83 return __invoke(__f, __a0, __a1); 84 } 85 86 template <class _Fn, class _A0, class _A1, class _A2> 87 static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2){ 88 return __invoke(__f, __a0, __a1, __a2); 89 } 90 #endif 91 }; 92 93 template <> 94 struct __invoke_void_return_wrapper<void> 95 { 96 #ifndef __WI_LIBCPP_CXX03_LANG 97 template <class ..._Args> 98 static void __call(_Args&&... __args) { 99 (void)__invoke(wistd::forward<_Args>(__args)...); 100 } 101 #else 102 template <class _Fn> 103 static void __call(_Fn __f) { 104 __invoke(__f); 105 } 106 107 template <class _Fn, class _A0> 108 static void __call(_Fn __f, _A0& __a0) { 109 __invoke(__f, __a0); 110 } 111 112 template <class _Fn, class _A0, class _A1> 113 static void __call(_Fn __f, _A0& __a0, _A1& __a1) { 114 __invoke(__f, __a0, __a1); 115 } 116 117 template <class _Fn, class _A0, class _A1, class _A2> 118 static void __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2) { 119 __invoke(__f, __a0, __a1, __a2); 120 } 121 #endif 122 }; 123 124 //////////////////////////////////////////////////////////////////////////////// 125 // FUNCTION 126 //============================================================================== 127 128 // bad_function_call 129 130 __WI_LIBCPP_NORETURN inline __WI_LIBCPP_INLINE_VISIBILITY 131 void __throw_bad_function_call() 132 { 133 __fastfail(7); // FAST_FAIL_FATAL_APP_EXIT 134 } 135 136 template<class _Fp> class __WI_LIBCPP_TEMPLATE_VIS function; // undefined 137 138 namespace __function 139 { 140 141 template<class _Rp> 142 struct __maybe_derive_from_unary_function 143 { 144 }; 145 146 template<class _Rp, class _A1> 147 struct __maybe_derive_from_unary_function<_Rp(_A1)> 148 : public unary_function<_A1, _Rp> 149 { 150 }; 151 152 template<class _Rp> 153 struct __maybe_derive_from_binary_function 154 { 155 }; 156 157 template<class _Rp, class _A1, class _A2> 158 struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)> 159 : public binary_function<_A1, _A2, _Rp> 160 { 161 }; 162 163 template <class _Fp> 164 __WI_LIBCPP_INLINE_VISIBILITY 165 bool __not_null(_Fp const&) { return true; } 166 167 template <class _Fp> 168 __WI_LIBCPP_INLINE_VISIBILITY 169 bool __not_null(_Fp* __ptr) { return __ptr; } 170 171 template <class _Ret, class _Class> 172 __WI_LIBCPP_INLINE_VISIBILITY 173 bool __not_null(_Ret _Class::*__ptr) { return __ptr; } 174 175 template <class _Fp> 176 __WI_LIBCPP_INLINE_VISIBILITY 177 bool __not_null(function<_Fp> const& __f) { return !!__f; } 178 179 } // namespace __function 180 181 #ifndef __WI_LIBCPP_CXX03_LANG 182 183 namespace __function { 184 185 template<class _Fp> class __base; 186 187 template<class _Rp, class ..._ArgTypes> 188 class __base<_Rp(_ArgTypes...)> 189 { 190 __base(const __base&); 191 __base& operator=(const __base&); 192 public: 193 __WI_LIBCPP_INLINE_VISIBILITY __base() {} 194 __WI_LIBCPP_INLINE_VISIBILITY virtual ~__base() {} 195 virtual void __clone(__base*) const = 0; 196 virtual void __move(__base*) = 0; 197 virtual void destroy() WI_NOEXCEPT = 0; 198 virtual _Rp operator()(_ArgTypes&& ...) = 0; 199 }; 200 201 template<class _FD, class _FB> class __func; 202 203 template<class _Fp, class _Rp, class ..._ArgTypes> 204 class __func<_Fp, _Rp(_ArgTypes...)> 205 : public __base<_Rp(_ArgTypes...)> 206 { 207 _Fp __f_; 208 public: 209 __WI_LIBCPP_INLINE_VISIBILITY 210 explicit __func(_Fp&& __f) 211 : __f_(wistd::move(__f)) {} 212 213 __WI_LIBCPP_INLINE_VISIBILITY 214 explicit __func(const _Fp& __f) 215 : __f_(__f) {} 216 217 virtual void __clone(__base<_Rp(_ArgTypes...)>*) const; 218 virtual void __move(__base<_Rp(_ArgTypes...)>*); 219 virtual void destroy() WI_NOEXCEPT; 220 virtual _Rp operator()(_ArgTypes&& ... __arg); 221 }; 222 223 template<class _Fp, class _Rp, class ..._ArgTypes> 224 void 225 __func<_Fp, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const 226 { 227 ::new (__p) __func(__f_); 228 } 229 230 template<class _Fp, class _Rp, class ..._ArgTypes> 231 void 232 __func<_Fp, _Rp(_ArgTypes...)>::__move(__base<_Rp(_ArgTypes...)>* __p) 233 { 234 ::new (__p) __func(wistd::move(__f_)); 235 } 236 237 template<class _Fp, class _Rp, class ..._ArgTypes> 238 void 239 __func<_Fp, _Rp(_ArgTypes...)>::destroy() WI_NOEXCEPT 240 { 241 __f_.~_Fp(); 242 } 243 244 template<class _Fp, class _Rp, class ..._ArgTypes> 245 _Rp 246 __func<_Fp, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg) 247 { 248 typedef __invoke_void_return_wrapper<_Rp> _Invoker; 249 return _Invoker::__call(__f_, wistd::forward<_ArgTypes>(__arg)...); 250 } 251 252 } // __function 253 254 template<class _Rp, class ..._ArgTypes> 255 class __WI_LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)> 256 : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>, 257 public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)> 258 { 259 // 'wistd::function' is most similar to 'inplace_function' in that it _only_ permits holding function objects 260 // that can fit within its internal buffer. Therefore, we expand this size to accommodate space for at least 12 261 // pointers (__base vtable takes an additional one). 262 static constexpr size_t __buffer_size = 13 * sizeof(void*); 263 264 typedef __function::__base<_Rp(_ArgTypes...)> __base; 265 __WI_LIBCPP_SUPPRESS_NONINIT_ANALYSIS 266 typename aligned_storage<__buffer_size>::type __buf_; 267 __base* __f_; 268 269 __WI_LIBCPP_NO_CFI static __base *__as_base(void *p) { 270 return reinterpret_cast<__base*>(p); 271 } 272 273 template <class _Fp, bool> 274 struct __callable_imp 275 { 276 static const bool value = is_same<void, _Rp>::value || 277 is_convertible<typename __invoke_of<_Fp&, _ArgTypes...>::type, 278 _Rp>::value; 279 }; 280 281 template <class _Fp> 282 struct __callable_imp<_Fp, false> 283 { 284 static const bool value = false; 285 }; 286 287 template <class _Fp> 288 struct __callable 289 { 290 static const bool value = __callable_imp<_Fp, __lazy_and< 291 integral_constant<bool, !is_same<__uncvref_t<_Fp>, function>::value>, 292 __invokable<_Fp&, _ArgTypes...> 293 >::value>::value; 294 }; 295 296 template <class _Fp> 297 using _EnableIfCallable = typename enable_if<__callable<_Fp>::value>::type; 298 public: 299 typedef _Rp result_type; 300 301 // construct/copy/destroy: 302 __WI_LIBCPP_INLINE_VISIBILITY __WI_LIBCPP_SUPPRESS_NONINIT_ANALYSIS 303 function() WI_NOEXCEPT : __f_(0) {} 304 __WI_LIBCPP_INLINE_VISIBILITY 305 function(nullptr_t) WI_NOEXCEPT : __f_(0) {} 306 function(const function&); 307 function(function&&); 308 template<class _Fp, class = _EnableIfCallable<_Fp>> 309 function(_Fp); 310 311 function& operator=(const function&); 312 function& operator=(function&&); 313 function& operator=(nullptr_t) WI_NOEXCEPT; 314 template<class _Fp, class = _EnableIfCallable<_Fp>> 315 function& operator=(_Fp&&); 316 317 ~function(); 318 319 // function modifiers: 320 void swap(function&); 321 322 // function capacity: 323 __WI_LIBCPP_INLINE_VISIBILITY 324 __WI_LIBCPP_EXPLICIT operator bool() const WI_NOEXCEPT {return __f_;} 325 326 // deleted overloads close possible hole in the type system 327 template<class _R2, class... _ArgTypes2> 328 bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete; 329 template<class _R2, class... _ArgTypes2> 330 bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete; 331 public: 332 // function invocation: 333 _Rp operator()(_ArgTypes...) const; 334 335 // NOTE: type_info is very compiler specific, and on top of that, we're operating in a namespace other than 336 // 'std' so all functions requiring RTTI have been removed 337 }; 338 339 template<class _Rp, class ..._ArgTypes> 340 __WI_LIBCPP_SUPPRESS_NONINIT_ANALYSIS 341 function<_Rp(_ArgTypes...)>::function(const function& __f) 342 { 343 if (__f.__f_ == 0) 344 __f_ = 0; 345 else 346 { 347 __f_ = __as_base(&__buf_); 348 __f.__f_->__clone(__f_); 349 } 350 } 351 352 template<class _Rp, class ..._ArgTypes> 353 __WI_LIBCPP_SUPPRESS_NONINIT_ANALYSIS __WI_LIBCPP_SUPPRESS_NOEXCEPT_ANALYSIS 354 function<_Rp(_ArgTypes...)>::function(function&& __f) 355 { 356 if (__f.__f_ == 0) 357 __f_ = 0; 358 else 359 { 360 __f_ = __as_base(&__buf_); 361 __f.__f_->__move(__f_); 362 __f.__f_->destroy(); 363 __f.__f_ = 0; 364 } 365 } 366 367 template<class _Rp, class ..._ArgTypes> 368 template <class _Fp, class> 369 __WI_LIBCPP_SUPPRESS_NONINIT_ANALYSIS 370 function<_Rp(_ArgTypes...)>::function(_Fp __f) 371 : __f_(0) 372 { 373 if (__function::__not_null(__f)) 374 { 375 typedef __function::__func<_Fp, _Rp(_ArgTypes...)> _FF; 376 static_assert(sizeof(_FF) <= sizeof(__buf_), 377 "The sizeof(wistd::function) has grown too large for the reserved buffer (12 pointers). Refactor to reduce size of the capture."); 378 __f_ = ::new((void*)&__buf_) _FF(wistd::move(__f)); 379 } 380 } 381 382 template<class _Rp, class ..._ArgTypes> 383 function<_Rp(_ArgTypes...)>& 384 function<_Rp(_ArgTypes...)>::operator=(const function& __f) 385 { 386 *this = nullptr; 387 if (__f.__f_) 388 { 389 __f_ = __as_base(&__buf_); 390 __f.__f_->__clone(__f_); 391 } 392 return *this; 393 } 394 395 template<class _Rp, class ..._ArgTypes> 396 function<_Rp(_ArgTypes...)>& 397 function<_Rp(_ArgTypes...)>::operator=(function&& __f) 398 { 399 *this = nullptr; 400 if (__f.__f_) 401 { 402 __f_ = __as_base(&__buf_); 403 __f.__f_->__move(__f_); 404 __f.__f_->destroy(); 405 __f.__f_ = 0; 406 } 407 return *this; 408 } 409 410 template<class _Rp, class ..._ArgTypes> 411 function<_Rp(_ArgTypes...)>& 412 function<_Rp(_ArgTypes...)>::operator=(nullptr_t) WI_NOEXCEPT 413 { 414 __base* __t = __f_; 415 __f_ = 0; 416 if (__t) 417 __t->destroy(); 418 return *this; 419 } 420 421 template<class _Rp, class ..._ArgTypes> 422 template <class _Fp, class> 423 function<_Rp(_ArgTypes...)>& 424 function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f) 425 { 426 *this = nullptr; 427 if (__function::__not_null(__f)) 428 { 429 typedef __function::__func<typename decay<_Fp>::type, _Rp(_ArgTypes...)> _FF; 430 static_assert(sizeof(_FF) <= sizeof(__buf_), 431 "The sizeof(wistd::function) has grown too large for the reserved buffer (12 pointers). Refactor to reduce size of the capture."); 432 __f_ = ::new((void*)&__buf_) _FF(wistd::move(__f)); 433 } 434 435 return *this; 436 } 437 438 template<class _Rp, class ..._ArgTypes> 439 function<_Rp(_ArgTypes...)>::~function() 440 { 441 if (__f_) 442 __f_->destroy(); 443 } 444 445 template<class _Rp, class ..._ArgTypes> 446 void 447 function<_Rp(_ArgTypes...)>::swap(function& __f) 448 { 449 if (wistd::addressof(__f) == this) 450 return; 451 if (__f_ && __f.__f_) 452 { 453 typename aligned_storage<sizeof(__buf_)>::type __tempbuf; 454 __base* __t = __as_base(&__tempbuf); 455 __f_->__move(__t); 456 __f_->destroy(); 457 __f_ = 0; 458 __f.__f_->__move(__as_base(&__buf_)); 459 __f.__f_->destroy(); 460 __f.__f_ = 0; 461 __f_ = __as_base(&__buf_); 462 __t->__move(__as_base(&__f.__buf_)); 463 __t->destroy(); 464 __f.__f_ = __as_base(&__f.__buf_); 465 } 466 else if (__f_) 467 { 468 __f_->__move(__as_base(&__f.__buf_)); 469 __f_->destroy(); 470 __f_ = 0; 471 __f.__f_ = __as_base(&__f.__buf_); 472 } 473 else if (__f.__f_) 474 { 475 __f.__f_->__move(__as_base(&__buf_)); 476 __f.__f_->destroy(); 477 __f.__f_ = 0; 478 __f_ = __as_base(&__buf_); 479 } 480 } 481 482 template<class _Rp, class ..._ArgTypes> 483 _Rp 484 function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const 485 { 486 if (__f_ == 0) 487 __throw_bad_function_call(); 488 return (*__f_)(wistd::forward<_ArgTypes>(__arg)...); 489 } 490 491 template <class _Rp, class... _ArgTypes> 492 inline __WI_LIBCPP_INLINE_VISIBILITY 493 bool 494 operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) WI_NOEXCEPT {return !__f;} 495 496 template <class _Rp, class... _ArgTypes> 497 inline __WI_LIBCPP_INLINE_VISIBILITY 498 bool 499 operator==(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) WI_NOEXCEPT {return !__f;} 500 501 template <class _Rp, class... _ArgTypes> 502 inline __WI_LIBCPP_INLINE_VISIBILITY 503 bool 504 operator!=(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) WI_NOEXCEPT {return (bool)__f;} 505 506 template <class _Rp, class... _ArgTypes> 507 inline __WI_LIBCPP_INLINE_VISIBILITY 508 bool 509 operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) WI_NOEXCEPT {return (bool)__f;} 510 511 // Provide both 'swap_wil' and 'swap' since we now have two ADL scenarios that we need to work 512 template <class _Rp, class... _ArgTypes> 513 inline __WI_LIBCPP_INLINE_VISIBILITY 514 void 515 swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) 516 {return __x.swap(__y);} 517 518 template <class _Rp, class... _ArgTypes> 519 inline __WI_LIBCPP_INLINE_VISIBILITY 520 void 521 swap_wil(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) 522 {return __x.swap(__y);} 523 524 // std::invoke 525 template <class _Fn, class ..._Args> 526 typename __invoke_of<_Fn, _Args...>::type 527 invoke(_Fn&& __f, _Args&&... __args) 528 __WI_NOEXCEPT_((__nothrow_invokable<_Fn, _Args...>::value)) 529 { 530 return wistd::__invoke(wistd::forward<_Fn>(__f), wistd::forward<_Args>(__args)...); 531 } 532 533 #else // __WI_LIBCPP_CXX03_LANG 534 535 #error wistd::function and wistd::invoke not implemented for pre-C++11 536 537 #endif 538 } 539 /// @endcond 540 541 #pragma warning(pop) 542 543 #endif // _WISTD_FUNCTIONAL_H_ 544