Fw/DataStructures/docs/ExternalFifoQueue.md
ExternalFifoQueue is a final class template
defined in Fw/DataStructures.
It represents a FIFO queue with external storage.
Internally it maintains an ExternalArray for
storing the items on the queue.
ExternalFifoQueue has the following template parameters.
| Kind | Name | Purpose |
|---|---|---|
typename | T | The type of an item on the queue |
ExternalFifoQueue<T> is publicly derived from
FifoQueueBase<T>.
ExternalFifoQueue has the following private member variables.
| Name | Type | Purpose | Default Value |
|---|---|---|---|
m_items | ExternalArray<T> | The array for storing the queue items | C++ default initialization |
m_enqueueIndex | CircularIndex | The enqueue index | CircularIndex(m_items.size(), 0) |
m_dequeueIndex | CircularIndex | The dequeue index | CircularIndex(m_items.size(), 0) |
m_size | FwSizeType | The number of items on the queue | 0 |
classDiagram
FifoQueue *-- ExternalArray
FifoQueue *-- CircularIndex
FifoQueue *-- CircularIndex
ExternalFifoQueue()
Initialize each member variable with its default value.
Example:
ExternalFifoQueue<U32> queue;
ExternalFifoQueue(T* items, FwSizeType capacity)
items must point to a primitive array of at least capacity
items of type T.
Call setStorage(items, capacity).
Initialize the other member variables with their default values.
Example:
constexpr FwSizeType capacity = 10;
U32 items[capacity];
ExternalFifoQueue<U32> queue(items, capacity);
ExternalFifoQueue(ByteArray data, FwSizeType capacity)
data must be aligned according to
getByteArrayAlignment() and must
contain at least getByteArraySize(capacity) bytes.
Call setStorage(data, capacity).
Initialize the other member variables with their default values.
Example:
constexpr FwSizeType capacity = 10;
constexpr U8 alignment = ExternalFifoQueue<U32>::getByteArrayAlignment();
constexpr FwSizeType byteArraySize = ExternalFifoQueue<U32>::getByteArraySize(capacity);
alignas(alignment) U8 bytes[byteArraySize];
ExternalFifoQueue<U32> queue(ByteArray(&bytes[0], sizeof bytes), capacity);
ExternalFifoQueue(const ExternalFifoQueue<T>& queue)
Set *this = queue.
Example:
constexpr FwSizeType capacity = 3;
U32 items[capacity];
// Call the constructor providing backing storage
ExternalFifoQueue<U32> q1(items, capacity);
// Enqueue an item
U32 value = 42;
(void) q1.enqueue(value);
// Call the copy constructor
ExternalFifoQueue<U32> q2(q1);
ASSERT_EQ(q2.getSize(), 1);
~ExternalFifoQueue() override
Defined as = default.
ExternalFifoQueue<T>& operator=(const ExternalFifoQueue<T>& queue)
If &queue != this
Set m_items = queue.m_items.
Set m_enqueueIndex = queue.m_enqueueIndex.
Set m_dequeueIndex = queue.m_dequeueIndex.
Set m_size = queue.m_size.
Return *this.
Example:
constexpr FwSizeType capacity = 3;
U32 items[capacity];
// Call the constructor providing backing storage
ExternalFifoQueue<U32> q1(items, capacity);
// Enqueue an item
U32 value = 42;
(void) q1.enqueue(value);
// Call the default constructor
ExternalFifoQueue q2;
ASSERT_EQ(q2.getSize(), 0);
// Call the copy assignment operator
q2 = q1;
ASSERT_EQ(q2.getSize(), 1);
void clear() override
Call m_enqueueIndex.setValue(0).
Call m_dequeueIndex.setValue(0).
Set m_size = 0.
Example:
constexpr FwSizeType capacity = 10;
U32 items[capacity];
ExternalFifoQueue<U32> queue(items, capacity);
const auto status = queue.enqueue(3);
ASSERT_EQ(queue.getSize(), 1);
queue.clear();
ASSERT_EQ(queue.getSize(), 0);
void setStorage(T* items, FwSizeType capacity)
items must point to a primitive array of at least capacity
items of type T.
Call m_items.setStorage(items, capacity).
If capacity > 0
Call this->m_enqueueIndex.setModulus(capacity).
Call this->m_dequeueIndex.setModulus(capacity).
Call this->clear().
Example:
constexpr FwSizeType capacity = 10;
ExternalFifoQueue<U32> queue;
U32 items[capacity];
queue.setStorage(items, capacity);
void setStorage(ByteArray data, FwSizeType capacity)
data must be aligned according to
getByteArrayAlignment() and must
contain at least getByteArraySize(capacity) bytes.
Call m_items.setStorage(data, capacity).
If capacity > 0
Call this->m_enqueueIndex.setModulus(capacity).
Call this->m_dequeueIndex.setModulus(capacity).
Call this->clear().
Example:
constexpr FwSizeType capacity = 10;
constexpr U8 alignment = ExternalFifoQueue<U32>::getByteArrayAlignment();
constexpr FwSizeType byteArraySize = ExternalFifoQueue<U32>::getByteArraySize(capacity);
alignas(alignment) U8 bytes[byteArraySize];
ExternalFifoQueue<U32> queue;
queue.setStorage(ByteArray(&bytes[0], sizeof bytes), capacity);
Success enqueue(const T& e) override
Set status = Success::FAILURE.
If m_size < getCapacity() then
Set i = m_enqueueIndex.getValue().
Set m_items[i] = e.
Call m_enqueueIndex.increment().
Increment m_size.
Return status.
Example:
constexpr FwSizeType capacity = 3;
U32 items[capacity];
ExternalFifoQueue<U32> queue(items, capacity);
ASSERT_EQ(queue.getSize(), 0);
auto status = queue.enqueue(42);
ASSERT_EQ(status, Success::SUCCESS);
ASSERT_EQ(queue.getSize(), 1);
const T& at(FwSizeType index) const override
Assert index < m_size.
Set ci = m_dequeueIndex.
Set i = ci.increment(index).
Return m_items[i].
Example:
constexpr FwSizeType capacity = 3;
U32 items[capacity];
ExternalFifoQueue<U32> queue(items, capacity);
const auto status = queue.enqueue(3);
ASSERT_EQ(status, Success::SUCCESS);
ASSERT_EQ(queue.at(0), 3);
ASSERT_DEATH(queue.at(1), "Assert");
Success dequeue(T& e) override
Set status = Success::FAILURE.
If m_size > 0 then
Set i = m_dequeueIndex.getValue().
Set e = m_items[i].
Call m_dequeueIndex.increment().
Decrement m_size.
Return status.
Example:
constexpr FwSizeType capacity = 3;
U32 items[capacity];
ExternalFifoQueue<U32> queue(items, capacity);
U32 val;
auto status = queue.dequeue(val);
ASSERT_EQ(status, Success::FAILURE);
status = queue.enqueue(42);
ASSERT_EQ(status, Success::SUCCESS);
status = queue.dequeue(val);
ASSERT_EQ(status, Success::SUCCESS);
ASSERT_EQ(val, 42);
FwSizeType getSize() const override
Return m_size.
Example:
constexpr FwSizeType capacity = 10;
U32 items[capacity];
ExternalFifoQueue<U32> queue(items, capacity);
auto size = queue.getSize();
ASSERT_EQ(size, 0);
const auto status = queue.enqueue(3);
ASSERT_EQ(status, Success::SUCCESS);
size = queue.getSize();
ASSERT_EQ(size, 1);
FwSizeType getCapacity() const override
Return m_items.getSize().
Example:
constexpr FwSizeType capacity = 10;
U32 items[capacity];
ExternalFifoQueue<U32> queue(items, capacity);
ASSERT_EQ(queue.getCapacity(), capacity);
<a name="getByteArrayAlignment"></a>
static constexpr U8 getByteArrayAlignment()
Return ExternalArray<T>::getByteArrayAlignment().
<a name="getByteArraySize"></a>
static constexpr FwSizeType getByteArraySize(FwSizeType capacity)
Return ExternalArray<T>::getByteArraySize(capacity).