#pragma once #include namespace AL { template struct BoostPool { static constexpr unsigned PageSize = 1 << PageSize_PowOf2, PagesInChunk = 1 << CountPageInChunk_PowOf2, ChunkSize = PageSize << CountPageInChunk_PowOf2; using Page = std::array; using Allocator = boost::fast_pool_allocator; using SingletonPool = boost::singleton_pool; using vector = std::vector; template class Array { void *Ptr = nullptr; public: Array() { Ptr = SingletonPool::ordered_malloc(PagesNum); } ~Array() { if(Ptr) SingletonPool::ordered_free(Ptr, PagesNum); } Array(const Array &array) { Ptr = SingletonPool::ordered_malloc(PagesNum); std::copy((const std::byte*) array.Ptr, (const std::byte*) array.Ptr + PageSize*PagesNum, (std::byte*) Ptr); } Array(Array &&pages) { Ptr = pages.Ptr; pages.Ptr = nullptr; } Array& operator=(const Array &pages) { if(this == &pages) return *this; std::copy((const std::byte*) pages.Ptr, (const std::byte*) pages.Ptr + PageSize*PagesNum, (std::byte*) Ptr); return *this; } Array& operator=(Array &&pages) { if(this == &pages) return *this; std::swap(Ptr, pages.Ptr); return *this; } std::byte* data() { return (std::byte*) Ptr; } const std::byte* data() const { return (std::byte*) Ptr; } constexpr size_t size() const { return PageSize*PagesNum; } std::byte& front() { return *(std::byte*) Ptr; } const std::byte& front() const { return *(const std::byte*) Ptr; } std::byte& back() { return *((std::byte*) Ptr + size()); } const std::byte& back() const { return *((const std::byte*) Ptr + size()); } std::byte& operator[](size_t index) { return ((std::byte*) Ptr)[index]; } const std::byte& operator[](size_t index) const { return ((const std::byte*) Ptr)[index]; } }; class PagePtr { void *Ptr = nullptr; public: PagePtr() { Ptr = SingletonPool::malloc(); } ~PagePtr() { if(Ptr) SingletonPool::free(Ptr); } PagePtr(const PagePtr &array) { Ptr = SingletonPool::malloc(); std::copy((const std::byte*) array.Ptr, (const std::byte*) array.Ptr + PageSize, (std::byte*) Ptr); } PagePtr(PagePtr &&pages) { Ptr = pages.Ptr; pages.Ptr = nullptr; } PagePtr& operator=(const PagePtr &pages) { if(this == &pages) return *this; std::copy((const std::byte*) pages.Ptr, (const std::byte*) pages.Ptr + PageSize, (std::byte*) Ptr); return *this; } PagePtr& operator=(PagePtr &&pages) { if(this == &pages) return *this; std::swap(Ptr, pages.Ptr); return *this; } std::byte* data() { return (std::byte*) Ptr; } const std::byte* data() const { return (std::byte*) Ptr; } constexpr size_t size() const { return PageSize; } std::byte& front() { return *(std::byte*) Ptr; } const std::byte& front() const { return *(const std::byte*) Ptr; } std::byte& back() { return *((std::byte*) Ptr + size()); } const std::byte& back() const { return *((const std::byte*) Ptr + size()); } std::byte& operator[](size_t index) { return ((std::byte*) Ptr)[index]; } const std::byte& operator[](size_t index) const { return ((const std::byte*) Ptr)[index]; } }; }; }