openMSX
monotonic_allocator.hh
Go to the documentation of this file.
1 #ifndef MEMORY_RESOURCE
2 #define MEMORY_RESOURCE
3 
4 #include <algorithm>
5 #include <cassert>
6 #include <cstddef>
7 #include <cstdlib>
8 #include <memory>
9 #include <new>
10 
11 // A minimal re-implementation of std::monotonic_buffer_resource.
12 // Because libc++ doesn't have this yet, even though it's part of c++17.
13 
15 {
16 public:
17  monotonic_allocator() = default;
18 
19  monotonic_allocator(size_t initialSize)
20  : nextSize(initialSize)
21  {
22  assert(initialSize != 0);
23  }
24 
25  monotonic_allocator(void* buffer, size_t bufferSize)
26  : current(buffer)
27  , available(bufferSize)
28  , nextSize(2 * bufferSize)
29  {
30  assert(buffer || bufferSize == 0);
31  }
32 
35 
37  {
38  void* p = head;
39  while (p) {
40  void* next = *static_cast<void**>(p);
41  free(p);
42  p = next;
43  }
44  }
45 
46  [[nodiscard]] void* allocate(size_t bytes, size_t alignment)
47  {
48  assert(alignment <= alignof(max_align_t));
49 
50  if (bytes == 0) bytes = 1;
51  void* p = std::align(alignment, bytes, current, available);
52  if (!p) {
53  newBuffer(bytes);
54  p = current;
55  }
56  current = static_cast<char*>(current) + bytes;
57  available -= bytes;
58  return p;
59  }
60 
61 private:
62  void newBuffer(size_t bytes)
63  {
64  size_t n = std::max(nextSize, bytes);
65  void* newBuf = malloc(n + sizeof(void*));
66  if (!newBuf) {
67  throw std::bad_alloc();
68  }
69 
70  void** p = static_cast<void**>(newBuf);
71  p[0] = head;
72 
73  current = static_cast<void*>(&p[1]);
74  available = n;
75  nextSize = 2 * n;
76  head = newBuf;
77  }
78 
79 private:
80  void* current = nullptr;
81  size_t available = 0;
82  size_t nextSize = 1024;
83  void* head = nullptr;
84 };
85 
86 #endif
monotonic_allocator(const monotonic_allocator &)=delete
monotonic_allocator()=default
monotonic_allocator(void *buffer, size_t bufferSize)
void * allocate(size_t bytes, size_t alignment)
monotonic_allocator(size_t initialSize)
monotonic_allocator & operator=(const monotonic_allocator &)=delete
constexpr vecN< N, T > max(const vecN< N, T > &x, const vecN< N, T > &y)
Definition: gl_vec.hh:287