wistd_functional.h 19 KB

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