Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

544 rindas
18KB

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