31template<
typename T,
size_t ALIGNMENT = 0>
class MemBuffer
33 static_assert(std::is_trivially_copyable_v<T>);
34 static_assert(std::is_trivially_destructible_v<T>);
47 : dat(static_cast<T*>(my_malloc(
size * sizeof(T))))
64 std::swap(dat, other.dat);
65 std::swap(sz , other.sz);
79 [[nodiscard]]
const T*
data()
const {
return dat; }
80 [[nodiscard]] T*
data() {
return dat; }
83 [[nodiscard]]
const T*
begin()
const {
return data(); }
85 [[nodiscard]]
const T*
end()
const {
return data() +
size(); }
100 [[nodiscard]]
bool empty()
const {
return sz == 0; }
101 [[nodiscard]]
size_t size()
const {
return sz; }
108 [[nodiscard]]
const T&
front()
const
118 [[nodiscard]]
const T&
back()
const
124 [[nodiscard]]
operator std::span< T>() {
return {
data(),
size()}; }
125 [[nodiscard]]
operator std::span<const T>()
const {
return {
data(),
size()}; }
127 [[nodiscard]] std::span<const T>
first(
size_t n)
const
130 return std::span{*
this}.first(n);
132 [[nodiscard]] std::span<T>
first(
size_t n)
135 return std::span{*
this}.first(n);
137 [[nodiscard]] std::span<const T>
subspan(
size_t offset,
size_t n = std::dynamic_extent)
const
139 assert(offset <= sz);
140 assert(n == std::dynamic_extent || (offset + n <= sz));
141 return std::span{*
this}.subspan(offset, n);
143 [[nodiscard]] std::span<T>
subspan(
size_t offset,
size_t n = std::dynamic_extent)
145 assert(offset <= sz);
146 assert(n == std::dynamic_extent || (offset + n <= sz));
147 return std::span{*
this}.subspan(offset, n);
159 dat =
static_cast<T*
>(my_realloc(dat,
size *
sizeof(T)));
184 static constexpr bool SIMPLE_MALLOC = ALIGNMENT <=
alignof(std::max_align_t);
186 [[nodiscard]]
static void* my_malloc(
size_t bytes)
188 if constexpr (SIMPLE_MALLOC) {
189 void* result = malloc(bytes);
190 if (!result && bytes)
throw std::bad_alloc();
198 static void my_free(
void* p)
200 if constexpr (SIMPLE_MALLOC) {
207 [[nodiscard]]
void* my_realloc(
void* old,
size_t bytes)
209 if constexpr (SIMPLE_MALLOC) {
210 void* result = realloc(old, bytes);
211 if (!result && bytes)
throw std::bad_alloc();
215 if (!result && bytes)
throw std::bad_alloc();
This class manages the lifetime of a block of memory.
~MemBuffer()
Free the memory buffer.
MemBuffer()
Construct an empty MemBuffer, no memory is allocated.
std::span< const T > first(size_t n) const
std::span< const T > subspan(size_t offset, size_t n=std::dynamic_extent) const
void resize(size_t size)
Grow or shrink the memory block.
MemBuffer(size_t size)
Construct a (uninitialized) memory buffer of given size.
MemBuffer(MemBuffer &&other) noexcept
Move constructor.
std::span< T > subspan(size_t offset, size_t n=std::dynamic_extent)
std::span< T > first(size_t n)
MemBuffer & operator=(MemBuffer &&other) noexcept
Move assignment.
const T * data() const
Returns pointer to the start of the memory buffer.
const T & operator[](size_t i) const
Access elements in the memory buffer.
void clear()
Free the allocated memory block and set the current size to 0.
void * mallocAligned(size_t alignment, size_t size)
This file implemented 3 utility functions: