Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 
 
 

545 wiersze
18 KiB

  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. } // __function
  213. template<class _Rp, class ..._ArgTypes>
  214. class __WI_LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)>
  215. : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>,
  216. public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)>
  217. {
  218. // 'wistd::function' is most similar to 'inplace_function' in that it _only_ permits holding function objects
  219. // that can fit within its internal buffer. Therefore, we expand this size to accommodate space for at least 12
  220. // pointers (__base vtable takes an additional one).
  221. static constexpr size_t __buffer_size = 13 * sizeof(void*);
  222. typedef __function::__base<_Rp(_ArgTypes...)> __base;
  223. __WI_LIBCPP_SUPPRESS_NONINIT_ANALYSIS
  224. typename aligned_storage<__buffer_size>::type __buf_;
  225. __base* __f_;
  226. __WI_LIBCPP_NO_CFI static __base *__as_base(void *p) {
  227. return reinterpret_cast<__base*>(p);
  228. }
  229. template <class _Fp, bool>
  230. struct __callable_imp
  231. {
  232. static const bool value = is_same<void, _Rp>::value ||
  233. is_convertible<typename __invoke_of<_Fp&, _ArgTypes...>::type,
  234. _Rp>::value;
  235. };
  236. template <class _Fp>
  237. struct __callable_imp<_Fp, false>
  238. {
  239. static const bool value = false;
  240. };
  241. template <class _Fp>
  242. struct __callable
  243. {
  244. static const bool value = __callable_imp<_Fp, __lazy_and<
  245. integral_constant<bool, !is_same<__uncvref_t<_Fp>, function>::value>,
  246. __invokable<_Fp&, _ArgTypes...>
  247. >::value>::value;
  248. };
  249. template <class _Fp>
  250. using _EnableIfCallable = typename enable_if<__callable<_Fp>::value>::type;
  251. public:
  252. typedef _Rp result_type;
  253. // construct/copy/destroy:
  254. __WI_LIBCPP_INLINE_VISIBILITY __WI_LIBCPP_SUPPRESS_NONINIT_ANALYSIS
  255. function() WI_NOEXCEPT : __f_(0) {}
  256. __WI_LIBCPP_INLINE_VISIBILITY
  257. function(nullptr_t) WI_NOEXCEPT : __f_(0) {}
  258. function(const function&);
  259. function(function&&);
  260. template<class _Fp, class = _EnableIfCallable<_Fp>>
  261. function(_Fp);
  262. function& operator=(const function&);
  263. function& operator=(function&&);
  264. function& operator=(nullptr_t) WI_NOEXCEPT;
  265. template<class _Fp, class = _EnableIfCallable<_Fp>>
  266. function& operator=(_Fp&&);
  267. ~function();
  268. // function modifiers:
  269. void swap(function&);
  270. // function capacity:
  271. __WI_LIBCPP_INLINE_VISIBILITY
  272. __WI_LIBCPP_EXPLICIT operator bool() const WI_NOEXCEPT {return __f_;}
  273. // deleted overloads close possible hole in the type system
  274. template<class _R2, class... _ArgTypes2>
  275. bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete;
  276. template<class _R2, class... _ArgTypes2>
  277. bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete;
  278. public:
  279. // function invocation:
  280. _Rp operator()(_ArgTypes...) const;
  281. // NOTE: type_info is very compiler specific, and on top of that, we're operating in a namespace other than
  282. // 'std' so all functions requiring RTTI have been removed
  283. };
  284. template<class _Rp, class ..._ArgTypes>
  285. __WI_LIBCPP_SUPPRESS_NONINIT_ANALYSIS
  286. function<_Rp(_ArgTypes...)>::function(const function& __f)
  287. {
  288. if (__f.__f_ == 0)
  289. __f_ = 0;
  290. else
  291. {
  292. __f_ = __as_base(&__buf_);
  293. __f.__f_->__clone(__f_);
  294. }
  295. }
  296. template<class _Rp, class ..._ArgTypes>
  297. __WI_LIBCPP_SUPPRESS_NONINIT_ANALYSIS __WI_LIBCPP_SUPPRESS_NOEXCEPT_ANALYSIS
  298. function<_Rp(_ArgTypes...)>::function(function&& __f)
  299. {
  300. if (__f.__f_ == 0)
  301. __f_ = 0;
  302. else
  303. {
  304. __f_ = __as_base(&__buf_);
  305. __f.__f_->__move(__f_);
  306. __f.__f_->destroy();
  307. __f.__f_ = 0;
  308. }
  309. }
  310. template<class _Rp, class ..._ArgTypes>
  311. template <class _Fp, class>
  312. __WI_LIBCPP_SUPPRESS_NONINIT_ANALYSIS
  313. function<_Rp(_ArgTypes...)>::function(_Fp __f)
  314. : __f_(0)
  315. {
  316. if (__function::__not_null(__f))
  317. {
  318. typedef __function::__func<_Fp, _Rp(_ArgTypes...)> _FF;
  319. static_assert(sizeof(_FF) <= sizeof(__buf_),
  320. "The sizeof(wistd::function) has grown too large for the reserved buffer (12 pointers). Refactor to reduce size of the capture.");
  321. __f_ = ::new((void*)&__buf_) _FF(wistd::move(__f));
  322. }
  323. }
  324. template<class _Rp, class ..._ArgTypes>
  325. function<_Rp(_ArgTypes...)>&
  326. function<_Rp(_ArgTypes...)>::operator=(const function& __f)
  327. {
  328. *this = nullptr;
  329. if (__f.__f_)
  330. {
  331. __f_ = __as_base(&__buf_);
  332. __f.__f_->__clone(__f_);
  333. }
  334. return *this;
  335. }
  336. template<class _Rp, class ..._ArgTypes>
  337. function<_Rp(_ArgTypes...)>&
  338. function<_Rp(_ArgTypes...)>::operator=(function&& __f)
  339. {
  340. *this = nullptr;
  341. if (__f.__f_)
  342. {
  343. __f_ = __as_base(&__buf_);
  344. __f.__f_->__move(__f_);
  345. __f.__f_->destroy();
  346. __f.__f_ = 0;
  347. }
  348. return *this;
  349. }
  350. template<class _Rp, class ..._ArgTypes>
  351. function<_Rp(_ArgTypes...)>&
  352. function<_Rp(_ArgTypes...)>::operator=(nullptr_t) WI_NOEXCEPT
  353. {
  354. __base* __t = __f_;
  355. __f_ = 0;
  356. if (__t)
  357. __t->destroy();
  358. return *this;
  359. }
  360. template<class _Rp, class ..._ArgTypes>
  361. template <class _Fp, class>
  362. function<_Rp(_ArgTypes...)>&
  363. function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f)
  364. {
  365. *this = nullptr;
  366. if (__function::__not_null(__f))
  367. {
  368. typedef __function::__func<typename decay<_Fp>::type, _Rp(_ArgTypes...)> _FF;
  369. static_assert(sizeof(_FF) <= sizeof(__buf_),
  370. "The sizeof(wistd::function) has grown too large for the reserved buffer (12 pointers). Refactor to reduce size of the capture.");
  371. __f_ = ::new((void*)&__buf_) _FF(wistd::move(__f));
  372. }
  373. return *this;
  374. }
  375. template<class _Rp, class ..._ArgTypes>
  376. function<_Rp(_ArgTypes...)>::~function()
  377. {
  378. if (__f_)
  379. __f_->destroy();
  380. }
  381. template<class _Rp, class ..._ArgTypes>
  382. void
  383. function<_Rp(_ArgTypes...)>::swap(function& __f)
  384. {
  385. if (wistd::addressof(__f) == this)
  386. return;
  387. if (__f_ && __f.__f_)
  388. {
  389. typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
  390. __base* __t = __as_base(&__tempbuf);
  391. __f_->__move(__t);
  392. __f_->destroy();
  393. __f_ = 0;
  394. __f.__f_->__move(__as_base(&__buf_));
  395. __f.__f_->destroy();
  396. __f.__f_ = 0;
  397. __f_ = __as_base(&__buf_);
  398. __t->__move(__as_base(&__f.__buf_));
  399. __t->destroy();
  400. __f.__f_ = __as_base(&__f.__buf_);
  401. }
  402. else if (__f_)
  403. {
  404. __f_->__move(__as_base(&__f.__buf_));
  405. __f_->destroy();
  406. __f_ = 0;
  407. __f.__f_ = __as_base(&__f.__buf_);
  408. }
  409. else if (__f.__f_)
  410. {
  411. __f.__f_->__move(__as_base(&__buf_));
  412. __f.__f_->destroy();
  413. __f.__f_ = 0;
  414. __f_ = __as_base(&__buf_);
  415. }
  416. }
  417. template<class _Rp, class ..._ArgTypes>
  418. _Rp
  419. function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
  420. {
  421. if (__f_ == 0)
  422. __throw_bad_function_call();
  423. return (*__f_)(wistd::forward<_ArgTypes>(__arg)...);
  424. }
  425. template <class _Rp, class... _ArgTypes>
  426. inline __WI_LIBCPP_INLINE_VISIBILITY
  427. bool
  428. operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) WI_NOEXCEPT {return !__f;}
  429. template <class _Rp, class... _ArgTypes>
  430. inline __WI_LIBCPP_INLINE_VISIBILITY
  431. bool
  432. operator==(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) WI_NOEXCEPT {return !__f;}
  433. template <class _Rp, class... _ArgTypes>
  434. inline __WI_LIBCPP_INLINE_VISIBILITY
  435. bool
  436. operator!=(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) WI_NOEXCEPT {return (bool)__f;}
  437. template <class _Rp, class... _ArgTypes>
  438. inline __WI_LIBCPP_INLINE_VISIBILITY
  439. bool
  440. operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) WI_NOEXCEPT {return (bool)__f;}
  441. // Provide both 'swap_wil' and 'swap' since we now have two ADL scenarios that we need to work
  442. template <class _Rp, class... _ArgTypes>
  443. inline __WI_LIBCPP_INLINE_VISIBILITY
  444. void
  445. swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y)
  446. {return __x.swap(__y);}
  447. template <class _Rp, class... _ArgTypes>
  448. inline __WI_LIBCPP_INLINE_VISIBILITY
  449. void
  450. swap_wil(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y)
  451. {return __x.swap(__y);}
  452. // std::invoke
  453. template <class _Fn, class ..._Args>
  454. typename __invoke_of<_Fn, _Args...>::type
  455. invoke(_Fn&& __f, _Args&&... __args)
  456. __WI_NOEXCEPT_((__nothrow_invokable<_Fn, _Args...>::value))
  457. {
  458. return wistd::__invoke(wistd::forward<_Fn>(__f), wistd::forward<_Args>(__args)...);
  459. }
  460. #else // __WI_LIBCPP_CXX03_LANG
  461. #error wistd::function and wistd::invoke not implemented for pre-C++11
  462. #endif
  463. }
  464. /// @endcond
  465. #pragma warning(pop)
  466. #endif // _WISTD_FUNCTIONAL_H_