From 29f21d84d84fc3cafb0ccae86dc57ce2357a9ace Mon Sep 17 00:00:00 2001 From: Medusa Slockbower Date: Fri, 30 May 2025 23:33:15 -0400 Subject: [PATCH] Documentation for fennec::allocation --- include/fennec/containers/dynarray.h | 14 +++++ include/fennec/memory/allocator.h | 89 +++++++++++++++++++++++----- 2 files changed, 88 insertions(+), 15 deletions(-) diff --git a/include/fennec/containers/dynarray.h b/include/fennec/containers/dynarray.h index b6a0e52..5acb43d 100644 --- a/include/fennec/containers/dynarray.h +++ b/include/fennec/containers/dynarray.h @@ -30,11 +30,25 @@ #ifndef FENNEC_CONTAINERS_DYNARRAY_H #define FENNEC_CONTAINERS_DYNARRAY_H +#include namespace fennec { +template +class dynarray +{ +public: + using element_t = T; + using alloc_t = Alloc; + dynarray() : _alloc(), _size(0) {} + dynarray() + +private: + allocation _alloc; + size_t _size; +}; } diff --git a/include/fennec/memory/allocator.h b/include/fennec/memory/allocator.h index 12291dc..0aab02f 100644 --- a/include/fennec/memory/allocator.h +++ b/include/fennec/memory/allocator.h @@ -158,22 +158,59 @@ public: /// /// \brief Container to hold an allocation /// \tparam T The data type of the allocation +/// +/// \details This simply acts as a proxy for allocating memory. It does not call any constructors or +/// initialize any values as if they were the provided data type. Any operations present work +/// only on individual bytes. template class allocation { public: - // TODO: Document + /// \brief alias for the allocator type + using alloc_t = typename allocator_traits::template rebind; - using alloc_t = typename allocator_traits::template rebind; - using element_t = T; - using size_t = size_t; - using diff_t = ptrdiff_t; + /// \brief alias for the data type + using value_t = T; - allocation() : _data(nullptr), _capacity(0) {} - allocation(size_t n) : _data(_alloc.al), _capacity(n) {} - ~allocation() { if (_data) _alloc.deallocate(_data); } + /// \brief size type definition for ptr_traits + using size_t = size_t; - void allocate(size_t n) + /// \brief diff type definition for ptr_traits + using diff_t = ptrdiff_t; + + /// + /// \brief Default Constructor, initializes internal data to `null` and the capacity to `0` + constexpr allocation() noexcept : _data(nullptr), _capacity(0) {} + + /// + /// \brief Sized Constructor, initializes the allocation with a block of size `n * sizeof(T)` bytes + /// \param n The number of elements of type `T` to allocate for + constexpr allocation(size_t n) noexcept : _data(_alloc.al), _capacity(n) {} + + /// + /// \brief Allocator Constructor + /// \param alloc The allocation object to copy. + /// + /// \details This constructor should be used when the type `AllocT` needs internal data. + constexpr allocation(const alloc_t& alloc) noexcept : _alloc(alloc), _data(nullptr), _capacity(0) {} + + /// + /// \brief Sized Allocator Constructor + /// \param n The number of elements of type `T` to allocate for + /// \param alloc The allocation object to copy. + /// + /// \details This constructor should be used when the type `AllocT` needs internal data. + constexpr allocation(size_t n, const alloc_t& alloc) noexcept : _alloc(alloc), _data(nullptr), _capacity(0) {} + + /// + /// \brief Default Destructor, releases the memory block if still present + constexpr ~allocation() noexcept { if (_data) _alloc.deallocate(_data); } + + /// + /// \brief Allocate a block of memory for the allocation. + /// If there is already an allocated block of memory, the previous allocation is released. + /// \param n The number of elements of type `T` to allocate for + constexpr void allocate(size_t n) noexcept { if (_data) _alloc.deallocate(_data); @@ -181,7 +218,9 @@ public: _data = alloc_t::allocate(_capacity = n); } - void release() + /// + /// \brief Release the block of memory. + constexpr void release() noexcept { if (_data) _alloc.deallocate(_data); @@ -189,22 +228,42 @@ public: _capacity = 0; } - void reallocate(size_t n) + /// + /// \brief Reallocate the block with a new size. + /// Contents are copied to the new allocation. + constexpr void reallocate(size_t n) noexcept { if (_data == nullptr) return _alloc.allocate(_capacity = n); - element_t* old = _data; + value_t* old = _data; _data = alloc_t::allocate(n); fennec::memcpy(_data, old, min(_capacity, n) * sizeof(T)); _alloc.deallocate(old); _capacity = n; } + /// + /// \brief Clear the block of memory, setting all bytes to 0. + constexpr void clear() noexcept + { + fennec::memset(_data, 0, _capacity * sizeof(T)); + } + + /// + /// \brief Getter for the byte size of the allocation. + /// \returns the size of the allocation in bytes + constexpr size_t size() const { return _capacity * sizeof(T); } + + /// + /// \brief Getter for the number of elements `n` of type `T` that the allocation can hold. + /// \return the size of the allocation in elements + constexpr size_t capacity() const { return _capacity; } + private: - alloc_t _alloc; - element_t* _data; - size_t _capacity; + alloc_t _alloc; // Allocator object + value_t* _data; // Handle for the memory block + size_t _capacity; // Capacity of the memory block in elements. }; }