154 lines
3.7 KiB
Plaintext
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
|