diff --git a/src/kiwano/2d/Canvas.cpp b/src/kiwano/2d/Canvas.cpp index aa9a0694..1cbbd781 100644 --- a/src/kiwano/2d/Canvas.cpp +++ b/src/kiwano/2d/Canvas.cpp @@ -26,7 +26,7 @@ namespace kiwano CanvasPtr Canvas::Create(const Size& size) { - void* mem = memory::Alloc(); + void* mem = memory::Alloc(sizeof(Canvas)); CanvasPtr ptr = ::new (mem) Canvas; if (ptr) { diff --git a/src/kiwano/core/Allocator.cpp b/src/kiwano/core/Allocator.cpp index aa9ee47b..2fe02281 100644 --- a/src/kiwano/core/Allocator.cpp +++ b/src/kiwano/core/Allocator.cpp @@ -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 diff --git a/src/kiwano/core/Allocator.h b/src/kiwano/core/Allocator.h index ff4980f6..e733a963 100644 --- a/src/kiwano/core/Allocator.h +++ b/src/kiwano/core/Allocator.h @@ -19,8 +19,9 @@ // THE SOFTWARE. #pragma once -#include -#include +#include // std::forward +#include // std::numeric_limits +#include // std::addressof #include namespace kiwano @@ -52,29 +53,16 @@ void SetAllocator(MemoryAllocator* allocator); /// \~chinese /// @brief 使用当前内存分配器分配内存 -template -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 -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 -inline _Ty* New() -{ - void* ptr = memory::Alloc<_Ty>(); - if (ptr) - { - return memory::Construct<_Ty>(ptr); - } - return nullptr; -} - /// \~chinese /// @brief 使用当前内存分配器创建对象 template 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 +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 + struct rebind + { + using other = Allocator<_Other>; + }; + + Allocator() noexcept {} + + Allocator(const Allocator&) noexcept = default; + + template + 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 + inline void construct(_UTy* ptr, _Args&&... args) + { + memory::Construct<_UTy>(ptr, std::forward<_Args>(args)...); + } + + template + inline void destroy(_UTy* ptr) + { + memory::Destroy<_UTy>(ptr); + } + + size_t max_size() const noexcept + { + return std::numeric_limits::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 +template <> +class Allocator +{ +public: + using value_type = void; + typedef void* pointer; + typedef const void* const_pointer; + + using size_type = size_t; + using difference_type = ptrdiff_t; + + template + struct rebind + { + using other = Allocator<_Other>; + }; +}; + +template +bool operator==(const Allocator<_Ty>&, const Allocator<_Other>&) noexcept +{ + return true; +} + +template +bool operator!=(const Allocator<_Ty>&, const Allocator<_Other>&) noexcept +{ + return false; +} } // namespace memory } // namespace kiwano