SwitchGame/source/Tool/Allocator.h

151 lines
3.1 KiB
C++

#pragma once
#include <limits>
#include <cstddef>
#include <utility>
namespace memory
{
/// \~chinese
/// @brief 内存分配器
class MemoryAllocator
{
public:
/// \~chinese
/// @brief 申请内存
virtual void *Alloc(size_t size) = 0;
/// \~chinese
/// @brief 释放内存
virtual void Free(void *ptr) = 0;
};
/// \~chinese
/// @brief 获取当前内存分配器
MemoryAllocator *GetAllocator();
/// \~chinese
/// @brief 设置当前内存分配器
void SetAllocator(MemoryAllocator *allocator);
/// \~chinese
/// @brief 使用当前内存分配器分配内存
inline void *Alloc(size_t size)
{
return memory::GetAllocator()->Alloc(size);
}
/// \~chinese
/// @brief 使用当前内存分配器释放内存
inline void Free(void *ptr)
{
memory::GetAllocator()->Free(ptr);
}
} // namespace memory
/// \~chinese
/// @brief 分配器
template <typename _Ty>
class Allocator
{
public:
typedef _Ty value_type;
typedef _Ty *pointer;
typedef const _Ty *const_pointer;
typedef _Ty &reference;
typedef const _Ty &const_reference;
using size_type = size_t;
using difference_type = ptrdiff_t;
template <class _Other>
struct rebind
{
using other = Allocator<_Other>;
};
Allocator() noexcept {}
Allocator(const Allocator &) noexcept = default;
template <class _Other>
Allocator(const Allocator<_Other> &) noexcept
{
}
inline _Ty *allocate(size_t count)
{
if (count > 0)
{
return static_cast<_Ty *>(memory::Alloc(sizeof(_Ty) * count));
}
return nullptr;
}
inline void *allocate(size_t count, const void *)
{
return allocate(count);
}
inline void deallocate(void *ptr, size_t count)
{
memory::Free(ptr /*, sizeof(_Ty) * count */);
}
template <typename _UTy, typename... _Args>
inline void construct(_UTy *const ptr, _Args &&...args)
{
::new (const_cast<void *>(static_cast<const volatile void *>(ptr))) _Ty(std::forward<_Args>(args)...);
}
template <typename _UTy>
inline void destroy(_UTy *ptr)
{
ptr->~_UTy();
}
size_t max_size() const noexcept
{
return std::numeric_limits<size_t>::max() / sizeof(_Ty);
}
_Ty *address(_Ty &val) const noexcept
{
return std::addressof(val);
}
const _Ty *address(const _Ty &val) const noexcept
{
return std::addressof(val);
}
};
// Allocator<void>
template <>
class Allocator<void>
{
public:
using value_type = void;
typedef void *pointer;
typedef const void *const_pointer;
using size_type = size_t;
using difference_type = ptrdiff_t;
template <class _Other>
struct rebind
{
using other = Allocator<_Other>;
};
};
template <class _Ty, class _Other>
bool operator==(const Allocator<_Ty> &, const Allocator<_Other> &) noexcept
{
return true;
}
template <class _Ty, class _Other>
bool operator!=(const Allocator<_Ty> &, const Allocator<_Other> &) noexcept
{
return false;
}