mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-07-01 18:39:16 +00:00
Merge remote-tracking branch 'Kernel/master'
This commit is contained in:
254
Kernel/include_std/functional
Normal file
254
Kernel/include_std/functional
Normal file
@ -0,0 +1,254 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <types.h>
|
||||
#include <algorithm>
|
||||
#include <typeinfo>
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <typename T = void>
|
||||
struct equal_to
|
||||
{
|
||||
bool operator()(const T &lhs, const T &rhs) const
|
||||
{
|
||||
return lhs == rhs;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Key>
|
||||
struct hash
|
||||
{
|
||||
size_t operator()(const Key &key) const
|
||||
{
|
||||
#if defined(a64)
|
||||
static_assert(sizeof(uintptr_t) == sizeof(uint64_t));
|
||||
const uint64_t FNV_OFFSET_BASIS = 14695981039346656037ull;
|
||||
const uint64_t FNV_PRIME = 1099511628211ull;
|
||||
#elif defined(a32)
|
||||
static_assert(sizeof(uintptr_t) == sizeof(uint32_t));
|
||||
const uint32_t FNV_OFFSET_BASIS = 2166136261u;
|
||||
const uint32_t FNV_PRIME = 16777619u;
|
||||
#else
|
||||
#error "Unsupported architecture"
|
||||
#endif
|
||||
|
||||
const uint8_t *data = reinterpret_cast<const uint8_t *>(&key);
|
||||
const size_t size = sizeof(Key);
|
||||
uintptr_t hash = FNV_OFFSET_BASIS;
|
||||
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
hash ^= static_cast<uintptr_t>(data[i]);
|
||||
hash *= FNV_PRIME;
|
||||
}
|
||||
|
||||
return static_cast<size_t>(hash);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class reference_wrapper;
|
||||
|
||||
template <class>
|
||||
class function; /* undefined */
|
||||
|
||||
template <class R, class... Args>
|
||||
class function<R(Args...)>
|
||||
{
|
||||
private:
|
||||
class impl_base
|
||||
{
|
||||
public:
|
||||
virtual ~impl_base() = default;
|
||||
virtual R invoke(Args...) const = 0;
|
||||
#ifdef __GXX_RTTI
|
||||
virtual const std::type_info &target_type() const noexcept = 0;
|
||||
#endif
|
||||
virtual impl_base *clone() const = 0;
|
||||
};
|
||||
|
||||
template <class F>
|
||||
class impl : public impl_base
|
||||
{
|
||||
public:
|
||||
F _f;
|
||||
|
||||
template <class G>
|
||||
impl(G &&f)
|
||||
: _f(std::forward<G>(f))
|
||||
{
|
||||
}
|
||||
|
||||
R invoke(Args... args) const override
|
||||
{
|
||||
return _f(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
#ifdef __GXX_RTTI
|
||||
const std::type_info &target_type() const noexcept override
|
||||
{
|
||||
return typeid(F);
|
||||
}
|
||||
#endif
|
||||
|
||||
impl_base *clone() const override
|
||||
{
|
||||
return new impl<F>(_f);
|
||||
}
|
||||
};
|
||||
|
||||
impl_base *_ptr;
|
||||
|
||||
public:
|
||||
using result_type = R;
|
||||
|
||||
function() noexcept
|
||||
: _ptr(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
function(std::nullptr_t) noexcept
|
||||
: _ptr(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
function(const function &other)
|
||||
: _ptr(other._ptr)
|
||||
{
|
||||
}
|
||||
|
||||
function(function &&other) noexcept
|
||||
: _ptr(other._ptr)
|
||||
{
|
||||
other._ptr = nullptr;
|
||||
}
|
||||
|
||||
template <class F>
|
||||
function(F &&f)
|
||||
: _ptr(new impl<F>(std::forward<F>(f)))
|
||||
{
|
||||
}
|
||||
|
||||
~function()
|
||||
{
|
||||
delete _ptr;
|
||||
}
|
||||
|
||||
function &operator=(const function &other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
delete _ptr;
|
||||
_ptr = other._ptr ? other._ptr->clone() : nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
function &operator=(function &&other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
delete _ptr;
|
||||
_ptr = other._ptr;
|
||||
other._ptr = nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
function &operator=(std::nullptr_t) noexcept
|
||||
{
|
||||
delete _ptr;
|
||||
_ptr = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class F>
|
||||
function &operator=(F &&f)
|
||||
{
|
||||
delete _ptr;
|
||||
_ptr = new impl<F>(std::forward<F>(f));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class F>
|
||||
function &operator=(std::reference_wrapper<F> f) noexcept
|
||||
{
|
||||
delete _ptr;
|
||||
_ptr = new impl<std::reference_wrapper<F>>(f);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(function &other) noexcept
|
||||
{
|
||||
std::swap(_ptr, other._ptr);
|
||||
}
|
||||
|
||||
explicit operator bool() const noexcept
|
||||
{
|
||||
return _ptr != nullptr;
|
||||
}
|
||||
|
||||
R operator()(Args... args) const
|
||||
{
|
||||
return _ptr->invoke(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
#ifdef __GXX_RTTI
|
||||
const std::type_info &target_type() const noexcept
|
||||
{
|
||||
return _ptr ? _ptr->target_type() : typeid(void);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T *target() noexcept
|
||||
{
|
||||
return _ptr && _ptr->target_type() == typeid(T) ? &static_cast<impl<T> *>(_ptr)->_f : nullptr;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
const T *target() const noexcept
|
||||
{
|
||||
return _ptr && _ptr->target_type() == typeid(T) ? &static_cast<impl<T> *>(_ptr)->_f : nullptr;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <class R, class... Args>
|
||||
void swap(std::function<R(Args...)> &lhs, std::function<R(Args...)> &rhs) noexcept
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
|
||||
template <class R, class... ArgTypes>
|
||||
|
||||
bool operator==(const std::function<R(ArgTypes...)> &f, std::nullptr_t) noexcept
|
||||
{
|
||||
return !f;
|
||||
}
|
||||
|
||||
template <class T = void>
|
||||
struct less
|
||||
{
|
||||
constexpr bool operator()(const T &lhs, const T &rhs) const
|
||||
{
|
||||
return lhs < rhs;
|
||||
}
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user