Data Structures

template<typename TType>
class Pool

Manages a collection of reusable objects of type TType using resource pooling.

Provides efficient memory management by reusing a fixed number of type TType pre-allocated objects. If the pool is exhausted, new objects can still be allocated on demand and returned to the pool.

Template Parameters:

TType – The type of object to manage in the pool.

Public Functions

inline void resize(const size_t new_size)

Resizes the pool to hold the specified number of pre-allocated objects.

This method will add or remove objects in the pool based on the given new_size.

  • If expanding: New objects are added to the pool up to new_size.

  • If shrinking: Objects are only removed if they are not in use.

Example

Pool<TestObject> myPool;
myPool.resize(10);  // Pre-allocates 10 objects
myPool.resize(5);   // Reduces pool size to 5 if possible
Parameters:

new_size – The new target number of objects for the pool.

Throws:

std::invalid_argument – If new_size is less than the number of currently in-use objects.

template<typename ...TArgs>
inline Object acquire(TArgs&&... args)

Acquires an object from the pool, constructing it if necessary.

This method provides an object from the pool, or constructs one if none are available. It uses perfect forwarding (std::forward<TArgs>(args)) to pass arguments to the constructor, enabling efficient resource acquisition and initialization.

Example

Pool<MyClass> pool;
pool.resize(5);  // Pre-allocates 5 objects

// Acquire an object, initializing it with a specific constructor
auto obj = pool.acquire(42);
obj->use();

// If all objects are in use, the method will resize the pool:
auto newObj = pool.acquire();
newObj->use();
Template Parameters:

TArgs – Variadic template parameter pack for constructor arguments.

Parameters:

args – Constructor arguments to initialize the object.

Throws:

std::runtime_error – if the pool is empty and unable to provide a new object.

Returns:

A Pool::Object that manages the acquired resource.

Private Functions

inline void release(TType *ptr)

Returns an object to the pool.

This method is called by the Object class’s destructor when an Object instance goes out of scope.

Parameters:

ptr – Pointer to the object being returned to the pool.

Private Members

std::stack<TType*> pool_

Stack of available objects in the pool.

std::vector<std::unique_ptr<TType>> allocated_

Storage for all allocated objects.

class Object

RAII-style wrapper for objects managed by the Pool.

Pool::Object is designed to handle the lifecycle of an acquired resource from the pool. When an instance of Object goes out of scope, it automatically returns the object back to the pool, ensuring safe and efficient resource management.

Public Functions

inline Object(TType *ptr, Pool &pool)

Constructor for Object, used internally by Pool to wrap a resource.

Note:

Choosing Pool& pool instead of Pool* pool helps enforce safety, improves code readability, and clarifies that Object always expects a valid pool instance without taking ownership, perfectly aligning with RAII design principles.

Parameters:
  • ptr – Pointer to the TType object acquired from the pool.

  • pool – Reference to the parent Pool instance, used to return the object on destruction.

inline ~Object()

Destructor for Object, automatically returns the resource to the pool.

When the Object instance is destroyed, the managed object is returned to the pool instead of being deallocated.

inline TType *operator->()

Arrow operator overload to access the underlying TType object.

Returns:

Pointer to the TType object.

Private Members

TType *ptr_

Pointer to the managed object.

Pool &pool_

Reference to the parent pool, for returning the object on destruction.

class DataBuffer

A polymorphic container for serializing and deserializing objects into byte format.

The DataBuffer class allows storing and retrieving objects in a byte format. It handles serialization (storing objects in the buffer) and deserialization (retrieving objects from the buffer) using the << and >> operators.

The class uses an internal byte buffer to store serialized data and provides convenient methods for storing and loading data of various types.

Example Usage:

Serializing and Deserializing Basic Types:

DataBuffer buffer;
int number = 42;
buffer << number;

int deserializedNumber;
buffer >> deserializedNumber;
std::cout << "Deserialized number: " << deserializedNumber << std::endl;  // Output: 42

Serializing and Deserializing Custom Objects:

class TestObject {
public:
    int x;
    std::string y;

    friend DataBuffer& operator<<(DataBuffer& p_buffer, const TestObject& p_object) {
        p_buffer << p_object.x << p_object.y;
        return p_buffer;
    }

    friend DataBuffer& operator>>(DataBuffer& p_buffer, TestObject& p_object) {
        p_buffer >> p_object.x >> p_object.y;
        return p_buffer;
    }
};

DataBuffer buffer;
TestObject obj1{42, "Hello"};
buffer << obj1;

TestObject deserializedObj;
buffer >> deserializedObj;
std::cout << "Deserialized object: x = " << deserializedObj.x << ", y = " << deserializedObj.y << std::endl;

Public Functions

DataBuffer()

Default constructor for DataBuffer.

Initializes an empty internal buffer to hold the serialized data.

DataBuffer(const std::vector<uint8_t> &buffer)

Constructor for DataBuffer.

Initializes a DataBuffer with the given data.

DataBuffer &operator<<(const std::string &str)

Serialize a std::string object and store it in the buffer.

This operator serializes the std::string object str by first storing its length followed by the characters of the string.

Parameters:

str – The std::string to be serialized and stored in the buffer.

Returns:

A reference to the current DataBuffer object for method chaining.

template<typename T>
inline DataBuffer &operator<<(const T &obj)

Serialize an object and store it in the buffer.

This operator appends the serialized representation of the object obj to the internal buffer. The object is first converted into a byte format and then inserted into the buffer.

Note

The type T must be trivially copyable. This is enforced via a static assertion that will cause a compile-time error if the type T is not trivially copyable. A trivially copyable type is one that can be safely copied byte-by-byte (such as primitive types or simple structs without virtual functions or non-trivial destructors). https://en.cppreference.com/w/cpp/types/is_trivially_copyable

Template Parameters:

T – The type of the object being serialized.

Parameters:

obj – The object to be serialized and stored in the buffer.

Returns:

A reference to the current DataBuffer object for method chaining.

DataBuffer &operator>>(std::string &str)

Serialize a std::string object and store it in the buffer.

This operator serializes the std::string object str by first storing its length followed by the characters of the string.

Parameters:

str – The std::string to be serialized and stored in the buffer.

Returns:

A reference to the current DataBuffer object for method chaining.

template<typename T>
inline DataBuffer &operator>>(T &obj)

Deserialize an object from the buffer.

This operator retrieves data from the internal buffer and deserializes it into the object obj. If the buffer contains insufficient data for the requested object, an exception is thrown.

Note

The type T must be trivially copyable. This is enforced via a static assertion that will cause a compile-time error if the type T is not trivially copyable. A trivially copyable type is one that can be safely copied byte-by-byte (such as primitive types or simple structs without virtual functions or non-trivial destructors). https://en.cppreference.com/w/cpp/types/is_trivially_copyable

Template Parameters:

T – The type of the object being deserialized.

Parameters:

obj – The object to be deserialized and populated with data from the buffer.

Throws:

std::out_of_range – If the buffer does not contain enough data for the object.

Returns:

A reference to the current DataBuffer object for method chaining.

const std::vector<uint8_t> &getData() const

Retrieve the raw byte data stored in the buffer.

This method returns a reference to the internal byte buffer containing the serialized data.

Returns:

A constant reference to the internal buffer.

Private Members

std::vector<uint8_t> buffer_

The internal buffer holding the serialized data.