| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329 | 
							- #ifndef __GBLIBCPP_FUNCTIONAL__
 
- #define __GBLIBCPP_FUNCTIONAL__
 
- #include <bits/fwd_functional>
 
- #include <cstddef>
 
- #include <memory>
 
- #include <new>
 
- #include <utility>
 
- #include <type_traits>
 
- namespace std {
 
- template <typename Func, typename... Args>
 
- constexpr auto invoke(Func&& func, Args&&... args)
 
-     noexcept(std::is_nothrow_invocable_v<Func, Args...>)
 
-     -> std::enable_if_t<std::is_invocable_v<Func, Args...>,
 
-         std::invoke_result_t<Func, Args...>>
 
- {
 
-     return __helpers::INVOKE(std::forward<Func>(func), std::forward<Args>(args)...);
 
- }
 
- template <typename R, typename Func, typename... Args>
 
- constexpr auto invoke_r(Func&& func, Args&&... args)
 
-     noexcept(std::is_nothrow_invocable_r_v<R, Func, Args...>)
 
-     -> std::enable_if_t<std::is_invocable_r_v<R, Func, Args...>, R>
 
- {
 
-     return __helpers::INVOKE_R<R>(std::forward<Func>(func), std::forward<Args>(args)...);
 
- }
 
- namespace __helpers {
 
- template <typename T> constexpr void __reference_wrapper_check(T&) noexcept {}
 
- template <typename T> void __reference_wrapper_check(T&&) = delete;
 
- } // namespace __helpers
 
- template <typename T>
 
- class reference_wrapper {
 
- private:
 
-     T* _ptr;
 
-     template <typename Ref, typename =
 
-         decltype(__helpers::__reference_wrapper_check<T>(std::declval<Ref>()))>
 
-     struct __check_reference_valid
 
-         : public bool_constant<!std::is_same_v<reference_wrapper, std::decay_t<Ref>>> {};
 
- public:
 
-     using type = T;
 
-     constexpr T& get(void) const noexcept { return *_ptr; }
 
-     constexpr operator T&(void) const noexcept { return *_ptr; }
 
-     template <typename U, std::enable_if_t<__check_reference_valid<U>::value, bool> = true>
 
-     constexpr reference_wrapper(U&& ref)
 
-         noexcept(noexcept(__helpers::__reference_wrapper_check<T>(std::declval<U>())))
 
-         : _ptr(std::addressof(ref)) {}
 
-     constexpr reference_wrapper(const reference_wrapper& val) noexcept
 
-     {
 
-         _ptr = val._ptr;
 
-     }
 
-     constexpr reference_wrapper& operator=(const reference_wrapper& val) noexcept = default;
 
-     // TODO: std::invoke_result_t
 
-     template <typename... Args>
 
-     constexpr invoke_result_t<type&, Args...>
 
-     operator()(Args&&... args) const noexcept(is_nothrow_invocable_v<type&, Args...>)
 
-     {
 
-         return std::invoke(get(), std::forward<Args>(args)...);
 
-     }
 
- };
 
- template <typename T>
 
- reference_wrapper(T&) -> reference_wrapper<T>;
 
- namespace __inner {
 
-     template <typename Ret, typename... Args>
 
-     class _function_base {
 
-     public:
 
-         virtual constexpr ~_function_base() = default;
 
-         virtual constexpr Ret operator()(Args... args) const = 0;
 
-         virtual constexpr void copy_to(_function_base* func) = 0;
 
-         virtual constexpr void move_to(_function_base* func) = 0;
 
-         virtual explicit constexpr operator bool(void) const = 0;
 
-     };
 
-     template <typename FuncLike, typename Ret, typename... Args>
 
-     class _function : public _function_base<Ret, Args...> {
 
-     private:
 
-         using __enable = std::enable_if_t<
 
-             std::is_invocable_r_v<Ret, std::decay_t<FuncLike>, Args...>
 
-         >;
 
-         FuncLike func;
 
-     public:
 
-         constexpr _function(const FuncLike& _func) : func(_func) {}
 
-         constexpr _function(FuncLike&& _func) : func(std::move(_func)) {}
 
-         constexpr Ret operator()(Args... args) const override
 
-         {
 
-             return std::invoke(func, std::forward<Args>(args)...);
 
-         }
 
-         constexpr void copy_to(_function_base<Ret, Args...>* dst) override
 
-         {
 
-             new (reinterpret_cast<_function*>(dst)) _function(*this);
 
-         }
 
-         constexpr void move_to(_function_base<Ret, Args...>* dst) override
 
-         {
 
-             new (reinterpret_cast<_function*>(dst)) _function(std::move(*this));
 
-         }
 
-         constexpr explicit operator bool(void) const override
 
-         {
 
-             return true;
 
-         }
 
-     };
 
-     template <typename Ret, typename... Args>
 
-     class _function<nullptr_t, Ret, Args...> : public _function_base<Ret, Args...> {
 
-     public:
 
-         [[noreturn]] Ret operator()(Args...) const override
 
-         {
 
-             // TODO: exception
 
-             *((int*)(100^100)) = 1; // triggers access to null pointer
 
-             for (;;);
 
-         }
 
-         constexpr void copy_to(_function_base<Ret, Args...>* dst) override
 
-         {
 
-             new (reinterpret_cast<_function*>(dst)) _function(*this);
 
-         }
 
-         constexpr void move_to(_function_base<Ret, Args...>* dst) override
 
-         {
 
-             new (reinterpret_cast<_function*>(dst)) _function(std::move(*this));
 
-         }
 
-         constexpr explicit operator bool(void) const override
 
-         {
 
-             return false;
 
-         }
 
-     };
 
- } // namespace __inner
 
- template <typename Ret, typename... Args>
 
- class function<Ret(Args...)> {
 
- public:
 
-     using result_type = Ret;
 
- private:
 
-     static constexpr std::size_t STACK_ALLOCATED_SIZE = 24;
 
-     char _data[STACK_ALLOCATED_SIZE];
 
-     using fb_t = __inner::_function_base<Ret, Args...>;
 
-     constexpr fb_t* _f(void) const
 
-     {
 
-         return (fb_t*)_data;
 
-     }
 
-     constexpr void _clear(void)
 
-     {
 
-         _f()->~_function_base();
 
-     }
 
- public:
 
-     constexpr function() noexcept
 
-     {
 
-         new (_f()) __inner::_function<nullptr_t, Ret, Args...>();
 
-     }
 
-     constexpr function(nullptr_t) noexcept : function() {}
 
-     constexpr function(const function& func)
 
-     {
 
-         func._f()->copy_to(_f());
 
-     }
 
-     constexpr function(function&& func) noexcept
 
-     {
 
-         func._f()->move_to(_f());
 
-     }
 
-     template <typename FuncLike, std::enable_if_t
 
-         <
 
-             // TODO: check its behavior for nullptr
 
-             std::is_invocable_r_v<Ret, std::decay_t<FuncLike>, Args...>
 
-             && (sizeof(std::decay_t<FuncLike>) <= STACK_ALLOCATED_SIZE - sizeof(void*))
 
-             && !std::is_same_v<std::decay_t<FuncLike>, function>
 
-         , bool> = true
 
-     >
 
-     constexpr function(FuncLike&& func)
 
-     {
 
-         new (_f()) __inner::_function<std::decay_t<FuncLike>, Ret, Args...>(std::forward<FuncLike>(func));
 
-     }
 
-     constexpr ~function()
 
-     {
 
-         _clear();
 
-     }
 
-     constexpr Ret operator()(Args... args) const
 
-     {
 
-         return (*_f())(std::forward<Args>(args)...);
 
-     }
 
-     explicit operator bool(void) const noexcept
 
-     {
 
-         return !!*_f();
 
-     }
 
-     function& operator=(function&& rhs)
 
-     {
 
-         _clear();
 
-         rhs._f()->move_to(_f());
 
-         return *this;
 
-     }
 
-     void swap(function& other) noexcept
 
-     {
 
-         function tmp(std::move(other));
 
-         other = std::move(*this);
 
-         *this = std::move(tmp);
 
-     }
 
-     function& operator=(const function& rhs)
 
-     {
 
-         _clear();
 
-         rhs._f()->copy_to(_f());
 
-         return *this;
 
-     }
 
-     function& operator=(nullptr_t) noexcept
 
-     {
 
-         _clear();
 
-         new (_f()) __inner::_function<nullptr_t, Ret, Args...>();
 
-         return *this;
 
-     }
 
-     template <typename FuncLike, std::enable_if_t
 
-         <
 
-             std::is_same_v<
 
-                 Ret,
 
-                 decltype(std::declval<std::decay_t<FuncLike>>()(std::declval<Args>()...))
 
-             >
 
-             && (sizeof(std::decay_t<FuncLike>) <= sizeof(_data))
 
-             && !std::is_same_v<std::decay_t<FuncLike>, function>
 
-         , bool> = true
 
-     >
 
-     function& operator=(FuncLike&& func)
 
-     {
 
-         function{std::forward<FuncLike>(func)}.swap(*this);
 
-         return *this;
 
-     }
 
-     template <typename FuncLike>
 
-     function& operator=(std::reference_wrapper<FuncLike> func) noexcept
 
-     {
 
-         function{func}.swap(*this);
 
-         return *this;
 
-     }
 
- };
 
- template <typename Ret, typename... Args>
 
- bool operator==(const std::function<Ret(Args...)>& func, std::nullptr_t) noexcept
 
- {
 
-     return !func;
 
- }
 
- template <typename Ret, typename... Args>
 
- void swap(std::function<Ret(Args...)>& lhs, std::function<Ret(Args...)>& rhs) noexcept
 
- {
 
-     return lhs.swap(rhs);
 
- }
 
- template <typename T>
 
- constexpr std::reference_wrapper<T> ref(T& t) noexcept
 
- {
 
-     return std::reference_wrapper<T>((t));
 
- }
 
- template <typename T>
 
- constexpr std::reference_wrapper<T>
 
-     ref(std::reference_wrapper<T> t) noexcept
 
- {
 
-     return t;
 
- }
 
- template <typename T>
 
- constexpr std::reference_wrapper<const T> cref(const T& t) noexcept
 
- {
 
-     return std::reference_wrapper<const T>((t));
 
- }
 
- template <typename T>
 
- constexpr std::reference_wrapper<const T>
 
-     cref(std::reference_wrapper<T> t) noexcept
 
- {
 
-     return t;
 
- }
 
- // Comparators
 
- template <typename T = void>
 
- struct less {
 
-     constexpr bool operator()(const T& lhs, const T& rhs) const
 
-     { return lhs < rhs; }
 
- };
 
- template <>
 
- struct less<void> {
 
-     template <typename T, typename U>
 
-     constexpr auto operator()(T&& lhs, U&& rhs) const
 
-         -> decltype(std::forward<T>(lhs) < std::forward<U>(rhs))
 
-     { return std::forward<T>(lhs) < std::forward<U>(rhs); }
 
- };
 
- template <typename T = void>
 
- struct greater {
 
-     constexpr bool operator()(const T& lhs, const T& rhs) const
 
-     { return lhs > rhs; }
 
- };
 
- template <>
 
- struct greater<void> {
 
-     template <typename T, typename U>
 
-     constexpr auto operator()(T&& lhs, U&& rhs) const
 
-         -> decltype(std::forward<T>(lhs) > std::forward<U>(rhs))
 
-     { return std::forward<T>(lhs) > std::forward<U>(rhs); }
 
- };
 
- } // namespace std
 
- #endif
 
 
  |