The Webview Univeral Flutter package for Appeto SDK.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 
 

545 lignes
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_