Fw/DataStructures/docs/ExternalStack.md
ExternalStack is a final class template
defined in Fw/DataStructures.
It represents a stack with external storage.
Internally it maintains an ExternalArray for
storing the items on the stack.
ExternalStack has the following template parameters.
| Kind | Name | Purpose |
|---|---|---|
typename | T | The type of an item on the stack |
ExternalStack<T> is publicly derived from
StackBase<T>.
ExternalStack has the following private member variables.
| Name | Type | Purpose | Default Value |
|---|---|---|---|
m_items | ExternalArray<T> | The array for storing the stack items | C++ default initialization |
m_size | FwSizeType | The number of items on the stack | 0 |
classDiagram
Stack *-- ExternalArray
ExternalStack()
Initialize each member variable with its default value.
Example:
ExternalStack<U32> stack;
ExternalStack(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];
ExternalStack<U32> stack(items, capacity);
ExternalStack(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 = ExternalStack<U32>::getByteArrayAlignment();
constexpr FwSizeType byteArraySize = ExternalStack<U32>::getByteArraySize(capacity);
alignas(alignment) U8 bytes[byteArraySize];
ExternalStack<U32> stack(ByteArray(&bytes[0], sizeof bytes), capacity);
ExternalStack(const ExternalStack<T>& stack)
Set *this = stack.
Example:
constexpr FwSizeType capacity = 3;
U32 items[capacity];
// Call the constructor providing backing storage
ExternalStack<U32> q1(items, capacity);
// Push an item
U32 value = 42;
(void) q1.push(value);
// Call the copy constructor
ExternalStack<U32> q2(q1);
ASSERT_EQ(q2.getSize(), 1);
~ExternalStack() override
Defined as = default.
ExternalStack<T>& operator=(const ExternalStack<T>& stack)
If &stack != this
Set m_items = stack.m_items.
Set m_size = stack.m_size.
Return *this.
Example:
constexpr FwSizeType capacity = 3;
U32 items[capacity];
// Call the constructor providing backing storage
ExternalStack<U32> q1(items, capacity);
// Push an item
U32 value = 42;
(void) q1.push(value);
// Call the default constructor
ExternalStack q2;
ASSERT_EQ(q2.getSize(), 0);
// Call the copy assignment operator
q2 = q1;
ASSERT_EQ(q2.getSize(), 1);
void clear() override
Set m_size = 0.
Example:
constexpr FwSizeType capacity = 10;
U32 items[capacity];
ExternalStack<U32> stack(items, capacity);
const auto status = stack.push(3);
ASSERT_EQ(stack.getSize(), 1);
stack.clear();
ASSERT_EQ(stack.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).
Call this->clear().
Example:
constexpr FwSizeType capacity = 10;
ExternalStack<U32> stack;
U32 items[capacity];
stack.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).
Call this->clear().
Example:
constexpr FwSizeType capacity = 10;
constexpr U8 alignment = ExternalStack<U32>::getByteArrayAlignment();
constexpr FwSizeType byteArraySize = ExternalStack<U32>::getByteArraySize(capacity);
alignas(alignment) U8 bytes[byteArraySize];
ExternalStack<U32> stack;
stack.setStorage(ByteArray(&bytes[0], sizeof bytes), capacity);
const T& at(FwSizeType index) const override
Assert index < m_size.
Return m_items[m_size - 1 - index].
Example:
constexpr FwSizeType capacity = 3;
U32 items[capacity];
ExternalStack<U32> stack(items, capacity);
const auto status = stack.push(3);
ASSERT_EQ(status, Success::SUCCESS);
ASSERT_EQ(stack.at(0), 3);
ASSERT_DEATH(stack.at(1), "Assert");
FwSizeType getSize() const override
Return m_size.
Example:
constexpr FwSizeType capacity = 10;
U32 items[capacity];
ExternalStack<U32> stack(items, capacity);
auto size = stack.getSize();
ASSERT_EQ(size, 0);
const auto status = stack.push(3);
ASSERT_EQ(status, Success::SUCCESS);
size = stack.getSize();
ASSERT_EQ(size, 1);
FwSizeType getCapacity() const override
Return m_items.getSize().
Example:
constexpr FwSizeType capacity = 10;
U32 items[capacity];
ExternalStack<U32> stack(items, capacity);
ASSERT_EQ(stack.getCapacity(), capacity);
Success pop(T& e) override
Set status = Success::FAILURE.
If m_size > 0 then
Decrement m_size.
Set e = m_items[m_size].
Return status.
Example:
constexpr FwSizeType capacity = 3;
U32 items[capacity];
ExternalStack<U32> stack(items, capacity);
U32 val;
auto status = stack.pop(val);
ASSERT_EQ(status, Success::FAILURE);
status = stack.push(42);
ASSERT_EQ(status, Success::SUCCESS);
status = stack.pop(val);
ASSERT_EQ(status, Success::SUCCESS);
ASSERT_EQ(val, 42);
Success push(const T& e) override
Set status = Success::FAILURE.
If m_size < getCapacity() then
Set m_items[m_size] = e.
Increment m_size.
Return status.
Example:
constexpr FwSizeType capacity = 3;
U32 items[capacity];
ExternalStack<U32> stack(items, capacity);
ASSERT_EQ(stack.getSize(), 0);
auto status = stack.push(42);
ASSERT_EQ(status, Success::SUCCESS);
ASSERT_EQ(stack.getSize(), 1);
<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).