gz-cpp-util 1.3
A c++20 library containing various utilities
gz::Queue< T > Class Template Reference

A thread-safe queue with a dynamic size up until a maximum size. More...

#include <queue.hpp>

Public Member Functions

 Queue (size_t size=10, size_t maxSize=-1)
 Create a new queue. More...
 
void push_back (T &t)
 
void push_back (T &&t)
 
void emplace_back (T &&t)
 
bool hasElement ()
 Check if the contains has an element that can be retrieved by get()
 
T & getRef ()
 Get a reference to the oldest element. More...
 
getCopy ()
 Get a copy of the oldest element. More...
 
void clear ()
 Remove all elements.
 
std::vector< T > & getInternalBuffer ()
 

Private Member Functions

void resize ()
 Resize the queue (if possible) More...
 

Private Attributes

size_t writeIndex
 Points to the element that was last written.
 
size_t readIndex
 Points to the element that was last read.
 
std::vector< T > buffer
 
size_t vectorCapacity
 
size_t maxSize
 
std::mutex mtx
 

Detailed Description

template<std::swappable T>
class gz::Queue< T >

A thread-safe queue with a dynamic size up until a maximum size.

Elements are ordered by the time they were put in the queue: You can only insert an element at the front and you can only get the element from the end.

The queue uses a ringbuffer (which itself uses a vector) for data storage. Reallocations happen when an element is inserted into a queue with n < maxSize elements and the size of the ringbuffer is n. The queue will then increase the size of the ringbuffer by 10% (at least 3 elements, but the size will never be greater than maxSize).

Note that "n elements" means n elements that were inserted and not accessed through get(). Elements might still by in memory after they have been get().

The queue is thread safe, IF: the end of the queue is only processed by a single thread. Data races can occur when multiple threads try to retrieve elements (or clear() the queue), since the information from hasElement() might not be valid anymore until getCopy() gets called. Putting elements into the queue can be done by multiple threads.

Constructor & Destructor Documentation

◆ Queue()

template<std::swappable T>
gz::Queue< T >::Queue ( size_t  size = 10,
size_t  maxSize = -1 
)

Create a new queue.

Parameters
sizeThe size the queue can grow to without reallocating memory.
maxSizeThe maximum size of the queue. If more than maxSize elements are inserted, the oldest elements are discarded until size == maxSize.

Member Function Documentation

◆ getCopy()

template<std::swappable T>
T gz::Queue< T >::getCopy

Get a copy of the oldest element.

Returns
Copy of the oldest element.
Warning
Leads to undefined behavior when there is no element to get. Always check hasElement() first.
Todo:
could this in some stupid edge case lead to a data race?

◆ getRef()

template<std::swappable T>
T & gz::Queue< T >::getRef

Get a reference to the oldest element.

Returns
Reference to the oldest element.
Note
The reference is at least valid until the next call to push_back/emplace_back. If you are in a multithreaded environment, it is probably better to use getCopy().
Warning
Leads to undefined behavior when there is no element to get. Always check hasElement() first.

◆ resize()

template<std::swappable T>
void gz::Queue< T >::resize
private

Resize the queue (if possible)

After calling this, readIndex and writeIndex will be valid so that a push_back or emplace_back can be performed.


The documentation for this class was generated from the following file: