KTL
Loading...
Searching...
No Matches
stack_allocator.h
Go to the documentation of this file.
1#pragma once
2
3#include "../utility/alignment.h"
5#include "type_allocator.h"
6
7#include <memory>
8#include <type_traits>
9
10namespace ktl
11{
15 template<size_t Size>
16 struct stack
17 {
18 alignas(detail::ALIGNMENT) char Data[Size];
19 char* Free;
21
22 stack() noexcept :
23 Data{},
24 Free(Data),
25 ObjectCount(0) {}
26 };
27
34 template<size_t Size>
36 {
37 public:
38 explicit stack_allocator(stack<Size>& block) noexcept :
39 m_Block(&block) {}
40
41 explicit stack_allocator(stack<Size>* block) noexcept
42 : m_Block(block) {}
43
44 stack_allocator(const stack_allocator&) noexcept = default;
45
46 stack_allocator(stack_allocator&&) noexcept = default;
47
48 stack_allocator& operator=(const stack_allocator&) noexcept = default;
49
50 stack_allocator& operator=(stack_allocator&&) noexcept = default;
51
52 bool operator==(const stack_allocator& rhs) const noexcept
53 {
54 return m_Block == rhs.m_Block;
55 }
56
57 bool operator!=(const stack_allocator& rhs) const noexcept
58 {
59 return m_Block != rhs.m_Block;
60 }
61
62#pragma region Allocation
63 void* allocate(size_t n) noexcept
64 {
65 size_t totalSize = n + detail::align_to_architecture(n);
66
67 if ((size_t(m_Block->Free - m_Block->Data) + totalSize) > Size)
68 return nullptr;
69
70 char* current = m_Block->Free;
71
72 m_Block->Free += totalSize;
73 m_Block->ObjectCount += totalSize;
74
75 return current;
76 }
77
78 void deallocate(void* p, size_t n) noexcept
79 {
80 size_t totalSize = n + detail::align_to_architecture(n);
81
82 if (m_Block->Free - totalSize == p)
83 m_Block->Free -= totalSize;
84
85 m_Block->ObjectCount -= totalSize;
86
87 // Assumes that people don't deallocate the same memory twice
88 if (m_Block->ObjectCount == 0)
89 m_Block->Free = m_Block->Data;
90 }
91#pragma endregion
92
93#pragma region Utility
94 size_t max_size() const noexcept
95 {
96 return Size;
97 }
98
99 bool owns(void* p) const noexcept
100 {
101 // Comparing pointers to different objects is unspecified
102 // But converting them to integers and comparing them isn't...
103 uintptr_t ptr = reinterpret_cast<uintptr_t>(p);
104 uintptr_t low = reinterpret_cast<uintptr_t>(m_Block->Data);
105 uintptr_t high = low + Size;
106
107 return ptr >= low && ptr < high;
108 }
109#pragma endregion
110
111 private:
112 stack<Size>* m_Block;
113 };
114}
A linear allocator which gives out chunks of its allocated stack. Increments a counter during allocat...
Definition stack_allocator.h:36
bool operator!=(const stack_allocator &rhs) const noexcept
Definition stack_allocator.h:57
void deallocate(void *p, size_t n) noexcept
Definition stack_allocator.h:78
stack_allocator(stack_allocator &&) noexcept=default
stack_allocator(stack< Size > &block) noexcept
Definition stack_allocator.h:38
void * allocate(size_t n) noexcept
Definition stack_allocator.h:63
size_t max_size() const noexcept
Definition stack_allocator.h:94
stack_allocator(stack< Size > *block) noexcept
Definition stack_allocator.h:41
bool owns(void *p) const noexcept
Definition stack_allocator.h:99
stack_allocator(const stack_allocator &) noexcept=default
constexpr size_t align_to_architecture(size_t n) noexcept
Definition alignment.h:10
constexpr size_t ALIGNMENT
Definition alignment.h:7
Definition cascading.h:16
A stack object of a given Size.
Definition stack_allocator.h:17
char Data[Size]
Definition stack_allocator.h:18
char * Free
Definition stack_allocator.h:19
size_t ObjectCount
Definition stack_allocator.h:20
stack() noexcept
Definition stack_allocator.h:22