nngn
Loading...
Searching...
No Matches
block.h
Go to the documentation of this file.
1#ifndef NNGN_UTILS_ALLOC_BLOCK_H
2#define NNGN_UTILS_ALLOC_BLOCK_H
3
4#include <cstddef>
5#include <cstdlib>
6#include <type_traits>
7
8#include "utils/concepts.h"
9#include "utils/utils.h"
10
11namespace nngn {
12
30template<typename H, typename T = char>
32 static constexpr bool both_trivial = trivial<H> && trivial<T>;
33public:
34 using header_type = H;
35 using value_type = T;
37 struct storage {
38 // Needed because types can never be deduced from nested classes.
39 // http://open-std.org/JTC1/SC22/WG21/docs/papers/2016/p0293r0.pdf
43 };
45 static constexpr std::size_t data_offset = [] {
46 if constexpr(std::is_standard_layout_v<alloc_block::storage>)
47 return offsetof(alloc_block::storage, data);
48 else {
49 struct S {
50 alignas(header_type) char header[sizeof(header_type)];
51 alignas(value_type) char data[sizeof(value_type)];
52 };
53 return offsetof(S, data);
54 }
55 }();
56 // Static helpers
58 static constexpr std::size_t alloc_size(std::size_t n);
59 // Constructors
61 static constexpr auto from_storage_ptr(void *p) { return alloc_block{p}; }
63 static constexpr alloc_block from_ptr(T *p);
65 alloc_block(void) noexcept = default;
66 // Accessors
68 constexpr storage *data(void) { return this->p; }
70 constexpr const storage *data(void) const { return this->p; }
72 constexpr header_type *header(void) { return &this->p->header; }
74 constexpr const header_type *header(void) const { return this->p->header; }
76 constexpr value_type *get(void) { return &this->p->data; }
78 constexpr const value_type *get(void) const { return &this->p->data; }
79 // Allocation functions
81 static alloc_block alloc(void) requires both_trivial
84 static alloc_block alloc(std::size_t s) requires both_trivial
85 { alloc_block ret; ret.realloc(s); return ret; }
87 void realloc(std::size_t s) requires both_trivial { // TODO clang
88 *this = alloc_block{::realloc(this->p, s + offsetof(storage, data))};
89 }
91 void free(void) requires both_trivial { ::free(this->p); }
92private:
94 explicit alloc_block(void *p_) : p{static_cast<storage*>(p_)} {}
96 storage *p = nullptr;
97};
98
99template<typename H, typename T>
100inline constexpr std::size_t alloc_block<H, T>::alloc_size(std::size_t n) {
102}
103
104template<typename H, typename T>
105inline constexpr auto alloc_block<H, T>::from_ptr(T *p) -> alloc_block {
106 using S = alloc_block::storage;
107 if constexpr(std::is_standard_layout_v<S>)
108 return alloc_block{NNGN_CONTAINER_OF(storage, data, p)};
109 else
110 return alloc_block{byte_cast<char*>(p) - alloc_block::data_offset};
111}
112
113}
114
115#endif
Non-owning handle to an aggregate header and data block.
Definition: block.h:31
T value_type
Definition: block.h:35
constexpr storage * data(void)
Pointer to the block.
Definition: block.h:68
void free(void)
Frees the block's memory.
Definition: block.h:91
static constexpr bool both_trivial
Definition: block.h:32
constexpr value_type * get(void)
Pointer to the data block.
Definition: block.h:76
void realloc(std::size_t s)
Reallocates the entire block.
Definition: block.h:87
static constexpr std::size_t data_offset
Total size of an allocation for n elements.
Definition: block.h:45
static constexpr auto from_storage_ptr(void *p)
Constructs a handle to a pre-existing storage block.
Definition: block.h:61
static alloc_block alloc(void)
Allocates a block to contain exactly a T.
Definition: block.h:81
alloc_block(void *p_)
Constructs from a pointer to the block.
Definition: block.h:94
constexpr header_type * header(void)
Pointer to the block header.
Definition: block.h:72
static alloc_block alloc(std::size_t s)
Allocates a block to contain s bytes of data.
Definition: block.h:84
constexpr const header_type * header(void) const
Pointer to the block header.
Definition: block.h:74
static constexpr std::size_t alloc_size(std::size_t n)
Total size of an allocation for n elements.
Definition: block.h:100
static constexpr alloc_block from_ptr(T *p)
Offsets p to the beginning of the entire block.
Definition: block.h:105
H header_type
Definition: block.h:34
constexpr const value_type * get(void) const
Pointer to the data block.
Definition: block.h:78
constexpr const storage * data(void) const
Pointer to the block.
Definition: block.h:70
alloc_block(void) noexcept=default
Initializes a handle with no associated block.
storage * p
Pointer to the underlying storage, non-owning.
Definition: block.h:96
Definition: concepts.h:11
Definition: debug.h:45
Underlying storage type.
Definition: block.h:37
header_type header
Definition: block.h:41
value_type data
Definition: block.h:42
std::chrono::seconds s
Definition: timing.cpp:6
#define NNGN_CONTAINER_OF(t, n, p)
Definition: utils.h:56
#define S(v0, v1)
Definition: vec2.h:16