KTL
stack_allocator.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "../utility/alignment.h"
4 #include "stack_allocator_fwd.h"
5 #include "type_allocator.h"
6 
7 #include <memory>
8 #include <type_traits>
9 
10 namespace ktl
11 {
15  template<size_t Size>
16  struct stack
17  {
18  alignas(detail::ALIGNMENT) char Data[Size];
19  char* Free;
20  size_t ObjectCount;
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
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
void * allocate(size_t n) noexcept
Definition: stack_allocator.h:63
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:15
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