Files
Custom-Operating-System/libs/libcxx/include/functional

154 lines
3.7 KiB
Plaintext

#pragma GCC system_header
#ifndef _LIBCXX_FUNCTIONAL
#define _LIBCXX_FUNCTIONAL
#include <__config>
#include <memory>
_LIBCXX_BEGIN_NAMESPACE_STD
template <typename>
class function;
template <typename R, typename... Args>
class function<R(Args...)> {
public:
using result_type = R;
function() = default;
function(std::nullptr_t) { }
template <typename Functor>
function(Functor f)
: m_constructor(reinterpret_cast<_constructor>(construct_functor<Functor>))
, m_destroyer(reinterpret_cast<_destroyer>(destroy_functor<Functor>))
, m_invoker(reinterpret_cast<_invoker>(invoke_functor<Functor>))
, m_functor_size(sizeof(Functor))
{
m_functor.reset(m_allocator.allocate(m_functor_size));
m_constructor(m_functor.get(), &f);
}
function(const function& other)
: m_constructor(other.m_constructor)
, m_destroyer(other.m_destroyer)
, m_invoker(other.m_invoker)
, m_functor_size(other.m_functor_size)
{
if (m_invoker && m_functor_size) {
m_functor.reset(m_allocator.allocate(m_functor_size));
m_constructor(m_functor.get(), other.m_functor.get());
}
}
function& operator=(const function& other)
{
m_constructor = other.m_constructor;
m_destroyer = other.m_destroyer;
m_invoker = other.m_invoker;
m_functor_size = other.m_functor_size;
if (m_invoker && m_functor_size) {
m_functor.reset(m_allocator.allocate(m_functor_size));
m_constructor(m_functor.get(), other.m_functor.get());
}
return *this;
}
~function()
{
if (m_functor) {
m_destroyer(m_functor.get());
}
}
result_type operator()(Args&&... args)
{
return m_invoker(m_functor.get(), std::forward<Args>(args)...);
}
operator bool() { return !!m_functor; }
private:
using _alloc_type = char;
using _invoker = R (*)(void*, Args&&...);
using _constructor = void (*)(void*, void*);
using _destroyer = void (*)(void*);
template <typename Functor>
static void construct_functor(Functor* at, Functor* other)
{
construct_at(at, *other);
}
template <typename Functor>
static void destroy_functor(Functor* p)
{
destroy_at(p);
}
template <typename Functor>
static result_type invoke_functor(Functor* functor, Args&&... args)
{
return (*functor)(std::forward<Args>(args)...);
}
_invoker m_invoker { nullptr };
_constructor m_constructor { nullptr };
_destroyer m_destroyer { nullptr };
std::unique_ptr<_alloc_type> m_functor { nullptr };
size_t m_functor_size { 0 };
std::allocator<_alloc_type> m_allocator {};
};
template <class T = void>
struct less {
constexpr bool operator()(const T& lhs, const T& rhs) const
{
return lhs < rhs;
}
};
template <class T = void>
struct greater {
constexpr bool operator()(const T& lhs, const T& rhs) const
{
return lhs > rhs;
}
};
template <class T = void>
struct equal_to {
constexpr bool operator()(const T& lhs, const T& rhs) const
{
return lhs == rhs;
}
};
template <class T = void>
struct less_equal {
constexpr bool operator()(const T& lhs, const T& rhs) const
{
return lhs <= rhs;
}
};
template <class T = void>
struct greater_equal {
constexpr bool operator()(const T& lhs, const T& rhs) const
{
return lhs >= rhs;
}
};
template <class T = void>
struct not_equal_to {
constexpr bool operator()(const T& lhs, const T& rhs) const
{
return lhs != rhs;
}
};
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX_FUNCTIONAL