functional 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. #ifndef __GBLIBCPP_FUNCTIONAL__
  2. #define __GBLIBCPP_FUNCTIONAL__
  3. #include <bits/fwd_functional>
  4. #include <cstddef>
  5. #include <memory>
  6. #include <new>
  7. #include <utility>
  8. #include <type_traits>
  9. namespace std {
  10. template <typename Func, typename... Args>
  11. constexpr auto invoke(Func&& func, Args&&... args)
  12. noexcept(std::is_nothrow_invocable_v<Func, Args...>)
  13. -> std::enable_if_t<std::is_invocable_v<Func, Args...>,
  14. std::invoke_result_t<Func, Args...>>
  15. {
  16. return __helpers::INVOKE(std::forward<Func>(func), std::forward<Args>(args)...);
  17. }
  18. namespace __helpers {
  19. template <typename T> constexpr void __reference_wrapper_check(T&) noexcept {}
  20. template <typename T> void __reference_wrapper_check(T&&) = delete;
  21. } // namespace __helpers
  22. template <typename T>
  23. class reference_wrapper {
  24. private:
  25. T* _ptr;
  26. template <typename Ref, typename =
  27. decltype(__helpers::__reference_wrapper_check<T>(std::declval<Ref>()))>
  28. struct __check_reference_valid
  29. : public bool_constant<!std::is_same_v<reference_wrapper, std::decay_t<Ref>>> {};
  30. public:
  31. using type = T;
  32. constexpr T& get(void) const noexcept { return *_ptr; }
  33. constexpr operator T&(void) const noexcept { return *_ptr; }
  34. template <typename U, std::enable_if_t<__check_reference_valid<U>::value, bool> = true>
  35. constexpr reference_wrapper(U&& ref)
  36. noexcept(noexcept(__helpers::__reference_wrapper_check<T>(std::declval<U>())))
  37. : _ptr(std::addressof(ref)) {}
  38. constexpr reference_wrapper(const reference_wrapper& val) noexcept
  39. {
  40. _ptr = val._ptr;
  41. }
  42. constexpr reference_wrapper& operator=(const reference_wrapper& val) noexcept = default;
  43. // TODO: std::invoke_result_t
  44. template <typename... Args>
  45. constexpr invoke_result_t<type&, Args...>
  46. operator()(Args&&... args) const noexcept(is_nothrow_invocable_v<type&, Args...>)
  47. {
  48. return std::invoke(get(), std::forward<Args>(args)...);
  49. }
  50. };
  51. template <typename T>
  52. reference_wrapper(T&) -> reference_wrapper<T>;
  53. namespace __inner {
  54. template <typename Ret, typename... Args>
  55. class _function_base {
  56. public:
  57. virtual constexpr ~_function_base() = default;
  58. virtual constexpr Ret operator()(Args... args) const = 0;
  59. virtual constexpr void copy_to(_function_base* func) = 0;
  60. virtual constexpr void move_to(_function_base* func) = 0;
  61. virtual explicit constexpr operator bool(void) const = 0;
  62. };
  63. template <typename FuncLike, typename Ret, typename... Args>
  64. class _function : public _function_base<Ret, Args...> {
  65. private:
  66. using __enable = std::enable_if_t<
  67. std::is_same_v<Ret,
  68. decltype(std::declval<std::decay_t<FuncLike>>()(std::declval<Args>()...))>
  69. >;
  70. FuncLike func;
  71. public:
  72. constexpr _function(const FuncLike& _func) : func(_func) {}
  73. constexpr _function(FuncLike&& _func) : func(std::move(_func)) {}
  74. constexpr Ret operator()(Args... args) const override
  75. {
  76. return std::invoke(func, std::forward<Args>(args)...);
  77. }
  78. constexpr void copy_to(_function_base<Ret, Args...>* dst) override
  79. {
  80. new (reinterpret_cast<_function*>(dst)) _function(*this);
  81. }
  82. constexpr void move_to(_function_base<Ret, Args...>* dst) override
  83. {
  84. new (reinterpret_cast<_function*>(dst)) _function(std::move(*this));
  85. }
  86. constexpr explicit operator bool(void) const override
  87. {
  88. return true;
  89. }
  90. };
  91. template <typename Ret, typename... Args>
  92. class _function<nullptr_t, Ret, Args...> : public _function_base<Ret, Args...> {
  93. public:
  94. [[noreturn]] Ret operator()(Args...) const override
  95. {
  96. // TODO: exception
  97. *((int*)(100^100)) = 1; // triggers access to null pointer
  98. for (;;);
  99. }
  100. constexpr void copy_to(_function_base<Ret, Args...>* dst) override
  101. {
  102. new (reinterpret_cast<_function*>(dst)) _function(*this);
  103. }
  104. constexpr void move_to(_function_base<Ret, Args...>* dst) override
  105. {
  106. new (reinterpret_cast<_function*>(dst)) _function(std::move(*this));
  107. }
  108. constexpr explicit operator bool(void) const override
  109. {
  110. return false;
  111. }
  112. };
  113. } // namespace __inner
  114. template <typename Ret, typename... Args>
  115. class function<Ret(Args...)> {
  116. public:
  117. using result_type = Ret;
  118. private:
  119. char _data[sizeof(void*) * 2];
  120. using fb_t = __inner::_function_base<Ret, Args...>;
  121. constexpr fb_t* _f(void) const
  122. {
  123. return (fb_t*)_data;
  124. }
  125. constexpr void _clear(void)
  126. {
  127. _f()->~_function_base();
  128. }
  129. public:
  130. constexpr function() noexcept
  131. {
  132. new (_f()) __inner::_function<nullptr_t, Ret, Args...>();
  133. }
  134. constexpr function(nullptr_t) noexcept : function() {}
  135. constexpr function(const function& func)
  136. {
  137. func._f()->copy_to(_f());
  138. }
  139. constexpr function(function&& func) noexcept
  140. {
  141. func._f()->move_to(_f());
  142. }
  143. template <typename FuncLike, std::enable_if_t
  144. <
  145. std::is_same_v<
  146. Ret,
  147. decltype(std::declval<std::decay_t<FuncLike>>()(std::declval<Args>()...))
  148. >
  149. && (sizeof(std::decay_t<FuncLike>) <= sizeof(_data))
  150. && !std::is_same_v<std::decay_t<FuncLike>, function>
  151. , bool> = true
  152. >
  153. constexpr function(FuncLike&& func)
  154. {
  155. new (_f()) __inner::_function<std::decay_t<FuncLike>, Ret, Args...>(std::forward<FuncLike>(func));
  156. }
  157. constexpr ~function()
  158. {
  159. _clear();
  160. }
  161. constexpr Ret operator()(Args... args) const
  162. {
  163. return (*_f())(std::forward<Args>(args)...);
  164. }
  165. explicit operator bool(void) const noexcept
  166. {
  167. return !!*_f();
  168. }
  169. function& operator=(function&& rhs)
  170. {
  171. _clear();
  172. rhs._f()->move_to(_f());
  173. return *this;
  174. }
  175. void swap(function& other) noexcept
  176. {
  177. function tmp(std::move(other));
  178. other = std::move(*this);
  179. *this = std::move(tmp);
  180. }
  181. function& operator=(const function& rhs)
  182. {
  183. _clear();
  184. rhs._f()->copy_to(_f());
  185. return *this;
  186. }
  187. function& operator=(nullptr_t) noexcept
  188. {
  189. _clear();
  190. new (_f()) __inner::_function<nullptr_t, Ret, Args...>();
  191. return *this;
  192. }
  193. template <typename FuncLike, std::enable_if_t
  194. <
  195. std::is_same_v<
  196. Ret,
  197. decltype(std::declval<std::decay_t<FuncLike>>()(std::declval<Args>()...))
  198. >
  199. && (sizeof(std::decay_t<FuncLike>) <= sizeof(_data))
  200. && !std::is_same_v<std::decay_t<FuncLike>, function>
  201. , bool> = true
  202. >
  203. function& operator=(FuncLike&& func)
  204. {
  205. function{std::forward<FuncLike>(func)}.swap(*this);
  206. return *this;
  207. }
  208. template <typename FuncLike>
  209. function& operator=(std::reference_wrapper<FuncLike> func) noexcept
  210. {
  211. function{func}.swap(*this);
  212. return *this;
  213. }
  214. };
  215. template <typename Ret, typename... Args>
  216. bool operator==(const std::function<Ret(Args...)>& func, std::nullptr_t) noexcept
  217. {
  218. return !func;
  219. }
  220. template <typename Ret, typename... Args>
  221. void swap(std::function<Ret(Args...)>& lhs, std::function<Ret(Args...)>& rhs) noexcept
  222. {
  223. return lhs.swap(rhs);
  224. }
  225. template <typename T>
  226. constexpr std::reference_wrapper<T> ref(T& t) noexcept
  227. {
  228. return std::reference_wrapper<T>((t));
  229. }
  230. template <typename T>
  231. constexpr std::reference_wrapper<T>
  232. ref(std::reference_wrapper<T> t) noexcept
  233. {
  234. return t;
  235. }
  236. template <typename T>
  237. constexpr std::reference_wrapper<const T> cref(const T& t) noexcept
  238. {
  239. return std::reference_wrapper<const T>((t));
  240. }
  241. template <typename T>
  242. constexpr std::reference_wrapper<const T>
  243. cref(std::reference_wrapper<T> t) noexcept
  244. {
  245. return t;
  246. }
  247. } // namespace std
  248. #endif