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{
16public:
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
61private:
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
79private:
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)
monotonic_allocator(size_t initialSize)
void * allocate(size_t bytes, size_t alignment)
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:284