Efficient Data Structures

Context

Using std::span

We can now create and manage instances of S with F == std::span.

struct Point2D { double x, y; };

template <template <class> class F>
struct S {
F<int> x;
F<int> y;
F<Point2D> point;
F<std::string> identifier;

int abs2() const { return x * x + y * y; }
int& getX() { return x; }
const int& getX() const { return x; }
void setX(auto x_new) { x = x_new; }
};

Using Memory of an Existing Buffer

Problem: Given an existing buffer, we want to allocate our data structures within that buffer.

Solution: We use std::pmr::memory_resource that takes a pointer to the buffer and its size in bytes.

struct BufferResource : public std::pmr::memory_resource {
char* buffer_begin;
char* buffer_end;
char* current;

BufferResource(char* buffer, std::size_t bytes)
    : buffer_begin(buffer), buffer_end(buffer + bytes), current(buffer) {}

protected:

void* do_allocate(std::size_t bytes, std::size_t alignment) override {
    std::size_t space = buffer_end - current;
void* aligned = std::align(
alignment,
bytes,
reinterpret_cast<void*&>(current),
space
);

if (!aligned) throw std::bad_alloc();
    current += bytes;
return aligned;
}

void do_deallocate(void*, std::size_t, std::size_t) override {}

bool do_is_equal(const std::pmr::memory_resource& other) const noexcept override {
return this == &other;
}
};