update Allocator

This commit is contained in:
Nomango 2020-05-29 17:44:07 +08:00
parent 764b67d4d3
commit ee165a234f
3 changed files with 130 additions and 61 deletions

View File

@ -26,7 +26,7 @@ namespace kiwano
CanvasPtr Canvas::Create(const Size& size)
{
void* mem = memory::Alloc<Canvas>();
void* mem = memory::Alloc(sizeof(Canvas));
CanvasPtr ptr = ::new (mem) Canvas;
if (ptr)
{

View File

@ -27,6 +27,26 @@ namespace memory
MemoryAllocator* current_allocator_ = nullptr;
MemoryAllocator* GetGlobalAllocator()
{
class KGE_API GlobalAllocator : public MemoryAllocator
{
public:
virtual void* Alloc(size_t size) override
{
return ::operator new(size);
}
virtual void Free(void* ptr, size_t size) override
{
::operator delete(ptr, size);
}
};
static GlobalAllocator global_allocator;
return &global_allocator;
}
MemoryAllocator* GetAllocator()
{
if (!current_allocator_)
@ -42,22 +62,5 @@ void SetAllocator(MemoryAllocator* allocator)
current_allocator_ = allocator;
}
GlobalAllocator* GetGlobalAllocator()
{
static GlobalAllocator global_allocator;
return &global_allocator;
}
void* GlobalAllocator::Alloc(size_t size)
{
return ::malloc(size);
}
void GlobalAllocator::Free(void* ptr, size_t size)
{
KGE_NOT_USED(size);
::free(ptr);
}
} // namespace memory
} // namespace kiwano

View File

@ -19,8 +19,9 @@
// THE SOFTWARE.
#pragma once
#include <utility>
#include <type_traits>
#include <utility> // std::forward
#include <limits> // std::numeric_limits
#include <memory> // std::addressof
#include <kiwano/macros.h>
namespace kiwano
@ -52,29 +53,16 @@ void SetAllocator(MemoryAllocator* allocator);
/// \~chinese
/// @brief 使用当前内存分配器分配内存
template <typename _Ty>
inline void* Alloc()
inline void* Alloc(size_t size)
{
return memory::GetAllocator()->Alloc(sizeof(_Ty));
return memory::GetAllocator()->Alloc(size);
}
/// \~chinese
/// @brief 使用当前内存分配器释放内存
inline void Free(void* ptr, size_t size)
{
return memory::GetAllocator()->Free(ptr, size);
}
/// \~chinese
/// @brief 构造对象
template <typename _Ty>
inline _Ty* Construct(void* addr)
{
if (addr)
{
return ::new (addr) _Ty;
}
return nullptr;
memory::GetAllocator()->Free(ptr, size);
}
/// \~chinese
@ -93,25 +81,12 @@ inline void Destroy(_Ty* ptr)
ptr->~_Ty();
}
/// \~chinese
/// @brief 使用当前内存分配器创建对象
template <typename _Ty>
inline _Ty* New()
{
void* ptr = memory::Alloc<_Ty>();
if (ptr)
{
return memory::Construct<_Ty>(ptr);
}
return nullptr;
}
/// \~chinese
/// @brief 使用当前内存分配器创建对象
template <typename _Ty, typename... _Args>
inline _Ty* New(_Args&&... args)
{
void* ptr = memory::Alloc<_Ty>();
void* ptr = memory::Alloc(sizeof(_Ty));
if (ptr)
{
return memory::Construct<_Ty>(ptr, std::forward<_Args>(args)...);
@ -131,23 +106,114 @@ inline void Delete(_Ty* ptr)
}
}
/// \~chinese
/// @brief 全局内存分配器使用malloc和free分配内存
class KGE_API GlobalAllocator : public MemoryAllocator
/// @brief ·ÖÅäÆ÷
template <typename _Ty>
class Allocator
{
public:
/// \~chinese
/// @brief 申请内存
virtual void* Alloc(size_t size) override;
typedef _Ty value_type;
typedef _Ty* pointer;
typedef const _Ty* const_pointer;
typedef _Ty& reference;
typedef const _Ty& const_reference;
/// \~chinese
/// @brief 释放内存
virtual void Free(void* ptr, size_t size) override;
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* ptr, _Args&&... args)
{
memory::Construct<_UTy>(ptr, std::forward<_Args>(args)...);
}
template <typename _UTy>
inline void destroy(_UTy* ptr)
{
memory::Destroy<_UTy>(ptr);
}
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);
}
};
/// \~chinese
/// @brief 获取全局内存分配器
GlobalAllocator* GetGlobalAllocator();
// 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;
}
} // namespace memory
} // namespace kiwano