53 template <
typename TYPE>
62 template <
typename TYPE>
83 template<
typename TYPE,
template <
typename>
typename DERIVED>
95 template <
typename O_TYPE>
135 template<
typename O_TYPE>
152 template<
typename TYPE>
201 template<
typename TYPE>
212 freeChunk* next =
nullptr;
219 class allocatedChunks {
221 void* chunks =
nullptr;
222 allocatedChunks* next =
nullptr;
232 static constexpr u_integer CHUNK_SIZE =
sizeof(
TYPE) >
sizeof(freeChunk*) ?
sizeof(
TYPE) :
sizeof(freeChunk*);
237 freeChunk** free_list_head;
238 allocatedChunks* allocated_list_head;
275 void release()
noexcept;
358 template<
typename TYPE>
362template<
typename TYPE>
369 return static_cast<TYPE*
>(
operator new(size *
sizeof(
TYPE)));
370 }
catch (
const std::bad_alloc&) {
375template<
typename TYPE>
377 ::operator
delete(ptr);
380template <
typename TYPE,
template <
typename>
typename DERIVED>
386template<
typename TYPE,
template <
typename>
typename DERIVED>
389template<
typename TYPE,
template <
typename>
typename DERIVED>
395template<
typename TYPE,
template <
typename>
typename DERIVED>
396template<
typename O_TYPE>
401template<
typename TYPE>
403 return allocators::malloc<TYPE>(size);
406template<
typename TYPE>
411template<
typename TYPE>
415 while (
static_cast<u_integer>(1) << index < size) {
421template<
typename TYPE>
423 this->chunk_count = allocators::malloc<u_integer>(this->size_class_count);
424 this->free_list_head = allocators::malloc<freeChunk*>(this->size_class_count);
425 this->chunks_available = allocators::malloc<u_integer>(this->size_class_count);
426 this->allocated_list_head =
nullptr;
428 for (u_integer i = 0; i < this->size_class_count; i++) {
429 this->chunk_count[i] = this->chunk_count_init;
430 this->free_list_head[i] =
nullptr;
431 this->chunks_available[i] = 0;
435template <
typename TYPE>
438 const u_integer block_size = (1 << index) * CHUNK_SIZE;
439 auto new_free_chunk = allocators::malloc<byte>(num_element * block_size);
440 auto new_allocated_chunk = allocators::malloc<allocatedChunks>(1);
442 new_allocated_chunk->chunks = new_free_chunk;
443 new_allocated_chunk->next = this->allocated_list_head;
444 this->allocated_list_head = new_allocated_chunk;
446 for (u_integer i = 0; i < num_element; i++)
448 auto cur_ptr =
reinterpret_cast<freeChunk*
>(new_free_chunk + i * block_size);
449 cur_ptr->next = this->free_list_head[index];
450 this->free_list_head[index] = cur_ptr;
452 this->chunks_available[index] += num_element;
453 this->chunk_count[index] = this->chunk_count[index] + (this->chunk_count[index] >> 1);
456template<
typename TYPE>
458 while (this->allocated_list_head) {
459 auto next_chunk = this->allocated_list_head->next;
462 this->allocated_list_head = next_chunk;
465 if (this->chunk_count) {
467 this->chunk_count =
nullptr;
469 if (this->free_list_head) {
471 this->free_list_head =
nullptr;
473 if (this->chunks_available) {
475 this->chunks_available =
nullptr;
479template <
typename TYPE>
481 : size_class_count(size_class_count), chunk_count_init(
count), chunk_count(
nullptr),
486template<
typename TYPE>
532 this->allocated_list_head =
nullptr;
533 other.allocated_list_head =
nullptr;
549template<
typename TYPE>
551 this->operator=(std::move(
other));
554template<
typename TYPE>
561 this->size_class_count =
other.size_class_count;
562 this->chunk_count_init =
other.chunk_count_init;
563 this->chunk_count =
other.chunk_count;
564 this->free_list_head =
other.free_list_head;
565 this->allocated_list_head =
other.allocated_list_head;
566 this->chunks_available =
other.chunks_available;
572template <
typename TYPE>
586template <
typename TYPE>
595 if (index >= this->size_class_count) {
596 return allocators::malloc<TYPE>(size);
599 if (!this->free_list_head[index] || this->chunks_available[index] * (
static_cast<u_integer>(1) << index) < size) {
603 auto cur_ptr = this->free_list_head[index];
604 this->free_list_head[index] = this->free_list_head[index]->next;
605 this->chunks_available[index] -= 1;
609template <
typename TYPE>
618 if (index >= this->size_class_count) {
623 auto p =
reinterpret_cast<freeChunk*
>(ptr);
624 p->next = this->free_list_head[index];
625 this->free_list_head[index] = p;
626 this->chunks_available[index] += 1;
629template<
typename TYPE>
634template <
typename TYPE>
Exception for memory allocation failures.
Definition error.h:385
Interface for other memory allocator implementations.
Definition allocator.h:84
std::false_type propagate_on_container_swap
No propagation on swap.
Definition allocator.h:88
std::false_type propagate_on_container_copy_assignment
No propagation on copy.
Definition allocator.h:86
virtual ~allocatorBase()=0
Virtual destructor.
std::false_type propagate_on_container_move_assignment
No propagation on move.
Definition allocator.h:87
void construct(O_TYPE *o_ptr, Args &&... args)
Constructs an object in allocated memory.
Definition allocator.h:391
constexpr allocatorBase()
Constructs a new allocatorBase instance.
Definition allocator.h:381
static void destroy(O_TYPE *o_ptr)
Destroys an object without deallocating.
Definition allocator.h:397
virtual void deallocate(TYPE *ptr, u_integer size)=0
Deallocates memory.
virtual TYPE * allocate(u_integer size)=0
Allocates raw memory.
std::false_type propagate_on_container_merge
No propagation on merge.
Definition allocator.h:89
Default memory allocator using allocators utilities.
Definition allocator.h:153
void deallocate(TYPE *ptr, u_integer size) override
Deallocates memory using global operator delete.
Definition allocator.h:407
TYPE * allocate(u_integer size) override
Allocates memory using global operator new.
Definition allocator.h:402
Utility class providing static memory allocation/de-allocation functions.
Definition allocator.h:42
static TYPE * malloc(u_integer size)
Allocates raw memory using global operator new.
Definition allocator.h:363
static void free(TYPE *ptr)
Deallocates memory using global operator delete.
Definition allocator.h:376
void swap(autoPtr &other) noexcept
Swaps the reference counters between two autoPtr instances.
Definition autoPtr.h:703
Object pool allocator for efficient fixed-size memory management.
Definition allocator.h:203
objPoolAllocator & operator+=(objPoolAllocator &other)
Merges another pool allocator into this one.
Definition allocator.h:487
objPoolAllocator(const objPoolAllocator &)=delete
Copy construction disabled.
TYPE * allocate(u_integer size) override
Allocates memory from the pool.
Definition allocator.h:587
std::true_type propagate_on_container_swap
Allows propagation on swap.
Definition allocator.h:280
void deallocate(TYPE *ptr, u_integer size) override
Returns memory to the pool.
Definition allocator.h:610
std::true_type propagate_on_container_move_assignment
Allows propagation on move.
Definition allocator.h:279
objPoolAllocator(u_integer size_class_count=8, u_integer count=4)
Constructs a new object pool allocator.
Definition allocator.h:480
void swap(objPoolAllocator &other) noexcept
Swaps the contents of two allocators.
Definition allocator.h:573
std::true_type propagate_on_container_merge
Allows propagation on merge.
Definition allocator.h:281
~objPoolAllocator() override
Destructor - releases all allocated memory.
Definition allocator.h:630
objPoolAllocator & operator=(const objPoolAllocator &)=delete
Copy assignment disabled.
Unique ownership smart pointer with move semantics.
Definition ownerPtr.h:37
Compile-time error triggering utility.
Definition error.h:167
Platform-independent type definitions and compiler/platform detection.
Custom exception classes and callback validation utilities.
Mathematical utilities, constants, and range generators.
Main namespace for the project Original.
Definition algorithms.h:21
auto count()
Creates a count pipe operation.
Definition generators.h:957
TYPE maximum(TYPE a, TYPE b)
Returns the larger of two given values.
Standard namespace extensions for original::alternative.
Definition allocator.h:351
void swap(original::objPoolAllocator< TYPE > &lhs, original::objPoolAllocator< TYPE > &rhs) noexcept
Specialization of std::swap for objPoolAllocator.
Definition allocator.h:635