Stratax 0.2.0
Loading...
Searching...
No Matches
Buffer

Buffer

Version: v0.2.0

Status: Complete

Header: include/stratax/core/containers/Buffer.hpp


Overview

Buffer<T> is a fixed-size contiguous storage container.

It owns dynamically allocated memory, provides RAII semantics, and supplies iterator support for all higher-level Stratax containers. Buffer<T> serves as the foundation upon which Shape, Strides, Vector, Matrix, and Tensor are built.


Responsibilities

The Buffer class is responsible for:

  • Allocating contiguous memory
  • Managing memory ownership (RAII)
  • Providing iterator support
  • Providing element access
  • Copy and move semantics
  • Serving as the storage backend for Stratax containers

The Buffer class is not responsible for:

  • Numerical algorithms
  • Shape validation
  • Bounds validation
  • Mathematical operations
  • Multidimensional indexing

Relationships

Buffer<T>
├── data_
│ Pointer to contiguous storage
└── size_
Number of stored elements

Depends on:

  • C++ Standard Library
  • Memory utilities
  • Iterator facilities

Used by:

  • Shape
  • Strides
  • Vector
  • Matrix
  • Tensor

Related classes:

  • Shape
  • Strides

Internal Data

Member Description
T* data_ Pointer to contiguous memory owned by the buffer
std::size_t size_ Number of stored elements

Invariants

The following conditions are always true:

  • size() is never negative.
  • data() is either nullptr or points to size() contiguous elements.
  • Buffer always owns the memory it manages.
  • Copy operations perform deep copies.
  • Copying duplicates storage.
  • Move operations transfer ownership.
  • Memory is released automatically when the buffer is destroyed.

Public Interface

Iterator Aliases

using iterator = T*;
using const_iterator = const T*;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;

Buffer<T> exposes iterator aliases for STL-style generic code. Other storage-related types such as pointers, references, and sizes remain spelled out in the public API.


Constructors

Default Constructor

Buffer();

Constructs an empty buffer that owns no storage.

Complexity

  • O(1)

Throws

  • None

Size Constructor

Buffer(std::size_t size);

Constructs a buffer containing size default-initialized elements.

Complexity

  • O(n)

Throws

  • std::bad_alloc

Fill Constructor

Buffer(std::size_t size, const T& value);

Constructs a buffer containing size copies of value.

Complexity

  • O(n)

Throws

  • std::bad_alloc

Initializer List Constructor

Buffer(std::initializer_list<T> list);

Constructs a buffer from an initializer list.

Complexity

  • O(n)

Throws

  • std::bad_alloc

Copy Constructor

Buffer(const Buffer& other);

Constructs a deep copy of another buffer.

Complexity

  • O(n)

Move Constructor

Buffer(Buffer&& other) noexcept;

Transfers ownership from another buffer.

Complexity

  • O(1)

Destructor

~Buffer();

Releases owned memory.

Complexity

  • O(n)

Assignment Operators

Copy Assignment

Buffer& operator=(const Buffer& other);

Performs a deep copy.

Complexity

  • O(n)

Move Assignment

Buffer& operator=(Buffer&& other) noexcept;

Transfers ownership.

Complexity

  • O(1)

Methods

front()

T& front();

Returns the first element of the buffer.

Preconditions

  • Buffer must not be empty.

Complexity

  • O(1)

See Also

const T& front() const;

back()

T& back();

Returns the last element of the buffer.

Preconditions

  • Buffer must not be empty.

Complexity

  • O(1)

See Also

const T& back() const;

data()

[[nodiscard]] T* data() noexcept;

Returns a pointer to the first stored element.

Complexity

  • O(1)

See Also

[[nodiscard]] const T* data() const noexcept;

size()

[[nodiscard]] std::size_t size() const noexcept;

Returns the number of stored elements.

Complexity

  • O(1)

empty()

[[nodiscard]] bool empty() const noexcept;

Returns true if the buffer contains no elements.

Complexity

  • O(1)

fill()

void fill(const T& value);

Assigns every stored element the value value.

Preconditions

  • Buffer has been constructed.

Postconditions

  • Every stored element equals value.

Complexity

  • O(n)

swap()

void swap(Buffer& other) noexcept;

Exchanges the contents of two buffers.

Complexity

  • O(1)

Operators

operator[]

T& operator[](std::size_t index) noexcept;

Returns a reference to an element.

Bounds checking is not performed.

Complexity

  • O(1)

See Also

const T& operator[](std::size_t index) const noexcept;

Complexity Summary

Operation Complexity
Default construction O(1)
Size construction O(n)
Fill construction O(n)
Initializer list construction O(n)
Copy construction O(n)
Move construction O(1)
Copy assignment O(n)
Move assignment O(1)
Destruction O(n)
Element access O(1)
Iteration O(n)
fill() O(n)
swap() O(1)

Examples

Creating a Buffer

Buffer<double> a(5);

Initializer List

Buffer<double> b{1.0, 2.0, 3.0};

Filling

Buffer<double> values(10);
values.fill(3.14);

Iteration

for (const auto& value : values)
{
std::cout << value << '\n';
}

Design Notes

Buffer<T> stores data in a single contiguous memory block.

Higher-level containers such as Matrix and Tensor interpret this one-dimensional storage using Shape and Strides. This design improves cache locality, simplifies memory management, and allows algorithms to operate on a consistent underlying representation.

Empty buffer iterators are valid sentinels: begin() == end() and reverse iterator pairs are also equal for an empty buffer.

Buffer<T> intentionally contains no mathematical logic. Its sole responsibility is memory ownership and element storage.


Future Improvements

  • Custom allocators
  • std::pmr allocator support
  • Additional memory alignment strategies
  • SIMD-aware allocation
  • Optional uninitialized allocation optimizations
  • Small-buffer optimization (if ever justified)

See Also