151 lines
3.1 KiB
C++
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;
|
|
} |