mijin2/source/mijin/memory/virtual_allocator.hpp

57 lines
1.7 KiB
C++

#pragma once
#if !defined(MIJIN_MEMORY_VIRTUAL_ALLOCATOR_HPP_INCLUDED)
#define MIJIN_MEMORY_VIRTUAL_ALLOCATOR_HPP_INCLUDED 1
#include "../internal/common.hpp"
#include "../util/annot.hpp"
namespace mijin
{
template<typename T>
class VirtualAllocator
{
public:
virtual ~VirtualAllocator() noexcept = default;
[[nodiscard]]
virtual owner_t<T*> allocate(std::size_t count) noexcept;
virtual void deallocate(owner_t<T*> ptr, std::size_t count) noexcept;
};
template<typename T, typename TImpl>
class WrappedVirtualAllocator : public VirtualAllocator<T>
{
private:
[[no_unique_address]] TImpl mImpl;
public:
explicit constexpr WrappedVirtualAllocator(TImpl impl = {}) MIJIN_NOEXCEPT_IF(std::is_nothrow_move_constructible_v<TImpl>)
: mImpl(std::move(impl)) {}
constexpr WrappedVirtualAllocator(const WrappedVirtualAllocator&) = default;
constexpr WrappedVirtualAllocator(WrappedVirtualAllocator&&) = default;
WrappedVirtualAllocator& operator=(const WrappedVirtualAllocator&) = default;
WrappedVirtualAllocator& operator=(WrappedVirtualAllocator&&) = default;
[[nodiscard]]
owner_t<T*> allocate(std::size_t count) noexcept override
{
return mImpl.allocate(count);
}
void deallocate(owner_t<T*> ptr, std::size_t count) noexcept override
{
mImpl.deallocate(ptr, count);
}
};
template<typename T>
WrappedVirtualAllocator<typename T::value_type, T> makeVirtualAllocator(T allocator) MIJIN_NOEXCEPT_IF(std::is_nothrow_move_constructible_v<T>)
{
return WrappedVirtualAllocator<typename T::value_type, T>(std::move(allocator));
}
} // namespace mijin
#endif // !defined(MIJIN_MEMORY_VIRTUAL_ALLOCATOR_HPP_INCLUDED)