mirror of
https://github.com/nasa/fprime.git
synced 2025-12-11 13:54:34 -06:00
* Revise SDD for SetBase * Revise SDD for SetBase * Revise SDD for Fw/DataStructures * Revise SDD for FifoQueue * Revise SDD for Fw/DataStructures * Revise SDD for MapBase * Revise SDD for StackBase * Revise SDD for Fw/DataStructures * Revise SDD for Fw/DataStructures * Add StackBase.hpp * Add ExternalStack.hpp * Add Stack.hpp * Add ExternalStackTest * Revise Stack tests * Revise ExternalStack * Revise ExternalStackTest * Revise ExternalStackTest * Revise ExternalStackTest * Revise ExternalStackTest * Add StackTest * Revise SDD for Fw/DataStructures * Revise SDD for Fw/DataStructures * Revise SDD for Fw/DataStructures * Add MapIterator * Add SetIterator * Add SetOrMapIterator * Add MapBase.hpp * Revise SDD for Fw/DataStructures * Revise SDD for ArraySetOrMapImpl * Revise SDD for ArraySetOrMapImpl * Revise SDD for ExternalArray * Revise SDD for Fw/DataStructures * Revise SDD for Fw/DataStructures * Revise MapBase * Revise MapBase * Revise comments * Revise SDD for ArraySetOrMapImpl * Revise Fw/DataStructures * Add ArraySetOrMapImpl * Add ExternalArrayMap * Revise ExternalArrayMap * Revise Fw/DataStructures * Revise SetBase * Revise SDD for Fw/DataStructures * Revise SDD for ExternalArraySet * Revise SDD for ExternalArraySet * Revise SDD for ArraySetOrMapImpl * Revise Fw/DataStructures * Revise SDD for Fw/DataStructures * Revise Fw/DataStructures tests * Revise unit tests for Fw/DataStructures * Revise tests for ArraySetOrMapImpl * Revise unit tests for Fw/DataStructures * Revise unit tests for Fw/DataStructures * Revise unit tests for ArraySetOrMapImpl * Revise unit tests for ArraySetOrMapImpl * Revise unit tests for ArraySetOrMapImpl * Revise unit tests for ArraySetOrMapImpl * Revise unit tests for ArraySetOrMapImpl * Revise unit tests for ArraySetOrMapImpl * Revise unit tests for Fw/DataStructures * Revise SDD for SetOrMapIterator * Add ExternalArrayMapTest * Revise ExternalArrayMapTest * Revise design for sets and maps * Revert changes to design * Revise unit tests for Fw/DataStructures * Revise unit tests for Fw/DataStructures * Revise ExternalArrayMapTest * Revise ExternalArrayMapTest * Revise unit tests for ArraySetOrMapImpl * Revise ExternalArrayMapTest * Revise ExternalArrayMapTest and MapTest * Revise MapTestScenarios * Revise ExternalArrayMapTest * Revise ExternalArrayMapTest * Revise ExternalArrayMapTest * Revise array set and map Remove at function from interface. It breaks the array or set abstraction. It provides little value, since one can use the iterator provided by SetBase or MapBase to range over the elements. * Revise ExternalArrayMapTest * Add ExternalArraySetTest * Revise ExternalArraySet and ExternalArrayMap * Revise ExternalArraySetTest * Revise ExternalArraySetTest * Revise ExternalArraySetTest * Revise ExternalArraySetTest * Revise ExternalArraySetTest * Revise ExternalArraySetTest * Revise ExternalArraySetTest and ExternalArrayMapTest * Revise ArraySetOrMapImplTest * Revise ExternalArrayMapTest * Revise ExternalArraySetTest * Revise SDD for ArrayMap * Revise SDD for ArraySet * Revise SDD for ArraySet * Add ArrayMap * Revise ArrayMapTest * Revise Fw/DataStructures * Revise SDDs for ArrayMap and ArraySet * Revise Fw/DataStructures * Refactor map test scenarios * Refactor data structures tests * Refactor SetTestScenarios * Refactor FifoQueueTestScenarios * Refactor ExternalFifoQueueTest * Revise Fifo Queue tests * Refactor ExternalFifoQueueTest * Revise comments * Revise Stack tests * Revise Stack tests * Refactor Stack tests * Revise Stack tests * Revise Array Remove getStaticSize * Refactor Fifo tests * Refactor ArraySetOrMapImplTest * Revise data structures design Rename Iterator to Entry * Revise data structures implementation Rename Iterator to Entry * Revise data structures impl and test Rename Iterator to Entry throughout * Revise data structures implementation Rename SetOrMapEntry to SetOrMapImplEntry * Revise data structure implementation Rename Entry to ImplEntry * Revise data structures design Rename symbols to match implementation * Revise design for data structures Add ConstIterator to Map * Revise ArraySetOrMapImpl Add ConstIterator * Add iterators to DS implementation * Revise map iteration * Revise unit tests Use iterators for maps * Revise iterators * Revise iterators * Rename MapEntry to MapConstEntry * Revise map interface * Rename SetOrMapImplEntry to SetOrMapImplConstEntry * Revert "Rename SetOrMapImplEntry to SetOrMapImplConstEntry" This reverts commit cc6371d03c8f65fa130212d589812cf4ab3714fe. * Rename SetEntry to SetConstEntry * Add SetConstIterator * Revise SetBase and unit tests Use iterators * Revise set interface * Revise comments * Reformat code * Revise array set and map impl Remove forward links * Revise data structures tests * Revise Set iterator * Remove SetConstEntry * Refactor SetOrMapImplEntry * Pull in changes from rb-tree branch * Revise MapBase * Revise MapBase and docs * Revise MapBase * Revise MapBase * Revise iterators * Revise MapConstIterator docs * Rename MapConstEntry to MapEntry * Revise MapEntry * Fix MapBase docs * Revise MapConstIterator * Revise MapEntry * Revise MapConstIterator docs * Revise docs for ExternalArrayMap * Revise ArrayMap docs * Revise ArraySetOrMapImpl * Revise SetOrMapImplEntry * Revise MapEntry * Revise map and set interfaces * Revert changes to map interface * Rename MapEntry to MapEntryBase * Revise type aliases * Reformat code * Revise SetBase * Revise map interface * Revise set and map interface * Revise ExternalArraySet docs * Revise ArraySet * Revise ArraySet docs * Revise SetConstIterator * Revise SetBase * Revise SetBase docs * Revise SetBase * Revise ArraySet * Revise ArraySet docs * Revise ExternalArraySet docs * Add SetOrMapImplEntry * Revise ArraySetOrMapImpl * Revise Fw/DataStructures Reformat code * Revise Fw/DataStructures Fix compile errors on Linux * Revise Fw/DataStructures Fix compile errors on Linux * Revise Fw/DataStructures Fix compile errors on Linux * Revise Fw/DataStructures Fix compile errors on Linux * Fix comments * Revise Fw/DataStructures Fix compile errors on Linux * Revise ArrayMap docs * Remove helper scripts * Revise tests for Fw/DataStructures * Fix spelling * Fix Markdown link * Fix uninitialized variable in test * Fix uninitialized variable in test * Fix "spelling" Why is the spelling check enforcing arbitrary rules of style? * Fix comments * Revise tests for ArraySetOrMapImpl * Revise comment * Revise ArraySetOrMap impl * Revise formatting * Revise docs * Revise docs for Fw/DataStructures * Revise Array and ExternalArray Add static assertions * Revise FifoQueue and Stack Add static assertions * Revise ArraySet and ArrayMap Add static assertions * Revise ArrayMap tests * Revise ExternalArraySet tests * Refactor ArraySetTest * Revise array initialization * Revise comments * Revise Array initialization * Revise Array design and implementation * Revert changes to Fw/DataStructures * Revise Array * Revise Array * Revise Array * Fix formatting * Add SizedContainer base class * Revise StackBase Make it inherit from SizedContainer Revise stack tests * Revise MapBase Make it inherit from SizedContainer Revise tests * Revise SetBase Make it inherit from SizedContainer Revise tests * Revise DataStructures design Add SizedContainer * Revise SDD for DataStructures * Revise DataStructures design * Revise DataStructures design * Revise DataStructures design * Revise DataStructures design * Fix spelling * Revise zero-arg constructor for Array * Revise Array interface Make it consistent with the arrays generated by FPP * Fix to assertion
290 lines
9.9 KiB
C++
290 lines
9.9 KiB
C++
// ======================================================================
|
|
// \title ArraySetOrMapImpl
|
|
// \author bocchino
|
|
// \brief An array-based implementation of a set or map
|
|
// ======================================================================
|
|
|
|
#ifndef Fw_ArraySetOrMapImpl_HPP
|
|
#define Fw_ArraySetOrMapImpl_HPP
|
|
|
|
#include "Fw/DataStructures/ExternalArray.hpp"
|
|
#include "Fw/DataStructures/SetOrMapImplConstIterator.hpp"
|
|
#include "Fw/DataStructures/SetOrMapImplEntry.hpp"
|
|
#include "Fw/Types/Assert.hpp"
|
|
#include "Fw/Types/SuccessEnumAc.hpp"
|
|
|
|
namespace Fw {
|
|
|
|
template <typename KE, typename VN>
|
|
class ArraySetOrMapImpl final {
|
|
// ----------------------------------------------------------------------
|
|
// Friend class for testing
|
|
// ----------------------------------------------------------------------
|
|
|
|
template <typename KK, typename VV>
|
|
friend class ArraySetOrMapImplTester;
|
|
|
|
public:
|
|
// ----------------------------------------------------------------------
|
|
// Public types
|
|
// ----------------------------------------------------------------------
|
|
|
|
//! The type of an entry in the set or map
|
|
using Entry = SetOrMapImplEntry<KE, VN>;
|
|
|
|
//! Const iterator
|
|
class ConstIterator final : public SetOrMapImplConstIterator<KE, VN> {
|
|
public:
|
|
using ImplKind = typename SetOrMapImplConstIterator<KE, VN>::ImplKind;
|
|
|
|
public:
|
|
//! Default constructor
|
|
ConstIterator() {}
|
|
|
|
//! Constructor providing the implementation
|
|
ConstIterator(const ArraySetOrMapImpl<KE, VN>& impl) : SetOrMapImplConstIterator<KE, VN>(), m_impl(&impl) {}
|
|
|
|
//! Copy constructor
|
|
ConstIterator(const ConstIterator& it)
|
|
: SetOrMapImplConstIterator<KE, VN>(), m_impl(it.m_impl), m_index(it.m_index) {}
|
|
|
|
//! Destructor
|
|
~ConstIterator() override = default;
|
|
|
|
public:
|
|
//! Copy assignment operator
|
|
ConstIterator& operator=(const ConstIterator& it) {
|
|
this->m_impl = it.m_impl;
|
|
this->m_index = it.m_index;
|
|
return *this;
|
|
}
|
|
|
|
//! Equality comparison operator
|
|
bool compareEqual(const ConstIterator& it) const {
|
|
bool result = false;
|
|
if ((this->m_impl == nullptr) && (it.m_impl == nullptr)) {
|
|
result = true;
|
|
} else if (this->m_impl == it.m_impl) {
|
|
result |= (this->m_index == it.m_index);
|
|
result |= (!this->isInRange() and !it.isInRange());
|
|
}
|
|
return result;
|
|
}
|
|
|
|
//! Return the impl kind
|
|
//! \return The impl kind
|
|
ImplKind implKind() const override { return ImplKind::ARRAY; }
|
|
|
|
//! Get the set or map impl entry pointed to by this iterator
|
|
//! \return The set or map impl entry
|
|
const Entry& getEntry() const override {
|
|
FW_ASSERT(this->m_impl != nullptr);
|
|
FW_ASSERT(this->isInRange(), static_cast<FwAssertArgType>(this->m_index),
|
|
static_cast<FwAssertArgType>(this->m_impl->m_size));
|
|
return this->m_impl->m_entries[this->m_index];
|
|
}
|
|
|
|
//! Increment operator
|
|
void increment() override {
|
|
if (this->isInRange()) {
|
|
this->m_index++;
|
|
}
|
|
}
|
|
|
|
//! Check whether the iterator is in range
|
|
bool isInRange() const override {
|
|
FW_ASSERT(this->m_impl != nullptr);
|
|
return this->m_index < this->m_impl->m_size;
|
|
}
|
|
|
|
//! Set the iterator to the end value
|
|
void setToEnd() {
|
|
FW_ASSERT(this->m_impl != nullptr);
|
|
this->m_index = this->m_impl->m_size;
|
|
}
|
|
|
|
private:
|
|
//! The implementation over which to iterate
|
|
const ArraySetOrMapImpl<KE, VN>* m_impl = nullptr;
|
|
|
|
//! The current iteration index
|
|
FwSizeType m_index = 0;
|
|
};
|
|
|
|
public:
|
|
// ----------------------------------------------------------------------
|
|
// Public constructors and destructors
|
|
// ----------------------------------------------------------------------
|
|
|
|
//! Zero-argument constructor
|
|
ArraySetOrMapImpl() = default;
|
|
|
|
//! Constructor providing typed backing storage.
|
|
//! entries must point to at least capacity elements of type Entry.
|
|
ArraySetOrMapImpl(Entry* entries, //!< The entries
|
|
FwSizeType capacity //!< The capacity
|
|
) {
|
|
this->setStorage(entries, capacity);
|
|
}
|
|
|
|
//! Constructor providing untyped backing storage.
|
|
//! data must be aligned according to getByteArrayAlignment().
|
|
//! data must contain at least getByteArraySize(capacity) bytes.
|
|
ArraySetOrMapImpl(ByteArray data, //!< The data
|
|
FwSizeType capacity //!< The capacity
|
|
) {
|
|
this->setStorage(data, capacity);
|
|
}
|
|
|
|
//! Copy constructor
|
|
ArraySetOrMapImpl(const ArraySetOrMapImpl<KE, VN>& impl) { *this = impl; }
|
|
|
|
//! Destructor
|
|
~ArraySetOrMapImpl() = default;
|
|
|
|
public:
|
|
// ----------------------------------------------------------------------
|
|
// Public member functions
|
|
// ----------------------------------------------------------------------
|
|
|
|
//! operator=
|
|
ArraySetOrMapImpl<KE, VN>& operator=(const ArraySetOrMapImpl<KE, VN>& impl) {
|
|
if (&impl != this) {
|
|
m_entries = impl.m_entries;
|
|
m_size = impl.m_size;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
//! Get the begin iterator
|
|
ConstIterator begin() const { return ConstIterator(*this); }
|
|
|
|
//! Clear the set or map
|
|
void clear() { this->m_size = 0; }
|
|
|
|
//! Get the end iterator
|
|
ConstIterator end() const {
|
|
auto it = begin();
|
|
it.setToEnd();
|
|
return it;
|
|
}
|
|
|
|
//! Find a value associated with a key in the map or an element in a set
|
|
//! \return SUCCESS if the item was found
|
|
Success find(const KE& keyOrElement, //!< The key or element
|
|
VN& valueOrNil //!< The value or Nil
|
|
) const {
|
|
auto status = Success::FAILURE;
|
|
for (FwSizeType i = 0; i < this->m_size; i++) {
|
|
const auto& e = this->m_entries[i];
|
|
if (e.getKey() == keyOrElement) {
|
|
valueOrNil = e.getValue();
|
|
status = Success::SUCCESS;
|
|
break;
|
|
}
|
|
}
|
|
return status;
|
|
}
|
|
|
|
//! Get the capacity of the set or map (max number of entries)
|
|
//! \return The capacity
|
|
FwSizeType getCapacity() const { return this->m_entries.getSize(); }
|
|
|
|
//! Get the size (number of entries)
|
|
//! \return The size
|
|
FwSizeType getSize() const { return this->m_size; }
|
|
|
|
//! Insert an element in the set or a (key, value) pair in the map
|
|
//! \return SUCCESS if there is room in the set or map
|
|
Success insert(const KE& keyOrElement, //!< The key or element
|
|
const VN& valueOrNil //!< The value or Nil
|
|
) {
|
|
auto status = Success::FAILURE;
|
|
for (FwSizeType i = 0; i < this->m_size; i++) {
|
|
auto& e = this->m_entries[i];
|
|
if (e.getKey() == keyOrElement) {
|
|
e.setValueOrNil(valueOrNil);
|
|
status = Success::SUCCESS;
|
|
break;
|
|
}
|
|
}
|
|
if ((status == Success::FAILURE) && (this->m_size < this->getCapacity())) {
|
|
this->m_entries[this->m_size] = Entry(keyOrElement, valueOrNil);
|
|
this->m_size++;
|
|
status = Success::SUCCESS;
|
|
}
|
|
return status;
|
|
}
|
|
|
|
//! Remove an element from the set or a (key, value) pair from the map
|
|
//! \return SUCCESS if the key or element was there
|
|
Success remove(const KE& keyOrElement, //!< The key or element
|
|
VN& valueOrNil //!< The value or Nil
|
|
) {
|
|
auto status = Success::FAILURE;
|
|
for (FwSizeType i = 0; i < this->m_size; i++) {
|
|
if (this->m_entries[i].getKey() == keyOrElement) {
|
|
valueOrNil = this->m_entries[i].getValue();
|
|
if (i < this->m_size - 1) {
|
|
this->m_entries[i] = this->m_entries[this->m_size - 1];
|
|
}
|
|
this->m_size--;
|
|
status = Success::SUCCESS;
|
|
break;
|
|
}
|
|
}
|
|
return status;
|
|
}
|
|
|
|
//! Set the backing storage (typed data)
|
|
//! entries must point to at least capacity elements of type Entry.
|
|
void setStorage(Entry* entries, //!< The entries
|
|
FwSizeType capacity //!< The capacity
|
|
) {
|
|
this->m_entries.setStorage(entries, capacity);
|
|
this->clear();
|
|
}
|
|
|
|
//! Set the backing storage (untyped data)
|
|
//! data must be aligned according to getByteArrayAlignment().
|
|
//! data must contain at least getByteArraySize(capacity) bytes.
|
|
void setStorage(ByteArray data, //!< The data
|
|
FwSizeType capacity //!< The capacity
|
|
) {
|
|
this->m_entries.setStorage(data, capacity);
|
|
this->clear();
|
|
}
|
|
|
|
public:
|
|
// ----------------------------------------------------------------------
|
|
// Public static functions
|
|
// ----------------------------------------------------------------------
|
|
|
|
//! Get the alignment of the storage for an ArraySetOrMapImpl
|
|
//! \return The alignment
|
|
static constexpr U8 getByteArrayAlignment() { return ExternalArray<Entry>::getByteArrayAlignment(); }
|
|
|
|
//! Get the size of the storage for an ExternalArray of the specified capacity,
|
|
//! as a byte array
|
|
//! \return The byte array size
|
|
static constexpr FwSizeType getByteArraySize(FwSizeType capacity //!< The capacity
|
|
) {
|
|
return ExternalArray<Entry>::getByteArraySize(capacity);
|
|
}
|
|
|
|
private:
|
|
// ----------------------------------------------------------------------
|
|
// Private member variables
|
|
// ----------------------------------------------------------------------
|
|
|
|
//! The array for storing the set or map entries
|
|
ExternalArray<Entry> m_entries = {};
|
|
|
|
//! The number of entries in the set or map
|
|
FwSizeType m_size = 0;
|
|
};
|
|
|
|
} // namespace Fw
|
|
|
|
#endif
|