functional 8.7 KB

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