functional 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  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_invocable_r_v<Ret, std::decay_t<FuncLike>, Args...>
  75. >;
  76. FuncLike func;
  77. public:
  78. constexpr _function(const FuncLike& _func) : func(_func) {}
  79. constexpr _function(FuncLike&& _func) : func(std::move(_func)) {}
  80. constexpr Ret operator()(Args... args) const override
  81. {
  82. return std::invoke(func, std::forward<Args>(args)...);
  83. }
  84. constexpr void copy_to(_function_base<Ret, Args...>* dst) override
  85. {
  86. new (reinterpret_cast<_function*>(dst)) _function(*this);
  87. }
  88. constexpr void move_to(_function_base<Ret, Args...>* dst) override
  89. {
  90. new (reinterpret_cast<_function*>(dst)) _function(std::move(*this));
  91. }
  92. constexpr explicit operator bool(void) const override
  93. {
  94. return true;
  95. }
  96. };
  97. template <typename Ret, typename... Args>
  98. class _function<nullptr_t, Ret, Args...> : public _function_base<Ret, Args...> {
  99. public:
  100. [[noreturn]] Ret operator()(Args...) const override
  101. {
  102. // TODO: exception
  103. *((int*)(100^100)) = 1; // triggers access to null pointer
  104. for (;;);
  105. }
  106. constexpr void copy_to(_function_base<Ret, Args...>* dst) override
  107. {
  108. new (reinterpret_cast<_function*>(dst)) _function(*this);
  109. }
  110. constexpr void move_to(_function_base<Ret, Args...>* dst) override
  111. {
  112. new (reinterpret_cast<_function*>(dst)) _function(std::move(*this));
  113. }
  114. constexpr explicit operator bool(void) const override
  115. {
  116. return false;
  117. }
  118. };
  119. } // namespace __inner
  120. template <typename Ret, typename... Args>
  121. class function<Ret(Args...)> {
  122. public:
  123. using result_type = Ret;
  124. private:
  125. static constexpr std::size_t STACK_ALLOCATED_SIZE = 12;
  126. char _data[STACK_ALLOCATED_SIZE];
  127. using fb_t = __inner::_function_base<Ret, Args...>;
  128. constexpr fb_t* _f(void) const
  129. {
  130. return (fb_t*)_data;
  131. }
  132. constexpr void _clear(void)
  133. {
  134. _f()->~_function_base();
  135. }
  136. public:
  137. constexpr function() noexcept
  138. {
  139. new (_f()) __inner::_function<nullptr_t, Ret, Args...>();
  140. }
  141. constexpr function(nullptr_t) noexcept : function() {}
  142. constexpr function(const function& func)
  143. {
  144. func._f()->copy_to(_f());
  145. }
  146. constexpr function(function&& func) noexcept
  147. {
  148. func._f()->move_to(_f());
  149. }
  150. template <typename FuncLike, std::enable_if_t
  151. <
  152. // TODO: check its behavior for nullptr
  153. std::is_invocable_r_v<Ret, std::decay_t<FuncLike>, Args...>
  154. && (sizeof(std::decay_t<FuncLike>) <= STACK_ALLOCATED_SIZE - sizeof(void*))
  155. && !std::is_same_v<std::decay_t<FuncLike>, function>
  156. , bool> = true
  157. >
  158. constexpr function(FuncLike&& func)
  159. {
  160. new (_f()) __inner::_function<std::decay_t<FuncLike>, Ret, Args...>(std::forward<FuncLike>(func));
  161. }
  162. constexpr ~function()
  163. {
  164. _clear();
  165. }
  166. constexpr Ret operator()(Args... args) const
  167. {
  168. return (*_f())(std::forward<Args>(args)...);
  169. }
  170. explicit operator bool(void) const noexcept
  171. {
  172. return !!*_f();
  173. }
  174. function& operator=(function&& rhs)
  175. {
  176. _clear();
  177. rhs._f()->move_to(_f());
  178. return *this;
  179. }
  180. void swap(function& other) noexcept
  181. {
  182. function tmp(std::move(other));
  183. other = std::move(*this);
  184. *this = std::move(tmp);
  185. }
  186. function& operator=(const function& rhs)
  187. {
  188. _clear();
  189. rhs._f()->copy_to(_f());
  190. return *this;
  191. }
  192. function& operator=(nullptr_t) noexcept
  193. {
  194. _clear();
  195. new (_f()) __inner::_function<nullptr_t, Ret, Args...>();
  196. return *this;
  197. }
  198. template <typename FuncLike, std::enable_if_t
  199. <
  200. std::is_same_v<
  201. Ret,
  202. decltype(std::declval<std::decay_t<FuncLike>>()(std::declval<Args>()...))
  203. >
  204. && (sizeof(std::decay_t<FuncLike>) <= sizeof(_data))
  205. && !std::is_same_v<std::decay_t<FuncLike>, function>
  206. , bool> = true
  207. >
  208. function& operator=(FuncLike&& func)
  209. {
  210. function{std::forward<FuncLike>(func)}.swap(*this);
  211. return *this;
  212. }
  213. template <typename FuncLike>
  214. function& operator=(std::reference_wrapper<FuncLike> func) noexcept
  215. {
  216. function{func}.swap(*this);
  217. return *this;
  218. }
  219. };
  220. template <typename Ret, typename... Args>
  221. bool operator==(const std::function<Ret(Args...)>& func, std::nullptr_t) noexcept
  222. {
  223. return !func;
  224. }
  225. template <typename Ret, typename... Args>
  226. void swap(std::function<Ret(Args...)>& lhs, std::function<Ret(Args...)>& rhs) noexcept
  227. {
  228. return lhs.swap(rhs);
  229. }
  230. template <typename T>
  231. constexpr std::reference_wrapper<T> ref(T& t) noexcept
  232. {
  233. return std::reference_wrapper<T>((t));
  234. }
  235. template <typename T>
  236. constexpr std::reference_wrapper<T>
  237. ref(std::reference_wrapper<T> t) noexcept
  238. {
  239. return t;
  240. }
  241. template <typename T>
  242. constexpr std::reference_wrapper<const T> cref(const T& t) noexcept
  243. {
  244. return std::reference_wrapper<const T>((t));
  245. }
  246. template <typename T>
  247. constexpr std::reference_wrapper<const T>
  248. cref(std::reference_wrapper<T> t) noexcept
  249. {
  250. return t;
  251. }
  252. // Comparators
  253. template <typename T = void>
  254. struct less {
  255. constexpr bool operator()(const T& lhs, const T& rhs) const
  256. { return lhs < rhs; }
  257. };
  258. template <>
  259. struct less<void> {
  260. template <typename T, typename U>
  261. constexpr auto operator()(T&& lhs, U&& rhs) const
  262. -> decltype(std::forward<T>(lhs) < std::forward<U>(rhs))
  263. { return std::forward<T>(lhs) < std::forward<U>(rhs); }
  264. };
  265. template <typename T = void>
  266. struct greater {
  267. constexpr bool operator()(const T& lhs, const T& rhs) const
  268. { return lhs > rhs; }
  269. };
  270. template <>
  271. struct greater<void> {
  272. template <typename T, typename U>
  273. constexpr auto operator()(T&& lhs, U&& rhs) const
  274. -> decltype(std::forward<T>(lhs) > std::forward<U>(rhs))
  275. { return std::forward<T>(lhs) > std::forward<U>(rhs); }
  276. };
  277. } // namespace std
  278. #endif