KTL
linear_allocator.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "../utility/assert.h"
4 #include "../utility/alignment.h"
5 #include "linear_allocator_fwd.h"
6 
7 #include <memory>
8 #include <type_traits>
9 
10 namespace ktl
11 {
17  template<size_t Size>
19  {
20  public:
21  linear_allocator() noexcept :
22  m_Data{},
23  m_Free(m_Data),
24  m_ObjectCount(0) {}
25 
26  linear_allocator(const linear_allocator&) noexcept = delete;
27 
33  linear_allocator(linear_allocator&& other) noexcept :
34  m_Data{},
35  m_Free(m_Data),
36  m_ObjectCount(0)
37  {
38  // Moving raw allocators in use is undefined
39  KTL_ASSERT(other.m_ObjectCount == 0);
40  }
41 
42  linear_allocator& operator=(const linear_allocator&) noexcept = delete;
43 
50  {
51  m_Free = m_Data;
52 
53  // Moving raw allocators in use is undefined
54  KTL_ASSERT(rhs.m_ObjectCount == 0);
55 
56  return *this;
57  }
58 
59  bool operator==(const linear_allocator& rhs) const noexcept
60  {
61  return m_Data == rhs.m_Data;
62  }
63 
64  bool operator!=(const linear_allocator& rhs) const noexcept
65  {
66  return m_Data != rhs.m_Data;
67  }
68 
69 #pragma region Allocation
75  void* allocate(size_t n) noexcept
76  {
77  size_t totalSize = n + detail::align_to_architecture(n);
78 
79  if ((size_t(m_Free - m_Data) + totalSize) > Size)
80  return nullptr;
81 
82  char* current = m_Free;
83 
84  m_Free += totalSize;
85  m_ObjectCount += totalSize;
86 
87  return current;
88  }
89 
96  void deallocate(void* p, size_t n) noexcept
97  {
98  KTL_ASSERT(p != nullptr);
99 
100  size_t totalSize = n + detail::align_to_architecture(n);
101 
102  if (m_Free - totalSize == p)
103  m_Free -= totalSize;
104 
105  m_ObjectCount -= totalSize;
106 
107  // Assumes that people don't deallocate the same memory twice
108  if (m_ObjectCount == 0)
109  m_Free = m_Data;
110  }
111 #pragma endregion
112 
113 #pragma region Utility
118  size_t max_size() const noexcept
119  {
120  return Size;
121  }
122 
128  bool owns(void* p) const noexcept
129  {
130  // Comparing pointers to different objects is unspecified
131  // But converting them to integers and comparing them isn't...
132  uintptr_t ptr = reinterpret_cast<uintptr_t>(p);
133  uintptr_t low = reinterpret_cast<uintptr_t>(m_Data);
134  uintptr_t high = low + Size;
135 
136  return ptr >= low && ptr < high;
137  }
138 #pragma endregion
139 
140  private:
141  alignas(detail::ALIGNMENT) char m_Data[Size];
142  char* m_Free;
143  size_t m_ObjectCount;
144  };
145 }
#define KTL_ASSERT(x)
Definition: assert.h:17
A linear allocator which gives out chunks of its internal stack. Increments a counter during allocati...
Definition: linear_allocator.h:19
linear_allocator & operator=(const linear_allocator &) noexcept=delete
linear_allocator & operator=(linear_allocator &&rhs) noexcept
Move assignment operator.
Definition: linear_allocator.h:49
bool owns(void *p) const noexcept
Returns whether or not the allocator owns the given location in memory.
Definition: linear_allocator.h:128
void deallocate(void *p, size_t n) noexcept
Attempts to deallocate the memory at location p.
Definition: linear_allocator.h:96
linear_allocator() noexcept
Definition: linear_allocator.h:21
void * allocate(size_t n) noexcept
Attempts to allocate a chunk of memory defined by n.
Definition: linear_allocator.h:75
bool operator==(const linear_allocator &rhs) const noexcept
Definition: linear_allocator.h:59
bool operator!=(const linear_allocator &rhs) const noexcept
Definition: linear_allocator.h:64
size_t max_size() const noexcept
Returns the maximum size that an allocation can be.
Definition: linear_allocator.h:118
linear_allocator(const linear_allocator &) noexcept=delete
linear_allocator(linear_allocator &&other) noexcept
Move constructor.
Definition: linear_allocator.h:33
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