Clustering
C++20 header-only: DBSCAN, HDBSCAN, k-means.
Loading...
Searching...
No Matches
linear_alloc.h
Go to the documentation of this file.
1#pragma once
2#include <cstdint>
3#include <new>
4#include <type_traits>
5#include <utility>
6
7namespace clustering {
8
9template <typename T> class LinearAllocator {
10 static_assert(std::is_trivially_destructible_v<T>, "T must be trivially destructible");
11
12public:
14 LinearAllocator(std::size_t count)
15 : size(count * sizeof(T)), memory(new char[count * sizeof(T)]), next(memory) {}
16
17 ~LinearAllocator() { delete[] memory; }
18
21
23 T *allocate() {
24 if (std::cmp_greater_equal(next - memory, size)) {
25 throw std::bad_alloc();
26 }
27
28 // Placement new modifies storage at `next` even though tidy can't see
29 // it through the pointer; suppress the false-positive const suggestion.
30 T *const result = new (next) T; // NOLINT(misc-const-correctness)
31 next += sizeof(T);
32 return result;
33 }
34
37 T *allocate(std::size_t count) {
38 const auto used = static_cast<std::size_t>(next - memory);
39 if (count == 0 || (count * sizeof(T)) > (size - used)) {
40 throw std::bad_alloc();
41 }
42
43 // Element-wise placement new sidesteps the implementation-defined cookie that array
44 // placement new may prepend; trivial default construction folds the loop away.
45 T *const result = new (next) T; // NOLINT(misc-const-correctness)
46 for (std::size_t i = 1; i < count; ++i) {
47 new (next + (i * sizeof(T))) T;
48 }
49 next += count * sizeof(T);
50 return result;
51 }
52
54 void deallocate(T * /*ptr*/) {
55 // Do nothing because T is trivially destructible
56 }
57
59 void reset() { next = memory; }
60
62 bool isDeallocSupported() { return false; }
63
64private:
65 std::size_t size;
66 char *memory;
67 char *next;
68};
69
70} // namespace clustering
bool isDeallocSupported()
Reports that per-element deallocate is not supported (false for this allocator).
T * allocate(std::size_t count)
Bump-allocates count contiguous T objects in one step; throws std::bad_alloc when fewer than count sl...
LinearAllocator & operator=(const LinearAllocator &)=delete
T * allocate()
Bump-allocates one T; throws std::bad_alloc when the arena is exhausted.
LinearAllocator(std::size_t count)
Reserves room for count objects of T from a single backing allocation.
void reset()
Rewinds the bump pointer, reclaiming every outstanding allocation in one shot.
LinearAllocator(const LinearAllocator &)=delete
void deallocate(T *)
No-op: trivial destructibility lets per-element reclamation be skipped.