From 9551876911a315d108fd8b2ad0b3f3d2bf0099a1 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 22 May 2025 08:28:17 -0700 Subject: [PATCH 001/458] Add sdd for Fw/Ds --- Fw/Ds/docs/sdd.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 Fw/Ds/docs/sdd.md diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md new file mode 100644 index 00000000000..733444a7bd0 --- /dev/null +++ b/Fw/Ds/docs/sdd.md @@ -0,0 +1,29 @@ +# Fw::Ds: Basic Data Structures + +This directory contains a library of basic data structures. + +## 1. Arrays + +TODO + +## 2. Queues + +TODO + +## 3. Linked List + +TODO + +## 4. Sets and Maps + +### 4.1. Array-Based Set and Map + +TODO + +### 4.2. Hash Set and Map + +TODO + +### 4.3. Balanced Binary Tree Set and Map + +TODO From f26f875216bb9498fcf44d6e727cb61dbab1f4f8 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 22 May 2025 15:24:55 -0700 Subject: [PATCH 002/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 71 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 733444a7bd0..2bba6303d2c 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -4,6 +4,77 @@ This directory contains a library of basic data structures. ## 1. Arrays +An *array* _A_ stores _n_ elements for _n > 0_ at indices +0, 1, ... _n - 1_. +The elements are stored in *backing memory* _M_. +An array provides bounds-checked access to the array elements. + +### 1.1. Array + +`Array` is a class template representing an array +with internal storage. +It maintains the backing memory _M_ as a member variable. + +#### 1.1.1. Template Parameters + +`Array` has two template parameters: + +1. The type `typename T` + +1. The size `FwSizeType S` + +#### 1.1.2. Private Member Variables + +`Array` has one private variable `m_elements` for +storing the array elements. +It is a native C++ array of type `T[S]`. + +#### 1.1.3. Constructors + +```c++ +Array() +``` + +Construct an array _A_ of type _T_ and size _S_ with default +values for all elements. + +Example: +``` +Array a; +``` + +```c++ +Array(const std::initializer_list&il) +``` + +Construct an array _A_ of type _T_ and size _S_. +Initialize the first _n_ elements from _il_, where +_n_ is the minimum of _S_ and the size of _il_. +Initialize any other elements of _A_ with default values. + +Example: +``` +Array a({ 1, 2, 3 }); +``` + +```c++ +Array(const T& elt) +``` + +Construct an array _A_ of type _T_ and size _S_. +Initialize all elements of _A_ with _elt_. + +Example: +``` +Array a(3); +``` + +#### 1.1.4. Public Member Functions + +TODO + +### 1.2. External Array + TODO ## 2. Queues From 6c8d0c18e291915d105fb0b6c2a92813c1cc6dff Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 22 May 2025 15:38:05 -0700 Subject: [PATCH 003/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 2bba6303d2c..b0796d11819 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -31,38 +31,44 @@ It is a native C++ array of type `T[S]`. #### 1.1.3. Constructors +*Zero-argument constructor:* + ```c++ Array() ``` -Construct an array _A_ of type _T_ and size _S_ with default -values for all elements. +Construct an array _A_ of type `T` and size `S`. +Initialize each element of `m_elements` with the default value for `T`. Example: ``` Array a; ``` +*Initializer list constructor:* + ```c++ -Array(const std::initializer_list&il) +Array(const std::initializer_list& il) ``` -Construct an array _A_ of type _T_ and size _S_. -Initialize the first _n_ elements from _il_, where -_n_ is the minimum of _S_ and the size of _il_. -Initialize any other elements of _A_ with default values. +Construct an array _A_ of type `T` and size `S`. +Initialize the first _n_ elements of `m_elements` from `il`, where +_n_ is the minimum of `S` and the size of `il`. +Initialize any other elements of `m_elements` with default values. Example: ``` Array a({ 1, 2, 3 }); ``` +*Single-item constructor:* + ```c++ Array(const T& elt) ``` -Construct an array _A_ of type _T_ and size _S_. -Initialize all elements of _A_ with _elt_. +Construct an array _A_ of type `T` and size `S`. +Initialize each element of `m_elements` with `elt`. Example: ``` From e5e49c7770b26307ac448eaf68fa7c0160ac46f5 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 22 May 2025 17:23:40 -0700 Subject: [PATCH 004/458] Revise SDD for Ds --- Fw/Ds/docs/sdd.md | 97 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 86 insertions(+), 11 deletions(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index b0796d11819..af1d4aa8b71 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -4,9 +4,9 @@ This directory contains a library of basic data structures. ## 1. Arrays -An *array* _A_ stores _n_ elements for _n > 0_ at indices +An **array** _A_ stores _n_ elements for _n > 0_ at indices 0, 1, ... _n - 1_. -The elements are stored in *backing memory* _M_. +The elements are stored in **backing memory** _M_. An array provides bounds-checked access to the array elements. ### 1.1. Array @@ -29,12 +29,12 @@ It maintains the backing memory _M_ as a member variable. storing the array elements. It is a native C++ array of type `T[S]`. -#### 1.1.3. Constructors +#### 1.1.3. Construction and Destruction -*Zero-argument constructor:* +**Zero-argument constructor:** ```c++ -Array() +Array() ``` Construct an array _A_ of type `T` and size `S`. @@ -45,10 +45,10 @@ Example: Array a; ``` -*Initializer list constructor:* +**Initializer list constructor:** ```c++ -Array(const std::initializer_list& il) +Array(const std::initializer_list& il) ``` Construct an array _A_ of type `T` and size `S`. @@ -61,10 +61,10 @@ Example: Array a({ 1, 2, 3 }); ``` -*Single-item constructor:* +**Single-item constructor:** ```c++ -Array(const T& elt) +Array(const T& elt) ``` Construct an array _A_ of type `T` and size `S`. @@ -72,12 +72,87 @@ Initialize each element of `m_elements` with `elt`. Example: ``` -Array a(3); +Array a(10); ``` +**Destructor (implicitly declared):** + +```c++ +~Array() +``` + +Destroy all the elements of `m_elements`. + #### 1.1.4. Public Member Functions -TODO +**operator[]:** + +```c++ +T& operator[](FwSizeType i) +const T& operator[](FwSizeType i) const +``` + +This operator asserts that `i < S`. +If the assertion is true, then it returns a reference to `m_elements[i]`. + +Example: +``` +const U32 x = a[0]; +a[0]++; +``` + +**operator=:** + +```c++ +Array& operator=(const Array& a) +``` + +If `&a == this` then this operator does nothing. +Otherwise it overwrites each element of `m_elements` with the corresponding +element of `a`. + +Example: +``` +Array a1(1); +Array a2(2); +a1 = a2; +``` + +**getElements:** + +```c++ +T[S]& getElements() +const T[S]& getElements() const +``` + +This function returns a reference to `m_elements`. + +Example: +``` +Array a; +auto& elements1 = a.getElements(); +FW_ASSERT(elements1[0] == 0); +elements1[0] = 1; +const auto& elements2 = a.getElements(); +FW_ASSERT(elements2[0] == 1); +``` + +#### 1.1.5. Public Static Functions + +**getSize:** + +```c++ +static constexpr FwSizeType getSize() +``` + +This function returns the size `S` of the array. + +Example: +``` +Array a; +const auto size = a.getSize(); +FW_ASSERT(size == 10); +``` ### 1.2. External Array From 9b129a493116a88a42803360da659a349777a3d7 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 22 May 2025 17:25:50 -0700 Subject: [PATCH 005/458] Revise SDD for Ds --- Fw/Ds/docs/sdd.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index af1d4aa8b71..be8a3e783ed 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -40,8 +40,8 @@ Array() Construct an array _A_ of type `T` and size `S`. Initialize each element of `m_elements` with the default value for `T`. -Example: -``` +_Example:_ +```c++ Array a; ``` @@ -56,8 +56,8 @@ Initialize the first _n_ elements of `m_elements` from `il`, where _n_ is the minimum of `S` and the size of `il`. Initialize any other elements of `m_elements` with default values. -Example: -``` +_Example:_ +```c++ Array a({ 1, 2, 3 }); ``` @@ -70,8 +70,8 @@ Array(const T& elt) Construct an array _A_ of type `T` and size `S`. Initialize each element of `m_elements` with `elt`. -Example: -``` +_Example:_ +```c++ Array a(10); ``` @@ -95,8 +95,8 @@ const T& operator[](FwSizeType i) const This operator asserts that `i < S`. If the assertion is true, then it returns a reference to `m_elements[i]`. -Example: -``` +_Example:_ +```c++ const U32 x = a[0]; a[0]++; ``` @@ -111,8 +111,8 @@ If `&a == this` then this operator does nothing. Otherwise it overwrites each element of `m_elements` with the corresponding element of `a`. -Example: -``` +_Example:_ +```c++ Array a1(1); Array a2(2); a1 = a2; @@ -127,8 +127,8 @@ const T[S]& getElements() const This function returns a reference to `m_elements`. -Example: -``` +_Example:_ +```c++ Array a; auto& elements1 = a.getElements(); FW_ASSERT(elements1[0] == 0); @@ -147,8 +147,8 @@ static constexpr FwSizeType getSize() This function returns the size `S` of the array. -Example: -``` +_Example:_ +```c++ Array a; const auto size = a.getSize(); FW_ASSERT(size == 10); From 10e44796033e19486ec8d70a27fca217cceacfd9 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 22 May 2025 17:42:27 -0700 Subject: [PATCH 006/458] Revise SDD for Ds --- Fw/Ds/docs/sdd.md | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index be8a3e783ed..80f5f557097 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -5,13 +5,13 @@ This directory contains a library of basic data structures. ## 1. Arrays An **array** _A_ stores _n_ elements for _n > 0_ at indices -0, 1, ... _n - 1_. +0, 1, ..., _n - 1_. The elements are stored in **backing memory** _M_. An array provides bounds-checked access to the array elements. ### 1.1. Array -`Array` is a class template representing an array +`Array` is a `final` class template representing an array with internal storage. It maintains the backing memory _M_ as a member variable. @@ -75,7 +75,23 @@ _Example:_ Array a(10); ``` -**Destructor (implicitly declared):** +**Copy constructor:** + +```c++ +Array(const Array& a) +``` + +Construct an array _A_ of type `T` and size `S`. +Initialize the elements of `m_elements` with the +elements of `a.m_elements`. + +_Example:_ +```c++ +Array a1(10); +Array a2(a1); +``` + +**Destructor:** ```c++ ~Array() @@ -97,8 +113,10 @@ If the assertion is true, then it returns a reference to `m_elements[i]`. _Example:_ ```c++ -const U32 x = a[0]; +Array a; +ASSERT_EQ(a[0], 0); a[0]++; +ASSERT_EQ(a[0], 1); ``` **operator=:** From 00f6f431f434128e6701ffadda6d5c64f0e442a6 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 22 May 2025 17:47:29 -0700 Subject: [PATCH 007/458] Revise SDD for Ds --- Fw/Ds/docs/sdd.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 80f5f557097..adf31e8e1ef 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -51,10 +51,11 @@ Array a; Array(const std::initializer_list& il) ``` -Construct an array _A_ of type `T` and size `S`. -Initialize the first _n_ elements of `m_elements` from `il`, where -_n_ is the minimum of `S` and the size of `il`. -Initialize any other elements of `m_elements` with default values. +1. Assert that `il.size == S`. + +1. Construct an array _A_ of type `T` and size `S`. + +1. Initialize `m_elements` from `il`. _Example:_ ```c++ @@ -149,10 +150,10 @@ _Example:_ ```c++ Array a; auto& elements1 = a.getElements(); -FW_ASSERT(elements1[0] == 0); +ASSERT_EQ(elements1[0], 0); elements1[0] = 1; const auto& elements2 = a.getElements(); -FW_ASSERT(elements2[0] == 1); +ASSERT_EQ(elements2[0], 1); ``` #### 1.1.5. Public Static Functions @@ -169,7 +170,7 @@ _Example:_ ```c++ Array a; const auto size = a.getSize(); -FW_ASSERT(size == 10); +ASSERT_EQ(size, 10); ``` ### 1.2. External Array From 59d6a30faa1b9f9e6003581b77e15b48ea5888ba Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 22 May 2025 17:50:25 -0700 Subject: [PATCH 008/458] Revise SDD for Array --- Fw/Ds/docs/sdd.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index adf31e8e1ef..a040866a27d 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -23,11 +23,13 @@ It maintains the backing memory _M_ as a member variable. 1. The size `FwSizeType S` +`Array` statically asserts that `S > 0`. + #### 1.1.2. Private Member Variables `Array` has one private variable `m_elements` for storing the array elements. -It is a native C++ array of type `T[S]`. +It is a primitive C++ array of type `T[S]`. #### 1.1.3. Construction and Destruction From 4611edb3dbb288cc58183435c1eb5e78304ddf4e Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 22 May 2025 18:00:22 -0700 Subject: [PATCH 009/458] Revise SDD for Array --- Fw/Ds/docs/sdd.md | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index a040866a27d..1addfa20569 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -39,7 +39,6 @@ It is a primitive C++ array of type `T[S]`. Array() ``` -Construct an array _A_ of type `T` and size `S`. Initialize each element of `m_elements` with the default value for `T`. _Example:_ @@ -55,8 +54,6 @@ Array(const std::initializer_list& il) 1. Assert that `il.size == S`. -1. Construct an array _A_ of type `T` and size `S`. - 1. Initialize `m_elements` from `il`. _Example:_ @@ -70,7 +67,6 @@ Array a({ 1, 2, 3 }); Array(const T& elt) ``` -Construct an array _A_ of type `T` and size `S`. Initialize each element of `m_elements` with `elt`. _Example:_ @@ -84,7 +80,6 @@ Array a(10); Array(const Array& a) ``` -Construct an array _A_ of type `T` and size `S`. Initialize the elements of `m_elements` with the elements of `a.m_elements`. @@ -111,8 +106,9 @@ T& operator[](FwSizeType i) const T& operator[](FwSizeType i) const ``` -This operator asserts that `i < S`. -If the assertion is true, then it returns a reference to `m_elements[i]`. +1. Assert that `i < S`. + +1. Return a reference to `m_elements[i]`. _Example:_ ```c++ @@ -128,8 +124,9 @@ ASSERT_EQ(a[0], 1); Array& operator=(const Array& a) ``` -If `&a == this` then this operator does nothing. -Otherwise it overwrites each element of `m_elements` with the corresponding +1. If `&a == this` then do nothing. + +1. Otherwise overwrite each element of `m_elements` with the corresponding element of `a`. _Example:_ @@ -146,7 +143,7 @@ T[S]& getElements() const T[S]& getElements() const ``` -This function returns a reference to `m_elements`. +Return a reference to `m_elements`. _Example:_ ```c++ @@ -166,12 +163,11 @@ ASSERT_EQ(elements2[0], 1); static constexpr FwSizeType getSize() ``` -This function returns the size `S` of the array. +Return the size `S` of the array. _Example:_ ```c++ -Array a; -const auto size = a.getSize(); +const auto size = Array::getSize(); ASSERT_EQ(size, 10); ``` From bdce3343bdeb4fba9b48d1be5c4ab04de4314020 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 22 May 2025 18:02:59 -0700 Subject: [PATCH 010/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 1addfa20569..f8c0a120bad 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -177,6 +177,12 @@ TODO ## 2. Queues +### 2.1. FIFO Queue + +TODO + +### 2.2. LIFO Queue + TODO ## 3. Linked List @@ -185,7 +191,7 @@ TODO ## 4. Sets and Maps -### 4.1. Array-Based Set and Map +### 4.1. Array Set and Map TODO From c2ba22aae26d214297554194ce3f1621af54b036 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 27 May 2025 08:36:51 -0700 Subject: [PATCH 011/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index f8c0a120bad..e64d7429e6f 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -31,7 +31,7 @@ It maintains the backing memory _M_ as a member variable. storing the array elements. It is a primitive C++ array of type `T[S]`. -#### 1.1.3. Construction and Destruction +#### 1.1.3. Public Constructors and Destructors **Zero-argument constructor:** @@ -56,9 +56,12 @@ Array(const std::initializer_list& il) 1. Initialize `m_elements` from `il`. -_Example:_ +_Examples:_ ```c++ +// Explicit call to constructor Array a({ 1, 2, 3 }); +// Implicit call to constructor via initialization +Array b = { 1, 2, 3 }; ``` **Single-item constructor:** @@ -71,7 +74,10 @@ Initialize each element of `m_elements` with `elt`. _Example:_ ```c++ +// Explicit call to constructor Array a(10); +// Implicit call to constructor via initialization +Array b = 10; ``` **Copy constructor:** From 74588f3e43003668bb73b35c3b8f13c7c07e68e6 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 27 May 2025 08:40:59 -0700 Subject: [PATCH 012/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index e64d7429e6f..e8b1bb2750d 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -83,7 +83,7 @@ Array b = 10; **Copy constructor:** ```c++ -Array(const Array& a) +Array(const Array& a) ``` Initialize the elements of `m_elements` with the @@ -122,12 +122,13 @@ Array a; ASSERT_EQ(a[0], 0); a[0]++; ASSERT_EQ(a[0], 1); +ASSERT_DEATH(a[11], "Assert"); ``` **operator=:** ```c++ -Array& operator=(const Array& a) +Array& operator=(const Array& a) ``` 1. If `&a == this` then do nothing. From c66a774275196d83a217377d4cff76472503efb7 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 27 May 2025 09:01:44 -0700 Subject: [PATCH 013/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index e8b1bb2750d..0d583f71da2 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -91,7 +91,9 @@ elements of `a.m_elements`. _Example:_ ```c++ +// Call the single-item constructor Array a1(10); +// Call the copy constructor Array a2(a1); ``` From a1014125e2f4aa147d521bfcc83785f6907143d9 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 27 May 2025 09:04:22 -0700 Subject: [PATCH 014/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 0d583f71da2..8f99e49ee47 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -121,10 +121,13 @@ const T& operator[](FwSizeType i) const _Example:_ ```c++ Array a; +// Constant access ASSERT_EQ(a[0], 0); +// Mutable access a[0]++; ASSERT_EQ(a[0], 1); -ASSERT_DEATH(a[11], "Assert"); +// Out-of-bounds access +ASSERT_DEATH(a[10], "Assert"); ``` **operator=:** @@ -157,9 +160,11 @@ Return a reference to `m_elements`. _Example:_ ```c++ Array a; +// Mutable reference auto& elements1 = a.getElements(); ASSERT_EQ(elements1[0], 0); elements1[0] = 1; +// Constant reference const auto& elements2 = a.getElements(); ASSERT_EQ(elements2[0], 1); ``` From e77468b7e1040b1d6fc4013c0604548bdf8c0fb9 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 27 May 2025 09:11:09 -0700 Subject: [PATCH 015/458] Revise SDD for ExternalArray --- Fw/Ds/docs/sdd.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 8f99e49ee47..739d34b6d65 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -187,6 +187,24 @@ ASSERT_EQ(size, 10); ### 1.2. External Array +`ExternalArray` is a `final` class template representing an array with external +storage. +It stores a pointer to the backing memory _M_. + +#### 1.2.1. Template Parameters + +TODO + +#### 1.2.2. Private Member Variables + +TODO + +#### 1.2.3. Public Constructors and Destructors + +TODO + +#### 1.2.4. Public Member Functions + TODO ## 2. Queues From 1cfc7482d7aa1fe3a93b19d580e8b234e41ef093 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 27 May 2025 09:17:14 -0700 Subject: [PATCH 016/458] Revise SDD for ExternalArray --- Fw/Ds/docs/sdd.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 739d34b6d65..0f6f4e46616 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -193,11 +193,18 @@ It stores a pointer to the backing memory _M_. #### 1.2.1. Template Parameters -TODO +`ExternalArray` has one template parameter: + +1. The type `typename T` #### 1.2.2. Private Member Variables -TODO +`ExternalArray` has the following private member variables. + +|Name|Type|Purpose| +|----|----|-------| +|`m_elements`|`T*`|Points to the backing memory| +|`m_size`|`FwSizeType`|Stores the size (number of elements) of the array| #### 1.2.3. Public Constructors and Destructors From b6549d99481db8b2fae6af25e55f6206d1b21eb9 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 27 May 2025 09:34:21 -0700 Subject: [PATCH 017/458] Revise SDD for ExternalArray --- Fw/Ds/docs/sdd.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 0f6f4e46616..b89dedddd94 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -201,10 +201,10 @@ It stores a pointer to the backing memory _M_. `ExternalArray` has the following private member variables. -|Name|Type|Purpose| -|----|----|-------| -|`m_elements`|`T*`|Points to the backing memory| -|`m_size`|`FwSizeType`|Stores the size (number of elements) of the array| +|Name|Type|Purpose|Initial Value| +|----|----|-------|-------------| +|`m_elements`|`T*`|Points to the backing memory|`nullptr`| +|`m_size`|`FwSizeType`|Stores the size (number of elements) of the array|0| #### 1.2.3. Public Constructors and Destructors From 29fe607e9bb07cfb9d193ea5f8fb1c5ee4b17ba0 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 27 May 2025 09:42:57 -0700 Subject: [PATCH 018/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index b89dedddd94..d2d2bbc0fe6 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -130,7 +130,7 @@ ASSERT_EQ(a[0], 1); ASSERT_DEATH(a[10], "Assert"); ``` -**operator=:** +**operator= with array argument:** ```c++ Array& operator=(const Array& a) @@ -148,6 +148,37 @@ Array a2(2); a1 = a2; ``` +**operator= with element type argument:** + +```c++ +Array& operator=(const T& elt) +``` + +Overwrite each element of `m_elements` with `elt`. + +_Example:_ +```c++ +Array a(); +a = 1; +``` + +**operator= with initializer list argument:** + +```c++ +Array& operator=(const std::initializer_list& il) +``` + +1. Assert that `il.size == S`. + +1. Overwrite each element of `m_elements` with the corresponding element of + `il`. + +_Example:_ +```c++ +Array a(); +a = { 1, 2, 3 }; +``` + **getElements:** ```c++ From eac5aeb87741c30011824b5ac24372a945758abd Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 27 May 2025 11:17:24 -0700 Subject: [PATCH 019/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 41 +++++------------------------------------ 1 file changed, 5 insertions(+), 36 deletions(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index d2d2bbc0fe6..7c51e55cd2b 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -67,17 +67,17 @@ Array b = { 1, 2, 3 }; **Single-item constructor:** ```c++ -Array(const T& elt) +explicit Array(const T& elt) ``` Initialize each element of `m_elements` with `elt`. _Example:_ ```c++ -// Explicit call to constructor -Array a(10); -// Implicit call to constructor via initialization -Array b = 10; +// Explicit call to constructor in variable declaration +Array a(1); +// Explicit call to constructor in assignment +a = Array(2); ``` **Copy constructor:** @@ -148,37 +148,6 @@ Array a2(2); a1 = a2; ``` -**operator= with element type argument:** - -```c++ -Array& operator=(const T& elt) -``` - -Overwrite each element of `m_elements` with `elt`. - -_Example:_ -```c++ -Array a(); -a = 1; -``` - -**operator= with initializer list argument:** - -```c++ -Array& operator=(const std::initializer_list& il) -``` - -1. Assert that `il.size == S`. - -1. Overwrite each element of `m_elements` with the corresponding element of - `il`. - -_Example:_ -```c++ -Array a(); -a = { 1, 2, 3 }; -``` - **getElements:** ```c++ From f0f8537118a6c0f16ee968314dd59eb6161d636f Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 27 May 2025 12:51:15 -0700 Subject: [PATCH 020/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 112 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 107 insertions(+), 5 deletions(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 7c51e55cd2b..34d7a520e22 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -67,10 +67,10 @@ Array b = { 1, 2, 3 }; **Single-item constructor:** ```c++ -explicit Array(const T& elt) +explicit Array(const T& element) ``` -Initialize each element of `m_elements` with `elt`. +Initialize each element of `m_elements` with `element`. _Example:_ ```c++ @@ -201,18 +201,120 @@ It stores a pointer to the backing memory _M_. `ExternalArray` has the following private member variables. -|Name|Type|Purpose|Initial Value| +|Name|Type|Purpose|Default Value| |----|----|-------|-------------| |`m_elements`|`T*`|Points to the backing memory|`nullptr`| |`m_size`|`FwSizeType`|Stores the size (number of elements) of the array|0| #### 1.2.3. Public Constructors and Destructors -TODO +**Zero-argument constructor:** + +```c++ +ExternalArray() +``` + +Initialize the member variables with their default values. + +_Example:_ +```c++ +ExternalArray a; +``` + +**Constructor providing backing storage:** + +```c++ +ExternalArray(T* elements, FwSizeType size) +``` + +Initialize `m_elements` with `elements` and `m_size` with `size`. + +_Example:_ +```c++ +U32 elements[10]; +ExternalArray a(elements, 10); +``` #### 1.2.4. Public Member Functions -TODO +**operator[]:** + +```c++ +T& operator[](FwSizeType i) +const T& operator[](FwSizeType i) const +``` + +1. Assert that `m_elements != nullptr`. + +1. Assert that `i < m_size`. + +1. Return a reference to `m_elements[i]`. + +_Example:_ +```c++ +U32 elements[10]; +ExternalArray(a, 10); +// Constant access +ASSERT_EQ(a[0], 0); +// Mutable access +a[0]++; +ASSERT_EQ(a[0], 1); +// Out-of-bounds access +ASSERT_DEATH(a[10], "Assert"); +``` + +**getElements:** + +```c++ +T* getElements() +const T* getElements() const +``` + +Return `m_elements`. + +_Example:_ +```c++ +U32 elements[10]; +ExternalArray a(elements, 10); +// Mutable pointer +auto& elements1 = a.getElements(); +ASSERT_EQ(elements1[0], 0); +elements1[0] = 1; +// Constant pointer +const auto& elements2 = a.getElements(); +ASSERT_EQ(elements2[0], 1); +``` + +**getSize:** + +```c++ +FwSizeType getSize() +``` + +Return `m_size`. + +_Example:_ +```c++ +U32 elements[10]; +ExternalArray a(elements, 10); +const auto size = a.getSize(); +ASSERT_EQ(size, 10); +``` + +**setStorage:** + +```c++ +void setStorage(T* elements, FwSizeType size) +``` + +Set `m_elements = elements` and `m_size = size`. + +_Example:_ +```c++ +ExternalArray a; +U32 elements[10]; +a.setStorage(elements, 10); +``` ## 2. Queues From cfd5f79303255dad080ff6c141c0cd8051df2ab0 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 27 May 2025 12:53:54 -0700 Subject: [PATCH 021/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 34d7a520e22..2975bc55853 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -253,7 +253,7 @@ const T& operator[](FwSizeType i) const _Example:_ ```c++ U32 elements[10]; -ExternalArray(a, 10); +ExternalArray a(elements, 10); // Constant access ASSERT_EQ(a[0], 0); // Mutable access From bf659f9ef7660b14d6e3a510af00df270c54682e Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 27 May 2025 13:40:14 -0700 Subject: [PATCH 022/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 49 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 2975bc55853..eb2661ac9b6 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -103,7 +103,7 @@ Array a2(a1); ~Array() ``` -Destroy all the elements of `m_elements`. +Destroy each element of `m_elements`. #### 1.1.4. Public Member Functions @@ -130,7 +130,7 @@ ASSERT_EQ(a[0], 1); ASSERT_DEATH(a[10], "Assert"); ``` -**operator= with array argument:** +**Copy assignment operator:** ```c++ Array& operator=(const Array& a) @@ -235,6 +235,33 @@ U32 elements[10]; ExternalArray a(elements, 10); ``` +**Copy constructor:** + +```c++ +ExternalArray(const ExternalArray& a) +``` + +Set `m_elements = a.elements` and `m_size = a.size`. + +_Example:_ +```c++ +U32 elements[3]; +// Call the constructor providing backing storage +ExternalArray a1(elements, 3); +// Call the copy constructor +ExternalArray a2(a1); +``` + +**Destructor:** + +```c++ +~ExternalArray() +``` + +1. If `m_elements == nullptr` then do nothing. + +1. Otherwise destroy each element of `m_elements`. + #### 1.2.4. Public Member Functions **operator[]:** @@ -263,6 +290,24 @@ ASSERT_EQ(a[0], 1); ASSERT_DEATH(a[10], "Assert"); ``` +**Copy assignment operator:** + +```c++ +ExternalArray& operator=(const ExternalArray& a) +``` + +1. If `&a == this` then do nothing. + +1. Otherwise set `m_elements = a.elements` and `m_size = a.size`. + +_Example:_ +```c++ +U32 elements[10]; +ExternalArray a1(elements, 10); +ExternalArray a2; +a2 = a1; +``` + **getElements:** ```c++ From 8256e1b582c215ca0aeb7488293bd5344513717c Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 27 May 2025 16:32:32 -0700 Subject: [PATCH 023/458] Start to add implementation for Fw/Ds --- Fw/CMakeLists.txt | 1 + Fw/Ds/Array.hpp | 89 ++++++++++++++++++++++++++++++ Fw/Ds/CMakeLists.txt | 16 ++++++ Fw/Ds/Ds.cpp | 1 + Fw/Ds/ExternalArray.hpp | 104 +++++++++++++++++++++++++++++++++++ Fw/Ds/test/ut/ArrayTest.cpp | 22 ++++++++ Fw/Ds/test/ut/DsTestMain.cpp | 15 +++++ 7 files changed, 248 insertions(+) create mode 100644 Fw/Ds/Array.hpp create mode 100644 Fw/Ds/CMakeLists.txt create mode 100644 Fw/Ds/Ds.cpp create mode 100644 Fw/Ds/ExternalArray.hpp create mode 100644 Fw/Ds/test/ut/ArrayTest.cpp create mode 100644 Fw/Ds/test/ut/DsTestMain.cpp diff --git a/Fw/CMakeLists.txt b/Fw/CMakeLists.txt index 5ce74bc57b0..1f261274a89 100644 --- a/Fw/CMakeLists.txt +++ b/Fw/CMakeLists.txt @@ -5,6 +5,7 @@ add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Buffer/") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Cmd/") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Com/") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Dp/") +add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Ds/") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Fpy/") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Log/") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Logger/") diff --git a/Fw/Ds/Array.hpp b/Fw/Ds/Array.hpp new file mode 100644 index 00000000000..70e9020e391 --- /dev/null +++ b/Fw/Ds/Array.hpp @@ -0,0 +1,89 @@ +// ====================================================================== +// \title Array +// \author bocchino +// \brief An array that stores its size and provides bounds checking +// ====================================================================== + +#ifndef Ds_Array_HPP +#define Ds_Array_HPP + +#include +#include + +#include "Fw/Types/Assert.hpp" + +namespace Ds { + +template +class Array final { + static_assert(S > 0, "array size must be greater than zero"); + + public: + // ---------------------------------------------------------------------- + // Constructors + // ---------------------------------------------------------------------- + + //! Zero-argument constructor + Array() {} + + //! Initializer list constructor + Array(const std::initializer_list& il) { + FW_ASSERT(il.size() == S, static_cast(il.size()), static_cast(S)); + // TODO + } + +#if 0 + public: + // ---------------------------------------------------------------------- + // Public operators + // ---------------------------------------------------------------------- + + //! Subscript operator + T& operator[](const FwSizeType i //!< The subscript index + ) { + FW_ASSERT(i < this->m_size, static_cast(i)); + return this->m_elements[i]; + } + + //! Const subscript operator + const T& operator[](const FwSizeType i //!< The subscript index + ) const { + FW_ASSERT(i < this->m_size, static_cast(i)); + return this->m_elements[i]; + } + + public: + // ---------------------------------------------------------------------- + // Public member functions + // ---------------------------------------------------------------------- + + //! Get the size + //! \return The size + FwSizeType getSize() const { return this->m_size; } + + //! Set the backing storage + void setStorage(T* const elements, //!< The array elements + const FwSizeType size //!< The size + ) { + this->m_elements = elements; + this->m_size = size; + } + + public: + // ---------------------------------------------------------------------- + // Public static functions + // ---------------------------------------------------------------------- +#endif + + private: + // ---------------------------------------------------------------------- + // Private member variables + // ---------------------------------------------------------------------- + + //! The array elements + T m_elements[S] = {}; +}; + +} // namespace Ds + +#endif diff --git a/Fw/Ds/CMakeLists.txt b/Fw/Ds/CMakeLists.txt new file mode 100644 index 00000000000..0ce81a95502 --- /dev/null +++ b/Fw/Ds/CMakeLists.txt @@ -0,0 +1,16 @@ +set(SOURCE_FILES + "${CMAKE_CURRENT_LIST_DIR}/Ds.cpp" +) + +register_fprime_module() + +set(UT_SOURCE_FILES + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/DsTestMain.cpp" +) + +set(UT_MOD_DEPS + STest +) + +register_fprime_ut() diff --git a/Fw/Ds/Ds.cpp b/Fw/Ds/Ds.cpp new file mode 100644 index 00000000000..3215aa7acb1 --- /dev/null +++ b/Fw/Ds/Ds.cpp @@ -0,0 +1 @@ +// Empty file to keep the F Prime build system happy diff --git a/Fw/Ds/ExternalArray.hpp b/Fw/Ds/ExternalArray.hpp new file mode 100644 index 00000000000..5cfcd10b4a8 --- /dev/null +++ b/Fw/Ds/ExternalArray.hpp @@ -0,0 +1,104 @@ +// ====================================================================== +// \title Array +// \author bocchino +// \brief An array that stores its size and provides bounds checking +// ====================================================================== + +#ifndef Ds_Array_HPP +#define Ds_Array_HPP + +#include + +#include "Fw/Types/Assert.hpp" +#include "Types/PointerAssert.hpp" + +namespace Ds { + +template +class Array { + public: + // ---------------------------------------------------------------------- + // Constructors + // ---------------------------------------------------------------------- + + //! Construct an Array object + Array() {} + + //! Construct an Array object with backing storage + Array(T* const elements, //!< The array elements + const FwSizeType size //!< The size + ) + : m_elements(elements), m_size(size) {} + + public: + // ---------------------------------------------------------------------- + // Public operators + // ---------------------------------------------------------------------- + + //! Subscript operator + T& operator[](const FwSizeType i //!< The subscript index + ) { + FW_ASSERT(i < this->m_size, static_cast(i)); + return this->m_elements[i]; + } + + //! Const subscript operator + const T& operator[](const FwSizeType i //!< The subscript index + ) const { + FW_ASSERT(i < this->m_size, static_cast(i)); + return this->m_elements[i]; + } + + public: + // ---------------------------------------------------------------------- + // Public member functions + // ---------------------------------------------------------------------- + + //! Get the size + //! \return The size + FwSizeType getSize() const { return this->m_size; } + + //! Set the backing storage + void setStorage(T* const elements, //!< The array elements + const FwSizeType size //!< The size + ) { + this->m_elements = elements; + this->m_size = size; + } + + public: + // ---------------------------------------------------------------------- + // Public static functions + // ---------------------------------------------------------------------- + + //! Allocate storage for an array with element type T + //! \return The storage + static T* allocateStorage(Fw::MemAllocator& memAllocator, //!< The mem allocator (input) + FwEnumStoreType memId, //!< The memory segment identifier (input) + FwSizeType numElts, //!< The number of array elements (input) + bool& recoverable //!< Whether the memory should be recoverable (input and output) + ) { + const NATIVE_UINT_TYPE requestedSize = static_cast(numElts * sizeof(T)); + NATIVE_UINT_TYPE allocatedSize = requestedSize; + void* memory = memAllocator.allocate(static_cast(memId), allocatedSize, recoverable); + FW_ASSERT((memory != nullptr) && (allocatedSize == requestedSize), static_cast(memId), + Ds_PTR_ASSERT_ARGS(memory), static_cast(requestedSize), + static_cast(allocatedSize)); + return static_cast(memory); + } + + private: + // ---------------------------------------------------------------------- + // Private member variables + // ---------------------------------------------------------------------- + + //! The array elements + T* m_elements = nullptr; + + //! The size + FwSizeType m_size = 0; +}; + +} // namespace Ds + +#endif diff --git a/Fw/Ds/test/ut/ArrayTest.cpp b/Fw/Ds/test/ut/ArrayTest.cpp new file mode 100644 index 00000000000..417bb05993e --- /dev/null +++ b/Fw/Ds/test/ut/ArrayTest.cpp @@ -0,0 +1,22 @@ +// ====================================================================== +// \title ArrayTest.cpp +// \author bocchino +// \brief cpp file for Array tests +// ====================================================================== + +#include + +#include "Fw/Ds/Array.hpp" + +namespace Ds { + +TEST(Array, ZeroArgConstructor) { + Array a; +#if 0 + for (FwSizeType i = 0; i < 3; i++) { + ASSERT_EQ(a[i], 0U); + } +#endif +} + +} // namespace Ds diff --git a/Fw/Ds/test/ut/DsTestMain.cpp b/Fw/Ds/test/ut/DsTestMain.cpp new file mode 100644 index 00000000000..f44dc73f441 --- /dev/null +++ b/Fw/Ds/test/ut/DsTestMain.cpp @@ -0,0 +1,15 @@ +// ====================================================================== +// \title DsTestMain.cpp +// \author bocchino +// \brief cpp file for Ds tests +// ====================================================================== + +#include + +#include "STest/Random/Random.hpp" + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + STest::Random::seed(); + return RUN_ALL_TESTS(); +} From 867499ca5633b1c364c80fe0b487258a0a6c2140 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 27 May 2025 16:33:58 -0700 Subject: [PATCH 024/458] Revise ExternalArray --- Fw/Ds/ExternalArray.hpp | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/Fw/Ds/ExternalArray.hpp b/Fw/Ds/ExternalArray.hpp index 5cfcd10b4a8..51ee9e0286e 100644 --- a/Fw/Ds/ExternalArray.hpp +++ b/Fw/Ds/ExternalArray.hpp @@ -10,7 +10,6 @@ #include #include "Fw/Types/Assert.hpp" -#include "Types/PointerAssert.hpp" namespace Ds { @@ -66,27 +65,6 @@ class Array { this->m_size = size; } - public: - // ---------------------------------------------------------------------- - // Public static functions - // ---------------------------------------------------------------------- - - //! Allocate storage for an array with element type T - //! \return The storage - static T* allocateStorage(Fw::MemAllocator& memAllocator, //!< The mem allocator (input) - FwEnumStoreType memId, //!< The memory segment identifier (input) - FwSizeType numElts, //!< The number of array elements (input) - bool& recoverable //!< Whether the memory should be recoverable (input and output) - ) { - const NATIVE_UINT_TYPE requestedSize = static_cast(numElts * sizeof(T)); - NATIVE_UINT_TYPE allocatedSize = requestedSize; - void* memory = memAllocator.allocate(static_cast(memId), allocatedSize, recoverable); - FW_ASSERT((memory != nullptr) && (allocatedSize == requestedSize), static_cast(memId), - Ds_PTR_ASSERT_ARGS(memory), static_cast(requestedSize), - static_cast(allocatedSize)); - return static_cast(memory); - } - private: // ---------------------------------------------------------------------- // Private member variables From a6cb66b40e39dd9045a617e02562faa9249ea085 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 27 May 2025 16:49:23 -0700 Subject: [PATCH 025/458] Revise Array tests --- Fw/Ds/Array.hpp | 44 +++++++++++++++++-------------------- Fw/Ds/docs/sdd.md | 2 +- Fw/Ds/test/ut/ArrayTest.cpp | 28 +++++++++++++++++++++-- 3 files changed, 47 insertions(+), 27 deletions(-) diff --git a/Fw/Ds/Array.hpp b/Fw/Ds/Array.hpp index 70e9020e391..3ce8c678961 100644 --- a/Fw/Ds/Array.hpp +++ b/Fw/Ds/Array.hpp @@ -27,52 +27,48 @@ class Array final { Array() {} //! Initializer list constructor - Array(const std::initializer_list& il) { + Array(const std::initializer_list& il //!< The initializer list + ) { FW_ASSERT(il.size() == S, static_cast(il.size()), static_cast(S)); - // TODO + FwSizeType i = 0; + for (const auto& e : il) { + FW_ASSERT(i < S); + this->m_elements[i] = e; + i++; + } + } + + //! Single-element constructor + explicit Array(const T& element //!< The element + ) { + for (FwSizeType i = 0; i < S; i++) { + this->m_elements[i] = element; + } } -#if 0 public: // ---------------------------------------------------------------------- - // Public operators + // Public member functions // ---------------------------------------------------------------------- //! Subscript operator T& operator[](const FwSizeType i //!< The subscript index ) { - FW_ASSERT(i < this->m_size, static_cast(i)); + FW_ASSERT(i < S, static_cast(i)); return this->m_elements[i]; } //! Const subscript operator const T& operator[](const FwSizeType i //!< The subscript index ) const { - FW_ASSERT(i < this->m_size, static_cast(i)); + FW_ASSERT(i < S, static_cast(i)); return this->m_elements[i]; } - public: - // ---------------------------------------------------------------------- - // Public member functions - // ---------------------------------------------------------------------- - +#if 0 //! Get the size //! \return The size FwSizeType getSize() const { return this->m_size; } - - //! Set the backing storage - void setStorage(T* const elements, //!< The array elements - const FwSizeType size //!< The size - ) { - this->m_elements = elements; - this->m_size = size; - } - - public: - // ---------------------------------------------------------------------- - // Public static functions - // ---------------------------------------------------------------------- #endif private: diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index eb2661ac9b6..1433694ffa1 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -64,7 +64,7 @@ Array a({ 1, 2, 3 }); Array b = { 1, 2, 3 }; ``` -**Single-item constructor:** +**Single-element constructor:** ```c++ explicit Array(const T& element) diff --git a/Fw/Ds/test/ut/ArrayTest.cpp b/Fw/Ds/test/ut/ArrayTest.cpp index 417bb05993e..dd5af62b591 100644 --- a/Fw/Ds/test/ut/ArrayTest.cpp +++ b/Fw/Ds/test/ut/ArrayTest.cpp @@ -12,11 +12,35 @@ namespace Ds { TEST(Array, ZeroArgConstructor) { Array a; -#if 0 for (FwSizeType i = 0; i < 3; i++) { ASSERT_EQ(a[i], 0U); } -#endif +} + +TEST(Array, InitializerListConstructor) { + // Explicit call to constructor + Array a({1, 2, 3}); + for (FwSizeType i = 0; i < 3; i++) { + ASSERT_EQ(a[i], i + 1); + } + // Implicit call to constructor via initialization + Array b = {1, 2, 3}; + for (FwSizeType i = 0; i < 3; i++) { + ASSERT_EQ(b[i], i + 1); + } +} + +TEST(Array, SingleElementConstructor) { + // Explicit call to constructor in variable declaration + Array a(1); + for (FwSizeType i = 0; i < 3; i++) { + ASSERT_EQ(a[i], 1); + } + // Explicit call to constructor in assignment + Array b = Array(2); + for (FwSizeType i = 0; i < 3; i++) { + ASSERT_EQ(b[i], 2); + } } } // namespace Ds From 4bf6502547b013781a86b5dd5ee835ba34949175 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 27 May 2025 16:53:13 -0700 Subject: [PATCH 026/458] Revise Array tests --- Fw/Ds/test/ut/ArrayTest.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Fw/Ds/test/ut/ArrayTest.cpp b/Fw/Ds/test/ut/ArrayTest.cpp index dd5af62b591..4eef1efe65a 100644 --- a/Fw/Ds/test/ut/ArrayTest.cpp +++ b/Fw/Ds/test/ut/ArrayTest.cpp @@ -43,4 +43,15 @@ TEST(Array, SingleElementConstructor) { } } +TEST(Array, Subscript) { + Array a = {0, 1, 2}; + // Constant access + ASSERT_EQ(a[1], 1); + // Mutable access + a[1]++; + ASSERT_EQ(a[1], 2); + // Out-of-bounds access + ASSERT_DEATH(a[3], "Assert"); +} + } // namespace Ds From e4a6a593cbedb8611b4e4a545708f0d0cd27abf5 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 27 May 2025 17:12:04 -0700 Subject: [PATCH 027/458] Revise Array tests --- Fw/Ds/Array.hpp | 39 +++++++++++++++++++++++++++++++++++-- Fw/Ds/docs/sdd.md | 19 +++++++++++------- Fw/Ds/test/ut/ArrayTest.cpp | 23 ++++++++++++++++++++++ 3 files changed, 72 insertions(+), 9 deletions(-) diff --git a/Fw/Ds/Array.hpp b/Fw/Ds/Array.hpp index 3ce8c678961..bdc8758541d 100644 --- a/Fw/Ds/Array.hpp +++ b/Fw/Ds/Array.hpp @@ -20,7 +20,15 @@ class Array final { public: // ---------------------------------------------------------------------- - // Constructors + // Types + // ---------------------------------------------------------------------- + + //! The type of the elements array + using Elements = T[S]; + + public: + // ---------------------------------------------------------------------- + // Public constructors and destructors // ---------------------------------------------------------------------- //! Zero-argument constructor @@ -46,6 +54,17 @@ class Array final { } } + //! Copy constructor + Array(const Array& a //!< The array to copy + ) { + for (FwSizeType i = 0; i < S; i++) { + this->m_elements[i] = a.m_elements[i]; + } + } + + //! Destructor + ~Array() {} + public: // ---------------------------------------------------------------------- // Public member functions @@ -65,6 +84,22 @@ class Array final { return this->m_elements[i]; } + //! Copy assignment operator + Array& operator=(const Array& a) { + if (&a != this) { + for (FwSizeType i = 0; i < S; i++) { + this->m_elements[i] = a.m_elements[i]; + } + } + return *this; + } + + //! Get a mutable reference to the elements + Elements& getElements() { return this->m_elements; } + + //! Get a const reference to the elements + const Elements& getElements() const { return this->m_elements; } + #if 0 //! Get the size //! \return The size @@ -77,7 +112,7 @@ class Array final { // ---------------------------------------------------------------------- //! The array elements - T m_elements[S] = {}; + Elements m_elements = {}; }; } // namespace Ds diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 1433694ffa1..54d0012a30f 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -25,13 +25,18 @@ It maintains the backing memory _M_ as a member variable. `Array` statically asserts that `S > 0`. -#### 1.1.2. Private Member Variables +#### 1.1.2. Types + +`Array` defines the type `Elements`. +It is an alias of `T[S]`. + +#### 1.1.3. Private Member Variables `Array` has one private variable `m_elements` for storing the array elements. -It is a primitive C++ array of type `T[S]`. +It is a primitive C++ array of type `Elements`. -#### 1.1.3. Public Constructors and Destructors +#### 1.1.4. Public Constructors and Destructors **Zero-argument constructor:** @@ -105,7 +110,7 @@ Array a2(a1); Destroy each element of `m_elements`. -#### 1.1.4. Public Member Functions +#### 1.1.5. Public Member Functions **operator[]:** @@ -151,8 +156,8 @@ a1 = a2; **getElements:** ```c++ -T[S]& getElements() -const T[S]& getElements() const +Elements& getElements() +const Elements& getElements() const ``` Return a reference to `m_elements`. @@ -169,7 +174,7 @@ const auto& elements2 = a.getElements(); ASSERT_EQ(elements2[0], 1); ``` -#### 1.1.5. Public Static Functions +#### 1.1.6. Public Static Functions **getSize:** diff --git a/Fw/Ds/test/ut/ArrayTest.cpp b/Fw/Ds/test/ut/ArrayTest.cpp index 4eef1efe65a..adf77162bb2 100644 --- a/Fw/Ds/test/ut/ArrayTest.cpp +++ b/Fw/Ds/test/ut/ArrayTest.cpp @@ -43,6 +43,16 @@ TEST(Array, SingleElementConstructor) { } } +TEST(Array, CopyConstructor) { + // Call the single-item constructor + Array a1(10); + // Call the copy constructor + Array a2(a1); + for (FwSizeType i = 0; i < 3; i++) { + ASSERT_EQ(a2[i], 10); + } +} + TEST(Array, Subscript) { Array a = {0, 1, 2}; // Constant access @@ -54,4 +64,17 @@ TEST(Array, Subscript) { ASSERT_DEATH(a[3], "Assert"); } +TEST(Array, CopyAssignmentOperator) { + Array a1(1); + for (FwSizeType i = 0; i < 3; i ++) { + ASSERT_EQ(a1[i], 1); + } + Array a2(2); + auto& a = (a1 = a2); + for (FwSizeType i = 0; i < 3; i ++) { + ASSERT_EQ(a1[i], 2); + } + ASSERT_EQ(&a, &a1); +} + } // namespace Ds From 4eee7e2f673a61b04c777504553ae9023da3708b Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 27 May 2025 17:14:42 -0700 Subject: [PATCH 028/458] Revise Array tests --- Fw/Ds/docs/sdd.md | 44 ++++++++++++++++++------------------- Fw/Ds/test/ut/ArrayTest.cpp | 11 ++++++++++ 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 54d0012a30f..71bcc99f08c 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -97,7 +97,7 @@ elements of `a.m_elements`. _Example:_ ```c++ // Call the single-item constructor -Array a1(10); +Array a1(3); // Call the copy constructor Array a2(a1); ``` @@ -125,14 +125,14 @@ const T& operator[](FwSizeType i) const _Example:_ ```c++ -Array a; +Array a; // Constant access ASSERT_EQ(a[0], 0); // Mutable access a[0]++; ASSERT_EQ(a[0], 1); // Out-of-bounds access -ASSERT_DEATH(a[10], "Assert"); +ASSERT_DEATH(a[3], "Assert"); ``` **Copy assignment operator:** @@ -148,8 +148,8 @@ element of `a`. _Example:_ ```c++ -Array a1(1); -Array a2(2); +Array a1(1); +Array a2(2); a1 = a2; ``` @@ -164,7 +164,7 @@ Return a reference to `m_elements`. _Example:_ ```c++ -Array a; +Array a; // Mutable reference auto& elements1 = a.getElements(); ASSERT_EQ(elements1[0], 0); @@ -186,8 +186,8 @@ Return the size `S` of the array. _Example:_ ```c++ -const auto size = Array::getSize(); -ASSERT_EQ(size, 10); +const auto size = Array::getSize(); +ASSERT_EQ(size, 3); ``` ### 1.2. External Array @@ -236,8 +236,8 @@ Initialize `m_elements` with `elements` and `m_size` with `size`. _Example:_ ```c++ -U32 elements[10]; -ExternalArray a(elements, 10); +U32 elements[3]; +ExternalArray a(elements, 3); ``` **Copy constructor:** @@ -284,15 +284,15 @@ const T& operator[](FwSizeType i) const _Example:_ ```c++ -U32 elements[10]; -ExternalArray a(elements, 10); +U32 elements[3]; +ExternalArray a(elements, 3); // Constant access ASSERT_EQ(a[0], 0); // Mutable access a[0]++; ASSERT_EQ(a[0], 1); // Out-of-bounds access -ASSERT_DEATH(a[10], "Assert"); +ASSERT_DEATH(a[3], "Assert"); ``` **Copy assignment operator:** @@ -307,8 +307,8 @@ ExternalArray& operator=(const ExternalArray& a) _Example:_ ```c++ -U32 elements[10]; -ExternalArray a1(elements, 10); +U32 elements[3]; +ExternalArray a1(elements, 3); ExternalArray a2; a2 = a1; ``` @@ -324,8 +324,8 @@ Return `m_elements`. _Example:_ ```c++ -U32 elements[10]; -ExternalArray a(elements, 10); +U32 elements[3]; +ExternalArray a(elements, 3); // Mutable pointer auto& elements1 = a.getElements(); ASSERT_EQ(elements1[0], 0); @@ -345,10 +345,10 @@ Return `m_size`. _Example:_ ```c++ -U32 elements[10]; -ExternalArray a(elements, 10); +U32 elements[3]; +ExternalArray a(elements, 3); const auto size = a.getSize(); -ASSERT_EQ(size, 10); +ASSERT_EQ(size, 3); ``` **setStorage:** @@ -362,8 +362,8 @@ Set `m_elements = elements` and `m_size = size`. _Example:_ ```c++ ExternalArray a; -U32 elements[10]; -a.setStorage(elements, 10); +U32 elements[3]; +a.setStorage(elements, 3); ``` ## 2. Queues diff --git a/Fw/Ds/test/ut/ArrayTest.cpp b/Fw/Ds/test/ut/ArrayTest.cpp index adf77162bb2..1bd89b2706e 100644 --- a/Fw/Ds/test/ut/ArrayTest.cpp +++ b/Fw/Ds/test/ut/ArrayTest.cpp @@ -77,4 +77,15 @@ TEST(Array, CopyAssignmentOperator) { ASSERT_EQ(&a, &a1); } +TEST(Array, GetElements) { + Array a; + // Mutable reference + auto& elements1 = a.getElements(); + ASSERT_EQ(elements1[0], 0); + elements1[0] = 1; + // Constant reference + const auto& elements2 = a.getElements(); + ASSERT_EQ(elements2[0], 1); +} + } // namespace Ds From a3764dbb623edffb2877808a4d2a24c9069e9a3c Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 27 May 2025 17:17:47 -0700 Subject: [PATCH 029/458] Revise ArrayTest --- Fw/Ds/Array.hpp | 16 +++++++++------- Fw/Ds/test/ut/ArrayTest.cpp | 5 +++++ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/Fw/Ds/Array.hpp b/Fw/Ds/Array.hpp index bdc8758541d..7bd359648e9 100644 --- a/Fw/Ds/Array.hpp +++ b/Fw/Ds/Array.hpp @@ -1,7 +1,7 @@ // ====================================================================== // \title Array // \author bocchino -// \brief An array that stores its size and provides bounds checking +// \brief A statically-sized, bounds checked array // ====================================================================== #ifndef Ds_Array_HPP @@ -20,7 +20,7 @@ class Array final { public: // ---------------------------------------------------------------------- - // Types + // Types // ---------------------------------------------------------------------- //! The type of the elements array @@ -100,11 +100,13 @@ class Array final { //! Get a const reference to the elements const Elements& getElements() const { return this->m_elements; } -#if 0 - //! Get the size - //! \return The size - FwSizeType getSize() const { return this->m_size; } -#endif + public: + // ---------------------------------------------------------------------- + // Public static functions + // ---------------------------------------------------------------------- + + //! Get the array size + static constexpr FwSizeType getSize() { return S; } private: // ---------------------------------------------------------------------- diff --git a/Fw/Ds/test/ut/ArrayTest.cpp b/Fw/Ds/test/ut/ArrayTest.cpp index 1bd89b2706e..4842cc2f25f 100644 --- a/Fw/Ds/test/ut/ArrayTest.cpp +++ b/Fw/Ds/test/ut/ArrayTest.cpp @@ -88,4 +88,9 @@ TEST(Array, GetElements) { ASSERT_EQ(elements2[0], 1); } +TEST(Array, GetSize) { + const auto size = Array::getSize(); + ASSERT_EQ(size, 3); +} + } // namespace Ds From 26b6304962637caa990ed7971f3083e28b4daa69 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 27 May 2025 17:50:25 -0700 Subject: [PATCH 030/458] Revise ExternalArray --- Fw/Ds/CMakeLists.txt | 1 + Fw/Ds/ExternalArray.hpp | 56 +++++++++++++++++++---------- Fw/Ds/docs/sdd.md | 4 +-- Fw/Ds/test/ut/ExternalArrayTest.cpp | 17 +++++++++ 4 files changed, 56 insertions(+), 22 deletions(-) create mode 100644 Fw/Ds/test/ut/ExternalArrayTest.cpp diff --git a/Fw/Ds/CMakeLists.txt b/Fw/Ds/CMakeLists.txt index 0ce81a95502..e9fbd4033be 100644 --- a/Fw/Ds/CMakeLists.txt +++ b/Fw/Ds/CMakeLists.txt @@ -7,6 +7,7 @@ register_fprime_module() set(UT_SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/DsTestMain.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" ) set(UT_MOD_DEPS diff --git a/Fw/Ds/ExternalArray.hpp b/Fw/Ds/ExternalArray.hpp index 51ee9e0286e..47422b70811 100644 --- a/Fw/Ds/ExternalArray.hpp +++ b/Fw/Ds/ExternalArray.hpp @@ -1,42 +1,49 @@ // ====================================================================== -// \title Array +// \title ExternalArray // \author bocchino -// \brief An array that stores its size and provides bounds checking +// \brief A bounds-checked array with external memory // ====================================================================== -#ifndef Ds_Array_HPP -#define Ds_Array_HPP +#ifndef Ds_ExternalArray_HPP +#define Ds_ExternalArray_HPP -#include +#include #include "Fw/Types/Assert.hpp" namespace Ds { template -class Array { +class ExternalArray final { public: // ---------------------------------------------------------------------- // Constructors // ---------------------------------------------------------------------- - //! Construct an Array object - Array() {} + //! Zero-argument constructor + ExternalArray() {} - //! Construct an Array object with backing storage - Array(T* const elements, //!< The array elements - const FwSizeType size //!< The size - ) + //! Constructor providing backing storage + ExternalArray(T* elements, //!< The elements + FwSizeType size //!< The array size + ) : m_elements(elements), m_size(size) {} + //! Copy constructor + ExternalArray(const ExternalArray& a) : m_elements(a.m_elements), m_size(a.m_size) {} + + //! Destructor + ~ExternalArray() {} + public: // ---------------------------------------------------------------------- - // Public operators + // Public member functions // ---------------------------------------------------------------------- //! Subscript operator T& operator[](const FwSizeType i //!< The subscript index ) { + FW_ASSERT(i < this->m_elements != nullptr); FW_ASSERT(i < this->m_size, static_cast(i)); return this->m_elements[i]; } @@ -44,22 +51,33 @@ class Array { //! Const subscript operator const T& operator[](const FwSizeType i //!< The subscript index ) const { + FW_ASSERT(i < this->m_elements != nullptr); FW_ASSERT(i < this->m_size, static_cast(i)); return this->m_elements[i]; } - public: - // ---------------------------------------------------------------------- - // Public member functions - // ---------------------------------------------------------------------- + //! Copy assignment operator + ExternalArray& operator=(const ExternalArray& a) { + if (&a != this) { + this->m_elements = a.m_elements; + this->m_size = a.m_size; + } + return *this; + } + + //! Get a mutable pointer to the elements + T* getElements() { return this->m_elements; } + + //! Get a const pointer to the elements + const T* getElements() const { return this->m_elements; } //! Get the size //! \return The size FwSizeType getSize() const { return this->m_size; } //! Set the backing storage - void setStorage(T* const elements, //!< The array elements - const FwSizeType size //!< The size + void setStorage(T* elements, //!< The array elements + FwSizeType size //!< The size ) { this->m_elements = elements; this->m_size = size; diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 71bcc99f08c..afef0d659fa 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -263,9 +263,7 @@ ExternalArray a2(a1); ~ExternalArray() ``` -1. If `m_elements == nullptr` then do nothing. - -1. Otherwise destroy each element of `m_elements`. +Do nothing. #### 1.2.4. Public Member Functions diff --git a/Fw/Ds/test/ut/ExternalArrayTest.cpp b/Fw/Ds/test/ut/ExternalArrayTest.cpp new file mode 100644 index 00000000000..10a62d0caf8 --- /dev/null +++ b/Fw/Ds/test/ut/ExternalArrayTest.cpp @@ -0,0 +1,17 @@ +// ====================================================================== +// \title ExternalArrayTest.cpp +// \author bocchino +// \brief cpp file for ExternalArray tests +// ====================================================================== + +#include + +#include "Fw/Ds/ExternalArray.hpp" + +namespace Ds { + +TEST(ExternalArray, ZeroArgConstructor) { + ExternalArray a; +} + +} // namespace Ds From 134c68ca9b82bfab8d991e252e1a4436980f505b Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 27 May 2025 17:55:54 -0700 Subject: [PATCH 031/458] Revise ExternalArrayTest --- Fw/Ds/test/ut/ExternalArrayTest.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Fw/Ds/test/ut/ExternalArrayTest.cpp b/Fw/Ds/test/ut/ExternalArrayTest.cpp index 10a62d0caf8..17a9d1aef61 100644 --- a/Fw/Ds/test/ut/ExternalArrayTest.cpp +++ b/Fw/Ds/test/ut/ExternalArrayTest.cpp @@ -12,6 +12,25 @@ namespace Ds { TEST(ExternalArray, ZeroArgConstructor) { ExternalArray a; + ASSERT_EQ(a.getElements(), nullptr); + ASSERT_EQ(a.getSize(), 0); +} + +TEST(ExternalArray, StorageConstructor) { + U32 elements[3]; + ExternalArray a(elements, 3); + ASSERT_EQ(a.getElements(), elements); + ASSERT_EQ(a.getSize(), 3); +} + +TEST(ExternalArray, CopyConstructor) { + U32 elements[3]; + // Call the constructor providing backing storage + ExternalArray a1(elements, 3); + // Call the copy constructor + ExternalArray a2(a1); + ASSERT_EQ(a2.getElements(), elements); + ASSERT_EQ(a2.getSize(), 3); } } // namespace Ds From d03660918ba3f08777282bec68481b0434567079 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 28 May 2025 08:14:02 -0700 Subject: [PATCH 032/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 288 ++++++++++++++++++++++++---------------------- 1 file changed, 148 insertions(+), 140 deletions(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index afef0d659fa..141ee63d0f3 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -9,108 +9,82 @@ An **array** _A_ stores _n_ elements for _n > 0_ at indices The elements are stored in **backing memory** _M_. An array provides bounds-checked access to the array elements. -### 1.1. Array +### 1.1. External Array -`Array` is a `final` class template representing an array -with internal storage. -It maintains the backing memory _M_ as a member variable. +`ExternalArray` is a `final` class template representing an array with external +storage. +It stores a pointer to the backing memory _M_. #### 1.1.1. Template Parameters -`Array` has two template parameters: +`ExternalArray` has one template parameter: 1. The type `typename T` -1. The size `FwSizeType S` +#### 1.1.2. Private Member Variables -`Array` statically asserts that `S > 0`. - -#### 1.1.2. Types - -`Array` defines the type `Elements`. -It is an alias of `T[S]`. - -#### 1.1.3. Private Member Variables +`ExternalArray` has the following private member variables. -`Array` has one private variable `m_elements` for -storing the array elements. -It is a primitive C++ array of type `Elements`. +|Name|Type|Purpose|Default Value| +|----|----|-------|-------------| +|`m_elements`|`T*`|Points to the backing memory|`nullptr`| +|`m_size`|`FwSizeType`|Stores the size (number of elements) of the array|0| -#### 1.1.4. Public Constructors and Destructors +#### 1.1.3. Public Constructors and Destructors **Zero-argument constructor:** ```c++ -Array() +ExternalArray() ``` -Initialize each element of `m_elements` with the default value for `T`. +Initialize the member variables with their default values. _Example:_ ```c++ -Array a; -``` - -**Initializer list constructor:** - -```c++ -Array(const std::initializer_list& il) -``` - -1. Assert that `il.size == S`. - -1. Initialize `m_elements` from `il`. - -_Examples:_ -```c++ -// Explicit call to constructor -Array a({ 1, 2, 3 }); -// Implicit call to constructor via initialization -Array b = { 1, 2, 3 }; +ExternalArray a; ``` -**Single-element constructor:** +**Constructor providing backing storage:** ```c++ -explicit Array(const T& element) +ExternalArray(T* elements, FwSizeType size) ``` -Initialize each element of `m_elements` with `element`. +Initialize `m_elements` with `elements` and `m_size` with `size`. _Example:_ ```c++ -// Explicit call to constructor in variable declaration -Array a(1); -// Explicit call to constructor in assignment -a = Array(2); +U32 elements[3]; +ExternalArray a(elements, 3); ``` **Copy constructor:** ```c++ -Array(const Array& a) +ExternalArray(const ExternalArray& a) ``` -Initialize the elements of `m_elements` with the -elements of `a.m_elements`. +Set `m_elements = a.elements` and `m_size = a.size`. _Example:_ ```c++ -// Call the single-item constructor -Array a1(3); +U32 elements[3]; +// Call the constructor providing backing storage +ExternalArray a1(elements, 3); // Call the copy constructor -Array a2(a1); +ExternalArray a2(a1); ``` **Destructor:** ```c++ -~Array() +~ExternalArray() ``` -Destroy each element of `m_elements`. +Do nothing. -#### 1.1.5. Public Member Functions +#### 1.1.4. Public Member Functions **operator[]:** @@ -119,13 +93,16 @@ T& operator[](FwSizeType i) const T& operator[](FwSizeType i) const ``` -1. Assert that `i < S`. +1. Assert that `m_elements != nullptr`. + +1. Assert that `i < m_size`. 1. Return a reference to `m_elements[i]`. _Example:_ ```c++ -Array a; +U32 elements[3]; +ExternalArray a(elements, 3); // Constant access ASSERT_EQ(a[0], 0); // Mutable access @@ -138,134 +115,176 @@ ASSERT_DEATH(a[3], "Assert"); **Copy assignment operator:** ```c++ -Array& operator=(const Array& a) +ExternalArray& operator=(const ExternalArray& a) ``` 1. If `&a == this` then do nothing. -1. Otherwise overwrite each element of `m_elements` with the corresponding -element of `a`. +1. Otherwise set `m_elements = a.elements` and `m_size = a.size`. _Example:_ ```c++ -Array a1(1); -Array a2(2); -a1 = a2; +U32 elements[3]; +ExternalArray a1(elements, 3); +ExternalArray a2; +a2 = a1; ``` **getElements:** ```c++ -Elements& getElements() -const Elements& getElements() const +T* getElements() +const T* getElements() const ``` -Return a reference to `m_elements`. +Return `m_elements`. _Example:_ ```c++ -Array a; -// Mutable reference +U32 elements[3]; +ExternalArray a(elements, 3); +// Mutable pointer auto& elements1 = a.getElements(); ASSERT_EQ(elements1[0], 0); elements1[0] = 1; -// Constant reference +// Constant pointer const auto& elements2 = a.getElements(); ASSERT_EQ(elements2[0], 1); ``` -#### 1.1.6. Public Static Functions - **getSize:** ```c++ -static constexpr FwSizeType getSize() +FwSizeType getSize() ``` -Return the size `S` of the array. +Return `m_size`. _Example:_ ```c++ -const auto size = Array::getSize(); +U32 elements[3]; +ExternalArray a(elements, 3); +const auto size = a.getSize(); ASSERT_EQ(size, 3); ``` -### 1.2. External Array +**setStorage:** -`ExternalArray` is a `final` class template representing an array with external -storage. -It stores a pointer to the backing memory _M_. +```c++ +void setStorage(T* elements, FwSizeType size) +``` + +Set `m_elements = elements` and `m_size = size`. + +_Example:_ +```c++ +ExternalArray a; +U32 elements[3]; +a.setStorage(elements, 3); +``` + +### 1.2. Array + +`Array` is a `final` class template representing an array +with internal storage. +It maintains the backing memory _M_ as a member variable. #### 1.2.1. Template Parameters -`ExternalArray` has one template parameter: +`Array` has two template parameters: 1. The type `typename T` -#### 1.2.2. Private Member Variables +1. The size `FwSizeType S` -`ExternalArray` has the following private member variables. +`Array` statically asserts that `S > 0`. -|Name|Type|Purpose|Default Value| -|----|----|-------|-------------| -|`m_elements`|`T*`|Points to the backing memory|`nullptr`| -|`m_size`|`FwSizeType`|Stores the size (number of elements) of the array|0| +#### 1.2.2. Types -#### 1.2.3. Public Constructors and Destructors +`Array` defines the type `Elements`. +It is an alias of `T[S]`. + +#### 1.2.3. Private Member Variables + +`Array` has one private variable `m_elements` for +storing the array elements. +It is a primitive C++ array of type `Elements`. + +#### 1.2.4. Public Constructors and Destructors **Zero-argument constructor:** ```c++ -ExternalArray() +Array() ``` -Initialize the member variables with their default values. +Initialize each element of `m_elements` with the default value for `T`. _Example:_ ```c++ -ExternalArray a; +Array a; ``` -**Constructor providing backing storage:** +**Initializer list constructor:** ```c++ -ExternalArray(T* elements, FwSizeType size) +Array(const std::initializer_list& il) ``` -Initialize `m_elements` with `elements` and `m_size` with `size`. +1. Assert that `il.size == S`. + +1. Initialize `m_elements` from `il`. + +_Examples:_ +```c++ +// Explicit call to constructor +Array a({ 1, 2, 3 }); +// Implicit call to constructor via initialization +Array b = { 1, 2, 3 }; +``` + +**Single-element constructor:** + +```c++ +explicit Array(const T& element) +``` + +Initialize each element of `m_elements` with `element`. _Example:_ ```c++ -U32 elements[3]; -ExternalArray a(elements, 3); +// Explicit call to constructor in variable declaration +Array a(1); +// Explicit call to constructor in assignment +a = Array(2); ``` **Copy constructor:** ```c++ -ExternalArray(const ExternalArray& a) +Array(const Array& a) ``` -Set `m_elements = a.elements` and `m_size = a.size`. +Initialize the elements of `m_elements` with the +elements of `a.m_elements`. _Example:_ ```c++ -U32 elements[3]; -// Call the constructor providing backing storage -ExternalArray a1(elements, 3); +// Call the single-item constructor +Array a1(3); // Call the copy constructor -ExternalArray a2(a1); +Array a2(a1); ``` **Destructor:** ```c++ -~ExternalArray() +~Array() ``` -Do nothing. +Destroy each element of `m_elements`. -#### 1.2.4. Public Member Functions +#### 1.2.5. Public Member Functions **operator[]:** @@ -274,16 +293,13 @@ T& operator[](FwSizeType i) const T& operator[](FwSizeType i) const ``` -1. Assert that `m_elements != nullptr`. - -1. Assert that `i < m_size`. +1. Assert that `i < S`. 1. Return a reference to `m_elements[i]`. _Example:_ ```c++ -U32 elements[3]; -ExternalArray a(elements, 3); +Array a; // Constant access ASSERT_EQ(a[0], 0); // Mutable access @@ -296,81 +312,73 @@ ASSERT_DEATH(a[3], "Assert"); **Copy assignment operator:** ```c++ -ExternalArray& operator=(const ExternalArray& a) +Array& operator=(const Array& a) ``` 1. If `&a == this` then do nothing. -1. Otherwise set `m_elements = a.elements` and `m_size = a.size`. +1. Otherwise overwrite each element of `m_elements` with the corresponding +element of `a`. _Example:_ ```c++ -U32 elements[3]; -ExternalArray a1(elements, 3); -ExternalArray a2; -a2 = a1; +Array a1(1); +Array a2(2); +a1 = a2; ``` **getElements:** ```c++ -T* getElements() -const T* getElements() const +Elements& getElements() +const Elements& getElements() const ``` -Return `m_elements`. +Return a reference to `m_elements`. _Example:_ ```c++ -U32 elements[3]; -ExternalArray a(elements, 3); -// Mutable pointer +Array a; +// Mutable reference auto& elements1 = a.getElements(); ASSERT_EQ(elements1[0], 0); elements1[0] = 1; -// Constant pointer +// Constant reference const auto& elements2 = a.getElements(); ASSERT_EQ(elements2[0], 1); ``` +#### 1.2.6. Public Static Functions + **getSize:** ```c++ -FwSizeType getSize() +static constexpr FwSizeType getSize() ``` -Return `m_size`. +Return the size `S` of the array. _Example:_ ```c++ -U32 elements[3]; -ExternalArray a(elements, 3); -const auto size = a.getSize(); +const auto size = Array::getSize(); ASSERT_EQ(size, 3); ``` -**setStorage:** +## 2. Queues -```c++ -void setStorage(T* elements, FwSizeType size) -``` +### 2.1. External FIFO Queue -Set `m_elements = elements` and `m_size = size`. +TODO -_Example:_ -```c++ -ExternalArray a; -U32 elements[3]; -a.setStorage(elements, 3); -``` +### 2.2. FIFO Queue -## 2. Queues +TODO -### 2.1. FIFO Queue +### 2.3. External LIFO Queue TODO -### 2.2. LIFO Queue +### 2.4. LIFO Queue TODO From 3650ec0381fd22e9c3f3205d44fe5c48bb33a0cf Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 28 May 2025 08:22:18 -0700 Subject: [PATCH 033/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 141ee63d0f3..117bd4bcbf2 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -366,23 +366,45 @@ ASSERT_EQ(size, 3); ## 2. Queues -### 2.1. External FIFO Queue +A *queue* is a data structure backed by an array. +It supports enqueue and dequeue operations. + +### 2.1. ExternalFifoQueue + +`ExternalFifoQueue` is a `final` class template representing a +first in first out (FIFO) queue with external storage. +Internally it maintains an `ExternalArray` for storing +the elements on the queue. + +#### 2.1.1. Template Parameters + +TODO + +#### 2.1.2. Private Member Variables + +TODO + +#### 2.1.3. Public Constructors and Destructors + +TODO + +#### 2.1.4. Public Member Functions TODO -### 2.2. FIFO Queue +### 2.2. FifoQueue TODO -### 2.3. External LIFO Queue +### 2.3. ExternalLifoQueue TODO -### 2.4. LIFO Queue +### 2.4. LifoQueue TODO -## 3. Linked List +## 3. Linked Lists TODO From d0a83fabb474697e5795ab071960281214ca6f05 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 28 May 2025 16:20:12 -0700 Subject: [PATCH 034/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 135 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 113 insertions(+), 22 deletions(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 117bd4bcbf2..8723abdcbfb 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -364,60 +364,151 @@ const auto size = Array::getSize(); ASSERT_EQ(size, 3); ``` -## 2. Queues +## 2. CircularIndex -A *queue* is a data structure backed by an array. -It supports enqueue and dequeue operations. +`CircularIndex` represents an index value that +wraps around modulo an integer. -### 2.1. ExternalFifoQueue +### 2.1. Private Member Variables + +`CircularIndex` has the following private member variables. + +|Name|Type|Purpose|Default Value| +|----|----|-------|-------------| +|`m_value`|`FwSizeType`|The index value|0| +|`m_modulus`|`FwSizeType`|The modulus|1| + +### 2.2. Public Constructors and Destructors + +**Zero-argument constructor:** + +```c++ +CircularIndex() +``` + +Initialize the member variables with their default values. + +**Constructor with specified members:** + +```c++ +CircularIndex(FwSizeType modulus, FwSizeType value = 0) +``` + +Set `m_modulus = modulus` and `m_value = value`. + +### 2.3. Public Member Functions + +**getValue:** + +```c++ +FwSizeType getValue() const +``` + +1. Assert `m_value < m_modulus`. + +1. Return `m_value`. + +**setValue:** + +```c++ +void setValue(FwSizeType value) +``` + +Set `m_value = m_value % m_modulus`. + +**getModulus:** + +```c++ +FwSizeType CircularIndex::getModulus() const +``` + +1. Assert `m_value < m_modulus`. + +1. Return `m_modulus`. + +**setModulus:** + +```c++ +void setModulus(FwSizeType modulus) +``` + +1. Set `m_modulus = modulus`. + +2. Call `setValue(m_value)`. + +**increment:** + +```c++ +FwSizeType increment(FwSizeType amount = 1) +``` + +1. Set `offset = amount % modulus`. + +1. Call `setValue(m_value + offset)`. + +1. Return `m_value`. + +**decrement:** + +```c++ +FwSizeType decrement(FwSizeType amount = 1) +``` + +1. Set `offset = amount % modulus`. + +1. Call `setValue(m_value + modulus - offset)`. + +1. Return `m_value`. + +## 3. FIFO Queues + +A *FIFO queue* is a data structure backed by an array. +It supports enqueue and dequeue operations in +first in first out (FIFO) order. + +### 3.1. ExternalFifoQueue `ExternalFifoQueue` is a `final` class template representing a first in first out (FIFO) queue with external storage. Internally it maintains an `ExternalArray` for storing the elements on the queue. -#### 2.1.1. Template Parameters - -TODO - -#### 2.1.2. Private Member Variables +#### 3.1.1. Template Parameters -TODO - -#### 2.1.3. Public Constructors and Destructors +`ExternalFifoQueue` has one template parameter: -TODO +1. The type `typename T` -#### 2.1.4. Public Member Functions +#### 3.1.2. Private Member Variables TODO -### 2.2. FifoQueue +#### 3.1.3. Public Constructors and Destructors TODO -### 2.3. ExternalLifoQueue +#### 3.1.4. Public Member Functions TODO -### 2.4. LifoQueue +### 3.2. FifoQueue TODO -## 3. Linked Lists +## 4. Linked Lists TODO -## 4. Sets and Maps +## 5. Sets and Maps -### 4.1. Array Set and Map +### 5.1. Array Set and Map TODO -### 4.2. Hash Set and Map +### 5.2. Hash Set and Map TODO -### 4.3. Balanced Binary Tree Set and Map +### 5.3. Balanced Binary Tree Set and Map TODO From b3dd7a7640a3f3ff86d6316f6099aa32ffb374bd Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 28 May 2025 16:22:35 -0700 Subject: [PATCH 035/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 8723abdcbfb..16464b32051 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -394,7 +394,11 @@ Initialize the member variables with their default values. CircularIndex(FwSizeType modulus, FwSizeType value = 0) ``` -Set `m_modulus = modulus` and `m_value = value`. +1. Assert `modulus > 0`. + +1. Set `m_modulus = modulus`. + +1. Call `setValue(value)`. ### 2.3. Public Member Functions From 2f425cd12c3785cf9ebe217dc7ec12bf0d9bbbb0 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 28 May 2025 16:57:09 -0700 Subject: [PATCH 036/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 51 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 16464b32051..1fc1efdbb04 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -466,7 +466,7 @@ FwSizeType decrement(FwSizeType amount = 1) ## 3. FIFO Queues -A *FIFO queue* is a data structure backed by an array. +A **FIFO queue** is a data structure backed by an array. It supports enqueue and dequeue operations in first in first out (FIFO) order. @@ -485,14 +485,61 @@ the elements on the queue. #### 3.1.2. Private Member Variables -TODO +`ExternalFifoQueue` has the following private member variables. + +|Name|Type|Purpose|Default Value| +|----|----|-------|-------------| +|`m_array`|`ExternalArray`|The array for storing the elements|C++ default initialization| +|`m_enqueueIndex`|`CircularIndex`|The enqueue index|0| +|`m_dequeueIndex`|`CircularIndex`|The dequeue index|0| +|`m_size`|`FwSizeType`|The number of elements on the queue|0| #### 3.1.3. Public Constructors and Destructors +**Zero-argument constructor:** + +TODO + +**Constructor providing backing storage:** + +TODO + +**Copy constructor:** + +TODO + +**Destructor:** + TODO #### 3.1.4. Public Member Functions +**clear:** + +TODO + +**setStorage:** + +TODO + +**enqueue:** + +TODO + +**peek:** + +TODO + +**dequeue:** + +TODO + +**getSize:** + +TODO + +**getCapacity:** + TODO ### 3.2. FifoQueue From c9b4232ad2255826d78a6e608b1742847155154f Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 28 May 2025 17:14:00 -0700 Subject: [PATCH 037/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 1fc1efdbb04..ba6296e8904 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -348,6 +348,21 @@ const auto& elements2 = a.getElements(); ASSERT_EQ(elements2[0], 1); ``` +**asExternalArray:** + +```c++ +ExternalArray asExternalArray() +``` + +Return `ExternalArray(m_elements, S)`. + +_Example:_ +```c++ +Array a = { 1, 2, 3 }; +ExternalArray ea = a.asExternalArray(); +ASSERT_EQ(ea[0], 1); +``` + #### 1.2.6. Public Static Functions **getSize:** @@ -498,36 +513,66 @@ the elements on the queue. **Zero-argument constructor:** +```c++ +ExternalFifoQueue() +``` + TODO **Constructor providing backing storage:** +```c++ +ExternalArray(T* elements, FwSizeType size) +``` + TODO **Copy constructor:** +```c++ +ExternalFifoQueue(const ExternalFifoQueue& queue) +``` + TODO **Destructor:** +```c++ +ExternalFifoQueue() +``` + TODO #### 3.1.4. Public Member Functions **clear:** +```c++ +void clear() +``` + TODO **setStorage:** -TODO +```c++ +void setStorage(T* elements, FwSizeType size) +``` **enqueue:** +```c++ +Fw::Success enqueue(const T& e) +``` + TODO **peek:** +```c++ +Fw::Success peek(T& e) +``` + TODO **dequeue:** From a5a4ca2eac520f60aa4dff4c79c5a720870d4998 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 28 May 2025 17:21:24 -0700 Subject: [PATCH 038/458] Revise Array --- Fw/Ds/Array.hpp | 5 +++++ Fw/Ds/ExternalArray.hpp | 2 +- Fw/Ds/docs/sdd.md | 2 +- Fw/Ds/test/ut/ArrayTest.cpp | 6 ++++++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/Fw/Ds/Array.hpp b/Fw/Ds/Array.hpp index 7bd359648e9..36078e907c6 100644 --- a/Fw/Ds/Array.hpp +++ b/Fw/Ds/Array.hpp @@ -10,6 +10,7 @@ #include #include +#include "Fw/Ds/ExternalArray.hpp" #include "Fw/Types/Assert.hpp" namespace Ds { @@ -100,6 +101,10 @@ class Array final { //! Get a const reference to the elements const Elements& getElements() const { return this->m_elements; } + //! Convert this array to an ExternalArray + // \return The ExternalArray + ExternalArray asExternalArray() { return ExternalArray(this->m_elements, S); } + public: // ---------------------------------------------------------------------- // Public static functions diff --git a/Fw/Ds/ExternalArray.hpp b/Fw/Ds/ExternalArray.hpp index 47422b70811..c4f70e272d4 100644 --- a/Fw/Ds/ExternalArray.hpp +++ b/Fw/Ds/ExternalArray.hpp @@ -43,7 +43,7 @@ class ExternalArray final { //! Subscript operator T& operator[](const FwSizeType i //!< The subscript index ) { - FW_ASSERT(i < this->m_elements != nullptr); + FW_ASSERT(this->m_elements != nullptr); FW_ASSERT(i < this->m_size, static_cast(i)); return this->m_elements[i]; } diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index ba6296e8904..19e4f7bf3d2 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -354,7 +354,7 @@ ASSERT_EQ(elements2[0], 1); ExternalArray asExternalArray() ``` -Return `ExternalArray(m_elements, S)`. +Return `ExternalArray(m_elements, S)`. _Example:_ ```c++ diff --git a/Fw/Ds/test/ut/ArrayTest.cpp b/Fw/Ds/test/ut/ArrayTest.cpp index 4842cc2f25f..793481a09d9 100644 --- a/Fw/Ds/test/ut/ArrayTest.cpp +++ b/Fw/Ds/test/ut/ArrayTest.cpp @@ -93,4 +93,10 @@ TEST(Array, GetSize) { ASSERT_EQ(size, 3); } +TEST(Array, AsExternalArray) { + Array a = { 1, 2, 3 }; + ExternalArray ea = a.asExternalArray(); + ASSERT_EQ(ea[0], 1); +} + } // namespace Ds From b8762774d2bde389fd47e588e8ebac5f69b279a5 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 28 May 2025 17:29:30 -0700 Subject: [PATCH 039/458] Revise tests for Fw/Ds --- Fw/Ds/Array.hpp | 4 ++-- Fw/Ds/docs/sdd.md | 2 +- Fw/Ds/test/ut/ExternalArrayTest.cpp | 12 ++++++++++++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Fw/Ds/Array.hpp b/Fw/Ds/Array.hpp index 36078e907c6..86480467556 100644 --- a/Fw/Ds/Array.hpp +++ b/Fw/Ds/Array.hpp @@ -72,14 +72,14 @@ class Array final { // ---------------------------------------------------------------------- //! Subscript operator - T& operator[](const FwSizeType i //!< The subscript index + T& operator[](FwSizeType i //!< The subscript index ) { FW_ASSERT(i < S, static_cast(i)); return this->m_elements[i]; } //! Const subscript operator - const T& operator[](const FwSizeType i //!< The subscript index + const T& operator[](FwSizeType i //!< The subscript index ) const { FW_ASSERT(i < S, static_cast(i)); return this->m_elements[i]; diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 19e4f7bf3d2..313fd6d6324 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -101,7 +101,7 @@ const T& operator[](FwSizeType i) const _Example:_ ```c++ -U32 elements[3]; +U32 elements[3] = {}; ExternalArray a(elements, 3); // Constant access ASSERT_EQ(a[0], 0); diff --git a/Fw/Ds/test/ut/ExternalArrayTest.cpp b/Fw/Ds/test/ut/ExternalArrayTest.cpp index 17a9d1aef61..0b7293ece04 100644 --- a/Fw/Ds/test/ut/ExternalArrayTest.cpp +++ b/Fw/Ds/test/ut/ExternalArrayTest.cpp @@ -33,4 +33,16 @@ TEST(ExternalArray, CopyConstructor) { ASSERT_EQ(a2.getSize(), 3); } +TEST(ExternalArray, Subscript) { + U32 elements[3] = {}; + ExternalArray a(elements, 3); + // Constant access + ASSERT_EQ(a[0], 0); + // Mutable access + a[0]++; + ASSERT_EQ(a[0], 1); + // Out-of-bounds access + ASSERT_DEATH(a[3], "Assert"); +} + } // namespace Ds From 83288ab38a5a768be522616bb315b9a7a56bd196 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 28 May 2025 17:33:29 -0700 Subject: [PATCH 040/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 313fd6d6324..1bbb897c5c5 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -97,7 +97,7 @@ const T& operator[](FwSizeType i) const 1. Assert that `i < m_size`. -1. Return a reference to `m_elements[i]`. +1. Return `m_elements[i]`. _Example:_ ```c++ @@ -295,7 +295,7 @@ const T& operator[](FwSizeType i) const 1. Assert that `i < S`. -1. Return a reference to `m_elements[i]`. +1. Return `m_elements[i]`. _Example:_ ```c++ @@ -334,7 +334,7 @@ Elements& getElements() const Elements& getElements() const ``` -Return a reference to `m_elements`. +Return `m_elements`. _Example:_ ```c++ From 0a1db4a736471e09b7ecd320739d3134da272bf0 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 28 May 2025 17:40:20 -0700 Subject: [PATCH 041/458] Revise ExternalArray and Array --- Fw/Ds/Array.hpp | 2 +- Fw/Ds/ExternalArray.hpp | 4 ++-- Fw/Ds/docs/sdd.md | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Fw/Ds/Array.hpp b/Fw/Ds/Array.hpp index 86480467556..bc09eca6979 100644 --- a/Fw/Ds/Array.hpp +++ b/Fw/Ds/Array.hpp @@ -64,7 +64,7 @@ class Array final { } //! Destructor - ~Array() {} + ~Array() = default; public: // ---------------------------------------------------------------------- diff --git a/Fw/Ds/ExternalArray.hpp b/Fw/Ds/ExternalArray.hpp index c4f70e272d4..0313d6dcc28 100644 --- a/Fw/Ds/ExternalArray.hpp +++ b/Fw/Ds/ExternalArray.hpp @@ -17,7 +17,7 @@ template class ExternalArray final { public: // ---------------------------------------------------------------------- - // Constructors + // Public constructors and destructors // ---------------------------------------------------------------------- //! Zero-argument constructor @@ -33,7 +33,7 @@ class ExternalArray final { ExternalArray(const ExternalArray& a) : m_elements(a.m_elements), m_size(a.m_size) {} //! Destructor - ~ExternalArray() {} + ~ExternalArray() = default; public: // ---------------------------------------------------------------------- diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 1bbb897c5c5..6dee2d06efc 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -82,7 +82,7 @@ ExternalArray a2(a1); ~ExternalArray() ``` -Do nothing. +Defined as `= default`. #### 1.1.4. Public Member Functions @@ -282,7 +282,7 @@ Array a2(a1); ~Array() ``` -Destroy each element of `m_elements`. +Defined as `= default`. #### 1.2.5. Public Member Functions From d49bc942d18b419ea98711981e0a69814c5c6199 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 29 May 2025 08:12:11 -0700 Subject: [PATCH 042/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 6dee2d06efc..c5ec987f00a 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -206,9 +206,14 @@ It is an alias of `T[S]`. #### 1.2.3. Private Member Variables -`Array` has one private variable `m_elements` for -storing the array elements. -It is a primitive C++ array of type `Elements`. +`Array` has one private variable `m_elements` of +type `Elements` for storing the array elements. + +`Array` has the following private member variables. + +|Name|Type|Purpose|Default Value| +|----|----|-------|-------------| +|`m_elements`|`Elements`|The array elements|C++ default initialization| #### 1.2.4. Public Constructors and Destructors From 9b566600404fc7454ce4c564b1de401b00d461b1 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 29 May 2025 08:12:32 -0700 Subject: [PATCH 043/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index c5ec987f00a..2a582f7be9e 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -206,9 +206,6 @@ It is an alias of `T[S]`. #### 1.2.3. Private Member Variables -`Array` has one private variable `m_elements` of -type `Elements` for storing the array elements. - `Array` has the following private member variables. |Name|Type|Purpose|Default Value| From 7872ad96787aa4e4790ab83faf7acc032bdf81c8 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 29 May 2025 08:41:49 -0700 Subject: [PATCH 044/458] Revise Fw/Ds --- Fw/Ds/Array.hpp | 6 ++++++ Fw/Ds/ExternalArray.hpp | 11 ++++++++--- Fw/Ds/docs/sdd.md | 23 ++++++++++++++--------- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/Fw/Ds/Array.hpp b/Fw/Ds/Array.hpp index bc09eca6979..2a2992e4b5e 100644 --- a/Fw/Ds/Array.hpp +++ b/Fw/Ds/Array.hpp @@ -72,6 +72,7 @@ class Array final { // ---------------------------------------------------------------------- //! Subscript operator + //! \return The element at index i T& operator[](FwSizeType i //!< The subscript index ) { FW_ASSERT(i < S, static_cast(i)); @@ -79,6 +80,7 @@ class Array final { } //! Const subscript operator + //! \return The element at index i const T& operator[](FwSizeType i //!< The subscript index ) const { FW_ASSERT(i < S, static_cast(i)); @@ -86,6 +88,7 @@ class Array final { } //! Copy assignment operator + //! \return *this Array& operator=(const Array& a) { if (&a != this) { for (FwSizeType i = 0; i < S; i++) { @@ -96,9 +99,11 @@ class Array final { } //! Get a mutable reference to the elements + //! \return A mutable reference to the elements Elements& getElements() { return this->m_elements; } //! Get a const reference to the elements + //! \return A const reference to the elements const Elements& getElements() const { return this->m_elements; } //! Convert this array to an ExternalArray @@ -111,6 +116,7 @@ class Array final { // ---------------------------------------------------------------------- //! Get the array size + //! \return The size static constexpr FwSizeType getSize() { return S; } private: diff --git a/Fw/Ds/ExternalArray.hpp b/Fw/Ds/ExternalArray.hpp index 0313d6dcc28..abbf49f3fb5 100644 --- a/Fw/Ds/ExternalArray.hpp +++ b/Fw/Ds/ExternalArray.hpp @@ -1,7 +1,7 @@ // ====================================================================== -// \title ExternalArray -// \author bocchino -// \brief A bounds-checked array with external memory +// @title ExternalArray +// @author bocchino +// @brief A bounds-checked array with external memory // ====================================================================== #ifndef Ds_ExternalArray_HPP @@ -41,6 +41,7 @@ class ExternalArray final { // ---------------------------------------------------------------------- //! Subscript operator + //! \return The element at index i T& operator[](const FwSizeType i //!< The subscript index ) { FW_ASSERT(this->m_elements != nullptr); @@ -49,6 +50,7 @@ class ExternalArray final { } //! Const subscript operator + //! \return The element at index i const T& operator[](const FwSizeType i //!< The subscript index ) const { FW_ASSERT(i < this->m_elements != nullptr); @@ -57,6 +59,7 @@ class ExternalArray final { } //! Copy assignment operator + //! \return *this ExternalArray& operator=(const ExternalArray& a) { if (&a != this) { this->m_elements = a.m_elements; @@ -66,9 +69,11 @@ class ExternalArray final { } //! Get a mutable pointer to the elements + //! \return A mutable pointer to the elements T* getElements() { return this->m_elements; } //! Get a const pointer to the elements + //! \return A const pointer to the elements const T* getElements() const { return this->m_elements; } //! Get the size diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 2a582f7be9e..12ef169866e 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -17,9 +17,11 @@ It stores a pointer to the backing memory _M_. #### 1.1.1. Template Parameters -`ExternalArray` has one template parameter: +`ExternalArray` has the following template parameters: -1. The type `typename T` +|Kind|Name|Purpose| +|----|----|-------| +|`typename`|`T`|The type of an array element| #### 1.1.2. Private Member Variables @@ -191,11 +193,12 @@ It maintains the backing memory _M_ as a member variable. #### 1.2.1. Template Parameters -`Array` has two template parameters: +`Array` has the following template parameters. -1. The type `typename T` - -1. The size `FwSizeType S` +|Kind|Name|Purpose| +|----|----|-------| +|`typename`|`T`|The type of an array element| +|`FwSizeType`|`S`|The array size in elements| `Array` statically asserts that `S > 0`. @@ -490,15 +493,17 @@ first in first out (FIFO) order. ### 3.1. ExternalFifoQueue `ExternalFifoQueue` is a `final` class template representing a -first in first out (FIFO) queue with external storage. +FIFO queue with external storage. Internally it maintains an `ExternalArray` for storing the elements on the queue. #### 3.1.1. Template Parameters -`ExternalFifoQueue` has one template parameter: +`ExternalFifoQueue` has the following template parameters. -1. The type `typename T` +|Kind|Name|Purpose| +|----|----|-------| +|`typename`|`T`|The type of an element on the queue| #### 3.1.2. Private Member Variables From 67edf659ff4ce02ff493a4854285546ea3f20e74 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 29 May 2025 08:43:53 -0700 Subject: [PATCH 045/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 12ef169866e..c76047d117f 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -17,7 +17,7 @@ It stores a pointer to the backing memory _M_. #### 1.1.1. Template Parameters -`ExternalArray` has the following template parameters: +`ExternalArray` has the following template parameters. |Kind|Name|Purpose| |----|----|-------| @@ -67,7 +67,7 @@ ExternalArray a(elements, 3); ExternalArray(const ExternalArray& a) ``` -Set `m_elements = a.elements` and `m_size = a.size`. +Set `m_elements = a.m_elements` and `m_size = a.m_size`. _Example:_ ```c++ @@ -122,7 +122,7 @@ ExternalArray& operator=(const ExternalArray& a) 1. If `&a == this` then do nothing. -1. Otherwise set `m_elements = a.elements` and `m_size = a.size`. +1. Otherwise set `m_elements = a.m_elements` and `m_size = a.m_size`. _Example:_ ```c++ @@ -236,7 +236,7 @@ Array a; Array(const std::initializer_list& il) ``` -1. Assert that `il.size == S`. +1. Assert that `il.m_size == S`. 1. Initialize `m_elements` from `il`. From 1b672ef64d3a97406dfa8be211bead374018d0ce Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 29 May 2025 08:45:11 -0700 Subject: [PATCH 046/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index c76047d117f..6e119003da0 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -466,7 +466,7 @@ void setModulus(FwSizeType modulus) FwSizeType increment(FwSizeType amount = 1) ``` -1. Set `offset = amount % modulus`. +1. Set `offset = amount % m_modulus`. 1. Call `setValue(m_value + offset)`. @@ -478,9 +478,9 @@ FwSizeType increment(FwSizeType amount = 1) FwSizeType decrement(FwSizeType amount = 1) ``` -1. Set `offset = amount % modulus`. +1. Set `offset = amount % m_modulus`. -1. Call `setValue(m_value + modulus - offset)`. +1. Call `setValue(m_value + m_modulus - offset)`. 1. Return `m_value`. From 10f048654f700b04e1bc437426acc8f7867b4e52 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 29 May 2025 08:56:30 -0700 Subject: [PATCH 047/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 6e119003da0..8e0bc3c4e70 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -7,7 +7,8 @@ This directory contains a library of basic data structures. An **array** _A_ stores _n_ elements for _n > 0_ at indices 0, 1, ..., _n - 1_. The elements are stored in **backing memory** _M_. -An array provides bounds-checked access to the array elements. +An array provides bounds-checked access to the array elements +stored in _M_. ### 1.1. External Array @@ -524,7 +525,8 @@ the elements on the queue. ExternalFifoQueue() ``` -TODO +`ExternalFifoQueue` is a `final` class template representing a FIFO queue with internal storage. +It maintains an `Array` for storing the elements on the queue. **Constructor providing backing storage:** @@ -598,6 +600,22 @@ TODO TODO +#### 3.2.1. Template Parameters + +TODO + +#### 3.2.2. Private Member Variables + +TODO + +#### 3.2.3. Public Constructors and Destructors + +TODO + +#### 3.2.4. Public Member Functions + +TODO + ## 4. Linked Lists TODO From 2a9ff8e785172fa85f5b5355aca380db0a115b10 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 29 May 2025 09:55:44 -0700 Subject: [PATCH 048/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 8e0bc3c4e70..5cd5f41a373 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -10,6 +10,7 @@ The elements are stored in **backing memory** _M_. An array provides bounds-checked access to the array elements stored in _M_. + ### 1.1. External Array `ExternalArray` is a `final` class template representing an array with external @@ -186,6 +187,7 @@ U32 elements[3]; a.setStorage(elements, 3); ``` + ### 1.2. Array `Array` is a `final` class template representing an array @@ -495,8 +497,8 @@ first in first out (FIFO) order. `ExternalFifoQueue` is a `final` class template representing a FIFO queue with external storage. -Internally it maintains an `ExternalArray` for storing -the elements on the queue. +Internally it maintains an `ExternalArray` for +storing the elements on the queue. #### 3.1.1. Template Parameters @@ -598,11 +600,21 @@ TODO ### 3.2. FifoQueue -TODO +`FifoQueue` is a `final` class template representing a +FIFO queue with internal storage. +Internally it maintains an `Array` +for storing the elements on the queue. #### 3.2.1. Template Parameters -TODO +`FifoQueue` has the following template parameters. + +|Kind|Name|Purpose| +|----|----|-------| +|`typename`|`T`|The type of a queue element| +|`FwSizeType`|`S`|The queue size in elements| + +`FifoQueue` statically asserts that `S > 0`. #### 3.2.2. Private Member Variables From aeec77c894fc1d189f64f6399ae4baf73759e610 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 29 May 2025 11:05:13 -0700 Subject: [PATCH 049/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 94 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 91 insertions(+), 3 deletions(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 5cd5f41a373..783fc2e9529 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -134,6 +134,20 @@ ExternalArray a2; a2 = a1; ``` +**copyFrom:** + +```c++ +void copyFrom(const ExternalArray& a) +``` + +1. If `&a == this` then do nothing. + +1. Otherwise + + 1. Let `m` be the minimum of `this->m_size` and `a.m_size` + + 1. For each `i` from 0 through `m - 1`, set `m_elements[i] = a.m_elements[i]` + **getElements:** ```c++ @@ -533,7 +547,7 @@ It maintains an `Array` for storing the elements on the queue. **Constructor providing backing storage:** ```c++ -ExternalArray(T* elements, FwSizeType size) +ExternalFifoQueue(T* elements, FwSizeType size) ``` TODO @@ -618,14 +632,88 @@ for storing the elements on the queue. #### 3.2.2. Private Member Variables -TODO +`FifoQueue` has the following private member variables. + +|Name|Type|Purpose|Default Value| +|----|----|-------|-------------| +|`m_eQueue`|`ExternalFifoQueue`|The external queue implementation|C++ default initialization| +|`m_array`|`Array`|The array providing the backing memory for `m_queue`|C++ default initialization| #### 3.2.3. Public Constructors and Destructors -TODO +**Zero-argument constructor:** + +```c++ +FifoQueue() +``` + +Initialize each member with default initialization. + +_Example:_ +```c++ +FifoQueue queue; +``` + +**Copy constructor:** + +```c++ +FifoQueue(const FifoQueue& queue) +``` + +Call `m_eQueue.copyFrom(queue.m_eQueue)`. + +_Example:_ +```c++ +FifoQueue q1; +q1.enqueue(3); +FifoQueue q2; +q2 = q1; +``` + +**Destructor:** + +```c++ +~FifoQueue() +``` + +Defined as `= default`. #### 3.2.4. Public Member Functions +**clear:** + +```c++ +void clear() +``` + +TODO + +**enqueue:** + +```c++ +Fw::Success enqueue(const T& e) +``` + +TODO + +**peek:** + +```c++ +Fw::Success peek(T& e) +``` + +TODO + +**dequeue:** + +TODO + +**getSize:** + +TODO + +**getCapacity:** + TODO ## 4. Linked Lists From 2bf0e7dd451a80067ac56f85237a7f03a761c5ea Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 29 May 2025 11:32:07 -0700 Subject: [PATCH 050/458] Revise ExternalArray --- Fw/Ds/ExternalArray.hpp | 10 +++++- Fw/Ds/docs/sdd.md | 16 +++++++-- Fw/Ds/test/ut/ExternalArrayTest.cpp | 51 +++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 3 deletions(-) diff --git a/Fw/Ds/ExternalArray.hpp b/Fw/Ds/ExternalArray.hpp index abbf49f3fb5..4c84cbb3c96 100644 --- a/Fw/Ds/ExternalArray.hpp +++ b/Fw/Ds/ExternalArray.hpp @@ -53,7 +53,7 @@ class ExternalArray final { //! \return The element at index i const T& operator[](const FwSizeType i //!< The subscript index ) const { - FW_ASSERT(i < this->m_elements != nullptr); + FW_ASSERT(this->m_elements != nullptr); FW_ASSERT(i < this->m_size, static_cast(i)); return this->m_elements[i]; } @@ -68,6 +68,14 @@ class ExternalArray final { return *this; } + //! Copy the elements from a + void copyFrom(const ExternalArray& a) { + const FwSizeType size = FW_MIN(this->m_size, a.m_size); + for (FwSizeType i = 0; i < size; i++) { + (*this)[i] = a[i]; + } + } + //! Get a mutable pointer to the elements //! \return A mutable pointer to the elements T* getElements() { return this->m_elements; } diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 783fc2e9529..9c31be12b3b 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -144,9 +144,21 @@ void copyFrom(const ExternalArray& a) 1. Otherwise - 1. Let `m` be the minimum of `this->m_size` and `a.m_size` + 1. Let `size` be the minimum of `this->m_size` and `a.m_size` - 1. For each `i` from 0 through `m - 1`, set `m_elements[i] = a.m_elements[i]` + 1. For each `i` from 0 through `size - 1`, set `m_elements[i] = a.m_elements[i]` + +_Example:_ +```c++ +U32 elements1[10]; +ExternalArray a1(elements, 10); +for (FwSizeType i = 0; i < 10; i++) { + a1[i] = i; +} +U32 elements2[10]; +ExternalArray a2(elements, 10); +a2.copyFrom(a1); +``` **getElements:** diff --git a/Fw/Ds/test/ut/ExternalArrayTest.cpp b/Fw/Ds/test/ut/ExternalArrayTest.cpp index 0b7293ece04..6ca991276ed 100644 --- a/Fw/Ds/test/ut/ExternalArrayTest.cpp +++ b/Fw/Ds/test/ut/ExternalArrayTest.cpp @@ -33,6 +33,48 @@ TEST(ExternalArray, CopyConstructor) { ASSERT_EQ(a2.getSize(), 3); } +TEST(ExternalArray, CopyAssignment) { + U32 elements[3]; + // Call the constructor providing backing storage + ExternalArray a1(elements, 3); + // Call the copy assignment operator + ExternalArray a2; + a2 = a1; + ASSERT_EQ(a1.getElements(), a2.getElements()); + ASSERT_EQ(a1.getSize(), a2.getSize()); +} + +static void testCopyFrom( + ExternalArray a1, + ExternalArray a2 +) { + const FwSizeType size1 = a1.getSize(); + for (FwSizeType i = 0; i < size1; i++) { + a1[i] = static_cast(i); + } + const FwSizeType size2 = a2.getSize(); + for (FwSizeType i = 0; i < size2; i++) { + a2[i] = 0; + } + a2.copyFrom(a1); + const FwSizeType size = FW_MIN(size1, size2); + for (FwSizeType i = 0; i < size; i++) { + ASSERT_EQ(a2[i], a1[i]); + } +} + +TEST(ExternalArray, CopyFrom) { + constexpr FwSizeType maxSize = 10; + U32 elements1[maxSize]; + U32 elements2[maxSize]; + // size1 < size2 + testCopyFrom(ExternalArray(elements1, 5), ExternalArray(elements2, 10)); + // size1 == size2 + testCopyFrom(ExternalArray(elements1, 10), ExternalArray(elements2, 10)); + // size1 > size2 + testCopyFrom(ExternalArray(elements1, 10), ExternalArray(elements2, 5)); +} + TEST(ExternalArray, Subscript) { U32 elements[3] = {}; ExternalArray a(elements, 3); @@ -45,4 +87,13 @@ TEST(ExternalArray, Subscript) { ASSERT_DEATH(a[3], "Assert"); } +TEST(ExternalArray, SetStorage) { + U32 elements[3]; + ExternalArray a1(elements, 3); + ExternalArray a2; + a2.setStorage(a1.getElements(), a1.getSize()); + ASSERT_EQ(a2.getElements(), a1.getElements()); + ASSERT_EQ(a2.getSize(), a1.getSize()); +} + } // namespace Ds From b395c7d41266d88855ec84d354d0446d4c2a2bb6 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 29 May 2025 11:36:48 -0700 Subject: [PATCH 051/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 9c31be12b3b..795d4c8e00c 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -158,6 +158,9 @@ for (FwSizeType i = 0; i < 10; i++) { U32 elements2[10]; ExternalArray a2(elements, 10); a2.copyFrom(a1); +for (FwSizeType i = 0; i < 10; i++) { + ASSERT_EQ(a2[i], a1[i]); +} ``` **getElements:** @@ -596,6 +599,16 @@ TODO void setStorage(T* elements, FwSizeType size) ``` +TODO + +**copyFrom:** + +```c++ +void copyFrom(const ExternalFifoQueue& queue) +``` + +TODO + **enqueue:** ```c++ @@ -680,6 +693,10 @@ FifoQueue q1; q1.enqueue(3); FifoQueue q2; q2 = q1; +U32 value = 0; +const auto status = q2.dequeue(value); +ASSERT_EQ(status, Fw::Success::SUCCESS); +ASSERT_EQ(value, 3); ``` **Destructor:** From 65c0681cd4c4483c4ab22bcc6671a7193e9ff948 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 29 May 2025 11:38:07 -0700 Subject: [PATCH 052/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 795d4c8e00c..7488534de74 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -690,11 +690,12 @@ Call `m_eQueue.copyFrom(queue.m_eQueue)`. _Example:_ ```c++ FifoQueue q1; -q1.enqueue(3); +auto status = q1.enqueue(3); +ASSERT_EQ(status, Fw::Success::SUCCESS); FifoQueue q2; q2 = q1; U32 value = 0; -const auto status = q2.dequeue(value); +status = q2.dequeue(value); ASSERT_EQ(status, Fw::Success::SUCCESS); ASSERT_EQ(value, 3); ``` From 31016fa5db7f511b51be483fa9968ae86383c26f Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 29 May 2025 11:47:08 -0700 Subject: [PATCH 053/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 7488534de74..39f3d964876 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -710,6 +710,14 @@ Defined as `= default`. #### 3.2.4. Public Member Functions +**Copy assignment operator:** + +```c++ +FifoQueue& operator=(const FifoQueue& queue) +``` + +TODO + **clear:** ```c++ @@ -746,6 +754,10 @@ TODO TODO +**asExternalFifoQueue:** + +TODO + ## 4. Linked Lists TODO From fade02b8ec632625f918326a15052878c34cc502 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 29 May 2025 11:55:21 -0700 Subject: [PATCH 054/458] Revise Fw/Ds --- Fw/Ds/ExternalArray.hpp | 2 +- Fw/Ds/docs/sdd.md | 43 +++++++++++++++-------------- Fw/Ds/test/ut/ExternalArrayTest.cpp | 17 +++++------- 3 files changed, 30 insertions(+), 32 deletions(-) diff --git a/Fw/Ds/ExternalArray.hpp b/Fw/Ds/ExternalArray.hpp index 4c84cbb3c96..b65f2f5d683 100644 --- a/Fw/Ds/ExternalArray.hpp +++ b/Fw/Ds/ExternalArray.hpp @@ -69,7 +69,7 @@ class ExternalArray final { } //! Copy the elements from a - void copyFrom(const ExternalArray& a) { + void copyElementsFrom(const ExternalArray& a) { const FwSizeType size = FW_MIN(this->m_size, a.m_size); for (FwSizeType i = 0; i < size; i++) { (*this)[i] = a[i]; diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 39f3d964876..e9e5f181c32 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -4,8 +4,8 @@ This directory contains a library of basic data structures. ## 1. Arrays -An **array** _A_ stores _n_ elements for _n > 0_ at indices -0, 1, ..., _n - 1_. +An **array** _A_ stores _S_ elements for _S > 0_ at indices +0, 1, ..., _S - 1_. The elements are stored in **backing memory** _M_. An array provides bounds-checked access to the array elements stored in _M_. @@ -134,10 +134,10 @@ ExternalArray a2; a2 = a1; ``` -**copyFrom:** +**copyElementsFrom:** ```c++ -void copyFrom(const ExternalArray& a) +void copyElementsFrom(const ExternalArray& a) ``` 1. If `&a == this` then do nothing. @@ -157,7 +157,7 @@ for (FwSizeType i = 0; i < 10; i++) { } U32 elements2[10]; ExternalArray a2(elements, 10); -a2.copyFrom(a1); +a2.copyElementsFrom(a1); for (FwSizeType i = 0; i < 10; i++) { ASSERT_EQ(a2[i], a1[i]); } @@ -527,7 +527,7 @@ first in first out (FIFO) order. `ExternalFifoQueue` is a `final` class template representing a FIFO queue with external storage. Internally it maintains an `ExternalArray` for -storing the elements on the queue. +storing the items on the queue. #### 3.1.1. Template Parameters @@ -535,7 +535,7 @@ storing the elements on the queue. |Kind|Name|Purpose| |----|----|-------| -|`typename`|`T`|The type of an element on the queue| +|`typename`|`T`|The type of an item on the queue| #### 3.1.2. Private Member Variables @@ -543,10 +543,10 @@ storing the elements on the queue. |Name|Type|Purpose|Default Value| |----|----|-------|-------------| -|`m_array`|`ExternalArray`|The array for storing the elements|C++ default initialization| +|`m_items`|`ExternalArray`|The array for storing the queue items|C++ default initialization| |`m_enqueueIndex`|`CircularIndex`|The enqueue index|0| |`m_dequeueIndex`|`CircularIndex`|The dequeue index|0| -|`m_size`|`FwSizeType`|The number of elements on the queue|0| +|`m_size`|`FwSizeType`|The number of items on the queue|0| #### 3.1.3. Public Constructors and Destructors @@ -556,13 +556,14 @@ storing the elements on the queue. ExternalFifoQueue() ``` -`ExternalFifoQueue` is a `final` class template representing a FIFO queue with internal storage. -It maintains an `Array` for storing the elements on the queue. +`ExternalFifoQueue` is a `final` class template representing a FIFO queue with +internal storage. +It maintains an `Array` for storing the items on the queue. **Constructor providing backing storage:** ```c++ -ExternalFifoQueue(T* elements, FwSizeType size) +ExternalFifoQueue(T* items, FwSizeType size) ``` TODO @@ -596,15 +597,15 @@ TODO **setStorage:** ```c++ -void setStorage(T* elements, FwSizeType size) +void setStorage(T* items, FwSizeType size) ``` TODO -**copyFrom:** +**copyItemsFrom:** ```c++ -void copyFrom(const ExternalFifoQueue& queue) +void copyItemsFrom(const ExternalFifoQueue& queue) ``` TODO @@ -642,7 +643,7 @@ TODO `FifoQueue` is a `final` class template representing a FIFO queue with internal storage. Internally it maintains an `Array` -for storing the elements on the queue. +for storing the items on the queue. #### 3.2.1. Template Parameters @@ -650,10 +651,10 @@ for storing the elements on the queue. |Kind|Name|Purpose| |----|----|-------| -|`typename`|`T`|The type of a queue element| -|`FwSizeType`|`S`|The queue size in elements| +|`typename`|`T`|The type of a queue item| +|`FwSizeType`|`C`|The queue capacity in items| -`FifoQueue` statically asserts that `S > 0`. +`FifoQueue` statically asserts that `C > 0`. #### 3.2.2. Private Member Variables @@ -662,7 +663,7 @@ for storing the elements on the queue. |Name|Type|Purpose|Default Value| |----|----|-------|-------------| |`m_eQueue`|`ExternalFifoQueue`|The external queue implementation|C++ default initialization| -|`m_array`|`Array`|The array providing the backing memory for `m_queue`|C++ default initialization| +|`m_array`|`Array`|The array providing the backing memory for `m_queue`|C++ default initialization| #### 3.2.3. Public Constructors and Destructors @@ -685,7 +686,7 @@ FifoQueue queue; FifoQueue(const FifoQueue& queue) ``` -Call `m_eQueue.copyFrom(queue.m_eQueue)`. +Call `m_eQueue.copyItemsFrom(queue.m_eQueue)`. _Example:_ ```c++ diff --git a/Fw/Ds/test/ut/ExternalArrayTest.cpp b/Fw/Ds/test/ut/ExternalArrayTest.cpp index 6ca991276ed..6eacef7d1dc 100644 --- a/Fw/Ds/test/ut/ExternalArrayTest.cpp +++ b/Fw/Ds/test/ut/ExternalArrayTest.cpp @@ -44,10 +44,7 @@ TEST(ExternalArray, CopyAssignment) { ASSERT_EQ(a1.getSize(), a2.getSize()); } -static void testCopyFrom( - ExternalArray a1, - ExternalArray a2 -) { +static void testCopyElementsFrom(ExternalArray a1, ExternalArray a2) { const FwSizeType size1 = a1.getSize(); for (FwSizeType i = 0; i < size1; i++) { a1[i] = static_cast(i); @@ -56,23 +53,23 @@ static void testCopyFrom( for (FwSizeType i = 0; i < size2; i++) { a2[i] = 0; } - a2.copyFrom(a1); + a2.copyElementsFrom(a1); const FwSizeType size = FW_MIN(size1, size2); for (FwSizeType i = 0; i < size; i++) { - ASSERT_EQ(a2[i], a1[i]); + ASSERT_EQ(a2[i], a1[i]); } } -TEST(ExternalArray, CopyFrom) { +TEST(ExternalArray, CopyElementsFrom) { constexpr FwSizeType maxSize = 10; U32 elements1[maxSize]; U32 elements2[maxSize]; // size1 < size2 - testCopyFrom(ExternalArray(elements1, 5), ExternalArray(elements2, 10)); + testCopyElementsFrom(ExternalArray(elements1, 5), ExternalArray(elements2, 10)); // size1 == size2 - testCopyFrom(ExternalArray(elements1, 10), ExternalArray(elements2, 10)); + testCopyElementsFrom(ExternalArray(elements1, 10), ExternalArray(elements2, 10)); // size1 > size2 - testCopyFrom(ExternalArray(elements1, 10), ExternalArray(elements2, 5)); + testCopyElementsFrom(ExternalArray(elements1, 10), ExternalArray(elements2, 5)); } TEST(ExternalArray, Subscript) { From ad72da94d24e5a73bde7ab13105c79e7c8e91036 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 29 May 2025 13:07:42 -0700 Subject: [PATCH 055/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index e9e5f181c32..89af2a7bd81 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -628,14 +628,26 @@ TODO **dequeue:** +```c++ +Fw::Success dequeue(T& e) +``` + TODO **getSize:** +```c++ +FwSizeType getSize() const +``` + TODO **getCapacity:** +```c++ +FwSizeType getCapacity() const +``` + TODO ### 3.2. FifoQueue @@ -745,18 +757,34 @@ TODO **dequeue:** +```c++ +Fw::Success dequeue(T& e) +``` + TODO **getSize:** +```c++ +FwSizeType getSize() const +``` + TODO **getCapacity:** +```c++ +FwSizeType getCapacity() const +``` + TODO **asExternalFifoQueue:** +```c++ +ExternalFifoQueue asExternalFifoQueue() +``` + TODO ## 4. Linked Lists From 39924e05c6d31aa2a5ba7503b7d58dd6921d464e Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 29 May 2025 13:30:52 -0700 Subject: [PATCH 056/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 89af2a7bd81..8709925e0e6 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -77,7 +77,7 @@ U32 elements[3]; // Call the constructor providing backing storage ExternalArray a1(elements, 3); // Call the copy constructor -ExternalArray a2(a1); +ExternalArray a2(a1); ``` **Destructor:** @@ -566,7 +566,13 @@ It maintains an `Array` for storing the items on the queue. ExternalFifoQueue(T* items, FwSizeType size) ``` -TODO +Initialize `m_items` with `items` and `size`. + +_Example:_ +```c++ +U32 items[10]; +ExternalFifoQueue queue(items, 10); +``` **Copy constructor:** @@ -574,7 +580,25 @@ TODO ExternalFifoQueue(const ExternalFifoQueue& queue) ``` -TODO +1. Set `m_items = queue.m_items`. + +1. Set `m_enqueueIndex = queue.m_enqueueIndex`. + +1. Set `m_dequeueIndex = queue.m_dequeueIndex`. + +1. Set `m_size = queue.size`. + +_Example:_ +```c++ +U32 items[10]; +// Call the constructor providing backing storage +ExternalFifoQueue q1(elements, 10); +// Enqueue an element +U32 value = 42; +(void) q1.enqueue(value); +// Call the copy constructor +ExternalFifoQueue a2(a1); +``` **Destructor:** @@ -582,7 +606,7 @@ TODO ExternalFifoQueue() ``` -TODO +Defined as `= default`. #### 3.1.4. Public Member Functions @@ -675,7 +699,7 @@ for storing the items on the queue. |Name|Type|Purpose|Default Value| |----|----|-------|-------------| |`m_eQueue`|`ExternalFifoQueue`|The external queue implementation|C++ default initialization| -|`m_array`|`Array`|The array providing the backing memory for `m_queue`|C++ default initialization| +|`m_array`|`Array`|The array providing the backing memory for `m_eQueue`|C++ default initialization| #### 3.2.3. Public Constructors and Destructors From 71ef451af2041bb1757ac6abece6a5b0999f7622 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 29 May 2025 13:55:42 -0700 Subject: [PATCH 057/458] Revise SDD for Fw/Ds --- Fw/Ds/docs/sdd.md | 73 ++++++++++++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 30 deletions(-) diff --git a/Fw/Ds/docs/sdd.md b/Fw/Ds/docs/sdd.md index 8709925e0e6..92723219353 100644 --- a/Fw/Ds/docs/sdd.md +++ b/Fw/Ds/docs/sdd.md @@ -59,8 +59,9 @@ Initialize `m_elements` with `elements` and `m_size` with `size`. _Example:_ ```c++ -U32 elements[3]; -ExternalArray a(elements, 3); +constexpr FwSizeType size = 3; +U32 elements[size]; +ExternalArray a(elements, size); ``` **Copy constructor:** @@ -73,9 +74,10 @@ Set `m_elements = a.m_elements` and `m_size = a.m_size`. _Example:_ ```c++ -U32 elements[3]; +constexpr FwSizeType size = 3; +U32 elements[size]; // Call the constructor providing backing storage -ExternalArray a1(elements, 3); +ExternalArray a1(elements, size); // Call the copy constructor ExternalArray a2(a1); ``` @@ -105,15 +107,16 @@ const T& operator[](FwSizeType i) const _Example:_ ```c++ -U32 elements[3] = {}; -ExternalArray a(elements, 3); +constexpr FwSizeType size = 3; +U32 elements[size] = {}; +ExternalArray a(elements, size); // Constant access ASSERT_EQ(a[0], 0); // Mutable access a[0]++; ASSERT_EQ(a[0], 1); // Out-of-bounds access -ASSERT_DEATH(a[3], "Assert"); +ASSERT_DEATH(a[size], "Assert"); ``` **Copy assignment operator:** @@ -128,8 +131,9 @@ ExternalArray& operator=(const ExternalArray& a) _Example:_ ```c++ -U32 elements[3]; -ExternalArray a1(elements, 3); +constexpr FwSizeType size = 3; +U32 elements[size]; +ExternalArray a1(elements, size); ExternalArray a2; a2 = a1; ``` @@ -150,15 +154,16 @@ void copyElementsFrom(const ExternalArray& a) _Example:_ ```c++ -U32 elements1[10]; -ExternalArray a1(elements, 10); -for (FwSizeType i = 0; i < 10; i++) { +constexpr FwSizeType size = 10; +U32 elements1[size]; +ExternalArray a1(elements, size); +for (FwSizeType i = 0; i < size; i++) { a1[i] = i; } -U32 elements2[10]; -ExternalArray a2(elements, 10); +U32 elements2[size]; +ExternalArray a2(elements, size); a2.copyElementsFrom(a1); -for (FwSizeType i = 0; i < 10; i++) { +for (FwSizeType i = 0; i < size; i++) { ASSERT_EQ(a2[i], a1[i]); } ``` @@ -174,8 +179,9 @@ Return `m_elements`. _Example:_ ```c++ -U32 elements[3]; -ExternalArray a(elements, 3); +constexpr FwSizeType size = 3; +U32 elements[size]; +ExternalArray a(elements, size); // Mutable pointer auto& elements1 = a.getElements(); ASSERT_EQ(elements1[0], 0); @@ -195,10 +201,11 @@ Return `m_size`. _Example:_ ```c++ -U32 elements[3]; -ExternalArray a(elements, 3); -const auto size = a.getSize(); -ASSERT_EQ(size, 3); +constexpr FwSizeType size = 3; +U32 elements[size]; +ExternalArray a(elements, size); +const auto size1 = a.getSize(); +ASSERT_EQ(size1, size); ``` **setStorage:** @@ -211,9 +218,10 @@ Set `m_elements = elements` and `m_size = size`. _Example:_ ```c++ +constexpr FwSizeType size = 3; ExternalArray a; -U32 elements[3]; -a.setStorage(elements, 3); +U32 elements[size]; +a.setStorage(elements, size); ``` @@ -336,14 +344,15 @@ const T& operator[](FwSizeType i) const _Example:_ ```c++ -Array a; +constexpr FwSizeType size = 3; +Array a; // Constant access ASSERT_EQ(a[0], 0); // Mutable access a[0]++; ASSERT_EQ(a[0], 1); // Out-of-bounds access -ASSERT_DEATH(a[3], "Assert"); +ASSERT_DEATH(a[size], "Assert"); ``` **Copy assignment operator:** @@ -375,7 +384,8 @@ Return `m_elements`. _Example:_ ```c++ -Array a; +constexpr FwSizeType size = 3; +Array a; // Mutable reference auto& elements1 = a.getElements(); ASSERT_EQ(elements1[0], 0); @@ -395,7 +405,8 @@ Return `ExternalArray(m_elements, S)`. _Example:_ ```c++ -Array a = { 1, 2, 3 }; +constexpr FwSizeType size = 3; +Array a = { 1, 2, 3 }; ExternalArray ea = a.asExternalArray(); ASSERT_EQ(ea[0], 1); ``` @@ -570,8 +581,9 @@ Initialize `m_items` with `items` and `size`. _Example:_ ```c++ -U32 items[10]; -ExternalFifoQueue queue(items, 10); +constexpr FwSizeType size = 10; +U32 items[size]; +ExternalFifoQueue queue(items, size); ``` **Copy constructor:** @@ -590,7 +602,8 @@ ExternalFifoQueue(const ExternalFifoQueue& queue) _Example:_ ```c++ -U32 items[10]; +constexpr FwSizeType size = 3; +U32 items[size]; // Call the constructor providing backing storage ExternalFifoQueue q1(elements, 10); // Enqueue an element From e3c25eebe106d8f72914adc4f34e95a75699d9a2 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 29 May 2025 16:07:08 -0700 Subject: [PATCH 058/458] Rename Ds --> DataStructures --- Fw/CMakeLists.txt | 2 +- Fw/{Ds => DataStructures}/Array.hpp | 10 +++++----- Fw/{Ds => DataStructures}/CMakeLists.txt | 4 ++-- Fw/{Ds/Ds.cpp => DataStructures/DataStructures.cpp} | 0 Fw/{Ds => DataStructures}/ExternalArray.hpp | 8 ++++---- Fw/{Ds => DataStructures}/docs/sdd.md | 0 Fw/{Ds => DataStructures}/test/ut/ArrayTest.cpp | 6 +++--- .../test/ut/DataStructuresTestMain.cpp} | 4 ++-- .../test/ut/ExternalArrayTest.cpp | 6 +++--- 9 files changed, 20 insertions(+), 20 deletions(-) rename Fw/{Ds => DataStructures}/Array.hpp (95%) rename Fw/{Ds => DataStructures}/CMakeLists.txt (66%) rename Fw/{Ds/Ds.cpp => DataStructures/DataStructures.cpp} (100%) rename Fw/{Ds => DataStructures}/ExternalArray.hpp (95%) rename Fw/{Ds => DataStructures}/docs/sdd.md (100%) rename Fw/{Ds => DataStructures}/test/ut/ArrayTest.cpp (96%) rename Fw/{Ds/test/ut/DsTestMain.cpp => DataStructures/test/ut/DataStructuresTestMain.cpp} (81%) rename Fw/{Ds => DataStructures}/test/ut/ExternalArrayTest.cpp (96%) diff --git a/Fw/CMakeLists.txt b/Fw/CMakeLists.txt index 1f261274a89..700d14decaa 100644 --- a/Fw/CMakeLists.txt +++ b/Fw/CMakeLists.txt @@ -4,8 +4,8 @@ set(FPRIME_FRAMEWORK_MODULES Fw_Prm Fw_Cmd Fw_Log Fw_Tlm Fw_Fpy Fw_Com Fw_Time F add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Buffer/") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Cmd/") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Com/") +add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/DataStructures/") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Dp/") -add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Ds/") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Fpy/") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Log/") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Logger/") diff --git a/Fw/Ds/Array.hpp b/Fw/DataStructures/Array.hpp similarity index 95% rename from Fw/Ds/Array.hpp rename to Fw/DataStructures/Array.hpp index 2a2992e4b5e..634381949de 100644 --- a/Fw/Ds/Array.hpp +++ b/Fw/DataStructures/Array.hpp @@ -4,16 +4,16 @@ // \brief A statically-sized, bounds checked array // ====================================================================== -#ifndef Ds_Array_HPP -#define Ds_Array_HPP +#ifndef DataStructures_Array_HPP +#define DataStructures_Array_HPP #include #include -#include "Fw/Ds/ExternalArray.hpp" +#include "Fw/DataStructures/ExternalArray.hpp" #include "Fw/Types/Assert.hpp" -namespace Ds { +namespace DataStructures { template class Array final { @@ -128,6 +128,6 @@ class Array final { Elements m_elements = {}; }; -} // namespace Ds +} // namespace DataStructures #endif diff --git a/Fw/Ds/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt similarity index 66% rename from Fw/Ds/CMakeLists.txt rename to Fw/DataStructures/CMakeLists.txt index e9fbd4033be..828280898b4 100644 --- a/Fw/Ds/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -1,12 +1,12 @@ set(SOURCE_FILES - "${CMAKE_CURRENT_LIST_DIR}/Ds.cpp" + "${CMAKE_CURRENT_LIST_DIR}/DataStructures.cpp" ) register_fprime_module() set(UT_SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/DsTestMain.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" ) diff --git a/Fw/Ds/Ds.cpp b/Fw/DataStructures/DataStructures.cpp similarity index 100% rename from Fw/Ds/Ds.cpp rename to Fw/DataStructures/DataStructures.cpp diff --git a/Fw/Ds/ExternalArray.hpp b/Fw/DataStructures/ExternalArray.hpp similarity index 95% rename from Fw/Ds/ExternalArray.hpp rename to Fw/DataStructures/ExternalArray.hpp index b65f2f5d683..b32ec937987 100644 --- a/Fw/Ds/ExternalArray.hpp +++ b/Fw/DataStructures/ExternalArray.hpp @@ -4,14 +4,14 @@ // @brief A bounds-checked array with external memory // ====================================================================== -#ifndef Ds_ExternalArray_HPP -#define Ds_ExternalArray_HPP +#ifndef DataStructures_ExternalArray_HPP +#define DataStructures_ExternalArray_HPP #include #include "Fw/Types/Assert.hpp" -namespace Ds { +namespace DataStructures { template class ExternalArray final { @@ -108,6 +108,6 @@ class ExternalArray final { FwSizeType m_size = 0; }; -} // namespace Ds +} // namespace DataStructures #endif diff --git a/Fw/Ds/docs/sdd.md b/Fw/DataStructures/docs/sdd.md similarity index 100% rename from Fw/Ds/docs/sdd.md rename to Fw/DataStructures/docs/sdd.md diff --git a/Fw/Ds/test/ut/ArrayTest.cpp b/Fw/DataStructures/test/ut/ArrayTest.cpp similarity index 96% rename from Fw/Ds/test/ut/ArrayTest.cpp rename to Fw/DataStructures/test/ut/ArrayTest.cpp index 793481a09d9..e5bd1d4f98d 100644 --- a/Fw/Ds/test/ut/ArrayTest.cpp +++ b/Fw/DataStructures/test/ut/ArrayTest.cpp @@ -6,9 +6,9 @@ #include -#include "Fw/Ds/Array.hpp" +#include "Fw/DataStructures/Array.hpp" -namespace Ds { +namespace DataStructures { TEST(Array, ZeroArgConstructor) { Array a; @@ -99,4 +99,4 @@ TEST(Array, AsExternalArray) { ASSERT_EQ(ea[0], 1); } -} // namespace Ds +} // namespace DataStructures diff --git a/Fw/Ds/test/ut/DsTestMain.cpp b/Fw/DataStructures/test/ut/DataStructuresTestMain.cpp similarity index 81% rename from Fw/Ds/test/ut/DsTestMain.cpp rename to Fw/DataStructures/test/ut/DataStructuresTestMain.cpp index f44dc73f441..17b1785f3f8 100644 --- a/Fw/Ds/test/ut/DsTestMain.cpp +++ b/Fw/DataStructures/test/ut/DataStructuresTestMain.cpp @@ -1,7 +1,7 @@ // ====================================================================== -// \title DsTestMain.cpp +// \title DataStructuresTestMain.cpp // \author bocchino -// \brief cpp file for Ds tests +// \brief cpp file for DataStructures tests // ====================================================================== #include diff --git a/Fw/Ds/test/ut/ExternalArrayTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayTest.cpp similarity index 96% rename from Fw/Ds/test/ut/ExternalArrayTest.cpp rename to Fw/DataStructures/test/ut/ExternalArrayTest.cpp index 6eacef7d1dc..8e9201f8580 100644 --- a/Fw/Ds/test/ut/ExternalArrayTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayTest.cpp @@ -6,9 +6,9 @@ #include -#include "Fw/Ds/ExternalArray.hpp" +#include "Fw/DataStructures/ExternalArray.hpp" -namespace Ds { +namespace DataStructures { TEST(ExternalArray, ZeroArgConstructor) { ExternalArray a; @@ -93,4 +93,4 @@ TEST(ExternalArray, SetStorage) { ASSERT_EQ(a2.getSize(), a1.getSize()); } -} // namespace Ds +} // namespace DataStructures From 83ad59bd1eae88993745a5d90d787baa32d4ca72 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 29 May 2025 16:08:51 -0700 Subject: [PATCH 059/458] Revise Sdd for Fw/DataStructures --- Fw/DataStructures/docs/sdd.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/sdd.md b/Fw/DataStructures/docs/sdd.md index 92723219353..de44ee7ce6d 100644 --- a/Fw/DataStructures/docs/sdd.md +++ b/Fw/DataStructures/docs/sdd.md @@ -1,4 +1,4 @@ -# Fw::Ds: Basic Data Structures +# Fw::DataStructures: Basic Data Structures This directory contains a library of basic data structures. From 9f411e42c1a334f43e6d60b6f0914b4324cfd1c4 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 29 May 2025 18:01:11 -0700 Subject: [PATCH 060/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/sdd.md | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/Fw/DataStructures/docs/sdd.md b/Fw/DataStructures/docs/sdd.md index de44ee7ce6d..92bfd4b609e 100644 --- a/Fw/DataStructures/docs/sdd.md +++ b/Fw/DataStructures/docs/sdd.md @@ -824,20 +824,30 @@ ExternalFifoQueue asExternalFifoQueue() TODO -## 4. Linked Lists +## 4. Maps + +### 4.1. Map + +TODO + +### 4.2. Array Map + +TODO + +### 4.3. AVL Tree Map TODO -## 5. Sets and Maps +## 5. Sets -### 5.1. Array Set and Map +### 5.1. Set TODO -### 5.2. Hash Set and Map +### 5.2. Array Set TODO -### 5.3. Balanced Binary Tree Set and Map +### 5.3. AVL Tree Set TODO From 1bdc08b5ae3e4b6dc5eb91924e2c947f4907a0f6 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 29 May 2025 18:03:34 -0700 Subject: [PATCH 061/458] Update SDD for Fw/DataStructures --- Fw/DataStructures/docs/sdd.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Fw/DataStructures/docs/sdd.md b/Fw/DataStructures/docs/sdd.md index 92bfd4b609e..f22f26c778f 100644 --- a/Fw/DataStructures/docs/sdd.md +++ b/Fw/DataStructures/docs/sdd.md @@ -711,8 +711,8 @@ for storing the items on the queue. |Name|Type|Purpose|Default Value| |----|----|-------|-------------| -|`m_eQueue`|`ExternalFifoQueue`|The external queue implementation|C++ default initialization| -|`m_array`|`Array`|The array providing the backing memory for `m_eQueue`|C++ default initialization| +|`m_extQueue`|`ExternalFifoQueue`|The external queue implementation|C++ default initialization| +|`m_array`|`Array`|The array providing the backing memory for `m_extQueue`|C++ default initialization| #### 3.2.3. Public Constructors and Destructors @@ -735,7 +735,7 @@ FifoQueue queue; FifoQueue(const FifoQueue& queue) ``` -Call `m_eQueue.copyItemsFrom(queue.m_eQueue)`. +Call `m_extQueue.copyItemsFrom(queue.m_extQueue)`. _Example:_ ```c++ From d216842cfd5f5b040f6f6d91abb0cf75f1b6bc5f Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 08:29:40 -0700 Subject: [PATCH 062/458] Revise data structures --- Fw/DataStructures/Array.hpp | 8 +++--- Fw/DataStructures/ExternalArray.hpp | 8 +++--- Fw/DataStructures/docs/sdd.md | 27 +++++++++++++++++-- Fw/DataStructures/test/ut/ArrayTest.cpp | 4 +-- .../test/ut/ExternalArrayTest.cpp | 4 +-- 5 files changed, 37 insertions(+), 14 deletions(-) diff --git a/Fw/DataStructures/Array.hpp b/Fw/DataStructures/Array.hpp index 634381949de..90e74424a4c 100644 --- a/Fw/DataStructures/Array.hpp +++ b/Fw/DataStructures/Array.hpp @@ -4,8 +4,8 @@ // \brief A statically-sized, bounds checked array // ====================================================================== -#ifndef DataStructures_Array_HPP -#define DataStructures_Array_HPP +#ifndef Fw_Array_HPP +#define Fw_Array_HPP #include #include @@ -13,7 +13,7 @@ #include "Fw/DataStructures/ExternalArray.hpp" #include "Fw/Types/Assert.hpp" -namespace DataStructures { +namespace Fw { template class Array final { @@ -128,6 +128,6 @@ class Array final { Elements m_elements = {}; }; -} // namespace DataStructures +} // namespace Fw #endif diff --git a/Fw/DataStructures/ExternalArray.hpp b/Fw/DataStructures/ExternalArray.hpp index b32ec937987..2fa90e0e26f 100644 --- a/Fw/DataStructures/ExternalArray.hpp +++ b/Fw/DataStructures/ExternalArray.hpp @@ -4,14 +4,14 @@ // @brief A bounds-checked array with external memory // ====================================================================== -#ifndef DataStructures_ExternalArray_HPP -#define DataStructures_ExternalArray_HPP +#ifndef Fw_ExternalArray_HPP +#define Fw_ExternalArray_HPP #include #include "Fw/Types/Assert.hpp" -namespace DataStructures { +namespace Fw { template class ExternalArray final { @@ -108,6 +108,6 @@ class ExternalArray final { FwSizeType m_size = 0; }; -} // namespace DataStructures +} // namespace Fw #endif diff --git a/Fw/DataStructures/docs/sdd.md b/Fw/DataStructures/docs/sdd.md index f22f26c778f..5d671599b22 100644 --- a/Fw/DataStructures/docs/sdd.md +++ b/Fw/DataStructures/docs/sdd.md @@ -1,6 +1,20 @@ -# Fw::DataStructures: Basic Data Structures +# Fw/DataStructures: Basic Data Structures This directory contains a library of basic data structures. +All the definitions in `Fw/DataStructures` are in the +namespace `Fw`. + +The data structures defined in `Fw/DataStructures` use the following concepts: + +* **size:** The number of elements currently stored in a data structure. + +* **capacity:** The maximum number of elements stored in a data structure. + +For a fixed-size array, the size and the capacity are the same. +For other data structures, the size and the capacity are not +in general the same. +For example, at all times a map has a fixed capacity _C_ and a size between 0 +and _C_. ## 1. Arrays @@ -11,7 +25,7 @@ An array provides bounds-checked access to the array elements stored in _M_. -### 1.1. External Array +### 1.1. ExternalArray `ExternalArray` is a `final` class template representing an array with external storage. @@ -623,6 +637,15 @@ Defined as `= default`. #### 3.1.4. Public Member Functions +**operator[]:** + +```c++ +T& operator[](FwSizeType i) +const T& operator[](FwSizeType i) const +``` + +TODO + **clear:** ```c++ diff --git a/Fw/DataStructures/test/ut/ArrayTest.cpp b/Fw/DataStructures/test/ut/ArrayTest.cpp index e5bd1d4f98d..8db4a26e765 100644 --- a/Fw/DataStructures/test/ut/ArrayTest.cpp +++ b/Fw/DataStructures/test/ut/ArrayTest.cpp @@ -8,7 +8,7 @@ #include "Fw/DataStructures/Array.hpp" -namespace DataStructures { +namespace Fw { TEST(Array, ZeroArgConstructor) { Array a; @@ -99,4 +99,4 @@ TEST(Array, AsExternalArray) { ASSERT_EQ(ea[0], 1); } -} // namespace DataStructures +} // namespace Fw diff --git a/Fw/DataStructures/test/ut/ExternalArrayTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayTest.cpp index 8e9201f8580..93d76644e23 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayTest.cpp @@ -8,7 +8,7 @@ #include "Fw/DataStructures/ExternalArray.hpp" -namespace DataStructures { +namespace Fw { TEST(ExternalArray, ZeroArgConstructor) { ExternalArray a; @@ -93,4 +93,4 @@ TEST(ExternalArray, SetStorage) { ASSERT_EQ(a2.getSize(), a1.getSize()); } -} // namespace DataStructures +} // namespace Fw From bf73324b56d8112efbba794ef7438f9e592959a6 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 09:25:47 -0700 Subject: [PATCH 063/458] Revise sdd for Fw/DataStructures --- Fw/DataStructures/docs/Array.md | 202 +++++++++++ Fw/DataStructures/docs/ExternalArray.md | 212 ++++++++++++ Fw/DataStructures/docs/sdd.md | 423 +----------------------- 3 files changed, 420 insertions(+), 417 deletions(-) create mode 100644 Fw/DataStructures/docs/Array.md create mode 100644 Fw/DataStructures/docs/ExternalArray.md diff --git a/Fw/DataStructures/docs/Array.md b/Fw/DataStructures/docs/Array.md new file mode 100644 index 00000000000..63aa0d7f443 --- /dev/null +++ b/Fw/DataStructures/docs/Array.md @@ -0,0 +1,202 @@ +# 1.2. Array + +`Array` is a `final` class template representing an array +with internal storage. +It maintains the backing memory _M_ as a member variable. + +## 1. Template Parameters + +`Array` has the following template parameters. + +|Kind|Name|Purpose| +|----|----|-------| +|`typename`|`T`|The type of an array element| +|`FwSizeType`|`S`|The array size in elements| + +`Array` statically asserts that `S > 0`. + +## 2. Types + +`Array` defines the type `Elements`. +It is an alias of `T[S]`. + +## 3. Private Member Variables + +`Array` has the following private member variables. + +|Name|Type|Purpose|Default Value| +|----|----|-------|-------------| +|`m_elements`|`Elements`|The array elements|C++ default initialization| + +## 4. Public Constructors and Destructors + +**Zero-argument constructor:** + +```c++ +Array() +``` + +Initialize each element of `m_elements` with the default value for `T`. + +_Example:_ +```c++ +Array a; +``` + +**Initializer list constructor:** + +```c++ +Array(const std::initializer_list& il) +``` + +1. Assert that `il.m_size == S`. + +1. Initialize `m_elements` from `il`. + +_Examples:_ +```c++ +// Explicit call to constructor +Array a({ 1, 2, 3 }); +// Implicit call to constructor via initialization +Array b = { 1, 2, 3 }; +``` + +**Single-element constructor:** + +```c++ +explicit Array(const T& element) +``` + +Initialize each element of `m_elements` with `element`. + +_Example:_ +```c++ +// Explicit call to constructor in variable declaration +Array a(1); +// Explicit call to constructor in assignment +a = Array(2); +``` + +**Copy constructor:** + +```c++ +Array(const Array& a) +``` + +Initialize the elements of `m_elements` with the +elements of `a.m_elements`. + +_Example:_ +```c++ +// Call the single-item constructor +Array a1(3); +// Call the copy constructor +Array a2(a1); +``` + +**Destructor:** + +```c++ +~Array() +``` + +Defined as `= default`. + +## 5. Public Member Functions + +**operator[]:** + +```c++ +T& operator[](FwSizeType i) +const T& operator[](FwSizeType i) const +``` + +1. Assert that `i < S`. + +1. Return `m_elements[i]`. + +_Example:_ +```c++ +constexpr FwSizeType size = 3; +Array a; +// Constant access +ASSERT_EQ(a[0], 0); +// Mutable access +a[0]++; +ASSERT_EQ(a[0], 1); +// Out-of-bounds access +ASSERT_DEATH(a[size], "Assert"); +``` + +**Copy assignment operator:** + +```c++ +Array& operator=(const Array& a) +``` + +1. If `&a == this` then do nothing. + +1. Otherwise overwrite each element of `m_elements` with the corresponding +element of `a`. + +_Example:_ +```c++ +Array a1(1); +Array a2(2); +a1 = a2; +``` + +**getElements:** + +```c++ +Elements& getElements() +const Elements& getElements() const +``` + +Return `m_elements`. + +_Example:_ +```c++ +constexpr FwSizeType size = 3; +Array a; +// Mutable reference +auto& elements1 = a.getElements(); +ASSERT_EQ(elements1[0], 0); +elements1[0] = 1; +// Constant reference +const auto& elements2 = a.getElements(); +ASSERT_EQ(elements2[0], 1); +``` + +**asExternalArray:** + +```c++ +ExternalArray asExternalArray() +``` + +Return `ExternalArray(m_elements, S)`. + +_Example:_ +```c++ +constexpr FwSizeType size = 3; +Array a = { 1, 2, 3 }; +ExternalArray ea = a.asExternalArray(); +ASSERT_EQ(ea[0], 1); +``` + +## 6. Public Static Functions + +**getSize:** + +```c++ +static constexpr FwSizeType getSize() +``` + +Return the size `S` of the array. + +_Example:_ +```c++ +const auto size = Array::getSize(); +ASSERT_EQ(size, 3); +``` + diff --git a/Fw/DataStructures/docs/ExternalArray.md b/Fw/DataStructures/docs/ExternalArray.md new file mode 100644 index 00000000000..63dcaf523d7 --- /dev/null +++ b/Fw/DataStructures/docs/ExternalArray.md @@ -0,0 +1,212 @@ +# ExternalArray + +`ExternalArray` is a `final` class template representing an array with external +storage. +It stores a pointer to the backing memory _M_. + +## 1. Template Parameters + +`ExternalArray` has the following template parameters. + +|Kind|Name|Purpose| +|----|----|-------| +|`typename`|`T`|The type of an array element| + +## 2. Private Member Variables + +`ExternalArray` has the following private member variables. + +|Name|Type|Purpose|Default Value| +|----|----|-------|-------------| +|`m_elements`|`T*`|Points to the backing memory|`nullptr`| +|`m_size`|`FwSizeType`|Stores the size (number of elements) of the array|0| + +## 3. Public Constructors and Destructors + +**Zero-argument constructor:** + +```c++ +ExternalArray() +``` + +Initialize the member variables with their default values. + +_Example:_ +```c++ +ExternalArray a; +``` + +**Constructor providing backing storage:** + +```c++ +ExternalArray(T* elements, FwSizeType size) +``` + +Initialize `m_elements` with `elements` and `m_size` with `size`. + +_Example:_ +```c++ +constexpr FwSizeType size = 3; +U32 elements[size]; +ExternalArray a(elements, size); +``` + +**Copy constructor:** + +```c++ +ExternalArray(const ExternalArray& a) +``` + +Set `m_elements = a.m_elements` and `m_size = a.m_size`. + +_Example:_ +```c++ +constexpr FwSizeType size = 3; +U32 elements[size]; +// Call the constructor providing backing storage +ExternalArray a1(elements, size); +// Call the copy constructor +ExternalArray a2(a1); +``` + +**Destructor:** + +```c++ +~ExternalArray() +``` + +Defined as `= default`. + +## 4. Public Member Functions + +**operator[]:** + +```c++ +T& operator[](FwSizeType i) +const T& operator[](FwSizeType i) const +``` + +1. Assert that `m_elements != nullptr`. + +1. Assert that `i < m_size`. + +1. Return `m_elements[i]`. + +_Example:_ +```c++ +constexpr FwSizeType size = 3; +U32 elements[size] = {}; +ExternalArray a(elements, size); +// Constant access +ASSERT_EQ(a[0], 0); +// Mutable access +a[0]++; +ASSERT_EQ(a[0], 1); +// Out-of-bounds access +ASSERT_DEATH(a[size], "Assert"); +``` + +**Copy assignment operator:** + +```c++ +ExternalArray& operator=(const ExternalArray& a) +``` + +1. If `&a == this` then do nothing. + +1. Otherwise set `m_elements = a.m_elements` and `m_size = a.m_size`. + +_Example:_ +```c++ +constexpr FwSizeType size = 3; +U32 elements[size]; +ExternalArray a1(elements, size); +ExternalArray a2; +a2 = a1; +``` + +**copyElementsFrom:** + +```c++ +void copyElementsFrom(const ExternalArray& a) +``` + +1. If `&a == this` then do nothing. + +1. Otherwise + + 1. Let `size` be the minimum of `this->m_size` and `a.m_size` + + 1. For each `i` from 0 through `size - 1`, set `m_elements[i] = a.m_elements[i]` + +_Example:_ +```c++ +constexpr FwSizeType size = 10; +U32 elements1[size]; +ExternalArray a1(elements, size); +for (FwSizeType i = 0; i < size; i++) { + a1[i] = i; +} +U32 elements2[size]; +ExternalArray a2(elements, size); +a2.copyElementsFrom(a1); +for (FwSizeType i = 0; i < size; i++) { + ASSERT_EQ(a2[i], a1[i]); +} +``` + +**getElements:** + +```c++ +T* getElements() +const T* getElements() const +``` + +Return `m_elements`. + +_Example:_ +```c++ +constexpr FwSizeType size = 3; +U32 elements[size]; +ExternalArray a(elements, size); +// Mutable pointer +auto& elements1 = a.getElements(); +ASSERT_EQ(elements1[0], 0); +elements1[0] = 1; +// Constant pointer +const auto& elements2 = a.getElements(); +ASSERT_EQ(elements2[0], 1); +``` + +**getSize:** + +```c++ +FwSizeType getSize() +``` + +Return `m_size`. + +_Example:_ +```c++ +constexpr FwSizeType size = 3; +U32 elements[size]; +ExternalArray a(elements, size); +const auto size1 = a.getSize(); +ASSERT_EQ(size1, size); +``` + +**setStorage:** + +```c++ +void setStorage(T* elements, FwSizeType size) +``` + +Set `m_elements = elements` and `m_size = size`. + +_Example:_ +```c++ +constexpr FwSizeType size = 3; +ExternalArray a; +U32 elements[size]; +a.setStorage(elements, size); +``` diff --git a/Fw/DataStructures/docs/sdd.md b/Fw/DataStructures/docs/sdd.md index 5d671599b22..84d486cb316 100644 --- a/Fw/DataStructures/docs/sdd.md +++ b/Fw/DataStructures/docs/sdd.md @@ -1,10 +1,10 @@ # Fw/DataStructures: Basic Data Structures -This directory contains a library of basic data structures. -All the definitions in `Fw/DataStructures` are in the +`Fw/DataStructures` contains a library of basic data structures. +All the definitions in this directory are in the namespace `Fw`. -The data structures defined in `Fw/DataStructures` use the following concepts: +The data structures defined here use the following concepts: * **size:** The number of elements currently stored in a data structure. @@ -24,422 +24,11 @@ The elements are stored in **backing memory** _M_. An array provides bounds-checked access to the array elements stored in _M_. - -### 1.1. ExternalArray +`Fw/DataStructures` provides the following array templates: -`ExternalArray` is a `final` class template representing an array with external -storage. -It stores a pointer to the backing memory _M_. +1. [`ExternalArray`](ExternalArray.md) -#### 1.1.1. Template Parameters - -`ExternalArray` has the following template parameters. - -|Kind|Name|Purpose| -|----|----|-------| -|`typename`|`T`|The type of an array element| - -#### 1.1.2. Private Member Variables - -`ExternalArray` has the following private member variables. - -|Name|Type|Purpose|Default Value| -|----|----|-------|-------------| -|`m_elements`|`T*`|Points to the backing memory|`nullptr`| -|`m_size`|`FwSizeType`|Stores the size (number of elements) of the array|0| - -#### 1.1.3. Public Constructors and Destructors - -**Zero-argument constructor:** - -```c++ -ExternalArray() -``` - -Initialize the member variables with their default values. - -_Example:_ -```c++ -ExternalArray a; -``` - -**Constructor providing backing storage:** - -```c++ -ExternalArray(T* elements, FwSizeType size) -``` - -Initialize `m_elements` with `elements` and `m_size` with `size`. - -_Example:_ -```c++ -constexpr FwSizeType size = 3; -U32 elements[size]; -ExternalArray a(elements, size); -``` - -**Copy constructor:** - -```c++ -ExternalArray(const ExternalArray& a) -``` - -Set `m_elements = a.m_elements` and `m_size = a.m_size`. - -_Example:_ -```c++ -constexpr FwSizeType size = 3; -U32 elements[size]; -// Call the constructor providing backing storage -ExternalArray a1(elements, size); -// Call the copy constructor -ExternalArray a2(a1); -``` - -**Destructor:** - -```c++ -~ExternalArray() -``` - -Defined as `= default`. - -#### 1.1.4. Public Member Functions - -**operator[]:** - -```c++ -T& operator[](FwSizeType i) -const T& operator[](FwSizeType i) const -``` - -1. Assert that `m_elements != nullptr`. - -1. Assert that `i < m_size`. - -1. Return `m_elements[i]`. - -_Example:_ -```c++ -constexpr FwSizeType size = 3; -U32 elements[size] = {}; -ExternalArray a(elements, size); -// Constant access -ASSERT_EQ(a[0], 0); -// Mutable access -a[0]++; -ASSERT_EQ(a[0], 1); -// Out-of-bounds access -ASSERT_DEATH(a[size], "Assert"); -``` - -**Copy assignment operator:** - -```c++ -ExternalArray& operator=(const ExternalArray& a) -``` - -1. If `&a == this` then do nothing. - -1. Otherwise set `m_elements = a.m_elements` and `m_size = a.m_size`. - -_Example:_ -```c++ -constexpr FwSizeType size = 3; -U32 elements[size]; -ExternalArray a1(elements, size); -ExternalArray a2; -a2 = a1; -``` - -**copyElementsFrom:** - -```c++ -void copyElementsFrom(const ExternalArray& a) -``` - -1. If `&a == this` then do nothing. - -1. Otherwise - - 1. Let `size` be the minimum of `this->m_size` and `a.m_size` - - 1. For each `i` from 0 through `size - 1`, set `m_elements[i] = a.m_elements[i]` - -_Example:_ -```c++ -constexpr FwSizeType size = 10; -U32 elements1[size]; -ExternalArray a1(elements, size); -for (FwSizeType i = 0; i < size; i++) { - a1[i] = i; -} -U32 elements2[size]; -ExternalArray a2(elements, size); -a2.copyElementsFrom(a1); -for (FwSizeType i = 0; i < size; i++) { - ASSERT_EQ(a2[i], a1[i]); -} -``` - -**getElements:** - -```c++ -T* getElements() -const T* getElements() const -``` - -Return `m_elements`. - -_Example:_ -```c++ -constexpr FwSizeType size = 3; -U32 elements[size]; -ExternalArray a(elements, size); -// Mutable pointer -auto& elements1 = a.getElements(); -ASSERT_EQ(elements1[0], 0); -elements1[0] = 1; -// Constant pointer -const auto& elements2 = a.getElements(); -ASSERT_EQ(elements2[0], 1); -``` - -**getSize:** - -```c++ -FwSizeType getSize() -``` - -Return `m_size`. - -_Example:_ -```c++ -constexpr FwSizeType size = 3; -U32 elements[size]; -ExternalArray a(elements, size); -const auto size1 = a.getSize(); -ASSERT_EQ(size1, size); -``` - -**setStorage:** - -```c++ -void setStorage(T* elements, FwSizeType size) -``` - -Set `m_elements = elements` and `m_size = size`. - -_Example:_ -```c++ -constexpr FwSizeType size = 3; -ExternalArray a; -U32 elements[size]; -a.setStorage(elements, size); -``` - - -### 1.2. Array - -`Array` is a `final` class template representing an array -with internal storage. -It maintains the backing memory _M_ as a member variable. - -#### 1.2.1. Template Parameters - -`Array` has the following template parameters. - -|Kind|Name|Purpose| -|----|----|-------| -|`typename`|`T`|The type of an array element| -|`FwSizeType`|`S`|The array size in elements| - -`Array` statically asserts that `S > 0`. - -#### 1.2.2. Types - -`Array` defines the type `Elements`. -It is an alias of `T[S]`. - -#### 1.2.3. Private Member Variables - -`Array` has the following private member variables. - -|Name|Type|Purpose|Default Value| -|----|----|-------|-------------| -|`m_elements`|`Elements`|The array elements|C++ default initialization| - -#### 1.2.4. Public Constructors and Destructors - -**Zero-argument constructor:** - -```c++ -Array() -``` - -Initialize each element of `m_elements` with the default value for `T`. - -_Example:_ -```c++ -Array a; -``` - -**Initializer list constructor:** - -```c++ -Array(const std::initializer_list& il) -``` - -1. Assert that `il.m_size == S`. - -1. Initialize `m_elements` from `il`. - -_Examples:_ -```c++ -// Explicit call to constructor -Array a({ 1, 2, 3 }); -// Implicit call to constructor via initialization -Array b = { 1, 2, 3 }; -``` - -**Single-element constructor:** - -```c++ -explicit Array(const T& element) -``` - -Initialize each element of `m_elements` with `element`. - -_Example:_ -```c++ -// Explicit call to constructor in variable declaration -Array a(1); -// Explicit call to constructor in assignment -a = Array(2); -``` - -**Copy constructor:** - -```c++ -Array(const Array& a) -``` - -Initialize the elements of `m_elements` with the -elements of `a.m_elements`. - -_Example:_ -```c++ -// Call the single-item constructor -Array a1(3); -// Call the copy constructor -Array a2(a1); -``` - -**Destructor:** - -```c++ -~Array() -``` - -Defined as `= default`. - -#### 1.2.5. Public Member Functions - -**operator[]:** - -```c++ -T& operator[](FwSizeType i) -const T& operator[](FwSizeType i) const -``` - -1. Assert that `i < S`. - -1. Return `m_elements[i]`. - -_Example:_ -```c++ -constexpr FwSizeType size = 3; -Array a; -// Constant access -ASSERT_EQ(a[0], 0); -// Mutable access -a[0]++; -ASSERT_EQ(a[0], 1); -// Out-of-bounds access -ASSERT_DEATH(a[size], "Assert"); -``` - -**Copy assignment operator:** - -```c++ -Array& operator=(const Array& a) -``` - -1. If `&a == this` then do nothing. - -1. Otherwise overwrite each element of `m_elements` with the corresponding -element of `a`. - -_Example:_ -```c++ -Array a1(1); -Array a2(2); -a1 = a2; -``` - -**getElements:** - -```c++ -Elements& getElements() -const Elements& getElements() const -``` - -Return `m_elements`. - -_Example:_ -```c++ -constexpr FwSizeType size = 3; -Array a; -// Mutable reference -auto& elements1 = a.getElements(); -ASSERT_EQ(elements1[0], 0); -elements1[0] = 1; -// Constant reference -const auto& elements2 = a.getElements(); -ASSERT_EQ(elements2[0], 1); -``` - -**asExternalArray:** - -```c++ -ExternalArray asExternalArray() -``` - -Return `ExternalArray(m_elements, S)`. - -_Example:_ -```c++ -constexpr FwSizeType size = 3; -Array a = { 1, 2, 3 }; -ExternalArray ea = a.asExternalArray(); -ASSERT_EQ(ea[0], 1); -``` - -#### 1.2.6. Public Static Functions - -**getSize:** - -```c++ -static constexpr FwSizeType getSize() -``` - -Return the size `S` of the array. - -_Example:_ -```c++ -const auto size = Array::getSize(); -ASSERT_EQ(size, 3); -``` +1. [`Array`](Array.md) ## 2. CircularIndex From b4d8fefbd262092310a77a1ee55af13cf3b43186 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 09:27:08 -0700 Subject: [PATCH 064/458] Revise ExternalArray --- Fw/DataStructures/docs/ExternalArray.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArray.md b/Fw/DataStructures/docs/ExternalArray.md index 63dcaf523d7..95048798f73 100644 --- a/Fw/DataStructures/docs/ExternalArray.md +++ b/Fw/DataStructures/docs/ExternalArray.md @@ -1,7 +1,7 @@ # ExternalArray -`ExternalArray` is a `final` class template representing an array with external -storage. +`ExternalArray` is a `final` class template representing an +(array)[sdd.md#1-arrays] with external storage. It stores a pointer to the backing memory _M_. ## 1. Template Parameters From b2df29bf48dd496c0f7b02a98667f1769d59f7eb Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 09:27:48 -0700 Subject: [PATCH 065/458] Revise ExternalArray --- Fw/DataStructures/docs/ExternalArray.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/ExternalArray.md b/Fw/DataStructures/docs/ExternalArray.md index 95048798f73..f84e19e813e 100644 --- a/Fw/DataStructures/docs/ExternalArray.md +++ b/Fw/DataStructures/docs/ExternalArray.md @@ -1,7 +1,7 @@ # ExternalArray `ExternalArray` is a `final` class template representing an -(array)[sdd.md#1-arrays] with external storage. +[array](sdd.md#1-arrays) with external storage. It stores a pointer to the backing memory _M_. ## 1. Template Parameters From 1aa219f0adb2f91e9df3da23f2f3c2f8f3bbda4b Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 11:14:34 -0700 Subject: [PATCH 066/458] Revise sdd for Fw/DataStructures --- Fw/DataStructures/docs/CircularIndex.md | 100 +++++ Fw/DataStructures/docs/ExternalFifoQueue.md | 163 ++++++++ Fw/DataStructures/docs/FifoQueue.md | 137 +++++++ Fw/DataStructures/docs/sdd.md | 418 +------------------- 4 files changed, 412 insertions(+), 406 deletions(-) create mode 100644 Fw/DataStructures/docs/CircularIndex.md create mode 100644 Fw/DataStructures/docs/ExternalFifoQueue.md create mode 100644 Fw/DataStructures/docs/FifoQueue.md diff --git a/Fw/DataStructures/docs/CircularIndex.md b/Fw/DataStructures/docs/CircularIndex.md new file mode 100644 index 00000000000..0e22ea8be28 --- /dev/null +++ b/Fw/DataStructures/docs/CircularIndex.md @@ -0,0 +1,100 @@ +# 1. CircularIndex + +`CircularIndex` represents an index value that +wraps around modulo an integer. + +## 1. Private Member Variables + +`CircularIndex` has the following private member variables. + +|Name|Type|Purpose|Default Value| +|----|----|-------|-------------| +|`m_value`|`FwSizeType`|The index value|0| +|`m_modulus`|`FwSizeType`|The modulus|1| + +## 2. Public Constructors and Destructors + +**Zero-argument constructor:** + +```c++ +CircularIndex() +``` + +Initialize the member variables with their default values. + +**Constructor with specified members:** + +```c++ +CircularIndex(FwSizeType modulus, FwSizeType value = 0) +``` + +1. Assert `modulus > 0`. + +1. Set `m_modulus = modulus`. + +1. Call `setValue(value)`. + +## 3. Public Member Functions + +**getValue:** + +```c++ +FwSizeType getValue() const +``` + +1. Assert `m_value < m_modulus`. + +1. Return `m_value`. + +**setValue:** + +```c++ +void setValue(FwSizeType value) +``` + +Set `m_value = m_value % m_modulus`. + +**getModulus:** + +```c++ +FwSizeType CircularIndex::getModulus() const +``` + +1. Assert `m_value < m_modulus`. + +1. Return `m_modulus`. + +**setModulus:** + +```c++ +void setModulus(FwSizeType modulus) +``` + +1. Set `m_modulus = modulus`. + +2. Call `setValue(m_value)`. + +**increment:** + +```c++ +FwSizeType increment(FwSizeType amount = 1) +``` + +1. Set `offset = amount % m_modulus`. + +1. Call `setValue(m_value + offset)`. + +1. Return `m_value`. + +**decrement:** + +```c++ +FwSizeType decrement(FwSizeType amount = 1) +``` + +1. Set `offset = amount % m_modulus`. + +1. Call `setValue(m_value + m_modulus - offset)`. + +1. Return `m_value`. + diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md new file mode 100644 index 00000000000..7ca68afcc84 --- /dev/null +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -0,0 +1,163 @@ +# ExternalFifoQueue + +`ExternalFifoQueue` is a `final` class template representing a +FIFO queue with external storage. +Internally it maintains an [`ExternalArray`](ExternalArray.md) for +storing the items on the queue. + +## 1. Template Parameters + +`ExternalFifoQueue` has the following template parameters. + +|Kind|Name|Purpose| +|----|----|-------| +|`typename`|`T`|The type of an item on the queue| + +## 2. Private Member Variables + +`ExternalFifoQueue` has the following private member variables. + +|Name|Type|Purpose|Default Value| +|----|----|-------|-------------| +|`m_items`|`ExternalArray`|The array for storing the queue items|C++ default initialization| +|`m_enqueueIndex`|`CircularIndex`|The enqueue index|0| +|`m_dequeueIndex`|`CircularIndex`|The dequeue index|0| +|`m_size`|`FwSizeType`|The number of items on the queue|0| + +## 3. Public Constructors and Destructors + +**Zero-argument constructor:** + +```c++ +ExternalFifoQueue() +``` + +`ExternalFifoQueue` is a `final` class template representing a FIFO queue with +internal storage. +It maintains an `Array` for storing the items on the queue. + +**Constructor providing backing storage:** + +```c++ +ExternalFifoQueue(T* items, FwSizeType size) +``` + +Initialize `m_items` with `items` and `size`. + +_Example:_ +```c++ +constexpr FwSizeType size = 10; +U32 items[size]; +ExternalFifoQueue queue(items, size); +``` + +**Copy constructor:** + +```c++ +ExternalFifoQueue(const ExternalFifoQueue& queue) +``` + +1. Set `m_items = queue.m_items`. + +1. Set `m_enqueueIndex = queue.m_enqueueIndex`. + +1. Set `m_dequeueIndex = queue.m_dequeueIndex`. + +1. Set `m_size = queue.size`. + +_Example:_ +```c++ +constexpr FwSizeType size = 3; +U32 items[size]; +// Call the constructor providing backing storage +ExternalFifoQueue q1(elements, 10); +// Enqueue an element +U32 value = 42; +(void) q1.enqueue(value); +// Call the copy constructor +ExternalFifoQueue a2(a1); +``` + +**Destructor:** + +```c++ +ExternalFifoQueue() +``` + +Defined as `= default`. + +## 4. Public Member Functions + +**operator[]:** + +```c++ +T& operator[](FwSizeType i) +const T& operator[](FwSizeType i) const +``` + +TODO + +**clear:** + +```c++ +void clear() +``` + +TODO + +**setStorage:** + +```c++ +void setStorage(T* items, FwSizeType size) +``` + +TODO + +**copyItemsFrom:** + +```c++ +void copyItemsFrom(const ExternalFifoQueue& queue) +``` + +TODO + +**enqueue:** + +```c++ +Fw::Success enqueue(const T& e) +``` + +TODO + +**peek:** + +```c++ +Fw::Success peek(T& e) +``` + +TODO + +**dequeue:** + +```c++ +Fw::Success dequeue(T& e) +``` + +TODO + +**getSize:** + +```c++ +FwSizeType getSize() const +``` + +TODO + +**getCapacity:** + +```c++ +FwSizeType getCapacity() const +``` + +TODO + diff --git a/Fw/DataStructures/docs/FifoQueue.md b/Fw/DataStructures/docs/FifoQueue.md new file mode 100644 index 00000000000..f3ac6298111 --- /dev/null +++ b/Fw/DataStructures/docs/FifoQueue.md @@ -0,0 +1,137 @@ +# FifoQueue + +`FifoQueue` is a `final` class template representing a +FIFO queue with internal storage. +Internally it maintains an `Array` +for storing the items on the queue. + +## 1. Template Parameters + +`FifoQueue` has the following template parameters. + +|Kind|Name|Purpose| +|----|----|-------| +|`typename`|`T`|The type of a queue item| +|`FwSizeType`|`C`|The queue capacity in items| + +`FifoQueue` statically asserts that `C > 0`. + +## 2. Private Member Variables + +`FifoQueue` has the following private member variables. + +|Name|Type|Purpose|Default Value| +|----|----|-------|-------------| +|`m_extQueue`|`ExternalFifoQueue`|The external queue implementation|C++ default initialization| +|`m_array`|`Array`|The array providing the backing memory for `m_extQueue`|C++ default initialization| + +## 3. Public Constructors and Destructors + +**Zero-argument constructor:** + +```c++ +FifoQueue() +``` + +Initialize each member with default initialization. + +_Example:_ +```c++ +FifoQueue queue; +``` + +**Copy constructor:** + +```c++ +FifoQueue(const FifoQueue& queue) +``` + +Call `m_extQueue.copyItemsFrom(queue.m_extQueue)`. + +_Example:_ +```c++ +FifoQueue q1; +auto status = q1.enqueue(3); +ASSERT_EQ(status, Fw::Success::SUCCESS); +FifoQueue q2; +q2 = q1; +U32 value = 0; +status = q2.dequeue(value); +ASSERT_EQ(status, Fw::Success::SUCCESS); +ASSERT_EQ(value, 3); +``` + +**Destructor:** + +```c++ +~FifoQueue() +``` + +Defined as `= default`. + +## 4. Public Member Functions + +**Copy assignment operator:** + +```c++ +FifoQueue& operator=(const FifoQueue& queue) +``` + +TODO + +**clear:** + +```c++ +void clear() +``` + +TODO + +**enqueue:** + +```c++ +Fw::Success enqueue(const T& e) +``` + +TODO + +**peek:** + +```c++ +Fw::Success peek(T& e) +``` + +TODO + +**dequeue:** + +```c++ +Fw::Success dequeue(T& e) +``` + +TODO + +**getSize:** + +```c++ +FwSizeType getSize() const +``` + +TODO + +**getCapacity:** + +```c++ +FwSizeType getCapacity() const +``` + +TODO + +**asExternalFifoQueue:** + +```c++ +ExternalFifoQueue asExternalFifoQueue() +``` + +TODO + diff --git a/Fw/DataStructures/docs/sdd.md b/Fw/DataStructures/docs/sdd.md index 84d486cb316..70750bebef2 100644 --- a/Fw/DataStructures/docs/sdd.md +++ b/Fw/DataStructures/docs/sdd.md @@ -30,436 +30,42 @@ stored in _M_. 1. [`Array`](Array.md) -## 2. CircularIndex - -`CircularIndex` represents an index value that -wraps around modulo an integer. - -### 2.1. Private Member Variables - -`CircularIndex` has the following private member variables. - -|Name|Type|Purpose|Default Value| -|----|----|-------|-------------| -|`m_value`|`FwSizeType`|The index value|0| -|`m_modulus`|`FwSizeType`|The modulus|1| - -### 2.2. Public Constructors and Destructors - -**Zero-argument constructor:** - -```c++ -CircularIndex() -``` - -Initialize the member variables with their default values. - -**Constructor with specified members:** - -```c++ -CircularIndex(FwSizeType modulus, FwSizeType value = 0) -``` - -1. Assert `modulus > 0`. - -1. Set `m_modulus = modulus`. - -1. Call `setValue(value)`. - -### 2.3. Public Member Functions - -**getValue:** - -```c++ -FwSizeType getValue() const -``` - -1. Assert `m_value < m_modulus`. - -1. Return `m_value`. - -**setValue:** - -```c++ -void setValue(FwSizeType value) -``` - -Set `m_value = m_value % m_modulus`. - -**getModulus:** - -```c++ -FwSizeType CircularIndex::getModulus() const -``` - -1. Assert `m_value < m_modulus`. - -1. Return `m_modulus`. - -**setModulus:** - -```c++ -void setModulus(FwSizeType modulus) -``` - -1. Set `m_modulus = modulus`. - -2. Call `setValue(m_value)`. - -**increment:** - -```c++ -FwSizeType increment(FwSizeType amount = 1) -``` - -1. Set `offset = amount % m_modulus`. - -1. Call `setValue(m_value + offset)`. - -1. Return `m_value`. - -**decrement:** - -```c++ -FwSizeType decrement(FwSizeType amount = 1) -``` - -1. Set `offset = amount % m_modulus`. - -1. Call `setValue(m_value + m_modulus - offset)`. - -1. Return `m_value`. - -## 3. FIFO Queues +## 2. FIFO Queues A **FIFO queue** is a data structure backed by an array. It supports enqueue and dequeue operations in first in first out (FIFO) order. -### 3.1. ExternalFifoQueue - -`ExternalFifoQueue` is a `final` class template representing a -FIFO queue with external storage. -Internally it maintains an `ExternalArray` for -storing the items on the queue. - -#### 3.1.1. Template Parameters - -`ExternalFifoQueue` has the following template parameters. - -|Kind|Name|Purpose| -|----|----|-------| -|`typename`|`T`|The type of an item on the queue| - -#### 3.1.2. Private Member Variables - -`ExternalFifoQueue` has the following private member variables. - -|Name|Type|Purpose|Default Value| -|----|----|-------|-------------| -|`m_items`|`ExternalArray`|The array for storing the queue items|C++ default initialization| -|`m_enqueueIndex`|`CircularIndex`|The enqueue index|0| -|`m_dequeueIndex`|`CircularIndex`|The dequeue index|0| -|`m_size`|`FwSizeType`|The number of items on the queue|0| - -#### 3.1.3. Public Constructors and Destructors - -**Zero-argument constructor:** - -```c++ -ExternalFifoQueue() -``` - -`ExternalFifoQueue` is a `final` class template representing a FIFO queue with -internal storage. -It maintains an `Array` for storing the items on the queue. - -**Constructor providing backing storage:** - -```c++ -ExternalFifoQueue(T* items, FwSizeType size) -``` - -Initialize `m_items` with `items` and `size`. - -_Example:_ -```c++ -constexpr FwSizeType size = 10; -U32 items[size]; -ExternalFifoQueue queue(items, size); -``` - -**Copy constructor:** - -```c++ -ExternalFifoQueue(const ExternalFifoQueue& queue) -``` - -1. Set `m_items = queue.m_items`. - -1. Set `m_enqueueIndex = queue.m_enqueueIndex`. - -1. Set `m_dequeueIndex = queue.m_dequeueIndex`. - -1. Set `m_size = queue.size`. - -_Example:_ -```c++ -constexpr FwSizeType size = 3; -U32 items[size]; -// Call the constructor providing backing storage -ExternalFifoQueue q1(elements, 10); -// Enqueue an element -U32 value = 42; -(void) q1.enqueue(value); -// Call the copy constructor -ExternalFifoQueue a2(a1); -``` - -**Destructor:** - -```c++ -ExternalFifoQueue() -``` - -Defined as `= default`. - -#### 3.1.4. Public Member Functions - -**operator[]:** - -```c++ -T& operator[](FwSizeType i) -const T& operator[](FwSizeType i) const -``` - -TODO - -**clear:** - -```c++ -void clear() -``` - -TODO - -**setStorage:** - -```c++ -void setStorage(T* items, FwSizeType size) -``` - -TODO - -**copyItemsFrom:** - -```c++ -void copyItemsFrom(const ExternalFifoQueue& queue) -``` - -TODO - -**enqueue:** - -```c++ -Fw::Success enqueue(const T& e) -``` - -TODO - -**peek:** - -```c++ -Fw::Success peek(T& e) -``` - -TODO - -**dequeue:** - -```c++ -Fw::Success dequeue(T& e) -``` - -TODO - -**getSize:** - -```c++ -FwSizeType getSize() const -``` - -TODO - -**getCapacity:** - -```c++ -FwSizeType getCapacity() const -``` - -TODO - -### 3.2. FifoQueue - -`FifoQueue` is a `final` class template representing a -FIFO queue with internal storage. -Internally it maintains an `Array` -for storing the items on the queue. - -#### 3.2.1. Template Parameters - -`FifoQueue` has the following template parameters. - -|Kind|Name|Purpose| -|----|----|-------| -|`typename`|`T`|The type of a queue item| -|`FwSizeType`|`C`|The queue capacity in items| - -`FifoQueue` statically asserts that `C > 0`. - -#### 3.2.2. Private Member Variables - -`FifoQueue` has the following private member variables. - -|Name|Type|Purpose|Default Value| -|----|----|-------|-------------| -|`m_extQueue`|`ExternalFifoQueue`|The external queue implementation|C++ default initialization| -|`m_array`|`Array`|The array providing the backing memory for `m_extQueue`|C++ default initialization| - -#### 3.2.3. Public Constructors and Destructors - -**Zero-argument constructor:** - -```c++ -FifoQueue() -``` - -Initialize each member with default initialization. - -_Example:_ -```c++ -FifoQueue queue; -``` +`Fw/DataStructures` provides the following FIFO queue templates: -**Copy constructor:** +1. [`ExternalFifoQueue`](ExternalFifoQueue.md) -```c++ -FifoQueue(const FifoQueue& queue) -``` - -Call `m_extQueue.copyItemsFrom(queue.m_extQueue)`. - -_Example:_ -```c++ -FifoQueue q1; -auto status = q1.enqueue(3); -ASSERT_EQ(status, Fw::Success::SUCCESS); -FifoQueue q2; -q2 = q1; -U32 value = 0; -status = q2.dequeue(value); -ASSERT_EQ(status, Fw::Success::SUCCESS); -ASSERT_EQ(value, 3); -``` - -**Destructor:** - -```c++ -~FifoQueue() -``` - -Defined as `= default`. - -#### 3.2.4. Public Member Functions - -**Copy assignment operator:** - -```c++ -FifoQueue& operator=(const FifoQueue& queue) -``` - -TODO - -**clear:** - -```c++ -void clear() -``` - -TODO - -**enqueue:** - -```c++ -Fw::Success enqueue(const T& e) -``` - -TODO - -**peek:** - -```c++ -Fw::Success peek(T& e) -``` - -TODO - -**dequeue:** - -```c++ -Fw::Success dequeue(T& e) -``` - -TODO - -**getSize:** - -```c++ -FwSizeType getSize() const -``` - -TODO - -**getCapacity:** - -```c++ -FwSizeType getCapacity() const -``` - -TODO - -**asExternalFifoQueue:** - -```c++ -ExternalFifoQueue asExternalFifoQueue() -``` - -TODO +1. [`FifoQueue`](FifoQueue.md) -## 4. Maps +## 3. Maps -### 4.1. Map +### 3.1. Map TODO -### 4.2. Array Map +### 3.2. Array Map TODO -### 4.3. AVL Tree Map +### 3.3. AVL Tree Map TODO -## 5. Sets +## 4. Sets -### 5.1. Set +### 4.1. Set TODO -### 5.2. Array Set +### 4.2. Array Set TODO -### 5.3. AVL Tree Set +### 4.3. AVL Tree Set TODO From 68bfcbe2f3326ddb149bfbd6384ea47123fa1c76 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 11:16:03 -0700 Subject: [PATCH 067/458] Revise sdd for Fw/DataStructures --- Fw/DataStructures/docs/ExternalFifoQueue.md | 4 ++-- Fw/DataStructures/docs/sdd.md | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index 7ca68afcc84..851e7b7354a 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -20,8 +20,8 @@ storing the items on the queue. |Name|Type|Purpose|Default Value| |----|----|-------|-------------| |`m_items`|`ExternalArray`|The array for storing the queue items|C++ default initialization| -|`m_enqueueIndex`|`CircularIndex`|The enqueue index|0| -|`m_dequeueIndex`|`CircularIndex`|The dequeue index|0| +|`m_enqueueIndex`|[`CircularIndex`](CircularIndex.md)|The enqueue index|0| +|`m_dequeueIndex`|[`CircularIndex`](CircularIndex.md)|The dequeue index|0| |`m_size`|`FwSizeType`|The number of items on the queue|0| ## 3. Public Constructors and Destructors diff --git a/Fw/DataStructures/docs/sdd.md b/Fw/DataStructures/docs/sdd.md index 70750bebef2..d86a75875a3 100644 --- a/Fw/DataStructures/docs/sdd.md +++ b/Fw/DataStructures/docs/sdd.md @@ -26,9 +26,9 @@ stored in _M_. `Fw/DataStructures` provides the following array templates: -1. [`ExternalArray`](ExternalArray.md) +* [`ExternalArray`](ExternalArray.md) -1. [`Array`](Array.md) +* [`Array`](Array.md) ## 2. FIFO Queues @@ -38,9 +38,9 @@ first in first out (FIFO) order. `Fw/DataStructures` provides the following FIFO queue templates: -1. [`ExternalFifoQueue`](ExternalFifoQueue.md) +* [`ExternalFifoQueue`](ExternalFifoQueue.md) -1. [`FifoQueue`](FifoQueue.md) +* [`FifoQueue`](FifoQueue.md) ## 3. Maps From afdc5a93c1a99738d0a663e12d56839adff3558a Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 11:17:11 -0700 Subject: [PATCH 068/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalFifoQueue.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index 851e7b7354a..e34f1673772 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -19,7 +19,7 @@ storing the items on the queue. |Name|Type|Purpose|Default Value| |----|----|-------|-------------| -|`m_items`|`ExternalArray`|The array for storing the queue items|C++ default initialization| +|`m_items`|[`ExternalArray`](ExternalArray.md)|The array for storing the queue items|C++ default initialization| |`m_enqueueIndex`|[`CircularIndex`](CircularIndex.md)|The enqueue index|0| |`m_dequeueIndex`|[`CircularIndex`](CircularIndex.md)|The dequeue index|0| |`m_size`|`FwSizeType`|The number of items on the queue|0| From 78b3a6c0384256ce2176f5c9ae8e2c206bb96a3f Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 11:25:14 -0700 Subject: [PATCH 069/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ArrayMap.md | 4 ++++ Fw/DataStructures/docs/ArraySet.md | 4 ++++ Fw/DataStructures/docs/AvlTreeMap.md | 4 ++++ Fw/DataStructures/docs/AvlTreeSet.md | 4 ++++ Fw/DataStructures/docs/Map.md | 4 ++++ Fw/DataStructures/docs/Set.md | 4 ++++ Fw/DataStructures/docs/sdd.md | 24 ++++++------------------ 7 files changed, 30 insertions(+), 18 deletions(-) create mode 100644 Fw/DataStructures/docs/ArrayMap.md create mode 100644 Fw/DataStructures/docs/ArraySet.md create mode 100644 Fw/DataStructures/docs/AvlTreeMap.md create mode 100644 Fw/DataStructures/docs/AvlTreeSet.md create mode 100644 Fw/DataStructures/docs/Map.md create mode 100644 Fw/DataStructures/docs/Set.md diff --git a/Fw/DataStructures/docs/ArrayMap.md b/Fw/DataStructures/docs/ArrayMap.md new file mode 100644 index 00000000000..e6fbbbd654a --- /dev/null +++ b/Fw/DataStructures/docs/ArrayMap.md @@ -0,0 +1,4 @@ +# ArrayMap + +TODO + diff --git a/Fw/DataStructures/docs/ArraySet.md b/Fw/DataStructures/docs/ArraySet.md new file mode 100644 index 00000000000..e0b4e7ee1c0 --- /dev/null +++ b/Fw/DataStructures/docs/ArraySet.md @@ -0,0 +1,4 @@ +# ArraySet + +TODO + diff --git a/Fw/DataStructures/docs/AvlTreeMap.md b/Fw/DataStructures/docs/AvlTreeMap.md new file mode 100644 index 00000000000..d6995493b53 --- /dev/null +++ b/Fw/DataStructures/docs/AvlTreeMap.md @@ -0,0 +1,4 @@ +# AvlTreeMap + +TODO + diff --git a/Fw/DataStructures/docs/AvlTreeSet.md b/Fw/DataStructures/docs/AvlTreeSet.md new file mode 100644 index 00000000000..9fbf4b6b5f3 --- /dev/null +++ b/Fw/DataStructures/docs/AvlTreeSet.md @@ -0,0 +1,4 @@ +# AvlTreeSet + +TODO + diff --git a/Fw/DataStructures/docs/Map.md b/Fw/DataStructures/docs/Map.md new file mode 100644 index 00000000000..aad6158a15d --- /dev/null +++ b/Fw/DataStructures/docs/Map.md @@ -0,0 +1,4 @@ +# Map + +TODO + diff --git a/Fw/DataStructures/docs/Set.md b/Fw/DataStructures/docs/Set.md new file mode 100644 index 00000000000..bc4d5bd8f8f --- /dev/null +++ b/Fw/DataStructures/docs/Set.md @@ -0,0 +1,4 @@ +# Set + +TODO + diff --git a/Fw/DataStructures/docs/sdd.md b/Fw/DataStructures/docs/sdd.md index d86a75875a3..b4a0141f0ed 100644 --- a/Fw/DataStructures/docs/sdd.md +++ b/Fw/DataStructures/docs/sdd.md @@ -44,28 +44,16 @@ first in first out (FIFO) order. ## 3. Maps -### 3.1. Map +* [`Map`](Map.md) -TODO +* [`ArrayMap`](ArrayMap.md) -### 3.2. Array Map - -TODO - -### 3.3. AVL Tree Map - -TODO +* [`AvlTreeMap`](AvlTreeMap.md) ## 4. Sets -### 4.1. Set - -TODO - -### 4.2. Array Set - -TODO +* [`Set`](Set.md) -### 4.3. AVL Tree Set +* [`ArraySet`](ArraySet.md) -TODO +* [`AvlTreeSet`](AvlTreeSet.md) From e3fa1627ae5478c00a0e3124db16e9137f2c29e9 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 11:29:44 -0700 Subject: [PATCH 070/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/Array.md | 2 +- Fw/DataStructures/docs/FifoQueue.md | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/Array.md b/Fw/DataStructures/docs/Array.md index 63aa0d7f443..ecb04d53f80 100644 --- a/Fw/DataStructures/docs/Array.md +++ b/Fw/DataStructures/docs/Array.md @@ -174,7 +174,7 @@ ASSERT_EQ(elements2[0], 1); ExternalArray asExternalArray() ``` -Return `ExternalArray(m_elements, S)`. +Return [`ExternalArray(m_elements, S)`](ExternalArray.md#3-public-constructors-and-destructors) _Example:_ ```c++ diff --git a/Fw/DataStructures/docs/FifoQueue.md b/Fw/DataStructures/docs/FifoQueue.md index f3ac6298111..d638d3e7b46 100644 --- a/Fw/DataStructures/docs/FifoQueue.md +++ b/Fw/DataStructures/docs/FifoQueue.md @@ -71,6 +71,15 @@ Defined as `= default`. ## 4. Public Member Functions +**operator[]:** + +```c++ +T& operator[](FwSizeType i) +const T& operator[](FwSizeType i) const +``` + +TODO + **Copy assignment operator:** ```c++ From 6a37d8c77b6c1a28fa93ddced8b492bbc3e6e8bf Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 11:35:14 -0700 Subject: [PATCH 071/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/Array.md | 5 +++-- Fw/DataStructures/docs/ExternalArray.md | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Fw/DataStructures/docs/Array.md b/Fw/DataStructures/docs/Array.md index ecb04d53f80..3b776592c68 100644 --- a/Fw/DataStructures/docs/Array.md +++ b/Fw/DataStructures/docs/Array.md @@ -1,7 +1,8 @@ # 1.2. Array -`Array` is a `final` class template representing an array -with internal storage. +`Array` is a `final` class template defined in +[`Fw/DataStructures`](sdd.md). +It represents an array with internal storage. It maintains the backing memory _M_ as a member variable. ## 1. Template Parameters diff --git a/Fw/DataStructures/docs/ExternalArray.md b/Fw/DataStructures/docs/ExternalArray.md index f84e19e813e..b18f7aa2f46 100644 --- a/Fw/DataStructures/docs/ExternalArray.md +++ b/Fw/DataStructures/docs/ExternalArray.md @@ -1,6 +1,8 @@ # ExternalArray -`ExternalArray` is a `final` class template representing an +`ExternalArray` is a `final` class template +defined in [`Fw/DataStructures`](sdd.md). +It represents an [array](sdd.md#1-arrays) with external storage. It stores a pointer to the backing memory _M_. From d90fe505a1b246f9228491025d3c3ce5ff8e9150 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 11:36:35 -0700 Subject: [PATCH 072/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalFifoQueue.md | 5 +++-- Fw/DataStructures/docs/FifoQueue.md | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index e34f1673772..eebd9f8b4f8 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -1,7 +1,8 @@ # ExternalFifoQueue -`ExternalFifoQueue` is a `final` class template representing a -FIFO queue with external storage. +`ExternalFifoQueue` is a `final` class template +defined in [`Fw/DataStructures`]. +It represents a FIFO queue with external storage. Internally it maintains an [`ExternalArray`](ExternalArray.md) for storing the items on the queue. diff --git a/Fw/DataStructures/docs/FifoQueue.md b/Fw/DataStructures/docs/FifoQueue.md index d638d3e7b46..d43b2c4202c 100644 --- a/Fw/DataStructures/docs/FifoQueue.md +++ b/Fw/DataStructures/docs/FifoQueue.md @@ -1,7 +1,8 @@ # FifoQueue -`FifoQueue` is a `final` class template representing a -FIFO queue with internal storage. +`FifoQueue` is a `final` class template +defined in [`Fw/DataStructures`](sdd.md). +It represents a FIFO queue with internal storage. Internally it maintains an `Array` for storing the items on the queue. From fad5ab6cfb0227b455bfb974d298707fef010c22 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 11:37:24 -0700 Subject: [PATCH 073/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalFifoQueue.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index eebd9f8b4f8..f552f536693 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -1,7 +1,7 @@ # ExternalFifoQueue `ExternalFifoQueue` is a `final` class template -defined in [`Fw/DataStructures`]. +defined in [`Fw/DataStructures`](sdd.md). It represents a FIFO queue with external storage. Internally it maintains an [`ExternalArray`](ExternalArray.md) for storing the items on the queue. From 0a6a11390ab38b0a18e7764019dfdf78aa3d356a Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 11:52:48 -0700 Subject: [PATCH 074/458] Revise ExternalFifoQueue design --- Fw/DataStructures/docs/ExternalFifoQueue.md | 57 ++++++++++++++++++--- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index f552f536693..60b1380fe73 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -21,8 +21,8 @@ storing the items on the queue. |Name|Type|Purpose|Default Value| |----|----|-------|-------------| |`m_items`|[`ExternalArray`](ExternalArray.md)|The array for storing the queue items|C++ default initialization| -|`m_enqueueIndex`|[`CircularIndex`](CircularIndex.md)|The enqueue index|0| -|`m_dequeueIndex`|[`CircularIndex`](CircularIndex.md)|The dequeue index|0| +|`m_enqueueIndex`|[`CircularIndex`](CircularIndex.md)|The enqueue index|`CircularIndex(m_items.size(), 0)`| +|`m_dequeueIndex`|[`CircularIndex`](CircularIndex.md)|The dequeue index|`CircularIndex(m_items.size(), 0)`| |`m_size`|`FwSizeType`|The number of items on the queue|0| ## 3. Public Constructors and Destructors @@ -92,11 +92,24 @@ Defined as `= default`. **operator[]:** ```c++ -T& operator[](FwSizeType i) const T& operator[](FwSizeType i) const ``` -TODO +1. Assert that `i < m_size`. + +1. Return `m_items[(m_enqueueIndex + i) % m_items.size()]`. + +_Example:_ +```c++ +constexpr FwSizeType size = 3; +U32 elements[size] = {}; +ExternalFifoQueue queue(elements, size); +const auto status = queue.enqueue(3); +// Constant access +ASSERT_EQ(queue[0], 3); +// Out-of-bounds access +ASSERT_DEATH(queue[1], "Assert"); +``` **clear:** @@ -104,7 +117,23 @@ TODO void clear() ``` -TODO +1. Call `m_enqueueIndex.setValue(0)`. + +1. Call `m_dequeueIndex.setValue(0)`. + +1. Set `m_size = 0`. + + +_Example:_ +```c++ +constexpr FwSizeType size = 3; +U32 elements[size] = {}; +ExternalFifoQueue queue(elements, size); +const auto status = queue.enqueue(3); +ASSERT_EQ(queue.getSize(), 1); +queue.clear(); +ASSERT_EQ(queue.getSize(), 0); +``` **setStorage:** @@ -112,7 +141,15 @@ TODO void setStorage(T* items, FwSizeType size) ``` -TODO +Call `m_items.setStorage(items, size)`. + +_Example:_ +```c++ +constexpr FwSizeType size = 3; +ExternalFifoQueue queue; +U32 elements[size]; +queue.setStorage(elements, size); +``` **copyItemsFrom:** @@ -136,7 +173,13 @@ TODO Fw::Success peek(T& e) ``` -TODO +1. If `m_size == 0` return `Fw::Success::FAILURE`. + +1. Otherwise + + 1. Set `e = (*this)[m_size - 1]`. + + 1. Return `Fw::Success::SUCCESS`. **dequeue:** From 321b7b4684cb2c8e012e1792d3ebcbc66035392f Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 11:57:45 -0700 Subject: [PATCH 075/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/AvlTreeSet.md | 2 +- Fw/DataStructures/docs/ExternalArrayMap.md | 4 ++++ Fw/DataStructures/docs/ExternalArraySet.md | 4 ++++ Fw/DataStructures/docs/ExternalAvlTreeMap.md | 4 ++++ Fw/DataStructures/docs/ExternalAvlTreeSet.md | 4 ++++ Fw/DataStructures/docs/sdd.md | 8 ++++++++ 6 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 Fw/DataStructures/docs/ExternalArrayMap.md create mode 100644 Fw/DataStructures/docs/ExternalArraySet.md create mode 100644 Fw/DataStructures/docs/ExternalAvlTreeMap.md create mode 100644 Fw/DataStructures/docs/ExternalAvlTreeSet.md diff --git a/Fw/DataStructures/docs/AvlTreeSet.md b/Fw/DataStructures/docs/AvlTreeSet.md index 9fbf4b6b5f3..cbf5920f607 100644 --- a/Fw/DataStructures/docs/AvlTreeSet.md +++ b/Fw/DataStructures/docs/AvlTreeSet.md @@ -1,4 +1,4 @@ -# AvlTreeSet +# ExternalAvlTreeSet TODO diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md new file mode 100644 index 00000000000..9c346d4713d --- /dev/null +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -0,0 +1,4 @@ +# ExternalArrayMap + +TODO + diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md new file mode 100644 index 00000000000..13dcfffe5d4 --- /dev/null +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -0,0 +1,4 @@ +# ExternalArraySet + +TODO + diff --git a/Fw/DataStructures/docs/ExternalAvlTreeMap.md b/Fw/DataStructures/docs/ExternalAvlTreeMap.md new file mode 100644 index 00000000000..f6088cf0d51 --- /dev/null +++ b/Fw/DataStructures/docs/ExternalAvlTreeMap.md @@ -0,0 +1,4 @@ +# ExternalAvlTreeMap + +TODO + diff --git a/Fw/DataStructures/docs/ExternalAvlTreeSet.md b/Fw/DataStructures/docs/ExternalAvlTreeSet.md new file mode 100644 index 00000000000..9fbf4b6b5f3 --- /dev/null +++ b/Fw/DataStructures/docs/ExternalAvlTreeSet.md @@ -0,0 +1,4 @@ +# AvlTreeSet + +TODO + diff --git a/Fw/DataStructures/docs/sdd.md b/Fw/DataStructures/docs/sdd.md index b4a0141f0ed..0dd59b64131 100644 --- a/Fw/DataStructures/docs/sdd.md +++ b/Fw/DataStructures/docs/sdd.md @@ -46,14 +46,22 @@ first in first out (FIFO) order. * [`Map`](Map.md) +* [`ExternalArrayMap`](ExternalArrayMap.md) + * [`ArrayMap`](ArrayMap.md) * [`AvlTreeMap`](AvlTreeMap.md) +* [`ExternalAvlTreeMap`](ExternalAvlTreeMap.md) + ## 4. Sets * [`Set`](Set.md) +* [`ExternalArraySet`](ExternalArraySet.md) + * [`ArraySet`](ArraySet.md) +* [`ExternalAvlTreeSet`](ExternalAvlTreeSet.md) + * [`AvlTreeSet`](AvlTreeSet.md) From b511db6f0f0c1f193b75825201f47850c4f80c0e Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 12:00:36 -0700 Subject: [PATCH 076/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalFifoQueue.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index 60b1380fe73..83d3889d2c7 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -181,6 +181,21 @@ Fw::Success peek(T& e) 1. Return `Fw::Success::SUCCESS`. +_Example:_ +```c++ +constexpr FwSizeType size = 3; +U32 elements[size] = {}; +ExternalFifoQueue queue(elements, size); +U32 value = 0; +auto status = queue.peek(value); +ASSERT_EQ(status, Fw::Success::FAILURE); +status = queue.enqueue(3); +ASSERT_EQ(status, Fw::Success::SUCCESS); +status = queue.peek(value); +ASSERT_EQ(status, Fw::Success::SUCCESS); +ASSERT_EQ(value, 3); +``` + **dequeue:** ```c++ From 1b3e5a6a16e5923d5ec746ee9f4a9a55fc2b5103 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 17:56:41 -0700 Subject: [PATCH 077/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalFifoQueue.md | 230 ++++++++++++++------ Fw/DataStructures/docs/FifoQueue.md | 11 +- Fw/DataStructures/docs/FifoQueueBase.md | 201 +++++++++++++++++ Fw/DataStructures/docs/sdd.md | 2 + 4 files changed, 374 insertions(+), 70 deletions(-) create mode 100644 Fw/DataStructures/docs/FifoQueueBase.md diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index 83d3889d2c7..6c9f55f2d76 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -14,7 +14,12 @@ storing the items on the queue. |----|----|-------| |`typename`|`T`|The type of an item on the queue| -## 2. Private Member Variables +## 2. Base Class + +`ExternalFifoQueue` is publicly derived from +[`FifoQueueBase`](FifoQueueBase.md). + +## 3. Private Member Variables `ExternalFifoQueue` has the following private member variables. @@ -25,7 +30,7 @@ storing the items on the queue. |`m_dequeueIndex`|[`CircularIndex`](CircularIndex.md)|The dequeue index|`CircularIndex(m_items.size(), 0)`| |`m_size`|`FwSizeType`|The number of items on the queue|0| -## 3. Public Constructors and Destructors +## 4. Public Constructors and Destructors **Zero-argument constructor:** @@ -33,23 +38,28 @@ storing the items on the queue. ExternalFifoQueue() ``` -`ExternalFifoQueue` is a `final` class template representing a FIFO queue with -internal storage. -It maintains an `Array` for storing the items on the queue. +Initialize the member variables with their default values. + +_Example:_ +```c++ +ExternalFifoQueue() +``` **Constructor providing backing storage:** ```c++ -ExternalFifoQueue(T* items, FwSizeType size) +ExternalFifoQueue(T* items, FwSizeType capacity) ``` -Initialize `m_items` with `items` and `size`. +1. Initialize `m_items` with `ExternalArray(items, capacity)`. + +1. Initialize the other member variables with their default values. _Example:_ ```c++ -constexpr FwSizeType size = 10; -U32 items[size]; -ExternalFifoQueue queue(items, size); +constexpr FwSizeType capacity = 10; +U32 items[capacity]; +ExternalFifoQueue queue(items, capacity); ``` **Copy constructor:** @@ -58,41 +68,71 @@ ExternalFifoQueue queue(items, size); ExternalFifoQueue(const ExternalFifoQueue& queue) ``` -1. Set `m_items = queue.m_items`. - -1. Set `m_enqueueIndex = queue.m_enqueueIndex`. - -1. Set `m_dequeueIndex = queue.m_dequeueIndex`. - -1. Set `m_size = queue.size`. +Set `*this = queue`. _Example:_ ```c++ -constexpr FwSizeType size = 3; -U32 items[size]; +constexpr FwSizeType capacity = 3; +U32 items[capacity]; // Call the constructor providing backing storage -ExternalFifoQueue q1(elements, 10); -// Enqueue an element +ExternalFifoQueue q1(items, capacity); +// Enqueue an item U32 value = 42; (void) q1.enqueue(value); // Call the copy constructor -ExternalFifoQueue a2(a1); +ExternalFifoQueue q2(q1); +ASSERT_EQ(q2.getSize(), 1); ``` **Destructor:** ```c++ -ExternalFifoQueue() +~ExternalFifoQueue() override ``` Defined as `= default`. -## 4. Public Member Functions +## 5. Public Member Functions -**operator[]:** +**Copy assignment operator:** ```c++ -const T& operator[](FwSizeType i) const +ExternalFifoQueue& operator=(const ExternalFifoQueue& queue) +``` + +1. If `&queue == this` then do nothing. + +1. Otherwise + + 1. Set `m_items = queue.m_items`. + + 1. Set `m_enqueueIndex = queue.m_enqueueIndex`. + + 1. Set `m_dequeueIndex = queue.m_dequeueIndex`. + + 1. Set `m_size = queue.size`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 3; +U32 items[capacity]; +// Call the constructor providing backing storage +ExternalFifoQueue 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); +``` + +**at:** + +```c++ +const T& at(FwSizeType i) const override ``` 1. Assert that `i < m_size`. @@ -101,20 +141,20 @@ const T& operator[](FwSizeType i) const _Example:_ ```c++ -constexpr FwSizeType size = 3; -U32 elements[size] = {}; -ExternalFifoQueue queue(elements, size); +constexpr FwSizeType capacity = 10; +U32 items[size] = {}; +ExternalFifoQueue queue(items, capacity); const auto status = queue.enqueue(3); // Constant access -ASSERT_EQ(queue[0], 3); +ASSERT_EQ(queue.at(0), 3); // Out-of-bounds access -ASSERT_DEATH(queue[1], "Assert"); +ASSERT_DEATH(queue.at(1), "Assert"); ``` **clear:** ```c++ -void clear() +void clear() override ``` 1. Call `m_enqueueIndex.setValue(0)`. @@ -123,12 +163,11 @@ void clear() 1. Set `m_size = 0`. - _Example:_ ```c++ -constexpr FwSizeType size = 3; -U32 elements[size] = {}; -ExternalFifoQueue queue(elements, size); +constexpr FwSizeType capacity = 10; +U32 items[capacity] = {}; +ExternalFifoQueue queue(items, capacity); const auto status = queue.enqueue(3); ASSERT_EQ(queue.getSize(), 1); queue.clear(); @@ -145,77 +184,134 @@ Call `m_items.setStorage(items, size)`. _Example:_ ```c++ -constexpr FwSizeType size = 3; +constexpr FwSizeType capacity = 10; ExternalFifoQueue queue; -U32 elements[size]; -queue.setStorage(elements, size); +U32 items[capacity]; +queue.setStorage(items, capacity); ``` -**copyItemsFrom:** +**copyDataFrom:** ```c++ -void copyItemsFrom(const ExternalFifoQueue& queue) +void copyDataFrom(const FifoQueueBase& queue) override ``` -TODO +1. Call `clear()`. -**enqueue:** +1. For `i` from 0 to `queue.getSize() - 1` + + 1. Set `const auto status = enqueue(queue.at(i))` + 1. Assert `status == Fw::Success::SUCCESS`. + +_Example:_ ```c++ -Fw::Success enqueue(const T& e) +constexpr FwSizeType capacity = 3; +U32 items1[capacity]; +// Call the constructor providing backing storage +ExternalFifoQueue q1(items1, capacity); +// Enqueue an item +U32 value = 42; +(void) q1.enqueue(value); +U32 items2[capacity]; +// Call the constructor providing backing storage +ExternalFifoQueue q2(items2, capacity); +ASSERT_EQ(q2.getSize(), 0); +q2.copyDataFrom(q1); +ASSERT_EQ(q2.getSize(), 1); ``` -TODO - -**peek:** +**enqueue:** ```c++ -Fw::Success peek(T& e) +Fw::Success enqueue(const T& e) override ``` -1. If `m_size == 0` return `Fw::Success::FAILURE`. +1. Set `status = Fw::Success::FAILURE`. + +1. If `m_size < m_capacity` then + + 1. Set `i = m_enqueueIndex.getValue()`. -1. Otherwise + 1. Set `m_items[i] = e`. - 1. Set `e = (*this)[m_size - 1]`. + 1. Call `m_enqueueIndex.increment()`. - 1. Return `Fw::Success::SUCCESS`. + 1. Increment `m_size`. + +1. Return `status`. _Example:_ ```c++ -constexpr FwSizeType size = 3; -U32 elements[size] = {}; -ExternalFifoQueue queue(elements, size); -U32 value = 0; -auto status = queue.peek(value); -ASSERT_EQ(status, Fw::Success::FAILURE); -status = queue.enqueue(3); -ASSERT_EQ(status, Fw::Success::SUCCESS); -status = queue.peek(value); +constexpr FwSizeType capacity = 3; +U32 items[capacity]; +ExternalFifoQueue queue(items, capacity); +ASSERT_EQ(queue.getSize(), 0); +auto status = queue.enqueue(42); ASSERT_EQ(status, Fw::Success::SUCCESS); -ASSERT_EQ(value, 3); +ASSERT_EQ(queue.getSize(), 1); ``` **dequeue:** ```c++ -Fw::Success dequeue(T& e) +Fw::Success dequeue(T& e) override ``` -TODO +1. Set `status = Fw::Success::FAILURE`. + +1. If `m_size > 0` then + + 1. Set `i = m_dequeueIndex.getValue()`. + + 1. Set `e = m_items[i]`. + + 1. Call `m_dequeueIndex.increment()`. + + 1. Decrement `m_size`. + +1. Return `status`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 3; +U32 items[capacity]; +ExternalFifoQueue queue(items, capacity); +U32 val; +auto status = queue.dequeue(val); +ASSERT_EQ(status, Fw::Success::FAILURE); +status = queue.enqueue(42); +ASSERT_EQ(status, Fw::Success::SUCCESS); +status = queue.dequeue(val); +ASSERT_EQ(status, Fw::Success::SUCCESS); +ASSERT_EQ(val, 42); +``` **getSize:** ```c++ -FwSizeType getSize() const +FwSizeType getSize() const override ``` -TODO +Return `m_size`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +U32 items[capacity]; +ExternalFifoQueue queue(items, capacity); +auto size = queue.getSize(); +ASSERT_EQ(size, 0); +const auto status = queue.enqueue(3); +ASSERT_EQ(status, Fw::Success::SUCCESS); +size = queue.getSize(); +ASSERT_EQ(size, 1); +``` **getCapacity:** ```c++ -FwSizeType getCapacity() const +FwSizeType getCapacity() const override ``` TODO diff --git a/Fw/DataStructures/docs/FifoQueue.md b/Fw/DataStructures/docs/FifoQueue.md index d43b2c4202c..b5e01bd8794 100644 --- a/Fw/DataStructures/docs/FifoQueue.md +++ b/Fw/DataStructures/docs/FifoQueue.md @@ -17,7 +17,12 @@ for storing the items on the queue. `FifoQueue` statically asserts that `C > 0`. -## 2. Private Member Variables +## 2. Base Class + +`ExternalFifoQueue` is publicly derived from +[`FifoQueueBase`](FifoQueueBase.md). + +## 3. Private Member Variables `FifoQueue` has the following private member variables. @@ -26,7 +31,7 @@ for storing the items on the queue. |`m_extQueue`|`ExternalFifoQueue`|The external queue implementation|C++ default initialization| |`m_array`|`Array`|The array providing the backing memory for `m_extQueue`|C++ default initialization| -## 3. Public Constructors and Destructors +## 4. Public Constructors and Destructors **Zero-argument constructor:** @@ -70,7 +75,7 @@ ASSERT_EQ(value, 3); Defined as `= default`. -## 4. Public Member Functions +## 5. Public Member Functions **operator[]:** diff --git a/Fw/DataStructures/docs/FifoQueueBase.md b/Fw/DataStructures/docs/FifoQueueBase.md new file mode 100644 index 00000000000..36d7699d996 --- /dev/null +++ b/Fw/DataStructures/docs/FifoQueueBase.md @@ -0,0 +1,201 @@ +# FifoQueueBase + +`FifoQueueBase` is a class template +defined in [`Fw/DataStructures`](sdd.md). +It represents an abstract base class for a FIFO queue. + +## 1. Template Parameters + +`FifoQueueBase` has the following template parameters. + +|Kind|Name|Purpose| +|----|----|-------| +|`typename`|`T`|The type of an item on the queue| + +## 2. Protected Constructors and Destructors + +**Zero-argument constructor:** + +```c++ +FifoQueueBase() +``` + +Defined as `= default`. + +**Copy constructor:** + +```c++ +FifoQueueBase(const FifoQueueBase& queue) +``` + +Defined as `= delete`. + +**Destructor:** + +```c++ +virtual FifoQueueBase() +``` + +Defined as `= default`. + +## 3. Public Member Functions + +**at:** + +```c++ +virtual const T& at(FwSizeType i) const = 0 +``` + +1. Assert that `i < getSize()`. + +1. Get a reference to the element of the queue at index `i`. +Index 0 is the first element inserted in the queue. + +_Example:_ +```c++ +void f(FifoQueueBase& queue) { + queue.clear(); + auto status = queue.enqueue(10); + ASSERT_EQ(status, Fw::Success::SUCCESS); + auto status = queue.enqueue(11); + ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(queue.at(0), 10); + ASSERT_EQ(queue.at(1), 11); + // Out-of-bounds access + ASSERT_DEATH(queue.at(2), "Assert"); +} +``` + +**clear:** + +```c++ +virtual void clear() = 0 +``` + +Clear the queue. + +_Example:_ +```c++ +void f(FifoQueueBase& queue) { + queue.clear(); + ASSERT_EQ(queue.getSize(), 0); +} +``` + +**copyDataFrom:** + +```c++ +virtual void copyDataFrom(const FifoQueueBase& queue) = 0 +``` + +Copy the data from `queue` to `*this`. + +_Example:_ +```c++ +void f(const FifoQueueBase& q1, FifoQueueBase& q2) { + q2.copyDataFrom(q1); +} +``` + +**enqueue:** + +```c++ +virtual void Fw::Success enqueue(const T& e) = 0 +``` + +1. If there is no room on the queue for a new item, then return `Fw::Success::FAILURE`. + +1. Otherwise + + 1. Enqueue `e`. + + 1. Return `Fw::Success::SUCCESS`. + +_Example:_ +```c++ +void f(FifoQueueBase& queue) { + queue.clear(); + status = queue.enqueue(3); + ASSERT_EQ(status, Fw::Success::SUCCESS); +} +``` + +**peek:** + +```c++ +void Fw::Success peek(T& e) +``` + +1. If `getSize() == 0` return `Fw::Success::FAILURE`. + +1. Otherwise + + 1. Set `e = (*this)[getSize() - 1]`. + + 1. Return `Fw::Success::SUCCESS`. + +_Example:_ +```c++ +void f(FifoQueueBase& queue) { + queue.clear(); + U32 value = 0; + auto status = queue.peek(value); + ASSERT_EQ(status, Fw::Success::FAILURE); + status = queue.enqueue(3); + ASSERT_EQ(status, Fw::Success::SUCCESS); + status = queue.peek(value); + ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(value, 3); +} +``` + +**dequeue:** + +```c++ +virtual void Fw::Success dequeue(T& e) = 0 +``` + +1. Set `status = peek(e)`. + +1. If `status == Fw::Success::SUCCESS` then dequeue an item and store it into + `e`. + +1. Return `status`. + +**getSize:** + +```c++ +virtual void FwSizeType getSize() const = 0 +``` + +Return the current size. + +_Example:_ +```c++ +void f(const FifoQueueBase& queue) { + queue.clear(); + auto size = queue.getSize(); + ASSERT_EQ(size, 0); + const auto status = queue.enqueue(3); + ASSERT_EQ(status, Fw::Success::SUCCESS); + size = queue.getSize(); + ASSERT_EQ(size, 1); +} +``` + +**getCapacity:** + +```c++ +virtual FwSizeType getCapacity() const = 0 +``` + +Return the current capacity. + +_Example:_ +```c++ +void f(const FifoQueueBase& queue) { + const auto size = queue.getSize(); + const auto capacity = queue.getCapacity(); + ASSERT_LE(size, capacity); +} +``` diff --git a/Fw/DataStructures/docs/sdd.md b/Fw/DataStructures/docs/sdd.md index 0dd59b64131..66651d07e01 100644 --- a/Fw/DataStructures/docs/sdd.md +++ b/Fw/DataStructures/docs/sdd.md @@ -38,6 +38,8 @@ first in first out (FIFO) order. `Fw/DataStructures` provides the following FIFO queue templates: +* [`FifoQueueBase`](FifoQueueBase.md) + * [`ExternalFifoQueue`](ExternalFifoQueue.md) * [`FifoQueue`](FifoQueue.md) From 138625385bc9739cd7b11da7d2ecfda219f5219b Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 17:58:33 -0700 Subject: [PATCH 078/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/FifoQueueBase.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Fw/DataStructures/docs/FifoQueueBase.md b/Fw/DataStructures/docs/FifoQueueBase.md index 36d7699d996..0fb3d1b3851 100644 --- a/Fw/DataStructures/docs/FifoQueueBase.md +++ b/Fw/DataStructures/docs/FifoQueueBase.md @@ -14,7 +14,7 @@ It represents an abstract base class for a FIFO queue. ## 2. Protected Constructors and Destructors -**Zero-argument constructor:** +### 2.1. Zero-argument Constructor ```c++ FifoQueueBase() @@ -22,7 +22,7 @@ FifoQueueBase() Defined as `= default`. -**Copy constructor:** +### 2.2. Copy Constructor ```c++ FifoQueueBase(const FifoQueueBase& queue) @@ -30,7 +30,7 @@ FifoQueueBase(const FifoQueueBase& queue) Defined as `= delete`. -**Destructor:** +### 2.3. Destructor ```c++ virtual FifoQueueBase() From be2cefa85d41b00a7732c1e06d862a0ed0db6f9e Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 18:00:21 -0700 Subject: [PATCH 079/458] Revise FifoQueueBase --- Fw/DataStructures/docs/FifoQueueBase.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Fw/DataStructures/docs/FifoQueueBase.md b/Fw/DataStructures/docs/FifoQueueBase.md index 0fb3d1b3851..a148eb45b95 100644 --- a/Fw/DataStructures/docs/FifoQueueBase.md +++ b/Fw/DataStructures/docs/FifoQueueBase.md @@ -40,7 +40,7 @@ Defined as `= default`. ## 3. Public Member Functions -**at:** +### 3.1. at ```c++ virtual const T& at(FwSizeType i) const = 0 @@ -66,7 +66,7 @@ void f(FifoQueueBase& queue) { } ``` -**clear:** +### 3.2. clear ```c++ virtual void clear() = 0 @@ -82,7 +82,7 @@ void f(FifoQueueBase& queue) { } ``` -**copyDataFrom:** +### 3.3. copyDataFrom ```c++ virtual void copyDataFrom(const FifoQueueBase& queue) = 0 @@ -97,7 +97,7 @@ void f(const FifoQueueBase& q1, FifoQueueBase& q2) { } ``` -**enqueue:** +### 3.4. enqueue ```c++ virtual void Fw::Success enqueue(const T& e) = 0 @@ -120,7 +120,7 @@ void f(FifoQueueBase& queue) { } ``` -**peek:** +### 3.5. peek ```c++ void Fw::Success peek(T& e) @@ -149,7 +149,7 @@ void f(FifoQueueBase& queue) { } ``` -**dequeue:** +### 3.6. dequeue ```c++ virtual void Fw::Success dequeue(T& e) = 0 @@ -162,7 +162,7 @@ virtual void Fw::Success dequeue(T& e) = 0 1. Return `status`. -**getSize:** +### 3.7. getSize ```c++ virtual void FwSizeType getSize() const = 0 @@ -183,7 +183,7 @@ void f(const FifoQueueBase& queue) { } ``` -**getCapacity:** +### 3.8. getCapacity ```c++ virtual FwSizeType getCapacity() const = 0 From 53ee392184aa4a68a54015b5db27ae4fd11e9ec3 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 18:05:24 -0700 Subject: [PATCH 080/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalFifoQueue.md | 31 ----------------- Fw/DataStructures/docs/FifoQueueBase.md | 38 ++++++++++++++++++--- 2 files changed, 34 insertions(+), 35 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index 6c9f55f2d76..18188b0d528 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -190,37 +190,6 @@ U32 items[capacity]; queue.setStorage(items, capacity); ``` -**copyDataFrom:** - -```c++ -void copyDataFrom(const FifoQueueBase& queue) override -``` - -1. Call `clear()`. - -1. For `i` from 0 to `queue.getSize() - 1` - - 1. Set `const auto status = enqueue(queue.at(i))` - - 1. Assert `status == Fw::Success::SUCCESS`. - -_Example:_ -```c++ -constexpr FwSizeType capacity = 3; -U32 items1[capacity]; -// Call the constructor providing backing storage -ExternalFifoQueue q1(items1, capacity); -// Enqueue an item -U32 value = 42; -(void) q1.enqueue(value); -U32 items2[capacity]; -// Call the constructor providing backing storage -ExternalFifoQueue q2(items2, capacity); -ASSERT_EQ(q2.getSize(), 0); -q2.copyDataFrom(q1); -ASSERT_EQ(q2.getSize(), 1); -``` - **enqueue:** ```c++ diff --git a/Fw/DataStructures/docs/FifoQueueBase.md b/Fw/DataStructures/docs/FifoQueueBase.md index a148eb45b95..1a17dd3d4ed 100644 --- a/Fw/DataStructures/docs/FifoQueueBase.md +++ b/Fw/DataStructures/docs/FifoQueueBase.md @@ -84,16 +84,31 @@ void f(FifoQueueBase& queue) { ### 3.3. copyDataFrom +**copyDataFrom:** + ```c++ -virtual void copyDataFrom(const FifoQueueBase& queue) = 0 +void copyDataFrom(const FifoQueueBase& queue) override ``` -Copy the data from `queue` to `*this`. +1. Call `clear()`. + +1. For `i` from 0 to `queue.getSize() - 1` + + 1. Set `const auto status = enqueue(queue.at(i))` + + 1. Assert `status == Fw::Success::SUCCESS`. _Example:_ ```c++ -void f(const FifoQueueBase& q1, FifoQueueBase& q2) { +void f(FifoQueueBase& q1, FifoQueueBase& q2) { + q1.clear(); + // Enqueue an item + U32 value = 42; + (void) q1.enqueue(value); + q2.clear(); + ASSERT_EQ(q2.getSize(), 0); q2.copyDataFrom(q1); + ASSERT_EQ(q2.getSize(), 1); } ``` @@ -136,7 +151,7 @@ void Fw::Success peek(T& e) _Example:_ ```c++ -void f(FifoQueueBase& queue) { +void f(FifoQueueBase& queue) { queue.clear(); U32 value = 0; auto status = queue.peek(value); @@ -162,6 +177,21 @@ virtual void Fw::Success dequeue(T& e) = 0 1. Return `status`. +_Example:_ +```c++ +void f(FifoQueueBase& queue) { + queue.clear(); + U32 val = 0; + auto status = queue.dequeue(val); + ASSERT_EQ(status, Fw::Success::FAILURE); + status = queue.enqueue(3); + ASSERT_EQ(status, Fw::Success::SUCCESS); + status = queue.dequeue(val); + ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(val, 3); +} +``` + ### 3.7. getSize ```c++ From f907d1b1e8b9d0329fb941d5d465143df9073945 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 18:07:37 -0700 Subject: [PATCH 081/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/Array.md | 20 ++++++++++---------- Fw/DataStructures/docs/FifoQueueBase.md | 2 -- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/Fw/DataStructures/docs/Array.md b/Fw/DataStructures/docs/Array.md index 3b776592c68..61f8c635362 100644 --- a/Fw/DataStructures/docs/Array.md +++ b/Fw/DataStructures/docs/Array.md @@ -31,7 +31,7 @@ It is an alias of `T[S]`. ## 4. Public Constructors and Destructors -**Zero-argument constructor:** +### 4.1. Zero-argument Constructor ```c++ Array() @@ -44,7 +44,7 @@ _Example:_ Array a; ``` -**Initializer list constructor:** +### 4.2. Initializer List Constructor ```c++ Array(const std::initializer_list& il) @@ -62,7 +62,7 @@ Array a({ 1, 2, 3 }); Array b = { 1, 2, 3 }; ``` -**Single-element constructor:** +### 4.3. Single-element Constructor ```c++ explicit Array(const T& element) @@ -78,7 +78,7 @@ Array a(1); a = Array(2); ``` -**Copy constructor:** +### 4.4. Copy Constructor ```c++ Array(const Array& a) @@ -95,7 +95,7 @@ Array a1(3); Array a2(a1); ``` -**Destructor:** +### 4.5. Destructor ```c++ ~Array() @@ -105,7 +105,7 @@ Defined as `= default`. ## 5. Public Member Functions -**operator[]:** +### 5.1. operator[] ```c++ T& operator[](FwSizeType i) @@ -129,7 +129,7 @@ ASSERT_EQ(a[0], 1); ASSERT_DEATH(a[size], "Assert"); ``` -**Copy assignment operator:** +### 5.2. Copy Assignment Operator ```c++ Array& operator=(const Array& a) @@ -147,7 +147,7 @@ Array a2(2); a1 = a2; ``` -**getElements:** +### 5.3. getElements ```c++ Elements& getElements() @@ -169,7 +169,7 @@ const auto& elements2 = a.getElements(); ASSERT_EQ(elements2[0], 1); ``` -**asExternalArray:** +### 5.4. asExternalArray ```c++ ExternalArray asExternalArray() @@ -187,7 +187,7 @@ ASSERT_EQ(ea[0], 1); ## 6. Public Static Functions -**getSize:** +### 6.1. getSize ```c++ static constexpr FwSizeType getSize() diff --git a/Fw/DataStructures/docs/FifoQueueBase.md b/Fw/DataStructures/docs/FifoQueueBase.md index 1a17dd3d4ed..1844c668b62 100644 --- a/Fw/DataStructures/docs/FifoQueueBase.md +++ b/Fw/DataStructures/docs/FifoQueueBase.md @@ -84,8 +84,6 @@ void f(FifoQueueBase& queue) { ### 3.3. copyDataFrom -**copyDataFrom:** - ```c++ void copyDataFrom(const FifoQueueBase& queue) override ``` From 3b28b393ecb3c05d5ed339cfb539e6c99b86cadc Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 18:09:06 -0700 Subject: [PATCH 082/458] Revise Array --- Fw/DataStructures/docs/Array.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Fw/DataStructures/docs/Array.md b/Fw/DataStructures/docs/Array.md index 61f8c635362..f6d4341be93 100644 --- a/Fw/DataStructures/docs/Array.md +++ b/Fw/DataStructures/docs/Array.md @@ -187,17 +187,17 @@ ASSERT_EQ(ea[0], 1); ## 6. Public Static Functions -### 6.1. getSize +### 6.1. getStaticSize ```c++ -static constexpr FwSizeType getSize() +static constexpr FwSizeType getStaticSize() ``` -Return the size `S` of the array. +Return the static size `S` of the array. _Example:_ ```c++ -const auto size = Array::getSize(); +const auto size = Array::getStaticSize(); ASSERT_EQ(size, 3); ``` From 89b6b0993d3521a86b37a3d08c3c68e30746102b Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 20:10:11 -0700 Subject: [PATCH 083/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalArray.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArray.md b/Fw/DataStructures/docs/ExternalArray.md index b18f7aa2f46..4ac8e12037c 100644 --- a/Fw/DataStructures/docs/ExternalArray.md +++ b/Fw/DataStructures/docs/ExternalArray.md @@ -25,7 +25,7 @@ It stores a pointer to the backing memory _M_. ## 3. Public Constructors and Destructors -**Zero-argument constructor:** +### 3.1. Zero-argument Constructor ```c++ ExternalArray() @@ -38,7 +38,7 @@ _Example:_ ExternalArray a; ``` -**Constructor providing backing storage:** +### 3.2. Constructor Providing Backing Storage ```c++ ExternalArray(T* elements, FwSizeType size) @@ -53,7 +53,7 @@ U32 elements[size]; ExternalArray a(elements, size); ``` -**Copy constructor:** +### 3.3. Copy Constructor ```c++ ExternalArray(const ExternalArray& a) @@ -71,7 +71,7 @@ ExternalArray a1(elements, size); ExternalArray a2(a1); ``` -**Destructor:** +### 3.4. Destructor ```c++ ~ExternalArray() @@ -81,7 +81,7 @@ Defined as `= default`. ## 4. Public Member Functions -**operator[]:** +### 4.1. operator[] ```c++ T& operator[](FwSizeType i) @@ -108,7 +108,7 @@ ASSERT_EQ(a[0], 1); ASSERT_DEATH(a[size], "Assert"); ``` -**Copy assignment operator:** +### 4.2. Copy Assignment Operator ```c++ ExternalArray& operator=(const ExternalArray& a) @@ -127,10 +127,10 @@ ExternalArray a2; a2 = a1; ``` -**copyElementsFrom:** +### 4.3. copyDataFrom ```c++ -void copyElementsFrom(const ExternalArray& a) +void copyDataFrom(const ExternalArray& a) ``` 1. If `&a == this` then do nothing. @@ -151,13 +151,13 @@ for (FwSizeType i = 0; i < size; i++) { } U32 elements2[size]; ExternalArray a2(elements, size); -a2.copyElementsFrom(a1); +a2.copyDataFrom(a1); for (FwSizeType i = 0; i < size; i++) { ASSERT_EQ(a2[i], a1[i]); } ``` -**getElements:** +### 4.4. getElements ```c++ T* getElements() @@ -180,7 +180,7 @@ const auto& elements2 = a.getElements(); ASSERT_EQ(elements2[0], 1); ``` -**getSize:** +### 4.5. getSize ```c++ FwSizeType getSize() @@ -197,7 +197,7 @@ const auto size1 = a.getSize(); ASSERT_EQ(size1, size); ``` -**setStorage:** +### 4.6. setStorage ```c++ void setStorage(T* elements, FwSizeType size) From 6d28961484d637b38ad5ba42682abb83ea8ef635 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 20:12:46 -0700 Subject: [PATCH 084/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalArray.md | 2 +- Fw/DataStructures/docs/sdd.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArray.md b/Fw/DataStructures/docs/ExternalArray.md index 4ac8e12037c..b7efff1863c 100644 --- a/Fw/DataStructures/docs/ExternalArray.md +++ b/Fw/DataStructures/docs/ExternalArray.md @@ -207,8 +207,8 @@ Set `m_elements = elements` and `m_size = size`. _Example:_ ```c++ -constexpr FwSizeType size = 3; ExternalArray a; +constexpr FwSizeType size = 3; U32 elements[size]; a.setStorage(elements, size); ``` diff --git a/Fw/DataStructures/docs/sdd.md b/Fw/DataStructures/docs/sdd.md index 66651d07e01..d127122d982 100644 --- a/Fw/DataStructures/docs/sdd.md +++ b/Fw/DataStructures/docs/sdd.md @@ -13,7 +13,7 @@ The data structures defined here use the following concepts: For a fixed-size array, the size and the capacity are the same. For other data structures, the size and the capacity are not in general the same. -For example, at all times a map has a fixed capacity _C_ and a size between 0 +For example, a map has a capacity _C_ and a size between 0 and _C_. ## 1. Arrays From 8ec6608789d79489a768ccf5d3cc5a6d7f7e6a65 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 20:16:02 -0700 Subject: [PATCH 085/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/Array.md | 6 +++--- Fw/DataStructures/docs/ExternalArray.md | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Fw/DataStructures/docs/Array.md b/Fw/DataStructures/docs/Array.md index f6d4341be93..7316161bb7b 100644 --- a/Fw/DataStructures/docs/Array.md +++ b/Fw/DataStructures/docs/Array.md @@ -31,7 +31,7 @@ It is an alias of `T[S]`. ## 4. Public Constructors and Destructors -### 4.1. Zero-argument Constructor +### 4.1. Zero-Argument Constructor ```c++ Array() @@ -62,7 +62,7 @@ Array a({ 1, 2, 3 }); Array b = { 1, 2, 3 }; ``` -### 4.3. Single-element Constructor +### 4.3. Single-Element Constructor ```c++ explicit Array(const T& element) @@ -129,7 +129,7 @@ ASSERT_EQ(a[0], 1); ASSERT_DEATH(a[size], "Assert"); ``` -### 5.2. Copy Assignment Operator +### 5.2. operator= ```c++ Array& operator=(const Array& a) diff --git a/Fw/DataStructures/docs/ExternalArray.md b/Fw/DataStructures/docs/ExternalArray.md index b7efff1863c..8fc6a68b2ef 100644 --- a/Fw/DataStructures/docs/ExternalArray.md +++ b/Fw/DataStructures/docs/ExternalArray.md @@ -25,7 +25,7 @@ It stores a pointer to the backing memory _M_. ## 3. Public Constructors and Destructors -### 3.1. Zero-argument Constructor +### 3.1. Zero-Argument Constructor ```c++ ExternalArray() @@ -108,7 +108,7 @@ ASSERT_EQ(a[0], 1); ASSERT_DEATH(a[size], "Assert"); ``` -### 4.2. Copy Assignment Operator +### 4.2. operator= ```c++ ExternalArray& operator=(const ExternalArray& a) From fa22c3857e4c1399c27643bdb6dc133800b416ef Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 20:46:28 -0700 Subject: [PATCH 086/458] Revise Fw/DataStructures --- Fw/DataStructures/Array.hpp | 4 ++-- Fw/DataStructures/ExternalArray.hpp | 4 ++-- Fw/DataStructures/test/ut/ArrayTest.cpp | 4 ++-- Fw/DataStructures/test/ut/ExternalArrayTest.cpp | 12 ++++++------ 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Fw/DataStructures/Array.hpp b/Fw/DataStructures/Array.hpp index 90e74424a4c..5f3ec5b2059 100644 --- a/Fw/DataStructures/Array.hpp +++ b/Fw/DataStructures/Array.hpp @@ -115,9 +115,9 @@ class Array final { // Public static functions // ---------------------------------------------------------------------- - //! Get the array size + //! Get the static array size //! \return The size - static constexpr FwSizeType getSize() { return S; } + static constexpr FwSizeType getStaticSize() { return S; } private: // ---------------------------------------------------------------------- diff --git a/Fw/DataStructures/ExternalArray.hpp b/Fw/DataStructures/ExternalArray.hpp index 2fa90e0e26f..995c6c4b5fb 100644 --- a/Fw/DataStructures/ExternalArray.hpp +++ b/Fw/DataStructures/ExternalArray.hpp @@ -68,8 +68,8 @@ class ExternalArray final { return *this; } - //! Copy the elements from a - void copyElementsFrom(const ExternalArray& a) { + //! Copy the data from a + void copyDataFrom(const ExternalArray& a) { const FwSizeType size = FW_MIN(this->m_size, a.m_size); for (FwSizeType i = 0; i < size; i++) { (*this)[i] = a[i]; diff --git a/Fw/DataStructures/test/ut/ArrayTest.cpp b/Fw/DataStructures/test/ut/ArrayTest.cpp index 8db4a26e765..e7a51e1404e 100644 --- a/Fw/DataStructures/test/ut/ArrayTest.cpp +++ b/Fw/DataStructures/test/ut/ArrayTest.cpp @@ -88,8 +88,8 @@ TEST(Array, GetElements) { ASSERT_EQ(elements2[0], 1); } -TEST(Array, GetSize) { - const auto size = Array::getSize(); +TEST(Array, GetStaticSize) { + const auto size = Array::getStaticSize(); ASSERT_EQ(size, 3); } diff --git a/Fw/DataStructures/test/ut/ExternalArrayTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayTest.cpp index 93d76644e23..592b2d20437 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayTest.cpp @@ -44,7 +44,7 @@ TEST(ExternalArray, CopyAssignment) { ASSERT_EQ(a1.getSize(), a2.getSize()); } -static void testCopyElementsFrom(ExternalArray a1, ExternalArray a2) { +static void testCopyDataFrom(ExternalArray a1, ExternalArray a2) { const FwSizeType size1 = a1.getSize(); for (FwSizeType i = 0; i < size1; i++) { a1[i] = static_cast(i); @@ -53,23 +53,23 @@ static void testCopyElementsFrom(ExternalArray a1, ExternalArray a2) { for (FwSizeType i = 0; i < size2; i++) { a2[i] = 0; } - a2.copyElementsFrom(a1); + a2.copyDataFrom(a1); const FwSizeType size = FW_MIN(size1, size2); for (FwSizeType i = 0; i < size; i++) { ASSERT_EQ(a2[i], a1[i]); } } -TEST(ExternalArray, CopyElementsFrom) { +TEST(ExternalArray, CopyDataFrom) { constexpr FwSizeType maxSize = 10; U32 elements1[maxSize]; U32 elements2[maxSize]; // size1 < size2 - testCopyElementsFrom(ExternalArray(elements1, 5), ExternalArray(elements2, 10)); + testCopyDataFrom(ExternalArray(elements1, 5), ExternalArray(elements2, 10)); // size1 == size2 - testCopyElementsFrom(ExternalArray(elements1, 10), ExternalArray(elements2, 10)); + testCopyDataFrom(ExternalArray(elements1, 10), ExternalArray(elements2, 10)); // size1 > size2 - testCopyElementsFrom(ExternalArray(elements1, 10), ExternalArray(elements2, 5)); + testCopyDataFrom(ExternalArray(elements1, 10), ExternalArray(elements2, 5)); } TEST(ExternalArray, Subscript) { From 5087712c1bf818457875e4286b860a4d0bd89386 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 20:53:11 -0700 Subject: [PATCH 087/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalFifoQueue.md | 18 ++++---- Fw/DataStructures/docs/FifoQueue.md | 10 ++--- Fw/DataStructures/docs/FifoQueueBase.md | 46 +++++++++++---------- 3 files changed, 39 insertions(+), 35 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index 18188b0d528..b63964f6b9a 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -193,10 +193,10 @@ queue.setStorage(items, capacity); **enqueue:** ```c++ -Fw::Success enqueue(const T& e) override +Success enqueue(const T& e) override ``` -1. Set `status = Fw::Success::FAILURE`. +1. Set `status = Success::FAILURE`. 1. If `m_size < m_capacity` then @@ -217,17 +217,17 @@ U32 items[capacity]; ExternalFifoQueue queue(items, capacity); ASSERT_EQ(queue.getSize(), 0); auto status = queue.enqueue(42); -ASSERT_EQ(status, Fw::Success::SUCCESS); +ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(queue.getSize(), 1); ``` **dequeue:** ```c++ -Fw::Success dequeue(T& e) override +Success dequeue(T& e) override ``` -1. Set `status = Fw::Success::FAILURE`. +1. Set `status = Success::FAILURE`. 1. If `m_size > 0` then @@ -248,11 +248,11 @@ U32 items[capacity]; ExternalFifoQueue queue(items, capacity); U32 val; auto status = queue.dequeue(val); -ASSERT_EQ(status, Fw::Success::FAILURE); +ASSERT_EQ(status, Success::FAILURE); status = queue.enqueue(42); -ASSERT_EQ(status, Fw::Success::SUCCESS); +ASSERT_EQ(status, Success::SUCCESS); status = queue.dequeue(val); -ASSERT_EQ(status, Fw::Success::SUCCESS); +ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(val, 42); ``` @@ -272,7 +272,7 @@ ExternalFifoQueue queue(items, capacity); auto size = queue.getSize(); ASSERT_EQ(size, 0); const auto status = queue.enqueue(3); -ASSERT_EQ(status, Fw::Success::SUCCESS); +ASSERT_EQ(status, Success::SUCCESS); size = queue.getSize(); ASSERT_EQ(size, 1); ``` diff --git a/Fw/DataStructures/docs/FifoQueue.md b/Fw/DataStructures/docs/FifoQueue.md index b5e01bd8794..3c5c5429d5c 100644 --- a/Fw/DataStructures/docs/FifoQueue.md +++ b/Fw/DataStructures/docs/FifoQueue.md @@ -58,12 +58,12 @@ _Example:_ ```c++ FifoQueue q1; auto status = q1.enqueue(3); -ASSERT_EQ(status, Fw::Success::SUCCESS); +ASSERT_EQ(status, Success::SUCCESS); FifoQueue q2; q2 = q1; U32 value = 0; status = q2.dequeue(value); -ASSERT_EQ(status, Fw::Success::SUCCESS); +ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(value, 3); ``` @@ -105,7 +105,7 @@ TODO **enqueue:** ```c++ -Fw::Success enqueue(const T& e) +Success enqueue(const T& e) ``` TODO @@ -113,7 +113,7 @@ TODO **peek:** ```c++ -Fw::Success peek(T& e) +Success peek(T& e) ``` TODO @@ -121,7 +121,7 @@ TODO **dequeue:** ```c++ -Fw::Success dequeue(T& e) +Success dequeue(T& e) ``` TODO diff --git a/Fw/DataStructures/docs/FifoQueueBase.md b/Fw/DataStructures/docs/FifoQueueBase.md index 1844c668b62..e29e663b91e 100644 --- a/Fw/DataStructures/docs/FifoQueueBase.md +++ b/Fw/DataStructures/docs/FifoQueueBase.md @@ -56,9 +56,9 @@ _Example:_ void f(FifoQueueBase& queue) { queue.clear(); auto status = queue.enqueue(10); - ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(status, Success::SUCCESS); auto status = queue.enqueue(11); - ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(queue.at(0), 10); ASSERT_EQ(queue.at(1), 11); // Out-of-bounds access @@ -85,16 +85,20 @@ void f(FifoQueueBase& queue) { ### 3.3. copyDataFrom ```c++ -void copyDataFrom(const FifoQueueBase& queue) override +Success copyDataFrom(const FifoQueueBase& queue) ``` 1. Call `clear()`. +1. Set `status = Success::SUCCESS`. + 1. For `i` from 0 to `queue.getSize() - 1` - 1. Set `const auto status = enqueue(queue.at(i))` + 1. Set `status = enqueue(queue.at(i))`. + + 1. If `status == Success::FAILURE` then break out of the loop. - 1. Assert `status == Fw::Success::SUCCESS`. +1. Return `status`. _Example:_ ```c++ @@ -113,39 +117,39 @@ void f(FifoQueueBase& q1, FifoQueueBase& q2) { ### 3.4. enqueue ```c++ -virtual void Fw::Success enqueue(const T& e) = 0 +virtual void Success enqueue(const T& e) = 0 ``` -1. If there is no room on the queue for a new item, then return `Fw::Success::FAILURE`. +1. If there is no room on the queue for a new item, then return `Success::FAILURE`. 1. Otherwise 1. Enqueue `e`. - 1. Return `Fw::Success::SUCCESS`. + 1. Return `Success::SUCCESS`. _Example:_ ```c++ void f(FifoQueueBase& queue) { queue.clear(); status = queue.enqueue(3); - ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(status, Success::SUCCESS); } ``` ### 3.5. peek ```c++ -void Fw::Success peek(T& e) +void Success peek(T& e) ``` -1. If `getSize() == 0` return `Fw::Success::FAILURE`. +1. If `getSize() == 0` return `Success::FAILURE`. 1. Otherwise 1. Set `e = (*this)[getSize() - 1]`. - 1. Return `Fw::Success::SUCCESS`. + 1. Return `Success::SUCCESS`. _Example:_ ```c++ @@ -153,11 +157,11 @@ void f(FifoQueueBase& queue) { queue.clear(); U32 value = 0; auto status = queue.peek(value); - ASSERT_EQ(status, Fw::Success::FAILURE); + ASSERT_EQ(status, Success::FAILURE); status = queue.enqueue(3); - ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(status, Success::SUCCESS); status = queue.peek(value); - ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(value, 3); } ``` @@ -165,12 +169,12 @@ void f(FifoQueueBase& queue) { ### 3.6. dequeue ```c++ -virtual void Fw::Success dequeue(T& e) = 0 +virtual void Success dequeue(T& e) = 0 ``` 1. Set `status = peek(e)`. -1. If `status == Fw::Success::SUCCESS` then dequeue an item and store it into +1. If `status == Success::SUCCESS` then dequeue an item and store it into `e`. 1. Return `status`. @@ -181,11 +185,11 @@ void f(FifoQueueBase& queue) { queue.clear(); U32 val = 0; auto status = queue.dequeue(val); - ASSERT_EQ(status, Fw::Success::FAILURE); + ASSERT_EQ(status, Success::FAILURE); status = queue.enqueue(3); - ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(status, Success::SUCCESS); status = queue.dequeue(val); - ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(val, 3); } ``` @@ -205,7 +209,7 @@ void f(const FifoQueueBase& queue) { auto size = queue.getSize(); ASSERT_EQ(size, 0); const auto status = queue.enqueue(3); - ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(status, Success::SUCCESS); size = queue.getSize(); ASSERT_EQ(size, 1); } From 122bf31c2a5cb89015a345cbf1815a1dd59c2ce8 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 20:56:42 -0700 Subject: [PATCH 088/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalFifoQueue.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index b63964f6b9a..bede096a620 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -42,7 +42,7 @@ Initialize the member variables with their default values. _Example:_ ```c++ -ExternalFifoQueue() +ExternalFifoQueue queue; ``` **Constructor providing backing storage:** @@ -59,7 +59,7 @@ _Example:_ ```c++ constexpr FwSizeType capacity = 10; U32 items[capacity]; -ExternalFifoQueue queue(items, capacity); +ExternalFifoQueue queue(items, capacity); ``` **Copy constructor:** From 87dd447ff9e94127e712e62dbb0e8479d9a8cf9f Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 21:03:02 -0700 Subject: [PATCH 089/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalFifoQueue.md | 35 ++++++++++++--------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index bede096a620..7987e6e5fb6 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -32,7 +32,7 @@ storing the items on the queue. ## 4. Public Constructors and Destructors -**Zero-argument constructor:** +### 4.1. Zero-Argument Constructor ```c++ ExternalFifoQueue() @@ -45,13 +45,13 @@ _Example:_ ExternalFifoQueue queue; ``` -**Constructor providing backing storage:** +### 4.2. Constructor Providing Backing Storage ```c++ ExternalFifoQueue(T* items, FwSizeType capacity) ``` -1. Initialize `m_items` with `ExternalArray(items, capacity)`. +1. Call `m_items.setStorage(items, capacity)`. 1. Initialize the other member variables with their default values. @@ -62,7 +62,7 @@ U32 items[capacity]; ExternalFifoQueue queue(items, capacity); ``` -**Copy constructor:** +### 4.3. Copy Constructor ```c++ ExternalFifoQueue(const ExternalFifoQueue& queue) @@ -84,7 +84,7 @@ ExternalFifoQueue q2(q1); ASSERT_EQ(q2.getSize(), 1); ``` -**Destructor:** +### 4.4. Destructor ```c++ ~ExternalFifoQueue() override @@ -94,7 +94,7 @@ Defined as `= default`. ## 5. Public Member Functions -**Copy assignment operator:** +### 5.1. operator= ```c++ ExternalFifoQueue& operator=(const ExternalFifoQueue& queue) @@ -129,7 +129,7 @@ q2 = q1; ASSERT_EQ(q2.getSize(), 1); ``` -**at:** +### 5.2. at ```c++ const T& at(FwSizeType i) const override @@ -151,7 +151,7 @@ ASSERT_EQ(queue.at(0), 3); ASSERT_DEATH(queue.at(1), "Assert"); ``` -**clear:** +### 5.3. clear ```c++ void clear() override @@ -174,7 +174,7 @@ queue.clear(); ASSERT_EQ(queue.getSize(), 0); ``` -**setStorage:** +### 5.4. setStorage ```c++ void setStorage(T* items, FwSizeType size) @@ -190,7 +190,7 @@ U32 items[capacity]; queue.setStorage(items, capacity); ``` -**enqueue:** +### 5.5. enqueue ```c++ Success enqueue(const T& e) override @@ -221,7 +221,7 @@ ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(queue.getSize(), 1); ``` -**dequeue:** +### 5.6. dequeue ```c++ Success dequeue(T& e) override @@ -256,7 +256,7 @@ ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(val, 42); ``` -**getSize:** +### 5.7. getSize ```c++ FwSizeType getSize() const override @@ -277,11 +277,18 @@ size = queue.getSize(); ASSERT_EQ(size, 1); ``` -**getCapacity:** +### 5.8. getCapacity ```c++ FwSizeType getCapacity() const override ``` -TODO +Return `m_items.getSize()`. +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +U32 items[capacity]; +ExternalFifoQueue queue(items, capacity); +ASSERT_EQ(queue.getCapacity(), capacity); +``` From bbe7ea341dd856e4ded915b2d019ea9ef3e6ceaf Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 21:13:34 -0700 Subject: [PATCH 090/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/CircularIndex.md | 49 ++++++++++++++++----- Fw/DataStructures/docs/ExternalFifoQueue.md | 4 +- 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/Fw/DataStructures/docs/CircularIndex.md b/Fw/DataStructures/docs/CircularIndex.md index 0e22ea8be28..4324d6faabd 100644 --- a/Fw/DataStructures/docs/CircularIndex.md +++ b/Fw/DataStructures/docs/CircularIndex.md @@ -1,6 +1,7 @@ # 1. CircularIndex -`CircularIndex` represents an index value that +`CircularIndex` is a `final` class. +It represents an index value that wraps around modulo an integer. ## 1. Private Member Variables @@ -14,15 +15,15 @@ wraps around modulo an integer. ## 2. Public Constructors and Destructors -**Zero-argument constructor:** +### 2.1. Zero-Argument Constructor ```c++ CircularIndex() ``` -Initialize the member variables with their default values. +Defined as `= default`. -**Constructor with specified members:** +### 2.2. Constructor with Specified Members ```c++ CircularIndex(FwSizeType modulus, FwSizeType value = 0) @@ -34,9 +35,37 @@ CircularIndex(FwSizeType modulus, FwSizeType value = 0) 1. Call `setValue(value)`. +### 2.3. Copy Constructor + +```c++ +CircularIndex(const CircularIndex& ci) +``` + +Set `*this = ci`. + +### 2.4. Destructor + +```c++ +~CircularIndex() +``` + +Defined as `= default`. + ## 3. Public Member Functions -**getValue:** +### 3.1. operator= + +```c++ +CircularIndex& operator=(const CircularIndex& ci) +``` + +1. Set `m_value = ci.m_value`. + +1. Set `m_modulus = ci.m_modulus`. + +1. Return `*this`. + +### 3.2. getValue ```c++ FwSizeType getValue() const @@ -46,7 +75,7 @@ FwSizeType getValue() const 1. Return `m_value`. -**setValue:** +### 3.3. setValue ```c++ void setValue(FwSizeType value) @@ -54,7 +83,7 @@ void setValue(FwSizeType value) Set `m_value = m_value % m_modulus`. -**getModulus:** +### 3.4. getModulus ```c++ FwSizeType CircularIndex::getModulus() const @@ -64,7 +93,7 @@ FwSizeType CircularIndex::getModulus() const 1. Return `m_modulus`. -**setModulus:** +### 3.5. setModulus ```c++ void setModulus(FwSizeType modulus) @@ -74,7 +103,7 @@ void setModulus(FwSizeType modulus) 2. Call `setValue(m_value)`. -**increment:** +### 3.6. increment ```c++ FwSizeType increment(FwSizeType amount = 1) @@ -86,7 +115,7 @@ FwSizeType increment(FwSizeType amount = 1) 1. Return `m_value`. -**decrement:** +### 3.7. decrement ```c++ FwSizeType decrement(FwSizeType amount = 1) diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index 7987e6e5fb6..08c10dcd871 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -137,7 +137,9 @@ const T& at(FwSizeType i) const override 1. Assert that `i < m_size`. -1. Return `m_items[(m_enqueueIndex + i) % m_items.size()]`. +1. Set `ci = m_enqueueIndex.increment(i)`. + +1. Return `m_items[ci]`. _Example:_ ```c++ From 8d61107f370956d43b7414daad11febb020d780f Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 21:15:21 -0700 Subject: [PATCH 091/458] Revise SDD for CircularIndex --- Fw/DataStructures/docs/CircularIndex.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/CircularIndex.md b/Fw/DataStructures/docs/CircularIndex.md index 4324d6faabd..01640d79b33 100644 --- a/Fw/DataStructures/docs/CircularIndex.md +++ b/Fw/DataStructures/docs/CircularIndex.md @@ -1,4 +1,4 @@ -# 1. CircularIndex +# CircularIndex `CircularIndex` is a `final` class. It represents an index value that From f4171dc1649a1f16aac10929ac4d46f7fb92fe1c Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 21:16:10 -0700 Subject: [PATCH 092/458] Revise SDD for CircularIndex --- Fw/DataStructures/docs/CircularIndex.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/CircularIndex.md b/Fw/DataStructures/docs/CircularIndex.md index 01640d79b33..421a4c47a3c 100644 --- a/Fw/DataStructures/docs/CircularIndex.md +++ b/Fw/DataStructures/docs/CircularIndex.md @@ -1,6 +1,7 @@ # CircularIndex -`CircularIndex` is a `final` class. +`CircularIndex` is a `final` class defined in +[`Fw/DataStructures`](sdd.md). It represents an index value that wraps around modulo an integer. From baff0bc66ec5f747aad2f516476c787dd480e38a Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 2 Jun 2025 21:49:51 -0700 Subject: [PATCH 093/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/Array.md | 2 +- Fw/DataStructures/docs/ExternalFifoQueue.md | 2 +- Fw/DataStructures/docs/FifoQueue.md | 100 +++++++++++++------- 3 files changed, 68 insertions(+), 36 deletions(-) diff --git a/Fw/DataStructures/docs/Array.md b/Fw/DataStructures/docs/Array.md index 7316161bb7b..323ad7bec41 100644 --- a/Fw/DataStructures/docs/Array.md +++ b/Fw/DataStructures/docs/Array.md @@ -50,7 +50,7 @@ Array a; Array(const std::initializer_list& il) ``` -1. Assert that `il.m_size == S`. +1. Assert that `il.size() == S`. 1. Initialize `m_elements` from `il`. diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index 08c10dcd871..01d0e489756 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -38,7 +38,7 @@ storing the items on the queue. ExternalFifoQueue() ``` -Initialize the member variables with their default values. +Initialize each member variable with its default value. _Example:_ ```c++ diff --git a/Fw/DataStructures/docs/FifoQueue.md b/Fw/DataStructures/docs/FifoQueue.md index 3c5c5429d5c..dd2e7b3d09f 100644 --- a/Fw/DataStructures/docs/FifoQueue.md +++ b/Fw/DataStructures/docs/FifoQueue.md @@ -3,7 +3,7 @@ `FifoQueue` is a `final` class template defined in [`Fw/DataStructures`](sdd.md). It represents a FIFO queue with internal storage. -Internally it maintains an `Array` +Internally it maintains an [`Array`](Array.md) for storing the items on the queue. ## 1. Template Parameters @@ -33,120 +33,152 @@ for storing the items on the queue. ## 4. Public Constructors and Destructors -**Zero-argument constructor:** +### 4.1. Zero-Argument Constructor ```c++ FifoQueue() ``` -Initialize each member with default initialization. +Initialize each member variable with its default value. _Example:_ ```c++ FifoQueue queue; ``` -**Copy constructor:** +### 4.2. Copy Constructor ```c++ FifoQueue(const FifoQueue& queue) ``` -Call `m_extQueue.copyItemsFrom(queue.m_extQueue)`. +Set `*this = queue`. _Example:_ ```c++ FifoQueue q1; auto status = q1.enqueue(3); ASSERT_EQ(status, Success::SUCCESS); -FifoQueue q2; -q2 = q1; +FifoQueue q2(q1); +ASSERT_EQ(q2.size(), 1); U32 value = 0; status = q2.dequeue(value); ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(value, 3); ``` -**Destructor:** +### 4.3. Destructor ```c++ -~FifoQueue() +~FifoQueue() override ``` Defined as `= default`. ## 5. Public Member Functions -**operator[]:** +### 5.1. at ```c++ -T& operator[](FwSizeType i) -const T& operator[](FwSizeType i) const +const T& operator[](FwSizeType i) const override ``` -TODO +Return `m_extQueue(i)`. -**Copy assignment operator:** +### 5.2. operator= ```c++ FifoQueue& operator=(const FifoQueue& queue) ``` -TODO +1. Set `status = m_extQueue.copyDataFrom(queue.m_extQueue)`. -**clear:** +1. Assert `status == Success::SUCCESS`. +_Example:_ ```c++ -void clear() +FifoQueue q1; +auto status = q1.enqueue(3); +ASSERT_EQ(status, Success::SUCCESS); +FifoQueue q2; +ASSERT_EQ(q2.size(), 0); +q2 = q1; +ASSERT_EQ(q2.size(), 1); +U32 value = 0; +status = q2.dequeue(value); +ASSERT_EQ(status, Success::SUCCESS); +ASSERT_EQ(value, 3); ``` -TODO - -**enqueue:** +### 5.3. clear ```c++ -Success enqueue(const T& e) +void clear() override ``` -TODO +Call `m_extQueue.clear()`. -**peek:** +### 5.4. enqueue ```c++ -Success peek(T& e) +Success enqueue(const T& e) override ``` -TODO +Return `m_extQueue.enqueue(e)`. -**dequeue:** +### 5.5. dequeue ```c++ -Success dequeue(T& e) +Success dequeue(T& e) override ``` -TODO +Return `m_extQueue.dequeue(e)`. -**getSize:** +### 5.6. getSize ```c++ FwSizeType getSize() const ``` -TODO +Return `m_extQueue.getSize()`. -**getCapacity:** +### 5.7. getCapacity ```c++ FwSizeType getCapacity() const ``` -TODO +Return `m_extQueue.getCapacity()`. -**asExternalFifoQueue:** +### 5.8. asExternalFifoQueue ```c++ ExternalFifoQueue asExternalFifoQueue() ``` -TODO +Return [`ExternalFifoQueue(m_items, C)`](ExternalFifoQueue.md#4-public-constructors-and-destructors) +_Example:_ +```c++ +constexpr FwSizeType size = 3; +FifoQueue queue; +(void) queue.enqueue(3); +ExternalFifoQueue extQueue = queue.asExternalFifoQueue(); +ASSERT_EQ(extQueue.size(), 1); +``` + +## 6. Public Static Functions + +### 6.1. getStaticCapacity + +```c++ +static constexpr FwSizeType getStaticCapacity() +``` + +Return the static capacity `C`. + +_Example:_ +```c++ +const auto capacity = FifoQueue::getStaticCapacity(); +ASSERT_EQ(capacity, 3); +``` From a77413709ca0632b4e64a51b434726f5c07d5dca Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 3 Jun 2025 08:11:34 -0700 Subject: [PATCH 094/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/FifoQueueBase.md | 46 ++++++++++++++++--------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/Fw/DataStructures/docs/FifoQueueBase.md b/Fw/DataStructures/docs/FifoQueueBase.md index e29e663b91e..a4dc433861b 100644 --- a/Fw/DataStructures/docs/FifoQueueBase.md +++ b/Fw/DataStructures/docs/FifoQueueBase.md @@ -12,25 +12,27 @@ It represents an abstract base class for a FIFO queue. |----|----|-------| |`typename`|`T`|The type of an item on the queue| -## 2. Protected Constructors and Destructors +## 2. Private Constructors -### 2.1. Zero-argument Constructor +### 2.1. Copy Constructor ```c++ -FifoQueueBase() +FifoQueueBase(const FifoQueueBase& queue) ``` -Defined as `= default`. +Defined as `= delete`. -### 2.2. Copy Constructor +## 3. Protected Constructors and Destructors + +### 3.1. Zero-argument Constructor ```c++ -FifoQueueBase(const FifoQueueBase& queue) +FifoQueueBase() ``` -Defined as `= delete`. +Defined as `= default`. -### 2.3. Destructor +### 3.2. Destructor ```c++ virtual FifoQueueBase() @@ -38,9 +40,19 @@ virtual FifoQueueBase() Defined as `= default`. -## 3. Public Member Functions +## 4. Private Member Functions + +### 4.1. operator= + +```c++ +FifoQueueBase& operator=(const FifoQueueBase&) +``` + +Defined as `= delete`. + +## 5. Public Member Functions -### 3.1. at +### 5.1. at ```c++ virtual const T& at(FwSizeType i) const = 0 @@ -66,7 +78,7 @@ void f(FifoQueueBase& queue) { } ``` -### 3.2. clear +### 5.2. clear ```c++ virtual void clear() = 0 @@ -82,7 +94,7 @@ void f(FifoQueueBase& queue) { } ``` -### 3.3. copyDataFrom +### 5.3. copyDataFrom ```c++ Success copyDataFrom(const FifoQueueBase& queue) @@ -114,7 +126,7 @@ void f(FifoQueueBase& q1, FifoQueueBase& q2) { } ``` -### 3.4. enqueue +### 5.4. enqueue ```c++ virtual void Success enqueue(const T& e) = 0 @@ -137,7 +149,7 @@ void f(FifoQueueBase& queue) { } ``` -### 3.5. peek +### 5.5. peek ```c++ void Success peek(T& e) @@ -166,7 +178,7 @@ void f(FifoQueueBase& queue) { } ``` -### 3.6. dequeue +### 5.6. dequeue ```c++ virtual void Success dequeue(T& e) = 0 @@ -194,7 +206,7 @@ void f(FifoQueueBase& queue) { } ``` -### 3.7. getSize +### 5.7. getSize ```c++ virtual void FwSizeType getSize() const = 0 @@ -215,7 +227,7 @@ void f(const FifoQueueBase& queue) { } ``` -### 3.8. getCapacity +### 5.8. getCapacity ```c++ virtual FwSizeType getCapacity() const = 0 From 8d3bc2b954f0df9346f308ed2225224b2f6fbf0f Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 3 Jun 2025 08:17:29 -0700 Subject: [PATCH 095/458] Revise FifoQueueBase --- Fw/DataStructures/docs/FifoQueueBase.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/Fw/DataStructures/docs/FifoQueueBase.md b/Fw/DataStructures/docs/FifoQueueBase.md index a4dc433861b..363d39b35fe 100644 --- a/Fw/DataStructures/docs/FifoQueueBase.md +++ b/Fw/DataStructures/docs/FifoQueueBase.md @@ -100,15 +100,19 @@ void f(FifoQueueBase& queue) { Success copyDataFrom(const FifoQueueBase& queue) ``` -1. Call `clear()`. +1. Set `status = Success::FAILURE`. -1. Set `status = Success::SUCCESS`. +1. If `getCapacity() <= queue.getSize()` -1. For `i` from 0 to `queue.getSize() - 1` + 1. Call `clear()`. - 1. Set `status = enqueue(queue.at(i))`. + 1. For `i` from 0 to `queue.getSize() - 1` - 1. If `status == Success::FAILURE` then break out of the loop. + 1. Set `enqueueStatus = enqueue(queue.at(i))`. + + 1. Assert `enqueueStatus == Success::SUCCESS` + + 1. Set `status = Success::SUCCESS`. 1. Return `status`. From 018d88087acce1e5974be6f48843de9761b9c96b Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 3 Jun 2025 08:31:34 -0700 Subject: [PATCH 096/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/FifoQueueBase.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/FifoQueueBase.md b/Fw/DataStructures/docs/FifoQueueBase.md index 363d39b35fe..cb2b7b0b3df 100644 --- a/Fw/DataStructures/docs/FifoQueueBase.md +++ b/Fw/DataStructures/docs/FifoQueueBase.md @@ -106,7 +106,7 @@ Success copyDataFrom(const FifoQueueBase& queue) 1. Call `clear()`. - 1. For `i` from 0 to `queue.getSize() - 1` + 1. For `i` in [0, `queue.getSize()`) 1. Set `enqueueStatus = enqueue(queue.at(i))`. From 2101eef61f825af099718b429b27431682804a1d Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 3 Jun 2025 08:33:43 -0700 Subject: [PATCH 097/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/Map.md | 4 ---- Fw/DataStructures/docs/MapBase.md | 4 ++++ Fw/DataStructures/docs/Set.md | 4 ---- Fw/DataStructures/docs/SetBase.md | 4 ++++ Fw/DataStructures/docs/sdd.md | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) delete mode 100644 Fw/DataStructures/docs/Map.md create mode 100644 Fw/DataStructures/docs/MapBase.md delete mode 100644 Fw/DataStructures/docs/Set.md create mode 100644 Fw/DataStructures/docs/SetBase.md diff --git a/Fw/DataStructures/docs/Map.md b/Fw/DataStructures/docs/Map.md deleted file mode 100644 index aad6158a15d..00000000000 --- a/Fw/DataStructures/docs/Map.md +++ /dev/null @@ -1,4 +0,0 @@ -# Map - -TODO - diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md new file mode 100644 index 00000000000..a8ec974c155 --- /dev/null +++ b/Fw/DataStructures/docs/MapBase.md @@ -0,0 +1,4 @@ +# MapBase + +TODO + diff --git a/Fw/DataStructures/docs/Set.md b/Fw/DataStructures/docs/Set.md deleted file mode 100644 index bc4d5bd8f8f..00000000000 --- a/Fw/DataStructures/docs/Set.md +++ /dev/null @@ -1,4 +0,0 @@ -# Set - -TODO - diff --git a/Fw/DataStructures/docs/SetBase.md b/Fw/DataStructures/docs/SetBase.md new file mode 100644 index 00000000000..d6cbecb392d --- /dev/null +++ b/Fw/DataStructures/docs/SetBase.md @@ -0,0 +1,4 @@ +# SetBase + +TODO + diff --git a/Fw/DataStructures/docs/sdd.md b/Fw/DataStructures/docs/sdd.md index d127122d982..1500ee64f7a 100644 --- a/Fw/DataStructures/docs/sdd.md +++ b/Fw/DataStructures/docs/sdd.md @@ -46,7 +46,7 @@ first in first out (FIFO) order. ## 3. Maps -* [`Map`](Map.md) +* [`MapBase`](MapBase.md) * [`ExternalArrayMap`](ExternalArrayMap.md) @@ -58,7 +58,7 @@ first in first out (FIFO) order. ## 4. Sets -* [`Set`](Set.md) +* [`SetBase`](SetBase.md) * [`ExternalArraySet`](ExternalArraySet.md) From f29927cab42bd7bebd95ad24090234b2bad1c6b6 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 3 Jun 2025 08:40:01 -0700 Subject: [PATCH 098/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalArray.md | 4 ++-- Fw/DataStructures/docs/FifoQueueBase.md | 14 +++++--------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArray.md b/Fw/DataStructures/docs/ExternalArray.md index 8fc6a68b2ef..a4126a84144 100644 --- a/Fw/DataStructures/docs/ExternalArray.md +++ b/Fw/DataStructures/docs/ExternalArray.md @@ -137,9 +137,9 @@ void copyDataFrom(const ExternalArray& a) 1. Otherwise - 1. Let `size` be the minimum of `this->m_size` and `a.m_size` + 1. Let `size` be the minimum of `m_size` and `a.m_size` - 1. For each `i` from 0 through `size - 1`, set `m_elements[i] = a.m_elements[i]` + 1. For each `i` in [0, `size), set `m_elements[i] = a.m_elements[i]` _Example:_ ```c++ diff --git a/Fw/DataStructures/docs/FifoQueueBase.md b/Fw/DataStructures/docs/FifoQueueBase.md index cb2b7b0b3df..9971cdfef35 100644 --- a/Fw/DataStructures/docs/FifoQueueBase.md +++ b/Fw/DataStructures/docs/FifoQueueBase.md @@ -97,25 +97,21 @@ void f(FifoQueueBase& queue) { ### 5.3. copyDataFrom ```c++ -Success copyDataFrom(const FifoQueueBase& queue) +void copyDataFrom(const FifoQueueBase& queue) ``` -1. Set `status = Success::FAILURE`. +1. If `&queue == this` then do nothing. -1. If `getCapacity() <= queue.getSize()` +1. Otherwise - 1. Call `clear()`. + 1. Let `size` be the minimum of `queue.getSize()` and `getCapacity()`. - 1. For `i` in [0, `queue.getSize()`) + 1. For `i` in [0, `size`) 1. Set `enqueueStatus = enqueue(queue.at(i))`. 1. Assert `enqueueStatus == Success::SUCCESS` - 1. Set `status = Success::SUCCESS`. - -1. Return `status`. - _Example:_ ```c++ void f(FifoQueueBase& q1, FifoQueueBase& q2) { From 4a4c2995f33865d014d24455885e31079f4766aa Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 3 Jun 2025 08:45:51 -0700 Subject: [PATCH 099/458] Revise FifoQueueBase --- Fw/DataStructures/docs/FifoQueueBase.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Fw/DataStructures/docs/FifoQueueBase.md b/Fw/DataStructures/docs/FifoQueueBase.md index 9971cdfef35..c9800c30aa3 100644 --- a/Fw/DataStructures/docs/FifoQueueBase.md +++ b/Fw/DataStructures/docs/FifoQueueBase.md @@ -65,7 +65,7 @@ Index 0 is the first element inserted in the queue. _Example:_ ```c++ -void f(FifoQueueBase& queue) { +void f(FifoQueueBase& queue) { queue.clear(); auto status = queue.enqueue(10); ASSERT_EQ(status, Success::SUCCESS); @@ -88,7 +88,7 @@ Clear the queue. _Example:_ ```c++ -void f(FifoQueueBase& queue) { +void f(FifoQueueBase& queue) { queue.clear(); ASSERT_EQ(queue.getSize(), 0); } @@ -110,7 +110,7 @@ void copyDataFrom(const FifoQueueBase& queue) 1. Set `enqueueStatus = enqueue(queue.at(i))`. - 1. Assert `enqueueStatus == Success::SUCCESS` + 1. Assert `enqueueStatus == Success::SUCCESS`. _Example:_ ```c++ @@ -142,7 +142,7 @@ virtual void Success enqueue(const T& e) = 0 _Example:_ ```c++ -void f(FifoQueueBase& queue) { +void f(FifoQueueBase& queue) { queue.clear(); status = queue.enqueue(3); ASSERT_EQ(status, Success::SUCCESS); @@ -216,7 +216,7 @@ Return the current size. _Example:_ ```c++ -void f(const FifoQueueBase& queue) { +void f(const FifoQueueBase& queue) { queue.clear(); auto size = queue.getSize(); ASSERT_EQ(size, 0); @@ -237,7 +237,7 @@ Return the current capacity. _Example:_ ```c++ -void f(const FifoQueueBase& queue) { +void f(const FifoQueueBase& queue) { const auto size = queue.getSize(); const auto capacity = queue.getCapacity(); ASSERT_LE(size, capacity); From a9549b349049824aa0cb97d46d0a9e5861abe885 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 3 Jun 2025 08:48:59 -0700 Subject: [PATCH 100/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/FifoQueueBase.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Fw/DataStructures/docs/FifoQueueBase.md b/Fw/DataStructures/docs/FifoQueueBase.md index c9800c30aa3..bd6a0657b33 100644 --- a/Fw/DataStructures/docs/FifoQueueBase.md +++ b/Fw/DataStructures/docs/FifoQueueBase.md @@ -24,7 +24,7 @@ Defined as `= delete`. ## 3. Protected Constructors and Destructors -### 3.1. Zero-argument Constructor +### 3.1. Zero-Argument Constructor ```c++ FifoQueueBase() @@ -186,8 +186,7 @@ virtual void Success dequeue(T& e) = 0 1. Set `status = peek(e)`. -1. If `status == Success::SUCCESS` then dequeue an item and store it into - `e`. +1. If `status == Success::SUCCESS` then dequeue the last-inserted item. 1. Return `status`. From b4b30b46e995378516a9d06532b40b0a8427f073 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 3 Jun 2025 16:57:26 -0700 Subject: [PATCH 101/458] Revise Fw/DataStructures --- Fw/DataStructures/Array.hpp | 2 +- Fw/DataStructures/ExternalArray.hpp | 3 +- Fw/DataStructures/FifoQueueBase.hpp | 104 ++++++++++++++++++++++++ Fw/DataStructures/docs/FifoQueueBase.md | 24 +++--- 4 files changed, 120 insertions(+), 13 deletions(-) create mode 100644 Fw/DataStructures/FifoQueueBase.hpp diff --git a/Fw/DataStructures/Array.hpp b/Fw/DataStructures/Array.hpp index 5f3ec5b2059..0aef69efd41 100644 --- a/Fw/DataStructures/Array.hpp +++ b/Fw/DataStructures/Array.hpp @@ -7,10 +7,10 @@ #ifndef Fw_Array_HPP #define Fw_Array_HPP -#include #include #include "Fw/DataStructures/ExternalArray.hpp" +#include "Fw/FPrimeBasicTypes.hpp" #include "Fw/Types/Assert.hpp" namespace Fw { diff --git a/Fw/DataStructures/ExternalArray.hpp b/Fw/DataStructures/ExternalArray.hpp index 995c6c4b5fb..3d96db28020 100644 --- a/Fw/DataStructures/ExternalArray.hpp +++ b/Fw/DataStructures/ExternalArray.hpp @@ -7,8 +7,7 @@ #ifndef Fw_ExternalArray_HPP #define Fw_ExternalArray_HPP -#include - +#include "Fw/FPrimeBasicTypes.hpp" #include "Fw/Types/Assert.hpp" namespace Fw { diff --git a/Fw/DataStructures/FifoQueueBase.hpp b/Fw/DataStructures/FifoQueueBase.hpp new file mode 100644 index 00000000000..57da3cec375 --- /dev/null +++ b/Fw/DataStructures/FifoQueueBase.hpp @@ -0,0 +1,104 @@ +// ====================================================================== +// \title FifoQueueBase +// \author bocchino +// \brief An abstract base class for a FIFO queue +// ====================================================================== + +#ifndef Fw_FifoQueueBase_HPP +#define Fw_FifoQueueBase_HPP + +#include "Fw/FPrimeBasicTypes.hpp" +#include "Fw/Types/Assert.hpp" +#include "Fw/Types/SuccessEnumAc.hpp" + +namespace Fw { + +template +class FifoQueueBase { + private: + // ---------------------------------------------------------------------- + // Private constructors + // ---------------------------------------------------------------------- + + //! Deleted copy constructor + FifoQueueBase(const FifoQueueBase&) = delete; + + protected: + // ---------------------------------------------------------------------- + // Protected constructors and destructors + // ---------------------------------------------------------------------- + + //! Zero-argument constructor + FifoQueueBase() = default; + + //! Destructor + virtual ~FifoQueueBase() = default; + + private: + // ---------------------------------------------------------------------- + // Private member functions + // ---------------------------------------------------------------------- + + //! Deleted operator= + FifoQueueBase& operator=(const FifoQueueBase&) = delete; + + public: + // ---------------------------------------------------------------------- + // Public member functions + // ---------------------------------------------------------------------- + + //! Get the element at a specified index + //! \return The element at index i + virtual const T& at(FwSizeType i //!< The index + ) const = 0; + + //! Clear the queue + virtual void clear() = 0; + + //! Copy data from another queue + void copyDataFrom(const FifoQueueBase& queue) { + if (&queue != this) { + this->clear(); + const FwSizeType size = FW_MIN(queue.getSize(), this->getCapacity()); + for (FwSizeType i = 0; i < size; i++) { + const auto status = this->enqueue(queue.at(i)); + FW_ASSERT(status == Fw::Success::SUCCESS, static_cast(status)); + } + } + } + + //! Enqueue an element + //! \return SUCCESS if element enqueued + virtual Success enqueue(const T& e //!< The element + ) = 0; + + //! Peek an element + //! \return SUCCESS if element exists + Success peek(T& e //!< The element + ) const { + auto status = Success::FAILURE; + auto size = this->getSize(); + if (size > 0) { + e = this->at(size - 1); + status = Success::SUCCESS; + } + return status; + } + + //! Dequeue an element + //! \return SUCCESS if element dequeued + virtual Success dequeue(T& e //!< The element + ) = 0; + + //! Get the size (number of items stored in the queue) + //! \return The size + virtual FwSizeType getSize() const = 0; + + //! Get the capacity (maximum number of items stored in the queue) + //! \return The capacity + virtual FwSizeType getCapacity() const = 0; +}; + +} // namespace Fw + +#endif diff --git a/Fw/DataStructures/docs/FifoQueueBase.md b/Fw/DataStructures/docs/FifoQueueBase.md index bd6a0657b33..ffd4cd708cf 100644 --- a/Fw/DataStructures/docs/FifoQueueBase.md +++ b/Fw/DataStructures/docs/FifoQueueBase.md @@ -104,13 +104,15 @@ void copyDataFrom(const FifoQueueBase& queue) 1. Otherwise + 1. Call `clear()`. + 1. Let `size` be the minimum of `queue.getSize()` and `getCapacity()`. 1. For `i` in [0, `size`) - 1. Set `enqueueStatus = enqueue(queue.at(i))`. + 1. Set `status = enqueue(queue.at(i))`. - 1. Assert `enqueueStatus == Success::SUCCESS`. + 1. Assert `status == Success::SUCCESS`. _Example:_ ```c++ @@ -129,7 +131,7 @@ void f(FifoQueueBase& q1, FifoQueueBase& q2) { ### 5.4. enqueue ```c++ -virtual void Success enqueue(const T& e) = 0 +virtual Success enqueue(const T& e) = 0 ``` 1. If there is no room on the queue for a new item, then return `Success::FAILURE`. @@ -152,16 +154,18 @@ void f(FifoQueueBase& queue) { ### 5.5. peek ```c++ -void Success peek(T& e) +void Success peek(T& e) const ``` -1. If `getSize() == 0` return `Success::FAILURE`. +1. Set `status = Success::FAILURE`. -1. Otherwise +1. If `getSize() > 0` - 1. Set `e = (*this)[getSize() - 1]`. + 1. Set `e = at(getSize() - 1)`. - 1. Return `Success::SUCCESS`. + 1. Set `status = Success::SUCCESS`. + +1. Return `status`. _Example:_ ```c++ @@ -181,7 +185,7 @@ void f(FifoQueueBase& queue) { ### 5.6. dequeue ```c++ -virtual void Success dequeue(T& e) = 0 +virtual Success dequeue(T& e) = 0 ``` 1. Set `status = peek(e)`. @@ -208,7 +212,7 @@ void f(FifoQueueBase& queue) { ### 5.7. getSize ```c++ -virtual void FwSizeType getSize() const = 0 +virtual FwSizeType getSize() const = 0 ``` Return the current size. From 78d8776a19c1dcaa0969a4ada0cec161f3f1be40 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 3 Jun 2025 17:19:38 -0700 Subject: [PATCH 102/458] Revise Fw/DataStructures --- Fw/DataStructures/Array.hpp | 2 +- Fw/DataStructures/CircularIndex.hpp | 105 ++++++++++++++++++++++++ Fw/DataStructures/ExternalArray.hpp | 6 +- Fw/DataStructures/docs/CircularIndex.md | 8 +- 4 files changed, 116 insertions(+), 5 deletions(-) create mode 100644 Fw/DataStructures/CircularIndex.hpp diff --git a/Fw/DataStructures/Array.hpp b/Fw/DataStructures/Array.hpp index 0aef69efd41..7a749d0e9d4 100644 --- a/Fw/DataStructures/Array.hpp +++ b/Fw/DataStructures/Array.hpp @@ -1,5 +1,5 @@ // ====================================================================== -// \title Array +// \file Array.hpp // \author bocchino // \brief A statically-sized, bounds checked array // ====================================================================== diff --git a/Fw/DataStructures/CircularIndex.hpp b/Fw/DataStructures/CircularIndex.hpp new file mode 100644 index 00000000000..9edaeab349e --- /dev/null +++ b/Fw/DataStructures/CircularIndex.hpp @@ -0,0 +1,105 @@ +// ====================================================================== +// \file CircularIndex.hpp +// \author bocchino +// \brief An index value that wraps around modulo an integer +// ====================================================================== + +#ifndef Fw_CircularIndex_HPP +#define Fw_CircularIndex_HPP + +#include "Fw/FPrimeBasicTypes.hpp" +#include "Fw/Types/Assert.hpp" + +namespace Fw { + +class CircularIndex final { + public: + // ---------------------------------------------------------------------- + // Public constructors and destructors + // ---------------------------------------------------------------------- + + //! Zero-argument constructor + CircularIndex() : m_value(0), m_modulus(1) {} + + //! Constructor with specified members + CircularIndex(const FwSizeType modulus, //!< The modulus + const FwSizeType value = 0 //!< The initial value + ) + : m_modulus(modulus) { + FW_ASSERT(modulus > 0); + this->setValue(value); + } + + //! Copy constructor + CircularIndex(const CircularIndex& ci) { *this = ci; } + + //! Destructor + ~CircularIndex() = default; + + public: + // ---------------------------------------------------------------------- + // Public functions + // ---------------------------------------------------------------------- + + //! Get the index value + //! \return The index value + FwSizeType getValue() const { + FW_ASSERT(this->m_value < this->m_modulus); + return this->m_value; + } + + //! Set the index value + void setValue(const FwSizeType value //!< The index value + ) { + FW_ASSERT(this->m_modulus > 0); + this->m_value = value % this->m_modulus; + } + + //! Get the modulus + FwSizeType getModulus() const { + FW_ASSERT(this->m_value < this->m_modulus); + return this->m_modulus; + } + + //! Set the modulus + void setModulus(const FwSizeType modulus //!< The modulus value + ) { + this->m_modulus = modulus; + this->setValue(this->m_value); + } + + //! Increment the index value + //! \return The new value + FwSizeType increment(const FwSizeType amount = 1 //!< The amount by which to increment + ) { + FW_ASSERT(this->m_modulus > 0); + const FwSizeType offset = amount % m_modulus; + this->setValue(this->m_value + offset); + return this->m_value; + } + + //! Decrement the index value + //! \return The new value + FwSizeType decrement(const FwSizeType amount = 1 //!< The amount by which to decrement + ) { + FW_ASSERT(this->m_modulus > 0); + const FwSizeType offset = amount % this->m_modulus; + this->setValue(this->m_value + this->m_modulus - offset); + return this->m_value; + } + + private: + // ---------------------------------------------------------------------- + // Private member variables + // ---------------------------------------------------------------------- + + //! The index value + FwSizeType m_value; + + //! The modulus + FwSizeType m_modulus; +}; + +} // namespace Fw + +#endif diff --git a/Fw/DataStructures/ExternalArray.hpp b/Fw/DataStructures/ExternalArray.hpp index 3d96db28020..a415736d3eb 100644 --- a/Fw/DataStructures/ExternalArray.hpp +++ b/Fw/DataStructures/ExternalArray.hpp @@ -1,7 +1,7 @@ // ====================================================================== -// @title ExternalArray -// @author bocchino -// @brief A bounds-checked array with external memory +// \file ExternalArray.hpp +// \author bocchino +// \brief A bounds-checked array with external memory // ====================================================================== #ifndef Fw_ExternalArray_HPP diff --git a/Fw/DataStructures/docs/CircularIndex.md b/Fw/DataStructures/docs/CircularIndex.md index 421a4c47a3c..ac37ffcb96e 100644 --- a/Fw/DataStructures/docs/CircularIndex.md +++ b/Fw/DataStructures/docs/CircularIndex.md @@ -82,7 +82,9 @@ FwSizeType getValue() const void setValue(FwSizeType value) ``` -Set `m_value = m_value % m_modulus`. +1. Assert `m_modulus > 0`. + +2. Set `m_value = m_value % m_modulus`. ### 3.4. getModulus @@ -110,6 +112,8 @@ void setModulus(FwSizeType modulus) FwSizeType increment(FwSizeType amount = 1) ``` +1. Assert `m_modulus > 0`. + 1. Set `offset = amount % m_modulus`. 1. Call `setValue(m_value + offset)`. @@ -122,6 +126,8 @@ FwSizeType increment(FwSizeType amount = 1) FwSizeType decrement(FwSizeType amount = 1) ``` +1. Assert `m_modulus > 0`. + 1. Set `offset = amount % m_modulus`. 1. Call `setValue(m_value + m_modulus - offset)`. From 31583bebbb568eddadf8e06fdb4117a889fb2887 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 3 Jun 2025 21:27:21 -0700 Subject: [PATCH 103/458] Revise Fw/DataStructures --- Fw/DataStructures/CircularIndex.hpp | 15 ++- Fw/DataStructures/ExternalFifoQueue.hpp | 134 ++++++++++++++++++++ Fw/DataStructures/FifoQueueBase.hpp | 1 + Fw/DataStructures/docs/CircularIndex.md | 8 +- Fw/DataStructures/docs/ExternalFifoQueue.md | 10 +- Fw/DataStructures/docs/FifoQueueBase.md | 22 +++- 6 files changed, 172 insertions(+), 18 deletions(-) create mode 100644 Fw/DataStructures/ExternalFifoQueue.hpp diff --git a/Fw/DataStructures/CircularIndex.hpp b/Fw/DataStructures/CircularIndex.hpp index 9edaeab349e..a69da28689a 100644 --- a/Fw/DataStructures/CircularIndex.hpp +++ b/Fw/DataStructures/CircularIndex.hpp @@ -22,9 +22,9 @@ class CircularIndex final { CircularIndex() : m_value(0), m_modulus(1) {} //! Constructor with specified members - CircularIndex(const FwSizeType modulus, //!< The modulus - const FwSizeType value = 0 //!< The initial value - ) + explicit CircularIndex(const FwSizeType modulus, //!< The modulus + const FwSizeType value = 0 //!< The initial value + ) : m_modulus(modulus) { FW_ASSERT(modulus > 0); this->setValue(value); @@ -41,6 +41,15 @@ class CircularIndex final { // Public functions // ---------------------------------------------------------------------- + //! operator= + CircularIndex& operator=(const CircularIndex& ci) { + if (this != &ci) { + this->m_value = ci.m_value; + this->m_modulus = ci.m_modulus; + } + return *this; + } + //! Get the index value //! \return The index value FwSizeType getValue() const { diff --git a/Fw/DataStructures/ExternalFifoQueue.hpp b/Fw/DataStructures/ExternalFifoQueue.hpp new file mode 100644 index 00000000000..66f00e3ed8c --- /dev/null +++ b/Fw/DataStructures/ExternalFifoQueue.hpp @@ -0,0 +1,134 @@ +// ====================================================================== +// \file ExternalFifoQueue.hpp +// \author bocchino +// \brief A FIFO queue with external storage +// ====================================================================== + +#ifndef Fw_ExternalFifoQueue_HPP +#define Fw_ExternalFifoQueue_HPP + +#include "Fw/DataStructures/CircularIndex.hpp" +#include "Fw/DataStructures/ExternalArray.hpp" +#include "Fw/DataStructures/FifoQueueBase.hpp" + +namespace Fw { + +template +class ExternalFifoQueue final : public FifoQueueBase { + public: + // ---------------------------------------------------------------------- + // Public constructors and destructors + // ---------------------------------------------------------------------- + + //! Zero-argument constructor + ExternalFifoQueue() = default; + + //! Constructor providing backing storage + ExternalFifoQueue(T* items, //!< The items + FwSizeType capacity //!< The capacity + ) { + this->setStorage(items, capacity); + } + + //! Copy constructor + ExternalFifoQueue(const ExternalFifoQueue& queue) { *this = queue; } + + //! Destructor + ~ExternalFifoQueue() override = default; + + public: + // ---------------------------------------------------------------------- + // Public member functions + // ---------------------------------------------------------------------- + + //! operator= + ExternalFifoQueue& operator=(const ExternalFifoQueue& queue) { + if (&queue != this) { + this->m_items = queue.m_items; + this->m_enqueueIndex = queue.m_enqueueIndex; + this->m_dequeueIndex = queue.m_dequeueIndex; + this->m_size = queue.m_size; + } + } + + //! Get the element at a specified index + //! Fail an assertion if i is out of bounds + //! \return The element at index i + const T& at(FwSizeType i //!< The index + ) const override { + FW_ASSERT(i < this->m_size, static_cast(i), static_cast(this->m_size)); + CircularIndex ci = this->m_enqueueIndex; + return this->m_items[ci.increment(i)]; + } + + //! Clear the queue + void clear() override { + this->m_enqueueIndex.setValue(0); + this->m_dequeueIndex.setValue(0); + this->m_size = 0; + } + + //! Set the storage + void setStorage(T* items, //!< The items + FwSizeType capacity //!< The capacity + ) { + this->m_items.setStorage(items, capacity); + } + + //! Enqueue an element + //! \return SUCCESS if element enqueued + Success enqueue(const T& e //!< The element + ) override { + auto status = Success::FAILURE; + if (this->m_size < this->getCapacity()) { + const auto i = this->m_enqueueIndex.getValue(); + this->m_items[i] = e; + (void)this->m_enqueueIndex.increment(); + this->m_size++; + } + return status; + } + + //! Dequeue an element + //! \return SUCCESS if element dequeued + virtual Success dequeue(T& e //!< The element + ) override { + auto status = this->peek(e); + if (this->m_size > 0) { + const auto i = this->m_dequeueIndex.getValue(); + e = this->m_items[i]; + (void)this->m_dequeueIndex.increment(); + this->m_size--; + } + return status; + } + + //! Get the size (number of items stored in the queue) + //! \return The size + FwSizeType getSize() const override { return this->m_size; } + + //! Get the capacity (maximum number of items stored in the queue) + //! \return The capacity + FwSizeType getCapacity() const override { return this->m_items.getSize(); } + + private: + // ---------------------------------------------------------------------- + // Private member variables + // ---------------------------------------------------------------------- + + //! The array for storing the queue items + ExternalArray m_items = {}; + + //! The enqueue index + CircularIndex m_enqueueIndex = {}; + + //! The dequeue index + CircularIndex m_dequeueIndex = {}; + + //! The number of items on the queue + FwSizeType m_size = 0; +}; + +} // namespace Fw + +#endif diff --git a/Fw/DataStructures/FifoQueueBase.hpp b/Fw/DataStructures/FifoQueueBase.hpp index 57da3cec375..bda11ec8ab5 100644 --- a/Fw/DataStructures/FifoQueueBase.hpp +++ b/Fw/DataStructures/FifoQueueBase.hpp @@ -48,6 +48,7 @@ class FifoQueueBase { // ---------------------------------------------------------------------- //! Get the element at a specified index + //! Fail an assertion if i is out of bounds //! \return The element at index i virtual const T& at(FwSizeType i //!< The index ) const = 0; diff --git a/Fw/DataStructures/docs/CircularIndex.md b/Fw/DataStructures/docs/CircularIndex.md index ac37ffcb96e..d417259b01e 100644 --- a/Fw/DataStructures/docs/CircularIndex.md +++ b/Fw/DataStructures/docs/CircularIndex.md @@ -27,7 +27,7 @@ Defined as `= default`. ### 2.2. Constructor with Specified Members ```c++ -CircularIndex(FwSizeType modulus, FwSizeType value = 0) +explicit CircularIndex(FwSizeType modulus, FwSizeType value = 0) ``` 1. Assert `modulus > 0`. @@ -60,9 +60,11 @@ Defined as `= default`. CircularIndex& operator=(const CircularIndex& ci) ``` -1. Set `m_value = ci.m_value`. +1. If `this != &ci` -1. Set `m_modulus = ci.m_modulus`. + 1. Set `m_value = ci.m_value`. + + 1. Set `m_modulus = ci.m_modulus`. 1. Return `*this`. diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index 01d0e489756..3bdd21f07ef 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -51,7 +51,7 @@ ExternalFifoQueue queue; ExternalFifoQueue(T* items, FwSizeType capacity) ``` -1. Call `m_items.setStorage(items, capacity)`. +1. Call `setStorage(items, capacity)`. 1. Initialize the other member variables with their default values. @@ -110,7 +110,7 @@ ExternalFifoQueue& operator=(const ExternalFifoQueue& queue) 1. Set `m_dequeueIndex = queue.m_dequeueIndex`. - 1. Set `m_size = queue.size`. + 1. Set `m_size = queue.m_size`. _Example:_ ```c++ @@ -137,9 +137,9 @@ const T& at(FwSizeType i) const override 1. Assert that `i < m_size`. -1. Set `ci = m_enqueueIndex.increment(i)`. +1. Set `ci = m_enqueueIndex`. -1. Return `m_items[ci]`. +1. Return `m_items[ci.increment(i)]`. _Example:_ ```c++ @@ -200,7 +200,7 @@ Success enqueue(const T& e) override 1. Set `status = Success::FAILURE`. -1. If `m_size < m_capacity` then +1. If `m_size < getCapacity()` then 1. Set `i = m_enqueueIndex.getValue()`. diff --git a/Fw/DataStructures/docs/FifoQueueBase.md b/Fw/DataStructures/docs/FifoQueueBase.md index ffd4cd708cf..8e419d0dd6d 100644 --- a/Fw/DataStructures/docs/FifoQueueBase.md +++ b/Fw/DataStructures/docs/FifoQueueBase.md @@ -134,13 +134,15 @@ void f(FifoQueueBase& q1, FifoQueueBase& q2) { virtual Success enqueue(const T& e) = 0 ``` -1. If there is no room on the queue for a new item, then return `Success::FAILURE`. +1. Set `status = Success::FAILURE`. -1. Otherwise +1. If there is room on the queue for a new item, then 1. Enqueue `e`. - 1. Return `Success::SUCCESS`. + 1. Set `status = Success::SUCCESS`. + +1. Return `status`. _Example:_ ```c++ @@ -159,9 +161,11 @@ void Success peek(T& e) const 1. Set `status = Success::FAILURE`. -1. If `getSize() > 0` +1. Set `size = getSize()`. - 1. Set `e = at(getSize() - 1)`. +1. If `size > 0` + + 1. Set `e = at(size - 1)`. 1. Set `status = Success::SUCCESS`. @@ -188,9 +192,13 @@ void f(FifoQueueBase& queue) { virtual Success dequeue(T& e) = 0 ``` -1. Set `status = peek(e)`. +1. Set `status = Success::FAILURE`. + +1. If `size > 0` -1. If `status == Success::SUCCESS` then dequeue the last-inserted item. + 1. Dequeue the last-inserted item and store it into `e`. + + 1. Set `status = Success::SUCCESS`. 1. Return `status`. From 6bca34586cd6880e019ec5d95a46aa8ef99d4b58 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 3 Jun 2025 21:37:18 -0700 Subject: [PATCH 104/458] Revise Fw/DataStructures --- Fw/DataStructures/CMakeLists.txt | 1 + Fw/DataStructures/ExternalFifoQueue.hpp | 2 +- .../test/ut/CircularIndexTest.cpp | 133 ++++++++++++++++++ 3 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 Fw/DataStructures/test/ut/CircularIndexTest.cpp diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index 828280898b4..34574dc7f6a 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -6,6 +6,7 @@ register_fprime_module() set(UT_SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" ) diff --git a/Fw/DataStructures/ExternalFifoQueue.hpp b/Fw/DataStructures/ExternalFifoQueue.hpp index 66f00e3ed8c..ffab3346d8b 100644 --- a/Fw/DataStructures/ExternalFifoQueue.hpp +++ b/Fw/DataStructures/ExternalFifoQueue.hpp @@ -57,7 +57,7 @@ class ExternalFifoQueue final : public FifoQueueBase { const T& at(FwSizeType i //!< The index ) const override { FW_ASSERT(i < this->m_size, static_cast(i), static_cast(this->m_size)); - CircularIndex ci = this->m_enqueueIndex; + auto ci = this->m_enqueueIndex; return this->m_items[ci.increment(i)]; } diff --git a/Fw/DataStructures/test/ut/CircularIndexTest.cpp b/Fw/DataStructures/test/ut/CircularIndexTest.cpp new file mode 100644 index 00000000000..0b6db6717bb --- /dev/null +++ b/Fw/DataStructures/test/ut/CircularIndexTest.cpp @@ -0,0 +1,133 @@ +// ====================================================================== +// \title CircularIndexTest.cpp +// \author bocchino +// \brief Tests for CircularIndex types +// ====================================================================== + +#include +#include + +#include "Fw/DataStructures/CircularIndex.hpp" +#include "STest/Pick/Pick.hpp" + +namespace Fw { + +namespace { + +FwSizeType pickValue() { + return static_cast(STest::Pick::any()); +} + +FwSizeType pickModulus() { + return static_cast(STest::Pick::lowerUpper(1, std::numeric_limits::max())); +} + +} // namespace + +TEST(CircularIndex, ZeroArgConstructor) { + CircularIndex ci; + ASSERT_EQ(ci.getValue(), 0); + ASSERT_EQ(ci.getModulus(), 1); +} + +TEST(CircularIndex, SpecifiedMemberConstructor) { + const FwSizeType modulus = pickModulus(); + const FwSizeType value = pickValue(); + CircularIndex ci(modulus, value); + ASSERT_EQ(ci.getModulus(), modulus); + ASSERT_EQ(ci.getValue(), value % modulus); +} + +TEST(CircularIndex, CopyConstructor) { + const FwSizeType modulus = pickModulus(); + const FwSizeType value = pickValue(); + CircularIndex ci1(modulus, value); + CircularIndex ci2(ci1); + ASSERT_EQ(ci1.getModulus(), ci2.getModulus()); + ASSERT_EQ(ci1.getValue(), ci2.getValue()); +} + +TEST(CircularIndex, CopyAssignment) { + const FwSizeType modulus = pickModulus(); + const FwSizeType value = pickValue(); + CircularIndex ci1(modulus, value); + CircularIndex ci2; + ci2 = ci1; + ASSERT_EQ(ci1.getModulus(), ci2.getModulus()); + ASSERT_EQ(ci1.getValue(), ci2.getValue()); +} + +TEST(CircularIndex, SetValue) { + const FwSizeType modulus = pickModulus(); + const FwSizeType value = pickValue(); + CircularIndex ci(modulus); + ASSERT_EQ(ci.getValue(), 0); + ASSERT_EQ(ci.getModulus(), modulus); + ci.setValue(value); + ASSERT_EQ(ci.getValue(), value % modulus); +} + +TEST(CircularIndex, SetModulus) { + const FwSizeType value = pickValue(); + const FwSizeType modulus = pickModulus(); + CircularIndex ci(modulus, value); + ASSERT_EQ(ci.getModulus(), modulus); + ASSERT_EQ(ci.getValue(), value % modulus); + ci.setModulus(modulus); + ASSERT_EQ(ci.getModulus(), modulus); + ASSERT_EQ(ci.getValue(), value % modulus); +} + +TEST(CircularIndex, IncrementOne) { + const FwSizeType value = pickValue(); + const FwSizeType modulus = pickModulus(); + CircularIndex ci(modulus, value); + ASSERT_EQ(ci.getModulus(), modulus); + ASSERT_EQ(ci.getValue(), value % modulus); + ci.increment(); + ASSERT_EQ(ci.getModulus(), modulus); + ASSERT_EQ(ci.getValue(), (value + 1) % modulus); +} + +TEST(CircularIndex, IncrementRandom) { + const FwSizeType value = pickValue(); + const FwSizeType modulus = pickModulus(); + const FwSizeType amount = pickValue(); + const FwSizeType offset = amount % modulus; + CircularIndex ci(modulus, value); + ASSERT_EQ(ci.getModulus(), modulus); + ASSERT_EQ(ci.getValue(), value % modulus); + ci.increment(amount); + ASSERT_EQ(ci.getModulus(), modulus); + ASSERT_GT(modulus, 0); + ASSERT_EQ(ci.getValue(), (value + offset) % modulus); +} + +TEST(CircularIndex, DecrementOne) { + const FwSizeType value = pickValue(); + const FwSizeType modulus = pickModulus(); + CircularIndex ci(modulus, value); + ASSERT_EQ(ci.getModulus(), modulus); + ASSERT_EQ(ci.getValue(), value % modulus); + ci.decrement(); + ASSERT_EQ(ci.getModulus(), modulus); + ASSERT_GT(modulus, 0); + ASSERT_GE(value + modulus, 1); + ASSERT_EQ(ci.getValue(), ((value + modulus) - 1) % modulus); +} + +TEST(CircularIndex, DecrementRandom) { + const FwSizeType value = pickValue(); + const FwSizeType modulus = pickModulus(); + const FwSizeType amount = pickValue(); + const FwSizeType offset = amount % modulus; + CircularIndex ci(modulus, value); + ASSERT_EQ(ci.getModulus(), modulus); + ASSERT_EQ(ci.getValue(), value % modulus); + ci.decrement(amount); + ASSERT_EQ(ci.getModulus(), modulus); + ASSERT_GT(modulus, 0); + ASSERT_GE(value + modulus, offset); + ASSERT_EQ(ci.getValue(), (value + modulus - offset) % modulus); +} +} // namespace Fw From 801e1b610fc0ffd0e67c55a41c6df58a6ec41d71 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 3 Jun 2025 22:39:46 -0700 Subject: [PATCH 105/458] Revise CircularIndex --- Fw/DataStructures/CircularIndex.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Fw/DataStructures/CircularIndex.hpp b/Fw/DataStructures/CircularIndex.hpp index a69da28689a..83f93d24595 100644 --- a/Fw/DataStructures/CircularIndex.hpp +++ b/Fw/DataStructures/CircularIndex.hpp @@ -22,8 +22,8 @@ class CircularIndex final { CircularIndex() : m_value(0), m_modulus(1) {} //! Constructor with specified members - explicit CircularIndex(const FwSizeType modulus, //!< The modulus - const FwSizeType value = 0 //!< The initial value + explicit CircularIndex(FwSizeType modulus, //!< The modulus + FwSizeType value = 0 //!< The initial value ) : m_modulus(modulus) { FW_ASSERT(modulus > 0); @@ -58,7 +58,7 @@ class CircularIndex final { } //! Set the index value - void setValue(const FwSizeType value //!< The index value + void setValue(FwSizeType value //!< The index value ) { FW_ASSERT(this->m_modulus > 0); this->m_value = value % this->m_modulus; @@ -71,7 +71,7 @@ class CircularIndex final { } //! Set the modulus - void setModulus(const FwSizeType modulus //!< The modulus value + void setModulus(FwSizeType modulus //!< The modulus value ) { this->m_modulus = modulus; this->setValue(this->m_value); @@ -79,7 +79,7 @@ class CircularIndex final { //! Increment the index value //! \return The new value - FwSizeType increment(const FwSizeType amount = 1 //!< The amount by which to increment + FwSizeType increment(FwSizeType amount = 1 //!< The amount by which to increment ) { FW_ASSERT(this->m_modulus > 0); const FwSizeType offset = amount % m_modulus; @@ -89,7 +89,7 @@ class CircularIndex final { //! Decrement the index value //! \return The new value - FwSizeType decrement(const FwSizeType amount = 1 //!< The amount by which to decrement + FwSizeType decrement(FwSizeType amount = 1 //!< The amount by which to decrement ) { FW_ASSERT(this->m_modulus > 0); const FwSizeType offset = amount % this->m_modulus; From 53eba6e91729039b1da4509ce76796f9cc15e21a Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 4 Jun 2025 08:48:56 -0700 Subject: [PATCH 106/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/sdd.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Fw/DataStructures/docs/sdd.md b/Fw/DataStructures/docs/sdd.md index 1500ee64f7a..abc17450e53 100644 --- a/Fw/DataStructures/docs/sdd.md +++ b/Fw/DataStructures/docs/sdd.md @@ -36,6 +36,8 @@ A **FIFO queue** is a data structure backed by an array. It supports enqueue and dequeue operations in first in first out (FIFO) order. +### 2.1. Templates + `Fw/DataStructures` provides the following FIFO queue templates: * [`FifoQueueBase`](FifoQueueBase.md) @@ -44,6 +46,17 @@ first in first out (FIFO) order. * [`FifoQueue`](FifoQueue.md) +The queue implementations use a template called [`CircularIndex`](CircularIndex.md) +for representing an index that wraps around modulo an integer. + +### 2.2. Class Diagram + +```mermaid +classDiagram + FifoQueueBase <|-- ExternalFifoQueue + FifoQueueBase <|-- FifoQueue +``` + ## 3. Maps * [`MapBase`](MapBase.md) From 1ae4b187e9ede3ec325dbecdfd65b0a8a42d7458 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 4 Jun 2025 09:21:02 -0700 Subject: [PATCH 107/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/FifoQueue.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Fw/DataStructures/docs/FifoQueue.md b/Fw/DataStructures/docs/FifoQueue.md index dd2e7b3d09f..d8e870968ca 100644 --- a/Fw/DataStructures/docs/FifoQueue.md +++ b/Fw/DataStructures/docs/FifoQueue.md @@ -31,6 +31,12 @@ for storing the items on the queue. |`m_extQueue`|`ExternalFifoQueue`|The external queue implementation|C++ default initialization| |`m_array`|`Array`|The array providing the backing memory for `m_extQueue`|C++ default initialization| +```mermaid +classDiagram + queue:FifoQueue *-- m_extQueue:ExternalFifoQueue + queue:FifoQueue *-- m_array:Array +``` + ## 4. Public Constructors and Destructors ### 4.1. Zero-Argument Constructor From 14b6e30018d08e2cdf8d57e7d56e27cd65ba9433 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 4 Jun 2025 09:27:02 -0700 Subject: [PATCH 108/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/FifoQueue.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/docs/FifoQueue.md b/Fw/DataStructures/docs/FifoQueue.md index d8e870968ca..a4d2f9132f9 100644 --- a/Fw/DataStructures/docs/FifoQueue.md +++ b/Fw/DataStructures/docs/FifoQueue.md @@ -33,8 +33,8 @@ for storing the items on the queue. ```mermaid classDiagram - queue:FifoQueue *-- m_extQueue:ExternalFifoQueue - queue:FifoQueue *-- m_array:Array + FifoQueue *-- ExternalFifoQueue + FifoQueue *-- Array ``` ## 4. Public Constructors and Destructors From 48850b4be97749a6b62fbc806ecb53789034b99a Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 4 Jun 2025 09:29:17 -0700 Subject: [PATCH 109/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalFifoQueue.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index 3bdd21f07ef..2a95d02cd44 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -30,6 +30,13 @@ storing the items on the queue. |`m_dequeueIndex`|[`CircularIndex`](CircularIndex.md)|The dequeue index|`CircularIndex(m_items.size(), 0)`| |`m_size`|`FwSizeType`|The number of items on the queue|0| +```mermaid +classDiagram + FifoQueue *-- ExternalArray + FifoQueue *-- CircularIndex + FifoQueue *-- CircularIndex +``` + ## 4. Public Constructors and Destructors ### 4.1. Zero-Argument Constructor From 1f43d1459e9df9277d76931f787cbf3da29c4d67 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 4 Jun 2025 09:41:42 -0700 Subject: [PATCH 110/458] Add ExternalFifoQueueTest --- Fw/DataStructures/CMakeLists.txt | 1 + Fw/DataStructures/ExternalFifoQueue.hpp | 5 +++-- .../test/ut/ExternalFifoQueueTest.cpp | 19 +++++++++++++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index 34574dc7f6a..d2f92560024 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -9,6 +9,7 @@ set(UT_SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" ) set(UT_MOD_DEPS diff --git a/Fw/DataStructures/ExternalFifoQueue.hpp b/Fw/DataStructures/ExternalFifoQueue.hpp index ffab3346d8b..81078c9a85c 100644 --- a/Fw/DataStructures/ExternalFifoQueue.hpp +++ b/Fw/DataStructures/ExternalFifoQueue.hpp @@ -26,12 +26,13 @@ class ExternalFifoQueue final : public FifoQueueBase { //! Constructor providing backing storage ExternalFifoQueue(T* items, //!< The items FwSizeType capacity //!< The capacity - ) { + ) + : FifoQueueBase() { this->setStorage(items, capacity); } //! Copy constructor - ExternalFifoQueue(const ExternalFifoQueue& queue) { *this = queue; } + ExternalFifoQueue(const ExternalFifoQueue& queue) : FifoQueueBase() { *this = queue; } //! Destructor ~ExternalFifoQueue() override = default; diff --git a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp new file mode 100644 index 00000000000..f50afc0a6f1 --- /dev/null +++ b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp @@ -0,0 +1,19 @@ +// ====================================================================== +// \title ExternalFifoQueueTest.cpp +// \author bocchino +// \brief cpp file for ExternalFifoQueue tests +// ====================================================================== + +#include + +#include "Fw/DataStructures/ExternalFifoQueue.hpp" + +namespace Fw { + +TEST(ExternalFifoQueue, ZeroArgConstructor) { + ExternalFifoQueue queue; + ASSERT_EQ(queue.getCapacity(), 0); + ASSERT_EQ(queue.getSize(), 0); +} + +} // namespace Fw From 95e151215033e788bb21b3de4e55c15a8fdd1894 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 4 Jun 2025 10:26:13 -0700 Subject: [PATCH 111/458] Revise unit tests for Fw/DataStructures --- .../test/ut/ExternalArrayTest.cpp | 38 +++++++++++-------- .../test/ut/ExternalFifoQueueTest.cpp | 8 ++++ 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/Fw/DataStructures/test/ut/ExternalArrayTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayTest.cpp index 592b2d20437..351459e8024 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayTest.cpp @@ -17,26 +17,29 @@ TEST(ExternalArray, ZeroArgConstructor) { } TEST(ExternalArray, StorageConstructor) { - U32 elements[3]; - ExternalArray a(elements, 3); + constexpr FwSizeType size = 3; + U32 elements[size]; + ExternalArray a(elements, size); ASSERT_EQ(a.getElements(), elements); - ASSERT_EQ(a.getSize(), 3); + ASSERT_EQ(a.getSize(), size); } TEST(ExternalArray, CopyConstructor) { - U32 elements[3]; + constexpr FwSizeType size = 3; + U32 elements[size]; // Call the constructor providing backing storage - ExternalArray a1(elements, 3); + ExternalArray a1(elements, size); // Call the copy constructor ExternalArray a2(a1); ASSERT_EQ(a2.getElements(), elements); - ASSERT_EQ(a2.getSize(), 3); + ASSERT_EQ(a2.getSize(), size); } TEST(ExternalArray, CopyAssignment) { - U32 elements[3]; + constexpr FwSizeType size = 3; + U32 elements[size]; // Call the constructor providing backing storage - ExternalArray a1(elements, 3); + ExternalArray a1(elements, size); // Call the copy assignment operator ExternalArray a2; a2 = a1; @@ -62,31 +65,34 @@ static void testCopyDataFrom(ExternalArray a1, ExternalArray a2) { TEST(ExternalArray, CopyDataFrom) { constexpr FwSizeType maxSize = 10; + constexpr FwSizeType smallSize = maxSize / 2; U32 elements1[maxSize]; U32 elements2[maxSize]; // size1 < size2 - testCopyDataFrom(ExternalArray(elements1, 5), ExternalArray(elements2, 10)); + testCopyDataFrom(ExternalArray(elements1, smallSize), ExternalArray(elements2, maxSize)); // size1 == size2 - testCopyDataFrom(ExternalArray(elements1, 10), ExternalArray(elements2, 10)); + testCopyDataFrom(ExternalArray(elements1, maxSize), ExternalArray(elements2, maxSize)); // size1 > size2 - testCopyDataFrom(ExternalArray(elements1, 10), ExternalArray(elements2, 5)); + testCopyDataFrom(ExternalArray(elements1, maxSize), ExternalArray(elements2, smallSize)); } TEST(ExternalArray, Subscript) { - U32 elements[3] = {}; - ExternalArray a(elements, 3); + constexpr FwSizeType size = 10; + U32 elements[size] = {}; + ExternalArray a(elements, size); // Constant access ASSERT_EQ(a[0], 0); // Mutable access a[0]++; ASSERT_EQ(a[0], 1); // Out-of-bounds access - ASSERT_DEATH(a[3], "Assert"); + ASSERT_DEATH(a[size], "Assert"); } TEST(ExternalArray, SetStorage) { - U32 elements[3]; - ExternalArray a1(elements, 3); + constexpr FwSizeType size = 10; + U32 elements[size]; + ExternalArray a1(elements, size); ExternalArray a2; a2.setStorage(a1.getElements(), a1.getSize()); ASSERT_EQ(a2.getElements(), a1.getElements()); diff --git a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp index f50afc0a6f1..042ac38ce08 100644 --- a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp @@ -16,4 +16,12 @@ TEST(ExternalFifoQueue, ZeroArgConstructor) { ASSERT_EQ(queue.getSize(), 0); } +TEST(ExternalFifoQueue, StorageConstructor) { + constexpr FwSizeType capacity = 10; + U32 items[capacity]; + ExternalFifoQueue queue(items, capacity); + ASSERT_EQ(queue.getCapacity(), capacity); + ASSERT_EQ(queue.getSize(), 0); +} + } // namespace Fw From 9c0be5496171b83489f49e7cda46b87e4c0fd39b Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 4 Jun 2025 10:32:23 -0700 Subject: [PATCH 112/458] Revise Fw/DataStructures --- Fw/DataStructures/ExternalFifoQueue.hpp | 1 + Fw/DataStructures/docs/ExternalFifoQueue.md | 6 +++--- Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp | 13 +++++++++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/Fw/DataStructures/ExternalFifoQueue.hpp b/Fw/DataStructures/ExternalFifoQueue.hpp index 81078c9a85c..221efee840f 100644 --- a/Fw/DataStructures/ExternalFifoQueue.hpp +++ b/Fw/DataStructures/ExternalFifoQueue.hpp @@ -50,6 +50,7 @@ class ExternalFifoQueue final : public FifoQueueBase { this->m_dequeueIndex = queue.m_dequeueIndex; this->m_size = queue.m_size; } + return *this; } //! Get the element at a specified index diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index 2a95d02cd44..ba8218bdc80 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -107,9 +107,7 @@ Defined as `= default`. ExternalFifoQueue& operator=(const ExternalFifoQueue& queue) ``` -1. If `&queue == this` then do nothing. - -1. Otherwise +1. If `&queue != this` 1. Set `m_items = queue.m_items`. @@ -119,6 +117,8 @@ ExternalFifoQueue& operator=(const ExternalFifoQueue& queue) 1. Set `m_size = queue.m_size`. +1. Return `*this`. + _Example:_ ```c++ constexpr FwSizeType capacity = 3; diff --git a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp index 042ac38ce08..ecacefdf957 100644 --- a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp @@ -24,4 +24,17 @@ TEST(ExternalFifoQueue, StorageConstructor) { ASSERT_EQ(queue.getSize(), 0); } +TEST(ExternalFifoQueue, CopyConstructor) { + constexpr FwSizeType capacity = 3; + U32 items[capacity]; + // Call the constructor providing backing storage + ExternalFifoQueue q1(items, capacity); + // Enqueue an item + U32 value = 42; + (void) q1.enqueue(value); + // Call the copy constructor + ExternalFifoQueue q2(q1); + ASSERT_EQ(q2.getSize(), 1); +} + } // namespace Fw From 1e42deb4b0e0d16fa8da3ad34d60f936814b4397 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 4 Jun 2025 14:24:46 -0700 Subject: [PATCH 113/458] Revise Fw/DataStructures --- Fw/DataStructures/ExternalFifoQueue.hpp | 7 +++ .../test/ut/ExternalFifoQueueTest.cpp | 44 +++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/Fw/DataStructures/ExternalFifoQueue.hpp b/Fw/DataStructures/ExternalFifoQueue.hpp index 221efee840f..ed676104e6f 100644 --- a/Fw/DataStructures/ExternalFifoQueue.hpp +++ b/Fw/DataStructures/ExternalFifoQueue.hpp @@ -15,6 +15,13 @@ namespace Fw { template class ExternalFifoQueue final : public FifoQueueBase { + + // ---------------------------------------------------------------------- + // Friend class for testing + // ---------------------------------------------------------------------- + + template friend class ExternalFifoQueueTester; + public: // ---------------------------------------------------------------------- // Public constructors and destructors diff --git a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp index ecacefdf957..70fa1e8d64c 100644 --- a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp @@ -10,6 +10,24 @@ namespace Fw { +template class ExternalFifoQueueTester { + + public: + + ExternalFifoQueueTester(const ExternalFifoQueue& queue) : m_queue(queue) {} + + const ExternalArray getItems() const { return this->m_queue.m_items; } + + const CircularIndex& getEnqueueIndex() const { return this->m_queue.m_enqueueIndex; } + + const CircularIndex& getDequeueIndex() const { return this->m_queue.m_dequeueIndex; } + + private: + + const ExternalFifoQueue& m_queue; + +}; + TEST(ExternalFifoQueue, ZeroArgConstructor) { ExternalFifoQueue queue; ASSERT_EQ(queue.getCapacity(), 0); @@ -20,6 +38,8 @@ TEST(ExternalFifoQueue, StorageConstructor) { constexpr FwSizeType capacity = 10; U32 items[capacity]; ExternalFifoQueue queue(items, capacity); + ExternalFifoQueueTester tester(queue); + ASSERT_EQ(tester.getItems().getElements(), items); ASSERT_EQ(queue.getCapacity(), capacity); ASSERT_EQ(queue.getSize(), 0); } @@ -34,6 +54,30 @@ TEST(ExternalFifoQueue, CopyConstructor) { (void) q1.enqueue(value); // Call the copy constructor ExternalFifoQueue q2(q1); + ExternalFifoQueueTester tester1(q1); + ExternalFifoQueueTester tester2(q2); + ASSERT_EQ(tester2.getItems().getElements(), items); + ASSERT_EQ(tester2.getItems().getSize(), capacity); +#if 0 + ASSERT_EQ(tester2.getEnqueueIndex().getValue(), 1); + ASSERT_EQ(tester2.getDequeueIndex().getValue(), 0); +#endif + ASSERT_EQ(q2.getSize(), 1); +} + +TEST(ExternalFifoQueue, CopyAssignmentOperator) { + constexpr FwSizeType capacity = 3; + U32 items[capacity]; + // Call the constructor providing backing storage + ExternalFifoQueue 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); } From ced5ca15cb90f15e2174ade75a087ddf344983ab Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 4 Jun 2025 15:42:42 -0700 Subject: [PATCH 114/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/Array.md | 6 ++-- Fw/DataStructures/docs/ExternalArray.md | 45 ++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/Fw/DataStructures/docs/Array.md b/Fw/DataStructures/docs/Array.md index 323ad7bec41..f918996bdd2 100644 --- a/Fw/DataStructures/docs/Array.md +++ b/Fw/DataStructures/docs/Array.md @@ -135,10 +135,8 @@ ASSERT_DEATH(a[size], "Assert"); Array& operator=(const Array& a) ``` -1. If `&a == this` then do nothing. - -1. Otherwise overwrite each element of `m_elements` with the corresponding -element of `a`. +1. If `&a != this`, overwrite each element of `m_elements` with the +corresponding element of `a`. _Example:_ ```c++ diff --git a/Fw/DataStructures/docs/ExternalArray.md b/Fw/DataStructures/docs/ExternalArray.md index a4126a84144..d683f8da43b 100644 --- a/Fw/DataStructures/docs/ExternalArray.md +++ b/Fw/DataStructures/docs/ExternalArray.md @@ -38,22 +38,37 @@ _Example:_ ExternalArray a; ``` -### 3.2. Constructor Providing Backing Storage +### 3.2. Constructor Providing Typed Backing Storage ```c++ ExternalArray(T* elements, FwSizeType size) ``` -Initialize `m_elements` with `elements` and `m_size` with `size`. +Call `setStorage(elements, size)`. _Example:_ ```c++ constexpr FwSizeType size = 3; U32 elements[size]; -ExternalArray a(elements, size); +ExternalArray a(elements, size); +``` + +### 3.3. Constructor Providing Untyped Backing Storage + +```c++ +ExternalArray(ByteArray data, FwSizeType size) +``` + +Call `setStorage(data, size)`. + +_Example:_ +```c++ +constexpr FwSizeType size = 3; +alignas(U32) U8 bytes[size * sizeof(U32)]; +ExternalArray a(ByteArray(&bytes[0], sizeof bytes), size); ``` -### 3.3. Copy Constructor +### 3.4. Copy Constructor ```c++ ExternalArray(const ExternalArray& a) @@ -71,7 +86,7 @@ ExternalArray a1(elements, size); ExternalArray a2(a1); ``` -### 3.4. Destructor +### 3.5. Destructor ```c++ ~ExternalArray() @@ -212,3 +227,23 @@ constexpr FwSizeType size = 3; U32 elements[size]; a.setStorage(elements, size); ``` + +```c++ +void setStorage(ByteArray data, FwSizeType size) +``` + +1. Check that `data.bytes` is correctly aligned for type `T`. + +1. Check that `size * sizeof(FwSizeType) <= data.size`. + +1. Initialize `m_elements` with `data.bytes`. + +1. Initialize `m_size` with `size`. + +_Example:_ +```c++ +constexpr FwSizeType size = 3; +alignas(U32) U8 bytes[size * sizeof(U32)]; +ExternalArray a; +a.setStorage(ByteArray(&bytes[0], sizeof bytes), size); +``` From 66a4411aa504b1258ae96a2c80c65a0d2bdcb857 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 4 Jun 2025 15:44:26 -0700 Subject: [PATCH 115/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalArray.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/ExternalArray.md b/Fw/DataStructures/docs/ExternalArray.md index d683f8da43b..81134693bf5 100644 --- a/Fw/DataStructures/docs/ExternalArray.md +++ b/Fw/DataStructures/docs/ExternalArray.md @@ -212,7 +212,7 @@ const auto size1 = a.getSize(); ASSERT_EQ(size1, size); ``` -### 4.6. setStorage +### 4.6. setStorage (Typed Data) ```c++ void setStorage(T* elements, FwSizeType size) @@ -228,6 +228,8 @@ U32 elements[size]; a.setStorage(elements, size); ``` +### 4.7. setStorage (Untyped Data) + ```c++ void setStorage(ByteArray data, FwSizeType size) ``` From c960f2de8f889ee83c82a6a9d4fd436136ecd06d Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 4 Jun 2025 15:45:19 -0700 Subject: [PATCH 116/458] Revise SDD for ExternalArray --- Fw/DataStructures/docs/ExternalArray.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArray.md b/Fw/DataStructures/docs/ExternalArray.md index 81134693bf5..d7abd9c4d3a 100644 --- a/Fw/DataStructures/docs/ExternalArray.md +++ b/Fw/DataStructures/docs/ExternalArray.md @@ -148,9 +148,7 @@ a2 = a1; void copyDataFrom(const ExternalArray& a) ``` -1. If `&a == this` then do nothing. - -1. Otherwise +1. If `&a != this` then do nothing. 1. Let `size` be the minimum of `m_size` and `a.m_size` From fe08ebdc01206e37803cb2dd16cc6a5a28fc5201 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 4 Jun 2025 15:56:24 -0700 Subject: [PATCH 117/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/Array.md | 1 - Fw/DataStructures/docs/ExternalArray.md | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/docs/Array.md b/Fw/DataStructures/docs/Array.md index f918996bdd2..a23cb5869ec 100644 --- a/Fw/DataStructures/docs/Array.md +++ b/Fw/DataStructures/docs/Array.md @@ -198,4 +198,3 @@ _Example:_ const auto size = Array::getStaticSize(); ASSERT_EQ(size, 3); ``` - diff --git a/Fw/DataStructures/docs/ExternalArray.md b/Fw/DataStructures/docs/ExternalArray.md index d7abd9c4d3a..30d28bc0f4c 100644 --- a/Fw/DataStructures/docs/ExternalArray.md +++ b/Fw/DataStructures/docs/ExternalArray.md @@ -232,9 +232,11 @@ a.setStorage(elements, size); void setStorage(ByteArray data, FwSizeType size) ``` +1. Check that `data.bytes != nullptr`. + 1. Check that `data.bytes` is correctly aligned for type `T`. -1. Check that `size * sizeof(FwSizeType) <= data.size`. +1. Check that `size * sizeof(T) <= data.size`. 1. Initialize `m_elements` with `data.bytes`. From 7cb86b23f45c6181830e64f6799bab6e681533bb Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 4 Jun 2025 18:02:57 -0700 Subject: [PATCH 118/458] Revise ExternalArray --- Fw/DataStructures/ExternalArray.hpp | 29 +++++++++++++++++++++++-- Fw/DataStructures/docs/ExternalArray.md | 6 ++--- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/Fw/DataStructures/ExternalArray.hpp b/Fw/DataStructures/ExternalArray.hpp index a415736d3eb..a6f52d585e9 100644 --- a/Fw/DataStructures/ExternalArray.hpp +++ b/Fw/DataStructures/ExternalArray.hpp @@ -7,8 +7,11 @@ #ifndef Fw_ExternalArray_HPP #define Fw_ExternalArray_HPP +#include + #include "Fw/FPrimeBasicTypes.hpp" #include "Fw/Types/Assert.hpp" +#include "Fw/Types/ByteArray.hpp" namespace Fw { @@ -22,12 +25,19 @@ class ExternalArray final { //! Zero-argument constructor ExternalArray() {} - //! Constructor providing backing storage + //! Constructor providing typed backing storage ExternalArray(T* elements, //!< The elements FwSizeType size //!< The array size ) : m_elements(elements), m_size(size) {} + //! Constructor providing untyped backing storage + ExternalArray(ByteArray data, //!< The data + FwSizeType size //!< The array size + ) { + this->setStorage(data, size); + } + //! Copy constructor ExternalArray(const ExternalArray& a) : m_elements(a.m_elements), m_size(a.m_size) {} @@ -87,7 +97,7 @@ class ExternalArray final { //! \return The size FwSizeType getSize() const { return this->m_size; } - //! Set the backing storage + //! Set the backing storage (typed data) void setStorage(T* elements, //!< The array elements FwSizeType size //!< The size ) { @@ -95,6 +105,21 @@ class ExternalArray final { this->m_size = size; } + //! Set the backing storage (untyped data) + void setStorage(ByteArray data, //!< The data + FwSizeType size //!< The array size + ) { + // Check that data.bytes is not null + FW_ASSERT(data.bytes != nullptr); + // Check that data.bytes is properly aligned + FW_ASSERT(reinterpret_cast(data.bytes) % alignof(T) == 0); + // Check that data.size is large enough to hold the array + FW_ASSERT(size * sizeof(T) <= data.size); + // Initialize the array members + this->m_elements = reinterpret_cast(data.bytes); + this->m_size = size; + } + private: // ---------------------------------------------------------------------- // Private member variables diff --git a/Fw/DataStructures/docs/ExternalArray.md b/Fw/DataStructures/docs/ExternalArray.md index 30d28bc0f4c..15d37d99d7f 100644 --- a/Fw/DataStructures/docs/ExternalArray.md +++ b/Fw/DataStructures/docs/ExternalArray.md @@ -232,11 +232,11 @@ a.setStorage(elements, size); void setStorage(ByteArray data, FwSizeType size) ``` -1. Check that `data.bytes != nullptr`. +1. Assert that `data.bytes != nullptr`. -1. Check that `data.bytes` is correctly aligned for type `T`. +1. Assert that `data.bytes` is correctly aligned for type `T`. -1. Check that `size * sizeof(T) <= data.size`. +1. Assert that `size * sizeof(T) <= data.size`. 1. Initialize `m_elements` with `data.bytes`. From ad69f54126b1e4cb4959365b92e8fdbe19da6915 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 4 Jun 2025 18:04:23 -0700 Subject: [PATCH 119/458] Revise ExternalArray --- Fw/DataStructures/docs/ExternalArray.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArray.md b/Fw/DataStructures/docs/ExternalArray.md index 15d37d99d7f..48d55ec6422 100644 --- a/Fw/DataStructures/docs/ExternalArray.md +++ b/Fw/DataStructures/docs/ExternalArray.md @@ -148,11 +148,11 @@ a2 = a1; void copyDataFrom(const ExternalArray& a) ``` -1. If `&a != this` then do nothing. +1. If `&a != this` 1. Let `size` be the minimum of `m_size` and `a.m_size` - 1. For each `i` in [0, `size), set `m_elements[i] = a.m_elements[i]` + 1. For each `i` in [0, `size`), set `m_elements[i] = a.m_elements[i]` _Example:_ ```c++ From 254fd076a1c63298f0e6e00ac664c6b1bcb691b6 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 4 Jun 2025 20:07:40 -0700 Subject: [PATCH 120/458] Revise FifoQueue --- Fw/DataStructures/FifoQueueBase.hpp | 7 +- Fw/DataStructures/docs/FifoQueueBase.md | 69 ++++++++----------- .../test/ut/ExternalArrayTest.cpp | 44 ++++++++++-- 3 files changed, 69 insertions(+), 51 deletions(-) diff --git a/Fw/DataStructures/FifoQueueBase.hpp b/Fw/DataStructures/FifoQueueBase.hpp index bda11ec8ab5..ca1c3f78c97 100644 --- a/Fw/DataStructures/FifoQueueBase.hpp +++ b/Fw/DataStructures/FifoQueueBase.hpp @@ -20,7 +20,8 @@ class FifoQueueBase { // Private constructors // ---------------------------------------------------------------------- - //! Deleted copy constructor + //! Copy constructor deleted in the abstract class + //! Behavior depends on the implementation FifoQueueBase(const FifoQueueBase&) = delete; protected: @@ -39,7 +40,9 @@ class FifoQueueBase { // Private member functions // ---------------------------------------------------------------------- - //! Deleted operator= + //! operator= deleted in the abstract class + //! Behavior depends on the implementation + //! We avoid virtual user-defined operators FifoQueueBase& operator=(const FifoQueueBase&) = delete; public: diff --git a/Fw/DataStructures/docs/FifoQueueBase.md b/Fw/DataStructures/docs/FifoQueueBase.md index 8e419d0dd6d..b048e950288 100644 --- a/Fw/DataStructures/docs/FifoQueueBase.md +++ b/Fw/DataStructures/docs/FifoQueueBase.md @@ -52,33 +52,7 @@ Defined as `= delete`. ## 5. Public Member Functions -### 5.1. at - -```c++ -virtual const T& at(FwSizeType i) const = 0 -``` - -1. Assert that `i < getSize()`. - -1. Get a reference to the element of the queue at index `i`. -Index 0 is the first element inserted in the queue. - -_Example:_ -```c++ -void f(FifoQueueBase& queue) { - queue.clear(); - auto status = queue.enqueue(10); - ASSERT_EQ(status, Success::SUCCESS); - auto status = queue.enqueue(11); - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(queue.at(0), 10); - ASSERT_EQ(queue.at(1), 11); - // Out-of-bounds access - ASSERT_DEATH(queue.at(2), "Assert"); -} -``` - -### 5.2. clear +### 5.1. clear ```c++ virtual void clear() = 0 @@ -94,7 +68,7 @@ void f(FifoQueueBase& queue) { } ``` -### 5.3. copyDataFrom +### 5.2. copyDataFrom ```c++ void copyDataFrom(const FifoQueueBase& queue) @@ -110,7 +84,13 @@ void copyDataFrom(const FifoQueueBase& queue) 1. For `i` in [0, `size`) - 1. Set `status = enqueue(queue.at(i))`. + 1. Set `T value = {}`. + + 1. Set `status = queue.peek(value)`. + + 1. Assert `status == Success::SUCCESS`. + + 1. Set `status = enqueue(value)`. 1. Assert `status == Success::SUCCESS`. @@ -128,7 +108,7 @@ void f(FifoQueueBase& q1, FifoQueueBase& q2) { } ``` -### 5.4. enqueue +### 5.3. enqueue ```c++ virtual Success enqueue(const T& e) = 0 @@ -138,7 +118,7 @@ virtual Success enqueue(const T& e) = 0 1. If there is room on the queue for a new item, then - 1. Enqueue `e`. + 1. Add `e` to the right of the queue. 1. Set `status = Success::SUCCESS`. @@ -153,19 +133,19 @@ void f(FifoQueueBase& queue) { } ``` -### 5.5. peek +### 5.4. peek ```c++ -void Success peek(T& e) const +void Success peek(T& e, FwSizeType index = 0) const ``` 1. Set `status = Success::FAILURE`. -1. Set `size = getSize()`. - -1. If `size > 0` +1. If `index < getSize()` - 1. Set `e = at(size - 1)`. + 1. Assign the element at index `index` to `e`. + Index 0 is the leftmost (earliest) element in the queue. + Increasing indices go from left to right. 1. Set `status = Success::SUCCESS`. @@ -179,14 +159,19 @@ void f(FifoQueueBase& queue) { auto status = queue.peek(value); ASSERT_EQ(status, Success::FAILURE); status = queue.enqueue(3); - ASSERT_EQ(status, Success::SUCCESS); status = queue.peek(value); ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(value, 3); + status = queue.peek(value, 1); + ASSERT_EQ(status, Success::FAILURE); + status = queue.enqueue(4); + status = queue.peek(value, 1); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(value, 4); } ``` -### 5.6. dequeue +### 5.5. dequeue ```c++ virtual Success dequeue(T& e) = 0 @@ -196,7 +181,7 @@ virtual Success dequeue(T& e) = 0 1. If `size > 0` - 1. Dequeue the last-inserted item and store it into `e`. + 1. Remove the leftmost item from the queue and store it into `e`. 1. Set `status = Success::SUCCESS`. @@ -217,7 +202,7 @@ void f(FifoQueueBase& queue) { } ``` -### 5.7. getSize +### 5.6. getSize ```c++ virtual FwSizeType getSize() const = 0 @@ -238,7 +223,7 @@ void f(const FifoQueueBase& queue) { } ``` -### 5.8. getCapacity +### 5.7. getCapacity ```c++ virtual FwSizeType getCapacity() const = 0 diff --git a/Fw/DataStructures/test/ut/ExternalArrayTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayTest.cpp index 351459e8024..5d9ac6b444b 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayTest.cpp @@ -16,7 +16,7 @@ TEST(ExternalArray, ZeroArgConstructor) { ASSERT_EQ(a.getSize(), 0); } -TEST(ExternalArray, StorageConstructor) { +TEST(ExternalArray, StorageConstructorTyped) { constexpr FwSizeType size = 3; U32 elements[size]; ExternalArray a(elements, size); @@ -24,6 +24,14 @@ TEST(ExternalArray, StorageConstructor) { ASSERT_EQ(a.getSize(), size); } +TEST(ExternalArray, StorageConstructorUntyped) { + constexpr FwSizeType size = 3; + alignas(U32) U8 bytes[size * sizeof(U32)]; + ExternalArray a(ByteArray(&bytes[0], sizeof bytes), size); + ASSERT_EQ(a.getElements(), reinterpret_cast(&bytes[0])); + ASSERT_EQ(a.getSize(), size); +} + TEST(ExternalArray, CopyConstructor) { constexpr FwSizeType size = 3; U32 elements[size]; @@ -89,14 +97,36 @@ TEST(ExternalArray, Subscript) { ASSERT_DEATH(a[size], "Assert"); } -TEST(ExternalArray, SetStorage) { +TEST(ExternalArray, SetStorageTyped) { constexpr FwSizeType size = 10; U32 elements[size]; - ExternalArray a1(elements, size); - ExternalArray a2; - a2.setStorage(a1.getElements(), a1.getSize()); - ASSERT_EQ(a2.getElements(), a1.getElements()); - ASSERT_EQ(a2.getSize(), a1.getSize()); + ExternalArray a; + a.setStorage(elements, size); + ASSERT_EQ(a.getElements(), elements); + ASSERT_EQ(a.getSize(), size); +} + +TEST(ExternalArray, SetStorageUnypedOK) { + constexpr FwSizeType size = 10; + alignas(U32) U8 bytes[size * sizeof(U32)]; + ExternalArray a; + a.setStorage(ByteArray(&bytes[0], sizeof bytes), size); + ASSERT_EQ(a.getElements(), reinterpret_cast(bytes)); + ASSERT_EQ(a.getSize(), size); +} + +TEST(ExternalArray, SetStorageUnypedBadSize) { + constexpr FwSizeType size = 10; + alignas(U32) U8 bytes[size * sizeof(U32)]; + ExternalArray a; + ASSERT_DEATH(a.setStorage(ByteArray(&bytes[0], sizeof bytes), size + 1), "Assert"); +} + +TEST(ExternalArray, SetStorageUnypedBadAlignment) { + constexpr FwSizeType size = 10; + alignas(U32) U8 bytes[size * sizeof(U32)]; + ExternalArray a; + ASSERT_DEATH(a.setStorage(ByteArray(&bytes[1], sizeof bytes), size), "Assert"); } } // namespace Fw From d6df8c8829dbd5634a983410bd478a8c6a01bd3b Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 4 Jun 2025 20:08:20 -0700 Subject: [PATCH 121/458] Revise FifoQueueBase --- Fw/DataStructures/docs/FifoQueueBase.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/FifoQueueBase.md b/Fw/DataStructures/docs/FifoQueueBase.md index b048e950288..70812e50d09 100644 --- a/Fw/DataStructures/docs/FifoQueueBase.md +++ b/Fw/DataStructures/docs/FifoQueueBase.md @@ -136,7 +136,7 @@ void f(FifoQueueBase& queue) { ### 5.4. peek ```c++ -void Success peek(T& e, FwSizeType index = 0) const +Success peek(T& e, FwSizeType index = 0) const ``` 1. Set `status = Success::FAILURE`. From f6170672bcd5b1f05035c41fcc85284da8663b40 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 4 Jun 2025 20:20:45 -0700 Subject: [PATCH 122/458] Revise ExternalFifoQueue --- Fw/DataStructures/docs/ExternalFifoQueue.md | 37 +++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index ba8218bdc80..99b1944cf7d 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -52,7 +52,7 @@ _Example:_ ExternalFifoQueue queue; ``` -### 4.2. Constructor Providing Backing Storage +### 4.2. Constructor Providing Typed Backing Storage ```c++ ExternalFifoQueue(T* items, FwSizeType capacity) @@ -69,6 +69,23 @@ U32 items[capacity]; ExternalFifoQueue queue(items, capacity); ``` +### 4.2. Constructor Providing Untyped Backing Storage + +```c++ +ExternalFifoQueue(ByteArray data, FwSizeType capacity) +``` + +1. Call `setStorage(data, capacity)`. + +1. Initialize the other member variables with their default values. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +alignas(U32) U8 bytes[capacity * sizeof(U32)]; +ExternalFifoQueue queue(ByteArray(&bytes[0], sizeof bytes), capacity); +``` + ### 4.3. Copy Constructor ```c++ @@ -183,7 +200,7 @@ queue.clear(); ASSERT_EQ(queue.getSize(), 0); ``` -### 5.4. setStorage +### 5.4. setStorage (Typed Data) ```c++ void setStorage(T* items, FwSizeType size) @@ -199,6 +216,22 @@ U32 items[capacity]; queue.setStorage(items, capacity); ``` +### 5.4. setStorage (Untyped Data) + +```c++ +void setStorage(ByteArray data, FwSizeType capacity) +``` + +Call `m_items.setStorage(data, capacity)`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +alignas(U32) U8 bytes[capacity * sizeof(U32)]; +ExternalFifoQueue queue; +queue.setStorage(ByteArray(&bytes[0], sizeof bytes), capacity); +``` + ### 5.5. enqueue ```c++ From 18b42c7d8b8c65452597eea315e5672fd86bc839 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 4 Jun 2025 20:41:04 -0700 Subject: [PATCH 123/458] Revise Fw/DataStructures --- Fw/DataStructures/ExternalFifoQueue.hpp | 58 +++++++++++++++++-------- Fw/DataStructures/FifoQueueBase.hpp | 39 +++++++---------- Fw/DataStructures/docs/FifoQueueBase.md | 2 +- 3 files changed, 56 insertions(+), 43 deletions(-) diff --git a/Fw/DataStructures/ExternalFifoQueue.hpp b/Fw/DataStructures/ExternalFifoQueue.hpp index ed676104e6f..d49b192b38b 100644 --- a/Fw/DataStructures/ExternalFifoQueue.hpp +++ b/Fw/DataStructures/ExternalFifoQueue.hpp @@ -10,17 +10,18 @@ #include "Fw/DataStructures/CircularIndex.hpp" #include "Fw/DataStructures/ExternalArray.hpp" #include "Fw/DataStructures/FifoQueueBase.hpp" +#include "Fw/Types/ByteArray.hpp" namespace Fw { template class ExternalFifoQueue final : public FifoQueueBase { - // ---------------------------------------------------------------------- // Friend class for testing // ---------------------------------------------------------------------- - template friend class ExternalFifoQueueTester; + template + friend class ExternalFifoQueueTester; public: // ---------------------------------------------------------------------- @@ -30,7 +31,7 @@ class ExternalFifoQueue final : public FifoQueueBase { //! Zero-argument constructor ExternalFifoQueue() = default; - //! Constructor providing backing storage + //! Constructor providing typed backing storage ExternalFifoQueue(T* items, //!< The items FwSizeType capacity //!< The capacity ) @@ -38,6 +39,14 @@ class ExternalFifoQueue final : public FifoQueueBase { this->setStorage(items, capacity); } + //! Constructor providing untyped backing storage + ExternalFifoQueue(ByteArray data, //!< The data + FwSizeType capacity //!< The capacity + ) + : FifoQueueBase() { + this->setStorage(data, capacity); + } + //! Copy constructor ExternalFifoQueue(const ExternalFifoQueue& queue) : FifoQueueBase() { *this = queue; } @@ -60,16 +69,6 @@ class ExternalFifoQueue final : public FifoQueueBase { return *this; } - //! Get the element at a specified index - //! Fail an assertion if i is out of bounds - //! \return The element at index i - const T& at(FwSizeType i //!< The index - ) const override { - FW_ASSERT(i < this->m_size, static_cast(i), static_cast(this->m_size)); - auto ci = this->m_enqueueIndex; - return this->m_items[ci.increment(i)]; - } - //! Clear the queue void clear() override { this->m_enqueueIndex.setValue(0); @@ -77,16 +76,23 @@ class ExternalFifoQueue final : public FifoQueueBase { this->m_size = 0; } - //! Set the storage + //! Set the storage (typed data) void setStorage(T* items, //!< The items FwSizeType capacity //!< The capacity ) { this->m_items.setStorage(items, capacity); } - //! Enqueue an element + //! Set the storage (untyped data) + void setStorage(ByteArray data, //!< The data + FwSizeType capacity //!< The capacity + ) { + this->m_items.setStorage(data, capacity); + } + + //! Enqueue an element (push on the right) //! \return SUCCESS if element enqueued - Success enqueue(const T& e //!< The element + Success enqueue(const T& e //!< The element (output) ) override { auto status = Success::FAILURE; if (this->m_size < this->getCapacity()) { @@ -98,9 +104,25 @@ class ExternalFifoQueue final : public FifoQueueBase { return status; } - //! Dequeue an element + //! Peek an element at an index + //! Indices go from left to right in the range [0, size) + //! \return SUCCESS if element exists + Success peek(T& e, //!< The element (output) + FwSizeType index = 0 //!< The index (input) + ) const override { + auto status = Success::FAILURE; + const auto size = this->getSize(); + if (size > 0) { + auto ci = this->m_enqueueIndex; + e = this->m_items[ci.increment(index)]; + status = Success::SUCCESS; + } + return status; + } + + //! Dequeue an element (pop from the left) //! \return SUCCESS if element dequeued - virtual Success dequeue(T& e //!< The element + virtual Success dequeue(T& e //!< The element (output) ) override { auto status = this->peek(e); if (this->m_size > 0) { diff --git a/Fw/DataStructures/FifoQueueBase.hpp b/Fw/DataStructures/FifoQueueBase.hpp index ca1c3f78c97..42483ce8501 100644 --- a/Fw/DataStructures/FifoQueueBase.hpp +++ b/Fw/DataStructures/FifoQueueBase.hpp @@ -20,7 +20,7 @@ class FifoQueueBase { // Private constructors // ---------------------------------------------------------------------- - //! Copy constructor deleted in the abstract class + //! Copy constructor deleted in the base class //! Behavior depends on the implementation FifoQueueBase(const FifoQueueBase&) = delete; @@ -40,7 +40,7 @@ class FifoQueueBase { // Private member functions // ---------------------------------------------------------------------- - //! operator= deleted in the abstract class + //! operator= deleted in the base class //! Behavior depends on the implementation //! We avoid virtual user-defined operators FifoQueueBase& operator=(const FifoQueueBase&) = delete; @@ -50,12 +50,6 @@ class FifoQueueBase { // Public member functions // ---------------------------------------------------------------------- - //! Get the element at a specified index - //! Fail an assertion if i is out of bounds - //! \return The element at index i - virtual const T& at(FwSizeType i //!< The index - ) const = 0; - //! Clear the queue virtual void clear() = 0; @@ -65,33 +59,30 @@ class FifoQueueBase { this->clear(); const FwSizeType size = FW_MIN(queue.getSize(), this->getCapacity()); for (FwSizeType i = 0; i < size; i++) { - const auto status = this->enqueue(queue.at(i)); + T value = {}; + auto status = queue.peek(value, i); + FW_ASSERT(status == Fw::Success::SUCCESS, static_cast(status)); + status = this->enqueue(value); FW_ASSERT(status == Fw::Success::SUCCESS, static_cast(status)); } } } - //! Enqueue an element + //! Enqueue an element (add to the right) //! \return SUCCESS if element enqueued - virtual Success enqueue(const T& e //!< The element + virtual Success enqueue(const T& e //!< The element (output) ) = 0; - //! Peek an element + //! Peek an element at an index + //! Indices go from left to right in the range [0, size) //! \return SUCCESS if element exists - Success peek(T& e //!< The element - ) const { - auto status = Success::FAILURE; - auto size = this->getSize(); - if (size > 0) { - e = this->at(size - 1); - status = Success::SUCCESS; - } - return status; - } + virtual Success peek(T& e, //!< The element (output) + FwSizeType index = 0 //!< The index (input) + ) const = 0; - //! Dequeue an element + //! Dequeue an element (pop from the left) //! \return SUCCESS if element dequeued - virtual Success dequeue(T& e //!< The element + virtual Success dequeue(T& e //!< The element (output) ) = 0; //! Get the size (number of items stored in the queue) diff --git a/Fw/DataStructures/docs/FifoQueueBase.md b/Fw/DataStructures/docs/FifoQueueBase.md index 70812e50d09..94962561c79 100644 --- a/Fw/DataStructures/docs/FifoQueueBase.md +++ b/Fw/DataStructures/docs/FifoQueueBase.md @@ -136,7 +136,7 @@ void f(FifoQueueBase& queue) { ### 5.4. peek ```c++ -Success peek(T& e, FwSizeType index = 0) const +Success peek(T& e, FwSizeType index = 0) const = 0 ``` 1. Set `status = Success::FAILURE`. From 03bd973ba983d8d40ff4718569f42e02be975b57 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 4 Jun 2025 20:57:43 -0700 Subject: [PATCH 124/458] Refactor FifoQueue --- Fw/DataStructures/ExternalFifoQueue.hpp | 22 +++++++++++++++++++ Fw/DataStructures/FifoQueueBase.hpp | 15 ++----------- Fw/DataStructures/docs/ExternalFifoQueue.md | 18 ++++++++++++--- .../test/ut/ExternalFifoQueueTest.cpp | 4 +--- 4 files changed, 40 insertions(+), 19 deletions(-) diff --git a/Fw/DataStructures/ExternalFifoQueue.hpp b/Fw/DataStructures/ExternalFifoQueue.hpp index d49b192b38b..46461906cb3 100644 --- a/Fw/DataStructures/ExternalFifoQueue.hpp +++ b/Fw/DataStructures/ExternalFifoQueue.hpp @@ -76,11 +76,30 @@ class ExternalFifoQueue final : public FifoQueueBase { this->m_size = 0; } + //! Copy data from another queue + virtual void copyDataFrom(const FifoQueueBase& queue //!< The queue + ) override { + if (&queue != this) { + this->clear(); + const FwSizeType size = FW_MIN(queue.getSize(), this->getCapacity()); + for (FwSizeType i = 0; i < size; i++) { + T value; + auto status = queue.peek(value, i); + FW_ASSERT(status == Fw::Success::SUCCESS, static_cast(status)); + status = this->enqueue(value); + FW_ASSERT(status == Fw::Success::SUCCESS, static_cast(status)); + } + } + } + //! Set the storage (typed data) void setStorage(T* items, //!< The items FwSizeType capacity //!< The capacity ) { this->m_items.setStorage(items, capacity); + this->m_enqueueIndex.setModulus(capacity); + this->m_dequeueIndex.setModulus(capacity); + this->clear(); } //! Set the storage (untyped data) @@ -88,6 +107,9 @@ class ExternalFifoQueue final : public FifoQueueBase { FwSizeType capacity //!< The capacity ) { this->m_items.setStorage(data, capacity); + this->m_enqueueIndex.setModulus(capacity); + this->m_dequeueIndex.setModulus(capacity); + this->clear(); } //! Enqueue an element (push on the right) diff --git a/Fw/DataStructures/FifoQueueBase.hpp b/Fw/DataStructures/FifoQueueBase.hpp index 42483ce8501..f48bdbab796 100644 --- a/Fw/DataStructures/FifoQueueBase.hpp +++ b/Fw/DataStructures/FifoQueueBase.hpp @@ -54,19 +54,8 @@ class FifoQueueBase { virtual void clear() = 0; //! Copy data from another queue - void copyDataFrom(const FifoQueueBase& queue) { - if (&queue != this) { - this->clear(); - const FwSizeType size = FW_MIN(queue.getSize(), this->getCapacity()); - for (FwSizeType i = 0; i < size; i++) { - T value = {}; - auto status = queue.peek(value, i); - FW_ASSERT(status == Fw::Success::SUCCESS, static_cast(status)); - status = this->enqueue(value); - FW_ASSERT(status == Fw::Success::SUCCESS, static_cast(status)); - } - } - } + virtual void copyDataFrom(const FifoQueueBase& queue //!< The queue + ) = 0; //! Enqueue an element (add to the right) //! \return SUCCESS if element enqueued diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index 99b1944cf7d..2045620ab10 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -203,10 +203,16 @@ ASSERT_EQ(queue.getSize(), 0); ### 5.4. setStorage (Typed Data) ```c++ -void setStorage(T* items, FwSizeType size) +void setStorage(T* items, FwSizeType capacity) ``` -Call `m_items.setStorage(items, size)`. +1. Call `m_items.setStorage(items, capacity)`. + +1. Call `this->m_enqueueIndex.setModulus(capacity)`. + +1. Call `this->m_dequeueIndex.setModulus(capacity)`. + +1. Call `this->clear()`. _Example:_ ```c++ @@ -222,7 +228,13 @@ queue.setStorage(items, capacity); void setStorage(ByteArray data, FwSizeType capacity) ``` -Call `m_items.setStorage(data, capacity)`. +1. Call `m_items.setStorage(data, capacity)`. + +1. Call `this->m_enqueueIndex.setModulus(capacity)`. + +1. Call `this->m_dequeueIndex.setModulus(capacity)`. + +1. Call `this->clear()`. _Example:_ ```c++ diff --git a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp index 70fa1e8d64c..e425a1ab350 100644 --- a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp @@ -34,7 +34,7 @@ TEST(ExternalFifoQueue, ZeroArgConstructor) { ASSERT_EQ(queue.getSize(), 0); } -TEST(ExternalFifoQueue, StorageConstructor) { +TEST(ExternalFifoQueue, TypedStorageConstructor) { constexpr FwSizeType capacity = 10; U32 items[capacity]; ExternalFifoQueue queue(items, capacity); @@ -58,10 +58,8 @@ TEST(ExternalFifoQueue, CopyConstructor) { ExternalFifoQueueTester tester2(q2); ASSERT_EQ(tester2.getItems().getElements(), items); ASSERT_EQ(tester2.getItems().getSize(), capacity); -#if 0 ASSERT_EQ(tester2.getEnqueueIndex().getValue(), 1); ASSERT_EQ(tester2.getDequeueIndex().getValue(), 0); -#endif ASSERT_EQ(q2.getSize(), 1); } From bc16c5479c03b2927b103131dfb7b44319683600 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 4 Jun 2025 21:02:52 -0700 Subject: [PATCH 125/458] Revise ExternalFifoQueue --- Fw/DataStructures/ExternalFifoQueue.hpp | 28 ++++++++++++++++--------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/Fw/DataStructures/ExternalFifoQueue.hpp b/Fw/DataStructures/ExternalFifoQueue.hpp index 46461906cb3..01095c932eb 100644 --- a/Fw/DataStructures/ExternalFifoQueue.hpp +++ b/Fw/DataStructures/ExternalFifoQueue.hpp @@ -77,16 +77,13 @@ class ExternalFifoQueue final : public FifoQueueBase { } //! Copy data from another queue - virtual void copyDataFrom(const FifoQueueBase& queue //!< The queue - ) override { + void copyDataFrom(const FifoQueueBase& queue //!< The queue + ) override { if (&queue != this) { this->clear(); const FwSizeType size = FW_MIN(queue.getSize(), this->getCapacity()); for (FwSizeType i = 0; i < size; i++) { - T value; - auto status = queue.peek(value, i); - FW_ASSERT(status == Fw::Success::SUCCESS, static_cast(status)); - status = this->enqueue(value); + const auto status = this->enqueue(this->getElementAtIndex(i)); FW_ASSERT(status == Fw::Success::SUCCESS, static_cast(status)); } } @@ -134,9 +131,8 @@ class ExternalFifoQueue final : public FifoQueueBase { ) const override { auto status = Success::FAILURE; const auto size = this->getSize(); - if (size > 0) { - auto ci = this->m_enqueueIndex; - e = this->m_items[ci.increment(index)]; + if (index < size) { + e = this->getElementAtIndex(index); status = Success::SUCCESS; } return status; @@ -144,7 +140,7 @@ class ExternalFifoQueue final : public FifoQueueBase { //! Dequeue an element (pop from the left) //! \return SUCCESS if element dequeued - virtual Success dequeue(T& e //!< The element (output) + Success dequeue(T& e //!< The element (output) ) override { auto status = this->peek(e); if (this->m_size > 0) { @@ -164,6 +160,18 @@ class ExternalFifoQueue final : public FifoQueueBase { //! \return The capacity FwSizeType getCapacity() const override { return this->m_items.getSize(); } + private: + // ---------------------------------------------------------------------- + // Private member functions + // ---------------------------------------------------------------------- + + //! Get an element at an index + const T& getElementAtIndex(FwSizeType index //!< The index + ) const { + auto ci = this->m_enqueueIndex; + return this->m_items[ci.increment(index)]; + } + private: // ---------------------------------------------------------------------- // Private member variables From b6c5df1bf808caf17243d17f7f9c0d6b863f3c0e Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 4 Jun 2025 21:26:01 -0700 Subject: [PATCH 126/458] Revise FifoQueue --- Fw/DataStructures/ExternalFifoQueue.hpp | 12 ++++++++---- Fw/DataStructures/docs/ExternalFifoQueue.md | 12 ++++++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/Fw/DataStructures/ExternalFifoQueue.hpp b/Fw/DataStructures/ExternalFifoQueue.hpp index 01095c932eb..9b66d0be8fa 100644 --- a/Fw/DataStructures/ExternalFifoQueue.hpp +++ b/Fw/DataStructures/ExternalFifoQueue.hpp @@ -94,8 +94,10 @@ class ExternalFifoQueue final : public FifoQueueBase { FwSizeType capacity //!< The capacity ) { this->m_items.setStorage(items, capacity); - this->m_enqueueIndex.setModulus(capacity); - this->m_dequeueIndex.setModulus(capacity); + if (capacity > 0) { + this->m_enqueueIndex.setModulus(capacity); + this->m_dequeueIndex.setModulus(capacity); + } this->clear(); } @@ -104,8 +106,10 @@ class ExternalFifoQueue final : public FifoQueueBase { FwSizeType capacity //!< The capacity ) { this->m_items.setStorage(data, capacity); - this->m_enqueueIndex.setModulus(capacity); - this->m_dequeueIndex.setModulus(capacity); + if (capacity > 0) { + this->m_enqueueIndex.setModulus(capacity); + this->m_dequeueIndex.setModulus(capacity); + } this->clear(); } diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index 2045620ab10..d7ab11823dc 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -208,9 +208,11 @@ void setStorage(T* items, FwSizeType capacity) 1. Call `m_items.setStorage(items, capacity)`. -1. Call `this->m_enqueueIndex.setModulus(capacity)`. +1. If `capacity > 0` -1. Call `this->m_dequeueIndex.setModulus(capacity)`. + 1. Call `this->m_enqueueIndex.setModulus(capacity)`. + + 1. Call `this->m_dequeueIndex.setModulus(capacity)`. 1. Call `this->clear()`. @@ -230,9 +232,11 @@ void setStorage(ByteArray data, FwSizeType capacity) 1. Call `m_items.setStorage(data, capacity)`. -1. Call `this->m_enqueueIndex.setModulus(capacity)`. +1. If `capacity > 0` + + 1. Call `this->m_enqueueIndex.setModulus(capacity)`. -1. Call `this->m_dequeueIndex.setModulus(capacity)`. + 1. Call `this->m_dequeueIndex.setModulus(capacity)`. 1. Call `this->clear()`. From f7334382af62ebd9ab0b8a050c689bb96ba65e38 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 4 Jun 2025 21:31:33 -0700 Subject: [PATCH 127/458] Revise FifoQueue --- Fw/DataStructures/docs/ExternalFifoQueue.md | 33 +++++++++++++++++++++ Fw/DataStructures/docs/FifoQueueBase.md | 21 +++---------- 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index d7ab11823dc..0f55f652074 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -248,6 +248,39 @@ ExternalFifoQueue queue; queue.setStorage(ByteArray(&bytes[0], sizeof bytes), capacity); ``` +### 5.2. copyDataFrom + +```c++ +void copyDataFrom(const FifoQueueBase& queue) +``` + +1. If `&queue != this` + + 1. Call `clear()`. + + 1. Let `size` be the minimum of `queue.getSize()` and `getCapacity()`. + + 1. For `i` in [0, `size`) + + 1. Let `e` be the element at index `i`. + + 1. Set `status = enqueue(e)`. + + 1. Assert `status == Success::SUCCESS`. + +_Example:_ +```c++ +ExternalFifoQueue& q1, ExternalFifoQueue& q2); +q1.clear(); +// Enqueue an item +U32 value = 42; +(void) q1.enqueue(value); +q2.clear(); +ASSERT_EQ(q2.getSize(), 0); +q2.copyDataFrom(q1); +ASSERT_EQ(q2.getSize(), 1); +``` + ### 5.5. enqueue ```c++ diff --git a/Fw/DataStructures/docs/FifoQueueBase.md b/Fw/DataStructures/docs/FifoQueueBase.md index 94962561c79..824a1dfbb91 100644 --- a/Fw/DataStructures/docs/FifoQueueBase.md +++ b/Fw/DataStructures/docs/FifoQueueBase.md @@ -71,28 +71,15 @@ void f(FifoQueueBase& queue) { ### 5.2. copyDataFrom ```c++ -void copyDataFrom(const FifoQueueBase& queue) +void copyDataFrom(const FifoQueueBase& queue) = 0 ``` -1. If `&queue == this` then do nothing. - -1. Otherwise +1. If `&queue != this` then 1. Call `clear()`. - 1. Let `size` be the minimum of `queue.getSize()` and `getCapacity()`. - - 1. For `i` in [0, `size`) - - 1. Set `T value = {}`. - - 1. Set `status = queue.peek(value)`. - - 1. Assert `status == Success::SUCCESS`. - - 1. Set `status = enqueue(value)`. - - 1. Assert `status == Success::SUCCESS`. + 1. For each item `e` on `queue`, in left-to-right order, + enqueue `e`. _Example:_ ```c++ From 7aec8bb5ed5f1f32b513386f8657749a24b4dd63 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 4 Jun 2025 21:38:50 -0700 Subject: [PATCH 128/458] Revise FifoQueue --- Fw/DataStructures/docs/ExternalFifoQueue.md | 61 +++++++++++++++++---- Fw/DataStructures/docs/FifoQueueBase.md | 4 +- 2 files changed, 54 insertions(+), 11 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index 0f55f652074..1337a431f71 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -69,7 +69,7 @@ U32 items[capacity]; ExternalFifoQueue queue(items, capacity); ``` -### 4.2. Constructor Providing Untyped Backing Storage +### 4.3. Constructor Providing Untyped Backing Storage ```c++ ExternalFifoQueue(ByteArray data, FwSizeType capacity) @@ -86,7 +86,7 @@ alignas(U32) U8 bytes[capacity * sizeof(U32)]; ExternalFifoQueue queue(ByteArray(&bytes[0], sizeof bytes), capacity); ``` -### 4.3. Copy Constructor +### 4.4. Copy Constructor ```c++ ExternalFifoQueue(const ExternalFifoQueue& queue) @@ -108,7 +108,7 @@ ExternalFifoQueue q2(q1); ASSERT_EQ(q2.getSize(), 1); ``` -### 4.4. Destructor +### 4.5. Destructor ```c++ ~ExternalFifoQueue() override @@ -224,7 +224,7 @@ U32 items[capacity]; queue.setStorage(items, capacity); ``` -### 5.4. setStorage (Untyped Data) +### 5.5. setStorage (Untyped Data) ```c++ void setStorage(ByteArray data, FwSizeType capacity) @@ -248,10 +248,10 @@ ExternalFifoQueue queue; queue.setStorage(ByteArray(&bytes[0], sizeof bytes), capacity); ``` -### 5.2. copyDataFrom +### 5.6. copyDataFrom ```c++ -void copyDataFrom(const FifoQueueBase& queue) +void copyDataFrom(const FifoQueueBase& queue) override ``` 1. If `&queue != this` @@ -281,7 +281,7 @@ q2.copyDataFrom(q1); ASSERT_EQ(q2.getSize(), 1); ``` -### 5.5. enqueue +### 5.7. enqueue ```c++ Success enqueue(const T& e) override @@ -312,7 +312,48 @@ ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(queue.getSize(), 1); ``` -### 5.6. dequeue +### 5.8. peek + +```c++ +Success peek(T& e, FwSizeType index = 0) override +``` + +1. Set `status = Success::FAILURE`. + +1. If `index < getSize()` + + 1. Let `e1` be the element at index `index`. + Index 0 is the leftmost (earliest) element in the queue. + Increasing indices go from left to right. + + 1. Set `e = e1`. + + 1. Set `status = Success::SUCCESS`. + +1. Return `status`. + +_Example:_ +```c++ +constexpr FwSizeType size = 10; +U32 items[size]; +ExternalFifoQueue queue(items, size); +U32 value = 0; +auto status = queue.peek(value); +ASSERT_EQ(status, Success::FAILURE); +status = queue.enqueue(3); +status = queue.peek(value); +ASSERT_EQ(status, Success::SUCCESS); +ASSERT_EQ(value, 3); +status = queue.peek(value, 1); +ASSERT_EQ(status, Success::FAILURE); +status = queue.enqueue(4); +status = queue.peek(value, 1); +ASSERT_EQ(status, Success::SUCCESS); +ASSERT_EQ(value, 4); +} +``` + +### 5.9. dequeue ```c++ Success dequeue(T& e) override @@ -347,7 +388,7 @@ ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(val, 42); ``` -### 5.7. getSize +### 5.10. getSize ```c++ FwSizeType getSize() const override @@ -368,7 +409,7 @@ size = queue.getSize(); ASSERT_EQ(size, 1); ``` -### 5.8. getCapacity +### 5.11. getCapacity ```c++ FwSizeType getCapacity() const override diff --git a/Fw/DataStructures/docs/FifoQueueBase.md b/Fw/DataStructures/docs/FifoQueueBase.md index 824a1dfbb91..937d6db2a17 100644 --- a/Fw/DataStructures/docs/FifoQueueBase.md +++ b/Fw/DataStructures/docs/FifoQueueBase.md @@ -130,10 +130,12 @@ Success peek(T& e, FwSizeType index = 0) const = 0 1. If `index < getSize()` - 1. Assign the element at index `index` to `e`. + 1. Let `e1` be the element at index `index`. Index 0 is the leftmost (earliest) element in the queue. Increasing indices go from left to right. + 1. Set `e = e1`. + 1. Set `status = Success::SUCCESS`. 1. Return `status`. From 1fe904f9754860597e8f9d2cc38073321e4e15db Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 4 Jun 2025 21:48:31 -0700 Subject: [PATCH 129/458] Revise FifoQueue --- Fw/DataStructures/ExternalFifoQueue.hpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Fw/DataStructures/ExternalFifoQueue.hpp b/Fw/DataStructures/ExternalFifoQueue.hpp index 9b66d0be8fa..530f4a4349e 100644 --- a/Fw/DataStructures/ExternalFifoQueue.hpp +++ b/Fw/DataStructures/ExternalFifoQueue.hpp @@ -134,8 +134,7 @@ class ExternalFifoQueue final : public FifoQueueBase { FwSizeType index = 0 //!< The index (input) ) const override { auto status = Success::FAILURE; - const auto size = this->getSize(); - if (index < size) { + if (index < this->m_size) { e = this->getElementAtIndex(index); status = Success::SUCCESS; } @@ -146,10 +145,9 @@ class ExternalFifoQueue final : public FifoQueueBase { //! \return SUCCESS if element dequeued Success dequeue(T& e //!< The element (output) ) override { - auto status = this->peek(e); + auto status = Success::FAILURE; if (this->m_size > 0) { - const auto i = this->m_dequeueIndex.getValue(); - e = this->m_items[i]; + e = this->getElementAtIndex(0); (void)this->m_dequeueIndex.increment(); this->m_size--; } From d28ac1b194629783f79434d46fd04c136e780c3b Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 4 Jun 2025 21:58:46 -0700 Subject: [PATCH 130/458] Revise FifoQueue --- Fw/DataStructures/docs/ExternalFifoQueue.md | 43 +++++---------------- Fw/DataStructures/docs/FifoQueue.md | 40 +++++++++++-------- 2 files changed, 32 insertions(+), 51 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index 1337a431f71..d3038b46706 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -1,4 +1,3 @@ -# ExternalFifoQueue `ExternalFifoQueue` is a `final` class template defined in [`Fw/DataStructures`](sdd.md). @@ -153,31 +152,7 @@ q2 = q1; ASSERT_EQ(q2.getSize(), 1); ``` -### 5.2. at - -```c++ -const T& at(FwSizeType i) const override -``` - -1. Assert that `i < m_size`. - -1. Set `ci = m_enqueueIndex`. - -1. Return `m_items[ci.increment(i)]`. - -_Example:_ -```c++ -constexpr FwSizeType capacity = 10; -U32 items[size] = {}; -ExternalFifoQueue queue(items, capacity); -const auto status = queue.enqueue(3); -// Constant access -ASSERT_EQ(queue.at(0), 3); -// Out-of-bounds access -ASSERT_DEATH(queue.at(1), "Assert"); -``` - -### 5.3. clear +### 5.2. clear ```c++ void clear() override @@ -200,7 +175,7 @@ queue.clear(); ASSERT_EQ(queue.getSize(), 0); ``` -### 5.4. setStorage (Typed Data) +### 5.3. setStorage (Typed Data) ```c++ void setStorage(T* items, FwSizeType capacity) @@ -224,7 +199,7 @@ U32 items[capacity]; queue.setStorage(items, capacity); ``` -### 5.5. setStorage (Untyped Data) +### 5.4. setStorage (Untyped Data) ```c++ void setStorage(ByteArray data, FwSizeType capacity) @@ -248,7 +223,7 @@ ExternalFifoQueue queue; queue.setStorage(ByteArray(&bytes[0], sizeof bytes), capacity); ``` -### 5.6. copyDataFrom +### 5.5. copyDataFrom ```c++ void copyDataFrom(const FifoQueueBase& queue) override @@ -281,7 +256,7 @@ q2.copyDataFrom(q1); ASSERT_EQ(q2.getSize(), 1); ``` -### 5.7. enqueue +### 5.6. enqueue ```c++ Success enqueue(const T& e) override @@ -312,7 +287,7 @@ ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(queue.getSize(), 1); ``` -### 5.8. peek +### 5.7. peek ```c++ Success peek(T& e, FwSizeType index = 0) override @@ -353,7 +328,7 @@ ASSERT_EQ(value, 4); } ``` -### 5.9. dequeue +### 5.8. dequeue ```c++ Success dequeue(T& e) override @@ -388,7 +363,7 @@ ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(val, 42); ``` -### 5.10. getSize +### 5.9. getSize ```c++ FwSizeType getSize() const override @@ -409,7 +384,7 @@ size = queue.getSize(); ASSERT_EQ(size, 1); ``` -### 5.11. getCapacity +### 5.10. getCapacity ```c++ FwSizeType getCapacity() const override diff --git a/Fw/DataStructures/docs/FifoQueue.md b/Fw/DataStructures/docs/FifoQueue.md index a4d2f9132f9..85eaf868025 100644 --- a/Fw/DataStructures/docs/FifoQueue.md +++ b/Fw/DataStructures/docs/FifoQueue.md @@ -83,23 +83,13 @@ Defined as `= default`. ## 5. Public Member Functions -### 5.1. at - -```c++ -const T& operator[](FwSizeType i) const override -``` - -Return `m_extQueue(i)`. - -### 5.2. operator= +### 5.1. operator= ```c++ FifoQueue& operator=(const FifoQueue& queue) ``` -1. Set `status = m_extQueue.copyDataFrom(queue.m_extQueue)`. - -1. Assert `status == Success::SUCCESS`. +Call `m_extQueue.copyDataFrom(queue.m_extQueue)`. _Example:_ ```c++ @@ -116,7 +106,7 @@ ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(value, 3); ``` -### 5.3. clear +### 5.2. clear ```c++ void clear() override @@ -124,6 +114,14 @@ void clear() override Call `m_extQueue.clear()`. +### 5.3. copyDataFrom + +```c++ +void copyDataFrom(const FifoQueueBase& queue) override +``` + +Call `m_extQueue.copyDataFrom(queue)`. + ### 5.4. enqueue ```c++ @@ -132,7 +130,15 @@ Success enqueue(const T& e) override Return `m_extQueue.enqueue(e)`. -### 5.5. dequeue +### 5.5. peek + +```c++ +Success peek(T& e, FwSizeType index = 0) override +``` + +Return `m_extQueue.peek(e, index)`. + +### 5.6. dequeue ```c++ Success dequeue(T& e) override @@ -140,7 +146,7 @@ Success dequeue(T& e) override Return `m_extQueue.dequeue(e)`. -### 5.6. getSize +### 5.7. getSize ```c++ FwSizeType getSize() const @@ -148,7 +154,7 @@ FwSizeType getSize() const Return `m_extQueue.getSize()`. -### 5.7. getCapacity +### 5.8. getCapacity ```c++ FwSizeType getCapacity() const @@ -156,7 +162,7 @@ FwSizeType getCapacity() const Return `m_extQueue.getCapacity()`. -### 5.8. asExternalFifoQueue +### 5.9. asExternalFifoQueue ```c++ ExternalFifoQueue asExternalFifoQueue() From 00500149a91bb83f4b0b7f003499ad30475c02b5 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 4 Jun 2025 22:36:42 -0700 Subject: [PATCH 131/458] Revise FifoQueue --- Fw/DataStructures/ExternalFifoQueue.hpp | 7 ++-- .../test/ut/ExternalFifoQueueTest.cpp | 36 +++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/ExternalFifoQueue.hpp b/Fw/DataStructures/ExternalFifoQueue.hpp index 530f4a4349e..9644b7c276c 100644 --- a/Fw/DataStructures/ExternalFifoQueue.hpp +++ b/Fw/DataStructures/ExternalFifoQueue.hpp @@ -123,6 +123,7 @@ class ExternalFifoQueue final : public FifoQueueBase { this->m_items[i] = e; (void)this->m_enqueueIndex.increment(); this->m_size++; + status = Success::SUCCESS; } return status; } @@ -150,6 +151,7 @@ class ExternalFifoQueue final : public FifoQueueBase { e = this->getElementAtIndex(0); (void)this->m_dequeueIndex.increment(); this->m_size--; + status = Success::SUCCESS; } return status; } @@ -170,8 +172,9 @@ class ExternalFifoQueue final : public FifoQueueBase { //! Get an element at an index const T& getElementAtIndex(FwSizeType index //!< The index ) const { - auto ci = this->m_enqueueIndex; - return this->m_items[ci.increment(index)]; + auto ci = this->m_dequeueIndex; + const auto i = ci.increment(index); + return this->m_items[i]; } private: diff --git a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp index e425a1ab350..e1a8e70a461 100644 --- a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp @@ -7,6 +7,7 @@ #include #include "Fw/DataStructures/ExternalFifoQueue.hpp" +#include "STest/Pick/Pick.hpp" namespace Fw { @@ -44,6 +45,41 @@ TEST(ExternalFifoQueue, TypedStorageConstructor) { ASSERT_EQ(queue.getSize(), 0); } +TEST(ExternalFifoQueue, UntypedStorageConstructor) { + constexpr FwSizeType capacity = 10; + alignas(U32) U8 bytes[capacity * sizeof(U32)]; + ExternalFifoQueue queue(ByteArray(&bytes[0], sizeof bytes), capacity); + ExternalFifoQueueTester tester(queue); + ASSERT_EQ(tester.getItems().getElements(), reinterpret_cast(bytes)); + ASSERT_EQ(queue.getCapacity(), capacity); + ASSERT_EQ(queue.getSize(), 0); +} + +TEST(ExternalFifoQueue, EnqueueOK) { + constexpr const FwSizeType capacity = 1000; + const FwSizeType size = STest::Pick::lowerUpper(1, capacity); + U32 elts[capacity]; + ExternalFifoQueue queue(elts, capacity); + ASSERT_EQ(queue.getCapacity(), capacity); + ASSERT_EQ(queue.getSize(), 0); + for (FwSizeType i = 0; i < size; i++) { + // Pick a value + const U32 val = STest::Pick::any(); + // Enqueue it + auto status = queue.enqueue(val); + ASSERT_EQ(status, Fw::Success::SUCCESS); + // Peek it + U32 val1 = 0; + status = queue.peek(val1, i); + ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(val1, val); + // Check the size + ASSERT_EQ(queue.getSize(), i + 1); + } + queue.clear(); + ASSERT_EQ(queue.getSize(), 0); +} + TEST(ExternalFifoQueue, CopyConstructor) { constexpr FwSizeType capacity = 3; U32 items[capacity]; From 20f6361106b53b71fc52c2d17c0cc82b297db4aa Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 4 Jun 2025 23:22:49 -0700 Subject: [PATCH 132/458] Revise FifoQueue --- Fw/DataStructures/ExternalFifoQueue.hpp | 15 +- Fw/DataStructures/FifoQueueBase.hpp | 23 ++- .../test/ut/ExternalArrayTest.cpp | 6 +- .../test/ut/ExternalFifoQueueTest.cpp | 154 ++++++++++++++---- 4 files changed, 153 insertions(+), 45 deletions(-) diff --git a/Fw/DataStructures/ExternalFifoQueue.hpp b/Fw/DataStructures/ExternalFifoQueue.hpp index 9644b7c276c..c185b9f0177 100644 --- a/Fw/DataStructures/ExternalFifoQueue.hpp +++ b/Fw/DataStructures/ExternalFifoQueue.hpp @@ -76,19 +76,6 @@ class ExternalFifoQueue final : public FifoQueueBase { this->m_size = 0; } - //! Copy data from another queue - void copyDataFrom(const FifoQueueBase& queue //!< The queue - ) override { - if (&queue != this) { - this->clear(); - const FwSizeType size = FW_MIN(queue.getSize(), this->getCapacity()); - for (FwSizeType i = 0; i < size; i++) { - const auto status = this->enqueue(this->getElementAtIndex(i)); - FW_ASSERT(status == Fw::Success::SUCCESS, static_cast(status)); - } - } - } - //! Set the storage (typed data) void setStorage(T* items, //!< The items FwSizeType capacity //!< The capacity @@ -171,7 +158,7 @@ class ExternalFifoQueue final : public FifoQueueBase { //! Get an element at an index const T& getElementAtIndex(FwSizeType index //!< The index - ) const { + ) const override { auto ci = this->m_dequeueIndex; const auto i = ci.increment(index); return this->m_items[i]; diff --git a/Fw/DataStructures/FifoQueueBase.hpp b/Fw/DataStructures/FifoQueueBase.hpp index f48bdbab796..ca0e5e5b9ce 100644 --- a/Fw/DataStructures/FifoQueueBase.hpp +++ b/Fw/DataStructures/FifoQueueBase.hpp @@ -54,8 +54,17 @@ class FifoQueueBase { virtual void clear() = 0; //! Copy data from another queue - virtual void copyDataFrom(const FifoQueueBase& queue //!< The queue - ) = 0; + void copyDataFrom(const FifoQueueBase& queue //!< The queue + ) { + if (&queue != this) { + this->clear(); + const FwSizeType size = FW_MIN(queue.getSize(), this->getCapacity()); + for (FwSizeType i = 0; i < size; i++) { + const auto status = this->enqueue(queue.getElementAtIndex(i)); + FW_ASSERT(status == Fw::Success::SUCCESS, static_cast(status)); + } + } + } //! Enqueue an element (add to the right) //! \return SUCCESS if element enqueued @@ -81,6 +90,16 @@ class FifoQueueBase { //! Get the capacity (maximum number of items stored in the queue) //! \return The capacity virtual FwSizeType getCapacity() const = 0; + + protected: + // ---------------------------------------------------------------------- + // Protected member functions + // ---------------------------------------------------------------------- + + //! Get an element at an index + //! Indices go from left to right in the queue + virtual const T& getElementAtIndex(FwSizeType index //!< The index + ) const = 0; }; } // namespace Fw diff --git a/Fw/DataStructures/test/ut/ExternalArrayTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayTest.cpp index 5d9ac6b444b..4a194022a61 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayTest.cpp @@ -55,7 +55,9 @@ TEST(ExternalArray, CopyAssignment) { ASSERT_EQ(a1.getSize(), a2.getSize()); } -static void testCopyDataFrom(ExternalArray a1, ExternalArray a2) { +namespace { + +void testCopyDataFrom(ExternalArray a1, ExternalArray a2) { const FwSizeType size1 = a1.getSize(); for (FwSizeType i = 0; i < size1; i++) { a1[i] = static_cast(i); @@ -71,6 +73,8 @@ static void testCopyDataFrom(ExternalArray a1, ExternalArray a2) { } } +} // namespace + TEST(ExternalArray, CopyDataFrom) { constexpr FwSizeType maxSize = 10; constexpr FwSizeType smallSize = maxSize / 2; diff --git a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp index e1a8e70a461..a84065792be 100644 --- a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp @@ -11,10 +11,9 @@ namespace Fw { -template class ExternalFifoQueueTester { - +template +class ExternalFifoQueueTester { public: - ExternalFifoQueueTester(const ExternalFifoQueue& queue) : m_queue(queue) {} const ExternalArray getItems() const { return this->m_queue.m_items; } @@ -24,9 +23,7 @@ template class ExternalFifoQueueTester { const CircularIndex& getDequeueIndex() const { return this->m_queue.m_dequeueIndex; } private: - const ExternalFifoQueue& m_queue; - }; TEST(ExternalFifoQueue, ZeroArgConstructor) { @@ -56,28 +53,43 @@ TEST(ExternalFifoQueue, UntypedStorageConstructor) { } TEST(ExternalFifoQueue, EnqueueOK) { - constexpr const FwSizeType capacity = 1000; - const FwSizeType size = STest::Pick::lowerUpper(1, capacity); - U32 elts[capacity]; - ExternalFifoQueue queue(elts, capacity); - ASSERT_EQ(queue.getCapacity(), capacity); - ASSERT_EQ(queue.getSize(), 0); - for (FwSizeType i = 0; i < size; i++) { - // Pick a value + constexpr const FwSizeType capacity = 1000; + const FwSizeType size = STest::Pick::lowerUpper(1, capacity); + U32 elts[capacity]; + ExternalFifoQueue queue(elts, capacity); + ASSERT_EQ(queue.getCapacity(), capacity); + ASSERT_EQ(queue.getSize(), 0); + for (FwSizeType i = 0; i < size; i++) { + // Pick a value + const U32 val = STest::Pick::any(); + // Enqueue it + auto status = queue.enqueue(val); + ASSERT_EQ(status, Fw::Success::SUCCESS); + // Peek it + U32 val1 = 0; + status = queue.peek(val1, i); + ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(val1, val); + // Check the size + ASSERT_EQ(queue.getSize(), i + 1); + } + queue.clear(); + ASSERT_EQ(queue.getSize(), 0); +} + +TEST(ArrayFIFO, EnqueueFull) { + constexpr const FwSizeType capacity = 1000; + U32 elts[capacity]; + ExternalFifoQueue queue(elts, capacity); + // Fill up the FIFO + for (FwSizeType i = 0; i < capacity; i++) { + queue.enqueue(0); + } + // Now try to push another element const U32 val = STest::Pick::any(); - // Enqueue it - auto status = queue.enqueue(val); - ASSERT_EQ(status, Fw::Success::SUCCESS); - // Peek it - U32 val1 = 0; - status = queue.peek(val1, i); - ASSERT_EQ(status, Fw::Success::SUCCESS); - ASSERT_EQ(val1, val); - // Check the size - ASSERT_EQ(queue.getSize(), i + 1); - } - queue.clear(); - ASSERT_EQ(queue.getSize(), 0); + const auto status = queue.enqueue(val); + // Push should fail + ASSERT_EQ(status, Fw::Success::FAILURE); } TEST(ExternalFifoQueue, CopyConstructor) { @@ -87,7 +99,7 @@ TEST(ExternalFifoQueue, CopyConstructor) { ExternalFifoQueue q1(items, capacity); // Enqueue an item U32 value = 42; - (void) q1.enqueue(value); + (void)q1.enqueue(value); // Call the copy constructor ExternalFifoQueue q2(q1); ExternalFifoQueueTester tester1(q1); @@ -106,7 +118,7 @@ TEST(ExternalFifoQueue, CopyAssignmentOperator) { ExternalFifoQueue q1(items, capacity); // Enqueue an item U32 value = 42; - (void) q1.enqueue(value); + (void)q1.enqueue(value); // Call the default constructor ExternalFifoQueue q2; ASSERT_EQ(q2.getSize(), 0); @@ -115,4 +127,90 @@ TEST(ExternalFifoQueue, CopyAssignmentOperator) { ASSERT_EQ(q2.getSize(), 1); } +TEST(ExternalFifoQueue, DequeueOK) { + constexpr const FwSizeType capacity = 1000; + const FwSizeType size = STest::Pick::lowerUpper(1, capacity); + U32 items[capacity]; + ExternalFifoQueue queue(items, capacity); + ASSERT_EQ(queue.getCapacity(), capacity); + ASSERT_EQ(queue.getSize(), 0); + for (FwSizeType i = 0; i < size; i++) { + // Pick a value + const U32 val = STest::Pick::any(); + // Enqueue it + const auto status = queue.enqueue(val); + ASSERT_EQ(val, items[i]); + ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(queue.getSize(), i + 1); + } + for (FwSizeType i = 0; i < size; i++) { + U32 val = 0; + // Peek + auto status = queue.peek(val); + ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(val, items[i]); + // Dequeue it + status = queue.dequeue(val); + ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(val, items[i]); + ASSERT_EQ(queue.getSize(), size - i - 1); + } + ASSERT_EQ(queue.getSize(), 0); +} + +TEST(ExternalFifoQueue, DequeueEmpty) { + constexpr const FwSizeType capacity = 1000; + U32 items[capacity]; + ExternalFifoQueue queue(items, capacity); + U32 val = 0; + const auto status = queue.dequeue(val); + ASSERT_EQ(status, Fw::Success::FAILURE); +} + +namespace { + +void testCopyDataFrom(FifoQueueBase& q1, FwSizeType size1, FifoQueueBase& q2) { + q1.clear(); + for (FwSizeType i = 0; i < size1; i++) { + const auto status = q1.enqueue(static_cast(i)); + ASSERT_EQ(status, Success::SUCCESS); + } + q2.copyDataFrom(q1); + const auto capacity2 = q2.getCapacity(); + const FwSizeType size = FW_MIN(size1, capacity2); + for (FwSizeType i = 0; i < size; i++) { + U32 val1 = 0; + auto status = q1.peek(val1, i); + ASSERT_EQ(status, Success::SUCCESS); + U32 val2 = 1; + status = q2.peek(val2, i); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(val1, val2); + } +} + +} // namespace + +TEST(ExternalFifoQueue, CopyDataFrom) { + constexpr FwSizeType maxSize = 10; + constexpr FwSizeType smallSize = maxSize / 2; + U32 items1[maxSize]; + U32 items2[maxSize]; + ExternalFifoQueue q1(items1, maxSize); + // size1 < capacity2 + { + ExternalFifoQueue q2(items2, maxSize); + testCopyDataFrom(q1, smallSize, q2); + } + // size1 == size2 + { + ExternalFifoQueue q2(items2, maxSize); + testCopyDataFrom(q1, maxSize, q2); + } + // size1 > size2 + { + ExternalFifoQueue q2(items2, smallSize); + testCopyDataFrom(q1, maxSize, q2); + } +} } // namespace Fw From 019f3fd761ca3bff47109f83103bfc55626bf56d Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 4 Jun 2025 23:35:51 -0700 Subject: [PATCH 133/458] Revise FifoQueues --- Fw/DataStructures/ExternalFifoQueue.hpp | 22 ++--- Fw/DataStructures/FifoQueueBase.hpp | 37 +++++--- Fw/DataStructures/docs/ExternalFifoQueue.md | 96 ++++----------------- Fw/DataStructures/docs/FifoQueueBase.md | 35 ++++++-- 4 files changed, 72 insertions(+), 118 deletions(-) diff --git a/Fw/DataStructures/ExternalFifoQueue.hpp b/Fw/DataStructures/ExternalFifoQueue.hpp index c185b9f0177..5df73ed0424 100644 --- a/Fw/DataStructures/ExternalFifoQueue.hpp +++ b/Fw/DataStructures/ExternalFifoQueue.hpp @@ -115,27 +115,13 @@ class ExternalFifoQueue final : public FifoQueueBase { return status; } - //! Peek an element at an index - //! Indices go from left to right in the range [0, size) - //! \return SUCCESS if element exists - Success peek(T& e, //!< The element (output) - FwSizeType index = 0 //!< The index (input) - ) const override { - auto status = Success::FAILURE; - if (index < this->m_size) { - e = this->getElementAtIndex(index); - status = Success::SUCCESS; - } - return status; - } - //! Dequeue an element (pop from the left) //! \return SUCCESS if element dequeued Success dequeue(T& e //!< The element (output) ) override { auto status = Success::FAILURE; if (this->m_size > 0) { - e = this->getElementAtIndex(0); + e = this->getItemAtIndex(0); (void)this->m_dequeueIndex.increment(); this->m_size--; status = Success::SUCCESS; @@ -156,8 +142,10 @@ class ExternalFifoQueue final : public FifoQueueBase { // Private member functions // ---------------------------------------------------------------------- - //! Get an element at an index - const T& getElementAtIndex(FwSizeType index //!< The index + //! Get an item at an index + //! Indices go from left to right in the queue + //! \return The item + const T& getItemAtIndex(FwSizeType index //!< The index ) const override { auto ci = this->m_dequeueIndex; const auto i = ci.increment(index); diff --git a/Fw/DataStructures/FifoQueueBase.hpp b/Fw/DataStructures/FifoQueueBase.hpp index ca0e5e5b9ce..79c8967566d 100644 --- a/Fw/DataStructures/FifoQueueBase.hpp +++ b/Fw/DataStructures/FifoQueueBase.hpp @@ -60,27 +60,35 @@ class FifoQueueBase { this->clear(); const FwSizeType size = FW_MIN(queue.getSize(), this->getCapacity()); for (FwSizeType i = 0; i < size; i++) { - const auto status = this->enqueue(queue.getElementAtIndex(i)); + const auto& e = queue.getItemAtIndex(i); + const auto status = this->enqueue(e); FW_ASSERT(status == Fw::Success::SUCCESS, static_cast(status)); } } } - //! Enqueue an element (add to the right) - //! \return SUCCESS if element enqueued - virtual Success enqueue(const T& e //!< The element (output) + //! Enqueue an item (add to the right) + //! \return SUCCESS if item enqueued + virtual Success enqueue(const T& e //!< The item (output) ) = 0; - //! Peek an element at an index + //! Peek an item at an index //! Indices go from left to right in the range [0, size) - //! \return SUCCESS if element exists - virtual Success peek(T& e, //!< The element (output) - FwSizeType index = 0 //!< The index (input) - ) const = 0; + //! \return SUCCESS if item exists + Success peek(T& e, //!< The item (output) + FwSizeType index = 0 //!< The index (input) + ) const { + auto status = Success::FAILURE; + if (index < this->getSize()) { + e = this->getItemAtIndex(index); + status = Success::SUCCESS; + } + return status; + } - //! Dequeue an element (pop from the left) - //! \return SUCCESS if element dequeued - virtual Success dequeue(T& e //!< The element (output) + //! Dequeue an item (pop from the left) + //! \return SUCCESS if item dequeued + virtual Success dequeue(T& e //!< The item (output) ) = 0; //! Get the size (number of items stored in the queue) @@ -96,9 +104,10 @@ class FifoQueueBase { // Protected member functions // ---------------------------------------------------------------------- - //! Get an element at an index + //! Get an item at an index //! Indices go from left to right in the queue - virtual const T& getElementAtIndex(FwSizeType index //!< The index + //! \return The item + virtual const T& getItemAtIndex(FwSizeType index //!< The index ) const = 0; }; diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index d3038b46706..6d823c6ce44 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -223,40 +223,7 @@ ExternalFifoQueue queue; queue.setStorage(ByteArray(&bytes[0], sizeof bytes), capacity); ``` -### 5.5. copyDataFrom - -```c++ -void copyDataFrom(const FifoQueueBase& queue) override -``` - -1. If `&queue != this` - - 1. Call `clear()`. - - 1. Let `size` be the minimum of `queue.getSize()` and `getCapacity()`. - - 1. For `i` in [0, `size`) - - 1. Let `e` be the element at index `i`. - - 1. Set `status = enqueue(e)`. - - 1. Assert `status == Success::SUCCESS`. - -_Example:_ -```c++ -ExternalFifoQueue& q1, ExternalFifoQueue& q2); -q1.clear(); -// Enqueue an item -U32 value = 42; -(void) q1.enqueue(value); -q2.clear(); -ASSERT_EQ(q2.getSize(), 0); -q2.copyDataFrom(q1); -ASSERT_EQ(q2.getSize(), 1); -``` - -### 5.6. enqueue +### 5.5. enqueue ```c++ Success enqueue(const T& e) override @@ -287,48 +254,7 @@ ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(queue.getSize(), 1); ``` -### 5.7. peek - -```c++ -Success peek(T& e, FwSizeType index = 0) override -``` - -1. Set `status = Success::FAILURE`. - -1. If `index < getSize()` - - 1. Let `e1` be the element at index `index`. - Index 0 is the leftmost (earliest) element in the queue. - Increasing indices go from left to right. - - 1. Set `e = e1`. - - 1. Set `status = Success::SUCCESS`. - -1. Return `status`. - -_Example:_ -```c++ -constexpr FwSizeType size = 10; -U32 items[size]; -ExternalFifoQueue queue(items, size); -U32 value = 0; -auto status = queue.peek(value); -ASSERT_EQ(status, Success::FAILURE); -status = queue.enqueue(3); -status = queue.peek(value); -ASSERT_EQ(status, Success::SUCCESS); -ASSERT_EQ(value, 3); -status = queue.peek(value, 1); -ASSERT_EQ(status, Success::FAILURE); -status = queue.enqueue(4); -status = queue.peek(value, 1); -ASSERT_EQ(status, Success::SUCCESS); -ASSERT_EQ(value, 4); -} -``` - -### 5.8. dequeue +### 5.6. dequeue ```c++ Success dequeue(T& e) override @@ -363,7 +289,7 @@ ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(val, 42); ``` -### 5.9. getSize +### 5.7. getSize ```c++ FwSizeType getSize() const override @@ -384,7 +310,7 @@ size = queue.getSize(); ASSERT_EQ(size, 1); ``` -### 5.10. getCapacity +### 5.8. getCapacity ```c++ FwSizeType getCapacity() const override @@ -399,3 +325,17 @@ U32 items[capacity]; ExternalFifoQueue queue(items, capacity); ASSERT_EQ(queue.getCapacity(), capacity); ``` + +## 6. Private Member Functions + +### 6.1. getItemAtIndex + +```c++ +const T& getItemAtIndex(FwSizeType index) const override +``` + +1. Set `ci = m_dequeueIndex`. + +1. Set `i = ci.increment(index)`. + +1. Return `m_items[i]`. diff --git a/Fw/DataStructures/docs/FifoQueueBase.md b/Fw/DataStructures/docs/FifoQueueBase.md index 937d6db2a17..338893b3ace 100644 --- a/Fw/DataStructures/docs/FifoQueueBase.md +++ b/Fw/DataStructures/docs/FifoQueueBase.md @@ -71,15 +71,23 @@ void f(FifoQueueBase& queue) { ### 5.2. copyDataFrom ```c++ -void copyDataFrom(const FifoQueueBase& queue) = 0 +void copyDataFrom(const FifoQueueBase& queue) ``` 1. If `&queue != this` then 1. Call `clear()`. - 1. For each item `e` on `queue`, in left-to-right order, - enqueue `e`. + 1. Let `size` be the minimum of `queue.getSize()` and `getCapacity()`. + + 1. For `i` in [0, `size`) + + 1. Set `e = getItemAtIndex(i)`. + + 1. Set `status = enqueue(e)`. + + 1. Assert `status == Success::SUCCESS`. + _Example:_ ```c++ @@ -123,18 +131,14 @@ void f(FifoQueueBase& queue) { ### 5.4. peek ```c++ -Success peek(T& e, FwSizeType index = 0) const = 0 +Success peek(T& e, FwSizeType index = 0) const ``` 1. Set `status = Success::FAILURE`. 1. If `index < getSize()` - 1. Let `e1` be the element at index `index`. - Index 0 is the leftmost (earliest) element in the queue. - Increasing indices go from left to right. - - 1. Set `e = e1`. + 1. Set `e = getItemAtIndex(index)`. 1. Set `status = Success::SUCCESS`. @@ -228,3 +232,16 @@ void f(const FifoQueueBase& queue) { ASSERT_LE(size, capacity); } ``` + +## 6. Protected Member Functions + +### 6.1. getItemAtIndex + +```c++ +virtual const T& getItemAtIndex(FwSizeType index) const = 0 +``` + +Return the item at the specified index. +Index 0 is the leftmost (earliest) element in the queue. +Increasing indices go from left to right. + From 65e7423a5c65b9a33bbc2c2cc11298ccdb868341 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 4 Jun 2025 23:59:59 -0700 Subject: [PATCH 134/458] Revise FifoQueue --- Fw/DataStructures/CMakeLists.txt | 1 + Fw/DataStructures/FifoQueue.hpp | 100 +++++++++ Fw/DataStructures/docs/FifoQueue.md | 40 ++-- Fw/DataStructures/test/ut/FifoQueueTest.cpp | 217 ++++++++++++++++++++ 4 files changed, 335 insertions(+), 23 deletions(-) create mode 100644 Fw/DataStructures/FifoQueue.hpp create mode 100644 Fw/DataStructures/test/ut/FifoQueueTest.cpp diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index d2f92560024..7bc1512d41d 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -10,6 +10,7 @@ set(UT_SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" ) set(UT_MOD_DEPS diff --git a/Fw/DataStructures/FifoQueue.hpp b/Fw/DataStructures/FifoQueue.hpp new file mode 100644 index 00000000000..1a373d77828 --- /dev/null +++ b/Fw/DataStructures/FifoQueue.hpp @@ -0,0 +1,100 @@ +// ====================================================================== +// \file FifoQueue.hpp +// \author bocchino +// \brief A FIFO queue with internal storage +// ====================================================================== + +#ifndef Fw_FifoQueue_HPP +#define Fw_FifoQueue_HPP + +#include "Fw/DataStructures/ExternalFifoQueue.hpp" +#include "Fw/DataStructures/Array.hpp" + +namespace Fw { + +template +class FifoQueue final : public FifoQueueBase { + // ---------------------------------------------------------------------- + // Friend class for testing + // ---------------------------------------------------------------------- + + template + friend class FifoQueueTester; + + public: + // ---------------------------------------------------------------------- + // Public constructors and destructors + // ---------------------------------------------------------------------- + + //! Zero-argument constructor + FifoQueue() = default; + + //! Copy constructor + FifoQueue(const FifoQueue& queue) : FifoQueueBase() { *this = queue; } + + //! Destructor + ~FifoQueue() override = default; + + public: + // ---------------------------------------------------------------------- + // Public member functions + // ---------------------------------------------------------------------- + + //! operator= + FifoQueue& operator=(const FifoQueue& queue) { + this->m_extQueue.copyDataFrom(queue); + } + + //! Clear the queue + void clear() override { this->m_extQueue.clear(); } + + //! Enqueue an item (push on the right) + //! \return SUCCESS if item enqueued + Success enqueue(const T& e //!< The item (output) + ) override { + return this->m_extQueue.enqueue(e); + } + + //! Dequeue an item (pop from the left) + //! \return SUCCESS if item dequeued + Success dequeue(T& e //!< The item (output) + ) override { + return this->m_extQueue.dequeue(e); + } + + //! Get the size (number of items stored in the queue) + //! \return The size + FwSizeType getSize() const override { return this->m_extQueue.getSize(); } + + //! Get the capacity (maximum number of items stored in the queue) + //! \return The capacity + FwSizeType getCapacity() const override { return this->m_extQueue.getCapacity(); } + + private: + // ---------------------------------------------------------------------- + // Private member functions + // ---------------------------------------------------------------------- + + //! Get an item at an index + //! Indices go from left to right in the queue + //! \return The item + const T& getItemAtIndex(FwSizeType index //!< The index + ) const override { return this->m_extQueue.getItemAtIndex(index); + } + + private: + // ---------------------------------------------------------------------- + // Private member variables + // ---------------------------------------------------------------------- + + //! The external queue implementation + ExternalFifoQueue m_extQueue = {}; + + //! The array providing the backing memory for m_extQueue + Array m_array = {}; + +}; + +} // namespace Fw + +#endif diff --git a/Fw/DataStructures/docs/FifoQueue.md b/Fw/DataStructures/docs/FifoQueue.md index 85eaf868025..3fd602da742 100644 --- a/Fw/DataStructures/docs/FifoQueue.md +++ b/Fw/DataStructures/docs/FifoQueue.md @@ -45,7 +45,7 @@ classDiagram FifoQueue() ``` -Initialize each member variable with its default value. +Defined as `= default`. _Example:_ ```c++ @@ -89,7 +89,7 @@ Defined as `= default`. FifoQueue& operator=(const FifoQueue& queue) ``` -Call `m_extQueue.copyDataFrom(queue.m_extQueue)`. +Call `m_extQueue.copyDataFrom(queue)`. _Example:_ ```c++ @@ -114,15 +114,7 @@ void clear() override Call `m_extQueue.clear()`. -### 5.3. copyDataFrom - -```c++ -void copyDataFrom(const FifoQueueBase& queue) override -``` - -Call `m_extQueue.copyDataFrom(queue)`. - -### 5.4. enqueue +### 5.3. enqueue ```c++ Success enqueue(const T& e) override @@ -130,15 +122,7 @@ Success enqueue(const T& e) override Return `m_extQueue.enqueue(e)`. -### 5.5. peek - -```c++ -Success peek(T& e, FwSizeType index = 0) override -``` - -Return `m_extQueue.peek(e, index)`. - -### 5.6. dequeue +### 5.4. dequeue ```c++ Success dequeue(T& e) override @@ -146,7 +130,7 @@ Success dequeue(T& e) override Return `m_extQueue.dequeue(e)`. -### 5.7. getSize +### 5.5. getSize ```c++ FwSizeType getSize() const @@ -154,7 +138,7 @@ FwSizeType getSize() const Return `m_extQueue.getSize()`. -### 5.8. getCapacity +### 5.6. getCapacity ```c++ FwSizeType getCapacity() const @@ -162,7 +146,7 @@ FwSizeType getCapacity() const Return `m_extQueue.getCapacity()`. -### 5.9. asExternalFifoQueue +### 5.7. asExternalFifoQueue ```c++ ExternalFifoQueue asExternalFifoQueue() @@ -194,3 +178,13 @@ _Example:_ const auto capacity = FifoQueue::getStaticCapacity(); ASSERT_EQ(capacity, 3); ``` + +## 7. Private Member Functions + +### 7.1. getItemAtIndex + +```c++ +const T& getItemAtIndex(FwSizeType index) const override +``` + +Return `m_extQueue.getItemAtIndex(index)`. diff --git a/Fw/DataStructures/test/ut/FifoQueueTest.cpp b/Fw/DataStructures/test/ut/FifoQueueTest.cpp new file mode 100644 index 00000000000..14c098b9c73 --- /dev/null +++ b/Fw/DataStructures/test/ut/FifoQueueTest.cpp @@ -0,0 +1,217 @@ +// ====================================================================== +// \title FifoQueueTest.cpp +// \author bocchino +// \brief cpp file for FifoQueue tests +// ====================================================================== + +#include + +#include "Fw/DataStructures/FifoQueue.hpp" + +#if 0 +namespace Fw { + +template +class FifoQueueTester { + public: + FifoQueueTester(const FifoQueue& queue) : m_queue(queue) {} + + const Array getItems() const { return this->m_queue.m_items; } + + const CircularIndex& getEnqueueIndex() const { return this->m_queue.m_enqueueIndex; } + + const CircularIndex& getDequeueIndex() const { return this->m_queue.m_dequeueIndex; } + + private: + const FifoQueue& m_queue; +}; + +TEST(FifoQueue, ZeroArgConstructor) { + FifoQueue queue; + ASSERT_EQ(queue.getCapacity(), 0); + ASSERT_EQ(queue.getSize(), 0); +} + +TEST(FifoQueue, TypedStorageConstructor) { + constexpr FwSizeType capacity = 10; + U32 items[capacity]; + FifoQueue queue(items, capacity); + FifoQueueTester tester(queue); + ASSERT_EQ(tester.getItems().getElements(), items); + ASSERT_EQ(queue.getCapacity(), capacity); + ASSERT_EQ(queue.getSize(), 0); +} + +TEST(FifoQueue, UntypedStorageConstructor) { + constexpr FwSizeType capacity = 10; + alignas(U32) U8 bytes[capacity * sizeof(U32)]; + FifoQueue queue(ByteArray(&bytes[0], sizeof bytes), capacity); + FifoQueueTester tester(queue); + ASSERT_EQ(tester.getItems().getElements(), reinterpret_cast(bytes)); + ASSERT_EQ(queue.getCapacity(), capacity); + ASSERT_EQ(queue.getSize(), 0); +} + +TEST(FifoQueue, EnqueueOK) { + constexpr const FwSizeType capacity = 1000; + const FwSizeType size = STest::Pick::lowerUpper(1, capacity); + U32 elts[capacity]; + FifoQueue queue(elts, capacity); + ASSERT_EQ(queue.getCapacity(), capacity); + ASSERT_EQ(queue.getSize(), 0); + for (FwSizeType i = 0; i < size; i++) { + // Pick a value + const U32 val = STest::Pick::any(); + // Enqueue it + auto status = queue.enqueue(val); + ASSERT_EQ(status, Fw::Success::SUCCESS); + // Peek it + U32 val1 = 0; + status = queue.peek(val1, i); + ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(val1, val); + // Check the size + ASSERT_EQ(queue.getSize(), i + 1); + } + queue.clear(); + ASSERT_EQ(queue.getSize(), 0); +} + +TEST(ArrayFIFO, EnqueueFull) { + constexpr const FwSizeType capacity = 1000; + U32 elts[capacity]; + FifoQueue queue(elts, capacity); + // Fill up the FIFO + for (FwSizeType i = 0; i < capacity; i++) { + queue.enqueue(0); + } + // Now try to push another element + const U32 val = STest::Pick::any(); + const auto status = queue.enqueue(val); + // Push should fail + ASSERT_EQ(status, Fw::Success::FAILURE); +} + +TEST(FifoQueue, CopyConstructor) { + constexpr FwSizeType capacity = 3; + U32 items[capacity]; + // Call the constructor providing backing storage + FifoQueue q1(items, capacity); + // Enqueue an item + U32 value = 42; + (void)q1.enqueue(value); + // Call the copy constructor + FifoQueue q2(q1); + FifoQueueTester tester1(q1); + FifoQueueTester tester2(q2); + ASSERT_EQ(tester2.getItems().getElements(), items); + ASSERT_EQ(tester2.getItems().getSize(), capacity); + ASSERT_EQ(tester2.getEnqueueIndex().getValue(), 1); + ASSERT_EQ(tester2.getDequeueIndex().getValue(), 0); + ASSERT_EQ(q2.getSize(), 1); +} + +TEST(FifoQueue, CopyAssignmentOperator) { + constexpr FwSizeType capacity = 3; + U32 items[capacity]; + // Call the constructor providing backing storage + FifoQueue q1(items, capacity); + // Enqueue an item + U32 value = 42; + (void)q1.enqueue(value); + // Call the default constructor + FifoQueue q2; + ASSERT_EQ(q2.getSize(), 0); + // Call the copy assignment operator + q2 = q1; + ASSERT_EQ(q2.getSize(), 1); +} + +TEST(FifoQueue, DequeueOK) { + constexpr const FwSizeType capacity = 1000; + const FwSizeType size = STest::Pick::lowerUpper(1, capacity); + U32 items[capacity]; + FifoQueue queue(items, capacity); + ASSERT_EQ(queue.getCapacity(), capacity); + ASSERT_EQ(queue.getSize(), 0); + for (FwSizeType i = 0; i < size; i++) { + // Pick a value + const U32 val = STest::Pick::any(); + // Enqueue it + const auto status = queue.enqueue(val); + ASSERT_EQ(val, items[i]); + ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(queue.getSize(), i + 1); + } + for (FwSizeType i = 0; i < size; i++) { + U32 val = 0; + // Peek + auto status = queue.peek(val); + ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(val, items[i]); + // Dequeue it + status = queue.dequeue(val); + ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(val, items[i]); + ASSERT_EQ(queue.getSize(), size - i - 1); + } + ASSERT_EQ(queue.getSize(), 0); +} + +TEST(FifoQueue, DequeueEmpty) { + constexpr const FwSizeType capacity = 1000; + U32 items[capacity]; + FifoQueue queue(items, capacity); + U32 val = 0; + const auto status = queue.dequeue(val); + ASSERT_EQ(status, Fw::Success::FAILURE); +} + +namespace { + +void testCopyDataFrom(FifoQueueBase& q1, FwSizeType size1, FifoQueueBase& q2) { + q1.clear(); + for (FwSizeType i = 0; i < size1; i++) { + const auto status = q1.enqueue(static_cast(i)); + ASSERT_EQ(status, Success::SUCCESS); + } + q2.copyDataFrom(q1); + const auto capacity2 = q2.getCapacity(); + const FwSizeType size = FW_MIN(size1, capacity2); + for (FwSizeType i = 0; i < size; i++) { + U32 val1 = 0; + auto status = q1.peek(val1, i); + ASSERT_EQ(status, Success::SUCCESS); + U32 val2 = 1; + status = q2.peek(val2, i); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(val1, val2); + } +} + +} // namespace + +TEST(FifoQueue, CopyDataFrom) { + constexpr FwSizeType maxSize = 10; + constexpr FwSizeType smallSize = maxSize / 2; + U32 items1[maxSize]; + U32 items2[maxSize]; + FifoQueue q1(items1, maxSize); + // size1 < capacity2 + { + FifoQueue q2(items2, maxSize); + testCopyDataFrom(q1, smallSize, q2); + } + // size1 == size2 + { + FifoQueue q2(items2, maxSize); + testCopyDataFrom(q1, maxSize, q2); + } + // size1 > size2 + { + FifoQueue q2(items2, smallSize); + testCopyDataFrom(q1, maxSize, q2); + } +} +} // namespace Fw +#endif From 10b5693fedfe9a6018c9c5a5156ea9f4d87d9c0c Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 5 Jun 2025 00:03:56 -0700 Subject: [PATCH 135/458] Revise FifoQueue --- Fw/DataStructures/docs/FifoQueue.md | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/Fw/DataStructures/docs/FifoQueue.md b/Fw/DataStructures/docs/FifoQueue.md index 3fd602da742..60fc8593f7b 100644 --- a/Fw/DataStructures/docs/FifoQueue.md +++ b/Fw/DataStructures/docs/FifoQueue.md @@ -133,7 +133,7 @@ Return `m_extQueue.dequeue(e)`. ### 5.5. getSize ```c++ -FwSizeType getSize() const +FwSizeType getSize() const override ``` Return `m_extQueue.getSize()`. @@ -141,28 +141,11 @@ Return `m_extQueue.getSize()`. ### 5.6. getCapacity ```c++ -FwSizeType getCapacity() const +FwSizeType getCapacity() const override ``` Return `m_extQueue.getCapacity()`. -### 5.7. asExternalFifoQueue - -```c++ -ExternalFifoQueue asExternalFifoQueue() -``` - -Return [`ExternalFifoQueue(m_items, C)`](ExternalFifoQueue.md#4-public-constructors-and-destructors) - -_Example:_ -```c++ -constexpr FwSizeType size = 3; -FifoQueue queue; -(void) queue.enqueue(3); -ExternalFifoQueue extQueue = queue.asExternalFifoQueue(); -ASSERT_EQ(extQueue.size(), 1); -``` - ## 6. Public Static Functions ### 6.1. getStaticCapacity From 9e050ea6e32ce56b675cecfe072ebf6bec366d0a Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 5 Jun 2025 00:24:48 -0700 Subject: [PATCH 136/458] Revise Fifo queue --- Fw/DataStructures/ExternalFifoQueue.hpp | 29 +++++++++------------ Fw/DataStructures/FifoQueue.hpp | 16 +++++------- Fw/DataStructures/FifoQueueBase.hpp | 21 +++++++-------- Fw/DataStructures/docs/FifoQueue.md | 4 +-- Fw/DataStructures/test/ut/FifoQueueTest.cpp | 22 ++++++++-------- 5 files changed, 41 insertions(+), 51 deletions(-) diff --git a/Fw/DataStructures/ExternalFifoQueue.hpp b/Fw/DataStructures/ExternalFifoQueue.hpp index 5df73ed0424..a9ea5c5cd2d 100644 --- a/Fw/DataStructures/ExternalFifoQueue.hpp +++ b/Fw/DataStructures/ExternalFifoQueue.hpp @@ -115,13 +115,25 @@ class ExternalFifoQueue final : public FifoQueueBase { return status; } + //! Get an item at an index + //! Indices go from left to right in the queue + //! Fails an assertion if the index is out of range + //! \return The item + const T& at(FwSizeType index //!< The index + ) const override { + FW_ASSERT(index < this->m_size); + auto ci = this->m_dequeueIndex; + const auto i = ci.increment(index); + return this->m_items[i]; + } + //! Dequeue an element (pop from the left) //! \return SUCCESS if element dequeued Success dequeue(T& e //!< The element (output) ) override { auto status = Success::FAILURE; if (this->m_size > 0) { - e = this->getItemAtIndex(0); + e = this->at(0); (void)this->m_dequeueIndex.increment(); this->m_size--; status = Success::SUCCESS; @@ -137,21 +149,6 @@ class ExternalFifoQueue final : public FifoQueueBase { //! \return The capacity FwSizeType getCapacity() const override { return this->m_items.getSize(); } - private: - // ---------------------------------------------------------------------- - // Private member functions - // ---------------------------------------------------------------------- - - //! Get an item at an index - //! Indices go from left to right in the queue - //! \return The item - const T& getItemAtIndex(FwSizeType index //!< The index - ) const override { - auto ci = this->m_dequeueIndex; - const auto i = ci.increment(index); - return this->m_items[i]; - } - private: // ---------------------------------------------------------------------- // Private member variables diff --git a/Fw/DataStructures/FifoQueue.hpp b/Fw/DataStructures/FifoQueue.hpp index 1a373d77828..f77d985b8f6 100644 --- a/Fw/DataStructures/FifoQueue.hpp +++ b/Fw/DataStructures/FifoQueue.hpp @@ -18,7 +18,7 @@ class FifoQueue final : public FifoQueueBase { // Friend class for testing // ---------------------------------------------------------------------- - template + template friend class FifoQueueTester; public: @@ -27,7 +27,7 @@ class FifoQueue final : public FifoQueueBase { // ---------------------------------------------------------------------- //! Zero-argument constructor - FifoQueue() = default; + FifoQueue() : m_extQueue(m_items, C) {} //! Copy constructor FifoQueue(const FifoQueue& queue) : FifoQueueBase() { *this = queue; } @@ -70,16 +70,12 @@ class FifoQueue final : public FifoQueueBase { //! \return The capacity FwSizeType getCapacity() const override { return this->m_extQueue.getCapacity(); } - private: - // ---------------------------------------------------------------------- - // Private member functions - // ---------------------------------------------------------------------- - //! Get an item at an index //! Indices go from left to right in the queue + //! Fails an assertion if the index is out of range //! \return The item - const T& getItemAtIndex(FwSizeType index //!< The index - ) const override { return this->m_extQueue.getItemAtIndex(index); + const T& at(FwSizeType index //!< The index + ) const override { return this->m_extQueue.at(index); } private: @@ -91,7 +87,7 @@ class FifoQueue final : public FifoQueueBase { ExternalFifoQueue m_extQueue = {}; //! The array providing the backing memory for m_extQueue - Array m_array = {}; + T m_items[C] = {}; }; diff --git a/Fw/DataStructures/FifoQueueBase.hpp b/Fw/DataStructures/FifoQueueBase.hpp index 79c8967566d..9250fab19ce 100644 --- a/Fw/DataStructures/FifoQueueBase.hpp +++ b/Fw/DataStructures/FifoQueueBase.hpp @@ -53,6 +53,13 @@ class FifoQueueBase { //! Clear the queue virtual void clear() = 0; + //! Get an item at an index + //! Indices go from left to right in the queue + //! Fails an assertion if the index is out of range + //! \return The item + virtual const T& at(FwSizeType index //!< The index + ) const = 0; + //! Copy data from another queue void copyDataFrom(const FifoQueueBase& queue //!< The queue ) { @@ -60,7 +67,7 @@ class FifoQueueBase { this->clear(); const FwSizeType size = FW_MIN(queue.getSize(), this->getCapacity()); for (FwSizeType i = 0; i < size; i++) { - const auto& e = queue.getItemAtIndex(i); + const auto& e = queue.at(i); const auto status = this->enqueue(e); FW_ASSERT(status == Fw::Success::SUCCESS, static_cast(status)); } @@ -80,7 +87,7 @@ class FifoQueueBase { ) const { auto status = Success::FAILURE; if (index < this->getSize()) { - e = this->getItemAtIndex(index); + e = this->at(index); status = Success::SUCCESS; } return status; @@ -99,16 +106,6 @@ class FifoQueueBase { //! \return The capacity virtual FwSizeType getCapacity() const = 0; - protected: - // ---------------------------------------------------------------------- - // Protected member functions - // ---------------------------------------------------------------------- - - //! Get an item at an index - //! Indices go from left to right in the queue - //! \return The item - virtual const T& getItemAtIndex(FwSizeType index //!< The index - ) const = 0; }; } // namespace Fw diff --git a/Fw/DataStructures/docs/FifoQueue.md b/Fw/DataStructures/docs/FifoQueue.md index 60fc8593f7b..eeedf476ea8 100644 --- a/Fw/DataStructures/docs/FifoQueue.md +++ b/Fw/DataStructures/docs/FifoQueue.md @@ -29,7 +29,7 @@ for storing the items on the queue. |Name|Type|Purpose|Default Value| |----|----|-------|-------------| |`m_extQueue`|`ExternalFifoQueue`|The external queue implementation|C++ default initialization| -|`m_array`|`Array`|The array providing the backing memory for `m_extQueue`|C++ default initialization| +|`m_items`|`T[C]`|The array providing the backing memory for `m_extQueue`|C++ default initialization| ```mermaid classDiagram @@ -45,7 +45,7 @@ classDiagram FifoQueue() ``` -Defined as `= default`. +Initialize `m_extQueue` with `ExternalFifoQueue(m_items, C)`. _Example:_ ```c++ diff --git a/Fw/DataStructures/test/ut/FifoQueueTest.cpp b/Fw/DataStructures/test/ut/FifoQueueTest.cpp index 14c098b9c73..40aa3af92ba 100644 --- a/Fw/DataStructures/test/ut/FifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/FifoQueueTest.cpp @@ -6,32 +6,32 @@ #include +#include "Fw/DataStructures/Array.hpp" #include "Fw/DataStructures/FifoQueue.hpp" -#if 0 namespace Fw { -template +template class FifoQueueTester { public: - FifoQueueTester(const FifoQueue& queue) : m_queue(queue) {} - - const Array getItems() const { return this->m_queue.m_items; } + FifoQueueTester(const FifoQueue& queue) : m_queue(queue) {} - const CircularIndex& getEnqueueIndex() const { return this->m_queue.m_enqueueIndex; } + const ExternalFifoQueue getExtQueue() const { return this->m_queue.extQueue; } - const CircularIndex& getDequeueIndex() const { return this->m_queue.m_dequeueIndex; } + const typename Array::Elements& getItems() const { return this->m_queue.m_items; } private: - const FifoQueue& m_queue; + const FifoQueue& m_queue; }; TEST(FifoQueue, ZeroArgConstructor) { - FifoQueue queue; - ASSERT_EQ(queue.getCapacity(), 0); + constexpr FwSizeType C = 10; + FifoQueue queue; + ASSERT_EQ(queue.getCapacity(), C); ASSERT_EQ(queue.getSize(), 0); } +#if 0 TEST(FifoQueue, TypedStorageConstructor) { constexpr FwSizeType capacity = 10; U32 items[capacity]; @@ -213,5 +213,5 @@ TEST(FifoQueue, CopyDataFrom) { testCopyDataFrom(q1, maxSize, q2); } } -} // namespace Fw #endif +} // namespace Fw From 6c78e9e85e2ca6587f07378eeb872f3ff1f68dcc Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 5 Jun 2025 00:34:07 -0700 Subject: [PATCH 137/458] Revise Fifo queue --- Fw/DataStructures/docs/ExternalFifoQueue.md | 45 +++++++++++------- Fw/DataStructures/docs/FifoQueue.md | 24 +++++----- Fw/DataStructures/docs/FifoQueueBase.md | 51 +++++++++++++-------- 3 files changed, 71 insertions(+), 49 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index 6d823c6ce44..05987fbbf17 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -254,7 +254,32 @@ ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(queue.getSize(), 1); ``` -### 5.6. dequeue +### 5.6. at + +```c++ +const T& at(FwSizeType index) const override +``` + +1. Assert `index < m_size`. + +1. Set `ci = m_dequeueIndex`. + +1. Set `i = ci.increment(index)`. + +1. Return `m_items[i]`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 3; +U32 items[capacity]; +ExternalFifoQueue 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"); +``` + +### 5.7. dequeue ```c++ Success dequeue(T& e) override @@ -289,7 +314,7 @@ ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(val, 42); ``` -### 5.7. getSize +### 5.8. getSize ```c++ FwSizeType getSize() const override @@ -310,7 +335,7 @@ size = queue.getSize(); ASSERT_EQ(size, 1); ``` -### 5.8. getCapacity +### 5.9. getCapacity ```c++ FwSizeType getCapacity() const override @@ -325,17 +350,3 @@ U32 items[capacity]; ExternalFifoQueue queue(items, capacity); ASSERT_EQ(queue.getCapacity(), capacity); ``` - -## 6. Private Member Functions - -### 6.1. getItemAtIndex - -```c++ -const T& getItemAtIndex(FwSizeType index) const override -``` - -1. Set `ci = m_dequeueIndex`. - -1. Set `i = ci.increment(index)`. - -1. Return `m_items[i]`. diff --git a/Fw/DataStructures/docs/FifoQueue.md b/Fw/DataStructures/docs/FifoQueue.md index eeedf476ea8..18e3a19f8ec 100644 --- a/Fw/DataStructures/docs/FifoQueue.md +++ b/Fw/DataStructures/docs/FifoQueue.md @@ -122,7 +122,15 @@ Success enqueue(const T& e) override Return `m_extQueue.enqueue(e)`. -### 5.4. dequeue +### 5.4. at + +```c++ +const T& at(FwSizeType index) const override +``` + +Return `m_extQueue.at(index)`. + +### 5.5. dequeue ```c++ Success dequeue(T& e) override @@ -130,7 +138,7 @@ Success dequeue(T& e) override Return `m_extQueue.dequeue(e)`. -### 5.5. getSize +### 5.6. getSize ```c++ FwSizeType getSize() const override @@ -138,7 +146,7 @@ FwSizeType getSize() const override Return `m_extQueue.getSize()`. -### 5.6. getCapacity +### 5.7. getCapacity ```c++ FwSizeType getCapacity() const override @@ -161,13 +169,3 @@ _Example:_ const auto capacity = FifoQueue::getStaticCapacity(); ASSERT_EQ(capacity, 3); ``` - -## 7. Private Member Functions - -### 7.1. getItemAtIndex - -```c++ -const T& getItemAtIndex(FwSizeType index) const override -``` - -Return `m_extQueue.getItemAtIndex(index)`. diff --git a/Fw/DataStructures/docs/FifoQueueBase.md b/Fw/DataStructures/docs/FifoQueueBase.md index 338893b3ace..5a12cc923be 100644 --- a/Fw/DataStructures/docs/FifoQueueBase.md +++ b/Fw/DataStructures/docs/FifoQueueBase.md @@ -82,7 +82,7 @@ void copyDataFrom(const FifoQueueBase& queue) 1. For `i` in [0, `size`) - 1. Set `e = getItemAtIndex(i)`. + 1. Set `e = at(i)`. 1. Set `status = enqueue(e)`. @@ -123,12 +123,37 @@ _Example:_ ```c++ void f(FifoQueueBase& queue) { queue.clear(); - status = queue.enqueue(3); + const auto status = queue.enqueue(3); ASSERT_EQ(status, Success::SUCCESS); } ``` -### 5.4. peek +### 5.4. at + +```c++ +virtual const T& at(FwSizeType index) const = 0 +``` + +Return the item at the specified index. +Index 0 is the leftmost (earliest) element in the queue. +Increasing indices go from left to right. +Fails an assertion if the index is out of range. + +_Example:_ +```c++ +void f(FifoQueueBase& queue) { + queue.clear(); + const auto status = queue.enqueue(3); + ASSERT_EQ(status, Success::SUCCESS); + const auto status = queue.enqueue(4); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(queue.at(0), 3); + ASSERT_EQ(queue.at(1), 4); + ASSERT_DEATH(queue.at(2), "Assert"); +} +``` + +### 5.5. peek ```c++ Success peek(T& e, FwSizeType index = 0) const @@ -138,7 +163,7 @@ Success peek(T& e, FwSizeType index = 0) const 1. If `index < getSize()` - 1. Set `e = getItemAtIndex(index)`. + 1. Set `e = at(index)`. 1. Set `status = Success::SUCCESS`. @@ -164,7 +189,7 @@ void f(FifoQueueBase& queue) { } ``` -### 5.5. dequeue +### 5.6. dequeue ```c++ virtual Success dequeue(T& e) = 0 @@ -195,7 +220,7 @@ void f(FifoQueueBase& queue) { } ``` -### 5.6. getSize +### 5.7. getSize ```c++ virtual FwSizeType getSize() const = 0 @@ -216,7 +241,7 @@ void f(const FifoQueueBase& queue) { } ``` -### 5.7. getCapacity +### 5.8. getCapacity ```c++ virtual FwSizeType getCapacity() const = 0 @@ -233,15 +258,3 @@ void f(const FifoQueueBase& queue) { } ``` -## 6. Protected Member Functions - -### 6.1. getItemAtIndex - -```c++ -virtual const T& getItemAtIndex(FwSizeType index) const = 0 -``` - -Return the item at the specified index. -Index 0 is the leftmost (earliest) element in the queue. -Increasing indices go from left to right. - From aaed50d47105e4bc76a4eda1027557aa38878ea8 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 5 Jun 2025 00:36:53 -0700 Subject: [PATCH 138/458] Revise data structures tests --- .../test/ut/ExternalFifoQueueTest.cpp | 14 +++++++------- Fw/DataStructures/test/ut/FifoQueueTest.cpp | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp index a84065792be..1a7d1a2e575 100644 --- a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp @@ -64,11 +64,11 @@ TEST(ExternalFifoQueue, EnqueueOK) { const U32 val = STest::Pick::any(); // Enqueue it auto status = queue.enqueue(val); - ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(status, Success::SUCCESS); // Peek it U32 val1 = 0; status = queue.peek(val1, i); - ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(val1, val); // Check the size ASSERT_EQ(queue.getSize(), i + 1); @@ -89,7 +89,7 @@ TEST(ArrayFIFO, EnqueueFull) { const U32 val = STest::Pick::any(); const auto status = queue.enqueue(val); // Push should fail - ASSERT_EQ(status, Fw::Success::FAILURE); + ASSERT_EQ(status, Success::FAILURE); } TEST(ExternalFifoQueue, CopyConstructor) { @@ -140,18 +140,18 @@ TEST(ExternalFifoQueue, DequeueOK) { // Enqueue it const auto status = queue.enqueue(val); ASSERT_EQ(val, items[i]); - ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(queue.getSize(), i + 1); } for (FwSizeType i = 0; i < size; i++) { U32 val = 0; // Peek auto status = queue.peek(val); - ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(val, items[i]); // Dequeue it status = queue.dequeue(val); - ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(val, items[i]); ASSERT_EQ(queue.getSize(), size - i - 1); } @@ -164,7 +164,7 @@ TEST(ExternalFifoQueue, DequeueEmpty) { ExternalFifoQueue queue(items, capacity); U32 val = 0; const auto status = queue.dequeue(val); - ASSERT_EQ(status, Fw::Success::FAILURE); + ASSERT_EQ(status, Success::FAILURE); } namespace { diff --git a/Fw/DataStructures/test/ut/FifoQueueTest.cpp b/Fw/DataStructures/test/ut/FifoQueueTest.cpp index 40aa3af92ba..2012b5c3124 100644 --- a/Fw/DataStructures/test/ut/FifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/FifoQueueTest.cpp @@ -64,11 +64,11 @@ TEST(FifoQueue, EnqueueOK) { const U32 val = STest::Pick::any(); // Enqueue it auto status = queue.enqueue(val); - ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(status, Success::SUCCESS); // Peek it U32 val1 = 0; status = queue.peek(val1, i); - ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(val1, val); // Check the size ASSERT_EQ(queue.getSize(), i + 1); @@ -89,7 +89,7 @@ TEST(ArrayFIFO, EnqueueFull) { const U32 val = STest::Pick::any(); const auto status = queue.enqueue(val); // Push should fail - ASSERT_EQ(status, Fw::Success::FAILURE); + ASSERT_EQ(status, Success::FAILURE); } TEST(FifoQueue, CopyConstructor) { @@ -140,18 +140,18 @@ TEST(FifoQueue, DequeueOK) { // Enqueue it const auto status = queue.enqueue(val); ASSERT_EQ(val, items[i]); - ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(queue.getSize(), i + 1); } for (FwSizeType i = 0; i < size; i++) { U32 val = 0; // Peek auto status = queue.peek(val); - ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(val, items[i]); // Dequeue it status = queue.dequeue(val); - ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(val, items[i]); ASSERT_EQ(queue.getSize(), size - i - 1); } @@ -164,7 +164,7 @@ TEST(FifoQueue, DequeueEmpty) { FifoQueue queue(items, capacity); U32 val = 0; const auto status = queue.dequeue(val); - ASSERT_EQ(status, Fw::Success::FAILURE); + ASSERT_EQ(status, Success::FAILURE); } namespace { From 1f3bfaaf82e74cf47b22abc0a641b0ac2e206783 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 5 Jun 2025 10:17:41 -0700 Subject: [PATCH 139/458] Revise Fw/DataStructures --- Fw/DataStructures/docs/AvlTreeMap.md | 4 ---- Fw/DataStructures/docs/AvlTreeSet.md | 4 ---- Fw/DataStructures/docs/ExternalAvlTreeMap.md | 4 ---- Fw/DataStructures/docs/ExternalAvlTreeSet.md | 4 ---- Fw/DataStructures/docs/ExternalRedBlackTreeMap.md | 4 ++++ Fw/DataStructures/docs/ExternalRedBlackTreeSet.md | 4 ++++ Fw/DataStructures/docs/RedBlackTreeMap.md | 4 ++++ Fw/DataStructures/docs/RedBlackTreeSet.md | 4 ++++ Fw/DataStructures/docs/sdd.md | 8 ++++---- 9 files changed, 20 insertions(+), 20 deletions(-) delete mode 100644 Fw/DataStructures/docs/AvlTreeMap.md delete mode 100644 Fw/DataStructures/docs/AvlTreeSet.md delete mode 100644 Fw/DataStructures/docs/ExternalAvlTreeMap.md delete mode 100644 Fw/DataStructures/docs/ExternalAvlTreeSet.md create mode 100644 Fw/DataStructures/docs/ExternalRedBlackTreeMap.md create mode 100644 Fw/DataStructures/docs/ExternalRedBlackTreeSet.md create mode 100644 Fw/DataStructures/docs/RedBlackTreeMap.md create mode 100644 Fw/DataStructures/docs/RedBlackTreeSet.md diff --git a/Fw/DataStructures/docs/AvlTreeMap.md b/Fw/DataStructures/docs/AvlTreeMap.md deleted file mode 100644 index d6995493b53..00000000000 --- a/Fw/DataStructures/docs/AvlTreeMap.md +++ /dev/null @@ -1,4 +0,0 @@ -# AvlTreeMap - -TODO - diff --git a/Fw/DataStructures/docs/AvlTreeSet.md b/Fw/DataStructures/docs/AvlTreeSet.md deleted file mode 100644 index cbf5920f607..00000000000 --- a/Fw/DataStructures/docs/AvlTreeSet.md +++ /dev/null @@ -1,4 +0,0 @@ -# ExternalAvlTreeSet - -TODO - diff --git a/Fw/DataStructures/docs/ExternalAvlTreeMap.md b/Fw/DataStructures/docs/ExternalAvlTreeMap.md deleted file mode 100644 index f6088cf0d51..00000000000 --- a/Fw/DataStructures/docs/ExternalAvlTreeMap.md +++ /dev/null @@ -1,4 +0,0 @@ -# ExternalAvlTreeMap - -TODO - diff --git a/Fw/DataStructures/docs/ExternalAvlTreeSet.md b/Fw/DataStructures/docs/ExternalAvlTreeSet.md deleted file mode 100644 index 9fbf4b6b5f3..00000000000 --- a/Fw/DataStructures/docs/ExternalAvlTreeSet.md +++ /dev/null @@ -1,4 +0,0 @@ -# AvlTreeSet - -TODO - diff --git a/Fw/DataStructures/docs/ExternalRedBlackTreeMap.md b/Fw/DataStructures/docs/ExternalRedBlackTreeMap.md new file mode 100644 index 00000000000..52e6a22c9a8 --- /dev/null +++ b/Fw/DataStructures/docs/ExternalRedBlackTreeMap.md @@ -0,0 +1,4 @@ +# ExternalRedBlackTreeMap + +TODO + diff --git a/Fw/DataStructures/docs/ExternalRedBlackTreeSet.md b/Fw/DataStructures/docs/ExternalRedBlackTreeSet.md new file mode 100644 index 00000000000..eaf1581452a --- /dev/null +++ b/Fw/DataStructures/docs/ExternalRedBlackTreeSet.md @@ -0,0 +1,4 @@ +# RedBlackTreeSet + +TODO + diff --git a/Fw/DataStructures/docs/RedBlackTreeMap.md b/Fw/DataStructures/docs/RedBlackTreeMap.md new file mode 100644 index 00000000000..47b9088b3e3 --- /dev/null +++ b/Fw/DataStructures/docs/RedBlackTreeMap.md @@ -0,0 +1,4 @@ +# RedBlackTreeMap + +TODO + diff --git a/Fw/DataStructures/docs/RedBlackTreeSet.md b/Fw/DataStructures/docs/RedBlackTreeSet.md new file mode 100644 index 00000000000..e0c1c939f2e --- /dev/null +++ b/Fw/DataStructures/docs/RedBlackTreeSet.md @@ -0,0 +1,4 @@ +# ExternalRedBlackTreeSet + +TODO + diff --git a/Fw/DataStructures/docs/sdd.md b/Fw/DataStructures/docs/sdd.md index abc17450e53..9d063171447 100644 --- a/Fw/DataStructures/docs/sdd.md +++ b/Fw/DataStructures/docs/sdd.md @@ -65,9 +65,9 @@ classDiagram * [`ArrayMap`](ArrayMap.md) -* [`AvlTreeMap`](AvlTreeMap.md) +* [`RedBlackTreeMap`](RedBlackTreeMap.md) -* [`ExternalAvlTreeMap`](ExternalAvlTreeMap.md) +* [`ExternalRedBlackTreeMap`](ExternalRedBlackTreeMap.md) ## 4. Sets @@ -77,6 +77,6 @@ classDiagram * [`ArraySet`](ArraySet.md) -* [`ExternalAvlTreeSet`](ExternalAvlTreeSet.md) +* [`ExternalRedBlackTreeSet`](ExternalRedBlackTreeSet.md) -* [`AvlTreeSet`](AvlTreeSet.md) +* [`RedBlackTreeSet`](RedBlackTreeSet.md) From d12f61f8b112337c92442b51ccd1774142b26835 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 5 Jun 2025 10:19:46 -0700 Subject: [PATCH 140/458] Revise Fw/DataStructures --- Fw/DataStructures/docs/sdd.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/docs/sdd.md b/Fw/DataStructures/docs/sdd.md index 9d063171447..42bfe9667c0 100644 --- a/Fw/DataStructures/docs/sdd.md +++ b/Fw/DataStructures/docs/sdd.md @@ -46,8 +46,11 @@ first in first out (FIFO) order. * [`FifoQueue`](FifoQueue.md) -The queue implementations use a template called [`CircularIndex`](CircularIndex.md) -for representing an index that wraps around modulo an integer. +The queue implementations use a template called +[`CircularIndex`](CircularIndex.md) +for representing a **circular index**, i.e., an index that wraps around modulo +an integer. +You can use this template to represent any circular index. ### 2.2. Class Diagram From add77a98d54665e4cbb82f7b56ce1143be338092 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 5 Jun 2025 13:47:40 -0700 Subject: [PATCH 141/458] Revise FifoQueue tests --- .../test/ut/ExternalFifoQueueTest.cpp | 2 +- Fw/DataStructures/test/ut/FifoQueueTest.cpp | 22 ++++++++- .../ut/STest/FifoQueue/FifoQueueRules.hpp | 46 +++++++++++++++++++ .../ut/STest/FifoQueue/FifoQueueTestState.hpp | 19 ++++++++ 4 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 Fw/DataStructures/test/ut/STest/FifoQueue/FifoQueueRules.hpp create mode 100644 Fw/DataStructures/test/ut/STest/FifoQueue/FifoQueueTestState.hpp diff --git a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp index 1a7d1a2e575..805ee5473c3 100644 --- a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp @@ -77,7 +77,7 @@ TEST(ExternalFifoQueue, EnqueueOK) { ASSERT_EQ(queue.getSize(), 0); } -TEST(ArrayFIFO, EnqueueFull) { +TEST(ExternalFifoQueue, EnqueueFull) { constexpr const FwSizeType capacity = 1000; U32 elts[capacity]; ExternalFifoQueue queue(elts, capacity); diff --git a/Fw/DataStructures/test/ut/FifoQueueTest.cpp b/Fw/DataStructures/test/ut/FifoQueueTest.cpp index 2012b5c3124..adaaaebc55a 100644 --- a/Fw/DataStructures/test/ut/FifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/FifoQueueTest.cpp @@ -8,6 +8,7 @@ #include "Fw/DataStructures/Array.hpp" #include "Fw/DataStructures/FifoQueue.hpp" +#include "Fw/DataStructures/test/ut/STest/FifoQueue/FifoQueueRules.hpp" namespace Fw { @@ -77,7 +78,7 @@ TEST(FifoQueue, EnqueueOK) { ASSERT_EQ(queue.getSize(), 0); } -TEST(ArrayFIFO, EnqueueFull) { +TEST(FifoQueue, EnqueueFull) { constexpr const FwSizeType capacity = 1000; U32 elts[capacity]; FifoQueue queue(elts, capacity); @@ -214,4 +215,23 @@ TEST(FifoQueue, CopyDataFrom) { } } #endif + +TEST(FifoQueueRules, EnqueueOK) { + constexpr FwSizeType capacity = 10; + FifoQueueRules::TestState state; + FifoQueueRules::EnqueueOK enqueueOK; + enqueueOK.apply(state); +} + +TEST(FifoQueueRules, EnqueueFull) { + constexpr FwSizeType capacity = 10; + FifoQueueRules::TestState state; + FifoQueueRules::EnqueueOK enqueueOK; + FifoQueueRules::EnqueueFull enqueueFull; + for (FwSizeType i = 0; i < capacity; i++) { + enqueueOK.apply(state); + } + enqueueFull.apply(state); +} + } // namespace Fw diff --git a/Fw/DataStructures/test/ut/STest/FifoQueue/FifoQueueRules.hpp b/Fw/DataStructures/test/ut/STest/FifoQueue/FifoQueueRules.hpp new file mode 100644 index 00000000000..c57581c209b --- /dev/null +++ b/Fw/DataStructures/test/ut/STest/FifoQueue/FifoQueueRules.hpp @@ -0,0 +1,46 @@ +#ifndef FifoQueueRules_HPP +#define FifoQueueRules_HPP + +#include "Fw/DataStructures/test/ut/STest/FifoQueue/FifoQueueTestState.hpp" +#include "STest/STest/Pick/Pick.hpp" +#include "STest/STest/Rule/Rule.hpp" + +namespace Fw { + +template +struct FifoQueueRules { + + using TestState = FifoQueueTestState; + + using Rule = STest::Rule; + + struct EnqueueOK : public Rule { + EnqueueOK() : Rule("EnqueueOK") {} + bool precondition(const TestState& state) { + return static_cast(state.abstractQueue.size()) < C; + } + void action(TestState& state) { + const U32 value = STest::Pick::any(); + const auto status = state.queue.enqueue(value); + state.abstractQueue.push_back(value); + ASSERT_EQ(status, Success::SUCCESS); + } + }; + + struct EnqueueFull : public Rule { + EnqueueFull() : Rule("EnqueueFull") {} + bool precondition(const TestState& state) { + return static_cast(state.abstractQueue.size()) >= C; + } + void action(TestState& state) { + const U32 value = STest::Pick::any(); + const auto status = state.queue.enqueue(value); + ASSERT_EQ(status, Success::FAILURE); + } + }; + +}; + +} // namespace Fw + +#endif diff --git a/Fw/DataStructures/test/ut/STest/FifoQueue/FifoQueueTestState.hpp b/Fw/DataStructures/test/ut/STest/FifoQueue/FifoQueueTestState.hpp new file mode 100644 index 00000000000..0216ed33fd9 --- /dev/null +++ b/Fw/DataStructures/test/ut/STest/FifoQueue/FifoQueueTestState.hpp @@ -0,0 +1,19 @@ +#ifndef FifoQueueTestState_HPP +#define FifoQueueTestState_HPP + +#include + +#include "Fw/DataStructures/FifoQueue.hpp" + +namespace Fw { + +template struct FifoQueueTestState { + //! The queue under test + FifoQueue queue; + //! The abstract queue for modeling correct behavior + std::vector abstractQueue; +}; + +} + +#endif From bed95f5faff1941093a4eb9a1f16659f6075c017 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 5 Jun 2025 14:52:54 -0700 Subject: [PATCH 142/458] Revise FifoQueue tests --- .../test/ut/STest/FifoQueue/FifoQueueRules.hpp | 16 +++++++++++++--- .../ut/STest/FifoQueue/FifoQueueTestState.hpp | 4 ++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Fw/DataStructures/test/ut/STest/FifoQueue/FifoQueueRules.hpp b/Fw/DataStructures/test/ut/STest/FifoQueue/FifoQueueRules.hpp index c57581c209b..cdd5bc66b91 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueue/FifoQueueRules.hpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueue/FifoQueueRules.hpp @@ -17,12 +17,12 @@ struct FifoQueueRules { struct EnqueueOK : public Rule { EnqueueOK() : Rule("EnqueueOK") {} bool precondition(const TestState& state) { - return static_cast(state.abstractQueue.size()) < C; + return static_cast(state.modelQueue.size()) < C; } void action(TestState& state) { const U32 value = STest::Pick::any(); const auto status = state.queue.enqueue(value); - state.abstractQueue.push_back(value); + state.modelQueue.push_back(value); ASSERT_EQ(status, Success::SUCCESS); } }; @@ -30,7 +30,7 @@ struct FifoQueueRules { struct EnqueueFull : public Rule { EnqueueFull() : Rule("EnqueueFull") {} bool precondition(const TestState& state) { - return static_cast(state.abstractQueue.size()) >= C; + return static_cast(state.modelQueue.size()) >= C; } void action(TestState& state) { const U32 value = STest::Pick::any(); @@ -39,6 +39,16 @@ struct FifoQueueRules { } }; + struct Clear : public Rule { + Clear() : Rule("Clear") {} + bool precondition(const TestState& state) { return true; } + void action(TestState& state) { + state.queue.clear(); + ASSERT_EQ(state.queue.getSize(), 0); + state.modelQueue.clear(); + } + }; + }; } // namespace Fw diff --git a/Fw/DataStructures/test/ut/STest/FifoQueue/FifoQueueTestState.hpp b/Fw/DataStructures/test/ut/STest/FifoQueue/FifoQueueTestState.hpp index 0216ed33fd9..0b265c59e2f 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueue/FifoQueueTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueue/FifoQueueTestState.hpp @@ -10,8 +10,8 @@ namespace Fw { template struct FifoQueueTestState { //! The queue under test FifoQueue queue; - //! The abstract queue for modeling correct behavior - std::vector abstractQueue; + //! The queue for modeling correct behavior + std::vector modelQueue; }; } From 15ca470245f2a0afbe8098045c6ab9fffab87e80 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 5 Jun 2025 15:12:03 -0700 Subject: [PATCH 143/458] Revise FifoQueue tests --- Fw/DataStructures/test/ut/FifoQueueTest.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Fw/DataStructures/test/ut/FifoQueueTest.cpp b/Fw/DataStructures/test/ut/FifoQueueTest.cpp index adaaaebc55a..fa3424c0901 100644 --- a/Fw/DataStructures/test/ut/FifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/FifoQueueTest.cpp @@ -234,4 +234,16 @@ TEST(FifoQueueRules, EnqueueFull) { enqueueFull.apply(state); } + +TEST(FifoQueueRules, Clear) { + constexpr FwSizeType capacity = 10; + FifoQueueRules::TestState state; + FifoQueueRules::Clear clear; + FifoQueueRules::EnqueueOK enqueueOK; + enqueueOK.apply(state); + ASSERT_EQ(state.queue.getSize(), 1); + clear.apply(state); + ASSERT_EQ(state.queue.getSize(), 0); +} + } // namespace Fw From 7b595c906af7d6e209e7c841f455520faf6bde2b Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Fri, 6 Jun 2025 17:00:28 -0700 Subject: [PATCH 144/458] Refactor data structures tests --- Fw/DataStructures/test/ut/FifoQueueTest.cpp | 28 +++++++-------- .../ut/STest/FifoQueue/FifoQueueTestState.hpp | 19 ---------- ...oQueueRules.hpp => FifoQueueTestRules.hpp} | 36 +++++++++---------- .../test/ut/STest/FifoQueueTestState.hpp | 30 ++++++++++++++++ 4 files changed, 62 insertions(+), 51 deletions(-) delete mode 100644 Fw/DataStructures/test/ut/STest/FifoQueue/FifoQueueTestState.hpp rename Fw/DataStructures/test/ut/STest/{FifoQueue/FifoQueueRules.hpp => FifoQueueTestRules.hpp} (57%) create mode 100644 Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp diff --git a/Fw/DataStructures/test/ut/FifoQueueTest.cpp b/Fw/DataStructures/test/ut/FifoQueueTest.cpp index fa3424c0901..9a09a56d27f 100644 --- a/Fw/DataStructures/test/ut/FifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/FifoQueueTest.cpp @@ -8,10 +8,12 @@ #include "Fw/DataStructures/Array.hpp" #include "Fw/DataStructures/FifoQueue.hpp" -#include "Fw/DataStructures/test/ut/STest/FifoQueue/FifoQueueRules.hpp" +#include "Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp" namespace Fw { +namespace FifoQueueTest { + template class FifoQueueTester { public: @@ -217,33 +219,31 @@ TEST(FifoQueue, CopyDataFrom) { #endif TEST(FifoQueueRules, EnqueueOK) { - constexpr FwSizeType capacity = 10; - FifoQueueRules::TestState state; - FifoQueueRules::EnqueueOK enqueueOK; + State state; + Rules::EnqueueOK enqueueOK; enqueueOK.apply(state); } TEST(FifoQueueRules, EnqueueFull) { - constexpr FwSizeType capacity = 10; - FifoQueueRules::TestState state; - FifoQueueRules::EnqueueOK enqueueOK; - FifoQueueRules::EnqueueFull enqueueFull; - for (FwSizeType i = 0; i < capacity; i++) { + State state; + Rules::EnqueueOK enqueueOK; + Rules::EnqueueFull enqueueFull; + for (FwSizeType i = 0; i < State::capacity; i++) { enqueueOK.apply(state); } enqueueFull.apply(state); } - TEST(FifoQueueRules, Clear) { - constexpr FwSizeType capacity = 10; - FifoQueueRules::TestState state; - FifoQueueRules::Clear clear; - FifoQueueRules::EnqueueOK enqueueOK; + State state; + Rules::Clear clear; + Rules::EnqueueOK enqueueOK; enqueueOK.apply(state); ASSERT_EQ(state.queue.getSize(), 1); clear.apply(state); ASSERT_EQ(state.queue.getSize(), 0); } +} + } // namespace Fw diff --git a/Fw/DataStructures/test/ut/STest/FifoQueue/FifoQueueTestState.hpp b/Fw/DataStructures/test/ut/STest/FifoQueue/FifoQueueTestState.hpp deleted file mode 100644 index 0b265c59e2f..00000000000 --- a/Fw/DataStructures/test/ut/STest/FifoQueue/FifoQueueTestState.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef FifoQueueTestState_HPP -#define FifoQueueTestState_HPP - -#include - -#include "Fw/DataStructures/FifoQueue.hpp" - -namespace Fw { - -template struct FifoQueueTestState { - //! The queue under test - FifoQueue queue; - //! The queue for modeling correct behavior - std::vector modelQueue; -}; - -} - -#endif diff --git a/Fw/DataStructures/test/ut/STest/FifoQueue/FifoQueueRules.hpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp similarity index 57% rename from Fw/DataStructures/test/ut/STest/FifoQueue/FifoQueueRules.hpp rename to Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp index cdd5bc66b91..2d34be5c8d3 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueue/FifoQueueRules.hpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp @@ -1,25 +1,24 @@ -#ifndef FifoQueueRules_HPP -#define FifoQueueRules_HPP +#ifndef FifoQueueTestRules_HPP +#define FifoQueueTestRules_HPP -#include "Fw/DataStructures/test/ut/STest/FifoQueue/FifoQueueTestState.hpp" +#include "Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp" #include "STest/STest/Pick/Pick.hpp" #include "STest/STest/Rule/Rule.hpp" namespace Fw { -template -struct FifoQueueRules { +namespace FifoQueueTest { - using TestState = FifoQueueTestState; +using Rule = STest::Rule; - using Rule = STest::Rule; +struct Rules { struct EnqueueOK : public Rule { EnqueueOK() : Rule("EnqueueOK") {} - bool precondition(const TestState& state) { - return static_cast(state.modelQueue.size()) < C; + bool precondition(const State& state) { + return static_cast(state.modelQueue.size()) < State::capacity; } - void action(TestState& state) { + void action(State& state) { const U32 value = STest::Pick::any(); const auto status = state.queue.enqueue(value); state.modelQueue.push_back(value); @@ -29,28 +28,29 @@ struct FifoQueueRules { struct EnqueueFull : public Rule { EnqueueFull() : Rule("EnqueueFull") {} - bool precondition(const TestState& state) { - return static_cast(state.modelQueue.size()) >= C; + bool precondition(const State& state) { + return static_cast(state.modelQueue.size()) >= State::capacity; } - void action(TestState& state) { - const U32 value = STest::Pick::any(); - const auto status = state.queue.enqueue(value); + void action(State& state) { + const auto item = State::getRandomItem(); + const auto status = state.queue.enqueue(item); ASSERT_EQ(status, Success::FAILURE); } }; struct Clear : public Rule { Clear() : Rule("Clear") {} - bool precondition(const TestState& state) { return true; } - void action(TestState& state) { + bool precondition(const State& state) { return true; } + void action(State& state) { state.queue.clear(); ASSERT_EQ(state.queue.getSize(), 0); state.modelQueue.clear(); } }; - }; +} + } // namespace Fw #endif diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp new file mode 100644 index 00000000000..aee7f6c5eb4 --- /dev/null +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp @@ -0,0 +1,30 @@ +#ifndef FifoQueueTestState_HPP +#define FifoQueueTestState_HPP + +#include + +#include "Fw/DataStructures/FifoQueue.hpp" +#include "STest/STest/Pick/Pick.hpp" + +namespace Fw { + +namespace FifoQueueTest { + +struct State { + //! The queue item type + using ItemType = U32; + //! The queue capacity + static constexpr FwSizeType capacity = 1024; + //! The queue under test + FifoQueue queue; + //! The queue for modeling correct behavior + std::vector modelQueue; + //! Get a random item + static ItemType getRandomItem() { return STest::Pick::any(); } +}; + +} + +} + +#endif From 3231e104bd5f0a86e6f175ab61512e24de274d13 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 9 Jun 2025 08:46:24 -0700 Subject: [PATCH 145/458] Revise tests for Fw/DataStructures --- Fw/DataStructures/test/ut/FifoQueueTest.cpp | 26 +++++++--------- .../test/ut/STest/FifoQueueTestRules.hpp | 9 ++++-- .../test/ut/STest/FifoQueueTestScenarios.hpp | 31 +++++++++++++++++++ 3 files changed, 49 insertions(+), 17 deletions(-) create mode 100644 Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp diff --git a/Fw/DataStructures/test/ut/FifoQueueTest.cpp b/Fw/DataStructures/test/ut/FifoQueueTest.cpp index 9a09a56d27f..cecdb5ac407 100644 --- a/Fw/DataStructures/test/ut/FifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/FifoQueueTest.cpp @@ -4,11 +4,7 @@ // \brief cpp file for FifoQueue tests // ====================================================================== -#include - -#include "Fw/DataStructures/Array.hpp" -#include "Fw/DataStructures/FifoQueue.hpp" -#include "Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp" +#include "Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp" namespace Fw { @@ -220,30 +216,30 @@ TEST(FifoQueue, CopyDataFrom) { TEST(FifoQueueRules, EnqueueOK) { State state; - Rules::EnqueueOK enqueueOK; - enqueueOK.apply(state); + Rules::enqueueOK.apply(state); } TEST(FifoQueueRules, EnqueueFull) { State state; - Rules::EnqueueOK enqueueOK; - Rules::EnqueueFull enqueueFull; for (FwSizeType i = 0; i < State::capacity; i++) { - enqueueOK.apply(state); + Rules::enqueueOK.apply(state); } - enqueueFull.apply(state); + Rules::enqueueFull.apply(state); } TEST(FifoQueueRules, Clear) { State state; - Rules::Clear clear; - Rules::EnqueueOK enqueueOK; - enqueueOK.apply(state); + Rules::enqueueOK.apply(state); ASSERT_EQ(state.queue.getSize(), 1); - clear.apply(state); + Rules::clear.apply(state); ASSERT_EQ(state.queue.getSize(), 0); } +TEST(FifoQueueScenarios, Random) { + State state; + Scenarios::random(state, 1000); +} + } } // namespace Fw diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp index 2d34be5c8d3..ecb96d6a345 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp @@ -1,6 +1,8 @@ #ifndef FifoQueueTestRules_HPP #define FifoQueueTestRules_HPP +#include + #include "Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp" #include "STest/STest/Pick/Pick.hpp" #include "STest/STest/Rule/Rule.hpp" @@ -11,7 +13,7 @@ namespace FifoQueueTest { using Rule = STest::Rule; -struct Rules { +namespace Rules { struct EnqueueOK : public Rule { EnqueueOK() : Rule("EnqueueOK") {} @@ -21,10 +23,11 @@ struct Rules { void action(State& state) { const U32 value = STest::Pick::any(); const auto status = state.queue.enqueue(value); - state.modelQueue.push_back(value); ASSERT_EQ(status, Success::SUCCESS); + state.modelQueue.push_back(value); } }; + static EnqueueOK enqueueOK; struct EnqueueFull : public Rule { EnqueueFull() : Rule("EnqueueFull") {} @@ -37,6 +40,7 @@ struct Rules { ASSERT_EQ(status, Success::FAILURE); } }; + static EnqueueFull enqueueFull; struct Clear : public Rule { Clear() : Rule("Clear") {} @@ -47,6 +51,7 @@ struct Rules { state.modelQueue.clear(); } }; + static Clear clear; }; } diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp new file mode 100644 index 00000000000..0781be9d2bc --- /dev/null +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp @@ -0,0 +1,31 @@ +// ====================================================================== +// \title FifoQueueTestScenarios.hpp +// \author Rob Bocchino +// \brief FifoQueue test scenarios +// ====================================================================== + +#include "Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp" +#include "STest/Scenario/BoundedScenario.hpp" +#include "STest/Scenario/RandomScenario.hpp" + +namespace Fw { + +namespace FifoQueueTest { + +namespace Scenarios { + +Rule* rules[] = {&Rules::enqueueOK, &Rules::enqueueFull, &Rules::clear}; + +void random(State& state, U32 maxNumSteps) { + STest::RandomScenario scenario("RandomScenario", rules, + sizeof(rules) / sizeof(STest::RandomScenario*)); + STest::BoundedScenario boundedScenario("BoundedRandomScenario", scenario, maxNumSteps); + const U32 numSteps = boundedScenario.run(state); + printf("Ran %u steps.\n", numSteps); +} + +} // namespace Scenarios + +} // namespace FifoQueueTest + +} // namespace Fw From c5412951ed994749d8b5dc68f814c3b0be2cf336 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 9 Jun 2025 08:48:09 -0700 Subject: [PATCH 146/458] Add ut script --- Fw/DataStructures/ut | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100755 Fw/DataStructures/ut diff --git a/Fw/DataStructures/ut b/Fw/DataStructures/ut new file mode 100755 index 00000000000..3996272a13c --- /dev/null +++ b/Fw/DataStructures/ut @@ -0,0 +1,6 @@ +#!/bin/sh -e + +cd `dirname $0` +fprime-util build --ut --jobs 4 +cp ../../build-fprime-automatic-native-ut/bin/Darwin/Fw_DataStructures_ut_exe . +./Fw_DataStructures_ut_exe From 7d04a822075aa3c4ee7e279bf1d6d0c02f9eb37f Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 9 Jun 2025 08:49:43 -0700 Subject: [PATCH 147/458] Revise ut scripts --- Fw/DataStructures/{ut => build_ut} | 1 - Fw/DataStructures/run_ut | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) rename Fw/DataStructures/{ut => build_ut} (84%) create mode 100755 Fw/DataStructures/run_ut diff --git a/Fw/DataStructures/ut b/Fw/DataStructures/build_ut similarity index 84% rename from Fw/DataStructures/ut rename to Fw/DataStructures/build_ut index 3996272a13c..730b54ed832 100755 --- a/Fw/DataStructures/ut +++ b/Fw/DataStructures/build_ut @@ -3,4 +3,3 @@ cd `dirname $0` fprime-util build --ut --jobs 4 cp ../../build-fprime-automatic-native-ut/bin/Darwin/Fw_DataStructures_ut_exe . -./Fw_DataStructures_ut_exe diff --git a/Fw/DataStructures/run_ut b/Fw/DataStructures/run_ut new file mode 100755 index 00000000000..36043aa613f --- /dev/null +++ b/Fw/DataStructures/run_ut @@ -0,0 +1,5 @@ +#!/bin/sh -e + +cd `dirname $0` +./build_ut +./Fw_DataStructures_ut_exe From bdf46d80e18eb45b9fb20d075e8aef219056b44c Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 9 Jun 2025 11:17:06 -0700 Subject: [PATCH 148/458] Revise FifoQueue tests --- Fw/DataStructures/FifoQueue.hpp | 17 ++-- Fw/DataStructures/build_ut | 1 + Fw/DataStructures/clear_gcda | 4 + .../test/ut/ExternalFifoQueueTest.cpp | 3 +- Fw/DataStructures/test/ut/FifoQueueTest.cpp | 81 ++++++------------- 5 files changed, 40 insertions(+), 66 deletions(-) create mode 100755 Fw/DataStructures/clear_gcda diff --git a/Fw/DataStructures/FifoQueue.hpp b/Fw/DataStructures/FifoQueue.hpp index f77d985b8f6..6809f27127b 100644 --- a/Fw/DataStructures/FifoQueue.hpp +++ b/Fw/DataStructures/FifoQueue.hpp @@ -7,8 +7,8 @@ #ifndef Fw_FifoQueue_HPP #define Fw_FifoQueue_HPP -#include "Fw/DataStructures/ExternalFifoQueue.hpp" #include "Fw/DataStructures/Array.hpp" +#include "Fw/DataStructures/ExternalFifoQueue.hpp" namespace Fw { @@ -27,10 +27,10 @@ class FifoQueue final : public FifoQueueBase { // ---------------------------------------------------------------------- //! Zero-argument constructor - FifoQueue() : m_extQueue(m_items, C) {} + FifoQueue() : FifoQueueBase(), m_extQueue(m_items, C) {} //! Copy constructor - FifoQueue(const FifoQueue& queue) : FifoQueueBase() { *this = queue; } + FifoQueue(const FifoQueue& queue) : FifoQueueBase(), m_extQueue(m_items, C) { *this = queue; } //! Destructor ~FifoQueue() override = default; @@ -43,6 +43,7 @@ class FifoQueue final : public FifoQueueBase { //! operator= FifoQueue& operator=(const FifoQueue& queue) { this->m_extQueue.copyDataFrom(queue); + return *this; } //! Clear the queue @@ -52,14 +53,14 @@ class FifoQueue final : public FifoQueueBase { //! \return SUCCESS if item enqueued Success enqueue(const T& e //!< The item (output) ) override { - return this->m_extQueue.enqueue(e); + return this->m_extQueue.enqueue(e); } //! Dequeue an item (pop from the left) //! \return SUCCESS if item dequeued Success dequeue(T& e //!< The item (output) - ) override { - return this->m_extQueue.dequeue(e); + ) override { + return this->m_extQueue.dequeue(e); } //! Get the size (number of items stored in the queue) @@ -75,7 +76,8 @@ class FifoQueue final : public FifoQueueBase { //! Fails an assertion if the index is out of range //! \return The item const T& at(FwSizeType index //!< The index - ) const override { return this->m_extQueue.at(index); + ) const override { + return this->m_extQueue.at(index); } private: @@ -88,7 +90,6 @@ class FifoQueue final : public FifoQueueBase { //! The array providing the backing memory for m_extQueue T m_items[C] = {}; - }; } // namespace Fw diff --git a/Fw/DataStructures/build_ut b/Fw/DataStructures/build_ut index 730b54ed832..75441c0d858 100755 --- a/Fw/DataStructures/build_ut +++ b/Fw/DataStructures/build_ut @@ -1,5 +1,6 @@ #!/bin/sh -e cd `dirname $0` +./clear_gcda fprime-util build --ut --jobs 4 cp ../../build-fprime-automatic-native-ut/bin/Darwin/Fw_DataStructures_ut_exe . diff --git a/Fw/DataStructures/clear_gcda b/Fw/DataStructures/clear_gcda new file mode 100755 index 00000000000..9be2282bfd7 --- /dev/null +++ b/Fw/DataStructures/clear_gcda @@ -0,0 +1,4 @@ +#!/bin/sh -e + +cd `dirname $0` +find ../.. -name '*.gcda' | xargs rm diff --git a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp index 805ee5473c3..172800994d5 100644 --- a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp @@ -83,7 +83,8 @@ TEST(ExternalFifoQueue, EnqueueFull) { ExternalFifoQueue queue(elts, capacity); // Fill up the FIFO for (FwSizeType i = 0; i < capacity; i++) { - queue.enqueue(0); + const auto status = queue.enqueue(0); + ASSERT_EQ(status, Success::SUCCESS); } // Now try to push another element const U32 val = STest::Pick::any(); diff --git a/Fw/DataStructures/test/ut/FifoQueueTest.cpp b/Fw/DataStructures/test/ut/FifoQueueTest.cpp index cecdb5ac407..bc4e1996777 100644 --- a/Fw/DataStructures/test/ut/FifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/FifoQueueTest.cpp @@ -30,32 +30,23 @@ TEST(FifoQueue, ZeroArgConstructor) { ASSERT_EQ(queue.getSize(), 0); } -#if 0 -TEST(FifoQueue, TypedStorageConstructor) { - constexpr FwSizeType capacity = 10; - U32 items[capacity]; - FifoQueue queue(items, capacity); - FifoQueueTester tester(queue); - ASSERT_EQ(tester.getItems().getElements(), items); - ASSERT_EQ(queue.getCapacity(), capacity); - ASSERT_EQ(queue.getSize(), 0); -} - -TEST(FifoQueue, UntypedStorageConstructor) { - constexpr FwSizeType capacity = 10; - alignas(U32) U8 bytes[capacity * sizeof(U32)]; - FifoQueue queue(ByteArray(&bytes[0], sizeof bytes), capacity); - FifoQueueTester tester(queue); - ASSERT_EQ(tester.getItems().getElements(), reinterpret_cast(bytes)); - ASSERT_EQ(queue.getCapacity(), capacity); - ASSERT_EQ(queue.getSize(), 0); +TEST(FifoQueue, CopyConstructor) { + constexpr FwSizeType capacity = 3; + // Construct q1 + FifoQueue q1; + // Enqueue an item + U32 value = 42; + (void)q1.enqueue(value); + ASSERT_EQ(q1.getSize(), 1); + // Use the copy constructor to construct q2 + FifoQueue q2(q1); + ASSERT_EQ(q2.getSize(), 1); } TEST(FifoQueue, EnqueueOK) { constexpr const FwSizeType capacity = 1000; const FwSizeType size = STest::Pick::lowerUpper(1, capacity); - U32 elts[capacity]; - FifoQueue queue(elts, capacity); + FifoQueue queue; ASSERT_EQ(queue.getCapacity(), capacity); ASSERT_EQ(queue.getSize(), 0); for (FwSizeType i = 0; i < size; i++) { @@ -78,11 +69,11 @@ TEST(FifoQueue, EnqueueOK) { TEST(FifoQueue, EnqueueFull) { constexpr const FwSizeType capacity = 1000; - U32 elts[capacity]; - FifoQueue queue(elts, capacity); + FifoQueue queue; // Fill up the FIFO for (FwSizeType i = 0; i < capacity; i++) { - queue.enqueue(0); + const auto status = queue.enqueue(0); + ASSERT_EQ(status, Success::SUCCESS); } // Now try to push another element const U32 val = STest::Pick::any(); @@ -91,35 +82,15 @@ TEST(FifoQueue, EnqueueFull) { ASSERT_EQ(status, Success::FAILURE); } -TEST(FifoQueue, CopyConstructor) { - constexpr FwSizeType capacity = 3; - U32 items[capacity]; - // Call the constructor providing backing storage - FifoQueue q1(items, capacity); - // Enqueue an item - U32 value = 42; - (void)q1.enqueue(value); - // Call the copy constructor - FifoQueue q2(q1); - FifoQueueTester tester1(q1); - FifoQueueTester tester2(q2); - ASSERT_EQ(tester2.getItems().getElements(), items); - ASSERT_EQ(tester2.getItems().getSize(), capacity); - ASSERT_EQ(tester2.getEnqueueIndex().getValue(), 1); - ASSERT_EQ(tester2.getDequeueIndex().getValue(), 0); - ASSERT_EQ(q2.getSize(), 1); -} - TEST(FifoQueue, CopyAssignmentOperator) { constexpr FwSizeType capacity = 3; - U32 items[capacity]; // Call the constructor providing backing storage - FifoQueue q1(items, capacity); + FifoQueue q1; // Enqueue an item U32 value = 42; (void)q1.enqueue(value); // Call the default constructor - FifoQueue q2; + FifoQueue q2; ASSERT_EQ(q2.getSize(), 0); // Call the copy assignment operator q2 = q1; @@ -130,7 +101,7 @@ TEST(FifoQueue, DequeueOK) { constexpr const FwSizeType capacity = 1000; const FwSizeType size = STest::Pick::lowerUpper(1, capacity); U32 items[capacity]; - FifoQueue queue(items, capacity); + FifoQueue queue; ASSERT_EQ(queue.getCapacity(), capacity); ASSERT_EQ(queue.getSize(), 0); for (FwSizeType i = 0; i < size; i++) { @@ -138,7 +109,7 @@ TEST(FifoQueue, DequeueOK) { const U32 val = STest::Pick::any(); // Enqueue it const auto status = queue.enqueue(val); - ASSERT_EQ(val, items[i]); + items[i] = val; ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(queue.getSize(), i + 1); } @@ -159,8 +130,7 @@ TEST(FifoQueue, DequeueOK) { TEST(FifoQueue, DequeueEmpty) { constexpr const FwSizeType capacity = 1000; - U32 items[capacity]; - FifoQueue queue(items, capacity); + FifoQueue queue; U32 val = 0; const auto status = queue.dequeue(val); ASSERT_EQ(status, Success::FAILURE); @@ -193,26 +163,23 @@ void testCopyDataFrom(FifoQueueBase& q1, FwSizeType size1, FifoQueueBase q1(items1, maxSize); + FifoQueue q1; // size1 < capacity2 { - FifoQueue q2(items2, maxSize); + FifoQueue q2; testCopyDataFrom(q1, smallSize, q2); } // size1 == size2 { - FifoQueue q2(items2, maxSize); + FifoQueue q2; testCopyDataFrom(q1, maxSize, q2); } // size1 > size2 { - FifoQueue q2(items2, smallSize); + FifoQueue q2; testCopyDataFrom(q1, maxSize, q2); } } -#endif TEST(FifoQueueRules, EnqueueOK) { State state; From dba5f2f0c291b3240645ae99c3131e234dcebfe8 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 9 Jun 2025 11:30:51 -0700 Subject: [PATCH 149/458] Revise Fifo Queue tests --- Fw/DataStructures/test/ut/FifoQueueTest.cpp | 34 ++++---- .../test/ut/STest/FifoQueueTestRules.hpp | 82 ++++++++++--------- .../test/ut/STest/FifoQueueTestScenarios.hpp | 2 +- 3 files changed, 65 insertions(+), 53 deletions(-) diff --git a/Fw/DataStructures/test/ut/FifoQueueTest.cpp b/Fw/DataStructures/test/ut/FifoQueueTest.cpp index bc4e1996777..1cb32e99181 100644 --- a/Fw/DataStructures/test/ut/FifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/FifoQueueTest.cpp @@ -182,31 +182,37 @@ TEST(FifoQueue, CopyDataFrom) { } TEST(FifoQueueRules, EnqueueOK) { - State state; - Rules::enqueueOK.apply(state); + State state; + Rules::enqueueOK.apply(state); } TEST(FifoQueueRules, EnqueueFull) { - State state; - for (FwSizeType i = 0; i < State::capacity; i++) { + State state; + for (FwSizeType i = 0; i < State::capacity; i++) { + Rules::enqueueOK.apply(state); + } + Rules::enqueueFull.apply(state); +} + +TEST(FifoQueueRules, At) { + State state; Rules::enqueueOK.apply(state); - } - Rules::enqueueFull.apply(state); + Rules::at.apply(state); } TEST(FifoQueueRules, Clear) { - State state; - Rules::enqueueOK.apply(state); - ASSERT_EQ(state.queue.getSize(), 1); - Rules::clear.apply(state); - ASSERT_EQ(state.queue.getSize(), 0); + State state; + Rules::enqueueOK.apply(state); + ASSERT_EQ(state.queue.getSize(), 1); + Rules::clear.apply(state); + ASSERT_EQ(state.queue.getSize(), 0); } TEST(FifoQueueScenarios, Random) { - State state; - Scenarios::random(state, 1000); + State state; + Scenarios::random(state, 1000); } -} +} // namespace FifoQueueTest } // namespace Fw diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp index ecb96d6a345..5624a592905 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp @@ -15,46 +15,52 @@ using Rule = STest::Rule; namespace Rules { - struct EnqueueOK : public Rule { - EnqueueOK() : Rule("EnqueueOK") {} - bool precondition(const State& state) { - return static_cast(state.modelQueue.size()) < State::capacity; - } - void action(State& state) { - const U32 value = STest::Pick::any(); - const auto status = state.queue.enqueue(value); - ASSERT_EQ(status, Success::SUCCESS); - state.modelQueue.push_back(value); - } - }; - static EnqueueOK enqueueOK; - - struct EnqueueFull : public Rule { - EnqueueFull() : Rule("EnqueueFull") {} - bool precondition(const State& state) { - return static_cast(state.modelQueue.size()) >= State::capacity; - } - void action(State& state) { - const auto item = State::getRandomItem(); - const auto status = state.queue.enqueue(item); - ASSERT_EQ(status, Success::FAILURE); - } - }; - static EnqueueFull enqueueFull; - - struct Clear : public Rule { - Clear() : Rule("Clear") {} - bool precondition(const State& state) { return true; } - void action(State& state) { - state.queue.clear(); - ASSERT_EQ(state.queue.getSize(), 0); - state.modelQueue.clear(); - } - }; - static Clear clear; +struct EnqueueOK : public Rule { + EnqueueOK() : Rule("EnqueueOK") {} + bool precondition(const State& state) { return static_cast(state.queue.getSize()) < State::capacity; } + void action(State& state) { + const U32 value = STest::Pick::any(); + const auto status = state.queue.enqueue(value); + ASSERT_EQ(status, Success::SUCCESS); + state.modelQueue.push_back(value); + } }; +static EnqueueOK enqueueOK; -} +struct EnqueueFull : public Rule { + EnqueueFull() : Rule("EnqueueFull") {} + bool precondition(const State& state) { return static_cast(state.queue.getSize()) >= State::capacity; } + void action(State& state) { + const auto item = State::getRandomItem(); + const auto status = state.queue.enqueue(item); + ASSERT_EQ(status, Success::FAILURE); + } +}; +static EnqueueFull enqueueFull; + +struct At : public Rule { + At() : Rule("At") {} + bool precondition(const State& state) { return state.queue.getSize() > 0; } + void action(State& state) { + const auto index = STest::Pick::startLength(0, static_cast(state.queue.getSize())); + ASSERT_EQ(state.queue.at(index), state.modelQueue.at(index)); + } +}; +static At at; + +struct Clear : public Rule { + Clear() : Rule("Clear") {} + bool precondition(const State& state) { return state.queue.getSize() > 0; } + void action(State& state) { + state.queue.clear(); + ASSERT_EQ(state.queue.getSize(), 0); + state.modelQueue.clear(); + } +}; +static Clear clear; +}; // namespace Rules + +} // namespace FifoQueueTest } // namespace Fw diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp index 0781be9d2bc..de069a3cdba 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp @@ -14,7 +14,7 @@ namespace FifoQueueTest { namespace Scenarios { -Rule* rules[] = {&Rules::enqueueOK, &Rules::enqueueFull, &Rules::clear}; +Rule* rules[] = {&Rules::enqueueOK, &Rules::enqueueFull, &Rules::at, &Rules::clear}; void random(State& state, U32 maxNumSteps) { STest::RandomScenario scenario("RandomScenario", rules, From 3a7ca21247f08095351215bfaf1c9997a1c5eadd Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 9 Jun 2025 11:53:19 -0700 Subject: [PATCH 150/458] Revise Fifo Queue tests --- Fw/DataStructures/ExternalFifoQueue.hpp | 5 +++-- Fw/DataStructures/test/ut/FifoQueueTest.cpp | 6 ++++++ .../test/ut/STest/FifoQueueTestRules.hpp | 15 +++++++++++++++ .../test/ut/STest/FifoQueueTestState.hpp | 4 ++-- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/Fw/DataStructures/ExternalFifoQueue.hpp b/Fw/DataStructures/ExternalFifoQueue.hpp index a9ea5c5cd2d..0d7bedaff97 100644 --- a/Fw/DataStructures/ExternalFifoQueue.hpp +++ b/Fw/DataStructures/ExternalFifoQueue.hpp @@ -121,7 +121,8 @@ class ExternalFifoQueue final : public FifoQueueBase { //! \return The item const T& at(FwSizeType index //!< The index ) const override { - FW_ASSERT(index < this->m_size); + FW_ASSERT(index < this->m_size, static_cast(index), + static_cast(this->m_size)); auto ci = this->m_dequeueIndex; const auto i = ci.increment(index); return this->m_items[i]; @@ -130,7 +131,7 @@ class ExternalFifoQueue final : public FifoQueueBase { //! Dequeue an element (pop from the left) //! \return SUCCESS if element dequeued Success dequeue(T& e //!< The element (output) - ) override { + ) override { auto status = Success::FAILURE; if (this->m_size > 0) { e = this->at(0); diff --git a/Fw/DataStructures/test/ut/FifoQueueTest.cpp b/Fw/DataStructures/test/ut/FifoQueueTest.cpp index 1cb32e99181..520b199a1a9 100644 --- a/Fw/DataStructures/test/ut/FifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/FifoQueueTest.cpp @@ -200,6 +200,12 @@ TEST(FifoQueueRules, At) { Rules::at.apply(state); } +TEST(FifoQueueRules, DequeueOK) { + State state; + Rules::enqueueOK.apply(state); + Rules::dequeueOK.apply(state); +} + TEST(FifoQueueRules, Clear) { State state; Rules::enqueueOK.apply(state); diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp index 5624a592905..596b48ff107 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp @@ -48,6 +48,21 @@ struct At : public Rule { }; static At at; +struct DequeueOK : public Rule { + DequeueOK() : Rule("DequeueOK") {} + bool precondition(const State& state) { return static_cast(state.queue.getSize()) > 0; } + void action(State& state) { + U32 value = 0; + const auto status = state.queue.dequeue(value); + ASSERT_EQ(status, Success::SUCCESS); + const auto expectedValue = state.modelQueue.at(0); + ASSERT_EQ(value, expectedValue); + state.modelQueue.pop_front(); + ASSERT_EQ(state.queue.getSize(), state.modelQueue.size()); + } +}; +static DequeueOK dequeueOK; + struct Clear : public Rule { Clear() : Rule("Clear") {} bool precondition(const State& state) { return state.queue.getSize() > 0; } diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp index aee7f6c5eb4..6cdbd50c3d2 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp @@ -1,7 +1,7 @@ #ifndef FifoQueueTestState_HPP #define FifoQueueTestState_HPP -#include +#include #include "Fw/DataStructures/FifoQueue.hpp" #include "STest/STest/Pick/Pick.hpp" @@ -18,7 +18,7 @@ struct State { //! The queue under test FifoQueue queue; //! The queue for modeling correct behavior - std::vector modelQueue; + std::deque modelQueue; //! Get a random item static ItemType getRandomItem() { return STest::Pick::any(); } }; From db265ca2d437a90986cd15ee2e3b7f1c82500921 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 9 Jun 2025 12:00:12 -0700 Subject: [PATCH 151/458] Revise FifoQueue tests --- Fw/DataStructures/test/ut/FifoQueueTest.cpp | 5 +++++ .../test/ut/STest/FifoQueueTestRules.hpp | 11 +++++++++++ 2 files changed, 16 insertions(+) diff --git a/Fw/DataStructures/test/ut/FifoQueueTest.cpp b/Fw/DataStructures/test/ut/FifoQueueTest.cpp index 520b199a1a9..2f8aad47f32 100644 --- a/Fw/DataStructures/test/ut/FifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/FifoQueueTest.cpp @@ -206,6 +206,11 @@ TEST(FifoQueueRules, DequeueOK) { Rules::dequeueOK.apply(state); } +TEST(FifoQueueRules, DequeueEmpty) { + State state; + Rules::dequeueEmpty.apply(state); +} + TEST(FifoQueueRules, Clear) { State state; Rules::enqueueOK.apply(state); diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp index 596b48ff107..7e24713be85 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp @@ -63,6 +63,17 @@ struct DequeueOK : public Rule { }; static DequeueOK dequeueOK; +struct DequeueEmpty : public Rule { + DequeueEmpty() : Rule("DequeueEmpty") {} + bool precondition(const State& state) { return static_cast(state.queue.getSize()) == 0; } + void action(State& state) { + U32 value = 0; + const auto status = state.queue.dequeue(value); + ASSERT_EQ(status, Success::FAILURE); + } +}; +static DequeueEmpty dequeueEmpty; + struct Clear : public Rule { Clear() : Rule("Clear") {} bool precondition(const State& state) { return state.queue.getSize() > 0; } From 559a39e6702f4ccf7251cc4b120169904d1e67dd Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 9 Jun 2025 15:31:48 -0700 Subject: [PATCH 152/458] Revise FifoQueue unit tests --- Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp index de069a3cdba..cade0ac5ec7 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp @@ -14,7 +14,8 @@ namespace FifoQueueTest { namespace Scenarios { -Rule* rules[] = {&Rules::enqueueOK, &Rules::enqueueFull, &Rules::at, &Rules::clear}; +Rule* rules[] = {&Rules::enqueueOK, &Rules::enqueueFull, &Rules::at, + &Rules::dequeueOK, &Rules::dequeueEmpty, &Rules::clear}; void random(State& state, U32 maxNumSteps) { STest::RandomScenario scenario("RandomScenario", rules, From 0ebe470f78d099a4df4999c06d188342db46bf2b Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 9 Jun 2025 15:43:48 -0700 Subject: [PATCH 153/458] Revise unit tests for FifoQueue --- Fw/DataStructures/test/ut/FifoQueueTest.cpp | 21 ++++++++++++------- .../test/ut/STest/FifoQueueTestState.hpp | 6 +++++- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/Fw/DataStructures/test/ut/FifoQueueTest.cpp b/Fw/DataStructures/test/ut/FifoQueueTest.cpp index 2f8aad47f32..1691e2cad59 100644 --- a/Fw/DataStructures/test/ut/FifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/FifoQueueTest.cpp @@ -182,12 +182,14 @@ TEST(FifoQueue, CopyDataFrom) { } TEST(FifoQueueRules, EnqueueOK) { - State state; + State::Queue queue; + State state(queue); Rules::enqueueOK.apply(state); } TEST(FifoQueueRules, EnqueueFull) { - State state; + State::Queue queue; + State state(queue); for (FwSizeType i = 0; i < State::capacity; i++) { Rules::enqueueOK.apply(state); } @@ -195,24 +197,28 @@ TEST(FifoQueueRules, EnqueueFull) { } TEST(FifoQueueRules, At) { - State state; + State::Queue queue; + State state(queue); Rules::enqueueOK.apply(state); Rules::at.apply(state); } TEST(FifoQueueRules, DequeueOK) { - State state; + State::Queue queue; + State state(queue); Rules::enqueueOK.apply(state); Rules::dequeueOK.apply(state); } TEST(FifoQueueRules, DequeueEmpty) { - State state; + State::Queue queue; + State state(queue); Rules::dequeueEmpty.apply(state); } TEST(FifoQueueRules, Clear) { - State state; + State::Queue queue; + State state(queue); Rules::enqueueOK.apply(state); ASSERT_EQ(state.queue.getSize(), 1); Rules::clear.apply(state); @@ -220,7 +226,8 @@ TEST(FifoQueueRules, Clear) { } TEST(FifoQueueScenarios, Random) { - State state; + State::Queue queue; + State state(queue); Scenarios::random(state, 1000); } diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp index 6cdbd50c3d2..316fec23e61 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp @@ -15,8 +15,12 @@ struct State { using ItemType = U32; //! The queue capacity static constexpr FwSizeType capacity = 1024; + //! The FifoQueue type + using Queue = FifoQueue; + //! Constructor + State(Queue& a_queue) : queue(a_queue) {} //! The queue under test - FifoQueue queue; + Queue& queue; //! The queue for modeling correct behavior std::deque modelQueue; //! Get a random item From eb80e6cad41a65e72e1af4b2b770fd6cfa3eece2 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 9 Jun 2025 16:18:42 -0700 Subject: [PATCH 154/458] Revise unit tests for ExternalFifoQueue --- .../test/ut/ExternalFifoQueueTest.cpp | 67 +++++++++++++++++-- Fw/DataStructures/test/ut/FifoQueueTest.cpp | 6 +- .../test/ut/STest/FifoQueueTestScenarios.hpp | 4 +- .../test/ut/STest/FifoQueueTestState.hpp | 10 ++- 4 files changed, 75 insertions(+), 12 deletions(-) diff --git a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp index 172800994d5..7b97805d6c3 100644 --- a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp @@ -4,10 +4,7 @@ // \brief cpp file for ExternalFifoQueue tests // ====================================================================== -#include - -#include "Fw/DataStructures/ExternalFifoQueue.hpp" -#include "STest/Pick/Pick.hpp" +#include "Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp" namespace Fw { @@ -26,6 +23,8 @@ class ExternalFifoQueueTester { const ExternalFifoQueue& m_queue; }; +namespace FifoQueueTest { + TEST(ExternalFifoQueue, ZeroArgConstructor) { ExternalFifoQueue queue; ASSERT_EQ(queue.getCapacity(), 0); @@ -214,4 +213,64 @@ TEST(ExternalFifoQueue, CopyDataFrom) { testCopyDataFrom(q1, maxSize, q2); } } + +TEST(ExternalFifoQueueRules, EnqueueOK) { + U32 items[State::capacity]; + State::ExternalQueue queue(items, State::capacity); + State state(queue); + Rules::enqueueOK.apply(state); +} + +TEST(ExternalFifoQueueRules, EnqueueFull) { + U32 items[State::capacity]; + State::ExternalQueue queue(items, State::capacity); + State state(queue); + for (FwSizeType i = 0; i < State::capacity; i++) { + Rules::enqueueOK.apply(state); + } + Rules::enqueueFull.apply(state); +} + +TEST(ExternalFifoQueueRules, At) { + U32 items[State::capacity]; + State::ExternalQueue queue(items, State::capacity); + State state(queue); + Rules::enqueueOK.apply(state); + Rules::at.apply(state); +} + +TEST(ExternalFifoQueueRules, DequeueOK) { + U32 items[State::capacity]; + State::ExternalQueue queue(items, State::capacity); + State state(queue); + Rules::enqueueOK.apply(state); + Rules::dequeueOK.apply(state); +} + +TEST(ExternalFifoQueueRules, DequeueEmpty) { + U32 items[State::capacity]; + State::ExternalQueue queue(items, State::capacity); + State state(queue); + Rules::dequeueEmpty.apply(state); +} + +TEST(ExternalFifoQueueRules, Clear) { + U32 items[State::capacity]; + State::ExternalQueue queue(items, State::capacity); + State state(queue); + Rules::enqueueOK.apply(state); + ASSERT_EQ(state.queue.getSize(), 1); + Rules::clear.apply(state); + ASSERT_EQ(state.queue.getSize(), 0); +} + +#if 0 +TEST(ExternalFifoQueueScenarios, Random) { + State::Queue queue; + State state(queue); + Scenarios::random(state, 1000); +} +#endif + +} // namespace FifoQueueTest } // namespace Fw diff --git a/Fw/DataStructures/test/ut/FifoQueueTest.cpp b/Fw/DataStructures/test/ut/FifoQueueTest.cpp index 1691e2cad59..8e6ad8eec5a 100644 --- a/Fw/DataStructures/test/ut/FifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/FifoQueueTest.cpp @@ -8,8 +8,6 @@ namespace Fw { -namespace FifoQueueTest { - template class FifoQueueTester { public: @@ -23,6 +21,8 @@ class FifoQueueTester { const FifoQueue& m_queue; }; +namespace FifoQueueTest { + TEST(FifoQueue, ZeroArgConstructor) { constexpr FwSizeType C = 10; FifoQueue queue; @@ -228,7 +228,7 @@ TEST(FifoQueueRules, Clear) { TEST(FifoQueueScenarios, Random) { State::Queue queue; State state(queue); - Scenarios::random(state, 1000); + Scenarios::random(Fw::String("FifoQueueRandom"), state, 1000); } } // namespace FifoQueueTest diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp index cade0ac5ec7..abb01ad4726 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp @@ -17,10 +17,10 @@ namespace Scenarios { Rule* rules[] = {&Rules::enqueueOK, &Rules::enqueueFull, &Rules::at, &Rules::dequeueOK, &Rules::dequeueEmpty, &Rules::clear}; -void random(State& state, U32 maxNumSteps) { +void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { STest::RandomScenario scenario("RandomScenario", rules, sizeof(rules) / sizeof(STest::RandomScenario*)); - STest::BoundedScenario boundedScenario("BoundedRandomScenario", scenario, maxNumSteps); + STest::BoundedScenario boundedScenario(name.toChar(), scenario, maxNumSteps); const U32 numSteps = boundedScenario.run(state); printf("Ran %u steps.\n", numSteps); } diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp index 316fec23e61..f1a25a93c94 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp @@ -15,12 +15,16 @@ struct State { using ItemType = U32; //! The queue capacity static constexpr FwSizeType capacity = 1024; - //! The FifoQueue type + //! The Queue type using Queue = FifoQueue; + //! The ExternalQueue type + using ExternalQueue = ExternalFifoQueue; + //! THe QueueBase type + using QueueBase = FifoQueueBase; //! Constructor - State(Queue& a_queue) : queue(a_queue) {} + State(QueueBase& a_queue) : queue(a_queue) {} //! The queue under test - Queue& queue; + QueueBase& queue; //! The queue for modeling correct behavior std::deque modelQueue; //! Get a random item From 85cf59564e7bbbe342d4d1bb0c20e99c9ae62543 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 9 Jun 2025 16:30:15 -0700 Subject: [PATCH 155/458] Revise unit tests for FifoQueue --- Fw/DataStructures/CMakeLists.txt | 2 ++ .../test/ut/ExternalFifoQueueTest.cpp | 1 + Fw/DataStructures/test/ut/FifoQueueTest.cpp | 1 + .../test/ut/STest/FifoQueueTestRules.cpp | 31 ++++++++++++++++++ .../test/ut/STest/FifoQueueTestRules.hpp | 19 +++++++---- .../test/ut/STest/FifoQueueTestScenarios.cpp | 32 +++++++++++++++++++ .../test/ut/STest/FifoQueueTestScenarios.hpp | 15 ++------- 7 files changed, 82 insertions(+), 19 deletions(-) create mode 100644 Fw/DataStructures/test/ut/STest/FifoQueueTestRules.cpp create mode 100644 Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.cpp diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index 7bc1512d41d..32570176695 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -11,6 +11,8 @@ set(UT_SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" ) set(UT_MOD_DEPS diff --git a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp index 7b97805d6c3..2cf71f32b66 100644 --- a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp @@ -5,6 +5,7 @@ // ====================================================================== #include "Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp" +#include "Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp" namespace Fw { diff --git a/Fw/DataStructures/test/ut/FifoQueueTest.cpp b/Fw/DataStructures/test/ut/FifoQueueTest.cpp index 8e6ad8eec5a..e2b3c8ad236 100644 --- a/Fw/DataStructures/test/ut/FifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/FifoQueueTest.cpp @@ -4,6 +4,7 @@ // \brief cpp file for FifoQueue tests // ====================================================================== +#include "Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp" #include "Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp" namespace Fw { diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.cpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.cpp new file mode 100644 index 00000000000..97f0a9f4f30 --- /dev/null +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.cpp @@ -0,0 +1,31 @@ +// ====================================================================== +// \title FifoQueueTestRules.cpp +// \author Rob Bocchino +// \brief FifoQueue test rules +// ====================================================================== + +#include "Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp" + +namespace Fw { + +namespace FifoQueueTest { + +namespace Rules { + +EnqueueOK enqueueOK; + +EnqueueFull enqueueFull; + +At at; + +DequeueOK dequeueOK; + +DequeueEmpty dequeueEmpty; + +Clear clear; + +}; // namespace Rules + +} // namespace FifoQueueTest + +} // namespace Fw diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp index 7e24713be85..dcabf830ee4 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp @@ -25,7 +25,8 @@ struct EnqueueOK : public Rule { state.modelQueue.push_back(value); } }; -static EnqueueOK enqueueOK; + +extern EnqueueOK enqueueOK; struct EnqueueFull : public Rule { EnqueueFull() : Rule("EnqueueFull") {} @@ -36,7 +37,8 @@ struct EnqueueFull : public Rule { ASSERT_EQ(status, Success::FAILURE); } }; -static EnqueueFull enqueueFull; + +extern EnqueueFull enqueueFull; struct At : public Rule { At() : Rule("At") {} @@ -46,7 +48,8 @@ struct At : public Rule { ASSERT_EQ(state.queue.at(index), state.modelQueue.at(index)); } }; -static At at; + +extern At at; struct DequeueOK : public Rule { DequeueOK() : Rule("DequeueOK") {} @@ -61,7 +64,8 @@ struct DequeueOK : public Rule { ASSERT_EQ(state.queue.getSize(), state.modelQueue.size()); } }; -static DequeueOK dequeueOK; + +extern DequeueOK dequeueOK; struct DequeueEmpty : public Rule { DequeueEmpty() : Rule("DequeueEmpty") {} @@ -72,7 +76,8 @@ struct DequeueEmpty : public Rule { ASSERT_EQ(status, Success::FAILURE); } }; -static DequeueEmpty dequeueEmpty; + +extern DequeueEmpty dequeueEmpty; struct Clear : public Rule { Clear() : Rule("Clear") {} @@ -83,7 +88,9 @@ struct Clear : public Rule { state.modelQueue.clear(); } }; -static Clear clear; + +extern Clear clear; + }; // namespace Rules } // namespace FifoQueueTest diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.cpp new file mode 100644 index 00000000000..90a204e1557 --- /dev/null +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.cpp @@ -0,0 +1,32 @@ +// ====================================================================== +// \title FifoQueueTestScenarios.cpp +// \author Rob Bocchino +// \brief FifoQueue test scenarios +// ====================================================================== + +#include "Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp" +#include "Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp" +#include "STest/Scenario/BoundedScenario.hpp" +#include "STest/Scenario/RandomScenario.hpp" + +namespace Fw { + +namespace FifoQueueTest { + +namespace Scenarios { + +void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { + Rule* rules[] = {&Rules::enqueueOK, &Rules::enqueueFull, &Rules::at, + &Rules::dequeueOK, &Rules::dequeueEmpty, &Rules::clear}; + STest::RandomScenario scenario("RandomScenario", rules, + sizeof(rules) / sizeof(STest::RandomScenario*)); + STest::BoundedScenario boundedScenario(name.toChar(), scenario, maxNumSteps); + const U32 numSteps = boundedScenario.run(state); + printf("Ran %u steps.\n", numSteps); +} + +} // namespace Scenarios + +} // namespace FifoQueueTest + +} // namespace Fw diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp index abb01ad4726..2747776338a 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp @@ -4,9 +4,7 @@ // \brief FifoQueue test scenarios // ====================================================================== -#include "Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp" -#include "STest/Scenario/BoundedScenario.hpp" -#include "STest/Scenario/RandomScenario.hpp" +#include "Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp" namespace Fw { @@ -14,16 +12,7 @@ namespace FifoQueueTest { namespace Scenarios { -Rule* rules[] = {&Rules::enqueueOK, &Rules::enqueueFull, &Rules::at, - &Rules::dequeueOK, &Rules::dequeueEmpty, &Rules::clear}; - -void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { - STest::RandomScenario scenario("RandomScenario", rules, - sizeof(rules) / sizeof(STest::RandomScenario*)); - STest::BoundedScenario boundedScenario(name.toChar(), scenario, maxNumSteps); - const U32 numSteps = boundedScenario.run(state); - printf("Ran %u steps.\n", numSteps); -} +void random(const Fw::StringBase& name, State& state, U32 maxNumSteps); } // namespace Scenarios From 59b5cbf3ef13b6ad41584d0f4c1542a3a0e2998c Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 9 Jun 2025 16:33:26 -0700 Subject: [PATCH 156/458] Revise unit tests for ExternalFifoQueue --- Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp index 2cf71f32b66..42d79470c8f 100644 --- a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp @@ -265,13 +265,12 @@ TEST(ExternalFifoQueueRules, Clear) { ASSERT_EQ(state.queue.getSize(), 0); } -#if 0 TEST(ExternalFifoQueueScenarios, Random) { - State::Queue queue; + U32 items[State::capacity]; + State::ExternalQueue queue(items, State::capacity); State state(queue); - Scenarios::random(state, 1000); + Scenarios::random(Fw::String("ExternalFifoQueueRandom"), state, 1000); } -#endif } // namespace FifoQueueTest } // namespace Fw From 45eccca18f2ed62165f5c9fc911778ab1822e94d Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 11 Jun 2025 11:42:14 -0700 Subject: [PATCH 157/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/sdd.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Fw/DataStructures/docs/sdd.md b/Fw/DataStructures/docs/sdd.md index 42bfe9667c0..2baff1e30f2 100644 --- a/Fw/DataStructures/docs/sdd.md +++ b/Fw/DataStructures/docs/sdd.md @@ -26,9 +26,10 @@ stored in _M_. `Fw/DataStructures` provides the following array templates: -* [`ExternalArray`](ExternalArray.md) - -* [`Array`](Array.md) +|Name|Description| +|----|-----------| +|[`Array`](Array.md)|A bounds-checked array with internal memory for storing the array elements| +|[`ExternalArray`](ExternalArray.md)|A bounds-checked array with external memory for storing the array elements| ## 2. FIFO Queues @@ -40,11 +41,11 @@ first in first out (FIFO) order. `Fw/DataStructures` provides the following FIFO queue templates: -* [`FifoQueueBase`](FifoQueueBase.md) - -* [`ExternalFifoQueue`](ExternalFifoQueue.md) - -* [`FifoQueue`](FifoQueue.md) +|Name|Description| +|----|-----------| +|[`ExternalFifoQueue`](ExternalFifoQueue.md)|A FIFO queue with external memory for storing the queue items| +|[`FifoQueue`](FifoQueue.md)|A FIFO queue with internal memory for storing the queue items| +|[`FifoQueueBase`](FifoQueueBase.md)|The abstract base class for a FIFO queue| The queue implementations use a template called [`CircularIndex`](CircularIndex.md) From 729b417d180cc8022fec636aaa774a1b3c56c3fb Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 08:38:04 -0700 Subject: [PATCH 158/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/build_ut | 2 +- Fw/DataStructures/docs/sdd.md | 25 ++++++++++++++++++++----- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/Fw/DataStructures/build_ut b/Fw/DataStructures/build_ut index 75441c0d858..55e45a4e109 100755 --- a/Fw/DataStructures/build_ut +++ b/Fw/DataStructures/build_ut @@ -2,5 +2,5 @@ cd `dirname $0` ./clear_gcda -fprime-util build --ut --jobs 4 +fprime-util build --ut "$@" cp ../../build-fprime-automatic-native-ut/bin/Darwin/Fw_DataStructures_ut_exe . diff --git a/Fw/DataStructures/docs/sdd.md b/Fw/DataStructures/docs/sdd.md index 2baff1e30f2..bbb45363c8d 100644 --- a/Fw/DataStructures/docs/sdd.md +++ b/Fw/DataStructures/docs/sdd.md @@ -63,15 +63,30 @@ classDiagram ## 3. Maps -* [`MapBase`](MapBase.md) +A *map* is a data structure that associates keys to values. +It provides insert, remove, and find operations. -* [`ExternalArrayMap`](ExternalArrayMap.md) +### 3.1. Templates -* [`ArrayMap`](ArrayMap.md) +`Fw/DataStructures` provides the following map templates: -* [`RedBlackTreeMap`](RedBlackTreeMap.md) +|Name|Description| +|----|-----------| +|[`ArrayMap`](ArrayMap.md)|An array-based map with internal memory for storing the array| +|[`ExternalArrayMap`](ExternalArrayMap.md)|An array-based map with external memory for storing the array| +|[`ExternalRedBlackTreeMap`](ExternalRedBlackTreeMap.md)|A red-black tree with external memory storing the tree| +|[`MapBase`](MapBase.md)|The abstract base class for a map| +|[`RedBlackTreeMap`](RedBlackTreeMap.md)|A red-black tree with internal memory for storing the tree| + +### 3.2. Class Diagram -* [`ExternalRedBlackTreeMap`](ExternalRedBlackTreeMap.md) +```mermaid +classDiagram + MapBase <|-- ArrayMap + MapBase <|-- ExternalArrayMap + MapBase <|-- ExternalRedBlackTreeMap + MapBase <|-- RedBlackTreeMap +``` ## 4. Sets From 10d1f39108bdf748d5c0087f1034a33b359b4563 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 08:46:56 -0700 Subject: [PATCH 159/458] Revise SDD for FifoQueueBase --- Fw/DataStructures/docs/FifoQueueBase.md | 150 ++++++++++++------------ 1 file changed, 75 insertions(+), 75 deletions(-) diff --git a/Fw/DataStructures/docs/FifoQueueBase.md b/Fw/DataStructures/docs/FifoQueueBase.md index 5a12cc923be..fdc9a264f6f 100644 --- a/Fw/DataStructures/docs/FifoQueueBase.md +++ b/Fw/DataStructures/docs/FifoQueueBase.md @@ -52,7 +52,32 @@ Defined as `= delete`. ## 5. Public Member Functions -### 5.1. clear +### 5.1. at + +```c++ +virtual const T& at(FwSizeType index) const = 0 +``` + +Return the item at the specified index. +Index 0 is the leftmost (earliest) element in the queue. +Increasing indices go from left to right. +Fails an assertion if the index is out of range. + +_Example:_ +```c++ +void f(FifoQueueBase& queue) { + queue.clear(); + const auto status = queue.enqueue(3); + ASSERT_EQ(status, Success::SUCCESS); + const auto status = queue.enqueue(4); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(queue.at(0), 3); + ASSERT_EQ(queue.at(1), 4); + ASSERT_DEATH(queue.at(2), "Assert"); +} +``` + +### 5.2. clear ```c++ virtual void clear() = 0 @@ -68,7 +93,7 @@ void f(FifoQueueBase& queue) { } ``` -### 5.2. copyDataFrom +### 5.3. copyDataFrom ```c++ void copyDataFrom(const FifoQueueBase& queue) @@ -103,17 +128,17 @@ void f(FifoQueueBase& q1, FifoQueueBase& q2) { } ``` -### 5.3. enqueue +### 5.4. dequeue ```c++ -virtual Success enqueue(const T& e) = 0 +virtual Success dequeue(T& e) = 0 ``` 1. Set `status = Success::FAILURE`. -1. If there is room on the queue for a new item, then +1. If `size > 0` - 1. Add `e` to the right of the queue. + 1. Remove the leftmost item from the queue and store it into `e`. 1. Set `status = Success::SUCCESS`. @@ -123,47 +148,28 @@ _Example:_ ```c++ void f(FifoQueueBase& queue) { queue.clear(); - const auto status = queue.enqueue(3); - ASSERT_EQ(status, Success::SUCCESS); -} -``` - -### 5.4. at - -```c++ -virtual const T& at(FwSizeType index) const = 0 -``` - -Return the item at the specified index. -Index 0 is the leftmost (earliest) element in the queue. -Increasing indices go from left to right. -Fails an assertion if the index is out of range. - -_Example:_ -```c++ -void f(FifoQueueBase& queue) { - queue.clear(); - const auto status = queue.enqueue(3); + U32 val = 0; + auto status = queue.dequeue(val); + ASSERT_EQ(status, Success::FAILURE); + status = queue.enqueue(3); ASSERT_EQ(status, Success::SUCCESS); - const auto status = queue.enqueue(4); + status = queue.dequeue(val); ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(queue.at(0), 3); - ASSERT_EQ(queue.at(1), 4); - ASSERT_DEATH(queue.at(2), "Assert"); + ASSERT_EQ(val, 3); } ``` -### 5.5. peek +### 5.5. enqueue ```c++ -Success peek(T& e, FwSizeType index = 0) const +virtual Success enqueue(const T& e) = 0 ``` 1. Set `status = Success::FAILURE`. -1. If `index < getSize()` +1. If there is room on the queue for a new item, then - 1. Set `e = at(index)`. + 1. Add `e` to the right of the queue. 1. Set `status = Success::SUCCESS`. @@ -173,50 +179,25 @@ _Example:_ ```c++ void f(FifoQueueBase& queue) { queue.clear(); - U32 value = 0; - auto status = queue.peek(value); - ASSERT_EQ(status, Success::FAILURE); - status = queue.enqueue(3); - status = queue.peek(value); - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(value, 3); - status = queue.peek(value, 1); - ASSERT_EQ(status, Success::FAILURE); - status = queue.enqueue(4); - status = queue.peek(value, 1); + const auto status = queue.enqueue(3); ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(value, 4); } ``` -### 5.6. dequeue +### 5.6. getCapacity ```c++ -virtual Success dequeue(T& e) = 0 +virtual FwSizeType getCapacity() const = 0 ``` -1. Set `status = Success::FAILURE`. - -1. If `size > 0` - - 1. Remove the leftmost item from the queue and store it into `e`. - - 1. Set `status = Success::SUCCESS`. - -1. Return `status`. +Return the current capacity. _Example:_ ```c++ -void f(FifoQueueBase& queue) { - queue.clear(); - U32 val = 0; - auto status = queue.dequeue(val); - ASSERT_EQ(status, Success::FAILURE); - status = queue.enqueue(3); - ASSERT_EQ(status, Success::SUCCESS); - status = queue.dequeue(val); - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(val, 3); +void f(const FifoQueueBase& queue) { + const auto size = queue.getSize(); + const auto capacity = queue.getCapacity(); + ASSERT_LE(size, capacity); } ``` @@ -241,20 +222,39 @@ void f(const FifoQueueBase& queue) { } ``` -### 5.8. getCapacity +### 5.8. peek ```c++ -virtual FwSizeType getCapacity() const = 0 +Success peek(T& e, FwSizeType index = 0) const ``` -Return the current capacity. +1. Set `status = Success::FAILURE`. + +1. If `index < getSize()` + + 1. Set `e = at(index)`. + + 1. Set `status = Success::SUCCESS`. + +1. Return `status`. _Example:_ ```c++ -void f(const FifoQueueBase& queue) { - const auto size = queue.getSize(); - const auto capacity = queue.getCapacity(); - ASSERT_LE(size, capacity); +void f(FifoQueueBase& queue) { + queue.clear(); + U32 value = 0; + auto status = queue.peek(value); + ASSERT_EQ(status, Success::FAILURE); + status = queue.enqueue(3); + status = queue.peek(value); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(value, 3); + status = queue.peek(value, 1); + ASSERT_EQ(status, Success::FAILURE); + status = queue.enqueue(4); + status = queue.peek(value, 1); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(value, 4); } ``` From 76451646db7a87279b56760ccb68dad61a6f2613 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 09:00:08 -0700 Subject: [PATCH 160/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/sdd.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/sdd.md b/Fw/DataStructures/docs/sdd.md index bbb45363c8d..bcba5fe0b36 100644 --- a/Fw/DataStructures/docs/sdd.md +++ b/Fw/DataStructures/docs/sdd.md @@ -16,6 +16,14 @@ in general the same. For example, a map has a capacity _C_ and a size between 0 and _C_. +The data structures in this directory are **sequential data structures**, +i.e., they do not support direct concurrent access by multiple threads. +To use these data structures in a multithreaded context, you have +to guard the access yourself. +The most common way to do this in F Prime is to make the data +structure a member of an active or queued component and use +the component queue to guard the access to the structure. + ## 1. Arrays An **array** _A_ stores _S_ elements for _S > 0_ at indices @@ -63,7 +71,7 @@ classDiagram ## 3. Maps -A *map* is a data structure that associates keys to values. +A **map** is a data structure that associates keys to values. It provides insert, remove, and find operations. ### 3.1. Templates From f64a82e591ab70898951d26862cf4dc3039ec6d3 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 09:01:03 -0700 Subject: [PATCH 161/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/sdd.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Fw/DataStructures/docs/sdd.md b/Fw/DataStructures/docs/sdd.md index bcba5fe0b36..ee704e0760c 100644 --- a/Fw/DataStructures/docs/sdd.md +++ b/Fw/DataStructures/docs/sdd.md @@ -19,9 +19,9 @@ and _C_. The data structures in this directory are **sequential data structures**, i.e., they do not support direct concurrent access by multiple threads. To use these data structures in a multithreaded context, you have -to guard the access yourself. -The most common way to do this in F Prime is to make the data -structure a member of an active or queued component and use +to guard the access separately. +The most common way to do this is to make the data +structure a member of an active or queued component and to use the component queue to guard the access to the structure. ## 1. Arrays From 0d056bdc56302da1c5a8523f58d302d8e9e744d8 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 09:48:51 -0700 Subject: [PATCH 162/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/MapBase.md | 198 ++++++++++++++++++++++++++++- Fw/DataStructures/docs/MapEntry.md | 80 ++++++++++++ Fw/DataStructures/docs/sdd.md | 6 +- 3 files changed, 282 insertions(+), 2 deletions(-) create mode 100644 Fw/DataStructures/docs/MapEntry.md diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index a8ec974c155..a74e35b8c6e 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -1,4 +1,200 @@ # MapBase -TODO +`MapBase` is a class template +defined in [`Fw/DataStructures`](sdd.md). +It represents an abstract base class for a map. + +## 1. Template Parameters + +`MapBase` has the following template parameters. + +|Kind|Name|Purpose| +|----|----|-------| +|`typename`|`K`|The type of a key in the map| +|`typename`|`V`|The type of a value in the map| + +## 2. Private Constructors + +### 2.1. Copy Constructor + +```c++ +MapBase(const MapBase& map) +``` + +Defined as `= delete`. + +## 3. Protected Constructors and Destructors + +### 3.1. Zero-Argument Constructor + +```c++ +MapBase() +``` + +Defined as `= default`. + +### 3.2. Destructor + +```c++ +virtual MapBase() +``` + +Defined as `= default`. + +## 4. Private Member Functions + +### 4.1. operator= + +```c++ +MapBase& operator=(const MapBase&) +``` + +Defined as `= delete`. + +## 5. Public Member Functions + +### 5.2. clear + +```c++ +virtual void clear() = 0 +``` + +Clear the map. + +_Example:_ +```c++ +void f(MapBase& map) { + map.clear(); + ASSERT_EQ(map.getSize(), 0); +} +``` + +### 5.3. copyDataFrom + +```c++ +void copyDataFrom(const MapBase& map) +``` + +1. If `&map != this` then + + 1. Call `clear()`. + + 1. Let `size` be the minimum of `map.getSize()` and `getCapacity()`. + + 1. For `i` in [0, `size`) + + 1. Set `e = at(i)`. + + 1. Set `status = enmap(e)`. + + 1. Assert `status == Success::SUCCESS`. + + +_Example:_ +```c++ +void f(MapBase& q1, MapBase& q2) { + q1.clear(); + // Enmap an item + U32 value = 42; + (void) q1.enmap(value); + q2.clear(); + ASSERT_EQ(q2.getSize(), 0); + q2.copyDataFrom(q1); + ASSERT_EQ(q2.getSize(), 1); +} +``` + +### 5.4. demap + +```c++ +virtual Success demap(T& e) = 0 +``` + +1. Set `status = Success::FAILURE`. + +1. If `size > 0` + + 1. Remove the leftmost item from the map and store it into `e`. + + 1. Set `status = Success::SUCCESS`. + +1. Return `status`. + +_Example:_ +```c++ +void f(MapBase& map) { + map.clear(); + U32 val = 0; + auto status = map.demap(val); + ASSERT_EQ(status, Success::FAILURE); + status = map.enmap(3); + ASSERT_EQ(status, Success::SUCCESS); + status = map.demap(val); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(val, 3); +} +``` + +### 5.5. enmap + +```c++ +virtual Success enmap(const T& e) = 0 +``` + +1. Set `status = Success::FAILURE`. + +1. If there is room on the map for a new item, then + + 1. Add `e` to the right of the map. + + 1. Set `status = Success::SUCCESS`. + +1. Return `status`. + +_Example:_ +```c++ +void f(MapBase& map) { + map.clear(); + const auto status = map.enmap(3); + ASSERT_EQ(status, Success::SUCCESS); +} +``` + +### 5.6. getCapacity + +```c++ +virtual FwSizeType getCapacity() const = 0 +``` + +Return the current capacity. + +_Example:_ +```c++ +void f(const MapBase& map) { + const auto size = map.getSize(); + const auto capacity = map.getCapacity(); + ASSERT_LE(size, capacity); +} +``` + +### 5.7. getSize + +```c++ +virtual FwSizeType getSize() const = 0 +``` + +Return the current size. + +_Example:_ +```c++ +void f(const MapBase& map) { + map.clear(); + auto size = map.getSize(); + ASSERT_EQ(size, 0); + const auto status = map.enmap(3); + ASSERT_EQ(status, Success::SUCCESS); + size = map.getSize(); + ASSERT_EQ(size, 1); +} +``` diff --git a/Fw/DataStructures/docs/MapEntry.md b/Fw/DataStructures/docs/MapEntry.md new file mode 100644 index 00000000000..3d660b7f45d --- /dev/null +++ b/Fw/DataStructures/docs/MapEntry.md @@ -0,0 +1,80 @@ +# MapEntry + +`MapEntry` is a class template +defined in [`Fw/DataStructures`](sdd.md). +It represents an entry in a map. + +## 1. Template Parameters + +`MapEntry` has the following template parameters. + +|Kind|Name|Purpose| +|----|----|-------| +|`typename`|`K`|The type of a key in the map| +|`typename`|`V`|The type of a value in the map| + +## 2. Private Constructors + +### 2.1. Copy Constructor + +```c++ +MapEntry(const MapEntry& map) +``` + +Defined as `= default`. + +## 3. Protected Constructors and Destructors + +### 3.1. Zero-Argument Constructor + +```c++ +MapEntry() +``` + +Defined as `= default`. + +### 3.2. Destructor + +```c++ +MapEntry() +``` + +Defined as `= default`. + +## 4. Private Member Functions + +### 4.1. operator= + +```c++ +MapEntry& operator=(const MapEntry&) +``` + +Defined as `= default`. + +## 5. Public Member Functions + +### 5.1. getKey + +```c++ +const K& getKey() const +``` + +Get a reference to the key. + +### 5.2. getValue + +```c++ +const K& getValue() const +``` + +Get a reference to the value. + +### 5.3. getNextEntry + +```c++ +Fw::Success getNextEntry(MapEntry& entry) +``` + +If the map has a next entry _E_, then set `entry` +to _E_ and return `SUCCESS`. +Otherwise return `FAILURE`. diff --git a/Fw/DataStructures/docs/sdd.md b/Fw/DataStructures/docs/sdd.md index ee704e0760c..b54bf63b4a4 100644 --- a/Fw/DataStructures/docs/sdd.md +++ b/Fw/DataStructures/docs/sdd.md @@ -82,10 +82,14 @@ It provides insert, remove, and find operations. |----|-----------| |[`ArrayMap`](ArrayMap.md)|An array-based map with internal memory for storing the array| |[`ExternalArrayMap`](ExternalArrayMap.md)|An array-based map with external memory for storing the array| -|[`ExternalRedBlackTreeMap`](ExternalRedBlackTreeMap.md)|A red-black tree with external memory storing the tree| +|[`ExternalRedBlackTreeMap`](ExternalRedBlackTreeMap.md)|A red-black tree with external memory for storing the tree| |[`MapBase`](MapBase.md)|The abstract base class for a map| |[`RedBlackTreeMap`](RedBlackTreeMap.md)|A red-black tree with internal memory for storing the tree| +The queue implementations use a template called +[`MapEntry`](MapEntry.md) for representing +an entry in the map. + ### 3.2. Class Diagram ```mermaid From 6efd73301e35984c44a389afd7ab20f64197ecf5 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 09:50:06 -0700 Subject: [PATCH 163/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/MapBase.md | 124 +----------------------------- 1 file changed, 3 insertions(+), 121 deletions(-) diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index a74e35b8c6e..cea8eef9254 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -71,130 +71,12 @@ void f(MapBase& map) { ### 5.3. copyDataFrom -```c++ -void copyDataFrom(const MapBase& map) -``` - -1. If `&map != this` then - - 1. Call `clear()`. - - 1. Let `size` be the minimum of `map.getSize()` and `getCapacity()`. - - 1. For `i` in [0, `size`) - - 1. Set `e = at(i)`. - - 1. Set `status = enmap(e)`. - - 1. Assert `status == Success::SUCCESS`. - - -_Example:_ -```c++ -void f(MapBase& q1, MapBase& q2) { - q1.clear(); - // Enmap an item - U32 value = 42; - (void) q1.enmap(value); - q2.clear(); - ASSERT_EQ(q2.getSize(), 0); - q2.copyDataFrom(q1); - ASSERT_EQ(q2.getSize(), 1); -} -``` - -### 5.4. demap - -```c++ -virtual Success demap(T& e) = 0 -``` - -1. Set `status = Success::FAILURE`. - -1. If `size > 0` - - 1. Remove the leftmost item from the map and store it into `e`. - - 1. Set `status = Success::SUCCESS`. - -1. Return `status`. - -_Example:_ -```c++ -void f(MapBase& map) { - map.clear(); - U32 val = 0; - auto status = map.demap(val); - ASSERT_EQ(status, Success::FAILURE); - status = map.enmap(3); - ASSERT_EQ(status, Success::SUCCESS); - status = map.demap(val); - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(val, 3); -} -``` - -### 5.5. enmap - -```c++ -virtual Success enmap(const T& e) = 0 -``` - -1. Set `status = Success::FAILURE`. - -1. If there is room on the map for a new item, then - - 1. Add `e` to the right of the map. - - 1. Set `status = Success::SUCCESS`. - -1. Return `status`. - -_Example:_ -```c++ -void f(MapBase& map) { - map.clear(); - const auto status = map.enmap(3); - ASSERT_EQ(status, Success::SUCCESS); -} -``` +TODO ### 5.6. getCapacity -```c++ -virtual FwSizeType getCapacity() const = 0 -``` - -Return the current capacity. - -_Example:_ -```c++ -void f(const MapBase& map) { - const auto size = map.getSize(); - const auto capacity = map.getCapacity(); - ASSERT_LE(size, capacity); -} -``` +TODO ### 5.7. getSize -```c++ -virtual FwSizeType getSize() const = 0 -``` - -Return the current size. - -_Example:_ -```c++ -void f(const MapBase& map) { - map.clear(); - auto size = map.getSize(); - ASSERT_EQ(size, 0); - const auto status = map.enmap(3); - ASSERT_EQ(status, Success::SUCCESS); - size = map.getSize(); - ASSERT_EQ(size, 1); -} -``` - +TODO From f0745a2b98174d23ff160fa2eb2f1a29ec1bf2aa Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 09:50:46 -0700 Subject: [PATCH 164/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/MapEntry.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/MapEntry.md b/Fw/DataStructures/docs/MapEntry.md index 3d660b7f45d..fee34c30c53 100644 --- a/Fw/DataStructures/docs/MapEntry.md +++ b/Fw/DataStructures/docs/MapEntry.md @@ -64,7 +64,7 @@ Get a reference to the key. ### 5.2. getValue ```c++ -const K& getValue() const +const V& getValue() const ``` Get a reference to the value. From ce49bd5a43fd8133524895712c1de118661125a3 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 09:54:28 -0700 Subject: [PATCH 165/458] Revise SDD for MapBase --- Fw/DataStructures/docs/MapBase.md | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index cea8eef9254..89bc3aa8098 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -53,7 +53,7 @@ Defined as `= delete`. ## 5. Public Member Functions -### 5.2. clear +### 5.1. clear ```c++ virtual void clear() = 0 @@ -69,7 +69,19 @@ void f(MapBase& map) { } ``` -### 5.3. copyDataFrom +### 5.2. copyDataFrom + +TODO + +### 5.3. delete + +TODO + +### 5.4. find + +TODO + +### 5.5. getHeadEntry TODO @@ -80,3 +92,7 @@ TODO ### 5.7. getSize TODO + +### 5.8. insert + +TODO From 9851c8a705c8d39fbad4f3146e61f4aadc12a4ed Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 15:43:44 -0700 Subject: [PATCH 166/458] Revise SDD for MapEntry --- Fw/DataStructures/docs/MapBase.md | 24 +++++++++++++++++++++-- Fw/DataStructures/docs/MapEntry.md | 31 +++++++++++++++++++----------- 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index 89bc3aa8098..937fbd4f3dd 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -18,7 +18,7 @@ It represents an abstract base class for a map. ### 2.1. Copy Constructor ```c++ -MapBase(const MapBase& map) +MapBase(const MapBase& map) ``` Defined as `= delete`. @@ -63,7 +63,7 @@ Clear the map. _Example:_ ```c++ -void f(MapBase& map) { +void f(MapBase& map) { map.clear(); ASSERT_EQ(map.getSize(), 0); } @@ -71,6 +71,26 @@ void f(MapBase& map) { ### 5.2. copyDataFrom +```c++ +void copyDataFrom(const MapBase& map) +``` + +1. If `&queue != this` then + + 1. Call `clear()`. + + 1. Let `size` be the minimum of `map.getSize()` and `getCapacity()`. + + 1. If `getHeedEntry(e)` returns SUCCESS + + 1. For `i` in [0, `size`) + + 1. Set `e = at(i)`. + + 1. Set `status = enqueue(e)`. + + 1. Assert `status == Success::SUCCESS`. + TODO ### 5.3. delete diff --git a/Fw/DataStructures/docs/MapEntry.md b/Fw/DataStructures/docs/MapEntry.md index fee34c30c53..f4fda88d968 100644 --- a/Fw/DataStructures/docs/MapEntry.md +++ b/Fw/DataStructures/docs/MapEntry.md @@ -13,9 +13,18 @@ It represents an entry in a map. |`typename`|`K`|The type of a key in the map| |`typename`|`V`|The type of a value in the map| -## 2. Private Constructors +## 2. Private Member Variables -### 2.1. Copy Constructor +`MapEntry` has the following private member variables. + +|Name|Type|Purpose|Default Value| +|----|----|-------|-------------| +|`m_key`|`K`|The key|C++ default initialization| +|`m_value`|`V`|The value|C++ default initialization| + +## 3. Private Constructors + +### 3.1. Copy Constructor ```c++ MapEntry(const MapEntry& map) @@ -23,9 +32,9 @@ MapEntry(const MapEntry& map) Defined as `= default`. -## 3. Protected Constructors and Destructors +## 4. Protected Constructors and Destructors -### 3.1. Zero-Argument Constructor +### 4.1. Zero-Argument Constructor ```c++ MapEntry() @@ -33,7 +42,7 @@ MapEntry() Defined as `= default`. -### 3.2. Destructor +### 4.2. Destructor ```c++ MapEntry() @@ -41,9 +50,9 @@ MapEntry() Defined as `= default`. -## 4. Private Member Functions +## 5. Private Member Functions -### 4.1. operator= +### 5.1. operator= ```c++ MapEntry& operator=(const MapEntry&) @@ -51,9 +60,9 @@ MapEntry& operator=(const MapEntry&) Defined as `= default`. -## 5. Public Member Functions +## 6. Public Member Functions -### 5.1. getKey +### 6.1. getKey ```c++ const K& getKey() const @@ -61,7 +70,7 @@ const K& getKey() const Get a reference to the key. -### 5.2. getValue +### 6.2. getValue ```c++ const V& getValue() const @@ -69,7 +78,7 @@ const V& getValue() const Get a reference to the value. -### 5.3. getNextEntry +### 6.3. getNextEntry ```c++ Fw::Success getNextEntry(MapEntry& entry) From fbd422deb3990ae067b7a1dce126972ca2d1ea3e Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 15:54:46 -0700 Subject: [PATCH 167/458] Revise SDD for MapEntry --- Fw/DataStructures/docs/MapEntry.md | 61 +++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 14 deletions(-) diff --git a/Fw/DataStructures/docs/MapEntry.md b/Fw/DataStructures/docs/MapEntry.md index f4fda88d968..b8ab5153ac9 100644 --- a/Fw/DataStructures/docs/MapEntry.md +++ b/Fw/DataStructures/docs/MapEntry.md @@ -21,6 +21,7 @@ It represents an entry in a map. |----|----|-------|-------------| |`m_key`|`K`|The key|C++ default initialization| |`m_value`|`V`|The value|C++ default initialization| +|`m_nextEntry|`MapEntry`|The next map entry|`nullptr`| ## 3. Private Constructors @@ -32,7 +33,7 @@ MapEntry(const MapEntry& map) Defined as `= default`. -## 4. Protected Constructors and Destructors +## 4. Public Constructors and Destructors ### 4.1. Zero-Argument Constructor @@ -42,7 +43,19 @@ MapEntry() Defined as `= default`. -### 4.2. Destructor +### 4.2. Constructor Providing Members + +```c++ +MapEntry(const K& key, const V& value, MapEntry* nextEntry = nullptr) +``` + +1. Set `m_key = key`. + +2. Set `m_value = value`. + +3. Set `m_nextEntry = nextEntry`. + +### 4.3. Destructor ```c++ MapEntry() @@ -50,7 +63,7 @@ MapEntry() Defined as `= default`. -## 5. Private Member Functions +## 5. Public Member Functions ### 5.1. operator= @@ -60,30 +73,50 @@ MapEntry& operator=(const MapEntry&) Defined as `= default`. -## 6. Public Member Functions - -### 6.1. getKey +### 5.2. getKey ```c++ const K& getKey() const ``` -Get a reference to the key. +Return a reference to the `m_key`. -### 6.2. getValue +### 5.3. getValue ```c++ const V& getValue() const ``` -Get a reference to the value. +Return a reference to `m_value`. + +### 5.4. getNextEntry + +```c++ +MapEntry* getNextEntry() +``` + +Return `m_nextEntry`. -### 6.3. getNextEntry +### 5.5. setKey ```c++ -Fw::Success getNextEntry(MapEntry& entry) +void setKey(const K& key) const +``` + +Set `m_key = key`. + +### 5.6. setValue + +```c++ +setValue(const V& value) const +``` + +Set `m_value = value`. + +### 5.7. setNextEntry + +```c+ +setNextEntry(MapEntry* nextEntry) ``` -If the map has a next entry _E_, then set `entry` -to _E_ and return `SUCCESS`. -Otherwise return `FAILURE`. +Set `m_nextEntry = nextEntry`. From 5aa71bd04dba8d96d25d096391370b545df48d27 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 15:55:25 -0700 Subject: [PATCH 168/458] Revise SDD for MapEntry --- Fw/DataStructures/docs/MapEntry.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/MapEntry.md b/Fw/DataStructures/docs/MapEntry.md index b8ab5153ac9..fcd5f001ccc 100644 --- a/Fw/DataStructures/docs/MapEntry.md +++ b/Fw/DataStructures/docs/MapEntry.md @@ -21,7 +21,7 @@ It represents an entry in a map. |----|----|-------|-------------| |`m_key`|`K`|The key|C++ default initialization| |`m_value`|`V`|The value|C++ default initialization| -|`m_nextEntry|`MapEntry`|The next map entry|`nullptr`| +|`m_nextEntry`|`MapEntry`|The next map entry|`nullptr`| ## 3. Private Constructors From cec058c9ce016a2a32abc4083a93f38084db2aa2 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 15:55:47 -0700 Subject: [PATCH 169/458] Revise SDD for MapEntry --- Fw/DataStructures/docs/MapEntry.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/MapEntry.md b/Fw/DataStructures/docs/MapEntry.md index fcd5f001ccc..5bd2c968bea 100644 --- a/Fw/DataStructures/docs/MapEntry.md +++ b/Fw/DataStructures/docs/MapEntry.md @@ -115,7 +115,7 @@ Set `m_value = value`. ### 5.7. setNextEntry -```c+ +```c++ setNextEntry(MapEntry* nextEntry) ``` From 747a76682bd94dc23fcb252ad3dad70a4ec603cb Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 15:56:37 -0700 Subject: [PATCH 170/458] Revise SDD for MapEntry --- Fw/DataStructures/docs/MapEntry.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/docs/MapEntry.md b/Fw/DataStructures/docs/MapEntry.md index 5bd2c968bea..a81c9be1956 100644 --- a/Fw/DataStructures/docs/MapEntry.md +++ b/Fw/DataStructures/docs/MapEntry.md @@ -108,7 +108,7 @@ Set `m_key = key`. ### 5.6. setValue ```c++ -setValue(const V& value) const +void setValue(const V& value) const ``` Set `m_value = value`. @@ -116,7 +116,7 @@ Set `m_value = value`. ### 5.7. setNextEntry ```c++ -setNextEntry(MapEntry* nextEntry) +void setNextEntry(MapEntry* nextEntry) ``` Set `m_nextEntry = nextEntry`. From 1b7cfc5cf4f9b832e3b511b05bbddad06d701363 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 15:57:35 -0700 Subject: [PATCH 171/458] Revise SDD for MapEntry --- Fw/DataStructures/docs/MapEntry.md | 42 ++++++++++++++---------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/Fw/DataStructures/docs/MapEntry.md b/Fw/DataStructures/docs/MapEntry.md index a81c9be1956..8c3155fb518 100644 --- a/Fw/DataStructures/docs/MapEntry.md +++ b/Fw/DataStructures/docs/MapEntry.md @@ -23,19 +23,9 @@ It represents an entry in a map. |`m_value`|`V`|The value|C++ default initialization| |`m_nextEntry`|`MapEntry`|The next map entry|`nullptr`| -## 3. Private Constructors +## 3. Public Constructors and Destructors -### 3.1. Copy Constructor - -```c++ -MapEntry(const MapEntry& map) -``` - -Defined as `= default`. - -## 4. Public Constructors and Destructors - -### 4.1. Zero-Argument Constructor +### 3.1. Zero-Argument Constructor ```c++ MapEntry() @@ -43,7 +33,7 @@ MapEntry() Defined as `= default`. -### 4.2. Constructor Providing Members +### 3.2. Constructor Providing Members ```c++ MapEntry(const K& key, const V& value, MapEntry* nextEntry = nullptr) @@ -55,7 +45,15 @@ MapEntry(const K& key, const V& value, MapEntry* nextEntry = nullptr) 3. Set `m_nextEntry = nextEntry`. -### 4.3. Destructor +### 3.3. Copy Constructor + +```c++ +MapEntry(const MapEntry& map) +``` + +Defined as `= default`. + +### 3.4. Destructor ```c++ MapEntry() @@ -63,9 +61,9 @@ MapEntry() Defined as `= default`. -## 5. Public Member Functions +## 4. Public Member Functions -### 5.1. operator= +### 4.1. operator= ```c++ MapEntry& operator=(const MapEntry&) @@ -73,7 +71,7 @@ MapEntry& operator=(const MapEntry&) Defined as `= default`. -### 5.2. getKey +### 4.2. getKey ```c++ const K& getKey() const @@ -81,7 +79,7 @@ const K& getKey() const Return a reference to the `m_key`. -### 5.3. getValue +### 4.3. getValue ```c++ const V& getValue() const @@ -89,7 +87,7 @@ const V& getValue() const Return a reference to `m_value`. -### 5.4. getNextEntry +### 4.4. getNextEntry ```c++ MapEntry* getNextEntry() @@ -97,7 +95,7 @@ MapEntry* getNextEntry() Return `m_nextEntry`. -### 5.5. setKey +### 4.5. setKey ```c++ void setKey(const K& key) const @@ -105,7 +103,7 @@ void setKey(const K& key) const Set `m_key = key`. -### 5.6. setValue +### 4.6. setValue ```c++ void setValue(const V& value) const @@ -113,7 +111,7 @@ void setValue(const V& value) const Set `m_value = value`. -### 5.7. setNextEntry +### 4.7. setNextEntry ```c++ void setNextEntry(MapEntry* nextEntry) From 5466d8dcfd808924b80fcbc207419c9cd6524104 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 15:58:06 -0700 Subject: [PATCH 172/458] Revise SDD for MapEntry --- Fw/DataStructures/docs/MapEntry.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/MapEntry.md b/Fw/DataStructures/docs/MapEntry.md index 8c3155fb518..8f19ce030a8 100644 --- a/Fw/DataStructures/docs/MapEntry.md +++ b/Fw/DataStructures/docs/MapEntry.md @@ -56,7 +56,7 @@ Defined as `= default`. ### 3.4. Destructor ```c++ -MapEntry() +~MapEntry() ``` Defined as `= default`. From c6059eede7cbd649bb26403a5dd3d1331ab7a6bd Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 16:22:32 -0700 Subject: [PATCH 173/458] Revise SDD for map --- Fw/DataStructures/docs/FifoQueueBase.md | 2 +- Fw/DataStructures/docs/MapBase.md | 65 +++++++++++++++++++------ 2 files changed, 51 insertions(+), 16 deletions(-) diff --git a/Fw/DataStructures/docs/FifoQueueBase.md b/Fw/DataStructures/docs/FifoQueueBase.md index fdc9a264f6f..b68c6d413f9 100644 --- a/Fw/DataStructures/docs/FifoQueueBase.md +++ b/Fw/DataStructures/docs/FifoQueueBase.md @@ -35,7 +35,7 @@ Defined as `= default`. ### 3.2. Destructor ```c++ -virtual FifoQueueBase() +virtual ~FifoQueueBase() ``` Defined as `= default`. diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index 937fbd4f3dd..932850827bb 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -36,7 +36,7 @@ Defined as `= default`. ### 3.2. Destructor ```c++ -virtual MapBase() +virtual ~MapBase() ``` Defined as `= default`. @@ -81,38 +81,73 @@ void copyDataFrom(const MapBase& map) 1. Let `size` be the minimum of `map.getSize()` and `getCapacity()`. - 1. If `getHeedEntry(e)` returns SUCCESS + 1. Set `e = getHeadEntry`. - 1. For `i` in [0, `size`) + 1. For `i` in [0, `size`) - 1. Set `e = at(i)`. + 1. Assert `e != nullptr`. - 1. Set `status = enqueue(e)`. + 1. Set `status = insert(*e)`. - 1. Assert `status == Success::SUCCESS`. + 1. Assert `status == Success::SUCCESS`. -TODO + 1. Set `e = e.getNextEntry()` + +_Example:_ +```c++ +void f(MapBase& m1, MapBase& m2) { + m1.clear(); + // Insert an entry + const U16 key = 0 + const U32 value = 42; + const auto status = m1.enqueue(key, value); + ASSERT_EQ(status, Fw::Success::SUCCESS); + m2.clear(); + ASSERT_EQ(m2.getSize(), 0); + m2.copyDataFrom(q1); + ASSERT_EQ(m2.getSize(), 1); +} +``` -### 5.3. delete +### 5.3. find TODO -### 5.4. find +### 5.4. getHeadEntry -TODO +```c++ +MapEntry& getHeadEntry() +const MapEntry& getHeadEntry const +``` -### 5.5. getHeadEntry +Get the head entry of the map. -TODO +### 5.5. getCapacity -### 5.6. getCapacity +```c++ +virtual FwSizeType getCapacity() const = 0 +``` + +Return the current capacity. + +_Example:_ +```c++ +void f(const MapBase& map) { + const auto size = map.getSize(); + const auto capacity = map.getCapacity(); + ASSERT_LE(size, capacity); +} +``` + +### 5.6. getSize TODO -### 5.7. getSize +### 5.7. insert TODO -### 5.8. insert +### 5.8. remove TODO + From 7816ec45517cca9f497e08090675d2deef810c65 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 16:29:43 -0700 Subject: [PATCH 174/458] Revise SDD for MapBase --- Fw/DataStructures/docs/MapBase.md | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index 932850827bb..f7783ed14eb 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -116,12 +116,15 @@ TODO ### 5.4. getHeadEntry ```c++ -MapEntry& getHeadEntry() -const MapEntry& getHeadEntry const +MapEntry* getHeadEntry() = 0 +const MapEntry* getHeadEntry const = 0 ``` Get the head entry of the map. +_Example:_ +See **copyDataFrom**. + ### 5.5. getCapacity ```c++ @@ -141,7 +144,24 @@ void f(const MapBase& map) { ### 5.6. getSize -TODO +```c++ +virtual FwSizeType getSize() const = 0 +``` + +Return the current size. + +_Example:_ +```c++ +void f(const MapBase& map) { + map.clear(); + auto size = map.getSize(); + ASSERT_EQ(size, 0); + const auto status = map.insert(0, 1); + ASSERT_EQ(status, Success::SUCCESS); + size = map.getSize(); + ASSERT_EQ(size, 1); +} +``` ### 5.7. insert From a4a32bbdc71cae089e8ab5a1285a3ae2c932db8d Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 16:33:11 -0700 Subject: [PATCH 175/458] Revise SDD for MapBase --- Fw/DataStructures/docs/MapBase.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index f7783ed14eb..5b446a894cc 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -123,7 +123,7 @@ const MapEntry* getHeadEntry const = 0 Get the head entry of the map. _Example:_ -See **copyDataFrom**. +See [**copyDataFrom**](MapEntry.md#52-copydatafrom). ### 5.5. getCapacity From 057fa44cf1f6e85a51e7ad15ad4e1751218e742a Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 16:33:50 -0700 Subject: [PATCH 176/458] Revise SDD for MapBase --- Fw/DataStructures/docs/MapBase.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index 5b446a894cc..97003db3c6c 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -123,7 +123,7 @@ const MapEntry* getHeadEntry const = 0 Get the head entry of the map. _Example:_ -See [**copyDataFrom**](MapEntry.md#52-copydatafrom). +See [**copyDataFrom**](MapBase.md#52-copydatafrom). ### 5.5. getCapacity From 761e1d781de1903983ffd1be501cf59f63b1081b Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 16:36:21 -0700 Subject: [PATCH 177/458] Revise SDD for MapBase --- Fw/DataStructures/docs/MapBase.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index 97003db3c6c..25899497226 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -123,6 +123,17 @@ const MapEntry* getHeadEntry const = 0 Get the head entry of the map. _Example:_ +```c++ +void f(const MapBase& map) { + map.clear(); + map.insert(0, 1); + const auto* e = map.getHeadEntry(); + FW_ASSERT(e != nullptr); + ASSERT_EQ(e.getKey(), 0); + ASSERT_EQ(e.getValue(), 1); +} + +``` See [**copyDataFrom**](MapBase.md#52-copydatafrom). ### 5.5. getCapacity From ce4afe6daba23780b06d24124b031e80760dd1b1 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 16:37:16 -0700 Subject: [PATCH 178/458] Revise SDD for MapBase --- Fw/DataStructures/docs/MapBase.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index 25899497226..09e0ba76925 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -126,8 +126,10 @@ _Example:_ ```c++ void f(const MapBase& map) { map.clear(); + auto* e = map.getHeadEntry(); + FW_ASSERT(e == nullptr); map.insert(0, 1); - const auto* e = map.getHeadEntry(); + e = map.getHeadEntry(); FW_ASSERT(e != nullptr); ASSERT_EQ(e.getKey(), 0); ASSERT_EQ(e.getValue(), 1); From 7d211f620cea7fdfde82d2a084cdcd9e467c8e64 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 16:57:55 -0700 Subject: [PATCH 179/458] Revise SDD for MapBase --- Fw/DataStructures/docs/MapBase.md | 56 ++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 8 deletions(-) diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index 09e0ba76925..6962d0b8e97 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -81,13 +81,13 @@ void copyDataFrom(const MapBase& map) 1. Let `size` be the minimum of `map.getSize()` and `getCapacity()`. - 1. Set `e = getHeadEntry`. + 1. Set `e = map.getHeadEntry`. 1. For `i` in [0, `size`) 1. Assert `e != nullptr`. - 1. Set `status = insert(*e)`. + 1. Set `e1 = insert(*e)`. 1. Assert `status == Success::SUCCESS`. @@ -126,7 +126,7 @@ _Example:_ ```c++ void f(const MapBase& map) { map.clear(); - auto* e = map.getHeadEntry(); + const auto* e = map.getHeadEntry(); FW_ASSERT(e == nullptr); map.insert(0, 1); e = map.getHeadEntry(); @@ -136,7 +136,6 @@ void f(const MapBase& map) { } ``` -See [**copyDataFrom**](MapBase.md#52-copydatafrom). ### 5.5. getCapacity @@ -163,6 +162,24 @@ virtual FwSizeType getSize() const = 0 Return the current size. +_Example:_ +See [**getCapacity**](MapBase.md#55-getCapacity). + +### 5.7. insert + +```c++ +Fw::Success insert(const K& key, const V& value) = 0 +Fw::Success insert(const MapEntry& e) = 0 +``` + +1. If an entry `e` exists with the specified key, then update the + value in `e` and return `SUCCESS`. + +1. Otherwise if there is room in the map, then add a new entry `e` with the +specified key-value pair and return `SUCCESS`. + +1. Otherwise return `FAILURE`. + _Example:_ ```c++ void f(const MapBase& map) { @@ -176,11 +193,34 @@ void f(const MapBase& map) { } ``` -### 5.7. insert +### 5.8. remove -TODO +```c++ +Fw::Success remove(const K& key) = 0 +``` -### 5.8. remove +1. If an entry `e` exists, then remove `e` and return `SUCCESS`. -TODO +1. Otherwise return `FAILURE`. + +_Example:_ +```c++ +void f(const MapBase& map) { + map.clear(); + auto size = map.getSize(); + ASSERT_EQ(size, 0); + auto status = map.insert(0, 1); + ASSERT_EQ(status, Success::SUCCESS); + size = map.getSize(); + ASSERT_EQ(size, 1); + // Key does not exist + status = map.remove(10); + ASSERT_EQ(status, Success::FAILURE); + ASSERT_EQ(size, 1); + // Key exists + status = map.remove(0); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(size, 0); +} +``` From b1081978410c858edab28aa558d1b20edb582649 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 16:59:06 -0700 Subject: [PATCH 180/458] Revise SDD for MapBase --- Fw/DataStructures/docs/MapBase.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index 6962d0b8e97..ca26ab7d94a 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -182,7 +182,7 @@ specified key-value pair and return `SUCCESS`. _Example:_ ```c++ -void f(const MapBase& map) { +void f(MapBase& map) { map.clear(); auto size = map.getSize(); ASSERT_EQ(size, 0); @@ -199,13 +199,14 @@ void f(const MapBase& map) { Fw::Success remove(const K& key) = 0 ``` -1. If an entry `e` exists, then remove `e` and return `SUCCESS`. +1. If an entry `e` exists with key `key`, then +remove `e` from the map and return `SUCCESS`. 1. Otherwise return `FAILURE`. _Example:_ ```c++ -void f(const MapBase& map) { +void f(MapBase& map) { map.clear(); auto size = map.getSize(); ASSERT_EQ(size, 0); From acfef73620775188e6022f3f06149bda872ad2d3 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 17:42:17 -0700 Subject: [PATCH 181/458] Revise SDD for MapBase --- Fw/DataStructures/docs/MapBase.md | 46 +++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index ca26ab7d94a..581abad44e9 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -111,12 +111,33 @@ void f(MapBase& m1, MapBase& m2) { ### 5.3. find -TODO +```c++ +Fw::Success find(const K& key, V& value) = 0 +``` + +1. If an entry `e` with value `key` exists in the map, +then store the value of `e` into `value` and return `SUCCESS`. + +1. Otherwise return `FAILURE`. + +_Example:_ +```c++ +void f(const MapBase& map) { + map.clear(); + U32 value = 0; + auto status = map.find(0, value); + ASSERT_EQ(status, Fw::Success::FAILURE); + status = map.insert(0, 1); + ASSERT_EQ(status, Fw::Success::SUCCESS); + status = map.find(0, value); + ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(value, 1); +} +``` ### 5.4. getHeadEntry ```c++ -MapEntry* getHeadEntry() = 0 const MapEntry* getHeadEntry const = 0 ``` @@ -125,14 +146,14 @@ Get the head entry of the map. _Example:_ ```c++ void f(const MapBase& map) { - map.clear(); - const auto* e = map.getHeadEntry(); - FW_ASSERT(e == nullptr); - map.insert(0, 1); - e = map.getHeadEntry(); - FW_ASSERT(e != nullptr); - ASSERT_EQ(e.getKey(), 0); - ASSERT_EQ(e.getValue(), 1); + map.clear(); + const auto* e = map.getHeadEntry(); + FW_ASSERT(e == nullptr); + map.insert(0, 1); + e = map.getHeadEntry(); + FW_ASSERT(e != nullptr); + ASSERT_EQ(e.getKey(), 0); + ASSERT_EQ(e.getValue(), 1); } ``` @@ -196,11 +217,12 @@ void f(MapBase& map) { ### 5.8. remove ```c++ -Fw::Success remove(const K& key) = 0 +Fw::Success remove(const K& key, V& value) = 0 ``` 1. If an entry `e` exists with key `key`, then -remove `e` from the map and return `SUCCESS`. +store the value of `e` into `value, +remove `e` from the map, and return `SUCCESS`. 1. Otherwise return `FAILURE`. From 04a71c8c4ec34e4308da471aa72270be8197b3e3 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 17:45:44 -0700 Subject: [PATCH 182/458] Revise SDD for MapBase --- Fw/DataStructures/docs/MapBase.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index 581abad44e9..c611f9a7da9 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -81,7 +81,7 @@ void copyDataFrom(const MapBase& map) 1. Let `size` be the minimum of `map.getSize()` and `getCapacity()`. - 1. Set `e = map.getHeadEntry`. + 1. Set `e = map.getHeadEntry()`. 1. For `i` in [0, `size`) @@ -221,7 +221,7 @@ Fw::Success remove(const K& key, V& value) = 0 ``` 1. If an entry `e` exists with key `key`, then -store the value of `e` into `value, +store the value of `e` into `value`, remove `e` from the map, and return `SUCCESS`. 1. Otherwise return `FAILURE`. @@ -237,13 +237,15 @@ void f(MapBase& map) { size = map.getSize(); ASSERT_EQ(size, 1); // Key does not exist - status = map.remove(10); + U32 value = 0; + status = map.remove(10, value); ASSERT_EQ(status, Success::FAILURE); ASSERT_EQ(size, 1); // Key exists - status = map.remove(0); + status = map.remove(0, value); ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(size, 0); + ASSERT_EQ(value, 1); } ``` From 7e422ad1e2d39aea3198d3b98e5306c196b2b15a Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 17:48:47 -0700 Subject: [PATCH 183/458] Revise SDD for ExternalFifoQueue --- Fw/DataStructures/docs/ExternalFifoQueue.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index 05987fbbf17..087509f12b1 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -1,3 +1,4 @@ +# ExternalFifoQueue `ExternalFifoQueue` is a `final` class template defined in [`Fw/DataStructures`](sdd.md). From 8d7ff086c30a9ec072c4ac9f80384b432e9b200b Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 20:02:43 -0700 Subject: [PATCH 184/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/ExternalArray.hpp | 12 + Fw/DataStructures/docs/ExternalArray.md | 12 + Fw/DataStructures/docs/ExternalArrayMap.md | 344 +++++++++++++++++- Fw/DataStructures/docs/MapBase.md | 13 +- .../test/ut/ExternalArrayTest.cpp | 12 +- 5 files changed, 386 insertions(+), 7 deletions(-) diff --git a/Fw/DataStructures/ExternalArray.hpp b/Fw/DataStructures/ExternalArray.hpp index a6f52d585e9..9bdefba7ea1 100644 --- a/Fw/DataStructures/ExternalArray.hpp +++ b/Fw/DataStructures/ExternalArray.hpp @@ -120,6 +120,18 @@ class ExternalArray final { this->m_size = size; } + public: + // ---------------------------------------------------------------------- + // Public static functions + // ---------------------------------------------------------------------- + + //! Get the size of the storage for an array of the specified size, + //! as a byte array + static constexpr FwSizeType getByteArraySize(FwSizeType size //!< The size + ) { + return size * sizeof(T); + } + private: // ---------------------------------------------------------------------- // Private member variables diff --git a/Fw/DataStructures/docs/ExternalArray.md b/Fw/DataStructures/docs/ExternalArray.md index 48d55ec6422..b81f6a7f520 100644 --- a/Fw/DataStructures/docs/ExternalArray.md +++ b/Fw/DataStructures/docs/ExternalArray.md @@ -60,6 +60,8 @@ ExternalArray(ByteArray data, FwSizeType size) ``` Call `setStorage(data, size)`. +`data` must be correctly aligned for `T` and must +contain at least `getByteArraySize(size)` bytes. _Example:_ ```c++ @@ -249,3 +251,13 @@ alignas(U32) U8 bytes[size * sizeof(U32)]; ExternalArray a; a.setStorage(ByteArray(&bytes[0], sizeof bytes), size); ``` + +## 5. Public Static Functions + +### 5.1. getByteArraySize + +```c++ +static constexpr FwSizeType getByteArraySize(FwSizeType size) +``` + +Return the size of a byte array for an array of the specified size. diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index 9c346d4713d..83e9d4e9337 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -1,4 +1,346 @@ # ExternalArrayMap -TODO +`ExternalArrayMap` is a `final` class template +defined in [`Fw/DataStructures`](sdd.md). +It represents an array-based map with external storage. +Internally it maintains an [`ExternalArray`](ExternalArray.md) for +storing the entries in the map. + +## 1. Template Parameters + +`ExternalArrayMap` has the following template parameters. + +|Kind|Name|Purpose| +|----|----|-------| +|`typename`|`K`|The type of a key in the map| +|`typename`|`V`|The type of a value in the map| + +## 2. Base Class + +`ExternalArrayMap` is publicly derived from +[`MapBase`](MapBase.md). + +## 3. Private Member Variables + +`ExternalArrayMap` has the following private member variables. + +|Name|Type|Purpose|Default Value| +|----|----|-------|-------------| +|`m_entries`|[`ExternalArray`](ExternalArray.md)|The array for storing the map entries|C++ default initialization| +|`m_size`|`FwSizeType`|The number of entries in the map|0| + +## 4. Public Constructors and Destructors + +### 4.1. Zero-Argument Constructor + +```c++ +ExternalArrayMap() +``` + +Initialize each member variable with its default value. + +_Example:_ +```c++ +ExternalArrayMap queue; +``` + +### 4.2. Constructor Providing Typed Backing Storage + +```c++ +ExternalArrayMap(Entry* entries, FwSizeType capacity) +``` + +1. Call `setStorage(entries, capacity)`. + +1. Initialize the other member variables with their default values. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +MapEntry entries[capacity]; +ExternalArrayMap map(entries, capacity); +``` + +### 4.3. Constructor Providing Untyped Backing Storage + +```c++ +ExternalArrayMap(ByteArray data, FwSizeType capacity) +``` + +1. Call `setStorage(data, capacity)`. + +1. Initialize the other member variables with their default values. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +alignas(U32) U8 bytes[capacity * sizeof(MapEntry)]; +ExternalArrayMap map(ByteArray(&bytes[0], sizeof bytes), capacity); +``` + +### 4.4. Copy Constructor + +```c++ +ExternalArrayMap(const ExternalArrayMap& queue) +``` + +Set `*this = queue`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 3; +U32 entries[capacity]; +// Call the constructor providing backing storage +ExternalArrayMap q1(entries, capacity); +// Enqueue an item +U32 value = 42; +(void) q1.enqueue(value); +// Call the copy constructor +ExternalArrayMap q2(q1); +ASSERT_EQ(q2.getSize(), 1); +``` + +### 4.5. Destructor + +```c++ +~ExternalArrayMap() override +``` + +Defined as `= default`. + +## 5. Public Member Functions + +### 5.1. operator= + +```c++ +ExternalArrayMap& operator=(const ExternalArrayMap& queue) +``` + +1. If `&queue != this` + + 1. Set `m_entries = queue.m_entries`. + + 1. Set `m_enqueueIndex = queue.m_enqueueIndex`. + + 1. Set `m_dequeueIndex = queue.m_dequeueIndex`. + + 1. Set `m_size = queue.m_size`. + +1. Return `*this`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 3; +U32 entries[capacity]; +// Call the constructor providing backing storage +ExternalArrayMap q1(entries, capacity); +// Enqueue an item +U32 value = 42; +(void) q1.enqueue(value); +// Call the default constructor +ExternalArrayMap q2; +ASSERT_EQ(q2.getSize(), 0); +// Call the copy assignment operator +q2 = q1; +ASSERT_EQ(q2.getSize(), 1); +``` + +### 5.2. clear + +```c++ +void clear() override +``` + +1. Call `m_enqueueIndex.setValue(0)`. + +1. Call `m_dequeueIndex.setValue(0)`. + +1. Set `m_size = 0`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +U32 entries[capacity] = {}; +ExternalArrayMap queue(entries, capacity); +const auto status = queue.enqueue(3); +ASSERT_EQ(queue.getSize(), 1); +queue.clear(); +ASSERT_EQ(queue.getSize(), 0); +``` + +### 5.3. setStorage (Typed Data) + +```c++ +void setStorage(T* entries, FwSizeType capacity) +``` + +1. Call `m_entries.setStorage(entries, capacity)`. + +1. If `capacity > 0` + + 1. Call `this->m_enqueueIndex.setModulus(capacity)`. + + 1. Call `this->m_dequeueIndex.setModulus(capacity)`. + +1. Call `this->clear()`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +ExternalArrayMap queue; +U32 entries[capacity]; +queue.setStorage(entries, capacity); +``` + +### 5.4. setStorage (Untyped Data) + +```c++ +void setStorage(ByteArray data, FwSizeType capacity) +``` + +1. Call `m_entries.setStorage(data, capacity)`. + +1. If `capacity > 0` + + 1. Call `this->m_enqueueIndex.setModulus(capacity)`. + + 1. Call `this->m_dequeueIndex.setModulus(capacity)`. + +1. Call `this->clear()`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +alignas(U32) U8 bytes[capacity * sizeof(U32)]; +ExternalArrayMap queue; +queue.setStorage(ByteArray(&bytes[0], sizeof bytes), capacity); +``` + +### 5.5. enqueue + +```c++ +Success enqueue(const T& e) override +``` + +1. Set `status = Success::FAILURE`. + +1. If `m_size < getCapacity()` then + + 1. Set `i = m_enqueueIndex.getValue()`. + + 1. Set `m_entries[i] = e`. + + 1. Call `m_enqueueIndex.increment()`. + + 1. Increment `m_size`. + +1. Return `status`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 3; +U32 entries[capacity]; +ExternalArrayMap queue(entries, capacity); +ASSERT_EQ(queue.getSize(), 0); +auto status = queue.enqueue(42); +ASSERT_EQ(status, Success::SUCCESS); +ASSERT_EQ(queue.getSize(), 1); +``` + +### 5.6. at + +```c++ +const T& at(FwSizeType index) const override +``` + +1. Assert `index < m_size`. + +1. Set `ci = m_dequeueIndex`. + +1. Set `i = ci.increment(index)`. + +1. Return `m_entries[i]`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 3; +U32 entries[capacity]; +ExternalArrayMap queue(entries, capacity); +const auto status = queue.enqueue(3); +ASSERT_EQ(status, Success::SUCCESS); +ASSERT_EQ(queue.at(0), 3); +ASSERT_DEATH(queue.at(1), "Assert"); +``` + +### 5.7. dequeue + +```c++ +Success dequeue(T& e) override +``` + +1. Set `status = Success::FAILURE`. + +1. If `m_size > 0` then + + 1. Set `i = m_dequeueIndex.getValue()`. + + 1. Set `e = m_entries[i]`. + + 1. Call `m_dequeueIndex.increment()`. + + 1. Decrement `m_size`. + +1. Return `status`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 3; +U32 entries[capacity]; +ExternalArrayMap queue(entries, 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); +``` + +### 5.8. getSize + +```c++ +FwSizeType getSize() const override +``` + +Return `m_size`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +U32 entries[capacity]; +ExternalArrayMap queue(entries, 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); +``` + +### 5.9. getCapacity + +```c++ +FwSizeType getCapacity() const override +``` + +Return `m_entries.getSize()`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +U32 entries[capacity]; +ExternalArrayMap queue(entries, capacity); +ASSERT_EQ(queue.getCapacity(), capacity); +``` diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index c611f9a7da9..213c9d72581 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -13,6 +13,15 @@ It represents an abstract base class for a map. |`typename`|`K`|The type of a key in the map| |`typename`|`V`|The type of a value in the map| +## Types + +`MapBase` defines the following types: + + +|Name|Definition| +|----|----------| +|`Entry`|`MapEntry| + ## 2. Private Constructors ### 2.1. Copy Constructor @@ -138,7 +147,7 @@ void f(const MapBase& map) { ### 5.4. getHeadEntry ```c++ -const MapEntry* getHeadEntry const = 0 +const Entry* getHeadEntry const = 0 ``` Get the head entry of the map. @@ -190,7 +199,7 @@ See [**getCapacity**](MapBase.md#55-getCapacity). ```c++ Fw::Success insert(const K& key, const V& value) = 0 -Fw::Success insert(const MapEntry& e) = 0 +Fw::Success insert(const Entry& e) = 0 ``` 1. If an entry `e` exists with the specified key, then update the diff --git a/Fw/DataStructures/test/ut/ExternalArrayTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayTest.cpp index 4a194022a61..bc2b0767bab 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayTest.cpp @@ -26,7 +26,8 @@ TEST(ExternalArray, StorageConstructorTyped) { TEST(ExternalArray, StorageConstructorUntyped) { constexpr FwSizeType size = 3; - alignas(U32) U8 bytes[size * sizeof(U32)]; + constexpr FwSizeType byteArraySize = ExternalArray::getByteArraySize(size); + alignas(U32) U8 bytes[byteArraySize]; ExternalArray a(ByteArray(&bytes[0], sizeof bytes), size); ASSERT_EQ(a.getElements(), reinterpret_cast(&bytes[0])); ASSERT_EQ(a.getSize(), size); @@ -112,7 +113,8 @@ TEST(ExternalArray, SetStorageTyped) { TEST(ExternalArray, SetStorageUnypedOK) { constexpr FwSizeType size = 10; - alignas(U32) U8 bytes[size * sizeof(U32)]; + constexpr FwSizeType byteArraySize = ExternalArray::getByteArraySize(size); + alignas(U32) U8 bytes[byteArraySize]; ExternalArray a; a.setStorage(ByteArray(&bytes[0], sizeof bytes), size); ASSERT_EQ(a.getElements(), reinterpret_cast(bytes)); @@ -121,14 +123,16 @@ TEST(ExternalArray, SetStorageUnypedOK) { TEST(ExternalArray, SetStorageUnypedBadSize) { constexpr FwSizeType size = 10; - alignas(U32) U8 bytes[size * sizeof(U32)]; + constexpr FwSizeType byteArraySize = ExternalArray::getByteArraySize(size); + alignas(U32) U8 bytes[byteArraySize]; ExternalArray a; ASSERT_DEATH(a.setStorage(ByteArray(&bytes[0], sizeof bytes), size + 1), "Assert"); } TEST(ExternalArray, SetStorageUnypedBadAlignment) { constexpr FwSizeType size = 10; - alignas(U32) U8 bytes[size * sizeof(U32)]; + constexpr FwSizeType byteArraySize = ExternalArray::getByteArraySize(size); + alignas(U32) U8 bytes[byteArraySize]; ExternalArray a; ASSERT_DEATH(a.setStorage(ByteArray(&bytes[1], sizeof bytes), size), "Assert"); } From f82cb02bf7defb5a94b166a1120ca3063bb9f09c Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 20:04:31 -0700 Subject: [PATCH 185/458] Revise SDD for ExternalArray --- Fw/DataStructures/docs/ExternalArray.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/ExternalArray.md b/Fw/DataStructures/docs/ExternalArray.md index b81f6a7f520..a4e9d13e798 100644 --- a/Fw/DataStructures/docs/ExternalArray.md +++ b/Fw/DataStructures/docs/ExternalArray.md @@ -260,4 +260,4 @@ a.setStorage(ByteArray(&bytes[0], sizeof bytes), size); static constexpr FwSizeType getByteArraySize(FwSizeType size) ``` -Return the size of a byte array for an array of the specified size. +Return `size * sizeof(T)`. From a6aa1856c9b68be072c42b6f65020a97cfc3371d Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 20:12:55 -0700 Subject: [PATCH 186/458] Revise Fw/DataStructures --- Fw/DataStructures/ExternalArray.hpp | 7 +++++-- Fw/DataStructures/ExternalFifoQueue.hpp | 13 +++++++++++++ Fw/DataStructures/docs/ExternalArray.md | 3 +++ Fw/DataStructures/docs/ExternalFifoQueue.md | 16 ++++++++++++++++ .../test/ut/ExternalFifoQueueTest.cpp | 3 ++- 5 files changed, 39 insertions(+), 3 deletions(-) diff --git a/Fw/DataStructures/ExternalArray.hpp b/Fw/DataStructures/ExternalArray.hpp index 9bdefba7ea1..af27eab1e3b 100644 --- a/Fw/DataStructures/ExternalArray.hpp +++ b/Fw/DataStructures/ExternalArray.hpp @@ -31,7 +31,8 @@ class ExternalArray final { ) : m_elements(elements), m_size(size) {} - //! Constructor providing untyped backing storage + //! Constructor providing untyped backing storage. + //! Data must be aligned for T and must contain at least getByteArraySize(size) bytes. ExternalArray(ByteArray data, //!< The data FwSizeType size //!< The array size ) { @@ -106,6 +107,7 @@ class ExternalArray final { } //! Set the backing storage (untyped data) + //! Data must be aligned for T and must contain at least getByteArraySize(size) bytes. void setStorage(ByteArray data, //!< The data FwSizeType size //!< The array size ) { @@ -125,8 +127,9 @@ class ExternalArray final { // Public static functions // ---------------------------------------------------------------------- - //! Get the size of the storage for an array of the specified size, + //! Get the size of the storage for an ExternalArray of the specified size, //! as a byte array + //! \return The byte array size static constexpr FwSizeType getByteArraySize(FwSizeType size //!< The size ) { return size * sizeof(T); diff --git a/Fw/DataStructures/ExternalFifoQueue.hpp b/Fw/DataStructures/ExternalFifoQueue.hpp index 0d7bedaff97..1d9eb842e9b 100644 --- a/Fw/DataStructures/ExternalFifoQueue.hpp +++ b/Fw/DataStructures/ExternalFifoQueue.hpp @@ -150,6 +150,19 @@ class ExternalFifoQueue final : public FifoQueueBase { //! \return The capacity FwSizeType getCapacity() const override { return this->m_items.getSize(); } + public: + // ---------------------------------------------------------------------- + // Public static functions + // ---------------------------------------------------------------------- + + //! Get the size of the storage for an ExternalFifoQueue of the specified + //! capacity, as a byte array + //! \return The byte array size + static constexpr FwSizeType getByteArraySize(FwSizeType capacity //!< The capacity + ) { + return ExternalArray::getByteArraySize(capacity); + } + private: // ---------------------------------------------------------------------- // Private member variables diff --git a/Fw/DataStructures/docs/ExternalArray.md b/Fw/DataStructures/docs/ExternalArray.md index a4e9d13e798..a8d03950305 100644 --- a/Fw/DataStructures/docs/ExternalArray.md +++ b/Fw/DataStructures/docs/ExternalArray.md @@ -234,6 +234,9 @@ a.setStorage(elements, size); void setStorage(ByteArray data, FwSizeType size) ``` +`data` must be correctly aligned for `T` and must +contain at least `getByteArraySize(size)` bytes. + 1. Assert that `data.bytes != nullptr`. 1. Assert that `data.bytes` is correctly aligned for type `T`. diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index 087509f12b1..1a25f688da1 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -75,6 +75,9 @@ ExternalFifoQueue queue(items, capacity); ExternalFifoQueue(ByteArray data, FwSizeType capacity) ``` +`data` must be correctly aligned for `T` and must +contain at least `ExternalArray::getByteArraySize(size)` bytes. + 1. Call `setStorage(data, capacity)`. 1. Initialize the other member variables with their default values. @@ -206,6 +209,9 @@ queue.setStorage(items, capacity); void setStorage(ByteArray data, FwSizeType capacity) ``` +`data` must be correctly aligned for `T` and must +contain at least `ExternalArray::getByteArraySize(size)` bytes. + 1. Call `m_items.setStorage(data, capacity)`. 1. If `capacity > 0` @@ -351,3 +357,13 @@ U32 items[capacity]; ExternalFifoQueue queue(items, capacity); ASSERT_EQ(queue.getCapacity(), capacity); ``` + +## 6. Public Static Functions + +### 6.1. getByteArraySize + +```c++ +static constexpr FwSizeType getByteArraySize(FwSizeType capacity) +``` + +Return `ExternalArray::getByteArraySize(capacity)`. diff --git a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp index 42d79470c8f..56fe26654eb 100644 --- a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp @@ -44,7 +44,8 @@ TEST(ExternalFifoQueue, TypedStorageConstructor) { TEST(ExternalFifoQueue, UntypedStorageConstructor) { constexpr FwSizeType capacity = 10; - alignas(U32) U8 bytes[capacity * sizeof(U32)]; + constexpr FwSizeType byteArraySize = ExternalFifoQueue::getByteArraySize(capacity); + alignas(U32) U8 bytes[byteArraySize]; ExternalFifoQueue queue(ByteArray(&bytes[0], sizeof bytes), capacity); ExternalFifoQueueTester tester(queue); ASSERT_EQ(tester.getItems().getElements(), reinterpret_cast(bytes)); From 4d8a3ea36cd4445660e6b9b7009b0cca5146792b Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 20:17:37 -0700 Subject: [PATCH 187/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalArray.md | 8 ++++++++ Fw/DataStructures/docs/ExternalArrayMap.md | 17 +++++++++++++++++ Fw/DataStructures/docs/ExternalFifoQueue.md | 8 ++++++++ 3 files changed, 33 insertions(+) diff --git a/Fw/DataStructures/docs/ExternalArray.md b/Fw/DataStructures/docs/ExternalArray.md index a8d03950305..68ce1016c54 100644 --- a/Fw/DataStructures/docs/ExternalArray.md +++ b/Fw/DataStructures/docs/ExternalArray.md @@ -264,3 +264,11 @@ static constexpr FwSizeType getByteArraySize(FwSizeType size) ``` Return `size * sizeof(T)`. + +_Example:_ +``` +c++ +const FwSizeType size = 10; +const FwSizeType byteArraySize = ExternalArrayMap::getByteArraySize(size); +ASSERT_EQ(byteArraySize, 10 * sizeof(U32)); +``` diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index 83e9d4e9337..f01740480b0 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -344,3 +344,20 @@ ExternalArrayMap queue(entries, capacity); ASSERT_EQ(queue.getCapacity(), capacity); ``` +## 6. Public Static Functions + +### 6.1. getByteArraySize + +```c++ +static constexpr FwSizeType getByteArraySize(FwSizeType capacity) +``` + +Return `ExternalArray::getByteArraySize(capacity)`. + +_Example:_ +``` +c++ +const FwSizeType size = 10; +const FwSizeType byteArraySize = ExternalFifoQueue::getByteArraySize(size); +ASSERT_EQ(byteArraySize, 10 * sizeof(U32)); +``` diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index 1a25f688da1..5da46e0f262 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -367,3 +367,11 @@ static constexpr FwSizeType getByteArraySize(FwSizeType capacity) ``` Return `ExternalArray::getByteArraySize(capacity)`. + +_Example:_ +``` +c++ +const FwSizeType size = 10; +const FwSizeType byteArraySize = ExternalFifoQueue::getByteArraySize(size); +ASSERT_EQ(byteArraySize, 10 * sizeof(U32)); +``` From ff2fbca7f0dfd01b9b7697da11160b01e390a2c1 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 20:18:07 -0700 Subject: [PATCH 188/458] Revise SDD for ExternalArrayMap --- Fw/DataStructures/docs/ExternalArrayMap.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index f01740480b0..90725e10920 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -355,8 +355,7 @@ static constexpr FwSizeType getByteArraySize(FwSizeType capacity) Return `ExternalArray::getByteArraySize(capacity)`. _Example:_ -``` -c++ +```c++ const FwSizeType size = 10; const FwSizeType byteArraySize = ExternalFifoQueue::getByteArraySize(size); ASSERT_EQ(byteArraySize, 10 * sizeof(U32)); From 5d7d9839a15472939fc333cd9c21c46ad0e57dce Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 20:27:15 -0700 Subject: [PATCH 189/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalArrayMap.md | 18 ++++++++--- Fw/DataStructures/docs/ExternalFifoQueue.md | 10 +++--- Fw/DataStructures/docs/MapBase.md | 34 ++++++++++----------- 3 files changed, 37 insertions(+), 25 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index 90725e10920..b1a65e7b178 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -29,6 +29,8 @@ storing the entries in the map. |`m_entries`|[`ExternalArray`](ExternalArray.md)|The array for storing the map entries|C++ default initialization| |`m_size`|`FwSizeType`|The number of entries in the map|0| +The type `Entry` is defined [in the base class](MapBase.md#2-types). + ## 4. Public Constructors and Destructors ### 4.1. Zero-Argument Constructor @@ -67,6 +69,9 @@ ExternalArrayMap map(entries, capacity); ExternalArrayMap(ByteArray data, FwSizeType capacity) ``` +`data` must be correctly aligned for `Entry` and must +contain at least `ExternalArrayMap::getByteArraySize(capacity)` bytes. + 1. Call `setStorage(data, capacity)`. 1. Initialize the other member variables with their default values. @@ -74,7 +79,8 @@ ExternalArrayMap(ByteArray data, FwSizeType capacity) _Example:_ ```c++ constexpr FwSizeType capacity = 10; -alignas(U32) U8 bytes[capacity * sizeof(MapEntry)]; +constexpr FwSizeType byteArraySize = ExternalArrayMap::getByteArraySize(); +alignas(MapEntry) U8 bytes[byteArraySize]; ExternalArrayMap map(ByteArray(&bytes[0], sizeof bytes), capacity); ``` @@ -198,6 +204,9 @@ queue.setStorage(entries, capacity); void setStorage(ByteArray data, FwSizeType capacity) ``` +`data` must be correctly aligned for `Entry` and must +contain at least `ExternalArrayMap::getByteArraySize(capacity)` bytes. + 1. Call `m_entries.setStorage(data, capacity)`. 1. If `capacity > 0` @@ -211,9 +220,10 @@ void setStorage(ByteArray data, FwSizeType capacity) _Example:_ ```c++ constexpr FwSizeType capacity = 10; -alignas(U32) U8 bytes[capacity * sizeof(U32)]; -ExternalArrayMap queue; -queue.setStorage(ByteArray(&bytes[0], sizeof bytes), capacity); +constexpr FwSizeType byteArraySize = ExternalArrayMap::getByteArraySize(); +alignas(MapEntry) U8 bytes[byteArraySize]; +ExternalArrayMap map; +map.setStorage(ByteArray(&bytes[0], sizeof bytes), capacity); ``` ### 5.5. enqueue diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index 5da46e0f262..0903a32d868 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -76,7 +76,7 @@ ExternalFifoQueue(ByteArray data, FwSizeType capacity) ``` `data` must be correctly aligned for `T` and must -contain at least `ExternalArray::getByteArraySize(size)` bytes. +contain at least `ExternalFifoQueue::getByteArraySize(capacity)` bytes. 1. Call `setStorage(data, capacity)`. @@ -85,7 +85,8 @@ contain at least `ExternalArray::getByteArraySize(size)` bytes. _Example:_ ```c++ constexpr FwSizeType capacity = 10; -alignas(U32) U8 bytes[capacity * sizeof(U32)]; +constexpr FwSizeType byteArraySize = ExternalFifoQueue::getByteArraySize(); +alignas(U32) U8 bytes[byteArraySize]; ExternalFifoQueue queue(ByteArray(&bytes[0], sizeof bytes), capacity); ``` @@ -210,7 +211,7 @@ void setStorage(ByteArray data, FwSizeType capacity) ``` `data` must be correctly aligned for `T` and must -contain at least `ExternalArray::getByteArraySize(size)` bytes. +contain at least `ExternalFifoQueue::getByteArraySize(capacity)` bytes. 1. Call `m_items.setStorage(data, capacity)`. @@ -225,7 +226,8 @@ contain at least `ExternalArray::getByteArraySize(size)` bytes. _Example:_ ```c++ constexpr FwSizeType capacity = 10; -alignas(U32) U8 bytes[capacity * sizeof(U32)]; +constexpr FwSizeType byteArraySize = ExternalFifoQueue::getByteArraySize(); +alignas(U32) U8 bytes[byteArraySize]; ExternalFifoQueue queue; queue.setStorage(ByteArray(&bytes[0], sizeof bytes), capacity); ``` diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index 213c9d72581..c4163032bf8 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -13,7 +13,7 @@ It represents an abstract base class for a map. |`typename`|`K`|The type of a key in the map| |`typename`|`V`|The type of a value in the map| -## Types +## 2. Types `MapBase` defines the following types: @@ -22,9 +22,9 @@ It represents an abstract base class for a map. |----|----------| |`Entry`|`MapEntry| -## 2. Private Constructors +## 3. Private Constructors -### 2.1. Copy Constructor +### 3.1. Copy Constructor ```c++ MapBase(const MapBase& map) @@ -32,9 +32,9 @@ MapBase(const MapBase& map) Defined as `= delete`. -## 3. Protected Constructors and Destructors +## 4. Protected Constructors and Destructors -### 3.1. Zero-Argument Constructor +### 4.1. Zero-Argument Constructor ```c++ MapBase() @@ -42,7 +42,7 @@ MapBase() Defined as `= default`. -### 3.2. Destructor +### 4.2. Destructor ```c++ virtual ~MapBase() @@ -50,9 +50,9 @@ virtual ~MapBase() Defined as `= default`. -## 4. Private Member Functions +## 5. Private Member Functions -### 4.1. operator= +### 5.1. operator= ```c++ MapBase& operator=(const MapBase&) @@ -60,9 +60,9 @@ MapBase& operator=(const MapBase&) Defined as `= delete`. -## 5. Public Member Functions +## 6. Public Member Functions -### 5.1. clear +### 6.1. clear ```c++ virtual void clear() = 0 @@ -78,7 +78,7 @@ void f(MapBase& map) { } ``` -### 5.2. copyDataFrom +### 6.2. copyDataFrom ```c++ void copyDataFrom(const MapBase& map) @@ -118,7 +118,7 @@ void f(MapBase& m1, MapBase& m2) { } ``` -### 5.3. find +### 6.3. find ```c++ Fw::Success find(const K& key, V& value) = 0 @@ -144,7 +144,7 @@ void f(const MapBase& map) { } ``` -### 5.4. getHeadEntry +### 6.4. getHeadEntry ```c++ const Entry* getHeadEntry const = 0 @@ -167,7 +167,7 @@ void f(const MapBase& map) { ``` -### 5.5. getCapacity +### 6.5. getCapacity ```c++ virtual FwSizeType getCapacity() const = 0 @@ -184,7 +184,7 @@ void f(const MapBase& map) { } ``` -### 5.6. getSize +### 6.6. getSize ```c++ virtual FwSizeType getSize() const = 0 @@ -195,7 +195,7 @@ Return the current size. _Example:_ See [**getCapacity**](MapBase.md#55-getCapacity). -### 5.7. insert +### 6.7. insert ```c++ Fw::Success insert(const K& key, const V& value) = 0 @@ -223,7 +223,7 @@ void f(MapBase& map) { } ``` -### 5.8. remove +### 6.8. remove ```c++ Fw::Success remove(const K& key, V& value) = 0 From f684a0dd3dffa9f8c760e099d3d2c0a3fd6ef031 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 20:28:21 -0700 Subject: [PATCH 190/458] Revise SDD for MapBase --- Fw/DataStructures/docs/MapBase.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index c4163032bf8..964b821d20e 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -20,7 +20,7 @@ It represents an abstract base class for a map. |Name|Definition| |----|----------| -|`Entry`|`MapEntry| +|`Entry`|`MapEntry`| ## 3. Private Constructors From 4381e0c0ca4e4f8f906bea5462a350deadb201d7 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 20:29:55 -0700 Subject: [PATCH 191/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalArrayMap.md | 110 ++++++++++---------- Fw/DataStructures/docs/ExternalFifoQueue.md | 4 +- 2 files changed, 57 insertions(+), 57 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index b1a65e7b178..cc797f7c647 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -43,7 +43,7 @@ Initialize each member variable with its default value. _Example:_ ```c++ -ExternalArrayMap queue; +ExternalArrayMap map; ``` ### 4.2. Constructor Providing Typed Backing Storage @@ -79,7 +79,7 @@ contain at least `ExternalArrayMap::getByteArraySize(capacity)` bytes. _Example:_ ```c++ constexpr FwSizeType capacity = 10; -constexpr FwSizeType byteArraySize = ExternalArrayMap::getByteArraySize(); +constexpr FwSizeType byteArraySize = ExternalArrayMap::getByteArraySize(capacity); alignas(MapEntry) U8 bytes[byteArraySize]; ExternalArrayMap map(ByteArray(&bytes[0], sizeof bytes), capacity); ``` @@ -87,10 +87,10 @@ ExternalArrayMap map(ByteArray(&bytes[0], sizeof bytes), capacity); ### 4.4. Copy Constructor ```c++ -ExternalArrayMap(const ExternalArrayMap& queue) +ExternalArrayMap(const ExternalArrayMap& map) ``` -Set `*this = queue`. +Set `*this = map`. _Example:_ ```c++ @@ -98,9 +98,9 @@ constexpr FwSizeType capacity = 3; U32 entries[capacity]; // Call the constructor providing backing storage ExternalArrayMap q1(entries, capacity); -// Enqueue an item +// Enmap an item U32 value = 42; -(void) q1.enqueue(value); +(void) q1.enmap(value); // Call the copy constructor ExternalArrayMap q2(q1); ASSERT_EQ(q2.getSize(), 1); @@ -119,18 +119,18 @@ Defined as `= default`. ### 5.1. operator= ```c++ -ExternalArrayMap& operator=(const ExternalArrayMap& queue) +ExternalArrayMap& operator=(const ExternalArrayMap& map) ``` -1. If `&queue != this` +1. If `&map != this` - 1. Set `m_entries = queue.m_entries`. + 1. Set `m_entries = map.m_entries`. - 1. Set `m_enqueueIndex = queue.m_enqueueIndex`. + 1. Set `m_enmapIndex = queue.m_enqueueIndex`. - 1. Set `m_dequeueIndex = queue.m_dequeueIndex`. + 1. Set `m_demapIndex = queue.m_dequeueIndex`. - 1. Set `m_size = queue.m_size`. + 1. Set `m_size = map.m_size`. 1. Return `*this`. @@ -140,9 +140,9 @@ constexpr FwSizeType capacity = 3; U32 entries[capacity]; // Call the constructor providing backing storage ExternalArrayMap q1(entries, capacity); -// Enqueue an item +// Enmap an item U32 value = 42; -(void) q1.enqueue(value); +(void) q1.enmap(value); // Call the default constructor ExternalArrayMap q2; ASSERT_EQ(q2.getSize(), 0); @@ -157,9 +157,9 @@ ASSERT_EQ(q2.getSize(), 1); void clear() override ``` -1. Call `m_enqueueIndex.setValue(0)`. +1. Call `m_enmapIndex.setValue(0)`. -1. Call `m_dequeueIndex.setValue(0)`. +1. Call `m_demapIndex.setValue(0)`. 1. Set `m_size = 0`. @@ -167,11 +167,11 @@ _Example:_ ```c++ constexpr FwSizeType capacity = 10; U32 entries[capacity] = {}; -ExternalArrayMap queue(entries, capacity); -const auto status = queue.enqueue(3); -ASSERT_EQ(queue.getSize(), 1); -queue.clear(); -ASSERT_EQ(queue.getSize(), 0); +ExternalArrayMap map(entries, capacity); +const auto status = map.enqueue(3); +ASSERT_EQ(map.getSize(), 1); +map.clear(); +ASSERT_EQ(map.getSize(), 0); ``` ### 5.3. setStorage (Typed Data) @@ -184,18 +184,18 @@ void setStorage(T* entries, FwSizeType capacity) 1. If `capacity > 0` - 1. Call `this->m_enqueueIndex.setModulus(capacity)`. + 1. Call `this->m_enmapIndex.setModulus(capacity)`. - 1. Call `this->m_dequeueIndex.setModulus(capacity)`. + 1. Call `this->m_demapIndex.setModulus(capacity)`. 1. Call `this->clear()`. _Example:_ ```c++ constexpr FwSizeType capacity = 10; -ExternalArrayMap queue; +ExternalArrayMap map; U32 entries[capacity]; -queue.setStorage(entries, capacity); +map.setStorage(entries, capacity); ``` ### 5.4. setStorage (Untyped Data) @@ -211,36 +211,36 @@ contain at least `ExternalArrayMap::getByteArraySize(capacity)` bytes. 1. If `capacity > 0` - 1. Call `this->m_enqueueIndex.setModulus(capacity)`. + 1. Call `this->m_enmapIndex.setModulus(capacity)`. - 1. Call `this->m_dequeueIndex.setModulus(capacity)`. + 1. Call `this->m_demapIndex.setModulus(capacity)`. 1. Call `this->clear()`. _Example:_ ```c++ constexpr FwSizeType capacity = 10; -constexpr FwSizeType byteArraySize = ExternalArrayMap::getByteArraySize(); +constexpr FwSizeType byteArraySize = ExternalArrayMap::getByteArraySize(capacity); alignas(MapEntry) U8 bytes[byteArraySize]; ExternalArrayMap map; map.setStorage(ByteArray(&bytes[0], sizeof bytes), capacity); ``` -### 5.5. enqueue +### 5.5. enmap ```c++ -Success enqueue(const T& e) override +Success enmap(const T& e) override ``` 1. Set `status = Success::FAILURE`. 1. If `m_size < getCapacity()` then - 1. Set `i = m_enqueueIndex.getValue()`. + 1. Set `i = m_enmapIndex.getValue()`. 1. Set `m_entries[i] = e`. - 1. Call `m_enqueueIndex.increment()`. + 1. Call `m_enmapIndex.increment()`. 1. Increment `m_size`. @@ -250,11 +250,11 @@ _Example:_ ```c++ constexpr FwSizeType capacity = 3; U32 entries[capacity]; -ExternalArrayMap queue(entries, capacity); -ASSERT_EQ(queue.getSize(), 0); -auto status = queue.enqueue(42); +ExternalArrayMap map(entries, capacity); +ASSERT_EQ(map.getSize(), 0); +auto status = map.enqueue(42); ASSERT_EQ(status, Success::SUCCESS); -ASSERT_EQ(queue.getSize(), 1); +ASSERT_EQ(map.getSize(), 1); ``` ### 5.6. at @@ -265,7 +265,7 @@ const T& at(FwSizeType index) const override 1. Assert `index < m_size`. -1. Set `ci = m_dequeueIndex`. +1. Set `ci = m_demapIndex`. 1. Set `i = ci.increment(index)`. @@ -275,28 +275,28 @@ _Example:_ ```c++ constexpr FwSizeType capacity = 3; U32 entries[capacity]; -ExternalArrayMap queue(entries, capacity); -const auto status = queue.enqueue(3); +ExternalArrayMap map(entries, capacity); +const auto status = map.enqueue(3); ASSERT_EQ(status, Success::SUCCESS); -ASSERT_EQ(queue.at(0), 3); -ASSERT_DEATH(queue.at(1), "Assert"); +ASSERT_EQ(map.at(0), 3); +ASSERT_DEATH(map.at(1), "Assert"); ``` -### 5.7. dequeue +### 5.7. demap ```c++ -Success dequeue(T& e) override +Success demap(T& e) override ``` 1. Set `status = Success::FAILURE`. 1. If `m_size > 0` then - 1. Set `i = m_dequeueIndex.getValue()`. + 1. Set `i = m_demapIndex.getValue()`. 1. Set `e = m_entries[i]`. - 1. Call `m_dequeueIndex.increment()`. + 1. Call `m_demapIndex.increment()`. 1. Decrement `m_size`. @@ -306,13 +306,13 @@ _Example:_ ```c++ constexpr FwSizeType capacity = 3; U32 entries[capacity]; -ExternalArrayMap queue(entries, capacity); +ExternalArrayMap map(entries, capacity); U32 val; -auto status = queue.dequeue(val); +auto status = map.dequeue(val); ASSERT_EQ(status, Success::FAILURE); -status = queue.enqueue(42); +status = map.enqueue(42); ASSERT_EQ(status, Success::SUCCESS); -status = queue.dequeue(val); +status = map.dequeue(val); ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(val, 42); ``` @@ -329,12 +329,12 @@ _Example:_ ```c++ constexpr FwSizeType capacity = 10; U32 entries[capacity]; -ExternalArrayMap queue(entries, capacity); -auto size = queue.getSize(); +ExternalArrayMap map(entries, capacity); +auto size = map.getSize(); ASSERT_EQ(size, 0); -const auto status = queue.enqueue(3); +const auto status = map.enqueue(3); ASSERT_EQ(status, Success::SUCCESS); -size = queue.getSize(); +size = map.getSize(); ASSERT_EQ(size, 1); ``` @@ -350,8 +350,8 @@ _Example:_ ```c++ constexpr FwSizeType capacity = 10; U32 entries[capacity]; -ExternalArrayMap queue(entries, capacity); -ASSERT_EQ(queue.getCapacity(), capacity); +ExternalArrayMap map(entries, capacity); +ASSERT_EQ(map.getCapacity(), capacity); ``` ## 6. Public Static Functions diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index 0903a32d868..3d7ff99a6bb 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -85,7 +85,7 @@ contain at least `ExternalFifoQueue::getByteArraySize(capacity)` bytes. _Example:_ ```c++ constexpr FwSizeType capacity = 10; -constexpr FwSizeType byteArraySize = ExternalFifoQueue::getByteArraySize(); +constexpr FwSizeType byteArraySize = ExternalFifoQueue::getByteArraySize(capacity); alignas(U32) U8 bytes[byteArraySize]; ExternalFifoQueue queue(ByteArray(&bytes[0], sizeof bytes), capacity); ``` @@ -226,7 +226,7 @@ contain at least `ExternalFifoQueue::getByteArraySize(capacity)` bytes. _Example:_ ```c++ constexpr FwSizeType capacity = 10; -constexpr FwSizeType byteArraySize = ExternalFifoQueue::getByteArraySize(); +constexpr FwSizeType byteArraySize = ExternalFifoQueue::getByteArraySize(capacity); alignas(U32) U8 bytes[byteArraySize]; ExternalFifoQueue queue; queue.setStorage(ByteArray(&bytes[0], sizeof bytes), capacity); From f06f459a1b8781dc74e803bbd5f8934ad62c9994 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 20:44:35 -0700 Subject: [PATCH 192/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalArrayMap.md | 216 +++++++-------------- Fw/DataStructures/docs/MapBase.md | 36 ++-- 2 files changed, 87 insertions(+), 165 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index cc797f7c647..01946a854a1 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -97,13 +97,15 @@ _Example:_ constexpr FwSizeType capacity = 3; U32 entries[capacity]; // Call the constructor providing backing storage -ExternalArrayMap q1(entries, capacity); -// Enmap an item -U32 value = 42; -(void) q1.enmap(value); +ExternalArrayMap m1(entries, capacity); +// Insert an item +const U16 key = 0; +const U32 value = 42; +const auto status = m1.insert(key, value); +ASSERT_EQ(status, Fw::Success::SUCCESS); // Call the copy constructor -ExternalArrayMap q2(q1); -ASSERT_EQ(q2.getSize(), 1); +ExternalArrayMap m2(m1); +ASSERT_EQ(m2.getSize(), 1); ``` ### 4.5. Destructor @@ -126,10 +128,6 @@ ExternalArrayMap& operator=(const ExternalArrayMap& map) 1. Set `m_entries = map.m_entries`. - 1. Set `m_enmapIndex = queue.m_enqueueIndex`. - - 1. Set `m_demapIndex = queue.m_dequeueIndex`. - 1. Set `m_size = map.m_size`. 1. Return `*this`. @@ -137,18 +135,20 @@ ExternalArrayMap& operator=(const ExternalArrayMap& map) _Example:_ ```c++ constexpr FwSizeType capacity = 3; -U32 entries[capacity]; +MapEntry entries[capacity]; // Call the constructor providing backing storage -ExternalArrayMap q1(entries, capacity); -// Enmap an item +ExternalArrayMap m1(entries, capacity); +// Insert an item +U16 key = 0; U32 value = 42; -(void) q1.enmap(value); +const auto status = m1.insert(value); +ASSERT_EQ(status, Fw::Success::SUCCESS); // Call the default constructor -ExternalArrayMap q2; -ASSERT_EQ(q2.getSize(), 0); +ExternalArrayMap m2; +ASSERT_EQ(m2.getSize(), 0); // Call the copy assignment operator -q2 = q1; -ASSERT_EQ(q2.getSize(), 1); +m2 = m1; +ASSERT_EQ(m2.getSize(), 1); ``` ### 5.2. clear @@ -157,201 +157,123 @@ ASSERT_EQ(q2.getSize(), 1); void clear() override ``` -1. Call `m_enmapIndex.setValue(0)`. - -1. Call `m_demapIndex.setValue(0)`. - 1. Set `m_size = 0`. _Example:_ ```c++ constexpr FwSizeType capacity = 10; -U32 entries[capacity] = {}; -ExternalArrayMap map(entries, capacity); +MapEntry entries[capacity]; +ExternalArrayMap map(entries, capacity); const auto status = map.enqueue(3); ASSERT_EQ(map.getSize(), 1); map.clear(); ASSERT_EQ(map.getSize(), 0); ``` -### 5.3. setStorage (Typed Data) +### 5.3. find ```c++ -void setStorage(T* entries, FwSizeType capacity) +Fw::Success find(const K& key, V& value) override ``` -1. Call `m_entries.setStorage(entries, capacity)`. - -1. If `capacity > 0` +TODO - 1. Call `this->m_enmapIndex.setModulus(capacity)`. - - 1. Call `this->m_demapIndex.setModulus(capacity)`. - -1. Call `this->clear()`. - -_Example:_ -```c++ -constexpr FwSizeType capacity = 10; -ExternalArrayMap map; -U32 entries[capacity]; -map.setStorage(entries, capacity); -``` - -### 5.4. setStorage (Untyped Data) +### 5.4. getCapacity ```c++ -void setStorage(ByteArray data, FwSizeType capacity) +FwSizeType getCapacity() const override ``` -`data` must be correctly aligned for `Entry` and must -contain at least `ExternalArrayMap::getByteArraySize(capacity)` bytes. - -1. Call `m_entries.setStorage(data, capacity)`. - -1. If `capacity > 0` - - 1. Call `this->m_enmapIndex.setModulus(capacity)`. - - 1. Call `this->m_demapIndex.setModulus(capacity)`. - -1. Call `this->clear()`. +Return `m_entries.getSize()`. _Example:_ ```c++ constexpr FwSizeType capacity = 10; -constexpr FwSizeType byteArraySize = ExternalArrayMap::getByteArraySize(capacity); -alignas(MapEntry) U8 bytes[byteArraySize]; -ExternalArrayMap map; -map.setStorage(ByteArray(&bytes[0], sizeof bytes), capacity); -``` - -### 5.5. enmap - -```c++ -Success enmap(const T& e) override +U32 entries[capacity]; +ExternalArrayMap map(entries, capacity); +ASSERT_EQ(map.getCapacity(), capacity); ``` -1. Set `status = Success::FAILURE`. - -1. If `m_size < getCapacity()` then - - 1. Set `i = m_enmapIndex.getValue()`. - - 1. Set `m_entries[i] = e`. - - 1. Call `m_enmapIndex.increment()`. +### 5.5. getHeadEntry - 1. Increment `m_size`. - -1. Return `status`. - -_Example:_ -```c++ -constexpr FwSizeType capacity = 3; -U32 entries[capacity]; -ExternalArrayMap map(entries, capacity); -ASSERT_EQ(map.getSize(), 0); -auto status = map.enqueue(42); -ASSERT_EQ(status, Success::SUCCESS); -ASSERT_EQ(map.getSize(), 1); -``` +TODO -### 5.6. at +### 5.6. getSize ```c++ -const T& at(FwSizeType index) const override +FwSizeType getSize() const override ``` -1. Assert `index < m_size`. - -1. Set `ci = m_demapIndex`. - -1. Set `i = ci.increment(index)`. - -1. Return `m_entries[i]`. +Return `m_size`. _Example:_ ```c++ -constexpr FwSizeType capacity = 3; +constexpr FwSizeType capacity = 10; U32 entries[capacity]; -ExternalArrayMap map(entries, capacity); +ExternalArrayMap map(entries, capacity); +auto size = map.getSize(); +ASSERT_EQ(size, 0); const auto status = map.enqueue(3); ASSERT_EQ(status, Success::SUCCESS); -ASSERT_EQ(map.at(0), 3); -ASSERT_DEATH(map.at(1), "Assert"); +size = map.getSize(); +ASSERT_EQ(size, 1); ``` -### 5.7. demap +### 5.7. insert ```c++ -Success demap(T& e) override +Fw::Success insert(const K& key, const V& value) override +Fw::Success insert(const Entry& e) override ``` -1. Set `status = Success::FAILURE`. +TODO -1. If `m_size > 0` then +### 5.8. remove - 1. Set `i = m_demapIndex.getValue()`. - - 1. Set `e = m_entries[i]`. - - 1. Call `m_demapIndex.increment()`. - - 1. Decrement `m_size`. - -1. Return `status`. - -_Example:_ ```c++ -constexpr FwSizeType capacity = 3; -U32 entries[capacity]; -ExternalArrayMap map(entries, capacity); -U32 val; -auto status = map.dequeue(val); -ASSERT_EQ(status, Success::FAILURE); -status = map.enqueue(42); -ASSERT_EQ(status, Success::SUCCESS); -status = map.dequeue(val); -ASSERT_EQ(status, Success::SUCCESS); -ASSERT_EQ(val, 42); +Fw::Success remove(const K& key, V& value) override ``` -### 5.8. getSize +TODO + +### 5.9. setStorage (Typed Data) ```c++ -FwSizeType getSize() const override +void setStorage(T* entries, FwSizeType capacity) ``` -Return `m_size`. +1. Call `m_entries.setStorage(entries, capacity)`. + +1. Call `this->clear()`. _Example:_ ```c++ constexpr FwSizeType capacity = 10; -U32 entries[capacity]; -ExternalArrayMap map(entries, capacity); -auto size = map.getSize(); -ASSERT_EQ(size, 0); -const auto status = map.enqueue(3); -ASSERT_EQ(status, Success::SUCCESS); -size = map.getSize(); -ASSERT_EQ(size, 1); +ExternalArrayMap map; +MapEntry entries[capacity]; +map.setStorage(entries, capacity); ``` -### 5.9. getCapacity +### 5.10. setStorage (Untyped Data) ```c++ -FwSizeType getCapacity() const override +void setStorage(ByteArray data, FwSizeType capacity) ``` -Return `m_entries.getSize()`. +`data` must be correctly aligned for `Entry` and must +contain at least `ExternalArrayMap::getByteArraySize(capacity)` bytes. + +1. Call `m_entries.setStorage(data, capacity)`. + +1. Call `this->clear()`. _Example:_ ```c++ constexpr FwSizeType capacity = 10; -U32 entries[capacity]; -ExternalArrayMap map(entries, capacity); -ASSERT_EQ(map.getCapacity(), capacity); +constexpr FwSizeType byteArraySize = ExternalArrayMap::getByteArraySize(capacity); +alignas(MapEntry) U8 bytes[byteArraySize]; +ExternalArrayMap map; +map.setStorage(ByteArray(&bytes[0], sizeof bytes), capacity); ``` ## 6. Public Static Functions @@ -367,6 +289,6 @@ Return `ExternalArray::getByteArraySize(capacity)`. _Example:_ ```c++ const FwSizeType size = 10; -const FwSizeType byteArraySize = ExternalFifoQueue::getByteArraySize(size); +const FwSizeType byteArraySize = ExternalFifoQueue::getByteArraySize(size); ASSERT_EQ(byteArraySize, 10 * sizeof(U32)); ``` diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index 964b821d20e..c3f3f256bec 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -144,44 +144,44 @@ void f(const MapBase& map) { } ``` -### 6.4. getHeadEntry +### 6.4. getCapacity ```c++ -const Entry* getHeadEntry const = 0 +virtual FwSizeType getCapacity() const = 0 ``` -Get the head entry of the map. +Return the current capacity. _Example:_ ```c++ void f(const MapBase& map) { - map.clear(); - const auto* e = map.getHeadEntry(); - FW_ASSERT(e == nullptr); - map.insert(0, 1); - e = map.getHeadEntry(); - FW_ASSERT(e != nullptr); - ASSERT_EQ(e.getKey(), 0); - ASSERT_EQ(e.getValue(), 1); + const auto size = map.getSize(); + const auto capacity = map.getCapacity(); + ASSERT_LE(size, capacity); } - ``` -### 6.5. getCapacity +### 6.5. getHeadEntry ```c++ -virtual FwSizeType getCapacity() const = 0 +const Entry* getHeadEntry const = 0 ``` -Return the current capacity. +Get the head entry of the map. _Example:_ ```c++ void f(const MapBase& map) { - const auto size = map.getSize(); - const auto capacity = map.getCapacity(); - ASSERT_LE(size, capacity); + map.clear(); + const auto* e = map.getHeadEntry(); + FW_ASSERT(e == nullptr); + map.insert(0, 1); + e = map.getHeadEntry(); + FW_ASSERT(e != nullptr); + ASSERT_EQ(e.getKey(), 0); + ASSERT_EQ(e.getValue(), 1); } + ``` ### 6.6. getSize From 908e7d621f00854e004aaf044b702ba71ad0206e Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 20:53:31 -0700 Subject: [PATCH 193/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalArrayMap.md | 67 +++++++++++++++++++--- Fw/DataStructures/docs/MapBase.md | 16 +++--- 2 files changed, 66 insertions(+), 17 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index 01946a854a1..80959274f30 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -102,7 +102,7 @@ ExternalArrayMap m1(entries, capacity); const U16 key = 0; const U32 value = 42; const auto status = m1.insert(key, value); -ASSERT_EQ(status, Fw::Success::SUCCESS); +ASSERT_EQ(status, Success::SUCCESS); // Call the copy constructor ExternalArrayMap m2(m1); ASSERT_EQ(m2.getSize(), 1); @@ -142,7 +142,7 @@ ExternalArrayMap m1(entries, capacity); U16 key = 0; U32 value = 42; const auto status = m1.insert(value); -ASSERT_EQ(status, Fw::Success::SUCCESS); +ASSERT_EQ(status, Success::SUCCESS); // Call the default constructor ExternalArrayMap m2; ASSERT_EQ(m2.getSize(), 0); @@ -157,7 +157,7 @@ ASSERT_EQ(m2.getSize(), 1); void clear() override ``` -1. Set `m_size = 0`. +Set `m_size = 0`. _Example:_ ```c++ @@ -173,10 +173,41 @@ ASSERT_EQ(map.getSize(), 0); ### 5.3. find ```c++ -Fw::Success find(const K& key, V& value) override +Success find(const K& key, V& value) override ``` -TODO +1. Set `status = Success::FAILURE`. + +1. Let `size = getSize()`. + +1. For `i` in `[0, size)` + + 1. Let `const auto& e = &m_entries[i]`. + + 1. If `e.getKey() == key` + + 1. Set `value = e.getValue()`. + + 1. Set `status = Success::SUCCESS`. + + 1. Break out of the loop. + +1. Return `status`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +U32 entries[capacity]; +ExternalArrayMap map(entries, capacity); +U32 value = 0; +auto status = map.find(0, value); +ASSERT_EQ(status, Success::FAILURE); +status = map.insert(0, 1); +ASSERT_EQ(status, Success::SUCCESS); +status = map.find(0, value); +ASSERT_EQ(status, Success::SUCCESS); +ASSERT_EQ(value, 1); +``` ### 5.4. getCapacity @@ -196,7 +227,25 @@ ASSERT_EQ(map.getCapacity(), capacity); ### 5.5. getHeadEntry -TODO +```c++ +const Entry* getHeadEntry const override +``` + +Get the head entry of the map. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +U32 entries[capacity]; +ExternalArrayMap map(entries, capacity); +const auto* e = map.getHeadEntry(); +FW_ASSERT(e == nullptr); +map.insert(0, 1); +e = map.getHeadEntry(); +FW_ASSERT(e != nullptr); +ASSERT_EQ(e.getKey(), 0); +ASSERT_EQ(e.getValue(), 1); +``` ### 5.6. getSize @@ -222,8 +271,8 @@ ASSERT_EQ(size, 1); ### 5.7. insert ```c++ -Fw::Success insert(const K& key, const V& value) override -Fw::Success insert(const Entry& e) override +Success insert(const K& key, const V& value) override +Success insert(const Entry& e) override ``` TODO @@ -231,7 +280,7 @@ TODO ### 5.8. remove ```c++ -Fw::Success remove(const K& key, V& value) override +Success remove(const K& key, V& value) override ``` TODO diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index c3f3f256bec..8d1685b271c 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -110,7 +110,7 @@ void f(MapBase& m1, MapBase& m2) { const U16 key = 0 const U32 value = 42; const auto status = m1.enqueue(key, value); - ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(status, Success::SUCCESS); m2.clear(); ASSERT_EQ(m2.getSize(), 0); m2.copyDataFrom(q1); @@ -121,7 +121,7 @@ void f(MapBase& m1, MapBase& m2) { ### 6.3. find ```c++ -Fw::Success find(const K& key, V& value) = 0 +Success find(const K& key, V& value) = 0 ``` 1. If an entry `e` with value `key` exists in the map, @@ -135,11 +135,11 @@ void f(const MapBase& map) { map.clear(); U32 value = 0; auto status = map.find(0, value); - ASSERT_EQ(status, Fw::Success::FAILURE); + ASSERT_EQ(status, Success::FAILURE); status = map.insert(0, 1); - ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(status, Success::SUCCESS); status = map.find(0, value); - ASSERT_EQ(status, Fw::Success::SUCCESS); + ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(value, 1); } ``` @@ -198,8 +198,8 @@ See [**getCapacity**](MapBase.md#55-getCapacity). ### 6.7. insert ```c++ -Fw::Success insert(const K& key, const V& value) = 0 -Fw::Success insert(const Entry& e) = 0 +Success insert(const K& key, const V& value) = 0 +Success insert(const Entry& e) = 0 ``` 1. If an entry `e` exists with the specified key, then update the @@ -226,7 +226,7 @@ void f(MapBase& map) { ### 6.8. remove ```c++ -Fw::Success remove(const K& key, V& value) = 0 +Success remove(const K& key, V& value) = 0 ``` 1. If an entry `e` exists with key `key`, then From b2875d9dfa7f678c2152e5542eb97a0aa38af978 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 21:12:56 -0700 Subject: [PATCH 194/458] Revise SDD for ExternalArrayMap --- Fw/DataStructures/docs/ExternalArrayMap.md | 33 ++++++++++++++++++---- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index 80959274f30..6bb3ab91783 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -178,9 +178,7 @@ Success find(const K& key, V& value) override 1. Set `status = Success::FAILURE`. -1. Let `size = getSize()`. - -1. For `i` in `[0, size)` +1. For `i` in `[0, m_size)` 1. Let `const auto& e = &m_entries[i]`. @@ -231,7 +229,7 @@ ASSERT_EQ(map.getCapacity(), capacity); const Entry* getHeadEntry const override ``` -Get the head entry of the map. +Return `(m_size > 0) ? &m_entries[0] : nullptr`. _Example:_ ```c++ @@ -275,7 +273,32 @@ Success insert(const K& key, const V& value) override Success insert(const Entry& e) override ``` -TODO +1. Set `status = Success::FAILURE`. + +1. For `i` in `[0, m_size)` + + 1. Let `auto& e = m_entries[i]`. + + 1. If `e.getKey() == key` + + 1. Call `e.setValue(value)`. + + 1. Set `status = Success::SUCCESS`. + + 1. Break out of the loop + +1. If `(status == Success::FAILURE) && (m_size < getCapacity())` + + 1. Set `m_entries[m_size] = Entry(key, value)`. + + 1. If `m_size > 0` then + call `m_entries[m_size - 1].setNextEntry(&m_entries[m_size])`. + + 1. Increment `m_size`. + + 1. Set `status = Success::SUCCESS`. + +1. Return `status`. ### 5.8. remove From 9f0c9be8602ee8a35b00a2ca9e0dbe2862c1b7d0 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 21:36:40 -0700 Subject: [PATCH 195/458] Revise SDD for ExternalArrayMap --- Fw/DataStructures/docs/ExternalArrayMap.md | 83 +++++++++++++++++++++- 1 file changed, 80 insertions(+), 3 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index 6bb3ab91783..d78aa5c057c 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -151,6 +151,27 @@ m2 = m1; ASSERT_EQ(m2.getSize(), 1); ``` +### 5.6. at + +```c++ +const V& at(FwSizeType index) const +``` + +1. Assert `index < m_size`. + +1. Return `m_entries[index].getValue()`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 3; +MapEntry entries[capacity]; +ExternalArrayMap map(entries, capacity); +const auto status = map.insert(0, 1); +ASSERT_EQ(status, Success::SUCCESS); +ASSERT_EQ(map.at(0), 1); +ASSERT_DEATH(map.at(1), "Assert"); +``` + ### 5.2. clear ```c++ @@ -300,13 +321,69 @@ Success insert(const Entry& e) override 1. Return `status`. +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +MapEntry entries[capacity]; +ExternalArrayMap map(entries, capacity); +auto size = map.getSize(); +ASSERT_EQ(size, 0); +const auto status = map.insert(0, 1); +ASSERT_EQ(status, Success::SUCCESS); +size = map.getSize(); +ASSERT_EQ(size, 1); +``` + ### 5.8. remove ```c++ Success remove(const K& key, V& value) override ``` -TODO +1. Set `status = Success::FAILURE`. + +1. For `i` in `[0, m_size)` + + 1. If `m_entries[i].getKey() == key` + + 1. If `i < m_size - 1` then + + 1. `m_entries[i] = m_entries[m_size - 1]`. + + 1. Call `m_entries[i].setNextEntry(&m_entries[i + 1])`. + + 1. Otherwise call `m_entries[i].setNextEntry(nullptr)`. + + 1. Decrement `size`. + + 1. Set `status = Success::SUCCESS`. + + 1. Break out of the loop. + +1. Return `status`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +MapEntry entries[capacity]; +ExternalArrayMap map(entries, capacity); +auto size = map.getSize(); +ASSERT_EQ(size, 0); +auto status = map.insert(0, 1); +ASSERT_EQ(status, Success::SUCCESS); +size = map.getSize(); +ASSERT_EQ(size, 1); +// Key does not exist +U32 value = 0; +status = map.remove(10, value); +ASSERT_EQ(status, Success::FAILURE); +ASSERT_EQ(size, 1); +// Key exists +status = map.remove(0, value); +ASSERT_EQ(status, Success::SUCCESS); +ASSERT_EQ(size, 0); +ASSERT_EQ(value, 1); +``` ### 5.9. setStorage (Typed Data) @@ -316,7 +393,7 @@ void setStorage(T* entries, FwSizeType capacity) 1. Call `m_entries.setStorage(entries, capacity)`. -1. Call `this->clear()`. +1. Call `clear()`. _Example:_ ```c++ @@ -337,7 +414,7 @@ contain at least `ExternalArrayMap::getByteArraySize(capacity)` bytes. 1. Call `m_entries.setStorage(data, capacity)`. -1. Call `this->clear()`. +1. Call `clear()`. _Example:_ ```c++ From 41e9aa981b36fa8e406284173978119a0edcd3a9 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 21:37:47 -0700 Subject: [PATCH 196/458] Revise SDD for ExternalArrayMap --- Fw/DataStructures/docs/ExternalArrayMap.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index d78aa5c057c..d1c14db810d 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -87,7 +87,7 @@ ExternalArrayMap map(ByteArray(&bytes[0], sizeof bytes), capacity); ### 4.4. Copy Constructor ```c++ -ExternalArrayMap(const ExternalArrayMap& map) +ExternalArrayMap(const ExternalArrayMap& map) ``` Set `*this = map`. @@ -121,7 +121,7 @@ Defined as `= default`. ### 5.1. operator= ```c++ -ExternalArrayMap& operator=(const ExternalArrayMap& map) +ExternalArrayMap& operator=(const ExternalArrayMap& map) ``` 1. If `&map != this` @@ -433,7 +433,7 @@ map.setStorage(ByteArray(&bytes[0], sizeof bytes), capacity); static constexpr FwSizeType getByteArraySize(FwSizeType capacity) ``` -Return `ExternalArray::getByteArraySize(capacity)`. +Return `ExternalArray::getByteArraySize(capacity)`. _Example:_ ```c++ From 62edd44d385c4e35bd97d0e85e416da78de783f9 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 16 Jun 2025 21:44:51 -0700 Subject: [PATCH 197/458] Revise SDD for ExternalArrayMap --- Fw/DataStructures/docs/ExternalArrayMap.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index d1c14db810d..915750d43f6 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -291,7 +291,6 @@ ASSERT_EQ(size, 1); ```c++ Success insert(const K& key, const V& value) override -Success insert(const Entry& e) override ``` 1. Set `status = Success::FAILURE`. @@ -334,6 +333,12 @@ size = map.getSize(); ASSERT_EQ(size, 1); ``` +```c++ +Success insert(const Entry& e) override +``` + +Call `insert(e.getKey(), e.getValue())`. + ### 5.8. remove ```c++ From c5be63cf5344049d0ec76c82f013712e1babb166 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 17:58:03 -0700 Subject: [PATCH 198/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/MapBase.md | 9 +- Fw/DataStructures/docs/MapEntry.md | 120 ---------- Fw/DataStructures/docs/MapIterator.md | 76 +++++++ Fw/DataStructures/docs/SetBase.md | 245 ++++++++++++++++++++- Fw/DataStructures/docs/SetIterator.md | 70 ++++++ Fw/DataStructures/docs/SetOrMapIterator.md | 153 +++++++++++++ 6 files changed, 547 insertions(+), 126 deletions(-) delete mode 100644 Fw/DataStructures/docs/MapEntry.md create mode 100644 Fw/DataStructures/docs/MapIterator.md create mode 100644 Fw/DataStructures/docs/SetIterator.md create mode 100644 Fw/DataStructures/docs/SetOrMapIterator.md diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index 8d1685b271c..d4f88cfd1b9 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -13,10 +13,9 @@ It represents an abstract base class for a map. |`typename`|`K`|The type of a key in the map| |`typename`|`V`|The type of a value in the map| -## 2. Types - -`MapBase` defines the following types: +## 2. Public Types +`MapBase` defines the following public types: |Name|Definition| |----|----------| @@ -109,7 +108,7 @@ void f(MapBase& m1, MapBase& m2) { // Insert an entry const U16 key = 0 const U32 value = 42; - const auto status = m1.enqueue(key, value); + const auto status = m1.insert(key, value); ASSERT_EQ(status, Success::SUCCESS); m2.clear(); ASSERT_EQ(m2.getSize(), 0); @@ -125,7 +124,7 @@ Success find(const K& key, V& value) = 0 ``` 1. If an entry `e` with value `key` exists in the map, -then store the value of `e` into `value` and return `SUCCESS`. +then set `value = e.getValue()` and return `SUCCESS`. 1. Otherwise return `FAILURE`. diff --git a/Fw/DataStructures/docs/MapEntry.md b/Fw/DataStructures/docs/MapEntry.md deleted file mode 100644 index 8f19ce030a8..00000000000 --- a/Fw/DataStructures/docs/MapEntry.md +++ /dev/null @@ -1,120 +0,0 @@ -# MapEntry - -`MapEntry` is a class template -defined in [`Fw/DataStructures`](sdd.md). -It represents an entry in a map. - -## 1. Template Parameters - -`MapEntry` has the following template parameters. - -|Kind|Name|Purpose| -|----|----|-------| -|`typename`|`K`|The type of a key in the map| -|`typename`|`V`|The type of a value in the map| - -## 2. Private Member Variables - -`MapEntry` has the following private member variables. - -|Name|Type|Purpose|Default Value| -|----|----|-------|-------------| -|`m_key`|`K`|The key|C++ default initialization| -|`m_value`|`V`|The value|C++ default initialization| -|`m_nextEntry`|`MapEntry`|The next map entry|`nullptr`| - -## 3. Public Constructors and Destructors - -### 3.1. Zero-Argument Constructor - -```c++ -MapEntry() -``` - -Defined as `= default`. - -### 3.2. Constructor Providing Members - -```c++ -MapEntry(const K& key, const V& value, MapEntry* nextEntry = nullptr) -``` - -1. Set `m_key = key`. - -2. Set `m_value = value`. - -3. Set `m_nextEntry = nextEntry`. - -### 3.3. Copy Constructor - -```c++ -MapEntry(const MapEntry& map) -``` - -Defined as `= default`. - -### 3.4. Destructor - -```c++ -~MapEntry() -``` - -Defined as `= default`. - -## 4. Public Member Functions - -### 4.1. operator= - -```c++ -MapEntry& operator=(const MapEntry&) -``` - -Defined as `= default`. - -### 4.2. getKey - -```c++ -const K& getKey() const -``` - -Return a reference to the `m_key`. - -### 4.3. getValue - -```c++ -const V& getValue() const -``` - -Return a reference to `m_value`. - -### 4.4. getNextEntry - -```c++ -MapEntry* getNextEntry() -``` - -Return `m_nextEntry`. - -### 4.5. setKey - -```c++ -void setKey(const K& key) const -``` - -Set `m_key = key`. - -### 4.6. setValue - -```c++ -void setValue(const V& value) const -``` - -Set `m_value = value`. - -### 4.7. setNextEntry - -```c++ -void setNextEntry(MapEntry* nextEntry) -``` - -Set `m_nextEntry = nextEntry`. diff --git a/Fw/DataStructures/docs/MapIterator.md b/Fw/DataStructures/docs/MapIterator.md new file mode 100644 index 00000000000..51aab583530 --- /dev/null +++ b/Fw/DataStructures/docs/MapIterator.md @@ -0,0 +1,76 @@ +# MapIterator + +`MapIterator` is a class template +defined in [`Fw/DataStructures`](sdd.md). +It represents an iterator for a map. + +## 1. Template Parameters + +`MapIterator` has the following template parameters. + +|Kind|Name|Purpose| +|----|----|-------| +|`typename`|`K`|The type of a key in the map| +|`typename`|`V`|The type of a value in the map| + +## 2. Protected Constructors and Destructors + +### 2.1. Zero-Argument Constructor + +```c++ +MapIterator() +``` + +Defined as `= default`. + +### 2.2. Destructor + +```c++ +virtual ~MapIterator() +``` + +Defined as `= default`. + +## 3. Private Constructors + +### 3.1. Copy Constructor + +```c++ +MapIterator(const MapIterator& map) +``` + +Defined as `= delete`. + +## 4. Public Member Functions + +### 4.1. operator= + +```c++ +MapIterator& operator=(const MapIterator&) +``` + +Defined as `= delete`. + +### 4.2. getKey + +```c++ +virtual const K& getKey() const = 0 +``` + +Return a reference to the key. + +### 4.3. getValue + +```c++ +virtual const V& getValue() const = 0 +``` + +Return a reference to the value. + +### 4.4. getNextMapIterator + +```c++ +virtual MapIterator* getNextMapIterator() = 0 +``` + +Return a pointer to the next map iterator, or `nullptr` if there is none. diff --git a/Fw/DataStructures/docs/SetBase.md b/Fw/DataStructures/docs/SetBase.md index d6cbecb392d..a8187ab4d52 100644 --- a/Fw/DataStructures/docs/SetBase.md +++ b/Fw/DataStructures/docs/SetBase.md @@ -1,4 +1,247 @@ # SetBase -TODO +`SetBase` is a class template +defined in [`Fw/DataStructures`](sdd.md). +It represents an abstract base class for a set. + +## 1. Template Parameters + +`SetBase` has the following template parameters. + +|Kind|Name|Purpose| +|----|----|-------| +|`typename`|`T`|The type of an element in the set| + +## 2. Protected Types + +`SetBase` defines the following protected types: + +|Name|Definition| +|----|----------| +|`Nil`|`struct Nil {}`| +|`MapImpl`|`MapBase`| +|`Entry`|`SetEntry`| + +## 3. Protected Member Variables + +`SetBase` has the following protected member variables. + +|Name|Type|Purpose|Default Value| +|----|----|-------|-------------| +|`m_mapImpl`|`MapImpl&`|The implementation of the set as a map| + +## 4. Protected Constructors and Destructors + +### 4.1. Constructor Providing the Map Implementation + +```c++ +SetBase(MapImpl& mapImpl) +``` + +Set `m_mapImpl = mapImpl`. + +## 5. Private Constructors and Destructors + +### 5.1. Copy Constructor + +```c++ +SetBase(const SetBase& set) +``` + +Defined as `= delete`. + +### 5.2. Destructor + +```c++ +virtual ~SetBase() +``` + +Defined as `= default`. + +## 6. Private Member Functions + +### 6.1. operator= + +```c++ +SetBase& operator=(const SetBase&) +``` + +Defined as `= delete`. + +## 7. Public Member Functions + +### 7.1. clear + +```c++ +virtual void clear() = 0 +``` + +Call `m_mapImpl.clear()`. + +_Example:_ +```c++ +void f(SetBase& set) { + set.clear(); + ASSERT_EQ(set.getSize(), 0); +} +``` + +### 7.2. copyDataFrom + +```c++ +void copyDataFrom(const SetBase& set) +``` + +Call `m_mapImpl.copyDataFrom(set.m_mapImpl)`. + +_Example:_ +```c++ +void f(SetBase& m1, SetBase& m2) { + m1.clear(); + // Insert an entry + const auto status = m1.insert(42); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(m1.getSize(), 1); + m2.clear(); + ASSERT_EQ(m2.getSize(), 0); + m2.copyDataFrom(q1); + ASSERT_EQ(m2.getSize(), 1); +} +``` + +### 7.3. find + +```c++ +Success find(const T& element) = 0 +``` + +1. Let `Nil nil = {}`. + +1. Return `m_mapImpl.find(element, nil); + +_Example:_ +```c++ +void f(const SetBase& set) { + set.clear(); + auto status = set.find(42); + ASSERT_EQ(status, Success::FAILURE); + status = set.insert(42); + ASSERT_EQ(status, Success::SUCCESS); + status = set.find(42); + ASSERT_EQ(status, Success::SUCCESS); +} +``` + +### 7.4. getCapacity + +```c++ +virtual FwSizeType getCapacity() const = 0 +``` + +Return `m_mapImpl.getCapacity()`. + +_Example:_ +```c++ +void f(const SetBase& set) { + const auto size = set.getSize(); + const auto capacity = set.getCapacity(); + ASSERT_LE(size, capacity); +} +``` + +### 7.5. getHeadEntry + +```c++ +const Entry* getHeadEntry const = 0 +``` + +Return `m_mapImpl.getHeadEntry()`. + +_Example:_ +```c++ +void f(const SetBase& set) { + set.clear(); + const auto* e = set.getHeadEntry(); + FW_ASSERT(e == nullptr); + set.insert(42); + e = set.getHeadEntry(); + FW_ASSERT(e != nullptr); + ASSERT_EQ(e.getElement(), 42); +} + +``` + +### 7.6. getSize + +```c++ +virtual FwSizeType getSize() const = 0 +``` + +Return the current size. + +_Example:_ +See [**getCapacity**](SetBase.md#55-getCapacity). + +### 7.7. insert + +```c++ +Success insert(const K& key, const V& value) = 0 +Success insert(const Entry& e) = 0 +``` + +1. If an entry `e` exists with the specified key, then update the + value in `e` and return `SUCCESS`. + +1. Otherwise if there is room in the set, then add a new entry `e` with the +specified key-value pair and return `SUCCESS`. + +1. Otherwise return `FAILURE`. + +_Example:_ +```c++ +void f(SetBase& set) { + set.clear(); + auto size = set.getSize(); + ASSERT_EQ(size, 0); + const auto status = set.insert(0, 1); + ASSERT_EQ(status, Success::SUCCESS); + size = set.getSize(); + ASSERT_EQ(size, 1); +} +``` + +### 7.8. remove + +```c++ +Success remove(const K& key, V& value) = 0 +``` + +1. If an entry `e` exists with key `key`, then +store the value of `e` into `value`, +remove `e` from the set, and return `SUCCESS`. + +1. Otherwise return `FAILURE`. + +_Example:_ +```c++ +void f(SetBase& set) { + set.clear(); + auto size = set.getSize(); + ASSERT_EQ(size, 0); + auto status = set.insert(0, 1); + ASSERT_EQ(status, Success::SUCCESS); + size = set.getSize(); + ASSERT_EQ(size, 1); + // Key does not exist + U32 value = 0; + status = set.remove(10, value); + ASSERT_EQ(status, Success::FAILURE); + ASSERT_EQ(size, 1); + // Key exists + status = set.remove(0, value); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(size, 0); + ASSERT_EQ(value, 1); +} +``` diff --git a/Fw/DataStructures/docs/SetIterator.md b/Fw/DataStructures/docs/SetIterator.md new file mode 100644 index 00000000000..50e17eaa04c --- /dev/null +++ b/Fw/DataStructures/docs/SetIterator.md @@ -0,0 +1,70 @@ +# SetIterator + +`SetIterator` is a class template +defined in [`Fw/DataStructures`](sdd.md). +It represents an iterator for a set. + +## 1. Template Parameters + +`SetIterator` has the following template parameters. + +|Kind|Name|Purpose| +|----|----|-------| +|`typename`|`T`|The type of an element in the set| + +## 3. Protected Constructors and Destructors + +### 3.1. Zero-Argument Constructor + +```c++ +SetIterator() +``` + +Defined as `= default`. + +### 3.4. Destructor + +```c++ +virtual ~SetIterator() +``` + +Defined as `= default`. + +## Private Constructors and Destructors + +### 3.3. Copy Constructor + +```c++ +SetIterator(const SetIterator& set) +``` + +Defined as `= delete`. + +## 4. Private Member Functions + +### 4.1. operator= + +```c++ +SetIterator& operator=(const SetIterator& setIterator) +``` + +Defined as `= delete`. + +## Public Member Functions + +### 4.2. getElement + +```c++ +virtual const T& getElement() const = 0 +``` + +Return a reference to the set element stored in the iterator. + +### 4.4. getNextSetIterator + +```c++ +virtual SetIterator* getNextSetIterator() = 0 +``` + +Return a pointer to the next iterator for the set, or `nullptr` if +there is none. diff --git a/Fw/DataStructures/docs/SetOrMapIterator.md b/Fw/DataStructures/docs/SetOrMapIterator.md new file mode 100644 index 00000000000..f54abd17752 --- /dev/null +++ b/Fw/DataStructures/docs/SetOrMapIterator.md @@ -0,0 +1,153 @@ +# SetOrMapIterator + +`SetOrMapIterator` is a class template +defined in [`Fw/DataStructures`](sdd.md). +It represents an iterator for a set or a map. + +## 1. Template Parameters + +`SetOrMapIterator` has the following template parameters. + +|Kind|Name|Purpose| +|----|----|-------| +|`typename`|`KE`|The type of a key in a map or the element of a set| +|`typename`|`V`|The type of a value in a map; unused in a set| + +## 2. Base Class + +`SetOrMapIterator` is publicly derived from the following +templates: + +1. [`MapIterator`](MapIterator.md). + +1. [`SetIterator`](SetIterator.md). + +## 3. Private Member Variables + +`SetOrMapIterator` has the following private member variables. + +|Name|Type|Purpose|Default Value| +|----|----|-------|-------------| +|`m_keyOrElement`|`KE`|The map key or set element|C++ default initialization| +|`m_value`|`V`|The value|C++ default initialization| +|`m_nextIterator`|`SetOrMapIterator*`|Pointer to the next iterator or `nullptr` if none|`nullptr`| + +## 4. Public Constructors and Destructors + +### 4.1. Zero-Argument Constructor + +```c++ +SetOrMapIterator() +``` + +Defined as `= default`. + +### 4.2. Constructor Providing Members + +```c++ +SetOrMapIterator(const KE& keyOrElement, const V& value, SetOrMapIterator* nextIterator = nullptr) +``` + +1. Set `m_keyOrElement = keyOrElement`. + +2. Set `m_value = value`. + +3. Set `m_nextIterator = nextIterator`. + +### 4.3. Copy Constructor + +```c++ +SetOrMapIterator(const SetOrMapIterator& map) +``` + +Defined as `= default`. + +### 4.4. Destructor + +```c++ +~SetOrMapIterator() override +``` + +Defined as `= default`. + +## 5. Public Member Functions + +### 5.1. operator= + +```c++ +SetOrMapIterator& operator=(const SetOrMapIterator&) +``` + +Defined as `= default`. + +### 5.3. getElement + +```c++ +const KE& getElement() const +``` + +Return a reference to `m_keyOrElement`. + +### 5.2. getKey + +```c++ +const KE& getKey() const override +``` + +Return a reference to `m_keyOrElement`. + +### 5.3. getValue + +```c++ +const V& getValue() const +``` + +Return a reference to `m_value`. + +### 5.4. getNextIterator + +```c++ +SetOrMapIterator getNextIterator() +``` + +Return `m_nextIterator`. + +### 5.4. getNextMapIterator + +```c++ +MapIterator getNextMapIterator() override +``` + +Return `m_nextIterator`. + +### 5.5. getNextSetIterator + +```c++ +SetIterator* getNextSetIterator() +``` + +Return `m_nextIterator`. + +### 5.6. setKeyOrElement + +```c++ +void setKeyOrElement(const KE& keyOrElement) const +``` + +Set `m_keyOrElement = keyOrElement`. + +### 5.8. setNextIterator + +```c++ +void setNextIterator(SetOrMapIterator* nextIterator) +``` + +Set `m_nextIterator = nextIterator`. + +### 5.7. setValue + +```c++ +void setValue(const V& value) const +``` + +Set `m_value = value`. From c36c9860b45fea4f08f7e3b7e0c4a368773852cc Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 20:10:24 -0700 Subject: [PATCH 199/458] Revise Fw/DataStructures --- Fw/DataStructures/ExternalArray.hpp | 6 + Fw/DataStructures/docs/ArraySetOrMapImpl.md | 255 ++++++++++++++++++ Fw/DataStructures/docs/ExternalArray.md | 29 +- Fw/DataStructures/docs/SetOrMapIterator.md | 16 +- .../test/ut/ExternalArrayTest.cpp | 12 +- 5 files changed, 301 insertions(+), 17 deletions(-) create mode 100644 Fw/DataStructures/docs/ArraySetOrMapImpl.md diff --git a/Fw/DataStructures/ExternalArray.hpp b/Fw/DataStructures/ExternalArray.hpp index af27eab1e3b..c7ecc92766e 100644 --- a/Fw/DataStructures/ExternalArray.hpp +++ b/Fw/DataStructures/ExternalArray.hpp @@ -127,6 +127,12 @@ class ExternalArray final { // Public static functions // ---------------------------------------------------------------------- + //! Get the alignment of the storage for an ExternalArray + //! \return The alignment + static constexpr U8 getByteArrayAlignment() { + return alignof(T); + } + //! Get the size of the storage for an ExternalArray of the specified size, //! as a byte array //! \return The byte array size diff --git a/Fw/DataStructures/docs/ArraySetOrMapImpl.md b/Fw/DataStructures/docs/ArraySetOrMapImpl.md new file mode 100644 index 00000000000..f431cd8a686 --- /dev/null +++ b/Fw/DataStructures/docs/ArraySetOrMapImpl.md @@ -0,0 +1,255 @@ +# ArraySetOrMapImpl + +`ArraySetOrMapImpl` is a `final` class template +defined in [`Fw/DataStructures`](sdd.md). +It represents an array-based implementation of a set or map. +Internally it maintains an [`ExternalArray`](ExternalArray.md) for +storing the entries in the set or map. + +## 1. Template Parameters + +`ArraySetOrMapImpl` has the following template parameters. + +|Kind|Name|Purpose| +|----|----|-------| +|`typename`|`KE`|The type of a key in a map or the element of a set| +|`typename`|`V`|The type of a value in a map; unused in a set| + +## Public Types + +`ArraySetOrMapImpl` defines the following types: +```c++ +using Entry = SetOrMapIterator +``` + +The type `SetOrMapIterator` is defined [here](SetOrMapIterator.md). + +## 3. Private Member Variables + +`ArraySetOrMapImpl` has the following private member variables. + +|Name|Type|Purpose|Default Value| +|----|----|-------|-------------| +|`m_entries`|[`ExternalArray`](ExternalArray.md)|The array for storing the set or map entries|C++ default initialization| +|`m_size`|`FwSizeType`|The number of entries in the map|0| + +## 4. Public Constructors and Destructors + +### 4.1. Zero-Argument Constructor + +```c++ +ArraySetOrMapImpl() +``` + +Initialize each member variable with its default value. + +### 4.2. Constructor Providing Typed Backing Storage + +```c++ +ArraySetOrMapImpl(Entry* entries, FwSizeType capacity) +``` + +1. Call `setStorage(entries, capacity)`. + +1. Initialize the other member variables with their default values. + +### 4.3. Constructor Providing Untyped Backing Storage + +```c++ +ArraySetOrMapImpl(ByteArray data, FwSizeType capacity) +``` + +`data` must be correctly aligned for `Entry` and must +contain at least `ArraySetOrMapImpl::getByteArraySize(capacity)` bytes. + +1. Call `setStorage(data, capacity)`. + +1. Initialize the other member variables with their default values. + +### 4.4. Copy Constructor + +```c++ +ArraySetOrMapImpl(const ArraySetOrMapImpl& map) +``` + +Set `*this = map`. + +### 4.5. Destructor + +```c++ +~ArraySetOrMapImpl() +``` + +Defined as `= default`. + +## 5. Public Member Functions + +### 5.1. operator= + +```c++ +ArraySetOrMapImpl& operator=(const ArraySetOrMapImpl& map) +``` + +1. If `&map != this` + + 1. Set `m_entries = map.m_entries`. + + 1. Set `m_size = map.m_size`. + +1. Return `*this`. + +### 5.6. at + +```c++ +const Entry& at(FwSizeType index) const +``` + +1. Assert `index < m_size`. + +1. Return `m_entries[index]`. + +### 5.2. clear + +```c++ +void clear() +``` + +Set `m_size = 0`. + +### 5.3. find + +```c++ +const Entry* find(const K& key) +``` + +1. Set `result = nullptr`. + +1. For `i` in `[0, m_size)` + + 1. Let `const auto& e = &m_entries[i]`. + + 1. If `e.getKey() == key` + + 1. Set `result = e`. + + 1. Break out of the loop. + +1. Return `result`. + +### 5.4. getCapacity + +```c++ +FwSizeType getCapacity() const +``` + +Return `m_entries.getSize()`. + +### 5.5. getHeadEntry + +```c++ +const Entry* getHeadEntry const +``` + +Return `(m_size > 0) ? &m_entries[0] : nullptr`. + +### 5.6. getSize + +```c++ +FwSizeType getSize() +``` + +Return `m_size`. + +### 5.7. insert + +```c++ +Success insert(const Entry& e) +``` + +1. Set `status = Success::FAILURE`. + +1. For `i` in `[0, m_size)` + + 1. Let `auto& ei = m_entries[i]`. + + 1. If `ei.getKey() == e.key` + + 1. Call `ei.setValue(e.value)`. + + 1. Set `status = Success::SUCCESS`. + + 1. Break out of the loop + +1. If `(status == Success::FAILURE) && (m_size < getCapacity())` + + 1. Set `m_entries[m_size] = Entry(e.key, e.value)`. + + 1. If `m_size > 0` then + call `m_entries[m_size - 1].setNextEntry(&m_entries[m_size])`. + + 1. Increment `m_size`. + + 1. Set `status = Success::SUCCESS`. + +1. Return `status`. + +### 5.8. remove + +```c++ +Success remove(const K& key, V& value) +``` + +1. Set `status = Success::FAILURE`. + +1. For `i` in `[0, m_size)` + + 1. If `m_entries[i].getKey() == key` + + 1. If `i < m_size - 1` then + + 1. `m_entries[i] = m_entries[m_size - 1]`. + + 1. Call `m_entries[i].setNextEntry(&m_entries[i + 1])`. + + 1. Otherwise call `m_entries[i].setNextEntry(nullptr)`. + + 1. Decrement `size`. + + 1. Set `status = Success::SUCCESS`. + + 1. Break out of the loop. + +1. Return `status`. + +### 5.9. setStorage (Typed Data) + +```c++ +void setStorage(T* entries, FwSizeType capacity) +``` + +1. Call `m_entries.setStorage(entries, capacity)`. + +1. Call `clear()`. + +### 5.10. setStorage (Untyped Data) + +```c++ +void setStorage(ByteArray data, FwSizeType capacity) +``` + +`data` must be correctly aligned for `Entry` and must +contain at least `ArraySetOrMapImpl::getByteArraySize(capacity)` bytes. + +1. Call `m_entries.setStorage(data, capacity)`. + +1. Call `clear()`. + +## 6. Public Static Functions + +### 6.1. getByteArraySize + +```c++ +static constexpr FwSizeType getByteArraySize(FwSizeType capacity) +``` + +Return `ExternalArray::getByteArraySize(capacity)`. diff --git a/Fw/DataStructures/docs/ExternalArray.md b/Fw/DataStructures/docs/ExternalArray.md index 68ce1016c54..14b7275f80b 100644 --- a/Fw/DataStructures/docs/ExternalArray.md +++ b/Fw/DataStructures/docs/ExternalArray.md @@ -60,13 +60,15 @@ ExternalArray(ByteArray data, FwSizeType size) ``` Call `setStorage(data, size)`. -`data` must be correctly aligned for `T` and must +`data` must be aligned according to `getByteArrayAlignment` and must contain at least `getByteArraySize(size)` bytes. _Example:_ ```c++ constexpr FwSizeType size = 3; -alignas(U32) U8 bytes[size * sizeof(U32)]; +constexpr U8 alignment = ExternalArray::byteArrayAlignment(); +constepxr FwSizeType byteArraySize = ExternalArray::getByteArraySize(size); +alignas(alignment) U8 bytes[byteArraySize]; ExternalArray a(ByteArray(&bytes[0], sizeof bytes), size); ``` @@ -250,14 +252,31 @@ contain at least `getByteArraySize(size)` bytes. _Example:_ ```c++ constexpr FwSizeType size = 3; -alignas(U32) U8 bytes[size * sizeof(U32)]; +constexpr U8 alignment = ExternalArray::byteArrayAlignment(); +constepxr FwSizeType byteArraySize = ExternalArray::getByteArraySize(size); +alignas(alignment) U8 bytes[byteArraySize]; ExternalArray a; a.setStorage(ByteArray(&bytes[0], sizeof bytes), size); ``` ## 5. Public Static Functions -### 5.1. getByteArraySize +### 5.1. getByteArrayAlignment + +```c++ +static constexpr U8 getByteArrayAlignment() +``` + +Return `alignof(T)`. + +_Example:_ +``` +c++ +const U8 byteArrayAlignment = ExternalArray::getByteArraySize(size); +ASSERT_EQ(byteArrayAlignment, alignof(U32)); +``` + +### 5.2. getByteArraySize ```c++ static constexpr FwSizeType getByteArraySize(FwSizeType size) @@ -269,6 +288,6 @@ _Example:_ ``` c++ const FwSizeType size = 10; -const FwSizeType byteArraySize = ExternalArrayMap::getByteArraySize(size); +const FwSizeType byteArraySize = ExternalArray::getByteArraySize(size); ASSERT_EQ(byteArraySize, 10 * sizeof(U32)); ``` diff --git a/Fw/DataStructures/docs/SetOrMapIterator.md b/Fw/DataStructures/docs/SetOrMapIterator.md index f54abd17752..455785d9b82 100644 --- a/Fw/DataStructures/docs/SetOrMapIterator.md +++ b/Fw/DataStructures/docs/SetOrMapIterator.md @@ -30,7 +30,7 @@ templates: |----|----|-------|-------------| |`m_keyOrElement`|`KE`|The map key or set element|C++ default initialization| |`m_value`|`V`|The value|C++ default initialization| -|`m_nextIterator`|`SetOrMapIterator*`|Pointer to the next iterator or `nullptr` if none|`nullptr`| +|`m_next`|`SetOrMapIterator*`|Pointer to the next iterator or `nullptr` if none|`nullptr`| ## 4. Public Constructors and Destructors @@ -45,14 +45,14 @@ Defined as `= default`. ### 4.2. Constructor Providing Members ```c++ -SetOrMapIterator(const KE& keyOrElement, const V& value, SetOrMapIterator* nextIterator = nullptr) +SetOrMapIterator(const KE& keyOrElement, const V& value, SetOrMapIterator* next = nullptr) ``` 1. Set `m_keyOrElement = keyOrElement`. 2. Set `m_value = value`. -3. Set `m_nextIterator = nextIterator`. +3. Set `m_next = next`. ### 4.3. Copy Constructor @@ -110,7 +110,7 @@ Return a reference to `m_value`. SetOrMapIterator getNextIterator() ``` -Return `m_nextIterator`. +Return `m_next`. ### 5.4. getNextMapIterator @@ -118,7 +118,7 @@ Return `m_nextIterator`. MapIterator getNextMapIterator() override ``` -Return `m_nextIterator`. +Return `m_next`. ### 5.5. getNextSetIterator @@ -126,7 +126,7 @@ Return `m_nextIterator`. SetIterator* getNextSetIterator() ``` -Return `m_nextIterator`. +Return `m_next`. ### 5.6. setKeyOrElement @@ -139,10 +139,10 @@ Set `m_keyOrElement = keyOrElement`. ### 5.8. setNextIterator ```c++ -void setNextIterator(SetOrMapIterator* nextIterator) +void setNextIterator(SetOrMapIterator* next) ``` -Set `m_nextIterator = nextIterator`. +Set `m_next = next`. ### 5.7. setValue diff --git a/Fw/DataStructures/test/ut/ExternalArrayTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayTest.cpp index bc2b0767bab..af732f36b70 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayTest.cpp @@ -26,8 +26,9 @@ TEST(ExternalArray, StorageConstructorTyped) { TEST(ExternalArray, StorageConstructorUntyped) { constexpr FwSizeType size = 3; + constexpr U8 alignment = ExternalArray::getByteArrayAlignment(); constexpr FwSizeType byteArraySize = ExternalArray::getByteArraySize(size); - alignas(U32) U8 bytes[byteArraySize]; + alignas(alignment) U8 bytes[byteArraySize]; ExternalArray a(ByteArray(&bytes[0], sizeof bytes), size); ASSERT_EQ(a.getElements(), reinterpret_cast(&bytes[0])); ASSERT_EQ(a.getSize(), size); @@ -113,8 +114,9 @@ TEST(ExternalArray, SetStorageTyped) { TEST(ExternalArray, SetStorageUnypedOK) { constexpr FwSizeType size = 10; + constexpr U8 alignment = ExternalArray::getByteArrayAlignment(); constexpr FwSizeType byteArraySize = ExternalArray::getByteArraySize(size); - alignas(U32) U8 bytes[byteArraySize]; + alignas(alignment) U8 bytes[byteArraySize]; ExternalArray a; a.setStorage(ByteArray(&bytes[0], sizeof bytes), size); ASSERT_EQ(a.getElements(), reinterpret_cast(bytes)); @@ -123,16 +125,18 @@ TEST(ExternalArray, SetStorageUnypedOK) { TEST(ExternalArray, SetStorageUnypedBadSize) { constexpr FwSizeType size = 10; + constexpr U8 alignment = ExternalArray::getByteArrayAlignment(); constexpr FwSizeType byteArraySize = ExternalArray::getByteArraySize(size); - alignas(U32) U8 bytes[byteArraySize]; + alignas(alignment) U8 bytes[byteArraySize]; ExternalArray a; ASSERT_DEATH(a.setStorage(ByteArray(&bytes[0], sizeof bytes), size + 1), "Assert"); } TEST(ExternalArray, SetStorageUnypedBadAlignment) { constexpr FwSizeType size = 10; + constexpr U8 alignment = ExternalArray::getByteArrayAlignment(); constexpr FwSizeType byteArraySize = ExternalArray::getByteArraySize(size); - alignas(U32) U8 bytes[byteArraySize]; + alignas(alignment) U8 bytes[byteArraySize]; ExternalArray a; ASSERT_DEATH(a.setStorage(ByteArray(&bytes[1], sizeof bytes), size), "Assert"); } From f141b5f1c61c85bb0669d7774cb3ebc9b31c5575 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 20:14:04 -0700 Subject: [PATCH 200/458] Revise SDD for ExternalArray --- Fw/DataStructures/docs/ExternalArray.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArray.md b/Fw/DataStructures/docs/ExternalArray.md index 14b7275f80b..cfc57258a6d 100644 --- a/Fw/DataStructures/docs/ExternalArray.md +++ b/Fw/DataStructures/docs/ExternalArray.md @@ -60,7 +60,7 @@ ExternalArray(ByteArray data, FwSizeType size) ``` Call `setStorage(data, size)`. -`data` must be aligned according to `getByteArrayAlignment` and must +`data` must be aligned according to `getByteArrayAlignment()` and must contain at least `getByteArraySize(size)` bytes. _Example:_ @@ -285,8 +285,7 @@ static constexpr FwSizeType getByteArraySize(FwSizeType size) Return `size * sizeof(T)`. _Example:_ -``` -c++ +```c++ const FwSizeType size = 10; const FwSizeType byteArraySize = ExternalArray::getByteArraySize(size); ASSERT_EQ(byteArraySize, 10 * sizeof(U32)); From f6754ead874ff5dac05bdeb5ff537e649f676917 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 20:16:20 -0700 Subject: [PATCH 201/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalArray.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArray.md b/Fw/DataStructures/docs/ExternalArray.md index cfc57258a6d..3422e9cd667 100644 --- a/Fw/DataStructures/docs/ExternalArray.md +++ b/Fw/DataStructures/docs/ExternalArray.md @@ -270,9 +270,8 @@ static constexpr U8 getByteArrayAlignment() Return `alignof(T)`. _Example:_ -``` -c++ -const U8 byteArrayAlignment = ExternalArray::getByteArraySize(size); +```c++ +const U8 byteArrayAlignment = ExternalArray::getByteArrayAlignment(size); ASSERT_EQ(byteArrayAlignment, alignof(U32)); ``` From 44d5b8cded7ebb6d1b36305ac44920539734b93c Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 20:19:10 -0700 Subject: [PATCH 202/458] Reivse SDD for ExternalArray --- Fw/DataStructures/docs/ExternalArray.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArray.md b/Fw/DataStructures/docs/ExternalArray.md index 3422e9cd667..4c625be9f34 100644 --- a/Fw/DataStructures/docs/ExternalArray.md +++ b/Fw/DataStructures/docs/ExternalArray.md @@ -236,8 +236,8 @@ a.setStorage(elements, size); void setStorage(ByteArray data, FwSizeType size) ``` -`data` must be correctly aligned for `T` and must -contain at least `getByteArraySize(size)` bytes. +`data` must be correctly aligned according to `getByteArrayAlignment` +and must contain at least `getByteArraySize(size)` bytes. 1. Assert that `data.bytes != nullptr`. From 1b9dc38fdc7369a422c53bdf830cc3ed323d7309 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 20:21:58 -0700 Subject: [PATCH 203/458] Revise SDD for ExternalArray --- Fw/DataStructures/docs/ExternalArray.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArray.md b/Fw/DataStructures/docs/ExternalArray.md index 4c625be9f34..d4fa2513f23 100644 --- a/Fw/DataStructures/docs/ExternalArray.md +++ b/Fw/DataStructures/docs/ExternalArray.md @@ -20,7 +20,7 @@ It stores a pointer to the backing memory _M_. |Name|Type|Purpose|Default Value| |----|----|-------|-------------| -|`m_elements`|`T*`|Points to the backing memory|`nullptr`| +|`m_elements`|`T*`|Pointer to backing memory or `nullptr`|`nullptr`| |`m_size`|`FwSizeType`|Stores the size (number of elements) of the array|0| ## 3. Public Constructors and Destructors @@ -60,8 +60,9 @@ ExternalArray(ByteArray data, FwSizeType size) ``` Call `setStorage(data, size)`. -`data` must be aligned according to `getByteArrayAlignment()` and must -contain at least `getByteArraySize(size)` bytes. +`data` must be aligned according to +[`getByteArrayAlignment()`](#getbytearrayalignment) and must +contain at least [`getByteArraySize(size)`](#getbytearraysize) bytes. _Example:_ ```c++ @@ -236,8 +237,8 @@ a.setStorage(elements, size); void setStorage(ByteArray data, FwSizeType size) ``` -`data` must be correctly aligned according to `getByteArrayAlignment` -and must contain at least `getByteArraySize(size)` bytes. +`data` must be correctly aligned according to [`getByteArrayAlignment`](#getbytearrayalignment) +and must contain at least [`getByteArraySize(size)`](#getbytearraysize) bytes. 1. Assert that `data.bytes != nullptr`. From 54a8e784db4a1c170b1b62072e63219776d1362e Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 20:23:04 -0700 Subject: [PATCH 204/458] Revise SDD for ExternalArray --- Fw/DataStructures/docs/ExternalArray.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArray.md b/Fw/DataStructures/docs/ExternalArray.md index d4fa2513f23..91b43d47c05 100644 --- a/Fw/DataStructures/docs/ExternalArray.md +++ b/Fw/DataStructures/docs/ExternalArray.md @@ -61,8 +61,8 @@ ExternalArray(ByteArray data, FwSizeType size) Call `setStorage(data, size)`. `data` must be aligned according to -[`getByteArrayAlignment()`](#getbytearrayalignment) and must -contain at least [`getByteArraySize(size)`](#getbytearraysize) bytes. +[`getByteArrayAlignment()`](#51-getbytearrayalignment) and must +contain at least [`getByteArraySize(size)`](#52-getbytearraysize) bytes. _Example:_ ```c++ @@ -237,8 +237,8 @@ a.setStorage(elements, size); void setStorage(ByteArray data, FwSizeType size) ``` -`data` must be correctly aligned according to [`getByteArrayAlignment`](#getbytearrayalignment) -and must contain at least [`getByteArraySize(size)`](#getbytearraysize) bytes. +`data` must be correctly aligned according to [`getByteArrayAlignment`](#51-getbytearrayalignment) +and must contain at least [`getByteArraySize(size)`](#52-getbytearraysize) bytes. 1. Assert that `data.bytes != nullptr`. From abfd5b00688806fe9c082b129dc020d8ee8b5d7b Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 20:29:51 -0700 Subject: [PATCH 205/458] Revise Fw/DataStructures --- Fw/DataStructures/ExternalFifoQueue.hpp | 6 ++++++ Fw/DataStructures/docs/ExternalFifoQueue.md | 16 +++++++++++++++- .../test/ut/ExternalFifoQueueTest.cpp | 3 ++- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/ExternalFifoQueue.hpp b/Fw/DataStructures/ExternalFifoQueue.hpp index 1d9eb842e9b..f3371fd0c66 100644 --- a/Fw/DataStructures/ExternalFifoQueue.hpp +++ b/Fw/DataStructures/ExternalFifoQueue.hpp @@ -155,6 +155,12 @@ class ExternalFifoQueue final : public FifoQueueBase { // Public static functions // ---------------------------------------------------------------------- + //! Get the alignment of the storage for an ExternalFifoQueue + //! \return The alignment + static constexpr U8 getByteArrayAlignment() { + return ExternalArray::getByteArrayAlignment(); + } + //! Get the size of the storage for an ExternalFifoQueue of the specified //! capacity, as a byte array //! \return The byte array size diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index 3d7ff99a6bb..f153744610e 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -362,7 +362,21 @@ ASSERT_EQ(queue.getCapacity(), capacity); ## 6. Public Static Functions -### 6.1. getByteArraySize +### 6.1. getByteArrayAlignment + +```c++ +static constexpr U8 getByteArrayAlignment() +``` + +Return `ExternalArray::getByteArrayAlignment()`. + +_Example:_ +```c++ +const U8 byteArrayAlignment = ExternalFifoQueue::getByteArrayAlignment(size); +ASSERT_EQ(byteArrayAlignment, alignof(U32)); +``` + +### 6.2. getByteArraySize ```c++ static constexpr FwSizeType getByteArraySize(FwSizeType capacity) diff --git a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp index 56fe26654eb..7cba55f786c 100644 --- a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp @@ -44,8 +44,9 @@ TEST(ExternalFifoQueue, TypedStorageConstructor) { TEST(ExternalFifoQueue, UntypedStorageConstructor) { constexpr FwSizeType capacity = 10; + constexpr U8 alignment = ExternalFifoQueue::getByteArrayAlignment(); constexpr FwSizeType byteArraySize = ExternalFifoQueue::getByteArraySize(capacity); - alignas(U32) U8 bytes[byteArraySize]; + alignas(alignment) U8 bytes[byteArraySize]; ExternalFifoQueue queue(ByteArray(&bytes[0], sizeof bytes), capacity); ExternalFifoQueueTester tester(queue); ASSERT_EQ(tester.getItems().getElements(), reinterpret_cast(bytes)); From 3c87ac76150171b9277c1c2e8ef9cbcfb5baeff4 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 20:32:06 -0700 Subject: [PATCH 206/458] Revise SDD for ExternalFifoQueue --- Fw/DataStructures/docs/ExternalFifoQueue.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index f153744610e..b7dc4597b44 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -75,8 +75,9 @@ ExternalFifoQueue queue(items, capacity); ExternalFifoQueue(ByteArray data, FwSizeType capacity) ``` -`data` must be correctly aligned for `T` and must -contain at least `ExternalFifoQueue::getByteArraySize(capacity)` bytes. +`data` must be aligned according to +[`getByteArrayAlignment()`](#61-getbytearrayalignment) and must +contain at least [`getByteArraySize(size)`](#62-getbytearraysize) bytes. 1. Call `setStorage(data, capacity)`. @@ -85,8 +86,9 @@ contain at least `ExternalFifoQueue::getByteArraySize(capacity)` bytes. _Example:_ ```c++ constexpr FwSizeType capacity = 10; +constexpr U8 alignment = ExternalFifoQueue::getByteArrayAlignment(); constexpr FwSizeType byteArraySize = ExternalFifoQueue::getByteArraySize(capacity); -alignas(U32) U8 bytes[byteArraySize]; +alignas(alignment) U8 bytes[byteArraySize]; ExternalFifoQueue queue(ByteArray(&bytes[0], sizeof bytes), capacity); ``` @@ -210,8 +212,9 @@ queue.setStorage(items, capacity); void setStorage(ByteArray data, FwSizeType capacity) ``` -`data` must be correctly aligned for `T` and must -contain at least `ExternalFifoQueue::getByteArraySize(capacity)` bytes. +`data` must be aligned according to +[`getByteArrayAlignment()`](#61-getbytearrayalignment) and must +contain at least [`getByteArraySize(size)`](#62-getbytearraysize) bytes. 1. Call `m_items.setStorage(data, capacity)`. @@ -226,8 +229,9 @@ contain at least `ExternalFifoQueue::getByteArraySize(capacity)` bytes. _Example:_ ```c++ constexpr FwSizeType capacity = 10; +constexpr U8 alignment = ExternalFifoQueue::getByteArrayAlignment(); constexpr FwSizeType byteArraySize = ExternalFifoQueue::getByteArraySize(capacity); -alignas(U32) U8 bytes[byteArraySize]; +alignas(alignment) U8 bytes[byteArraySize]; ExternalFifoQueue queue; queue.setStorage(ByteArray(&bytes[0], sizeof bytes), capacity); ``` From 9312a1eee96efd8174b12e0bf7f1ecaa7800e99d Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 20:39:53 -0700 Subject: [PATCH 207/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ArraySetOrMapImpl.md | 42 +++++++++++++-------- Fw/DataStructures/docs/ExternalFifoQueue.md | 2 +- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/Fw/DataStructures/docs/ArraySetOrMapImpl.md b/Fw/DataStructures/docs/ArraySetOrMapImpl.md index f431cd8a686..7c8846c0fa2 100644 --- a/Fw/DataStructures/docs/ArraySetOrMapImpl.md +++ b/Fw/DataStructures/docs/ArraySetOrMapImpl.md @@ -15,7 +15,7 @@ storing the entries in the set or map. |`typename`|`KE`|The type of a key in a map or the element of a set| |`typename`|`V`|The type of a value in a map; unused in a set| -## Public Types +## 2. Public Types `ArraySetOrMapImpl` defines the following types: ```c++ @@ -59,8 +59,9 @@ ArraySetOrMapImpl(Entry* entries, FwSizeType capacity) ArraySetOrMapImpl(ByteArray data, FwSizeType capacity) ``` -`data` must be correctly aligned for `Entry` and must -contain at least `ArraySetOrMapImpl::getByteArraySize(capacity)` bytes. +`data` must be aligned according to +[`getByteArrayAlignment()`](#61-getbytearrayalignment) and must +contain at least [`getByteArraySize(size)`](#62-getbytearraysize) bytes. 1. Call `setStorage(data, capacity)`. @@ -98,7 +99,7 @@ ArraySetOrMapImpl& operator=(const ArraySetOrMapImpl& map) 1. Return `*this`. -### 5.6. at +### 5.2. at ```c++ const Entry& at(FwSizeType index) const @@ -108,7 +109,7 @@ const Entry& at(FwSizeType index) const 1. Return `m_entries[index]`. -### 5.2. clear +### 5.3. clear ```c++ void clear() @@ -116,7 +117,7 @@ void clear() Set `m_size = 0`. -### 5.3. find +### 5.4. find ```c++ const Entry* find(const K& key) @@ -136,7 +137,7 @@ const Entry* find(const K& key) 1. Return `result`. -### 5.4. getCapacity +### 5.5. getCapacity ```c++ FwSizeType getCapacity() const @@ -144,7 +145,7 @@ FwSizeType getCapacity() const Return `m_entries.getSize()`. -### 5.5. getHeadEntry +### 5.6. getHeadEntry ```c++ const Entry* getHeadEntry const @@ -152,7 +153,7 @@ const Entry* getHeadEntry const Return `(m_size > 0) ? &m_entries[0] : nullptr`. -### 5.6. getSize +### 5.7. getSize ```c++ FwSizeType getSize() @@ -160,7 +161,7 @@ FwSizeType getSize() Return `m_size`. -### 5.7. insert +### 5.8. insert ```c++ Success insert(const Entry& e) @@ -193,7 +194,7 @@ Success insert(const Entry& e) 1. Return `status`. -### 5.8. remove +### 5.9. remove ```c++ Success remove(const K& key, V& value) @@ -221,7 +222,7 @@ Success remove(const K& key, V& value) 1. Return `status`. -### 5.9. setStorage (Typed Data) +### 5.10. setStorage (Typed Data) ```c++ void setStorage(T* entries, FwSizeType capacity) @@ -231,14 +232,15 @@ void setStorage(T* entries, FwSizeType capacity) 1. Call `clear()`. -### 5.10. setStorage (Untyped Data) +### 5.11. setStorage (Untyped Data) ```c++ void setStorage(ByteArray data, FwSizeType capacity) ``` -`data` must be correctly aligned for `Entry` and must -contain at least `ArraySetOrMapImpl::getByteArraySize(capacity)` bytes. +`data` must be aligned according to +[`getByteArrayAlignment()`](#61-getbytearrayalignment) and must +contain at least [`getByteArraySize(size)`](#62-getbytearraysize) bytes. 1. Call `m_entries.setStorage(data, capacity)`. @@ -246,7 +248,15 @@ contain at least `ArraySetOrMapImpl::getByteArraySize(capacity)` bytes. ## 6. Public Static Functions -### 6.1. getByteArraySize +### 6.1. getByteArrayAlignment + +```c++ +static constexpr U8 getByteArrayAlignment() +``` + +Return `ArraySetOrMapImpl::getByteArrayAlignment()`. + +### 6.2. getByteArraySize ```c++ static constexpr FwSizeType getByteArraySize(FwSizeType capacity) diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index b7dc4597b44..95383d9dcdf 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -376,7 +376,7 @@ Return `ExternalArray::getByteArrayAlignment()`. _Example:_ ```c++ -const U8 byteArrayAlignment = ExternalFifoQueue::getByteArrayAlignment(size); +constexpr U8 byteArrayAlignment = ExternalFifoQueue::getByteArrayAlignment(); ASSERT_EQ(byteArrayAlignment, alignof(U32)); ``` From e0305f0e086fb3785b99e0e7b1aaa5e4c8a8c3f0 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 20:45:15 -0700 Subject: [PATCH 208/458] Revise SDD for ArraySetOrMapImpl --- Fw/DataStructures/docs/ArraySetOrMapImpl.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/ArraySetOrMapImpl.md b/Fw/DataStructures/docs/ArraySetOrMapImpl.md index 7c8846c0fa2..284629bf499 100644 --- a/Fw/DataStructures/docs/ArraySetOrMapImpl.md +++ b/Fw/DataStructures/docs/ArraySetOrMapImpl.md @@ -151,7 +151,15 @@ Return `m_entries.getSize()`. const Entry* getHeadEntry const ``` -Return `(m_size > 0) ? &m_entries[0] : nullptr`. +1. Set `result = nullptr`. + +1. If `m_size > 0` + + 1. Assert `m_entries != nullptr`. + + 1. Set `result = &m_entries[0]`. + +1. Return `result`. ### 5.7. getSize From d5429e2e5d12ffa8c2d773d8f070d958b90ca549 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 20:48:04 -0700 Subject: [PATCH 209/458] Revise SDD for ArraySetOrMapImpl --- Fw/DataStructures/docs/ArraySetOrMapImpl.md | 28 ++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Fw/DataStructures/docs/ArraySetOrMapImpl.md b/Fw/DataStructures/docs/ArraySetOrMapImpl.md index 284629bf499..3e02889d3c9 100644 --- a/Fw/DataStructures/docs/ArraySetOrMapImpl.md +++ b/Fw/DataStructures/docs/ArraySetOrMapImpl.md @@ -19,7 +19,7 @@ storing the entries in the set or map. `ArraySetOrMapImpl` defines the following types: ```c++ -using Entry = SetOrMapIterator +using Iterator = SetOrMapIterator ``` The type `SetOrMapIterator` is defined [here](SetOrMapIterator.md). @@ -30,7 +30,7 @@ The type `SetOrMapIterator` is defined [here](SetOrMapIterator.md). |Name|Type|Purpose|Default Value| |----|----|-------|-------------| -|`m_entries`|[`ExternalArray`](ExternalArray.md)|The array for storing the set or map entries|C++ default initialization| +|`m_entries`|[`ExternalArray`](ExternalArray.md)|The array for storing the set or map entries|C++ default initialization| |`m_size`|`FwSizeType`|The number of entries in the map|0| ## 4. Public Constructors and Destructors @@ -46,7 +46,7 @@ Initialize each member variable with its default value. ### 4.2. Constructor Providing Typed Backing Storage ```c++ -ArraySetOrMapImpl(Entry* entries, FwSizeType capacity) +ArraySetOrMapImpl(Iterator* entries, FwSizeType capacity) ``` 1. Call `setStorage(entries, capacity)`. @@ -102,7 +102,7 @@ ArraySetOrMapImpl& operator=(const ArraySetOrMapImpl& map) ### 5.2. at ```c++ -const Entry& at(FwSizeType index) const +const Iterator& at(FwSizeType index) const ``` 1. Assert `index < m_size`. @@ -120,7 +120,7 @@ Set `m_size = 0`. ### 5.4. find ```c++ -const Entry* find(const K& key) +const Iterator* find(const K& key) ``` 1. Set `result = nullptr`. @@ -145,10 +145,10 @@ FwSizeType getCapacity() const Return `m_entries.getSize()`. -### 5.6. getHeadEntry +### 5.6. getHeadIterator ```c++ -const Entry* getHeadEntry const +const Iterator* getHeadIterator const ``` 1. Set `result = nullptr`. @@ -172,7 +172,7 @@ Return `m_size`. ### 5.8. insert ```c++ -Success insert(const Entry& e) +Success insert(const Iterator& e) ``` 1. Set `status = Success::FAILURE`. @@ -191,10 +191,10 @@ Success insert(const Entry& e) 1. If `(status == Success::FAILURE) && (m_size < getCapacity())` - 1. Set `m_entries[m_size] = Entry(e.key, e.value)`. + 1. Set `m_entries[m_size] = Iterator(e.key, e.value)`. 1. If `m_size > 0` then - call `m_entries[m_size - 1].setNextEntry(&m_entries[m_size])`. + call `m_entries[m_size - 1].setNextIterator(&m_entries[m_size])`. 1. Increment `m_size`. @@ -218,9 +218,9 @@ Success remove(const K& key, V& value) 1. `m_entries[i] = m_entries[m_size - 1]`. - 1. Call `m_entries[i].setNextEntry(&m_entries[i + 1])`. + 1. Call `m_entries[i].setNextIterator(&m_entries[i + 1])`. - 1. Otherwise call `m_entries[i].setNextEntry(nullptr)`. + 1. Otherwise call `m_entries[i].setNextIterator(nullptr)`. 1. Decrement `size`. @@ -262,7 +262,7 @@ contain at least [`getByteArraySize(size)`](#62-getbytearraysize) bytes. static constexpr U8 getByteArrayAlignment() ``` -Return `ArraySetOrMapImpl::getByteArrayAlignment()`. +Return `ExternalArray::getByteArrayAlignment()`. ### 6.2. getByteArraySize @@ -270,4 +270,4 @@ Return `ArraySetOrMapImpl::getByteArrayAlignment()`. static constexpr FwSizeType getByteArraySize(FwSizeType capacity) ``` -Return `ExternalArray::getByteArraySize(capacity)`. +Return `ExternalArray::getByteArraySize(capacity)`. From e7807d1092d365c655747b7b77abed8db49bde70 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 21:26:30 -0700 Subject: [PATCH 210/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ArraySetOrMapImpl.md | 10 +- Fw/DataStructures/docs/ExternalArrayMap.md | 209 ++++++++------------ Fw/DataStructures/docs/ExternalFifoQueue.md | 14 -- Fw/DataStructures/docs/MapBase.md | 16 +- 4 files changed, 97 insertions(+), 152 deletions(-) diff --git a/Fw/DataStructures/docs/ArraySetOrMapImpl.md b/Fw/DataStructures/docs/ArraySetOrMapImpl.md index 3e02889d3c9..7a25a91a6ca 100644 --- a/Fw/DataStructures/docs/ArraySetOrMapImpl.md +++ b/Fw/DataStructures/docs/ArraySetOrMapImpl.md @@ -172,18 +172,18 @@ Return `m_size`. ### 5.8. insert ```c++ -Success insert(const Iterator& e) +Success insert(const KE& keyOrElement, const V& value) ``` 1. Set `status = Success::FAILURE`. 1. For `i` in `[0, m_size)` - 1. Let `auto& ei = m_entries[i]`. + 1. Let `auto& e = m_entries[i]`. - 1. If `ei.getKey() == e.key` + 1. If `e.getKey() == e.keyOrElement` - 1. Call `ei.setValue(e.value)`. + 1. Call `e.setValue(value)`. 1. Set `status = Success::SUCCESS`. @@ -191,7 +191,7 @@ Success insert(const Iterator& e) 1. If `(status == Success::FAILURE) && (m_size < getCapacity())` - 1. Set `m_entries[m_size] = Iterator(e.key, e.value)`. + 1. Set `m_entries[m_size] = Iterator(keyOrElement, value)`. 1. If `m_size > 0` then call `m_entries[m_size - 1].setNextIterator(&m_entries[m_size])`. diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index 915750d43f6..54491b74e83 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -17,23 +17,31 @@ storing the entries in the map. ## 2. Base Class -`ExternalArrayMap` is publicly derived from +`ExternalArrayMap` is publicly derived from [`MapBase`](MapBase.md). -## 3. Private Member Variables +## 3. Public Types + +`ExternalArrayMap` defines the following public types: + +```c++ +using Entry = SetOrMapIterator +``` + +The type `SetOrMapIterator` is defined [here](SetOrMapIterator.md). + +## 4. Private Member Variables `ExternalArrayMap` has the following private member variables. |Name|Type|Purpose|Default Value| |----|----|-------|-------------| -|`m_entries`|[`ExternalArray`](ExternalArray.md)|The array for storing the map entries|C++ default initialization| -|`m_size`|`FwSizeType`|The number of entries in the map|0| +|`m_mapImpl`|[`ArraySetOrMapImpl`](ArraySetOrMapImpl.md)|The array for storing the map entries|C++ default initialization| -The type `Entry` is defined [in the base class](MapBase.md#2-types). -## 4. Public Constructors and Destructors +## 5. Public Constructors and Destructors -### 4.1. Zero-Argument Constructor +### 5.1. Zero-Argument Constructor ```c++ ExternalArrayMap() @@ -46,45 +54,47 @@ _Example:_ ExternalArrayMap map; ``` -### 4.2. Constructor Providing Typed Backing Storage +### 5.2. Constructor Providing Typed Backing Storage ```c++ ExternalArrayMap(Entry* entries, FwSizeType capacity) ``` -1. Call `setStorage(entries, capacity)`. +1. Call `m_mapImpl.setStorage(entries, capacity)`. 1. Initialize the other member variables with their default values. _Example:_ ```c++ constexpr FwSizeType capacity = 10; -MapEntry entries[capacity]; +ExternalArrayMap::Entry entries[capacity]; ExternalArrayMap map(entries, capacity); ``` -### 4.3. Constructor Providing Untyped Backing Storage +### 5.3. Constructor Providing Untyped Backing Storage ```c++ ExternalArrayMap(ByteArray data, FwSizeType capacity) ``` -`data` must be correctly aligned for `Entry` and must -contain at least `ExternalArrayMap::getByteArraySize(capacity)` bytes. +`data` must be aligned according to +[`getByteArrayAlignment()`](#71-getbytearrayalignment) and must +contain at least [`getByteArraySize(size)`](#72-getbytearraysize) bytes. -1. Call `setStorage(data, capacity)`. +1. Call `m_mapImpl.setStorage(data, capacity)`. 1. Initialize the other member variables with their default values. _Example:_ ```c++ constexpr FwSizeType capacity = 10; +constexpr U8 alignment = ExternalArrayMap::getByteAlignment(); constexpr FwSizeType byteArraySize = ExternalArrayMap::getByteArraySize(capacity); -alignas(MapEntry) U8 bytes[byteArraySize]; +alignas(alignment) U8 bytes[byteArraySize]; ExternalArrayMap map(ByteArray(&bytes[0], sizeof bytes), capacity); ``` -### 4.4. Copy Constructor +### 5.4. Copy Constructor ```c++ ExternalArrayMap(const ExternalArrayMap& map) @@ -95,7 +105,7 @@ Set `*this = map`. _Example:_ ```c++ constexpr FwSizeType capacity = 3; -U32 entries[capacity]; +ExternalArrayMap::Entry entries[capacity]; // Call the constructor providing backing storage ExternalArrayMap m1(entries, capacity); // Insert an item @@ -108,7 +118,7 @@ ExternalArrayMap m2(m1); ASSERT_EQ(m2.getSize(), 1); ``` -### 4.5. Destructor +### 5.5. Destructor ```c++ ~ExternalArrayMap() override @@ -116,9 +126,9 @@ ASSERT_EQ(m2.getSize(), 1); Defined as `= default`. -## 5. Public Member Functions +## 6. Public Member Functions -### 5.1. operator= +### 6.1. operator= ```c++ ExternalArrayMap& operator=(const ExternalArrayMap& map) @@ -126,16 +136,14 @@ ExternalArrayMap& operator=(const ExternalArrayMap& map) 1. If `&map != this` - 1. Set `m_entries = map.m_entries`. - - 1. Set `m_size = map.m_size`. + 1. Set `m_mapImpl = map.m_mapImpl`. 1. Return `*this`. _Example:_ ```c++ constexpr FwSizeType capacity = 3; -MapEntry entries[capacity]; +ExternalArrayMap::Entry entries[capacity]; // Call the constructor providing backing storage ExternalArrayMap m1(entries, capacity); // Insert an item @@ -151,20 +159,18 @@ m2 = m1; ASSERT_EQ(m2.getSize(), 1); ``` -### 5.6. at +### 6.2. at ```c++ const V& at(FwSizeType index) const ``` -1. Assert `index < m_size`. - -1. Return `m_entries[index].getValue()`. +Return `m_mapImpl[index]`. _Example:_ ```c++ constexpr FwSizeType capacity = 3; -MapEntry entries[capacity]; +ExternalArrayMap::Entry entries[capacity]; ExternalArrayMap map(entries, capacity); const auto status = map.insert(0, 1); ASSERT_EQ(status, Success::SUCCESS); @@ -172,18 +178,18 @@ ASSERT_EQ(map.at(0), 1); ASSERT_DEATH(map.at(1), "Assert"); ``` -### 5.2. clear +### 6.3. clear ```c++ void clear() override ``` -Set `m_size = 0`. +Call `m_mapImpl.clear()`. _Example:_ ```c++ constexpr FwSizeType capacity = 10; -MapEntry entries[capacity]; +ExternalArrayMap::Entry entries[capacity]; ExternalArrayMap map(entries, capacity); const auto status = map.enqueue(3); ASSERT_EQ(map.getSize(), 1); @@ -191,7 +197,7 @@ map.clear(); ASSERT_EQ(map.getSize(), 0); ``` -### 5.3. find +### 6.4. find ```c++ Success find(const K& key, V& value) override @@ -199,24 +205,20 @@ Success find(const K& key, V& value) override 1. Set `status = Success::FAILURE`. -1. For `i` in `[0, m_size)` - - 1. Let `const auto& e = &m_entries[i]`. +1. Set `iterator = m_mapImpl.find(key)`. - 1. If `e.getKey() == key` +1. If `iterator != nullptr` - 1. Set `value = e.getValue()`. + 1. Set `value = iterator.getValue()`. - 1. Set `status = Success::SUCCESS`. - - 1. Break out of the loop. + 1. Set `status = Success::SUCCESS`. 1. Return `status`. _Example:_ ```c++ constexpr FwSizeType capacity = 10; -U32 entries[capacity]; +ExternalArrayMap::Entry entries[capacity]; ExternalArrayMap map(entries, capacity); U32 value = 0; auto status = map.find(0, value); @@ -228,56 +230,58 @@ ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(value, 1); ``` -### 5.4. getCapacity +### 6.5. getCapacity ```c++ FwSizeType getCapacity() const override ``` -Return `m_entries.getSize()`. +Return `m_mapImpl.getCapacity()`. _Example:_ ```c++ constexpr FwSizeType capacity = 10; -U32 entries[capacity]; +ExternalArrayMap::Entry entries[capacity]; ExternalArrayMap map(entries, capacity); ASSERT_EQ(map.getCapacity(), capacity); ``` -### 5.5. getHeadEntry +### 6.6. getHeadIterator ```c++ -const Entry* getHeadEntry const override +const Iterator* getHeadIterator const override ``` -Return `(m_size > 0) ? &m_entries[0] : nullptr`. +The type `Iterator` is defined [in the base class](MapBase.md#2-publictypes). + +Return `m_impl.getHeadIterator()`. _Example:_ ```c++ constexpr FwSizeType capacity = 10; -U32 entries[capacity]; +ExternalArrayMap::Entry entries[capacity]; ExternalArrayMap map(entries, capacity); -const auto* e = map.getHeadEntry(); +const auto* e = map.getHeadIterator(); FW_ASSERT(e == nullptr); map.insert(0, 1); -e = map.getHeadEntry(); +e = map.getHeadIterator(); FW_ASSERT(e != nullptr); ASSERT_EQ(e.getKey(), 0); ASSERT_EQ(e.getValue(), 1); ``` -### 5.6. getSize +### 6.7. getSize ```c++ FwSizeType getSize() const override ``` -Return `m_size`. +Return `m_mapImpl.getSize()`. _Example:_ ```c++ constexpr FwSizeType capacity = 10; -U32 entries[capacity]; +ExternalArrayMap::Entry entries[capacity]; ExternalArrayMap map(entries, capacity); auto size = map.getSize(); ASSERT_EQ(size, 0); @@ -287,43 +291,18 @@ size = map.getSize(); ASSERT_EQ(size, 1); ``` -### 5.7. insert +### 6.8. insert ```c++ Success insert(const K& key, const V& value) override ``` -1. Set `status = Success::FAILURE`. - -1. For `i` in `[0, m_size)` - - 1. Let `auto& e = m_entries[i]`. - - 1. If `e.getKey() == key` - - 1. Call `e.setValue(value)`. - - 1. Set `status = Success::SUCCESS`. - - 1. Break out of the loop - -1. If `(status == Success::FAILURE) && (m_size < getCapacity())` - - 1. Set `m_entries[m_size] = Entry(key, value)`. - - 1. If `m_size > 0` then - call `m_entries[m_size - 1].setNextEntry(&m_entries[m_size])`. - - 1. Increment `m_size`. - - 1. Set `status = Success::SUCCESS`. - -1. Return `status`. +Return `m_mapImpl.insert(key, value)`. _Example:_ ```c++ constexpr FwSizeType capacity = 10; -MapEntry entries[capacity]; +ExternalArrayMap::Entry entries[capacity]; ExternalArrayMap map(entries, capacity); auto size = map.getSize(); ASSERT_EQ(size, 0); @@ -334,43 +313,23 @@ ASSERT_EQ(size, 1); ``` ```c++ -Success insert(const Entry& e) override +Success insert(const Iterator& e) override ``` Call `insert(e.getKey(), e.getValue())`. -### 5.8. remove +### 6.9. remove ```c++ Success remove(const K& key, V& value) override ``` -1. Set `status = Success::FAILURE`. - -1. For `i` in `[0, m_size)` - - 1. If `m_entries[i].getKey() == key` - - 1. If `i < m_size - 1` then - - 1. `m_entries[i] = m_entries[m_size - 1]`. - - 1. Call `m_entries[i].setNextEntry(&m_entries[i + 1])`. - - 1. Otherwise call `m_entries[i].setNextEntry(nullptr)`. - - 1. Decrement `size`. - - 1. Set `status = Success::SUCCESS`. - - 1. Break out of the loop. - -1. Return `status`. +Return `m_mapImpl.remove(key, value)`. _Example:_ ```c++ constexpr FwSizeType capacity = 10; -MapEntry entries[capacity]; +ExternalArrayMap::Entry entries[capacity]; ExternalArrayMap map(entries, capacity); auto size = map.getSize(); ASSERT_EQ(size, 0); @@ -390,59 +349,59 @@ ASSERT_EQ(size, 0); ASSERT_EQ(value, 1); ``` -### 5.9. setStorage (Typed Data) +### 6.10. setStorage (Typed Data) ```c++ -void setStorage(T* entries, FwSizeType capacity) +void setStorage(Entry* entries, FwSizeType capacity) ``` -1. Call `m_entries.setStorage(entries, capacity)`. - -1. Call `clear()`. +1. Call `m_mapImpl.setStorage(entries, capacity)`. _Example:_ ```c++ constexpr FwSizeType capacity = 10; ExternalArrayMap map; -MapEntry entries[capacity]; +ExternalArrayMap::Entry entries[capacity]; map.setStorage(entries, capacity); ``` -### 5.10. setStorage (Untyped Data) +### 6.11. setStorage (Untyped Data) ```c++ void setStorage(ByteArray data, FwSizeType capacity) ``` -`data` must be correctly aligned for `Entry` and must -contain at least `ExternalArrayMap::getByteArraySize(capacity)` bytes. +`data` must be aligned according to +[`getByteArrayAlignment()`](#71-getbytearrayalignment) and must +contain at least [`getByteArraySize(size)`](#72-getbytearraysize) bytes. 1. Call `m_entries.setStorage(data, capacity)`. 1. Call `clear()`. -_Example:_ ```c++ constexpr FwSizeType capacity = 10; +constexpr U8 alignment = ExternalArrayMap::getByteAlignment(); constexpr FwSizeType byteArraySize = ExternalArrayMap::getByteArraySize(capacity); -alignas(MapEntry) U8 bytes[byteArraySize]; +alignas(alignment) U8 bytes[byteArraySize]; ExternalArrayMap map; map.setStorage(ByteArray(&bytes[0], sizeof bytes), capacity); ``` -## 6. Public Static Functions +## 7. Public Static Functions -### 6.1. getByteArraySize +### 7.1. getByteArrayAlignment ```c++ -static constexpr FwSizeType getByteArraySize(FwSizeType capacity) +static constexpr U8 getByteArrayAlignment() ``` -Return `ExternalArray::getByteArraySize(capacity)`. +Return `ExternalArray::getByteArrayAlignment()`. + +### 7.2. getByteArraySize -_Example:_ ```c++ -const FwSizeType size = 10; -const FwSizeType byteArraySize = ExternalFifoQueue::getByteArraySize(size); -ASSERT_EQ(byteArraySize, 10 * sizeof(U32)); +static constexpr FwSizeType getByteArraySize(FwSizeType capacity) ``` + +Return `ExternalArray::getByteArraySize(capacity)`. diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index 95383d9dcdf..52a7e53cd44 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -374,12 +374,6 @@ static constexpr U8 getByteArrayAlignment() Return `ExternalArray::getByteArrayAlignment()`. -_Example:_ -```c++ -constexpr U8 byteArrayAlignment = ExternalFifoQueue::getByteArrayAlignment(); -ASSERT_EQ(byteArrayAlignment, alignof(U32)); -``` - ### 6.2. getByteArraySize ```c++ @@ -387,11 +381,3 @@ static constexpr FwSizeType getByteArraySize(FwSizeType capacity) ``` Return `ExternalArray::getByteArraySize(capacity)`. - -_Example:_ -``` -c++ -const FwSizeType size = 10; -const FwSizeType byteArraySize = ExternalFifoQueue::getByteArraySize(size); -ASSERT_EQ(byteArraySize, 10 * sizeof(U32)); -``` diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index d4f88cfd1b9..7d1ed72cb23 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -19,7 +19,7 @@ It represents an abstract base class for a map. |Name|Definition| |----|----------| -|`Entry`|`MapEntry`| +|`Iterator`|`MapIterator`| ## 3. Private Constructors @@ -89,7 +89,7 @@ void copyDataFrom(const MapBase& map) 1. Let `size` be the minimum of `map.getSize()` and `getCapacity()`. - 1. Set `e = map.getHeadEntry()`. + 1. Set `e = map.getHeadIterator()`. 1. For `i` in [0, `size`) @@ -99,7 +99,7 @@ void copyDataFrom(const MapBase& map) 1. Assert `status == Success::SUCCESS`. - 1. Set `e = e.getNextEntry()` + 1. Set `e = e.getNextIterator()` _Example:_ ```c++ @@ -160,10 +160,10 @@ void f(const MapBase& map) { } ``` -### 6.5. getHeadEntry +### 6.5. getHeadIterator ```c++ -const Entry* getHeadEntry const = 0 +const Iterator* getHeadIterator const = 0 ``` Get the head entry of the map. @@ -172,10 +172,10 @@ _Example:_ ```c++ void f(const MapBase& map) { map.clear(); - const auto* e = map.getHeadEntry(); + const auto* e = map.getHeadIterator(); FW_ASSERT(e == nullptr); map.insert(0, 1); - e = map.getHeadEntry(); + e = map.getHeadIterator(); FW_ASSERT(e != nullptr); ASSERT_EQ(e.getKey(), 0); ASSERT_EQ(e.getValue(), 1); @@ -198,7 +198,7 @@ See [**getCapacity**](MapBase.md#55-getCapacity). ```c++ Success insert(const K& key, const V& value) = 0 -Success insert(const Entry& e) = 0 +Success insert(const Iterator& e) = 0 ``` 1. If an entry `e` exists with the specified key, then update the From 043226fa2db59a7dc707fc761e8737c1da844794 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 21:30:32 -0700 Subject: [PATCH 211/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ArraySetOrMapImpl.md | 5 +++++ Fw/DataStructures/docs/ExternalArrayMap.md | 4 ++++ Fw/DataStructures/docs/SetOrMapIterator.md | 6 ++++++ 3 files changed, 15 insertions(+) diff --git a/Fw/DataStructures/docs/ArraySetOrMapImpl.md b/Fw/DataStructures/docs/ArraySetOrMapImpl.md index 7a25a91a6ca..bffc1736927 100644 --- a/Fw/DataStructures/docs/ArraySetOrMapImpl.md +++ b/Fw/DataStructures/docs/ArraySetOrMapImpl.md @@ -33,6 +33,11 @@ The type `SetOrMapIterator` is defined [here](SetOrMapIterator.md). |`m_entries`|[`ExternalArray`](ExternalArray.md)|The array for storing the set or map entries|C++ default initialization| |`m_size`|`FwSizeType`|The number of entries in the map|0| +```mermaid +classDiagram + ArraySetOrMapImpl *-- ExternalArray +``` + ## 4. Public Constructors and Destructors ### 4.1. Zero-Argument Constructor diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index 54491b74e83..2e81b016be0 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -38,6 +38,10 @@ The type `SetOrMapIterator` is defined [here](SetOrMapIterator.md). |----|----|-------|-------------| |`m_mapImpl`|[`ArraySetOrMapImpl`](ArraySetOrMapImpl.md)|The array for storing the map entries|C++ default initialization| +```mermaid +classDiagram + ExternalArrayMap *-- ArraySetOrMapImpl +``` ## 5. Public Constructors and Destructors diff --git a/Fw/DataStructures/docs/SetOrMapIterator.md b/Fw/DataStructures/docs/SetOrMapIterator.md index 455785d9b82..354b586f73d 100644 --- a/Fw/DataStructures/docs/SetOrMapIterator.md +++ b/Fw/DataStructures/docs/SetOrMapIterator.md @@ -22,6 +22,12 @@ templates: 1. [`SetIterator`](SetIterator.md). +```mermaid +classDiagram + MapIterator <|-- SetOrMapIterator + SetIterator <|-- SetOrMapIterator +``` + ## 3. Private Member Variables `SetOrMapIterator` has the following private member variables. From b075bbd000b5f9adc498e35fe3bf0d0dfa888202 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 21:32:37 -0700 Subject: [PATCH 212/458] Revise SDD for ExternalArrayMap --- Fw/DataStructures/docs/ExternalArrayMap.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index 2e81b016be0..d24a9c4ff61 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -92,7 +92,7 @@ contain at least [`getByteArraySize(size)`](#72-getbytearraysize) bytes. _Example:_ ```c++ constexpr FwSizeType capacity = 10; -constexpr U8 alignment = ExternalArrayMap::getByteAlignment(); +constexpr U8 alignment = ExternalArrayMap::getByteArrayAlignment(); constexpr FwSizeType byteArraySize = ExternalArrayMap::getByteArraySize(capacity); alignas(alignment) U8 bytes[byteArraySize]; ExternalArrayMap map(ByteArray(&bytes[0], sizeof bytes), capacity); @@ -385,7 +385,7 @@ contain at least [`getByteArraySize(size)`](#72-getbytearraysize) bytes. ```c++ constexpr FwSizeType capacity = 10; -constexpr U8 alignment = ExternalArrayMap::getByteAlignment(); +constexpr U8 alignment = ExternalArrayMap::getByteArrayAlignment(); constexpr FwSizeType byteArraySize = ExternalArrayMap::getByteArraySize(capacity); alignas(alignment) U8 bytes[byteArraySize]; ExternalArrayMap map; From a726ee97923cdddc59f23cd35a24410bf78c13a2 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 22:13:20 -0700 Subject: [PATCH 213/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalArrayMap.md | 6 +- Fw/DataStructures/docs/ExternalArraySet.md | 408 ++++++++++++++++++++- Fw/DataStructures/docs/MapBase.md | 21 +- Fw/DataStructures/docs/SetBase.md | 143 ++++---- Fw/DataStructures/docs/SetIterator.md | 2 +- Fw/DataStructures/docs/sdd.md | 31 +- 6 files changed, 514 insertions(+), 97 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index d24a9c4ff61..5c5b6d9720c 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -3,8 +3,8 @@ `ExternalArrayMap` is a `final` class template defined in [`Fw/DataStructures`](sdd.md). It represents an array-based map with external storage. -Internally it maintains an [`ExternalArray`](ExternalArray.md) for -storing the entries in the map. +Internally it maintains an [`ArraySetOrMapImpl`](ArraySetOrMapImpl.md) +as the map implementation. ## 1. Template Parameters @@ -36,7 +36,7 @@ The type `SetOrMapIterator` is defined [here](SetOrMapIterator.md). |Name|Type|Purpose|Default Value| |----|----|-------|-------------| -|`m_mapImpl`|[`ArraySetOrMapImpl`](ArraySetOrMapImpl.md)|The array for storing the map entries|C++ default initialization| +|`m_mapImpl`|[`ArraySetOrMapImpl`](ArraySetOrMapImpl.md)|The map implementation|C++ default initialization| ```mermaid classDiagram diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md index 13dcfffe5d4..d7976b7601e 100644 --- a/Fw/DataStructures/docs/ExternalArraySet.md +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -1,4 +1,410 @@ # ExternalArraySet -TODO +`ExternalArraySet` is a `final` class template +defined in [`Fw/DataStructures`](sdd.md). +It represents an array-based set with external storage. +Internally it maintains an [`ArraySetOrSetImpl`](ArraySetOrSetImpl.md) +as the set implementation. +## 1. Template Parameters + +`ExternalArraySet` has the following template parameters. + +|Kind|Name|Purpose| +|----|----|-------| +|`typename`|`T`|The type of an element in the set| + +## 2. Base Class + +`ExternalArraySet` is publicly derived from +[`SetBase`](SetBase.md). + +## 3. Public Types + +`ExternalArraySet` defines the following public types: + +```c++ +using Entry = SetOrSetIterator +``` + +The type `SetOrMapIterator` is defined [here](SetOrSetIterator.md). + +## 4. Private Member Variables + +`ExternalArraySet` has the following private member variables. + +|Name|Type|Purpose|Default Value| +|----|----|-------|-------------| +|`m_setImpl`|[`ArraySetOrSetImpl`](ArraySetOrSetImpl.md)|The set implementation|C++ default initialization| + +```mermaid +classDiagram + ExternalArraySet *-- ArraySetOrSetImpl +``` + +## 5. Public Constructors and Destructors + +### 5.1. Zero-Argument Constructor + +```c++ +ExternalArraySet() +``` + +Initialize each member variable with its default value. + +_Example:_ +```c++ +ExternalArraySet set; +``` + +### 5.2. Constructor Providing Typed Backing Storage + +```c++ +ExternalArraySet(Entry* entries, FwSizeType capacity) +``` + +1. Call `m_setImpl.setStorage(entries, capacity)`. + +1. Initialize the other member variables with their default values. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +ExternalArraySet::Entry entries[capacity]; +ExternalArraySet set(entries, capacity); +``` + +### 5.3. Constructor Providing Untyped Backing Storage + +```c++ +ExternalArraySet(ByteArray data, FwSizeType capacity) +``` + +`data` must be aligned according to +[`getByteArrayAlignment()`](#71-getbytearrayalignment) and must +contain at least [`getByteArraySize(size)`](#72-getbytearraysize) bytes. + +1. Call `m_setImpl.setStorage(data, capacity)`. + +1. Initialize the other member variables with their default values. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +constexpr U8 alignment = ExternalArraySet::getByteArrayAlignment(); +constexpr FwSizeType byteArraySize = ExternalArraySet::getByteArraySize(capacity); +alignas(alignment) U8 bytes[byteArraySize]; +ExternalArraySet set(ByteArray(&bytes[0], sizeof bytes), capacity); +``` + +### 5.4. Copy Constructor + +```c++ +ExternalArraySet(const ExternalArraySet& set) +``` + +Set `*this = set`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 3; +ExternalArraySet::Entry entries[capacity]; +// Call the constructor providing backing storage +ExternalArraySet m1(entries, capacity); +// Insert an item +const U16 key = 0; +const U32 value = 42; +const auto status = m1.insert(key, value); +ASSERT_EQ(status, Success::SUCCESS); +// Call the copy constructor +ExternalArraySet m2(m1); +ASSERT_EQ(m2.getSize(), 1); +``` + +### 5.5. Destructor + +```c++ +~ExternalArraySet() override +``` + +Defined as `= default`. + +## 6. Public Member Functions + +### 6.1. operator= + +```c++ +ExternalArraySet& operator=(const ExternalArraySet& set) +``` + +1. If `&set != this` + + 1. Set `m_setImpl = set.m_setImpl`. + +1. Return `*this`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 3; +ExternalArraySet::Entry entries[capacity]; +// Call the constructor providing backing storage +ExternalArraySet m1(entries, capacity); +// Insert an item +U16 key = 0; +U32 value = 42; +const auto status = m1.insert(value); +ASSERT_EQ(status, Success::SUCCESS); +// Call the default constructor +ExternalArraySet m2; +ASSERT_EQ(m2.getSize(), 0); +// Call the copy assignment operator +m2 = m1; +ASSERT_EQ(m2.getSize(), 1); +``` + +### 6.2. at + +```c++ +const V& at(FwSizeType index) const +``` + +Return `m_setImpl[index]`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 3; +ExternalArraySet::Entry entries[capacity]; +ExternalArraySet set(entries, capacity); +const auto status = set.insert(0, 1); +ASSERT_EQ(status, Success::SUCCESS); +ASSERT_EQ(set.at(0), 1); +ASSERT_DEATH(set.at(1), "Assert"); +``` + +### 6.3. clear + +```c++ +void clear() override +``` + +Call `m_setImpl.clear()`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +ExternalArraySet::Entry entries[capacity]; +ExternalArraySet set(entries, capacity); +const auto status = set.enqueue(3); +ASSERT_EQ(set.getSize(), 1); +set.clear(); +ASSERT_EQ(set.getSize(), 0); +``` + +### 6.4. find + +```c++ +Success find(const K& key, V& value) override +``` + +1. Set `status = Success::FAILURE`. + +1. Set `iterator = m_setImpl.find(key)`. + +1. If `iterator != nullptr` + + 1. Set `value = iterator.getValue()`. + + 1. Set `status = Success::SUCCESS`. + +1. Return `status`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +ExternalArraySet::Entry entries[capacity]; +ExternalArraySet set(entries, capacity); +U32 value = 0; +auto status = set.find(0, value); +ASSERT_EQ(status, Success::FAILURE); +status = set.insert(0, 1); +ASSERT_EQ(status, Success::SUCCESS); +status = set.find(0, value); +ASSERT_EQ(status, Success::SUCCESS); +ASSERT_EQ(value, 1); +``` + +### 6.5. getCapacity + +```c++ +FwSizeType getCapacity() const override +``` + +Return `m_setImpl.getCapacity()`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +ExternalArraySet::Entry entries[capacity]; +ExternalArraySet set(entries, capacity); +ASSERT_EQ(set.getCapacity(), capacity); +``` + +### 6.6. getHeadIterator + +```c++ +const Iterator* getHeadIterator const override +``` + +The type `Iterator` is defined [in the base class](SetBase.md#2-publictypes). + +Return `m_impl.getHeadIterator()`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +ExternalArraySet::Entry entries[capacity]; +ExternalArraySet set(entries, capacity); +const auto* e = set.getHeadIterator(); +FW_ASSERT(e == nullptr); +set.insert(0, 1); +e = set.getHeadIterator(); +FW_ASSERT(e != nullptr); +ASSERT_EQ(e.getKey(), 0); +ASSERT_EQ(e.getValue(), 1); +``` + +### 6.7. getSize + +```c++ +FwSizeType getSize() const override +``` + +Return `m_setImpl.getSize()`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +ExternalArraySet::Entry entries[capacity]; +ExternalArraySet set(entries, capacity); +auto size = set.getSize(); +ASSERT_EQ(size, 0); +const auto status = set.enqueue(3); +ASSERT_EQ(status, Success::SUCCESS); +size = set.getSize(); +ASSERT_EQ(size, 1); +``` + +### 6.8. insert + +```c++ +Success insert(const K& key, const V& value) override +``` + +Return `m_setImpl.insert(key, value)`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +ExternalArraySet::Entry entries[capacity]; +ExternalArraySet set(entries, capacity); +auto size = set.getSize(); +ASSERT_EQ(size, 0); +const auto status = set.insert(0, 1); +ASSERT_EQ(status, Success::SUCCESS); +size = set.getSize(); +ASSERT_EQ(size, 1); +``` + +```c++ +Success insert(const Iterator& e) override +``` + +Call `insert(e.getKey(), e.getValue())`. + +### 6.9. remove + +```c++ +Success remove(const K& key, V& value) override +``` + +Return `m_setImpl.remove(key, value)`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +ExternalArraySet::Entry entries[capacity]; +ExternalArraySet set(entries, capacity); +auto size = set.getSize(); +ASSERT_EQ(size, 0); +auto status = set.insert(0, 1); +ASSERT_EQ(status, Success::SUCCESS); +size = set.getSize(); +ASSERT_EQ(size, 1); +// Key does not exist +U32 value = 0; +status = set.remove(10, value); +ASSERT_EQ(status, Success::FAILURE); +ASSERT_EQ(size, 1); +// Key exists +status = set.remove(0, value); +ASSERT_EQ(status, Success::SUCCESS); +ASSERT_EQ(size, 0); +ASSERT_EQ(value, 1); +``` + +### 6.10. setStorage (Typed Data) + +```c++ +void setStorage(Entry* entries, FwSizeType capacity) +``` + +1. Call `m_setImpl.setStorage(entries, capacity)`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +ExternalArraySet set; +ExternalArraySet::Entry entries[capacity]; +set.setStorage(entries, capacity); +``` + +### 6.11. setStorage (Untyped Data) + +```c++ +void setStorage(ByteArray data, FwSizeType capacity) +``` + +`data` must be aligned according to +[`getByteArrayAlignment()`](#71-getbytearrayalignment) and must +contain at least [`getByteArraySize(size)`](#72-getbytearraysize) bytes. + +1. Call `m_entries.setStorage(data, capacity)`. + +1. Call `clear()`. + +```c++ +constexpr FwSizeType capacity = 10; +constexpr U8 alignment = ExternalArraySet::getByteArrayAlignment(); +constexpr FwSizeType byteArraySize = ExternalArraySet::getByteArraySize(capacity); +alignas(alignment) U8 bytes[byteArraySize]; +ExternalArraySet set; +set.setStorage(ByteArray(&bytes[0], sizeof bytes), capacity); +``` + +## 7. Public Static Functions + +### 7.1. getByteArrayAlignment + +```c++ +static constexpr U8 getByteArrayAlignment() +``` + +Return `ExternalArray::getByteArrayAlignment()`. + +### 7.2. getByteArraySize + +```c++ +static constexpr FwSizeType getByteArraySize(FwSizeType capacity) +``` + +Return `ExternalArray::getByteArraySize(capacity)`. diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index 7d1ed72cb23..0c9de5e2d13 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -1,6 +1,6 @@ # MapBase -`MapBase` is a class template +`MapBase` is an abstract class template defined in [`Fw/DataStructures`](sdd.md). It represents an abstract base class for a map. @@ -83,7 +83,7 @@ void f(MapBase& map) { void copyDataFrom(const MapBase& map) ``` -1. If `&queue != this` then +1. If `&map != this` then 1. Call `clear()`. @@ -95,11 +95,11 @@ void copyDataFrom(const MapBase& map) 1. Assert `e != nullptr`. - 1. Set `e1 = insert(*e)`. + 1. Set `e1 = insert(e->getKey(), e->getValue())`. 1. Assert `status == Success::SUCCESS`. - 1. Set `e = e.getNextIterator()` + 1. Set `e = e->getNextMapIterator()` _Example:_ ```c++ @@ -166,19 +166,19 @@ void f(const MapBase& map) { const Iterator* getHeadIterator const = 0 ``` -Get the head entry of the map. +Get the head iterator for the map. _Example:_ ```c++ void f(const MapBase& map) { map.clear(); const auto* e = map.getHeadIterator(); - FW_ASSERT(e == nullptr); + ASSERT_EQ(e, nullptr); map.insert(0, 1); e = map.getHeadIterator(); - FW_ASSERT(e != nullptr); - ASSERT_EQ(e.getKey(), 0); - ASSERT_EQ(e.getValue(), 1); + ASSERT_EQ(e, nullptr); + ASSERT_EQ(e->getKey(), 0); + ASSERT_EQ(e->getValue(), 1); } ``` @@ -192,13 +192,12 @@ virtual FwSizeType getSize() const = 0 Return the current size. _Example:_ -See [**getCapacity**](MapBase.md#55-getCapacity). +See [**getCapacity**](MapBase.md#65-getcapacity). ### 6.7. insert ```c++ Success insert(const K& key, const V& value) = 0 -Success insert(const Iterator& e) = 0 ``` 1. If an entry `e` exists with the specified key, then update the diff --git a/Fw/DataStructures/docs/SetBase.md b/Fw/DataStructures/docs/SetBase.md index a8187ab4d52..16dbaaa3b47 100644 --- a/Fw/DataStructures/docs/SetBase.md +++ b/Fw/DataStructures/docs/SetBase.md @@ -1,6 +1,6 @@ # SetBase -`SetBase` is a class template +`SetBase` is an abstract class template defined in [`Fw/DataStructures`](sdd.md). It represents an abstract base class for a set. @@ -12,45 +12,35 @@ It represents an abstract base class for a set. |----|----|-------| |`typename`|`T`|The type of an element in the set| -## 2. Protected Types +## 2. Public Types -`SetBase` defines the following protected types: +`SetBase` defines the following public types: |Name|Definition| |----|----------| -|`Nil`|`struct Nil {}`| -|`MapImpl`|`MapBase`| -|`Entry`|`SetEntry`| +|`Iterator`|`SetIterator`| -## 3. Protected Member Variables +## 3. Private Constructors -`SetBase` has the following protected member variables. - -|Name|Type|Purpose|Default Value| -|----|----|-------|-------------| -|`m_mapImpl`|`MapImpl&`|The implementation of the set as a map| - -## 4. Protected Constructors and Destructors - -### 4.1. Constructor Providing the Map Implementation +### 3.1. Copy Constructor ```c++ -SetBase(MapImpl& mapImpl) +SetBase(const SetBase& set) ``` -Set `m_mapImpl = mapImpl`. +Defined as `= delete`. -## 5. Private Constructors and Destructors +## 4. Protected Constructors and Destructors -### 5.1. Copy Constructor +### 4.1. Zero-Argument Constructor ```c++ -SetBase(const SetBase& set) +SetBase() ``` -Defined as `= delete`. +Defined as `= default`. -### 5.2. Destructor +### 4.2. Destructor ```c++ virtual ~SetBase() @@ -58,9 +48,9 @@ virtual ~SetBase() Defined as `= default`. -## 6. Private Member Functions +## 5. Private Member Functions -### 6.1. operator= +### 5.1. operator= ```c++ SetBase& operator=(const SetBase&) @@ -68,15 +58,15 @@ SetBase& operator=(const SetBase&) Defined as `= delete`. -## 7. Public Member Functions +## 6. Public Member Functions -### 7.1. clear +### 6.1. clear ```c++ virtual void clear() = 0 ``` -Call `m_mapImpl.clear()`. +Call `m_setImpl.clear()`. _Example:_ ```c++ @@ -86,38 +76,56 @@ void f(SetBase& set) { } ``` -### 7.2. copyDataFrom +### 6.2. copyDataFrom ```c++ void copyDataFrom(const SetBase& set) ``` -Call `m_mapImpl.copyDataFrom(set.m_mapImpl)`. +1. If `&set != this` then + + 1. Call `clear()`. + + 1. Let `size` be the minimum of `set.getSize()` and `getCapacity()`. + + 1. Set `e = set.getHeadIterator()`. + + 1. For `i` in [0, `size`) + + 1. Assert `e != nullptr`. + + 1. Set `status = insert(e->getElement())`. + + 1. Assert `status == Success::SUCCESS`. + + 1. Set `e = e->getNextSetIterator()` + _Example:_ ```c++ -void f(SetBase& m1, SetBase& m2) { - m1.clear(); +void f(SetBase& s1, SetBase& s2) { + s1.clear(); // Insert an entry - const auto status = m1.insert(42); + const auto status = s1.insert(42); ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(m1.getSize(), 1); - m2.clear(); - ASSERT_EQ(m2.getSize(), 0); - m2.copyDataFrom(q1); - ASSERT_EQ(m2.getSize(), 1); + ASSERT_EQ(s1.getSize(), 1); + s2.clear(); + ASSERT_EQ(s2.getSize(), 0); + s2.copyDataFrom(q1); + ASSERT_EQ(s2.getSize(), 1); } ``` -### 7.3. find +### 6.3. find ```c++ Success find(const T& element) = 0 ``` -1. Let `Nil nil = {}`. +1. If an entry `e` with value `key` exists in the set, +then set `element = e.getElement()` and return `SUCCESS`. -1. Return `m_mapImpl.find(element, nil); +1. Otherwise return `FAILURE`. _Example:_ ```c++ @@ -129,16 +137,17 @@ void f(const SetBase& set) { ASSERT_EQ(status, Success::SUCCESS); status = set.find(42); ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(value, 1); } ``` -### 7.4. getCapacity +### 6.4. getCapacity ```c++ virtual FwSizeType getCapacity() const = 0 ``` -Return `m_mapImpl.getCapacity()`. +Return the current capacity. _Example:_ ```c++ @@ -149,29 +158,29 @@ void f(const SetBase& set) { } ``` -### 7.5. getHeadEntry +### 6.5. getHeadIterator ```c++ -const Entry* getHeadEntry const = 0 +const Iterator* getHeadIterator const = 0 ``` -Return `m_mapImpl.getHeadEntry()`. +Get the head iterator for the set. _Example:_ ```c++ void f(const SetBase& set) { set.clear(); - const auto* e = set.getHeadEntry(); - FW_ASSERT(e == nullptr); + const auto* e = set.getHeadIterator(); + ASSERT_EQ(e, nullptr); set.insert(42); - e = set.getHeadEntry(); - FW_ASSERT(e != nullptr); - ASSERT_EQ(e.getElement(), 42); + e = set.getHeadIterator(); + ASSERT_NE(e, nullptr); + ASSERT_EQ(e->getElement(), 42); } ``` -### 7.6. getSize +### 6.6. getSize ```c++ virtual FwSizeType getSize() const = 0 @@ -180,26 +189,24 @@ virtual FwSizeType getSize() const = 0 Return the current size. _Example:_ -See [**getCapacity**](SetBase.md#55-getCapacity). +See [**getCapacity**](SetBase.md#65-getcapacity). -### 7.7. insert +### 6.7. insert ```c++ -Success insert(const K& key, const V& value) = 0 -Success insert(const Entry& e) = 0 +Success insert(const T& element) = 0 ``` -1. If an entry `e` exists with the specified key, then update the - value in `e` and return `SUCCESS`. +1. If an entry `e` exists with the specified element, then return `SUCCESS`. 1. Otherwise if there is room in the set, then add a new entry `e` with the -specified key-value pair and return `SUCCESS`. + specified element and return `SUCCESS`. 1. Otherwise return `FAILURE`. _Example:_ ```c++ -void f(SetBase& set) { +void f(SetBase& set) { set.clear(); auto size = set.getSize(); ASSERT_EQ(size, 0); @@ -210,14 +217,13 @@ void f(SetBase& set) { } ``` -### 7.8. remove +### 6.8. remove ```c++ -Success remove(const K& key, V& value) = 0 +Success remove(const T& element) = 0 ``` 1. If an entry `e` exists with key `key`, then -store the value of `e` into `value`, remove `e` from the set, and return `SUCCESS`. 1. Otherwise return `FAILURE`. @@ -228,20 +234,17 @@ void f(SetBase& set) { set.clear(); auto size = set.getSize(); ASSERT_EQ(size, 0); - auto status = set.insert(0, 1); + auto status = set.insert(0); ASSERT_EQ(status, Success::SUCCESS); size = set.getSize(); ASSERT_EQ(size, 1); - // Key does not exist - U32 value = 0; - status = set.remove(10, value); + // Element does not exist + status = set.remove(42); ASSERT_EQ(status, Success::FAILURE); ASSERT_EQ(size, 1); // Key exists - status = set.remove(0, value); + status = set.remove(0); ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(size, 0); - ASSERT_EQ(value, 1); } ``` - diff --git a/Fw/DataStructures/docs/SetIterator.md b/Fw/DataStructures/docs/SetIterator.md index 50e17eaa04c..60a64910d54 100644 --- a/Fw/DataStructures/docs/SetIterator.md +++ b/Fw/DataStructures/docs/SetIterator.md @@ -1,6 +1,6 @@ # SetIterator -`SetIterator` is a class template +`SetIterator` is an abstract class template defined in [`Fw/DataStructures`](sdd.md). It represents an iterator for a set. diff --git a/Fw/DataStructures/docs/sdd.md b/Fw/DataStructures/docs/sdd.md index b54bf63b4a4..ee9fa318944 100644 --- a/Fw/DataStructures/docs/sdd.md +++ b/Fw/DataStructures/docs/sdd.md @@ -18,8 +18,8 @@ and _C_. The data structures in this directory are **sequential data structures**, i.e., they do not support direct concurrent access by multiple threads. -To use these data structures in a multithreaded context, you have -to guard the access separately. +To use these data structures in a multithreaded context, you need +to provide separate concurrency control. The most common way to do this is to make the data structure a member of an active or queued component and to use the component queue to guard the access to the structure. @@ -86,10 +86,6 @@ It provides insert, remove, and find operations. |[`MapBase`](MapBase.md)|The abstract base class for a map| |[`RedBlackTreeMap`](RedBlackTreeMap.md)|A red-black tree with internal memory for storing the tree| -The queue implementations use a template called -[`MapEntry`](MapEntry.md) for representing -an entry in the map. - ### 3.2. Class Diagram ```mermaid @@ -102,12 +98,25 @@ classDiagram ## 4. Sets -* [`SetBase`](SetBase.md) +A **set** is a data structure that contains elements. +It provides insert, remove, and find operations. -* [`ExternalArraySet`](ExternalArraySet.md) +### 4.1. Templates -* [`ArraySet`](ArraySet.md) +|Name|Description| +|----|-----------| +|[`ArraySet`](ArraySet.md)|An array-based set with internal memory for storing the array| +|[`ExternalArraySet`](ExternalArraySet.md)|An array-based set with external memory for storing the array| +|[`ExternalRedBlackTreeSet`](ExternalRedBlackTreeSet.md)|A red-black tree with external memory for storing the tree| +|[`RedBlackTreeSet`](RedBlackTreeSet.md)|A red-black tree with internal memory for storing the tree| +|[`SetBase`](SetBase.md)|The abstract base class for a set| -* [`ExternalRedBlackTreeSet`](ExternalRedBlackTreeSet.md) +### 4.2. Class Diagram -* [`RedBlackTreeSet`](RedBlackTreeSet.md) +```mermaid +classDiagram + SetBase <|-- ArraySet + SetBase <|-- ExternalArraySet + SetBase <|-- ExternalRedBlackTreeSet + SetBase <|-- RedBlackTreeSet +``` From 8804cb5dd4fbaee41211c9434e551cfefdb07293 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 22:19:25 -0700 Subject: [PATCH 214/458] Revise SDD for SetBase --- Fw/DataStructures/docs/SetBase.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/docs/SetBase.md b/Fw/DataStructures/docs/SetBase.md index 16dbaaa3b47..53200eb6461 100644 --- a/Fw/DataStructures/docs/SetBase.md +++ b/Fw/DataStructures/docs/SetBase.md @@ -122,7 +122,7 @@ void f(SetBase& s1, SetBase& s2) { Success find(const T& element) = 0 ``` -1. If an entry `e` with value `key` exists in the set, +1. If an entry `e` with element `element` exists in the set, then set `element = e.getElement()` and return `SUCCESS`. 1. Otherwise return `FAILURE`. @@ -223,7 +223,7 @@ void f(SetBase& set) { Success remove(const T& element) = 0 ``` -1. If an entry `e` exists with key `key`, then +1. If an entry `e` exists with element `element`, then remove `e` from the set, and return `SUCCESS`. 1. Otherwise return `FAILURE`. From b07ac0100a1d43bae1f7c6fa0773a426390aff52 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 22:20:24 -0700 Subject: [PATCH 215/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/MapBase.md | 2 +- Fw/DataStructures/docs/SetBase.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index 0c9de5e2d13..fe0dc334d2e 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -19,7 +19,7 @@ It represents an abstract base class for a map. |Name|Definition| |----|----------| -|`Iterator`|`MapIterator`| +|`Iterator`|[`MapIterator`](MapIterator.md)| ## 3. Private Constructors diff --git a/Fw/DataStructures/docs/SetBase.md b/Fw/DataStructures/docs/SetBase.md index 53200eb6461..66c69d941c4 100644 --- a/Fw/DataStructures/docs/SetBase.md +++ b/Fw/DataStructures/docs/SetBase.md @@ -18,7 +18,7 @@ It represents an abstract base class for a set. |Name|Definition| |----|----------| -|`Iterator`|`SetIterator`| +|`Iterator`|[`SetIterator`](SetIterator.md)| ## 3. Private Constructors From 55a57bd77483f819d3f57807bc9b97654c43dad5 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 22:23:08 -0700 Subject: [PATCH 216/458] Revise SDD for ExternalArraySet --- Fw/DataStructures/docs/ExternalArraySet.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md index d7976b7601e..f82b9e044c9 100644 --- a/Fw/DataStructures/docs/ExternalArraySet.md +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -3,7 +3,7 @@ `ExternalArraySet` is a `final` class template defined in [`Fw/DataStructures`](sdd.md). It represents an array-based set with external storage. -Internally it maintains an [`ArraySetOrSetImpl`](ArraySetOrSetImpl.md) +Internally it maintains an [`ArraySetOrMapImpl`](ArraySetOrMapImpl.md) as the set implementation. ## 1. Template Parameters @@ -24,10 +24,10 @@ as the set implementation. `ExternalArraySet` defines the following public types: ```c++ -using Entry = SetOrSetIterator +using Entry = SetOrMapIterator ``` -The type `SetOrMapIterator` is defined [here](SetOrSetIterator.md). +The type `SetOrMapIterator` is defined [here](SetOrMapIterator.md). ## 4. Private Member Variables @@ -35,11 +35,11 @@ The type `SetOrMapIterator` is defined [here](SetOrSetIterator.md). |Name|Type|Purpose|Default Value| |----|----|-------|-------------| -|`m_setImpl`|[`ArraySetOrSetImpl`](ArraySetOrSetImpl.md)|The set implementation|C++ default initialization| +|`m_setImpl`|[`ArraySetOrMapImpl`](ArraySetOrMapImpl.md)|The set implementation|C++ default initialization| ```mermaid classDiagram - ExternalArraySet *-- ArraySetOrSetImpl + ExternalArraySet *-- ArraySetOrMapImpl ``` ## 5. Public Constructors and Destructors From 7d94d81a278b15df58f533056fb71461859c4d91 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 22:45:02 -0700 Subject: [PATCH 217/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalArrayMap.md | 92 ++++----- Fw/DataStructures/docs/ExternalArraySet.md | 219 +++++++++------------ Fw/DataStructures/docs/MapBase.md | 2 + Fw/DataStructures/docs/SetBase.md | 2 + 4 files changed, 133 insertions(+), 182 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index 5c5b6d9720c..8ee8779de5c 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -20,17 +20,7 @@ as the map implementation. `ExternalArrayMap` is publicly derived from [`MapBase`](MapBase.md). -## 3. Public Types - -`ExternalArrayMap` defines the following public types: - -```c++ -using Entry = SetOrMapIterator -``` - -The type `SetOrMapIterator` is defined [here](SetOrMapIterator.md). - -## 4. Private Member Variables +## 3. Private Member Variables `ExternalArrayMap` has the following private member variables. @@ -38,14 +28,16 @@ The type `SetOrMapIterator` is defined [here](SetOrMapIterator.md). |----|----|-------|-------------| |`m_mapImpl`|[`ArraySetOrMapImpl`](ArraySetOrMapImpl.md)|The map implementation|C++ default initialization| +The type `Entry` is defined [in the base class](MapBase.md#2-publictypes). + ```mermaid classDiagram ExternalArrayMap *-- ArraySetOrMapImpl ``` -## 5. Public Constructors and Destructors +## 4. Public Constructors and Destructors -### 5.1. Zero-Argument Constructor +### 4.1. Zero-Argument Constructor ```c++ ExternalArrayMap() @@ -58,15 +50,13 @@ _Example:_ ExternalArrayMap map; ``` -### 5.2. Constructor Providing Typed Backing Storage +### 4.2. Constructor Providing Typed Backing Storage ```c++ ExternalArrayMap(Entry* entries, FwSizeType capacity) ``` -1. Call `m_mapImpl.setStorage(entries, capacity)`. - -1. Initialize the other member variables with their default values. +Call `m_mapImpl.setStorage(entries, capacity)`. _Example:_ ```c++ @@ -75,19 +65,17 @@ ExternalArrayMap::Entry entries[capacity]; ExternalArrayMap map(entries, capacity); ``` -### 5.3. Constructor Providing Untyped Backing Storage +### 4.3. Constructor Providing Untyped Backing Storage ```c++ ExternalArrayMap(ByteArray data, FwSizeType capacity) ``` `data` must be aligned according to -[`getByteArrayAlignment()`](#71-getbytearrayalignment) and must -contain at least [`getByteArraySize(size)`](#72-getbytearraysize) bytes. - -1. Call `m_mapImpl.setStorage(data, capacity)`. +[`getByteArrayAlignment()`](#61-getbytearrayalignment) and must +contain at least [`getByteArraySize(size)`](#62-getbytearraysize) bytes. -1. Initialize the other member variables with their default values. +Call `m_mapImpl.setStorage(data, capacity)`. _Example:_ ```c++ @@ -98,7 +86,7 @@ alignas(alignment) U8 bytes[byteArraySize]; ExternalArrayMap map(ByteArray(&bytes[0], sizeof bytes), capacity); ``` -### 5.4. Copy Constructor +### 4.4. Copy Constructor ```c++ ExternalArrayMap(const ExternalArrayMap& map) @@ -122,7 +110,7 @@ ExternalArrayMap m2(m1); ASSERT_EQ(m2.getSize(), 1); ``` -### 5.5. Destructor +### 4.5. Destructor ```c++ ~ExternalArrayMap() override @@ -130,9 +118,9 @@ ASSERT_EQ(m2.getSize(), 1); Defined as `= default`. -## 6. Public Member Functions +## 5. Public Member Functions -### 6.1. operator= +### 5.1. operator= ```c++ ExternalArrayMap& operator=(const ExternalArrayMap& map) @@ -163,7 +151,7 @@ m2 = m1; ASSERT_EQ(m2.getSize(), 1); ``` -### 6.2. at +### 5.2. at ```c++ const V& at(FwSizeType index) const @@ -182,7 +170,7 @@ ASSERT_EQ(map.at(0), 1); ASSERT_DEATH(map.at(1), "Assert"); ``` -### 6.3. clear +### 5.3. clear ```c++ void clear() override @@ -195,13 +183,13 @@ _Example:_ constexpr FwSizeType capacity = 10; ExternalArrayMap::Entry entries[capacity]; ExternalArrayMap map(entries, capacity); -const auto status = map.enqueue(3); +const auto status = map.insert(0, 3); ASSERT_EQ(map.getSize(), 1); map.clear(); ASSERT_EQ(map.getSize(), 0); ``` -### 6.4. find +### 5.4. find ```c++ Success find(const K& key, V& value) override @@ -234,7 +222,7 @@ ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(value, 1); ``` -### 6.5. getCapacity +### 5.5. getCapacity ```c++ FwSizeType getCapacity() const override @@ -250,7 +238,7 @@ ExternalArrayMap map(entries, capacity); ASSERT_EQ(map.getCapacity(), capacity); ``` -### 6.6. getHeadIterator +### 5.6. getHeadIterator ```c++ const Iterator* getHeadIterator const override @@ -270,11 +258,11 @@ FW_ASSERT(e == nullptr); map.insert(0, 1); e = map.getHeadIterator(); FW_ASSERT(e != nullptr); -ASSERT_EQ(e.getKey(), 0); -ASSERT_EQ(e.getValue(), 1); +ASSERT_EQ(e->getKey(), 0); +ASSERT_EQ(e->getValue(), 1); ``` -### 6.7. getSize +### 5.7. getSize ```c++ FwSizeType getSize() const override @@ -289,13 +277,13 @@ ExternalArrayMap::Entry entries[capacity]; ExternalArrayMap map(entries, capacity); auto size = map.getSize(); ASSERT_EQ(size, 0); -const auto status = map.enqueue(3); +const auto status = map.insert(0, 3); ASSERT_EQ(status, Success::SUCCESS); size = map.getSize(); ASSERT_EQ(size, 1); ``` -### 6.8. insert +### 5.8. insert ```c++ Success insert(const K& key, const V& value) override @@ -316,13 +304,7 @@ size = map.getSize(); ASSERT_EQ(size, 1); ``` -```c++ -Success insert(const Iterator& e) override -``` - -Call `insert(e.getKey(), e.getValue())`. - -### 6.9. remove +### 5.9. remove ```c++ Success remove(const K& key, V& value) override @@ -353,13 +335,13 @@ ASSERT_EQ(size, 0); ASSERT_EQ(value, 1); ``` -### 6.10. setStorage (Typed Data) +### 5.10. setStorage (Typed Data) ```c++ void setStorage(Entry* entries, FwSizeType capacity) ``` -1. Call `m_mapImpl.setStorage(entries, capacity)`. +Call `m_mapImpl.setStorage(entries, capacity)`. _Example:_ ```c++ @@ -369,15 +351,15 @@ ExternalArrayMap::Entry entries[capacity]; map.setStorage(entries, capacity); ``` -### 6.11. setStorage (Untyped Data) +### 5.11. setStorage (Untyped Data) ```c++ void setStorage(ByteArray data, FwSizeType capacity) ``` `data` must be aligned according to -[`getByteArrayAlignment()`](#71-getbytearrayalignment) and must -contain at least [`getByteArraySize(size)`](#72-getbytearraysize) bytes. +[`getByteArrayAlignment()`](#61-getbytearrayalignment) and must +contain at least [`getByteArraySize(size)`](#62-getbytearraysize) bytes. 1. Call `m_entries.setStorage(data, capacity)`. @@ -392,20 +374,20 @@ ExternalArrayMap map; map.setStorage(ByteArray(&bytes[0], sizeof bytes), capacity); ``` -## 7. Public Static Functions +## 6. Public Static Functions -### 7.1. getByteArrayAlignment +### 6.1. getByteArrayAlignment ```c++ static constexpr U8 getByteArrayAlignment() ``` -Return `ExternalArray::getByteArrayAlignment()`. +Return `ArraySetOrMapImpl::getByteArrayAlignment()`. -### 7.2. getByteArraySize +### 6.2. getByteArraySize ```c++ static constexpr FwSizeType getByteArraySize(FwSizeType capacity) ``` -Return `ExternalArray::getByteArraySize(capacity)`. +Return `ArraySetOrMapImpl::getByteArraySize(capacity)`. diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md index f82b9e044c9..2b844823421 100644 --- a/Fw/DataStructures/docs/ExternalArraySet.md +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -19,17 +19,7 @@ as the set implementation. `ExternalArraySet` is publicly derived from [`SetBase`](SetBase.md). -## 3. Public Types - -`ExternalArraySet` defines the following public types: - -```c++ -using Entry = SetOrMapIterator -``` - -The type `SetOrMapIterator` is defined [here](SetOrMapIterator.md). - -## 4. Private Member Variables +## 3. Private Member Variables `ExternalArraySet` has the following private member variables. @@ -37,14 +27,16 @@ The type `SetOrMapIterator` is defined [here](SetOrMapIterator.md). |----|----|-------|-------------| |`m_setImpl`|[`ArraySetOrMapImpl`](ArraySetOrMapImpl.md)|The set implementation|C++ default initialization| +The type `Entry` is defined [in the base class](MapBase.md#2-publictypes). + ```mermaid classDiagram ExternalArraySet *-- ArraySetOrMapImpl ``` -## 5. Public Constructors and Destructors +## 4. Public Constructors and Destructors -### 5.1. Zero-Argument Constructor +### 4.1. Zero-Argument Constructor ```c++ ExternalArraySet() @@ -54,53 +46,49 @@ Initialize each member variable with its default value. _Example:_ ```c++ -ExternalArraySet set; +ExternalArraySet set; ``` -### 5.2. Constructor Providing Typed Backing Storage +### 4.2. Constructor Providing Typed Backing Storage ```c++ ExternalArraySet(Entry* entries, FwSizeType capacity) ``` -1. Call `m_setImpl.setStorage(entries, capacity)`. - -1. Initialize the other member variables with their default values. +Call `m_setImpl.setStorage(entries, capacity)`. _Example:_ ```c++ constexpr FwSizeType capacity = 10; -ExternalArraySet::Entry entries[capacity]; -ExternalArraySet set(entries, capacity); +ExternalArraySet::Entry entries[capacity]; +ExternalArraySet set(entries, capacity); ``` -### 5.3. Constructor Providing Untyped Backing Storage +### 4.3. Constructor Providing Untyped Backing Storage ```c++ ExternalArraySet(ByteArray data, FwSizeType capacity) ``` `data` must be aligned according to -[`getByteArrayAlignment()`](#71-getbytearrayalignment) and must -contain at least [`getByteArraySize(size)`](#72-getbytearraysize) bytes. +[`getByteArrayAlignment()`](#61-getbytearrayalignment) and must +contain at least [`getByteArraySize(size)`](#62-getbytearraysize) bytes. -1. Call `m_setImpl.setStorage(data, capacity)`. - -1. Initialize the other member variables with their default values. +Call `m_setImpl.setStorage(data, capacity)`. _Example:_ ```c++ constexpr FwSizeType capacity = 10; -constexpr U8 alignment = ExternalArraySet::getByteArrayAlignment(); -constexpr FwSizeType byteArraySize = ExternalArraySet::getByteArraySize(capacity); +constexpr U8 alignment = ExternalArraySet::getByteArrayAlignment(); +constexpr FwSizeType byteArraySize = ExternalArraySet::getByteArraySize(capacity); alignas(alignment) U8 bytes[byteArraySize]; -ExternalArraySet set(ByteArray(&bytes[0], sizeof bytes), capacity); +ExternalArraySet set(ByteArray(&bytes[0], sizeof bytes), capacity); ``` -### 5.4. Copy Constructor +### 4.4. Copy Constructor ```c++ -ExternalArraySet(const ExternalArraySet& set) +ExternalArraySet(const ExternalArraySet& set) ``` Set `*this = set`. @@ -108,20 +96,18 @@ Set `*this = set`. _Example:_ ```c++ constexpr FwSizeType capacity = 3; -ExternalArraySet::Entry entries[capacity]; +ExternalArraySet::Entry entries[capacity]; // Call the constructor providing backing storage -ExternalArraySet m1(entries, capacity); +ExternalArraySet m1(entries, capacity); // Insert an item -const U16 key = 0; -const U32 value = 42; -const auto status = m1.insert(key, value); +const auto status = m1.insert(42); ASSERT_EQ(status, Success::SUCCESS); // Call the copy constructor -ExternalArraySet m2(m1); +ExternalArraySet m2(m1); ASSERT_EQ(m2.getSize(), 1); ``` -### 5.5. Destructor +### 4.5. Destructor ```c++ ~ExternalArraySet() override @@ -129,12 +115,12 @@ ASSERT_EQ(m2.getSize(), 1); Defined as `= default`. -## 6. Public Member Functions +## 5. Public Member Functions -### 6.1. operator= +### 5.1. operator= ```c++ -ExternalArraySet& operator=(const ExternalArraySet& set) +ExternalArraySet& operator=(const ExternalArraySet& set) ``` 1. If `&set != this` @@ -146,13 +132,11 @@ ExternalArraySet& operator=(const ExternalArraySet& set) _Example:_ ```c++ constexpr FwSizeType capacity = 3; -ExternalArraySet::Entry entries[capacity]; +ExternalArraySet::Entry entries[capacity]; // Call the constructor providing backing storage -ExternalArraySet m1(entries, capacity); +ExternalArraySet m1(entries, capacity); // Insert an item -U16 key = 0; -U32 value = 42; -const auto status = m1.insert(value); +const auto status = m1.insert(42); ASSERT_EQ(status, Success::SUCCESS); // Call the default constructor ExternalArraySet m2; @@ -162,7 +146,7 @@ m2 = m1; ASSERT_EQ(m2.getSize(), 1); ``` -### 6.2. at +### 5.2. at ```c++ const V& at(FwSizeType index) const @@ -173,15 +157,15 @@ Return `m_setImpl[index]`. _Example:_ ```c++ constexpr FwSizeType capacity = 3; -ExternalArraySet::Entry entries[capacity]; -ExternalArraySet set(entries, capacity); -const auto status = set.insert(0, 1); +ExternalArraySet::Entry entries[capacity]; +ExternalArraySet set(entries, capacity); +const auto status = set.insert(42); ASSERT_EQ(status, Success::SUCCESS); -ASSERT_EQ(set.at(0), 1); +ASSERT_EQ(set.at(0), 42); ASSERT_DEATH(set.at(1), "Assert"); ``` -### 6.3. clear +### 5.3. clear ```c++ void clear() override @@ -192,48 +176,36 @@ Call `m_setImpl.clear()`. _Example:_ ```c++ constexpr FwSizeType capacity = 10; -ExternalArraySet::Entry entries[capacity]; -ExternalArraySet set(entries, capacity); -const auto status = set.enqueue(3); +ExternalArraySet::Entry entries[capacity]; +ExternalArraySet set(entries, capacity); +const auto status = set.insert(42); ASSERT_EQ(set.getSize(), 1); set.clear(); ASSERT_EQ(set.getSize(), 0); ``` -### 6.4. find +### 5.4. find ```c++ -Success find(const K& key, V& value) override +Success find(const T& element) override ``` -1. Set `status = Success::FAILURE`. - -1. Set `iterator = m_setImpl.find(key)`. - -1. If `iterator != nullptr` - - 1. Set `value = iterator.getValue()`. - - 1. Set `status = Success::SUCCESS`. - -1. Return `status`. +1. Return `m_setImpl.find(element, Nil())`. _Example:_ ```c++ constexpr FwSizeType capacity = 10; -ExternalArraySet::Entry entries[capacity]; -ExternalArraySet set(entries, capacity); -U32 value = 0; -auto status = set.find(0, value); +ExternalArraySet::Entry entries[capacity]; +ExternalArraySet set(entries, capacity); +auto status = set.find(42); ASSERT_EQ(status, Success::FAILURE); -status = set.insert(0, 1); +status = set.insert(42); ASSERT_EQ(status, Success::SUCCESS); -status = set.find(0, value); +status = set.find(42); ASSERT_EQ(status, Success::SUCCESS); -ASSERT_EQ(value, 1); ``` -### 6.5. getCapacity +### 5.5. getCapacity ```c++ FwSizeType getCapacity() const override @@ -244,12 +216,12 @@ Return `m_setImpl.getCapacity()`. _Example:_ ```c++ constexpr FwSizeType capacity = 10; -ExternalArraySet::Entry entries[capacity]; -ExternalArraySet set(entries, capacity); +ExternalArraySet::Entry entries[capacity]; +ExternalArraySet set(entries, capacity); ASSERT_EQ(set.getCapacity(), capacity); ``` -### 6.6. getHeadIterator +### 5.6. getHeadIterator ```c++ const Iterator* getHeadIterator const override @@ -262,18 +234,17 @@ Return `m_impl.getHeadIterator()`. _Example:_ ```c++ constexpr FwSizeType capacity = 10; -ExternalArraySet::Entry entries[capacity]; -ExternalArraySet set(entries, capacity); +ExternalArraySet::Entry entries[capacity]; +ExternalArraySet set(entries, capacity); const auto* e = set.getHeadIterator(); FW_ASSERT(e == nullptr); -set.insert(0, 1); +set.insert(42); e = set.getHeadIterator(); FW_ASSERT(e != nullptr); -ASSERT_EQ(e.getKey(), 0); -ASSERT_EQ(e.getValue(), 1); +ASSERT_EQ(e->getElement(), 42); ``` -### 6.7. getSize +### 5.7. getSize ```c++ FwSizeType getSize() const override @@ -284,99 +255,93 @@ Return `m_setImpl.getSize()`. _Example:_ ```c++ constexpr FwSizeType capacity = 10; -ExternalArraySet::Entry entries[capacity]; -ExternalArraySet set(entries, capacity); +ExternalArraySet::Entry entries[capacity]; +ExternalArraySet set(entries, capacity); auto size = set.getSize(); ASSERT_EQ(size, 0); -const auto status = set.enqueue(3); +const auto status = set.insert(42); ASSERT_EQ(status, Success::SUCCESS); size = set.getSize(); ASSERT_EQ(size, 1); ``` -### 6.8. insert +### 5.8. insert ```c++ -Success insert(const K& key, const V& value) override +Success insert(const T& element) override ``` -Return `m_setImpl.insert(key, value)`. +Return `m_setImpl.insert(key, Nil())`. _Example:_ ```c++ constexpr FwSizeType capacity = 10; -ExternalArraySet::Entry entries[capacity]; -ExternalArraySet set(entries, capacity); +ExternalArraySet::Entry entries[capacity]; +ExternalArraySet set(entries, capacity); auto size = set.getSize(); ASSERT_EQ(size, 0); -const auto status = set.insert(0, 1); +const auto status = set.insert(42); ASSERT_EQ(status, Success::SUCCESS); size = set.getSize(); ASSERT_EQ(size, 1); ``` -```c++ -Success insert(const Iterator& e) override -``` - -Call `insert(e.getKey(), e.getValue())`. - -### 6.9. remove +### 5.9. remove ```c++ -Success remove(const K& key, V& value) override +Success remove(const T& element) override ``` -Return `m_setImpl.remove(key, value)`. +1. Set `Nil nil = {}`. + +1. Return `m_setImpl.remove(key, nil)`. _Example:_ ```c++ constexpr FwSizeType capacity = 10; -ExternalArraySet::Entry entries[capacity]; -ExternalArraySet set(entries, capacity); +ExternalArraySet::Entry entries[capacity]; +ExternalArraySet set(entries, capacity); auto size = set.getSize(); ASSERT_EQ(size, 0); -auto status = set.insert(0, 1); +auto status = set.insert(42); ASSERT_EQ(status, Success::SUCCESS); size = set.getSize(); ASSERT_EQ(size, 1); -// Key does not exist -U32 value = 0; -status = set.remove(10, value); +// Element does not exist +status = set.remove(0); ASSERT_EQ(status, Success::FAILURE); ASSERT_EQ(size, 1); -// Key exists -status = set.remove(0, value); +// Element exists +status = set.remove(42, value); ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(size, 0); -ASSERT_EQ(value, 1); ``` -### 6.10. setStorage (Typed Data) +### 5.10. setStorage (Typed Data) ```c++ void setStorage(Entry* entries, FwSizeType capacity) ``` -1. Call `m_setImpl.setStorage(entries, capacity)`. +Call `m_setImpl.setStorage(entries, capacity)`. _Example:_ ```c++ constexpr FwSizeType capacity = 10; -ExternalArraySet set; -ExternalArraySet::Entry entries[capacity]; +ExternalArraySet set; +ExternalArraySet::Entry entries[capacity]; set.setStorage(entries, capacity); ``` -### 6.11. setStorage (Untyped Data) +### 5.11. setStorage (Untyped Data) ```c++ void setStorage(ByteArray data, FwSizeType capacity) ``` `data` must be aligned according to -[`getByteArrayAlignment()`](#71-getbytearrayalignment) and must -contain at least [`getByteArraySize(size)`](#72-getbytearraysize) bytes. +[`getByteArrayAlignment()`](#61-getbytearrayalignment) and must +contain at least [`getByteArraySize(size)`](#62-getbytearraysize) bytes. 1. Call `m_entries.setStorage(data, capacity)`. @@ -384,27 +349,27 @@ contain at least [`getByteArraySize(size)`](#72-getbytearraysize) bytes. ```c++ constexpr FwSizeType capacity = 10; -constexpr U8 alignment = ExternalArraySet::getByteArrayAlignment(); -constexpr FwSizeType byteArraySize = ExternalArraySet::getByteArraySize(capacity); +constexpr U8 alignment = ExternalArraySet::getByteArrayAlignment(); +constexpr FwSizeType byteArraySize = ExternalArraySet::getByteArraySize(capacity); alignas(alignment) U8 bytes[byteArraySize]; -ExternalArraySet set; +ExternalArraySet set; set.setStorage(ByteArray(&bytes[0], sizeof bytes), capacity); ``` -## 7. Public Static Functions +## 6. Public Static Functions -### 7.1. getByteArrayAlignment +### 6.1. getByteArrayAlignment ```c++ static constexpr U8 getByteArrayAlignment() ``` -Return `ExternalArray::getByteArrayAlignment()`. +Return `ArraySetOrMapImpl::getByteArrayAlignment()`. -### 7.2. getByteArraySize +### 6.2. getByteArraySize ```c++ static constexpr FwSizeType getByteArraySize(FwSizeType capacity) ``` -Return `ExternalArray::getByteArraySize(capacity)`. +Return `ArraySetOrMapImpl::getByteArraySize(capacity)`. diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index fe0dc334d2e..8b9c11103a6 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -20,6 +20,8 @@ It represents an abstract base class for a map. |Name|Definition| |----|----------| |`Iterator`|[`MapIterator`](MapIterator.md)| +|`Entry`|Alias of [`SetOrMapIterator`(SetOrMapIterator.md)| + ## 3. Private Constructors diff --git a/Fw/DataStructures/docs/SetBase.md b/Fw/DataStructures/docs/SetBase.md index 66c69d941c4..015654332c7 100644 --- a/Fw/DataStructures/docs/SetBase.md +++ b/Fw/DataStructures/docs/SetBase.md @@ -18,7 +18,9 @@ It represents an abstract base class for a set. |Name|Definition| |----|----------| +|`Entry`|Alias of [`SetOrMapIterator`(SetOrMapIterator.md)| |`Iterator`|[`SetIterator`](SetIterator.md)| +|`Nil`|`struct Nil {}`| ## 3. Private Constructors From efae88064b2820d19be56ada70912f321dbc9a32 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 22:45:51 -0700 Subject: [PATCH 218/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/MapBase.md | 2 +- Fw/DataStructures/docs/SetBase.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index 8b9c11103a6..f7f1275c91b 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -20,7 +20,7 @@ It represents an abstract base class for a map. |Name|Definition| |----|----------| |`Iterator`|[`MapIterator`](MapIterator.md)| -|`Entry`|Alias of [`SetOrMapIterator`(SetOrMapIterator.md)| +|`Entry`|Alias of [`SetOrMapIterator`](SetOrMapIterator.md)| ## 3. Private Constructors diff --git a/Fw/DataStructures/docs/SetBase.md b/Fw/DataStructures/docs/SetBase.md index 015654332c7..09272318fca 100644 --- a/Fw/DataStructures/docs/SetBase.md +++ b/Fw/DataStructures/docs/SetBase.md @@ -18,7 +18,7 @@ It represents an abstract base class for a set. |Name|Definition| |----|----------| -|`Entry`|Alias of [`SetOrMapIterator`(SetOrMapIterator.md)| +|`Entry`|Alias of [`SetOrMapIterator`](SetOrMapIterator.md)| |`Iterator`|[`SetIterator`](SetIterator.md)| |`Nil`|`struct Nil {}`| From d57a2780a04d003a31a363a50b3aee28ef9ba1f9 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 22:50:48 -0700 Subject: [PATCH 219/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalArrayMap.md | 2 +- Fw/DataStructures/docs/ExternalArraySet.md | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index 8ee8779de5c..4ce1af797e9 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -201,7 +201,7 @@ Success find(const K& key, V& value) override 1. If `iterator != nullptr` - 1. Set `value = iterator.getValue()`. + 1. Set `value = iterator->getValue()`. 1. Set `status = Success::SUCCESS`. diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md index 2b844823421..9798e41383e 100644 --- a/Fw/DataStructures/docs/ExternalArraySet.md +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -190,7 +190,9 @@ ASSERT_EQ(set.getSize(), 0); Success find(const T& element) override ``` -1. Return `m_setImpl.find(element, Nil())`. +1. Set `iterator = m_setImpl.find(element, Nil())`. + +1. Return `(iterator != nullptr) ? Success::SUCCESS : Success::FAILURE _Example:_ ```c++ From 6ba88f0906eb29b505b81809e71b86f05214f181 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 22:52:05 -0700 Subject: [PATCH 220/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalArrayMap.md | 4 ++-- Fw/DataStructures/docs/ExternalArraySet.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index 4ce1af797e9..74f23175468 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -28,7 +28,7 @@ as the map implementation. |----|----|-------|-------------| |`m_mapImpl`|[`ArraySetOrMapImpl`](ArraySetOrMapImpl.md)|The map implementation|C++ default initialization| -The type `Entry` is defined [in the base class](MapBase.md#2-publictypes). +The type `Entry` is defined [in the base class](MapBase.md#2-public-types). ```mermaid classDiagram @@ -244,7 +244,7 @@ ASSERT_EQ(map.getCapacity(), capacity); const Iterator* getHeadIterator const override ``` -The type `Iterator` is defined [in the base class](MapBase.md#2-publictypes). +The type `Iterator` is defined [in the base class](MapBase.md#2-public-types). Return `m_impl.getHeadIterator()`. diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md index 9798e41383e..9008d853f9f 100644 --- a/Fw/DataStructures/docs/ExternalArraySet.md +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -27,7 +27,7 @@ as the set implementation. |----|----|-------|-------------| |`m_setImpl`|[`ArraySetOrMapImpl`](ArraySetOrMapImpl.md)|The set implementation|C++ default initialization| -The type `Entry` is defined [in the base class](MapBase.md#2-publictypes). +The type `Entry` is defined [in the base class](MapBase.md#2-public-types). ```mermaid classDiagram @@ -229,7 +229,7 @@ ASSERT_EQ(set.getCapacity(), capacity); const Iterator* getHeadIterator const override ``` -The type `Iterator` is defined [in the base class](SetBase.md#2-publictypes). +The type `Iterator` is defined [in the base class](SetBase.md#2-public-types). Return `m_impl.getHeadIterator()`. From 386d531167457faa4a027ea72fa1878afbae8f26 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 22:55:36 -0700 Subject: [PATCH 221/458] Revise SDD for SetOrMapIterator --- Fw/DataStructures/docs/SetOrMapIterator.md | 32 +++++++++++----------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/Fw/DataStructures/docs/SetOrMapIterator.md b/Fw/DataStructures/docs/SetOrMapIterator.md index 354b586f73d..7124be59ad6 100644 --- a/Fw/DataStructures/docs/SetOrMapIterator.md +++ b/Fw/DataStructures/docs/SetOrMapIterator.md @@ -11,14 +11,14 @@ It represents an iterator for a set or a map. |Kind|Name|Purpose| |----|----|-------| |`typename`|`KE`|The type of a key in a map or the element of a set| -|`typename`|`V`|The type of a value in a map; unused in a set| +|`typename`|`VN`|The type of a value in a map or Nil in a set| ## 2. Base Class -`SetOrMapIterator` is publicly derived from the following +`SetOrMapIterator` is publicly derived from the following templates: -1. [`MapIterator`](MapIterator.md). +1. [`MapIterator`](MapIterator.md). 1. [`SetIterator`](SetIterator.md). @@ -35,8 +35,8 @@ classDiagram |Name|Type|Purpose|Default Value| |----|----|-------|-------------| |`m_keyOrElement`|`KE`|The map key or set element|C++ default initialization| -|`m_value`|`V`|The value|C++ default initialization| -|`m_next`|`SetOrMapIterator*`|Pointer to the next iterator or `nullptr` if none|`nullptr`| +|`m_valueOrNil`|`VN`|The value or Nil|C++ default initialization| +|`m_next`|`SetOrMapIterator*`|Pointer to the next iterator or `nullptr` if none|`nullptr`| ## 4. Public Constructors and Destructors @@ -51,19 +51,19 @@ Defined as `= default`. ### 4.2. Constructor Providing Members ```c++ -SetOrMapIterator(const KE& keyOrElement, const V& value, SetOrMapIterator* next = nullptr) +SetOrMapIterator(const KE& keyOrElement, const VN& valueOrNil, SetOrMapIterator* next = nullptr) ``` 1. Set `m_keyOrElement = keyOrElement`. -2. Set `m_value = value`. +2. Set `m_valueOrNil = valueOrNil`. 3. Set `m_next = next`. ### 4.3. Copy Constructor ```c++ -SetOrMapIterator(const SetOrMapIterator& map) +SetOrMapIterator(const SetOrMapIterator& map) ``` Defined as `= default`. @@ -81,7 +81,7 @@ Defined as `= default`. ### 5.1. operator= ```c++ -SetOrMapIterator& operator=(const SetOrMapIterator&) +SetOrMapIterator& operator=(const SetOrMapIterator&) ``` Defined as `= default`. @@ -105,15 +105,15 @@ Return a reference to `m_keyOrElement`. ### 5.3. getValue ```c++ -const V& getValue() const +const VN& getValue() const ``` -Return a reference to `m_value`. +Return a reference to `m_valueOrNil`. ### 5.4. getNextIterator ```c++ -SetOrMapIterator getNextIterator() +SetOrMapIterator getNextIterator() ``` Return `m_next`. @@ -121,7 +121,7 @@ Return `m_next`. ### 5.4. getNextMapIterator ```c++ -MapIterator getNextMapIterator() override +MapIterator getNextMapIterator() override ``` Return `m_next`. @@ -145,7 +145,7 @@ Set `m_keyOrElement = keyOrElement`. ### 5.8. setNextIterator ```c++ -void setNextIterator(SetOrMapIterator* next) +void setNextIterator(SetOrMapIterator* next) ``` Set `m_next = next`. @@ -153,7 +153,7 @@ Set `m_next = next`. ### 5.7. setValue ```c++ -void setValue(const V& value) const +void setValue(const VN& valueOrNil) const ``` -Set `m_value = value`. +Set `m_valueOrNil = valueOrNil`. From 920516d11d9df8fc410d9a9c2508de5a170df450 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 22:59:00 -0700 Subject: [PATCH 222/458] Revise SDD for SetOrMapIterator --- Fw/DataStructures/docs/SetOrMapIterator.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Fw/DataStructures/docs/SetOrMapIterator.md b/Fw/DataStructures/docs/SetOrMapIterator.md index 7124be59ad6..0dbfcdea898 100644 --- a/Fw/DataStructures/docs/SetOrMapIterator.md +++ b/Fw/DataStructures/docs/SetOrMapIterator.md @@ -63,7 +63,7 @@ SetOrMapIterator(const KE& keyOrElement, const VN& valueOrNil, SetOrMapIterator< ### 4.3. Copy Constructor ```c++ -SetOrMapIterator(const SetOrMapIterator& map) +SetOrMapIterator(const SetOrMapIterator& iterator) ``` Defined as `= default`. @@ -81,7 +81,7 @@ Defined as `= default`. ### 5.1. operator= ```c++ -SetOrMapIterator& operator=(const SetOrMapIterator&) +SetOrMapIterator& operator=(const SetOrMapIterator& iterator) ``` Defined as `= default`. @@ -113,7 +113,7 @@ Return a reference to `m_valueOrNil`. ### 5.4. getNextIterator ```c++ -SetOrMapIterator getNextIterator() +SetOrMapIterator* getNextIterator() ``` Return `m_next`. @@ -121,7 +121,7 @@ Return `m_next`. ### 5.4. getNextMapIterator ```c++ -MapIterator getNextMapIterator() override +MapIterator* getNextMapIterator() override ``` Return `m_next`. From aa03720da8d00949a53f480d48ecd38caebf9357 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 23:04:06 -0700 Subject: [PATCH 223/458] Revise SDD for MapIterator --- Fw/DataStructures/docs/MapIterator.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/MapIterator.md b/Fw/DataStructures/docs/MapIterator.md index 51aab583530..914c6bdab08 100644 --- a/Fw/DataStructures/docs/MapIterator.md +++ b/Fw/DataStructures/docs/MapIterator.md @@ -1,6 +1,6 @@ # MapIterator -`MapIterator` is a class template +`MapIterator` is an abstract class template defined in [`Fw/DataStructures`](sdd.md). It represents an iterator for a map. From 4c8f85a12b3fb395f935b1f3440b7f0ef3baf38b Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 23:05:06 -0700 Subject: [PATCH 224/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalArrayMap.md | 2 +- Fw/DataStructures/docs/ExternalArraySet.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index 74f23175468..07038ab5300 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -157,7 +157,7 @@ ASSERT_EQ(m2.getSize(), 1); const V& at(FwSizeType index) const ``` -Return `m_mapImpl[index]`. +Return `m_mapImpl.at(index)`. _Example:_ ```c++ diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md index 9008d853f9f..964c18730c9 100644 --- a/Fw/DataStructures/docs/ExternalArraySet.md +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -152,7 +152,7 @@ ASSERT_EQ(m2.getSize(), 1); const V& at(FwSizeType index) const ``` -Return `m_setImpl[index]`. +Return `m_setImpl.at(index)`. _Example:_ ```c++ From b11f4ea33f39b81defb6d795f0348a5a7cabbfc8 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 23:22:16 -0700 Subject: [PATCH 225/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ArraySetOrMapImpl.md | 52 +++++++++++---------- Fw/DataStructures/docs/ExternalArrayMap.md | 10 ++-- Fw/DataStructures/docs/ExternalArraySet.md | 10 ++-- 3 files changed, 41 insertions(+), 31 deletions(-) diff --git a/Fw/DataStructures/docs/ArraySetOrMapImpl.md b/Fw/DataStructures/docs/ArraySetOrMapImpl.md index bffc1736927..ca2dab184e9 100644 --- a/Fw/DataStructures/docs/ArraySetOrMapImpl.md +++ b/Fw/DataStructures/docs/ArraySetOrMapImpl.md @@ -13,16 +13,16 @@ storing the entries in the set or map. |Kind|Name|Purpose| |----|----|-------| |`typename`|`KE`|The type of a key in a map or the element of a set| -|`typename`|`V`|The type of a value in a map; unused in a set| +|`typename`|`VN`|The type of a value in a map or Nil for set| ## 2. Public Types `ArraySetOrMapImpl` defines the following types: -```c++ -using Iterator = SetOrMapIterator -``` -The type `SetOrMapIterator` is defined [here](SetOrMapIterator.md). +|Name|Definition| +|----|----------| +|`Entry`|Alias for [`SetOrMapIterator`](SetOrMapIterator.md)| +|`Iterator`|Alias for [`SetOrMapIterator`](SetOrMapIterator.md)| ## 3. Private Member Variables @@ -30,7 +30,7 @@ The type `SetOrMapIterator` is defined [here](SetOrMapIterator.md). |Name|Type|Purpose|Default Value| |----|----|-------|-------------| -|`m_entries`|[`ExternalArray`](ExternalArray.md)|The array for storing the set or map entries|C++ default initialization| +|`m_entries`|[`ExternalArray`](ExternalArray.md)|The array for storing the set or map entries|C++ default initialization| |`m_size`|`FwSizeType`|The number of entries in the map|0| ```mermaid @@ -75,7 +75,7 @@ contain at least [`getByteArraySize(size)`](#62-getbytearraysize) bytes. ### 4.4. Copy Constructor ```c++ -ArraySetOrMapImpl(const ArraySetOrMapImpl& map) +ArraySetOrMapImpl(const ArraySetOrMapImpl& map) ``` Set `*this = map`. @@ -93,14 +93,14 @@ Defined as `= default`. ### 5.1. operator= ```c++ -ArraySetOrMapImpl& operator=(const ArraySetOrMapImpl& map) +ArraySetOrMapImpl& operator=(const ArraySetOrMapImpl& impl) ``` -1. If `&map != this` +1. If `&impl != this` - 1. Set `m_entries = map.m_entries`. + 1. Set `m_entries = impl.m_entries`. - 1. Set `m_size = map.m_size`. + 1. Set `m_size = impl.m_size`. 1. Return `*this`. @@ -125,22 +125,24 @@ Set `m_size = 0`. ### 5.4. find ```c++ -const Iterator* find(const K& key) +Success find(const KE& keyOrElement, VN& valueOrNil) ``` -1. Set `result = nullptr`. +1. Set `status = Success::FAILURE`. 1. For `i` in `[0, m_size)` - 1. Let `const auto& e = &m_entries[i]`. + 1. Let `const auto& e = m_entries[i]`. - 1. If `e.getKey() == key` + 1. If `e.getKey() == keyOrElement` - 1. Set `result = e`. + 1. Set `valueOrNil = e.getValue()`. + + 1. Set `status = Success::SUCCESS`. 1. Break out of the loop. -1. Return `result`. +1. Return `status`. ### 5.5. getCapacity @@ -177,7 +179,7 @@ Return `m_size`. ### 5.8. insert ```c++ -Success insert(const KE& keyOrElement, const V& value) +Success insert(const KE& keyOrElement, const VN& valueOrNil) ``` 1. Set `status = Success::FAILURE`. @@ -188,7 +190,7 @@ Success insert(const KE& keyOrElement, const V& value) 1. If `e.getKey() == e.keyOrElement` - 1. Call `e.setValue(value)`. + 1. Call `e.setValue(valueOrNil)`. 1. Set `status = Success::SUCCESS`. @@ -196,7 +198,7 @@ Success insert(const KE& keyOrElement, const V& value) 1. If `(status == Success::FAILURE) && (m_size < getCapacity())` - 1. Set `m_entries[m_size] = Iterator(keyOrElement, value)`. + 1. Set `m_entries[m_size] = Iterator(keyOrElement, valueOrNil)`. 1. If `m_size > 0` then call `m_entries[m_size - 1].setNextIterator(&m_entries[m_size])`. @@ -210,14 +212,16 @@ Success insert(const KE& keyOrElement, const V& value) ### 5.9. remove ```c++ -Success remove(const K& key, V& value) +Success remove(const KE& keyOrElement, VN& valueOrNil) ``` 1. Set `status = Success::FAILURE`. 1. For `i` in `[0, m_size)` - 1. If `m_entries[i].getKey() == key` + 1. If `m_entries[i].getKey() == keyOrElement` + + 1. Set `valueOrNil = m_entries[i].getValue()`. 1. If `i < m_size - 1` then @@ -267,7 +271,7 @@ contain at least [`getByteArraySize(size)`](#62-getbytearraysize) bytes. static constexpr U8 getByteArrayAlignment() ``` -Return `ExternalArray::getByteArrayAlignment()`. +Return `ExternalArray::getByteArrayAlignment()`. ### 6.2. getByteArraySize @@ -275,4 +279,4 @@ Return `ExternalArray::getByteArrayAlignment()`. static constexpr FwSizeType getByteArraySize(FwSizeType capacity) ``` -Return `ExternalArray::getByteArraySize(capacity)`. +Return `ExternalArray::getByteArraySize(capacity)`. diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index 07038ab5300..ec488b52237 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -3,7 +3,7 @@ `ExternalArrayMap` is a `final` class template defined in [`Fw/DataStructures`](sdd.md). It represents an array-based map with external storage. -Internally it maintains an [`ArraySetOrMapImpl`](ArraySetOrMapImpl.md) +Internally it maintains an [`ArraySetOrMapImpl`](ArraySetOrMapImpl.md) as the map implementation. ## 1. Template Parameters @@ -26,9 +26,7 @@ as the map implementation. |Name|Type|Purpose|Default Value| |----|----|-------|-------------| -|`m_mapImpl`|[`ArraySetOrMapImpl`](ArraySetOrMapImpl.md)|The map implementation|C++ default initialization| - -The type `Entry` is defined [in the base class](MapBase.md#2-public-types). +|`m_mapImpl`|[`ArraySetOrMapImpl`](ArraySetOrMapImpl.md)|The map implementation|C++ default initialization| ```mermaid classDiagram @@ -56,6 +54,8 @@ ExternalArrayMap map; ExternalArrayMap(Entry* entries, FwSizeType capacity) ``` +The type `Entry` is defined [in the base class](MapBase.md#2-public-types). + Call `m_mapImpl.setStorage(entries, capacity)`. _Example:_ @@ -341,6 +341,8 @@ ASSERT_EQ(value, 1); void setStorage(Entry* entries, FwSizeType capacity) ``` +The type `Entry` is defined [in the base class](MapBase.md#2-public-types). + Call `m_mapImpl.setStorage(entries, capacity)`. _Example:_ diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md index 964c18730c9..444c9ddfca6 100644 --- a/Fw/DataStructures/docs/ExternalArraySet.md +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -3,7 +3,7 @@ `ExternalArraySet` is a `final` class template defined in [`Fw/DataStructures`](sdd.md). It represents an array-based set with external storage. -Internally it maintains an [`ArraySetOrMapImpl`](ArraySetOrMapImpl.md) +Internally it maintains an [`ArraySetOrMapImpl`](ArraySetOrMapImpl.md) as the set implementation. ## 1. Template Parameters @@ -25,9 +25,9 @@ as the set implementation. |Name|Type|Purpose|Default Value| |----|----|-------|-------------| -|`m_setImpl`|[`ArraySetOrMapImpl`](ArraySetOrMapImpl.md)|The set implementation|C++ default initialization| +|`m_setImpl`|[`ArraySetOrMapImpl`](ArraySetOrMapImpl.md)|The set implementation|C++ default initialization| -The type `Entry` is defined [in the base class](MapBase.md#2-public-types). +The type `Nil` is defined [in the base class](SetBase.md#2-public-types). ```mermaid classDiagram @@ -55,6 +55,8 @@ ExternalArraySet set; ExternalArraySet(Entry* entries, FwSizeType capacity) ``` +The type `Entry` is defined [in the base class](SetBase.md#2-public-types). + Call `m_setImpl.setStorage(entries, capacity)`. _Example:_ @@ -325,6 +327,8 @@ ASSERT_EQ(size, 0); void setStorage(Entry* entries, FwSizeType capacity) ``` +The type `Entry` is defined [in the base class](SetBase.md#2-public-types). + Call `m_setImpl.setStorage(entries, capacity)`. _Example:_ From 09d0a7bbab780b22ae7aa65cc2d55870ca980e36 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 23:24:14 -0700 Subject: [PATCH 226/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalArrayMap.md | 24 +++++++++++----------- Fw/DataStructures/docs/ExternalArraySet.md | 24 +++++++++++----------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index ec488b52237..3d36e91b006 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -26,7 +26,7 @@ as the map implementation. |Name|Type|Purpose|Default Value| |----|----|-------|-------------| -|`m_mapImpl`|[`ArraySetOrMapImpl`](ArraySetOrMapImpl.md)|The map implementation|C++ default initialization| +|`m_impl`|[`ArraySetOrMapImpl`](ArraySetOrMapImpl.md)|The map implementation|C++ default initialization| ```mermaid classDiagram @@ -56,7 +56,7 @@ ExternalArrayMap(Entry* entries, FwSizeType capacity) The type `Entry` is defined [in the base class](MapBase.md#2-public-types). -Call `m_mapImpl.setStorage(entries, capacity)`. +Call `m_impl.setStorage(entries, capacity)`. _Example:_ ```c++ @@ -75,7 +75,7 @@ ExternalArrayMap(ByteArray data, FwSizeType capacity) [`getByteArrayAlignment()`](#61-getbytearrayalignment) and must contain at least [`getByteArraySize(size)`](#62-getbytearraysize) bytes. -Call `m_mapImpl.setStorage(data, capacity)`. +Call `m_impl.setStorage(data, capacity)`. _Example:_ ```c++ @@ -128,7 +128,7 @@ ExternalArrayMap& operator=(const ExternalArrayMap& map) 1. If `&map != this` - 1. Set `m_mapImpl = map.m_mapImpl`. + 1. Set `m_impl = map.m_impl`. 1. Return `*this`. @@ -157,7 +157,7 @@ ASSERT_EQ(m2.getSize(), 1); const V& at(FwSizeType index) const ``` -Return `m_mapImpl.at(index)`. +Return `m_impl.at(index)`. _Example:_ ```c++ @@ -176,7 +176,7 @@ ASSERT_DEATH(map.at(1), "Assert"); void clear() override ``` -Call `m_mapImpl.clear()`. +Call `m_impl.clear()`. _Example:_ ```c++ @@ -197,7 +197,7 @@ Success find(const K& key, V& value) override 1. Set `status = Success::FAILURE`. -1. Set `iterator = m_mapImpl.find(key)`. +1. Set `iterator = m_impl.find(key)`. 1. If `iterator != nullptr` @@ -228,7 +228,7 @@ ASSERT_EQ(value, 1); FwSizeType getCapacity() const override ``` -Return `m_mapImpl.getCapacity()`. +Return `m_impl.getCapacity()`. _Example:_ ```c++ @@ -268,7 +268,7 @@ ASSERT_EQ(e->getValue(), 1); FwSizeType getSize() const override ``` -Return `m_mapImpl.getSize()`. +Return `m_impl.getSize()`. _Example:_ ```c++ @@ -289,7 +289,7 @@ ASSERT_EQ(size, 1); Success insert(const K& key, const V& value) override ``` -Return `m_mapImpl.insert(key, value)`. +Return `m_impl.insert(key, value)`. _Example:_ ```c++ @@ -310,7 +310,7 @@ ASSERT_EQ(size, 1); Success remove(const K& key, V& value) override ``` -Return `m_mapImpl.remove(key, value)`. +Return `m_impl.remove(key, value)`. _Example:_ ```c++ @@ -343,7 +343,7 @@ void setStorage(Entry* entries, FwSizeType capacity) The type `Entry` is defined [in the base class](MapBase.md#2-public-types). -Call `m_mapImpl.setStorage(entries, capacity)`. +Call `m_impl.setStorage(entries, capacity)`. _Example:_ ```c++ diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md index 444c9ddfca6..1ceaa976330 100644 --- a/Fw/DataStructures/docs/ExternalArraySet.md +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -25,7 +25,7 @@ as the set implementation. |Name|Type|Purpose|Default Value| |----|----|-------|-------------| -|`m_setImpl`|[`ArraySetOrMapImpl`](ArraySetOrMapImpl.md)|The set implementation|C++ default initialization| +|`m_impl`|[`ArraySetOrMapImpl`](ArraySetOrMapImpl.md)|The set implementation|C++ default initialization| The type `Nil` is defined [in the base class](SetBase.md#2-public-types). @@ -57,7 +57,7 @@ ExternalArraySet(Entry* entries, FwSizeType capacity) The type `Entry` is defined [in the base class](SetBase.md#2-public-types). -Call `m_setImpl.setStorage(entries, capacity)`. +Call `m_impl.setStorage(entries, capacity)`. _Example:_ ```c++ @@ -76,7 +76,7 @@ ExternalArraySet(ByteArray data, FwSizeType capacity) [`getByteArrayAlignment()`](#61-getbytearrayalignment) and must contain at least [`getByteArraySize(size)`](#62-getbytearraysize) bytes. -Call `m_setImpl.setStorage(data, capacity)`. +Call `m_impl.setStorage(data, capacity)`. _Example:_ ```c++ @@ -127,7 +127,7 @@ ExternalArraySet& operator=(const ExternalArraySet& set) 1. If `&set != this` - 1. Set `m_setImpl = set.m_setImpl`. + 1. Set `m_impl = set.m_impl`. 1. Return `*this`. @@ -154,7 +154,7 @@ ASSERT_EQ(m2.getSize(), 1); const V& at(FwSizeType index) const ``` -Return `m_setImpl.at(index)`. +Return `m_impl.at(index)`. _Example:_ ```c++ @@ -173,7 +173,7 @@ ASSERT_DEATH(set.at(1), "Assert"); void clear() override ``` -Call `m_setImpl.clear()`. +Call `m_impl.clear()`. _Example:_ ```c++ @@ -192,7 +192,7 @@ ASSERT_EQ(set.getSize(), 0); Success find(const T& element) override ``` -1. Set `iterator = m_setImpl.find(element, Nil())`. +1. Set `iterator = m_impl.find(element, Nil())`. 1. Return `(iterator != nullptr) ? Success::SUCCESS : Success::FAILURE @@ -215,7 +215,7 @@ ASSERT_EQ(status, Success::SUCCESS); FwSizeType getCapacity() const override ``` -Return `m_setImpl.getCapacity()`. +Return `m_impl.getCapacity()`. _Example:_ ```c++ @@ -254,7 +254,7 @@ ASSERT_EQ(e->getElement(), 42); FwSizeType getSize() const override ``` -Return `m_setImpl.getSize()`. +Return `m_impl.getSize()`. _Example:_ ```c++ @@ -275,7 +275,7 @@ ASSERT_EQ(size, 1); Success insert(const T& element) override ``` -Return `m_setImpl.insert(key, Nil())`. +Return `m_impl.insert(key, Nil())`. _Example:_ ```c++ @@ -298,7 +298,7 @@ Success remove(const T& element) override 1. Set `Nil nil = {}`. -1. Return `m_setImpl.remove(key, nil)`. +1. Return `m_impl.remove(key, nil)`. _Example:_ ```c++ @@ -329,7 +329,7 @@ void setStorage(Entry* entries, FwSizeType capacity) The type `Entry` is defined [in the base class](SetBase.md#2-public-types). -Call `m_setImpl.setStorage(entries, capacity)`. +Call `m_impl.setStorage(entries, capacity)`. _Example:_ ```c++ From 9786ddcda34c7810d01e39cc9f43d7026fcb5963 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 23:25:47 -0700 Subject: [PATCH 227/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalArrayMap.md | 12 +----------- Fw/DataStructures/docs/ExternalArraySet.md | 4 +--- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index 3d36e91b006..110a9a56228 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -195,17 +195,7 @@ ASSERT_EQ(map.getSize(), 0); Success find(const K& key, V& value) override ``` -1. Set `status = Success::FAILURE`. - -1. Set `iterator = m_impl.find(key)`. - -1. If `iterator != nullptr` - - 1. Set `value = iterator->getValue()`. - - 1. Set `status = Success::SUCCESS`. - -1. Return `status`. +Return `m_impl.find(key, value)`. _Example:_ ```c++ diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md index 1ceaa976330..071301ed96e 100644 --- a/Fw/DataStructures/docs/ExternalArraySet.md +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -192,9 +192,7 @@ ASSERT_EQ(set.getSize(), 0); Success find(const T& element) override ``` -1. Set `iterator = m_impl.find(element, Nil())`. - -1. Return `(iterator != nullptr) ? Success::SUCCESS : Success::FAILURE +Return `m_impl.find(key, Nil())`. _Example:_ ```c++ From a4611e1cddf2959e42e7f8426a4a202d9375f09b Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 23:29:51 -0700 Subject: [PATCH 228/458] Revise SDD for SetBase --- Fw/DataStructures/docs/SetBase.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/SetBase.md b/Fw/DataStructures/docs/SetBase.md index 09272318fca..cf351e5fb31 100644 --- a/Fw/DataStructures/docs/SetBase.md +++ b/Fw/DataStructures/docs/SetBase.md @@ -125,7 +125,7 @@ Success find(const T& element) = 0 ``` 1. If an entry `e` with element `element` exists in the set, -then set `element = e.getElement()` and return `SUCCESS`. +then return `SUCCESS`. 1. Otherwise return `FAILURE`. From 0ad0c30fdd2ed824e22a291c697c38d00076072a Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 23:34:11 -0700 Subject: [PATCH 229/458] Revise SDD for SetBase --- Fw/DataStructures/docs/SetBase.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/SetBase.md b/Fw/DataStructures/docs/SetBase.md index cf351e5fb31..cec298a0d17 100644 --- a/Fw/DataStructures/docs/SetBase.md +++ b/Fw/DataStructures/docs/SetBase.md @@ -19,7 +19,7 @@ It represents an abstract base class for a set. |Name|Definition| |----|----------| |`Entry`|Alias of [`SetOrMapIterator`](SetOrMapIterator.md)| -|`Iterator`|[`SetIterator`](SetIterator.md)| +|`Iterator`|Alias of [`SetIterator`](SetIterator.md)| |`Nil`|`struct Nil {}`| ## 3. Private Constructors From f562d17519cfadba60632bd3c668935b0afc3515 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 23:36:11 -0700 Subject: [PATCH 230/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/MapBase.md | 2 +- Fw/DataStructures/docs/SetBase.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index f7f1275c91b..a3b39fee206 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -194,7 +194,7 @@ virtual FwSizeType getSize() const = 0 Return the current size. _Example:_ -See [**getCapacity**](MapBase.md#65-getcapacity). +See [**getCapacity**](MapBase.md#64-getcapacity). ### 6.7. insert diff --git a/Fw/DataStructures/docs/SetBase.md b/Fw/DataStructures/docs/SetBase.md index cec298a0d17..15bb5555438 100644 --- a/Fw/DataStructures/docs/SetBase.md +++ b/Fw/DataStructures/docs/SetBase.md @@ -191,7 +191,7 @@ virtual FwSizeType getSize() const = 0 Return the current size. _Example:_ -See [**getCapacity**](SetBase.md#65-getcapacity). +See [**getCapacity**](SetBase.md#64-getcapacity). ### 6.7. insert From 1150eb2f692204f1f226a34217492ae9801520b6 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 17 Jun 2025 23:42:34 -0700 Subject: [PATCH 231/458] Revise SDD for FifoQueue --- Fw/DataStructures/docs/FifoQueue.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/Fw/DataStructures/docs/FifoQueue.md b/Fw/DataStructures/docs/FifoQueue.md index 18e3a19f8ec..87830229c2b 100644 --- a/Fw/DataStructures/docs/FifoQueue.md +++ b/Fw/DataStructures/docs/FifoQueue.md @@ -3,8 +3,6 @@ `FifoQueue` is a `final` class template defined in [`Fw/DataStructures`](sdd.md). It represents a FIFO queue with internal storage. -Internally it maintains an [`Array`](Array.md) -for storing the items on the queue. ## 1. Template Parameters @@ -34,7 +32,6 @@ for storing the items on the queue. ```mermaid classDiagram FifoQueue *-- ExternalFifoQueue - FifoQueue *-- Array ``` ## 4. Public Constructors and Destructors From a643b22c3d0def441a121932b5f1b960193d26c3 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 18 Jun 2025 11:06:42 -0700 Subject: [PATCH 232/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalStack.md | 3 ++ Fw/DataStructures/docs/Stack.md | 3 ++ Fw/DataStructures/docs/StackBase.md | 3 ++ Fw/DataStructures/docs/sdd.md | 49 ++++++++++++++++++------- 4 files changed, 45 insertions(+), 13 deletions(-) create mode 100644 Fw/DataStructures/docs/ExternalStack.md create mode 100644 Fw/DataStructures/docs/Stack.md create mode 100644 Fw/DataStructures/docs/StackBase.md diff --git a/Fw/DataStructures/docs/ExternalStack.md b/Fw/DataStructures/docs/ExternalStack.md new file mode 100644 index 00000000000..dcc32692e71 --- /dev/null +++ b/Fw/DataStructures/docs/ExternalStack.md @@ -0,0 +1,3 @@ +# ExternalStack + +TODO diff --git a/Fw/DataStructures/docs/Stack.md b/Fw/DataStructures/docs/Stack.md new file mode 100644 index 00000000000..e320f3577a4 --- /dev/null +++ b/Fw/DataStructures/docs/Stack.md @@ -0,0 +1,3 @@ +# Stack + +TODO diff --git a/Fw/DataStructures/docs/StackBase.md b/Fw/DataStructures/docs/StackBase.md new file mode 100644 index 00000000000..28538261645 --- /dev/null +++ b/Fw/DataStructures/docs/StackBase.md @@ -0,0 +1,3 @@ +# StackBase + +TODO diff --git a/Fw/DataStructures/docs/sdd.md b/Fw/DataStructures/docs/sdd.md index ee9fa318944..2fc1b2d3dc8 100644 --- a/Fw/DataStructures/docs/sdd.md +++ b/Fw/DataStructures/docs/sdd.md @@ -13,7 +13,7 @@ The data structures defined here use the following concepts: For a fixed-size array, the size and the capacity are the same. For other data structures, the size and the capacity are not in general the same. -For example, a map has a capacity _C_ and a size between 0 +For example, a map has a capacity _C_ and a size _S_ between 0 and _C_. The data structures in this directory are **sequential data structures**, @@ -27,7 +27,7 @@ the component queue to guard the access to the structure. ## 1. Arrays An **array** _A_ stores _S_ elements for _S > 0_ at indices -0, 1, ..., _S - 1_. +0, 1, ..., _S_ - 1. The elements are stored in **backing memory** _M_. An array provides bounds-checked access to the array elements stored in _M_. @@ -39,14 +39,37 @@ stored in _M_. |[`Array`](Array.md)|A bounds-checked array with internal memory for storing the array elements| |[`ExternalArray`](ExternalArray.md)|A bounds-checked array with external memory for storing the array elements| -## 2. FIFO Queues +## 2. Stacks -A **FIFO queue** is a data structure backed by an array. -It supports enqueue and dequeue operations in -first in first out (FIFO) order. +A **stack** is a data structure that provides push and pop +operations in last-in-first-out (LIFO) order. ### 2.1. Templates +`Fw/DataStructures` provides the following stack templates: + +|Name|Description| +|----|-----------| +|[`ExternalStack`](ExternalStack.md)|A stack with external memory for storing the stack items| +|[`Stack`](Stack.md)|A stack with internal memory for storing the stack items| +|[`StackBase`](StackBase.md)|The abstract base class for a stack| + +### 2.2. Class Diagram + +```mermaid +classDiagram + StackBase <|-- ExternalStack + StackBase <|-- Stack +``` + +## 3. FIFO Queues + +A **FIFO queue** is a data structure that +provides enqueue and dequeue operations in +first-in-first-out (FIFO) order. + +### 3.1. Templates + `Fw/DataStructures` provides the following FIFO queue templates: |Name|Description| @@ -61,7 +84,7 @@ for representing a **circular index**, i.e., an index that wraps around modulo an integer. You can use this template to represent any circular index. -### 2.2. Class Diagram +### 3.2. Class Diagram ```mermaid classDiagram @@ -69,12 +92,12 @@ classDiagram FifoQueueBase <|-- FifoQueue ``` -## 3. Maps +## 4. Maps A **map** is a data structure that associates keys to values. It provides insert, remove, and find operations. -### 3.1. Templates +### 4.1. Templates `Fw/DataStructures` provides the following map templates: @@ -86,7 +109,7 @@ It provides insert, remove, and find operations. |[`MapBase`](MapBase.md)|The abstract base class for a map| |[`RedBlackTreeMap`](RedBlackTreeMap.md)|A red-black tree with internal memory for storing the tree| -### 3.2. Class Diagram +### 4.2. Class Diagram ```mermaid classDiagram @@ -96,12 +119,12 @@ classDiagram MapBase <|-- RedBlackTreeMap ``` -## 4. Sets +## 5. Sets A **set** is a data structure that contains elements. It provides insert, remove, and find operations. -### 4.1. Templates +### 5.1. Templates |Name|Description| |----|-----------| @@ -111,7 +134,7 @@ It provides insert, remove, and find operations. |[`RedBlackTreeSet`](RedBlackTreeSet.md)|A red-black tree with internal memory for storing the tree| |[`SetBase`](SetBase.md)|The abstract base class for a set| -### 4.2. Class Diagram +### 5.2. Class Diagram ```mermaid classDiagram From a717eef308359c19838731e7b0a20fb8c279c1b5 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 18 Jun 2025 11:10:13 -0700 Subject: [PATCH 233/458] Revise SDD for MapBase --- Fw/DataStructures/docs/MapBase.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index a3b39fee206..bd81d7f3965 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -19,7 +19,7 @@ It represents an abstract base class for a map. |Name|Definition| |----|----------| -|`Iterator`|[`MapIterator`](MapIterator.md)| +|`Iterator`|Alias of [`MapIterator`](MapIterator.md)| |`Entry`|Alias of [`SetOrMapIterator`](SetOrMapIterator.md)| From 75d9d163eeb2ffd721b74a2604665def8782a661 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 18 Jun 2025 11:15:06 -0700 Subject: [PATCH 234/458] Revise SDD for StackBase --- Fw/DataStructures/docs/StackBase.md | 258 +++++++++++++++++++++++++++- 1 file changed, 257 insertions(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/StackBase.md b/Fw/DataStructures/docs/StackBase.md index 28538261645..f37762fb771 100644 --- a/Fw/DataStructures/docs/StackBase.md +++ b/Fw/DataStructures/docs/StackBase.md @@ -1,3 +1,259 @@ # StackBase -TODO +`StackBase` is a class template +defined in [`Fw/DataStructures`](sdd.md). +It represents an abstract base class for a stack. + +## 1. Template Parameters + +`StackBase` has the following template parameters. + +|Kind|Name|Purpose| +|----|----|-------| +|`typename`|`T`|The type of an item on the stack| + +## 2. Private Constructors + +### 2.1. Copy Constructor + +```c++ +StackBase(const StackBase& stack) +``` + +Defined as `= delete`. + +## 3. Protected Constructors and Destructors + +### 3.1. Zero-Argument Constructor + +```c++ +StackBase() +``` + +Defined as `= default`. + +### 3.2. Destructor + +```c++ +virtual ~StackBase() +``` + +Defined as `= default`. + +## 4. Private Member Functions + +### 4.1. operator= + +```c++ +StackBase& operator=(const StackBase&) +``` + +Defined as `= delete`. + +## 5. Public Member Functions + +### 5.1. at + +```c++ +virtual const T& at(FwSizeType index) const = 0 +``` + +Return the item at the specified index. +Index 0 is the leftmost (earliest) element in the stack. +Increasing indices go from left to right. +Fails an assertion if the index is out of range. + +_Example:_ +```c++ +void f(StackBase& stack) { + stack.clear(); + const auto status = stack.push(3); + ASSERT_EQ(status, Success::SUCCESS); + const auto status = stack.push(4); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(stack.at(0), 3); + ASSERT_EQ(stack.at(1), 4); + ASSERT_DEATH(stack.at(2), "Assert"); +} +``` + +### 5.2. clear + +```c++ +virtual void clear() = 0 +``` + +Clear the stack. + +_Example:_ +```c++ +void f(StackBase& stack) { + stack.clear(); + ASSERT_EQ(stack.getSize(), 0); +} +``` + +### 5.3. copyDataFrom + +```c++ +void copyDataFrom(const StackBase& stack) +``` + +1. If `&stack != this` then + + 1. Call `clear()`. + + 1. Let `size` be the minimum of `stack.getSize()` and `getCapacity()`. + + 1. For `i` in [0, `size`) + + 1. Set `e = at(i)`. + + 1. Set `status = push(e)`. + + 1. Assert `status == Success::SUCCESS`. + + +_Example:_ +```c++ +void f(StackBase& q1, StackBase& q2) { + q1.clear(); + // Push an item + U32 value = 42; + (void) q1.push(value); + q2.clear(); + ASSERT_EQ(q2.getSize(), 0); + q2.copyDataFrom(q1); + ASSERT_EQ(q2.getSize(), 1); +} +``` + +### 5.4. getCapacity + +```c++ +virtual FwSizeType getCapacity() const = 0 +``` + +Return the current capacity. + +_Example:_ +```c++ +void f(const StackBase& stack) { + const auto size = stack.getSize(); + const auto capacity = stack.getCapacity(); + ASSERT_LE(size, capacity); +} +``` + +### 5.5. getSize + +```c++ +virtual FwSizeType getSize() const = 0 +``` + +Return the current size. + +_Example:_ +```c++ +void f(const StackBase& stack) { + stack.clear(); + 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); +} +``` + +### 5.6. peek + +```c++ +Success peek(T& e, FwSizeType index = 0) const +``` + +1. Set `status = Success::FAILURE`. + +1. If `index < getSize()` + + 1. Set `e = at(index)`. + + 1. Set `status = Success::SUCCESS`. + +1. Return `status`. + +_Example:_ +```c++ +void f(StackBase& stack) { + stack.clear(); + U32 value = 0; + auto status = stack.peek(value); + ASSERT_EQ(status, Success::FAILURE); + status = stack.push(3); + status = stack.peek(value); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(value, 3); + status = stack.peek(value, 1); + ASSERT_EQ(status, Success::FAILURE); + status = stack.push(4); + status = stack.peek(value, 1); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(value, 4); +} +``` + +### 5.7. push + +```c++ +virtual Success push(const T& e) = 0 +``` + +1. Set `status = Success::FAILURE`. + +1. If there is room on the stack for a new item, then + + 1. Add `e` to the right of the stack. + + 1. Set `status = Success::SUCCESS`. + +1. Return `status`. + +_Example:_ +```c++ +void f(StackBase& stack) { + stack.clear(); + const auto status = stack.push(3); + ASSERT_EQ(status, Success::SUCCESS); +} +``` + +### 5.8. pop + +```c++ +virtual Success pop(T& e) = 0 +``` + +1. Set `status = Success::FAILURE`. + +1. If `size > 0` + + 1. Remove the rightmost item from the stack and store it into `e`. + + 1. Set `status = Success::SUCCESS`. + +1. Return `status`. + +_Example:_ +```c++ +void f(StackBase& stack) { + stack.clear(); + U32 val = 0; + auto status = stack.pop(val); + ASSERT_EQ(status, Success::FAILURE); + status = stack.push(3); + ASSERT_EQ(status, Success::SUCCESS); + status = stack.pop(val); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(val, 3); +} +``` From a05e2c03e0c87920256160b4fdfab7b4bab3653c Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 18 Jun 2025 11:23:55 -0700 Subject: [PATCH 235/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalFifoQueue.md | 2 +- Fw/DataStructures/docs/ExternalStack.md | 346 +++++++++++++++++++- 2 files changed, 346 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index 52a7e53cd44..08d0fb23505 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -174,7 +174,7 @@ void clear() override _Example:_ ```c++ constexpr FwSizeType capacity = 10; -U32 items[capacity] = {}; +U32 items[capacity]; ExternalFifoQueue queue(items, capacity); const auto status = queue.enqueue(3); ASSERT_EQ(queue.getSize(), 1); diff --git a/Fw/DataStructures/docs/ExternalStack.md b/Fw/DataStructures/docs/ExternalStack.md index dcc32692e71..f31be460d35 100644 --- a/Fw/DataStructures/docs/ExternalStack.md +++ b/Fw/DataStructures/docs/ExternalStack.md @@ -1,3 +1,347 @@ # ExternalStack -TODO +`ExternalStack` is a `final` class template +defined in [`Fw/DataStructures`](sdd.md). +It represents a stack with external storage. +Internally it maintains an [`ExternalArray`](ExternalArray.md) for +storing the items on the stack. + +## 1. Template Parameters + +`ExternalStack` has the following template parameters. + +|Kind|Name|Purpose| +|----|----|-------| +|`typename`|`T`|The type of an item on the stack| + +## 2. Base Class + +`ExternalStack` is publicly derived from +[`StackBase`](StackBase.md). + +## 3. Private Member Variables + +`ExternalStack` has the following private member variables. + +|Name|Type|Purpose|Default Value| +|----|----|-------|-------------| +|`m_items`|[`ExternalArray`](ExternalArray.md)|The array for storing the stack items|C++ default initialization| +|`m_size`|`FwSizeType`|The number of items on the stack|0| + +```mermaid +classDiagram + Stack *-- ExternalArray +``` + +## 4. Public Constructors and Destructors + +### 4.1. Zero-Argument Constructor + +```c++ +ExternalStack() +``` + +Initialize each member variable with its default value. + +_Example:_ +```c++ +ExternalStack stack; +``` + +### 4.2. Constructor Providing Typed Backing Storage + +```c++ +ExternalStack(T* items, FwSizeType capacity) +``` + +1. Call `setStorage(items, capacity)`. + +1. Initialize the other member variables with their default values. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +U32 items[capacity]; +ExternalStack stack(items, capacity); +``` + +### 4.3. Constructor Providing Untyped Backing Storage + +```c++ +ExternalStack(ByteArray data, FwSizeType capacity) +``` + +`data` must be aligned according to +[`getByteArrayAlignment()`](#61-getbytearrayalignment) and must +contain at least [`getByteArraySize(size)`](#62-getbytearraysize) bytes. + +1. Call `setStorage(data, capacity)`. + +1. Initialize the other member variables with their default values. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +constexpr U8 alignment = ExternalStack::getByteArrayAlignment(); +constexpr FwSizeType byteArraySize = ExternalStack::getByteArraySize(capacity); +alignas(alignment) U8 bytes[byteArraySize]; +ExternalStack stack(ByteArray(&bytes[0], sizeof bytes), capacity); +``` + +### 4.4. Copy Constructor + +```c++ +ExternalStack(const ExternalStack& stack) +``` + +Set `*this = stack`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 3; +U32 items[capacity]; +// Call the constructor providing backing storage +ExternalStack q1(items, capacity); +// Push an item +U32 value = 42; +(void) q1.push(value); +// Call the copy constructor +ExternalStack q2(q1); +ASSERT_EQ(q2.getSize(), 1); +``` + +### 4.5. Destructor + +```c++ +~ExternalStack() override +``` + +Defined as `= default`. + +## 5. Public Member Functions + +### 5.1. operator= + +```c++ +ExternalStack& operator=(const ExternalStack& stack) +``` + +1. If `&stack != this` + + 1. Set `m_items = stack.m_items`. + + 1. Set `m_size = stack.m_size`. + +1. Return `*this`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 3; +U32 items[capacity]; +// Call the constructor providing backing storage +ExternalStack 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); +``` + +### 5.2. clear + +```c++ +void clear() override +``` + +Set `m_size = 0`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +U32 items[capacity]; +ExternalStack stack(items, capacity); +const auto status = stack.push(3); +ASSERT_EQ(stack.getSize(), 1); +stack.clear(); +ASSERT_EQ(stack.getSize(), 0); +``` + +### 5.3. setStorage (Typed Data) + +```c++ +void setStorage(T* items, FwSizeType capacity) +``` + +1. Call `m_items.setStorage(items, capacity)`. + +1. Call `this->clear()`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +ExternalStack stack; +U32 items[capacity]; +stack.setStorage(items, capacity); +``` + +### 5.4. setStorage (Untyped Data) + +```c++ +void setStorage(ByteArray data, FwSizeType capacity) +``` + +`data` must be aligned according to +[`getByteArrayAlignment()`](#61-getbytearrayalignment) and must +contain at least [`getByteArraySize(size)`](#62-getbytearraysize) bytes. + +1. Call `m_items.setStorage(data, capacity)`. + +1. Call `this->clear()`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +constexpr U8 alignment = ExternalStack::getByteArrayAlignment(); +constexpr FwSizeType byteArraySize = ExternalStack::getByteArraySize(capacity); +alignas(alignment) U8 bytes[byteArraySize]; +ExternalStack stack; +stack.setStorage(ByteArray(&bytes[0], sizeof bytes), capacity); +``` + +### 5.6. at + +```c++ +const T& at(FwSizeType index) const override +``` + +1. Assert `index < m_size`. + +1. Return `m_items[index]`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 3; +U32 items[capacity]; +ExternalStack 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"); +``` + +### 5.8. getSize + +```c++ +FwSizeType getSize() const override +``` + +Return `m_size`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +U32 items[capacity]; +ExternalStack 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); +``` + +### 5.9. getCapacity + +```c++ +FwSizeType getCapacity() const override +``` + +Return `m_items.getSize()`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 10; +U32 items[capacity]; +ExternalStack stack(items, capacity); +ASSERT_EQ(stack.getCapacity(), capacity); +``` + +### 5.7. pop + +```c++ +Success pop(T& e) override +``` + +1. Set `status = Success::FAILURE`. + +1. If `m_size > 0` then + + 1. Set `e = m_items[m_size]`. + + 1. Decrement `m_size`. + +1. Return `status`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 3; +U32 items[capacity]; +ExternalStack 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); +``` + +### 5.5. push + +```c++ +Success push(const T& e) override +``` + +1. Set `status = Success::FAILURE`. + +1. If `m_size < getCapacity()` then + + 1. Set `m_items[m_size] = e`. + + 1. Increment `m_size`. + +1. Return `status`. + +_Example:_ +```c++ +constexpr FwSizeType capacity = 3; +U32 items[capacity]; +ExternalStack stack(items, capacity); +ASSERT_EQ(stack.getSize(), 0); +auto status = stack.push(42); +ASSERT_EQ(status, Success::SUCCESS); +ASSERT_EQ(stack.getSize(), 1); +``` + +## 6. Public Static Functions + +### 6.1. getByteArrayAlignment + +```c++ +static constexpr U8 getByteArrayAlignment() +``` + +Return `ExternalArray::getByteArrayAlignment()`. + +### 6.2. getByteArraySize + +```c++ +static constexpr FwSizeType getByteArraySize(FwSizeType capacity) +``` + +Return `ExternalArray::getByteArraySize(capacity)`. From 6106abc9de7e9a86a8ea48931bdea591b941492a Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 18 Jun 2025 11:28:05 -0700 Subject: [PATCH 236/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/FifoQueue.md | 2 +- Fw/DataStructures/docs/Stack.md | 167 +++++++++++++++++++++++++++- 2 files changed, 167 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/docs/FifoQueue.md b/Fw/DataStructures/docs/FifoQueue.md index 87830229c2b..4505fdabb56 100644 --- a/Fw/DataStructures/docs/FifoQueue.md +++ b/Fw/DataStructures/docs/FifoQueue.md @@ -17,7 +17,7 @@ It represents a FIFO queue with internal storage. ## 2. Base Class -`ExternalFifoQueue` is publicly derived from +`FifoQueue` is publicly derived from [`FifoQueueBase`](FifoQueueBase.md). ## 3. Private Member Variables diff --git a/Fw/DataStructures/docs/Stack.md b/Fw/DataStructures/docs/Stack.md index e320f3577a4..a081cc117ed 100644 --- a/Fw/DataStructures/docs/Stack.md +++ b/Fw/DataStructures/docs/Stack.md @@ -1,3 +1,168 @@ # Stack -TODO +`Stack` is a `final` class template +defined in [`Fw/DataStructures`](sdd.md). +It represents a stack with internal storage. + +## 1. Template Parameters + +`Stack` has the following template parameters. + +|Kind|Name|Purpose| +|----|----|-------| +|`typename`|`T`|The type of a stack item| +|`FwSizeType`|`C`|The stack capacity in items| + +`Stack` statically asserts that `C > 0`. + +## 2. Base Class + +`Stack` is publicly derived from +[`StackBase`](StackBase.md). + +## 3. Private Member Variables + +`Stack` has the following private member variables. + +|Name|Type|Purpose|Default Value| +|----|----|-------|-------------| +|`m_extStack`|`ExternalStack`|The external stack implementation|C++ default initialization| +|`m_items`|`T[C]`|The array providing the backing memory for `m_extStack`|C++ default initialization| + +```mermaid +classDiagram + Stack *-- ExternalStack +``` + +## 4. Public Constructors and Destructors + +### 4.1. Zero-Argument Constructor + +```c++ +Stack() +``` + +Initialize `m_extStack` with `ExternalStack(m_items, C)`. + +_Example:_ +```c++ +Stack stack; +``` + +### 4.2. Copy Constructor + +```c++ +Stack(const Stack& stack) +``` + +Set `*this = stack`. + +_Example:_ +```c++ +Stack q1; +auto status = q1.push(3); +ASSERT_EQ(status, Success::SUCCESS); +Stack q2(q1); +ASSERT_EQ(q2.size(), 1); +U32 value = 0; +status = q2.pop(value); +ASSERT_EQ(status, Success::SUCCESS); +ASSERT_EQ(value, 3); +``` + +### 4.3. Destructor + +```c++ +~Stack() override +``` + +Defined as `= default`. + +## 5. Public Member Functions + +### 5.1. operator= + +```c++ +Stack& operator=(const Stack& stack) +``` + +Call `m_extStack.copyDataFrom(stack)`. + +_Example:_ +```c++ +Stack q1; +auto status = q1.push(3); +ASSERT_EQ(status, Success::SUCCESS); +Stack q2; +ASSERT_EQ(q2.size(), 0); +q2 = q1; +ASSERT_EQ(q2.size(), 1); +U32 value = 0; +status = q2.pop(value); +ASSERT_EQ(status, Success::SUCCESS); +ASSERT_EQ(value, 3); +``` + +### 5.2. clear + +```c++ +void clear() override +``` + +Call `m_extStack.clear()`. + +### 5.3. push + +```c++ +Success push(const T& e) override +``` + +Return `m_extStack.push(e)`. + +### 5.4. at + +```c++ +const T& at(FwSizeType index) const override +``` + +Return `m_extStack.at(index)`. + +### 5.5. pop + +```c++ +Success pop(T& e) override +``` + +Return `m_extStack.pop(e)`. + +### 5.6. getSize + +```c++ +FwSizeType getSize() const override +``` + +Return `m_extStack.getSize()`. + +### 5.7. getCapacity + +```c++ +FwSizeType getCapacity() const override +``` + +Return `m_extStack.getCapacity()`. + +## 6. Public Static Functions + +### 6.1. getStaticCapacity + +```c++ +static constexpr FwSizeType getStaticCapacity() +``` + +Return the static capacity `C`. + +_Example:_ +```c++ +const auto capacity = Stack::getStaticCapacity(); +ASSERT_EQ(capacity, 3); +``` From 9c4a30daac6b08d7e547742fefb95b771384e35b Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 18 Jun 2025 11:44:12 -0700 Subject: [PATCH 237/458] Add StackBase.hpp --- Fw/DataStructures/FifoQueueBase.hpp | 2 +- Fw/DataStructures/StackBase.hpp | 112 ++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 Fw/DataStructures/StackBase.hpp diff --git a/Fw/DataStructures/FifoQueueBase.hpp b/Fw/DataStructures/FifoQueueBase.hpp index 9250fab19ce..71a71fc3919 100644 --- a/Fw/DataStructures/FifoQueueBase.hpp +++ b/Fw/DataStructures/FifoQueueBase.hpp @@ -93,7 +93,7 @@ class FifoQueueBase { return status; } - //! Dequeue an item (pop from the left) + //! Dequeue an item (remove from the left) //! \return SUCCESS if item dequeued virtual Success dequeue(T& e //!< The item (output) ) = 0; diff --git a/Fw/DataStructures/StackBase.hpp b/Fw/DataStructures/StackBase.hpp new file mode 100644 index 00000000000..a07f4802f82 --- /dev/null +++ b/Fw/DataStructures/StackBase.hpp @@ -0,0 +1,112 @@ +// ====================================================================== +// \title StackBase +// \author bocchino +// \brief An abstract base class for a stack +// ====================================================================== + +#ifndef Fw_StackBase_HPP +#define Fw_StackBase_HPP + +#include "Fw/FPrimeBasicTypes.hpp" +#include "Fw/Types/Assert.hpp" +#include "Fw/Types/SuccessEnumAc.hpp" + +namespace Fw { + +template +class StackBase { + private: + // ---------------------------------------------------------------------- + // Private constructors + // ---------------------------------------------------------------------- + + //! Copy constructor deleted in the base class + //! Behavior depends on the implementation + StackBase(const StackBase&) = delete; + + protected: + // ---------------------------------------------------------------------- + // Protected constructors and destructors + // ---------------------------------------------------------------------- + + //! Zero-argument constructor + StackBase() = default; + + //! Destructor + virtual ~StackBase() = default; + + private: + // ---------------------------------------------------------------------- + // Private member functions + // ---------------------------------------------------------------------- + + //! operator= deleted in the base class + //! Behavior depends on the implementation + //! We avoid virtual user-defined operators + StackBase& operator=(const StackBase&) = delete; + + public: + // ---------------------------------------------------------------------- + // Public member functions + // ---------------------------------------------------------------------- + + //! Clear the stack + virtual void clear() = 0; + + //! Get an item at an index + //! Indices go from left to right in the stack + //! Fails an assertion if the index is out of range + //! \return The item + virtual const T& at(FwSizeType index //!< The index + ) const = 0; + + //! Copy data from another stack + void copyDataFrom(const StackBase& stack //!< The stack + ) { + if (&stack != this) { + this->clear(); + const FwSizeType size = FW_MIN(stack.getSize(), this->getCapacity()); + for (FwSizeType i = 0; i < size; i++) { + const auto& e = stack.at(i); + const auto status = this->push(e); + FW_ASSERT(status == Fw::Success::SUCCESS, static_cast(status)); + } + } + } + + //! Push an item (add to the right) + //! \return SUCCESS if item pushd + virtual Success push(const T& e //!< The item (output) + ) = 0; + + //! Peek an item at an index + //! Indices go from left to right in the range [0, size) + //! \return SUCCESS if item exists + Success peek(T& e, //!< The item (output) + FwSizeType index = 0 //!< The index (input) + ) const { + auto status = Success::FAILURE; + if (index < this->getSize()) { + e = this->at(index); + status = Success::SUCCESS; + } + return status; + } + + //! Pop an item (remove from the right) + //! \return SUCCESS if item popped + virtual Success pop(T& e //!< The item (output) + ) = 0; + + //! Get the size (number of items stored in the stack) + //! \return The size + virtual FwSizeType getSize() const = 0; + + //! Get the capacity (maximum number of items stored in the stack) + //! \return The capacity + virtual FwSizeType getCapacity() const = 0; +}; + +} // namespace Fw + +#endif From 558b3cb4633130b40ee6325f51a5824f1801c638 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 18 Jun 2025 13:01:12 -0700 Subject: [PATCH 238/458] Add ExternalStack.hpp --- Fw/DataStructures/ExternalFifoQueue.hpp | 2 +- Fw/DataStructures/ExternalStack.hpp | 164 ++++++++++++++++++++++++ Fw/DataStructures/FifoQueue.hpp | 2 +- Fw/DataStructures/docs/ExternalStack.md | 4 +- 4 files changed, 168 insertions(+), 4 deletions(-) create mode 100644 Fw/DataStructures/ExternalStack.hpp diff --git a/Fw/DataStructures/ExternalFifoQueue.hpp b/Fw/DataStructures/ExternalFifoQueue.hpp index f3371fd0c66..8ee805fbf91 100644 --- a/Fw/DataStructures/ExternalFifoQueue.hpp +++ b/Fw/DataStructures/ExternalFifoQueue.hpp @@ -128,7 +128,7 @@ class ExternalFifoQueue final : public FifoQueueBase { return this->m_items[i]; } - //! Dequeue an element (pop from the left) + //! Dequeue an element (remove from the left) //! \return SUCCESS if element dequeued Success dequeue(T& e //!< The element (output) ) override { diff --git a/Fw/DataStructures/ExternalStack.hpp b/Fw/DataStructures/ExternalStack.hpp new file mode 100644 index 00000000000..66a2e41dc58 --- /dev/null +++ b/Fw/DataStructures/ExternalStack.hpp @@ -0,0 +1,164 @@ +// ====================================================================== +// \file ExternalStack.hpp +// \author bocchino +// \brief A stack with external storage +// ====================================================================== + +#ifndef Fw_ExternalStack_HPP +#define Fw_ExternalStack_HPP + +#include "Fw/DataStructures/ExternalArray.hpp" +#include "Fw/DataStructures/StackBase.hpp" +#include "Fw/Types/ByteArray.hpp" + +namespace Fw { + +template +class ExternalStack final : public StackBase { + // ---------------------------------------------------------------------- + // Friend class for testing + // ---------------------------------------------------------------------- + + template + friend class ExternalStackTester; + + public: + // ---------------------------------------------------------------------- + // Public constructors and destructors + // ---------------------------------------------------------------------- + + //! Zero-argument constructor + ExternalStack() = default; + + //! Constructor providing typed backing storage + ExternalStack(T* items, //!< The items + FwSizeType capacity //!< The capacity + ) + : StackBase() { + this->setStorage(items, capacity); + } + + //! Constructor providing untyped backing storage + ExternalStack(ByteArray data, //!< The data + FwSizeType capacity //!< The capacity + ) + : StackBase() { + this->setStorage(data, capacity); + } + + //! Copy constructor + ExternalStack(const ExternalStack& stack) : StackBase() { *this = stack; } + + //! Destructor + ~ExternalStack() override = default; + + public: + // ---------------------------------------------------------------------- + // Public member functions + // ---------------------------------------------------------------------- + + //! operator= + ExternalStack& operator=(const ExternalStack& stack) { + if (&stack != this) { + this->m_items = stack.m_items; + this->m_size = stack.m_size; + } + return *this; + } + + //! Clear the stack + void clear() override { this->m_size = 0; } + + //! Set the storage (typed data) + void setStorage(T* items, //!< The items + FwSizeType capacity //!< The capacity + ) { + this->m_items.setStorage(items, capacity); + this->clear(); + } + + //! Set the storage (untyped data) + void setStorage(ByteArray data, //!< The data + FwSizeType capacity //!< The capacity + ) { + this->m_items.setStorage(data, capacity); + this->clear(); + } + + //! Push an element (push on the right) + //! \return SUCCESS if element pushed + Success push(const T& e //!< The element (output) + ) override { + auto status = Success::FAILURE; + if (this->m_size < this->getCapacity()) { + this->m_items[this->m_size] = e; + this->m_size++; + status = Success::SUCCESS; + } + return status; + } + + //! Get an item at an index + //! Indices go from left to right in the stack + //! Fails an assertion if the index is out of range + //! \return The item + const T& at(FwSizeType index //!< The index + ) const override { + FW_ASSERT(index < this->m_size, static_cast(index), + static_cast(this->m_size)); + return this->m_items[this->m_size]; + } + + //! Pop an element (remove from the right) + //! \return SUCCESS if element popped + Success pop(T& e //!< The element (output) + ) override { + auto status = Success::FAILURE; + if (this->m_size > 0) { + this->m_size--; + e = this->at(this->m_size); + status = Success::SUCCESS; + } + return status; + } + + //! Get the size (number of items stored in the stack) + //! \return The size + FwSizeType getSize() const override { return this->m_size; } + + //! Get the capacity (maximum number of items stored in the stack) + //! \return The capacity + FwSizeType getCapacity() const override { return this->m_items.getSize(); } + + public: + // ---------------------------------------------------------------------- + // Public static functions + // ---------------------------------------------------------------------- + + //! Get the alignment of the storage for an ExternalStack + //! \return The alignment + static constexpr U8 getByteArrayAlignment() { return ExternalArray::getByteArrayAlignment(); } + + //! Get the size of the storage for an ExternalStack of the specified + //! capacity, as a byte array + //! \return The byte array size + static constexpr FwSizeType getByteArraySize(FwSizeType capacity //!< The capacity + ) { + return ExternalArray::getByteArraySize(capacity); + } + + private: + // ---------------------------------------------------------------------- + // Private member variables + // ---------------------------------------------------------------------- + + //! The array for storing the stack items + ExternalArray m_items = {}; + + //! The number of items on the stack + FwSizeType m_size = 0; +}; + +} // namespace Fw + +#endif diff --git a/Fw/DataStructures/FifoQueue.hpp b/Fw/DataStructures/FifoQueue.hpp index 6809f27127b..4ac9260f712 100644 --- a/Fw/DataStructures/FifoQueue.hpp +++ b/Fw/DataStructures/FifoQueue.hpp @@ -56,7 +56,7 @@ class FifoQueue final : public FifoQueueBase { return this->m_extQueue.enqueue(e); } - //! Dequeue an item (pop from the left) + //! Dequeue an item (remove from the left) //! \return SUCCESS if item dequeued Success dequeue(T& e //!< The item (output) ) override { diff --git a/Fw/DataStructures/docs/ExternalStack.md b/Fw/DataStructures/docs/ExternalStack.md index f31be460d35..1ec298be76e 100644 --- a/Fw/DataStructures/docs/ExternalStack.md +++ b/Fw/DataStructures/docs/ExternalStack.md @@ -280,10 +280,10 @@ Success pop(T& e) override 1. If `m_size > 0` then - 1. Set `e = m_items[m_size]`. - 1. Decrement `m_size`. + 1. Set `e = m_items[m_size]`. + 1. Return `status`. _Example:_ From 02f5e8aa5cc96e6ea54b12577717078fb3c53126 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 18 Jun 2025 14:39:02 -0700 Subject: [PATCH 239/458] Add Stack.hpp --- Fw/DataStructures/Stack.hpp | 97 +++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 Fw/DataStructures/Stack.hpp diff --git a/Fw/DataStructures/Stack.hpp b/Fw/DataStructures/Stack.hpp new file mode 100644 index 00000000000..891beee13e5 --- /dev/null +++ b/Fw/DataStructures/Stack.hpp @@ -0,0 +1,97 @@ +// ====================================================================== +// \file Stack.hpp +// \author bocchino +// \brief A stack with internal storage +// ====================================================================== + +#ifndef Fw_Stack_HPP +#define Fw_Stack_HPP + +#include "Fw/DataStructures/Array.hpp" +#include "Fw/DataStructures/ExternalStack.hpp" + +namespace Fw { + +template +class Stack final : public StackBase { + // ---------------------------------------------------------------------- + // Friend class for testing + // ---------------------------------------------------------------------- + + template + friend class StackTester; + + public: + // ---------------------------------------------------------------------- + // Public constructors and destructors + // ---------------------------------------------------------------------- + + //! Zero-argument constructor + Stack() : StackBase(), m_extStack(m_items, C) {} + + //! Copy constructor + Stack(const Stack& stack) : StackBase(), m_extStack(m_items, C) { *this = stack; } + + //! Destructor + ~Stack() override = default; + + public: + // ---------------------------------------------------------------------- + // Public member functions + // ---------------------------------------------------------------------- + + //! operator= + Stack& operator=(const Stack& stack) { + this->m_extStack.copyDataFrom(stack); + return *this; + } + + //! Clear the stack + void clear() override { this->m_extStack.clear(); } + + //! Push an item (push on the right) + //! \return SUCCESS if item pushed + Success push(const T& e //!< The item (output) + ) override { + return this->m_extStack.push(e); + } + + //! Pop an item (remove from the right) + //! \return SUCCESS if item popped + Success pop(T& e //!< The item (output) + ) override { + return this->m_extStack.pop(e); + } + + //! Get the size (number of items stored in the stack) + //! \return The size + FwSizeType getSize() const override { return this->m_extStack.getSize(); } + + //! Get the capacity (maximum number of items stored in the stack) + //! \return The capacity + FwSizeType getCapacity() const override { return this->m_extStack.getCapacity(); } + + //! Get an item at an index + //! Indices go from left to right in the stack + //! Fails an assertion if the index is out of range + //! \return The item + const T& at(FwSizeType index //!< The index + ) const override { + return this->m_extStack.at(index); + } + + private: + // ---------------------------------------------------------------------- + // Private member variables + // ---------------------------------------------------------------------- + + //! The external stack implementation + ExternalStack m_extStack = {}; + + //! The array providing the backing memory for m_extStack + T m_items[C] = {}; +}; + +} // namespace Fw + +#endif From ebc537437b191d2d131d678a94595e3c01b1243c Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 18 Jun 2025 15:19:45 -0700 Subject: [PATCH 240/458] Add ExternalStackTest --- Fw/DataStructures/CMakeLists.txt | 1 + .../test/ut/ExternalFifoQueueTest.cpp | 2 +- .../test/ut/ExternalStackTest.cpp | 276 ++++++++++++++++++ .../test/ut/STest/FifoQueueTestState.hpp | 6 + .../test/ut/STest/StackTestRules.hpp | 102 +++++++ .../test/ut/STest/StackTestScenarios.hpp | 23 ++ .../test/ut/STest/StackTestState.hpp | 44 +++ 7 files changed, 453 insertions(+), 1 deletion(-) create mode 100644 Fw/DataStructures/test/ut/ExternalStackTest.cpp create mode 100644 Fw/DataStructures/test/ut/STest/StackTestRules.hpp create mode 100644 Fw/DataStructures/test/ut/STest/StackTestScenarios.hpp create mode 100644 Fw/DataStructures/test/ut/STest/StackTestState.hpp diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index 32570176695..3762771f00b 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -10,6 +10,7 @@ set(UT_SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" diff --git a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp index 7cba55f786c..50bdaf6f346 100644 --- a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp @@ -14,7 +14,7 @@ class ExternalFifoQueueTester { public: ExternalFifoQueueTester(const ExternalFifoQueue& queue) : m_queue(queue) {} - const ExternalArray getItems() const { return this->m_queue.m_items; } + const ExternalArray& getItems() const { return this->m_queue.m_items; } const CircularIndex& getEnqueueIndex() const { return this->m_queue.m_enqueueIndex; } diff --git a/Fw/DataStructures/test/ut/ExternalStackTest.cpp b/Fw/DataStructures/test/ut/ExternalStackTest.cpp new file mode 100644 index 00000000000..1cdc6704b78 --- /dev/null +++ b/Fw/DataStructures/test/ut/ExternalStackTest.cpp @@ -0,0 +1,276 @@ +// ====================================================================== +// \title ExternalStackTest.cpp +// \author bocchino +// \brief cpp file for ExternalStack tests +// ====================================================================== + +#include "Fw/DataStructures/test/ut/STest/StackTestRules.hpp" +#include "Fw/DataStructures/test/ut/STest/StackTestScenarios.hpp" + +namespace Fw { + +template +class ExternalStackTester { + public: + ExternalStackTester(const ExternalStack& stack) : m_stack(stack) {} + + const ExternalArray getItems() const { return this->m_stack.m_items; } + + private: + const ExternalStack& m_stack; +}; + +namespace StackTest { + +#if 0 +TEST(ExternalStack, ZeroArgConstructor) { + ExternalStack stack; + ASSERT_EQ(stack.getCapacity(), 0); + ASSERT_EQ(stack.getSize(), 0); +} + +TEST(ExternalStack, TypedStorageConstructor) { + constexpr FwSizeType capacity = 10; + U32 items[capacity]; + ExternalStack stack(items, capacity); + ExternalStackTester tester(stack); + ASSERT_EQ(tester.getItems().getElements(), items); + ASSERT_EQ(stack.getCapacity(), capacity); + ASSERT_EQ(stack.getSize(), 0); +} + +TEST(ExternalStack, UntypedStorageConstructor) { + constexpr FwSizeType capacity = 10; + constexpr U8 alignment = ExternalStack::getByteArrayAlignment(); + constexpr FwSizeType byteArraySize = ExternalStack::getByteArraySize(capacity); + alignas(alignment) U8 bytes[byteArraySize]; + ExternalStack stack(ByteArray(&bytes[0], sizeof bytes), capacity); + ExternalStackTester tester(stack); + ASSERT_EQ(tester.getItems().getElements(), reinterpret_cast(bytes)); + ASSERT_EQ(stack.getCapacity(), capacity); + ASSERT_EQ(stack.getSize(), 0); +} + +TEST(ExternalStack, EnstackOK) { + constexpr const FwSizeType capacity = 1000; + const FwSizeType size = STest::Pick::lowerUpper(1, capacity); + U32 elts[capacity]; + ExternalStack stack(elts, capacity); + ASSERT_EQ(stack.getCapacity(), capacity); + ASSERT_EQ(stack.getSize(), 0); + for (FwSizeType i = 0; i < size; i++) { + // Pick a value + const U32 val = STest::Pick::any(); + // Enstack it + auto status = stack.enstack(val); + ASSERT_EQ(status, Success::SUCCESS); + // Peek it + U32 val1 = 0; + status = stack.peek(val1, i); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(val1, val); + // Check the size + ASSERT_EQ(stack.getSize(), i + 1); + } + stack.clear(); + ASSERT_EQ(stack.getSize(), 0); +} + +TEST(ExternalStack, EnstackFull) { + constexpr const FwSizeType capacity = 1000; + U32 elts[capacity]; + ExternalStack stack(elts, capacity); + // Fill up the FIFO + for (FwSizeType i = 0; i < capacity; i++) { + const auto status = stack.enstack(0); + ASSERT_EQ(status, Success::SUCCESS); + } + // Now try to push another element + const U32 val = STest::Pick::any(); + const auto status = stack.enstack(val); + // Push should fail + ASSERT_EQ(status, Success::FAILURE); +} + +TEST(ExternalStack, CopyConstructor) { + constexpr FwSizeType capacity = 3; + U32 items[capacity]; + // Call the constructor providing backing storage + ExternalStack q1(items, capacity); + // Enstack an item + U32 value = 42; + (void)q1.enstack(value); + // Call the copy constructor + ExternalStack q2(q1); + ExternalStackTester tester1(q1); + ExternalStackTester tester2(q2); + ASSERT_EQ(tester2.getItems().getElements(), items); + ASSERT_EQ(tester2.getItems().getSize(), capacity); + ASSERT_EQ(tester2.getEnstackIndex().getValue(), 1); + ASSERT_EQ(tester2.getDestackIndex().getValue(), 0); + ASSERT_EQ(q2.getSize(), 1); +} + +TEST(ExternalStack, CopyAssignmentOperator) { + constexpr FwSizeType capacity = 3; + U32 items[capacity]; + // Call the constructor providing backing storage + ExternalStack q1(items, capacity); + // Enstack an item + U32 value = 42; + (void)q1.enstack(value); + // Call the default constructor + ExternalStack q2; + ASSERT_EQ(q2.getSize(), 0); + // Call the copy assignment operator + q2 = q1; + ASSERT_EQ(q2.getSize(), 1); +} + +TEST(ExternalStack, DestackOK) { + constexpr const FwSizeType capacity = 1000; + const FwSizeType size = STest::Pick::lowerUpper(1, capacity); + U32 items[capacity]; + ExternalStack stack(items, capacity); + ASSERT_EQ(stack.getCapacity(), capacity); + ASSERT_EQ(stack.getSize(), 0); + for (FwSizeType i = 0; i < size; i++) { + // Pick a value + const U32 val = STest::Pick::any(); + // Enstack it + const auto status = stack.enstack(val); + ASSERT_EQ(val, items[i]); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(stack.getSize(), i + 1); + } + for (FwSizeType i = 0; i < size; i++) { + U32 val = 0; + // Peek + auto status = stack.peek(val); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(val, items[i]); + // Destack it + status = stack.destack(val); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(val, items[i]); + ASSERT_EQ(stack.getSize(), size - i - 1); + } + ASSERT_EQ(stack.getSize(), 0); +} + +TEST(ExternalStack, DestackEmpty) { + constexpr const FwSizeType capacity = 1000; + U32 items[capacity]; + ExternalStack stack(items, capacity); + U32 val = 0; + const auto status = stack.destack(val); + ASSERT_EQ(status, Success::FAILURE); +} + +namespace { + +void testCopyDataFrom(StackBase& q1, FwSizeType size1, StackBase& q2) { + q1.clear(); + for (FwSizeType i = 0; i < size1; i++) { + const auto status = q1.enstack(static_cast(i)); + ASSERT_EQ(status, Success::SUCCESS); + } + q2.copyDataFrom(q1); + const auto capacity2 = q2.getCapacity(); + const FwSizeType size = FW_MIN(size1, capacity2); + for (FwSizeType i = 0; i < size; i++) { + U32 val1 = 0; + auto status = q1.peek(val1, i); + ASSERT_EQ(status, Success::SUCCESS); + U32 val2 = 1; + status = q2.peek(val2, i); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(val1, val2); + } +} + +} // namespace + +TEST(ExternalStack, CopyDataFrom) { + constexpr FwSizeType maxSize = 10; + constexpr FwSizeType smallSize = maxSize / 2; + U32 items1[maxSize]; + U32 items2[maxSize]; + ExternalStack q1(items1, maxSize); + // size1 < capacity2 + { + ExternalStack q2(items2, maxSize); + testCopyDataFrom(q1, smallSize, q2); + } + // size1 == size2 + { + ExternalStack q2(items2, maxSize); + testCopyDataFrom(q1, maxSize, q2); + } + // size1 > size2 + { + ExternalStack q2(items2, smallSize); + testCopyDataFrom(q1, maxSize, q2); + } +} + +TEST(ExternalStackRules, EnstackOK) { + U32 items[State::capacity]; + State::ExternalQueue stack(items, State::capacity); + State state(stack); + Rules::enstackOK.apply(state); +} + +TEST(ExternalStackRules, EnstackFull) { + U32 items[State::capacity]; + State::ExternalQueue stack(items, State::capacity); + State state(stack); + for (FwSizeType i = 0; i < State::capacity; i++) { + Rules::enstackOK.apply(state); + } + Rules::enstackFull.apply(state); +} + +TEST(ExternalStackRules, At) { + U32 items[State::capacity]; + State::ExternalQueue stack(items, State::capacity); + State state(stack); + Rules::enstackOK.apply(state); + Rules::at.apply(state); +} + +TEST(ExternalStackRules, DestackOK) { + U32 items[State::capacity]; + State::ExternalQueue stack(items, State::capacity); + State state(stack); + Rules::enstackOK.apply(state); + Rules::destackOK.apply(state); +} + +TEST(ExternalStackRules, DestackEmpty) { + U32 items[State::capacity]; + State::ExternalQueue stack(items, State::capacity); + State state(stack); + Rules::destackEmpty.apply(state); +} + +TEST(ExternalStackRules, Clear) { + U32 items[State::capacity]; + State::ExternalQueue stack(items, State::capacity); + State state(stack); + Rules::enstackOK.apply(state); + ASSERT_EQ(state.stack.getSize(), 1); + Rules::clear.apply(state); + ASSERT_EQ(state.stack.getSize(), 0); +} + +TEST(ExternalStackScenarios, Random) { + U32 items[State::capacity]; + State::ExternalQueue stack(items, State::capacity); + State state(stack); + Scenarios::random(Fw::String("ExternalStackRandom"), state, 1000); +} +#endif + +} // namespace StackTest +} // namespace Fw diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp index f1a25a93c94..837ef1ce5b5 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp @@ -1,3 +1,9 @@ +// ====================================================================== +// \title FifoQueueTestState.hpp +// \author bocchino +// \brief hpp file for FIFO queue test state +// ====================================================================== + #ifndef FifoQueueTestState_HPP #define FifoQueueTestState_HPP diff --git a/Fw/DataStructures/test/ut/STest/StackTestRules.hpp b/Fw/DataStructures/test/ut/STest/StackTestRules.hpp new file mode 100644 index 00000000000..0ced81e27db --- /dev/null +++ b/Fw/DataStructures/test/ut/STest/StackTestRules.hpp @@ -0,0 +1,102 @@ +#ifndef StackTestRules_HPP +#define StackTestRules_HPP + +#include + +#include "Fw/DataStructures/test/ut/STest/StackTestState.hpp" +#include "STest/STest/Pick/Pick.hpp" +#include "STest/STest/Rule/Rule.hpp" + +#if 0 +namespace Fw { + +namespace StackTest { + +using Rule = STest::Rule; + +namespace Rules { + +struct EnqueueOK : public Rule { + EnqueueOK() : Rule("EnqueueOK") {} + bool precondition(const State& state) { return static_cast(state.queue.getSize()) < State::capacity; } + void action(State& state) { + const U32 value = STest::Pick::any(); + const auto status = state.queue.enqueue(value); + ASSERT_EQ(status, Success::SUCCESS); + state.modelQueue.push_back(value); + } +}; + +extern EnqueueOK enqueueOK; + +struct EnqueueFull : public Rule { + EnqueueFull() : Rule("EnqueueFull") {} + bool precondition(const State& state) { return static_cast(state.queue.getSize()) >= State::capacity; } + void action(State& state) { + const auto item = State::getRandomItem(); + const auto status = state.queue.enqueue(item); + ASSERT_EQ(status, Success::FAILURE); + } +}; + +extern EnqueueFull enqueueFull; + +struct At : public Rule { + At() : Rule("At") {} + bool precondition(const State& state) { return state.queue.getSize() > 0; } + void action(State& state) { + const auto index = STest::Pick::startLength(0, static_cast(state.queue.getSize())); + ASSERT_EQ(state.queue.at(index), state.modelQueue.at(index)); + } +}; + +extern At at; + +struct DequeueOK : public Rule { + DequeueOK() : Rule("DequeueOK") {} + bool precondition(const State& state) { return static_cast(state.queue.getSize()) > 0; } + void action(State& state) { + U32 value = 0; + const auto status = state.queue.dequeue(value); + ASSERT_EQ(status, Success::SUCCESS); + const auto expectedValue = state.modelQueue.at(0); + ASSERT_EQ(value, expectedValue); + state.modelQueue.pop_front(); + ASSERT_EQ(state.queue.getSize(), state.modelQueue.size()); + } +}; + +extern DequeueOK dequeueOK; + +struct DequeueEmpty : public Rule { + DequeueEmpty() : Rule("DequeueEmpty") {} + bool precondition(const State& state) { return static_cast(state.queue.getSize()) == 0; } + void action(State& state) { + U32 value = 0; + const auto status = state.queue.dequeue(value); + ASSERT_EQ(status, Success::FAILURE); + } +}; + +extern DequeueEmpty dequeueEmpty; + +struct Clear : public Rule { + Clear() : Rule("Clear") {} + bool precondition(const State& state) { return state.queue.getSize() > 0; } + void action(State& state) { + state.queue.clear(); + ASSERT_EQ(state.queue.getSize(), 0); + state.modelQueue.clear(); + } +}; + +extern Clear clear; + +}; // namespace Rules + +} // namespace StackTest + +} // namespace Fw +#endif + +#endif diff --git a/Fw/DataStructures/test/ut/STest/StackTestScenarios.hpp b/Fw/DataStructures/test/ut/STest/StackTestScenarios.hpp new file mode 100644 index 00000000000..ff838f0d4fa --- /dev/null +++ b/Fw/DataStructures/test/ut/STest/StackTestScenarios.hpp @@ -0,0 +1,23 @@ +// ====================================================================== +// \title StackTestScenarios.hpp +// \author Rob Bocchino +// \brief Stack test scenarios +// ====================================================================== + +#include "Fw/DataStructures/test/ut/STest/StackTestState.hpp" + +#if 0 +namespace Fw { + +namespace StackTest { + +namespace Scenarios { + +void random(const Fw::StringBase& name, State& state, U32 maxNumSteps); + +} // namespace Scenarios + +} // namespace StackTest + +} // namespace Fw +#endif diff --git a/Fw/DataStructures/test/ut/STest/StackTestState.hpp b/Fw/DataStructures/test/ut/STest/StackTestState.hpp new file mode 100644 index 00000000000..285e4416e91 --- /dev/null +++ b/Fw/DataStructures/test/ut/STest/StackTestState.hpp @@ -0,0 +1,44 @@ +// ====================================================================== +// \title StackTestState.hpp +// \author bocchino +// \brief hpp file for Stack test state +// ====================================================================== + +#ifndef StackTestState_HPP +#define StackTestState_HPP + +#include + +#include "Fw/DataStructures/Stack.hpp" +#include "STest/STest/Pick/Pick.hpp" + +namespace Fw { + +namespace StackTest { + +struct State { + //! The stack item type + using ItemType = U32; + //! The stack capacity + static constexpr FwSizeType capacity = 1024; + //! The Stack type + using Stack = Stack; + //! The ExternalStack type + using ExternalStack = ExternalStack; + //! THe StackBase type + using StackBase = StackBase; + //! Constructor + State(StackBase& a_stack) : stack(a_stack) {} + //! The stack under test + StackBase& stack; + //! The stack for modeling correct behavior + std::deque modelStack; + //! Get a random item + static ItemType getRandomItem() { return STest::Pick::any(); } +}; + +} + +} + +#endif From 19a785dcef81bba1e3002d4a6003645ef8912d62 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 18 Jun 2025 15:25:16 -0700 Subject: [PATCH 241/458] Revise Stack tests --- Fw/DataStructures/CMakeLists.txt | 2 + .../test/ut/STest/FifoQueueTestRules.cpp | 2 +- .../test/ut/STest/FifoQueueTestRules.hpp | 6 +++ .../test/ut/STest/StackTestRules.cpp | 33 +++++++++++++++++ .../test/ut/STest/StackTestRules.hpp | 10 ++++- .../test/ut/STest/StackTestScenarios.cpp | 37 +++++++++++++++++++ .../test/ut/STest/StackTestScenarios.hpp | 2 - 7 files changed, 87 insertions(+), 5 deletions(-) create mode 100644 Fw/DataStructures/test/ut/STest/StackTestRules.cpp create mode 100644 Fw/DataStructures/test/ut/STest/StackTestScenarios.cpp diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index 3762771f00b..3e7f441cef6 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -14,6 +14,8 @@ set(UT_SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" ) set(UT_MOD_DEPS diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.cpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.cpp index 97f0a9f4f30..8f86c270235 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.cpp @@ -1,7 +1,7 @@ // ====================================================================== // \title FifoQueueTestRules.cpp // \author Rob Bocchino -// \brief FifoQueue test rules +// \brief cpp file for FifoQueue test rules // ====================================================================== #include "Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp" diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp index dcabf830ee4..e813268a138 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp @@ -1,3 +1,9 @@ +// ====================================================================== +// \title FifoQueueTestRules.hpp +// \author bocchino +// \brief hpp file for FIFO queue test rules +// ====================================================================== + #ifndef FifoQueueTestRules_HPP #define FifoQueueTestRules_HPP diff --git a/Fw/DataStructures/test/ut/STest/StackTestRules.cpp b/Fw/DataStructures/test/ut/STest/StackTestRules.cpp new file mode 100644 index 00000000000..e1f87ddddd8 --- /dev/null +++ b/Fw/DataStructures/test/ut/STest/StackTestRules.cpp @@ -0,0 +1,33 @@ +// ====================================================================== +// \title StackTestRules.cpp +// \author Rob Bocchino +// \brief cpp file for Stack test rules +// ====================================================================== + +#include "Fw/DataStructures/test/ut/STest/StackTestRules.hpp" + +namespace Fw { + +namespace StackTest { + +namespace Rules { + +#if 0 +EnqueueOK enqueueOK; + +EnqueueFull enqueueFull; + +At at; + +DequeueOK dequeueOK; + +DequeueEmpty dequeueEmpty; + +Clear clear; +#endif + +}; // namespace Rules + +} // namespace StackTest + +} // namespace Fw diff --git a/Fw/DataStructures/test/ut/STest/StackTestRules.hpp b/Fw/DataStructures/test/ut/STest/StackTestRules.hpp index 0ced81e27db..a16140baebd 100644 --- a/Fw/DataStructures/test/ut/STest/StackTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/StackTestRules.hpp @@ -1,3 +1,9 @@ +// ====================================================================== +// \title StackTestRules.hpp +// \author bocchino +// \brief hpp file for Stack test rules +// ====================================================================== + #ifndef StackTestRules_HPP #define StackTestRules_HPP @@ -7,7 +13,6 @@ #include "STest/STest/Pick/Pick.hpp" #include "STest/STest/Rule/Rule.hpp" -#if 0 namespace Fw { namespace StackTest { @@ -16,6 +21,7 @@ using Rule = STest::Rule; namespace Rules { +#if 0 struct EnqueueOK : public Rule { EnqueueOK() : Rule("EnqueueOK") {} bool precondition(const State& state) { return static_cast(state.queue.getSize()) < State::capacity; } @@ -91,12 +97,12 @@ struct Clear : public Rule { }; extern Clear clear; +#endif }; // namespace Rules } // namespace StackTest } // namespace Fw -#endif #endif diff --git a/Fw/DataStructures/test/ut/STest/StackTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/StackTestScenarios.cpp new file mode 100644 index 00000000000..7e9f5f5e4d0 --- /dev/null +++ b/Fw/DataStructures/test/ut/STest/StackTestScenarios.cpp @@ -0,0 +1,37 @@ +// ====================================================================== +// \title StackTestScenarios.cpp +// \author Rob Bocchino +// \brief Stack test scenarios +// ====================================================================== + +#include "Fw/DataStructures/test/ut/STest/StackTestRules.hpp" +#include "Fw/DataStructures/test/ut/STest/StackTestScenarios.hpp" +#include "STest/Scenario/BoundedScenario.hpp" +#include "STest/Scenario/RandomScenario.hpp" + +namespace Fw { + +namespace StackTest { + +namespace Scenarios { + +void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { + (void) name; + (void) state; + (void) maxNumSteps; +#if 0 + Rule* rules[] = {&Rules::enqueueOK, &Rules::enqueueFull, &Rules::at, + &Rules::dequeueOK, &Rules::dequeueEmpty, &Rules::clear}; + STest::RandomScenario scenario("RandomScenario", rules, + sizeof(rules) / sizeof(STest::RandomScenario*)); + STest::BoundedScenario boundedScenario(name.toChar(), scenario, maxNumSteps); + const U32 numSteps = boundedScenario.run(state); + printf("Ran %u steps.\n", numSteps); +#endif +} + +} // namespace Scenarios + +} // namespace StackTest + +} // namespace Fw diff --git a/Fw/DataStructures/test/ut/STest/StackTestScenarios.hpp b/Fw/DataStructures/test/ut/STest/StackTestScenarios.hpp index ff838f0d4fa..bfd567ff202 100644 --- a/Fw/DataStructures/test/ut/STest/StackTestScenarios.hpp +++ b/Fw/DataStructures/test/ut/STest/StackTestScenarios.hpp @@ -6,7 +6,6 @@ #include "Fw/DataStructures/test/ut/STest/StackTestState.hpp" -#if 0 namespace Fw { namespace StackTest { @@ -20,4 +19,3 @@ void random(const Fw::StringBase& name, State& state, U32 maxNumSteps); } // namespace StackTest } // namespace Fw -#endif From e5c7752418a8c294ddd8e71e4aca9ebdb0eb527c Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 18 Jun 2025 15:49:31 -0700 Subject: [PATCH 242/458] Revise ExternalStack --- Fw/DataStructures/ExternalStack.hpp | 4 +- Fw/DataStructures/docs/StackBase.md | 17 ++-- .../test/ut/ExternalStackTest.cpp | 87 +++++++++++-------- 3 files changed, 63 insertions(+), 45 deletions(-) diff --git a/Fw/DataStructures/ExternalStack.hpp b/Fw/DataStructures/ExternalStack.hpp index 66a2e41dc58..ca372895d12 100644 --- a/Fw/DataStructures/ExternalStack.hpp +++ b/Fw/DataStructures/ExternalStack.hpp @@ -106,7 +106,7 @@ class ExternalStack final : public StackBase { ) const override { FW_ASSERT(index < this->m_size, static_cast(index), static_cast(this->m_size)); - return this->m_items[this->m_size]; + return this->m_items[this->m_size - 1 - index]; } //! Pop an element (remove from the right) @@ -115,8 +115,8 @@ class ExternalStack final : public StackBase { ) override { auto status = Success::FAILURE; if (this->m_size > 0) { + e = this->at(0); this->m_size--; - e = this->at(this->m_size); status = Success::SUCCESS; } return status; diff --git a/Fw/DataStructures/docs/StackBase.md b/Fw/DataStructures/docs/StackBase.md index f37762fb771..b5dfa2b79d8 100644 --- a/Fw/DataStructures/docs/StackBase.md +++ b/Fw/DataStructures/docs/StackBase.md @@ -59,20 +59,20 @@ virtual const T& at(FwSizeType index) const = 0 ``` Return the item at the specified index. -Index 0 is the leftmost (earliest) element in the stack. -Increasing indices go from left to right. +Index 0 is the rightmost (latest) element in the stack. +Increasing indices go from right to left. Fails an assertion if the index is out of range. _Example:_ ```c++ void f(StackBase& stack) { stack.clear(); - const auto status = stack.push(3); + auto status = stack.push(3); ASSERT_EQ(status, Success::SUCCESS); - const auto status = stack.push(4); + status = stack.push(4); ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(stack.at(0), 3); - ASSERT_EQ(stack.at(1), 4); + ASSERT_EQ(stack.at(0), 4); + ASSERT_EQ(stack.at(1), 3); ASSERT_DEATH(stack.at(2), "Assert"); } ``` @@ -196,9 +196,12 @@ void f(StackBase& stack) { status = stack.peek(value, 1); ASSERT_EQ(status, Success::FAILURE); status = stack.push(4); - status = stack.peek(value, 1); + status = stack.peek(value); ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(value, 4); + status = stack.peek(value, 1); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(value, 3); } ``` diff --git a/Fw/DataStructures/test/ut/ExternalStackTest.cpp b/Fw/DataStructures/test/ut/ExternalStackTest.cpp index 1cdc6704b78..09953b48e38 100644 --- a/Fw/DataStructures/test/ut/ExternalStackTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalStackTest.cpp @@ -22,7 +22,6 @@ class ExternalStackTester { namespace StackTest { -#if 0 TEST(ExternalStack, ZeroArgConstructor) { ExternalStack stack; ASSERT_EQ(stack.getCapacity(), 0); @@ -51,7 +50,20 @@ TEST(ExternalStack, UntypedStorageConstructor) { ASSERT_EQ(stack.getSize(), 0); } -TEST(ExternalStack, EnstackOK) { +TEST(ExternalStack, At) { + constexpr FwSizeType capacity = 10; + U32 items[capacity]; + ExternalStack stack(items, capacity); + auto status = stack.push(3); + ASSERT_EQ(status, Success::SUCCESS); + status = stack.push(4); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(stack.at(0), 4); + ASSERT_EQ(stack.at(1), 3); + ASSERT_DEATH(stack.at(2), "Assert"); +} + +TEST(ExternalStack, PushOK) { constexpr const FwSizeType capacity = 1000; const FwSizeType size = STest::Pick::lowerUpper(1, capacity); U32 elts[capacity]; @@ -61,12 +73,12 @@ TEST(ExternalStack, EnstackOK) { for (FwSizeType i = 0; i < size; i++) { // Pick a value const U32 val = STest::Pick::any(); - // Enstack it - auto status = stack.enstack(val); + // Push it + auto status = stack.push(val); ASSERT_EQ(status, Success::SUCCESS); // Peek it U32 val1 = 0; - status = stack.peek(val1, i); + status = stack.peek(val1); ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(val1, val); // Check the size @@ -76,18 +88,18 @@ TEST(ExternalStack, EnstackOK) { ASSERT_EQ(stack.getSize(), 0); } -TEST(ExternalStack, EnstackFull) { +TEST(ExternalStack, PushFull) { constexpr const FwSizeType capacity = 1000; U32 elts[capacity]; ExternalStack stack(elts, capacity); - // Fill up the FIFO + // Fill up the stack for (FwSizeType i = 0; i < capacity; i++) { - const auto status = stack.enstack(0); + const auto status = stack.push(0); ASSERT_EQ(status, Success::SUCCESS); } // Now try to push another element const U32 val = STest::Pick::any(); - const auto status = stack.enstack(val); + const auto status = stack.push(val); // Push should fail ASSERT_EQ(status, Success::FAILURE); } @@ -97,17 +109,16 @@ TEST(ExternalStack, CopyConstructor) { U32 items[capacity]; // Call the constructor providing backing storage ExternalStack q1(items, capacity); - // Enstack an item + // Push an item U32 value = 42; - (void)q1.enstack(value); + const auto status = q1.push(value); + ASSERT_EQ(status, Success::SUCCESS); // Call the copy constructor ExternalStack q2(q1); ExternalStackTester tester1(q1); ExternalStackTester tester2(q2); ASSERT_EQ(tester2.getItems().getElements(), items); ASSERT_EQ(tester2.getItems().getSize(), capacity); - ASSERT_EQ(tester2.getEnstackIndex().getValue(), 1); - ASSERT_EQ(tester2.getDestackIndex().getValue(), 0); ASSERT_EQ(q2.getSize(), 1); } @@ -116,9 +127,10 @@ TEST(ExternalStack, CopyAssignmentOperator) { U32 items[capacity]; // Call the constructor providing backing storage ExternalStack q1(items, capacity); - // Enstack an item + // Push an item U32 value = 42; - (void)q1.enstack(value); + const auto status = q1.push(value); + ASSERT_EQ(status, Success::SUCCESS); // Call the default constructor ExternalStack q2; ASSERT_EQ(q2.getSize(), 0); @@ -127,7 +139,7 @@ TEST(ExternalStack, CopyAssignmentOperator) { ASSERT_EQ(q2.getSize(), 1); } -TEST(ExternalStack, DestackOK) { +TEST(ExternalStack, PopOK) { constexpr const FwSizeType capacity = 1000; const FwSizeType size = STest::Pick::lowerUpper(1, capacity); U32 items[capacity]; @@ -137,33 +149,36 @@ TEST(ExternalStack, DestackOK) { for (FwSizeType i = 0; i < size; i++) { // Pick a value const U32 val = STest::Pick::any(); - // Enstack it - const auto status = stack.enstack(val); + // Push it + const auto status = stack.push(val); ASSERT_EQ(val, items[i]); ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(stack.getSize(), i + 1); } +#if 0 for (FwSizeType i = 0; i < size; i++) { U32 val = 0; // Peek auto status = stack.peek(val); ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(val, items[i]); - // Destack it - status = stack.destack(val); + // Pop it + status = stack.pop(val); ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(val, items[i]); - ASSERT_EQ(stack.getSize(), size - i - 1); + ASSERT_EQ(stack.getSize(), size - 1 - i); } ASSERT_EQ(stack.getSize(), 0); +#endif } -TEST(ExternalStack, DestackEmpty) { +#if 0 +TEST(ExternalStack, PopEmpty) { constexpr const FwSizeType capacity = 1000; U32 items[capacity]; ExternalStack stack(items, capacity); U32 val = 0; - const auto status = stack.destack(val); + const auto status = stack.pop(val); ASSERT_EQ(status, Success::FAILURE); } @@ -172,7 +187,7 @@ namespace { void testCopyDataFrom(StackBase& q1, FwSizeType size1, StackBase& q2) { q1.clear(); for (FwSizeType i = 0; i < size1; i++) { - const auto status = q1.enstack(static_cast(i)); + const auto status = q1.push(static_cast(i)); ASSERT_EQ(status, Success::SUCCESS); } q2.copyDataFrom(q1); @@ -214,51 +229,51 @@ TEST(ExternalStack, CopyDataFrom) { } } -TEST(ExternalStackRules, EnstackOK) { +TEST(ExternalStackRules, PushOK) { U32 items[State::capacity]; State::ExternalQueue stack(items, State::capacity); State state(stack); - Rules::enstackOK.apply(state); + Rules::pushOK.apply(state); } -TEST(ExternalStackRules, EnstackFull) { +TEST(ExternalStackRules, PushFull) { U32 items[State::capacity]; State::ExternalQueue stack(items, State::capacity); State state(stack); for (FwSizeType i = 0; i < State::capacity; i++) { - Rules::enstackOK.apply(state); + Rules::pushOK.apply(state); } - Rules::enstackFull.apply(state); + Rules::pushFull.apply(state); } TEST(ExternalStackRules, At) { U32 items[State::capacity]; State::ExternalQueue stack(items, State::capacity); State state(stack); - Rules::enstackOK.apply(state); + Rules::pushOK.apply(state); Rules::at.apply(state); } -TEST(ExternalStackRules, DestackOK) { +TEST(ExternalStackRules, PopOK) { U32 items[State::capacity]; State::ExternalQueue stack(items, State::capacity); State state(stack); - Rules::enstackOK.apply(state); - Rules::destackOK.apply(state); + Rules::pushOK.apply(state); + Rules::popOK.apply(state); } -TEST(ExternalStackRules, DestackEmpty) { +TEST(ExternalStackRules, PopEmpty) { U32 items[State::capacity]; State::ExternalQueue stack(items, State::capacity); State state(stack); - Rules::destackEmpty.apply(state); + Rules::popEmpty.apply(state); } TEST(ExternalStackRules, Clear) { U32 items[State::capacity]; State::ExternalQueue stack(items, State::capacity); State state(stack); - Rules::enstackOK.apply(state); + Rules::pushOK.apply(state); ASSERT_EQ(state.stack.getSize(), 1); Rules::clear.apply(state); ASSERT_EQ(state.stack.getSize(), 0); From e9008ad7cfe44b96c8d3755230032f81c1bbafe8 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 18 Jun 2025 15:58:25 -0700 Subject: [PATCH 243/458] Revise ExternalStackTest --- Fw/DataStructures/StackBase.hpp | 2 +- .../test/ut/ExternalStackTest.cpp | 19 ++++++------------- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/Fw/DataStructures/StackBase.hpp b/Fw/DataStructures/StackBase.hpp index a07f4802f82..2a9732b4325 100644 --- a/Fw/DataStructures/StackBase.hpp +++ b/Fw/DataStructures/StackBase.hpp @@ -67,7 +67,7 @@ class StackBase { this->clear(); const FwSizeType size = FW_MIN(stack.getSize(), this->getCapacity()); for (FwSizeType i = 0; i < size; i++) { - const auto& e = stack.at(i); + const auto& e = stack.at(size - 1 - i); const auto status = this->push(e); FW_ASSERT(status == Fw::Success::SUCCESS, static_cast(status)); } diff --git a/Fw/DataStructures/test/ut/ExternalStackTest.cpp b/Fw/DataStructures/test/ut/ExternalStackTest.cpp index 09953b48e38..012c1899e62 100644 --- a/Fw/DataStructures/test/ut/ExternalStackTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalStackTest.cpp @@ -155,24 +155,22 @@ TEST(ExternalStack, PopOK) { ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(stack.getSize(), i + 1); } -#if 0 for (FwSizeType i = 0; i < size; i++) { + const FwSizeType stackIndex = size - 1 - i; U32 val = 0; // Peek auto status = stack.peek(val); ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(val, items[i]); + ASSERT_EQ(val, items[stackIndex]); // Pop it status = stack.pop(val); ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(val, items[i]); - ASSERT_EQ(stack.getSize(), size - 1 - i); + ASSERT_EQ(val, items[stackIndex]); + ASSERT_EQ(stack.getSize(), stackIndex); } ASSERT_EQ(stack.getSize(), 0); -#endif } -#if 0 TEST(ExternalStack, PopEmpty) { constexpr const FwSizeType capacity = 1000; U32 items[capacity]; @@ -194,13 +192,7 @@ void testCopyDataFrom(StackBase& q1, FwSizeType size1, StackBase& q2) const auto capacity2 = q2.getCapacity(); const FwSizeType size = FW_MIN(size1, capacity2); for (FwSizeType i = 0; i < size; i++) { - U32 val1 = 0; - auto status = q1.peek(val1, i); - ASSERT_EQ(status, Success::SUCCESS); - U32 val2 = 1; - status = q2.peek(val2, i); - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(val1, val2); + ASSERT_EQ(q1.at(i), q2.at(i)); } } @@ -229,6 +221,7 @@ TEST(ExternalStack, CopyDataFrom) { } } +#if 0 TEST(ExternalStackRules, PushOK) { U32 items[State::capacity]; State::ExternalQueue stack(items, State::capacity); From aef7050746faf9d966562fd197e62fb71d8debab Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 18 Jun 2025 16:11:12 -0700 Subject: [PATCH 244/458] Revise ExternalStackTest --- .../test/ut/ExternalStackTest.cpp | 16 ++--- .../test/ut/STest/StackTestRules.cpp | 10 ++-- .../test/ut/STest/StackTestRules.hpp | 58 +++++++++---------- .../test/ut/STest/StackTestState.hpp | 4 +- 4 files changed, 44 insertions(+), 44 deletions(-) diff --git a/Fw/DataStructures/test/ut/ExternalStackTest.cpp b/Fw/DataStructures/test/ut/ExternalStackTest.cpp index 012c1899e62..44fde3c0973 100644 --- a/Fw/DataStructures/test/ut/ExternalStackTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalStackTest.cpp @@ -221,17 +221,16 @@ TEST(ExternalStack, CopyDataFrom) { } } -#if 0 TEST(ExternalStackRules, PushOK) { U32 items[State::capacity]; - State::ExternalQueue stack(items, State::capacity); + State::ExternalStack stack(items, State::capacity); State state(stack); Rules::pushOK.apply(state); } TEST(ExternalStackRules, PushFull) { U32 items[State::capacity]; - State::ExternalQueue stack(items, State::capacity); + State::ExternalStack stack(items, State::capacity); State state(stack); for (FwSizeType i = 0; i < State::capacity; i++) { Rules::pushOK.apply(state); @@ -239,9 +238,10 @@ TEST(ExternalStackRules, PushFull) { Rules::pushFull.apply(state); } +#if 0 TEST(ExternalStackRules, At) { U32 items[State::capacity]; - State::ExternalQueue stack(items, State::capacity); + State::ExternalStack stack(items, State::capacity); State state(stack); Rules::pushOK.apply(state); Rules::at.apply(state); @@ -249,7 +249,7 @@ TEST(ExternalStackRules, At) { TEST(ExternalStackRules, PopOK) { U32 items[State::capacity]; - State::ExternalQueue stack(items, State::capacity); + State::ExternalStack stack(items, State::capacity); State state(stack); Rules::pushOK.apply(state); Rules::popOK.apply(state); @@ -257,14 +257,14 @@ TEST(ExternalStackRules, PopOK) { TEST(ExternalStackRules, PopEmpty) { U32 items[State::capacity]; - State::ExternalQueue stack(items, State::capacity); + State::ExternalStack stack(items, State::capacity); State state(stack); Rules::popEmpty.apply(state); } TEST(ExternalStackRules, Clear) { U32 items[State::capacity]; - State::ExternalQueue stack(items, State::capacity); + State::ExternalStack stack(items, State::capacity); State state(stack); Rules::pushOK.apply(state); ASSERT_EQ(state.stack.getSize(), 1); @@ -274,7 +274,7 @@ TEST(ExternalStackRules, Clear) { TEST(ExternalStackScenarios, Random) { U32 items[State::capacity]; - State::ExternalQueue stack(items, State::capacity); + State::ExternalStack stack(items, State::capacity); State state(stack); Scenarios::random(Fw::String("ExternalStackRandom"), state, 1000); } diff --git a/Fw/DataStructures/test/ut/STest/StackTestRules.cpp b/Fw/DataStructures/test/ut/STest/StackTestRules.cpp index e1f87ddddd8..01dd73c4818 100644 --- a/Fw/DataStructures/test/ut/STest/StackTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/StackTestRules.cpp @@ -12,16 +12,16 @@ namespace StackTest { namespace Rules { -#if 0 -EnqueueOK enqueueOK; +PushOK pushOK; -EnqueueFull enqueueFull; +PushFull pushFull; +#if 0 At at; -DequeueOK dequeueOK; +PopOK popOK; -DequeueEmpty dequeueEmpty; +PopEmpty popEmpty; Clear clear; #endif diff --git a/Fw/DataStructures/test/ut/STest/StackTestRules.hpp b/Fw/DataStructures/test/ut/STest/StackTestRules.hpp index a16140baebd..f25a770a5a7 100644 --- a/Fw/DataStructures/test/ut/STest/StackTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/StackTestRules.hpp @@ -21,77 +21,77 @@ using Rule = STest::Rule; namespace Rules { -#if 0 -struct EnqueueOK : public Rule { - EnqueueOK() : Rule("EnqueueOK") {} - bool precondition(const State& state) { return static_cast(state.queue.getSize()) < State::capacity; } +struct PushOK : public Rule { + PushOK() : Rule("PushOK") {} + bool precondition(const State& state) { return static_cast(state.stack.getSize()) < State::capacity; } void action(State& state) { const U32 value = STest::Pick::any(); - const auto status = state.queue.enqueue(value); + const auto status = state.stack.push(value); ASSERT_EQ(status, Success::SUCCESS); - state.modelQueue.push_back(value); + state.modelStack.push_back(value); } }; -extern EnqueueOK enqueueOK; +extern PushOK pushOK; -struct EnqueueFull : public Rule { - EnqueueFull() : Rule("EnqueueFull") {} - bool precondition(const State& state) { return static_cast(state.queue.getSize()) >= State::capacity; } +struct PushFull : public Rule { + PushFull() : Rule("PushFull") {} + bool precondition(const State& state) { return static_cast(state.stack.getSize()) >= State::capacity; } void action(State& state) { const auto item = State::getRandomItem(); - const auto status = state.queue.enqueue(item); + const auto status = state.stack.push(item); ASSERT_EQ(status, Success::FAILURE); } }; -extern EnqueueFull enqueueFull; +extern PushFull pushFull; +#if 0 struct At : public Rule { At() : Rule("At") {} - bool precondition(const State& state) { return state.queue.getSize() > 0; } + bool precondition(const State& state) { return state.stack.getSize() > 0; } void action(State& state) { - const auto index = STest::Pick::startLength(0, static_cast(state.queue.getSize())); - ASSERT_EQ(state.queue.at(index), state.modelQueue.at(index)); + const auto index = STest::Pick::startLength(0, static_cast(state.stack.getSize())); + ASSERT_EQ(state.stack.at(index), state.modelQueue.at(index)); } }; extern At at; -struct DequeueOK : public Rule { - DequeueOK() : Rule("DequeueOK") {} - bool precondition(const State& state) { return static_cast(state.queue.getSize()) > 0; } +struct DestackOK : public Rule { + DestackOK() : Rule("DestackOK") {} + bool precondition(const State& state) { return static_cast(state.stack.getSize()) > 0; } void action(State& state) { U32 value = 0; - const auto status = state.queue.dequeue(value); + const auto status = state.stack.pop(value); ASSERT_EQ(status, Success::SUCCESS); const auto expectedValue = state.modelQueue.at(0); ASSERT_EQ(value, expectedValue); state.modelQueue.pop_front(); - ASSERT_EQ(state.queue.getSize(), state.modelQueue.size()); + ASSERT_EQ(state.stack.getSize(), state.modelQueue.size()); } }; -extern DequeueOK dequeueOK; +extern DestackOK popOK; -struct DequeueEmpty : public Rule { - DequeueEmpty() : Rule("DequeueEmpty") {} - bool precondition(const State& state) { return static_cast(state.queue.getSize()) == 0; } +struct DestackEmpty : public Rule { + DestackEmpty() : Rule("DestackEmpty") {} + bool precondition(const State& state) { return static_cast(state.stack.getSize()) == 0; } void action(State& state) { U32 value = 0; - const auto status = state.queue.dequeue(value); + const auto status = state.stack.pop(value); ASSERT_EQ(status, Success::FAILURE); } }; -extern DequeueEmpty dequeueEmpty; +extern DestackEmpty popEmpty; struct Clear : public Rule { Clear() : Rule("Clear") {} - bool precondition(const State& state) { return state.queue.getSize() > 0; } + bool precondition(const State& state) { return state.stack.getSize() > 0; } void action(State& state) { - state.queue.clear(); - ASSERT_EQ(state.queue.getSize(), 0); + state.stack.clear(); + ASSERT_EQ(state.stack.getSize(), 0); state.modelQueue.clear(); } }; diff --git a/Fw/DataStructures/test/ut/STest/StackTestState.hpp b/Fw/DataStructures/test/ut/STest/StackTestState.hpp index 285e4416e91..9f3779e7fc5 100644 --- a/Fw/DataStructures/test/ut/STest/StackTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/StackTestState.hpp @@ -7,7 +7,7 @@ #ifndef StackTestState_HPP #define StackTestState_HPP -#include +#include #include "Fw/DataStructures/Stack.hpp" #include "STest/STest/Pick/Pick.hpp" @@ -32,7 +32,7 @@ struct State { //! The stack under test StackBase& stack; //! The stack for modeling correct behavior - std::deque modelStack; + std::vector modelStack; //! Get a random item static ItemType getRandomItem() { return STest::Pick::any(); } }; From c52abac211edcfb3b7aca0b8d026a2e42d4a8d40 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 18 Jun 2025 16:19:27 -0700 Subject: [PATCH 245/458] Revise ExternalStackTest --- .../test/ut/ExternalStackTest.cpp | 8 ++++-- .../test/ut/STest/StackTestRules.cpp | 2 +- .../test/ut/STest/StackTestRules.hpp | 28 ++++++++++--------- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/Fw/DataStructures/test/ut/ExternalStackTest.cpp b/Fw/DataStructures/test/ut/ExternalStackTest.cpp index 44fde3c0973..6287e55e56d 100644 --- a/Fw/DataStructures/test/ut/ExternalStackTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalStackTest.cpp @@ -238,12 +238,13 @@ TEST(ExternalStackRules, PushFull) { Rules::pushFull.apply(state); } -#if 0 TEST(ExternalStackRules, At) { U32 items[State::capacity]; State::ExternalStack stack(items, State::capacity); State state(stack); - Rules::pushOK.apply(state); + for (FwSizeType i = 0; i < State::capacity; i++) { + Rules::pushOK.apply(state); + } Rules::at.apply(state); } @@ -252,9 +253,12 @@ TEST(ExternalStackRules, PopOK) { State::ExternalStack stack(items, State::capacity); State state(stack); Rules::pushOK.apply(state); + Rules::pushOK.apply(state); + Rules::popOK.apply(state); Rules::popOK.apply(state); } +#if 0 TEST(ExternalStackRules, PopEmpty) { U32 items[State::capacity]; State::ExternalStack stack(items, State::capacity); diff --git a/Fw/DataStructures/test/ut/STest/StackTestRules.cpp b/Fw/DataStructures/test/ut/STest/StackTestRules.cpp index 01dd73c4818..dce16f54f4a 100644 --- a/Fw/DataStructures/test/ut/STest/StackTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/StackTestRules.cpp @@ -16,11 +16,11 @@ PushOK pushOK; PushFull pushFull; -#if 0 At at; PopOK popOK; +#if 0 PopEmpty popEmpty; Clear clear; diff --git a/Fw/DataStructures/test/ut/STest/StackTestRules.hpp b/Fw/DataStructures/test/ut/STest/StackTestRules.hpp index f25a770a5a7..b28be1a1cbf 100644 --- a/Fw/DataStructures/test/ut/STest/StackTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/StackTestRules.hpp @@ -46,36 +46,38 @@ struct PushFull : public Rule { extern PushFull pushFull; -#if 0 struct At : public Rule { At() : Rule("At") {} bool precondition(const State& state) { return state.stack.getSize() > 0; } void action(State& state) { - const auto index = STest::Pick::startLength(0, static_cast(state.stack.getSize())); - ASSERT_EQ(state.stack.at(index), state.modelQueue.at(index)); + const auto size = state.stack.getSize(); + const auto index = STest::Pick::startLength(0, static_cast(size)); + ASSERT_EQ(state.stack.at(index), state.modelStack.at(size - 1 - index)); } }; extern At at; -struct DestackOK : public Rule { - DestackOK() : Rule("DestackOK") {} +struct PopOK : public Rule { + PopOK() : Rule("PopOK") {} bool precondition(const State& state) { return static_cast(state.stack.getSize()) > 0; } void action(State& state) { + const auto size = state.stack.getSize(); U32 value = 0; const auto status = state.stack.pop(value); ASSERT_EQ(status, Success::SUCCESS); - const auto expectedValue = state.modelQueue.at(0); + const auto expectedValue = state.modelStack.at(size - 1); ASSERT_EQ(value, expectedValue); - state.modelQueue.pop_front(); - ASSERT_EQ(state.stack.getSize(), state.modelQueue.size()); + state.modelStack.pop_back(); + ASSERT_EQ(state.stack.getSize(), state.modelStack.size()); } }; -extern DestackOK popOK; +extern PopOK popOK; -struct DestackEmpty : public Rule { - DestackEmpty() : Rule("DestackEmpty") {} +#if 0 +struct PopEmpty : public Rule { + PopEmpty() : Rule("PopEmpty") {} bool precondition(const State& state) { return static_cast(state.stack.getSize()) == 0; } void action(State& state) { U32 value = 0; @@ -84,7 +86,7 @@ struct DestackEmpty : public Rule { } }; -extern DestackEmpty popEmpty; +extern PopEmpty popEmpty; struct Clear : public Rule { Clear() : Rule("Clear") {} @@ -92,7 +94,7 @@ struct Clear : public Rule { void action(State& state) { state.stack.clear(); ASSERT_EQ(state.stack.getSize(), 0); - state.modelQueue.clear(); + state.modelStack.clear(); } }; From c7128fd0b62d3b91f491e3376b8e0e3a19d3c100 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 18 Jun 2025 16:25:08 -0700 Subject: [PATCH 246/458] Revise ExternalStackTest --- Fw/DataStructures/test/ut/ExternalStackTest.cpp | 4 ---- .../test/ut/STest/StackTestRules.cpp | 2 -- .../test/ut/STest/StackTestRules.hpp | 2 -- .../test/ut/STest/StackTestScenarios.cpp | 15 ++++++++------- 4 files changed, 8 insertions(+), 15 deletions(-) diff --git a/Fw/DataStructures/test/ut/ExternalStackTest.cpp b/Fw/DataStructures/test/ut/ExternalStackTest.cpp index 6287e55e56d..854f3e2a308 100644 --- a/Fw/DataStructures/test/ut/ExternalStackTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalStackTest.cpp @@ -258,7 +258,6 @@ TEST(ExternalStackRules, PopOK) { Rules::popOK.apply(state); } -#if 0 TEST(ExternalStackRules, PopEmpty) { U32 items[State::capacity]; State::ExternalStack stack(items, State::capacity); @@ -271,9 +270,7 @@ TEST(ExternalStackRules, Clear) { State::ExternalStack stack(items, State::capacity); State state(stack); Rules::pushOK.apply(state); - ASSERT_EQ(state.stack.getSize(), 1); Rules::clear.apply(state); - ASSERT_EQ(state.stack.getSize(), 0); } TEST(ExternalStackScenarios, Random) { @@ -282,7 +279,6 @@ TEST(ExternalStackScenarios, Random) { State state(stack); Scenarios::random(Fw::String("ExternalStackRandom"), state, 1000); } -#endif } // namespace StackTest } // namespace Fw diff --git a/Fw/DataStructures/test/ut/STest/StackTestRules.cpp b/Fw/DataStructures/test/ut/STest/StackTestRules.cpp index dce16f54f4a..b6abf2df22d 100644 --- a/Fw/DataStructures/test/ut/STest/StackTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/StackTestRules.cpp @@ -20,11 +20,9 @@ At at; PopOK popOK; -#if 0 PopEmpty popEmpty; Clear clear; -#endif }; // namespace Rules diff --git a/Fw/DataStructures/test/ut/STest/StackTestRules.hpp b/Fw/DataStructures/test/ut/STest/StackTestRules.hpp index b28be1a1cbf..78ddddb3698 100644 --- a/Fw/DataStructures/test/ut/STest/StackTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/StackTestRules.hpp @@ -75,7 +75,6 @@ struct PopOK : public Rule { extern PopOK popOK; -#if 0 struct PopEmpty : public Rule { PopEmpty() : Rule("PopEmpty") {} bool precondition(const State& state) { return static_cast(state.stack.getSize()) == 0; } @@ -99,7 +98,6 @@ struct Clear : public Rule { }; extern Clear clear; -#endif }; // namespace Rules diff --git a/Fw/DataStructures/test/ut/STest/StackTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/StackTestScenarios.cpp index 7e9f5f5e4d0..284ee8518f7 100644 --- a/Fw/DataStructures/test/ut/STest/StackTestScenarios.cpp +++ b/Fw/DataStructures/test/ut/STest/StackTestScenarios.cpp @@ -16,18 +16,19 @@ namespace StackTest { namespace Scenarios { void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { - (void) name; - (void) state; - (void) maxNumSteps; -#if 0 - Rule* rules[] = {&Rules::enqueueOK, &Rules::enqueueFull, &Rules::at, - &Rules::dequeueOK, &Rules::dequeueEmpty, &Rules::clear}; + Rule* rules[] = { + &Rules::pushOK, + &Rules::pushFull, + &Rules::at, + &Rules::popOK, + &Rules::popEmpty, + &Rules::clear + }; STest::RandomScenario scenario("RandomScenario", rules, sizeof(rules) / sizeof(STest::RandomScenario*)); STest::BoundedScenario boundedScenario(name.toChar(), scenario, maxNumSteps); const U32 numSteps = boundedScenario.run(state); printf("Ran %u steps.\n", numSteps); -#endif } } // namespace Scenarios From dffe5492fbbfbf25628cd2514cc1127dd43dbbf1 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 18 Jun 2025 16:35:33 -0700 Subject: [PATCH 247/458] Add StackTest --- Fw/DataStructures/CMakeLists.txt | 1 + .../test/ut/ExternalStackTest.cpp | 50 ++-- Fw/DataStructures/test/ut/StackTest.cpp | 233 ++++++++++++++++++ 3 files changed, 259 insertions(+), 25 deletions(-) create mode 100644 Fw/DataStructures/test/ut/StackTest.cpp diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index 3e7f441cef6..7b6188d72a3 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -12,6 +12,7 @@ set(UT_SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" diff --git a/Fw/DataStructures/test/ut/ExternalStackTest.cpp b/Fw/DataStructures/test/ut/ExternalStackTest.cpp index 854f3e2a308..32211c8019d 100644 --- a/Fw/DataStructures/test/ut/ExternalStackTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalStackTest.cpp @@ -108,35 +108,35 @@ TEST(ExternalStack, CopyConstructor) { constexpr FwSizeType capacity = 3; U32 items[capacity]; // Call the constructor providing backing storage - ExternalStack q1(items, capacity); + ExternalStack s1(items, capacity); // Push an item U32 value = 42; - const auto status = q1.push(value); + const auto status = s1.push(value); ASSERT_EQ(status, Success::SUCCESS); // Call the copy constructor - ExternalStack q2(q1); - ExternalStackTester tester1(q1); - ExternalStackTester tester2(q2); + ExternalStack s2(s1); + ExternalStackTester tester1(s1); + ExternalStackTester tester2(s2); ASSERT_EQ(tester2.getItems().getElements(), items); ASSERT_EQ(tester2.getItems().getSize(), capacity); - ASSERT_EQ(q2.getSize(), 1); + ASSERT_EQ(s2.getSize(), 1); } TEST(ExternalStack, CopyAssignmentOperator) { constexpr FwSizeType capacity = 3; U32 items[capacity]; // Call the constructor providing backing storage - ExternalStack q1(items, capacity); + ExternalStack s1(items, capacity); // Push an item U32 value = 42; - const auto status = q1.push(value); + const auto status = s1.push(value); ASSERT_EQ(status, Success::SUCCESS); // Call the default constructor - ExternalStack q2; - ASSERT_EQ(q2.getSize(), 0); + ExternalStack s2; + ASSERT_EQ(s2.getSize(), 0); // Call the copy assignment operator - q2 = q1; - ASSERT_EQ(q2.getSize(), 1); + s2 = s1; + ASSERT_EQ(s2.getSize(), 1); } TEST(ExternalStack, PopOK) { @@ -182,17 +182,17 @@ TEST(ExternalStack, PopEmpty) { namespace { -void testCopyDataFrom(StackBase& q1, FwSizeType size1, StackBase& q2) { - q1.clear(); +void testCopyDataFrom(StackBase& s1, FwSizeType size1, StackBase& s2) { + s1.clear(); for (FwSizeType i = 0; i < size1; i++) { - const auto status = q1.push(static_cast(i)); + const auto status = s1.push(static_cast(i)); ASSERT_EQ(status, Success::SUCCESS); } - q2.copyDataFrom(q1); - const auto capacity2 = q2.getCapacity(); + s2.copyDataFrom(s1); + const auto capacity2 = s2.getCapacity(); const FwSizeType size = FW_MIN(size1, capacity2); for (FwSizeType i = 0; i < size; i++) { - ASSERT_EQ(q1.at(i), q2.at(i)); + ASSERT_EQ(s1.at(i), s2.at(i)); } } @@ -203,21 +203,21 @@ TEST(ExternalStack, CopyDataFrom) { constexpr FwSizeType smallSize = maxSize / 2; U32 items1[maxSize]; U32 items2[maxSize]; - ExternalStack q1(items1, maxSize); + ExternalStack s1(items1, maxSize); // size1 < capacity2 { - ExternalStack q2(items2, maxSize); - testCopyDataFrom(q1, smallSize, q2); + ExternalStack s2(items2, maxSize); + testCopyDataFrom(s1, smallSize, s2); } // size1 == size2 { - ExternalStack q2(items2, maxSize); - testCopyDataFrom(q1, maxSize, q2); + ExternalStack s2(items2, maxSize); + testCopyDataFrom(s1, maxSize, s2); } // size1 > size2 { - ExternalStack q2(items2, smallSize); - testCopyDataFrom(q1, maxSize, q2); + ExternalStack s2(items2, smallSize); + testCopyDataFrom(s1, maxSize, s2); } } diff --git a/Fw/DataStructures/test/ut/StackTest.cpp b/Fw/DataStructures/test/ut/StackTest.cpp new file mode 100644 index 00000000000..cac08ec79e3 --- /dev/null +++ b/Fw/DataStructures/test/ut/StackTest.cpp @@ -0,0 +1,233 @@ +// ====================================================================== +// \title StackTest.cpp +// \author bocchino +// \brief cpp file for Stack tests +// ====================================================================== + +#include "Fw/DataStructures/test/ut/STest/StackTestRules.hpp" +#include "Fw/DataStructures/test/ut/STest/StackTestScenarios.hpp" + +namespace Fw { + +template +class StackTester { + public: + StackTester(const Stack& stack) : m_stack(stack) {} + + const ExternalStack getExtStack() const { return this->m_stack.extStack; } + + const typename Array::Elements& getItems() const { return this->m_stack.m_items; } + + private: + const Stack& m_stack; +}; + +namespace StackTest { + +TEST(Stack, ZeroArgConstructor) { + constexpr FwSizeType C = 10; + Stack stack; + ASSERT_EQ(stack.getCapacity(), C); + ASSERT_EQ(stack.getSize(), 0); +} + +TEST(Stack, CopyConstructor) { + constexpr FwSizeType capacity = 3; + // Construct s1 + Stack s1; + // Push an item + U32 value = 42; + const auto status = s1.push(value); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(s1.getSize(), 1); + // Use the copy constructor to construct s2 + Stack s2(s1); + ASSERT_EQ(s2.getSize(), 1); +} + +TEST(Stack, PushOK) { + constexpr const FwSizeType capacity = 1000; + const FwSizeType size = STest::Pick::lowerUpper(1, capacity); + Stack stack; + ASSERT_EQ(stack.getCapacity(), capacity); + ASSERT_EQ(stack.getSize(), 0); + for (FwSizeType i = 0; i < size; i++) { + // Pick a value + const U32 val = STest::Pick::any(); + // Push it + auto status = stack.push(val); + ASSERT_EQ(status, Success::SUCCESS); + // Peek it + U32 val1 = 0; + status = stack.peek(val1); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(val1, val); + // Check the size + ASSERT_EQ(stack.getSize(), i + 1); + } + stack.clear(); + ASSERT_EQ(stack.getSize(), 0); +} + +TEST(Stack, PushFull) { + constexpr const FwSizeType capacity = 1000; + Stack stack; + // Fill up the FIFO + for (FwSizeType i = 0; i < capacity; i++) { + const auto status = stack.push(0); + ASSERT_EQ(status, Success::SUCCESS); + } + // Now try to push another element + const U32 val = STest::Pick::any(); + const auto status = stack.push(val); + // Push should fail + ASSERT_EQ(status, Success::FAILURE); +} + +TEST(Stack, CopyAssignmentOperator) { + constexpr FwSizeType capacity = 3; + // Call the constructor providing backing storage + Stack s1; + // Push an item + U32 value = 42; + (void)s1.push(value); + // Call the default constructor + Stack s2; + ASSERT_EQ(s2.getSize(), 0); + // Call the copy assignment operator + s2 = s1; + ASSERT_EQ(s2.getSize(), 1); +} + +TEST(Stack, PopOK) { + constexpr const FwSizeType capacity = 1000; + const FwSizeType size = STest::Pick::lowerUpper(1, capacity); + U32 items[capacity]; + Stack stack; + ASSERT_EQ(stack.getCapacity(), capacity); + ASSERT_EQ(stack.getSize(), 0); + for (FwSizeType i = 0; i < size; i++) { + // Pick a value + const U32 val = STest::Pick::any(); + // Push it + const auto status = stack.push(val); + items[i] = val; + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(stack.getSize(), i + 1); + } + for (FwSizeType i = 0; i < size; i++) { + const FwSizeType stackIndex = size - 1 - i; + U32 val = 0; + // Peek + auto status = stack.peek(val); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(val, items[stackIndex]); + // Pop it + status = stack.pop(val); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(val, items[stackIndex]); + ASSERT_EQ(stack.getSize(), stackIndex); + } + ASSERT_EQ(stack.getSize(), 0); +} + +TEST(Stack, PopEmpty) { + constexpr const FwSizeType capacity = 1000; + Stack stack; + U32 val = 0; + const auto status = stack.pop(val); + ASSERT_EQ(status, Success::FAILURE); +} + +namespace { + +void testCopyDataFrom(StackBase& s1, FwSizeType size1, StackBase& s2) { + s1.clear(); + for (FwSizeType i = 0; i < size1; i++) { + const auto status = s1.push(static_cast(i)); + ASSERT_EQ(status, Success::SUCCESS); + } + s2.copyDataFrom(s1); + const auto capacity2 = s2.getCapacity(); + const FwSizeType size = FW_MIN(size1, capacity2); + for (FwSizeType i = 0; i < size; i++) { + ASSERT_EQ(s1.at(i), s2.at(i)); + } +} + +} // namespace + +TEST(Stack, CopyDataFrom) { + constexpr FwSizeType maxSize = 10; + constexpr FwSizeType smallSize = maxSize / 2; + Stack s1; + // size1 < capacity2 + { + Stack s2; + testCopyDataFrom(s1, smallSize, s2); + } + // size1 == size2 + { + Stack s2; + testCopyDataFrom(s1, maxSize, s2); + } + // size1 > size2 + { + Stack s2; + testCopyDataFrom(s1, maxSize, s2); + } +} + +TEST(StackRules, PushOK) { + State::Stack stack; + State state(stack); + Rules::pushOK.apply(state); +} + +TEST(StackRules, PushFull) { + State::Stack stack; + State state(stack); + for (FwSizeType i = 0; i < State::capacity; i++) { + Rules::pushOK.apply(state); + } + Rules::pushFull.apply(state); +} + +TEST(StackRules, At) { + State::Stack stack; + State state(stack); + Rules::pushOK.apply(state); + for (FwSizeType i = 0; i < State::capacity; i++) { + Rules::at.apply(state); + } +} + +TEST(StackRules, PopOK) { + State::Stack stack; + State state(stack); + Rules::pushOK.apply(state); + Rules::popOK.apply(state); +} + +TEST(StackRules, PopEmpty) { + State::Stack stack; + State state(stack); + Rules::popEmpty.apply(state); +} + +TEST(StackRules, Clear) { + State::Stack stack; + State state(stack); + Rules::pushOK.apply(state); + Rules::clear.apply(state); +} + +TEST(StackScenarios, Random) { + State::Stack stack; + State state(stack); + Scenarios::random(Fw::String("StackRandom"), state, 1000); +} + +} // namespace StackTest + +} // namespace Fw From 9bb2fe4efde7d1d8eaefcce8fb6c034b81d3d4fb Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 18 Jun 2025 16:40:00 -0700 Subject: [PATCH 248/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalStack.md | 2 +- Fw/DataStructures/docs/StackBase.md | 34 ++++++++++++------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalStack.md b/Fw/DataStructures/docs/ExternalStack.md index 1ec298be76e..699ebb332ea 100644 --- a/Fw/DataStructures/docs/ExternalStack.md +++ b/Fw/DataStructures/docs/ExternalStack.md @@ -220,7 +220,7 @@ const T& at(FwSizeType index) const override 1. Assert `index < m_size`. -1. Return `m_items[index]`. +1. Return `m_items[m_size - 1 - index]`. _Example:_ ```c++ diff --git a/Fw/DataStructures/docs/StackBase.md b/Fw/DataStructures/docs/StackBase.md index b5dfa2b79d8..184e3ceabab 100644 --- a/Fw/DataStructures/docs/StackBase.md +++ b/Fw/DataStructures/docs/StackBase.md @@ -107,7 +107,7 @@ void copyDataFrom(const StackBase& stack) 1. For `i` in [0, `size`) - 1. Set `e = at(i)`. + 1. Set `e = at(size - 1 - i)`. 1. Set `status = push(e)`. @@ -205,17 +205,17 @@ void f(StackBase& stack) { } ``` -### 5.7. push +### 5.7. pop ```c++ -virtual Success push(const T& e) = 0 +virtual Success pop(T& e) = 0 ``` 1. Set `status = Success::FAILURE`. -1. If there is room on the stack for a new item, then +1. If `size > 0` - 1. Add `e` to the right of the stack. + 1. Remove the rightmost item from the stack and store it into `e`. 1. Set `status = Success::SUCCESS`. @@ -225,22 +225,28 @@ _Example:_ ```c++ void f(StackBase& stack) { stack.clear(); - const auto status = stack.push(3); + U32 val = 0; + auto status = stack.pop(val); + ASSERT_EQ(status, Success::FAILURE); + status = stack.push(3); ASSERT_EQ(status, Success::SUCCESS); + status = stack.pop(val); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(val, 3); } ``` -### 5.8. pop +### 5.8. push ```c++ -virtual Success pop(T& e) = 0 +virtual Success push(const T& e) = 0 ``` 1. Set `status = Success::FAILURE`. -1. If `size > 0` +1. If there is room on the stack for a new item, then - 1. Remove the rightmost item from the stack and store it into `e`. + 1. Add `e` to the right of the stack. 1. Set `status = Success::SUCCESS`. @@ -250,13 +256,7 @@ _Example:_ ```c++ void f(StackBase& stack) { stack.clear(); - U32 val = 0; - auto status = stack.pop(val); - ASSERT_EQ(status, Success::FAILURE); - status = stack.push(3); - ASSERT_EQ(status, Success::SUCCESS); - status = stack.pop(val); + const auto status = stack.push(3); ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(val, 3); } ``` From bc583c6c4742241d6d95a2b705bf869bcd13092a Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 18 Jun 2025 16:52:32 -0700 Subject: [PATCH 249/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/MapBase.md | 2 +- Fw/DataStructures/docs/SetBase.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index bd81d7f3965..1de3d589db0 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -168,7 +168,7 @@ void f(const MapBase& map) { const Iterator* getHeadIterator const = 0 ``` -Get the head iterator for the map. +Get a pointer to the head iterator for the map, or `nullptr` if there is none. _Example:_ ```c++ diff --git a/Fw/DataStructures/docs/SetBase.md b/Fw/DataStructures/docs/SetBase.md index 15bb5555438..be130d6d20a 100644 --- a/Fw/DataStructures/docs/SetBase.md +++ b/Fw/DataStructures/docs/SetBase.md @@ -166,7 +166,7 @@ void f(const SetBase& set) { const Iterator* getHeadIterator const = 0 ``` -Get the head iterator for the set. +Get a pointer to the head iterator for the set, or `nullptr` if there is none. _Example:_ ```c++ From 94459237255c2c728f8eec6daae9856507a6b6a2 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 18 Jun 2025 17:06:44 -0700 Subject: [PATCH 250/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/MapIterator.md | 32 ++++++++++++++------------- Fw/DataStructures/docs/SetIterator.md | 28 +++++++++++------------ 2 files changed, 31 insertions(+), 29 deletions(-) diff --git a/Fw/DataStructures/docs/MapIterator.md b/Fw/DataStructures/docs/MapIterator.md index 914c6bdab08..3741adfd276 100644 --- a/Fw/DataStructures/docs/MapIterator.md +++ b/Fw/DataStructures/docs/MapIterator.md @@ -13,35 +13,35 @@ It represents an iterator for a map. |`typename`|`K`|The type of a key in the map| |`typename`|`V`|The type of a value in the map| -## 2. Protected Constructors and Destructors +## 2. Private Constructors and Destructors -### 2.1. Zero-Argument Constructor +### 2.1. Copy Constructor ```c++ -MapIterator() +MapIterator(const MapIterator& map) ``` -Defined as `= default`. +Defined as `= delete`. -### 2.2. Destructor +## 3. Protected Constructors and Destructors + +### 3.1. Zero-Argument Constructor ```c++ -virtual ~MapIterator() +MapIterator() ``` Defined as `= default`. -## 3. Private Constructors - -### 3.1. Copy Constructor +### 3.2. Destructor ```c++ -MapIterator(const MapIterator& map) +virtual ~MapIterator() ``` -Defined as `= delete`. +Defined as `= default`. -## 4. Public Member Functions +## 4. Private Member Functions ### 4.1. operator= @@ -51,7 +51,9 @@ MapIterator& operator=(const MapIterator&) Defined as `= delete`. -### 4.2. getKey +## 5. Public Member Functions + +### 5.1. getKey ```c++ virtual const K& getKey() const = 0 @@ -59,7 +61,7 @@ virtual const K& getKey() const = 0 Return a reference to the key. -### 4.3. getValue +### 5.2. getValue ```c++ virtual const V& getValue() const = 0 @@ -67,7 +69,7 @@ virtual const V& getValue() const = 0 Return a reference to the value. -### 4.4. getNextMapIterator +### 5.3. getNextMapIterator ```c++ virtual MapIterator* getNextMapIterator() = 0 diff --git a/Fw/DataStructures/docs/SetIterator.md b/Fw/DataStructures/docs/SetIterator.md index 60a64910d54..24906c67462 100644 --- a/Fw/DataStructures/docs/SetIterator.md +++ b/Fw/DataStructures/docs/SetIterator.md @@ -12,33 +12,33 @@ It represents an iterator for a set. |----|----|-------| |`typename`|`T`|The type of an element in the set| -## 3. Protected Constructors and Destructors +## 2. Private Constructors and Destructors -### 3.1. Zero-Argument Constructor +### 2.1. Copy Constructor ```c++ -SetIterator() +SetIterator(const SetIterator& set) ``` -Defined as `= default`. +Defined as `= delete`. + +## 3. Protected Constructors and Destructors -### 3.4. Destructor +### 3.1. Zero-Argument Constructor ```c++ -virtual ~SetIterator() +SetIterator() ``` Defined as `= default`. -## Private Constructors and Destructors - -### 3.3. Copy Constructor +### 3.2. Destructor ```c++ -SetIterator(const SetIterator& set) +virtual ~SetIterator() ``` -Defined as `= delete`. +Defined as `= default`. ## 4. Private Member Functions @@ -50,9 +50,9 @@ SetIterator& operator=(const SetIterator& setIterator) Defined as `= delete`. -## Public Member Functions +## 5. Public Member Functions -### 4.2. getElement +### 5.1. getElement ```c++ virtual const T& getElement() const = 0 @@ -60,7 +60,7 @@ virtual const T& getElement() const = 0 Return a reference to the set element stored in the iterator. -### 4.4. getNextSetIterator +### 5.2. getNextSetIterator ```c++ virtual SetIterator* getNextSetIterator() = 0 From 2454c0b95755a34abb116d61460487f1132de9ff Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 18 Jun 2025 17:13:07 -0700 Subject: [PATCH 251/458] Add MapIterator --- Fw/DataStructures/MapIterator.hpp | 66 +++++++++++++++++++++++++++ Fw/DataStructures/docs/MapIterator.md | 2 +- Fw/DataStructures/docs/SetIterator.md | 2 +- 3 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 Fw/DataStructures/MapIterator.hpp diff --git a/Fw/DataStructures/MapIterator.hpp b/Fw/DataStructures/MapIterator.hpp new file mode 100644 index 00000000000..6fe1c87192f --- /dev/null +++ b/Fw/DataStructures/MapIterator.hpp @@ -0,0 +1,66 @@ +// ====================================================================== +// \title MapIterator +// \author bocchino +// \brief An abstract class representing an iterator for a map +// ====================================================================== + +#ifndef Fw_MapIterator_HPP +#define Fw_MapIterator_HPP + +#include "Fw/FPrimeBasicTypes.hpp" + +namespace Fw { + +template +class MapIterator { + private: + // ---------------------------------------------------------------------- + // Private constructors + // ---------------------------------------------------------------------- + + //! Copy constructor deleted in the base class + //! Behavior depends on the implementation + MapIterator(const MapIterator&) = delete; + + protected: + // ---------------------------------------------------------------------- + // Protected constructors and destructors + // ---------------------------------------------------------------------- + + //! Zero-argument constructor + MapIterator() = default; + + //! Destructor + virtual ~MapIterator() = default; + + private: + // ---------------------------------------------------------------------- + // Private member functions + // ---------------------------------------------------------------------- + + //! operator= deleted in the base class + //! Behavior depends on the implementation + //! We avoid virtual user-defined operators + MapIterator& operator=(const MapIterator&) = delete; + + public: + // ---------------------------------------------------------------------- + // Public member functions + // ---------------------------------------------------------------------- + + //! Get the key + //! \return The key + virtual const K& getKey() const = 0; + + //! Get the value + //! \return The value + virtual const V& getValue() const = 0; + + //! Get the next map iterator + //! \return The map iterator, or nullptr if none + virtual const MapIterator* getNextMapIterator() const = 0; +}; + +} // namespace Fw + +#endif diff --git a/Fw/DataStructures/docs/MapIterator.md b/Fw/DataStructures/docs/MapIterator.md index 3741adfd276..87384e0a863 100644 --- a/Fw/DataStructures/docs/MapIterator.md +++ b/Fw/DataStructures/docs/MapIterator.md @@ -72,7 +72,7 @@ Return a reference to the value. ### 5.3. getNextMapIterator ```c++ -virtual MapIterator* getNextMapIterator() = 0 +virtual const MapIterator* getNextMapIterator() = 0 ``` Return a pointer to the next map iterator, or `nullptr` if there is none. diff --git a/Fw/DataStructures/docs/SetIterator.md b/Fw/DataStructures/docs/SetIterator.md index 24906c67462..2290529c5ae 100644 --- a/Fw/DataStructures/docs/SetIterator.md +++ b/Fw/DataStructures/docs/SetIterator.md @@ -63,7 +63,7 @@ Return a reference to the set element stored in the iterator. ### 5.2. getNextSetIterator ```c++ -virtual SetIterator* getNextSetIterator() = 0 +virtual const SetIterator* getNextSetIterator() = 0 ``` Return a pointer to the next iterator for the set, or `nullptr` if From bdbd6f897411a8df0f580300110325beeb69760e Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 18 Jun 2025 17:15:10 -0700 Subject: [PATCH 252/458] Add SetIterator --- Fw/DataStructures/MapIterator.hpp | 4 +- Fw/DataStructures/SetIterator.hpp | 62 +++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 Fw/DataStructures/SetIterator.hpp diff --git a/Fw/DataStructures/MapIterator.hpp b/Fw/DataStructures/MapIterator.hpp index 6fe1c87192f..493fab709d9 100644 --- a/Fw/DataStructures/MapIterator.hpp +++ b/Fw/DataStructures/MapIterator.hpp @@ -48,11 +48,11 @@ class MapIterator { // Public member functions // ---------------------------------------------------------------------- - //! Get the key + //! Get the key associated with this iterator //! \return The key virtual const K& getKey() const = 0; - //! Get the value + //! Get the value associated with this iterator //! \return The value virtual const V& getValue() const = 0; diff --git a/Fw/DataStructures/SetIterator.hpp b/Fw/DataStructures/SetIterator.hpp new file mode 100644 index 00000000000..8fffa30816d --- /dev/null +++ b/Fw/DataStructures/SetIterator.hpp @@ -0,0 +1,62 @@ +// ====================================================================== +// \title SetIterator +// \author bocchino +// \brief An abstract class representing an iterator for a set +// ====================================================================== + +#ifndef Fw_SetIterator_HPP +#define Fw_SetIterator_HPP + +#include "Fw/FPrimeBasicTypes.hpp" + +namespace Fw { + +template +class SetIterator { + private: + // ---------------------------------------------------------------------- + // Private constructors + // ---------------------------------------------------------------------- + + //! Copy constructor deleted in the base class + //! Behavior depends on the implementation + SetIterator(const SetIterator&) = delete; + + protected: + // ---------------------------------------------------------------------- + // Protected constructors and destructors + // ---------------------------------------------------------------------- + + //! Zero-argument constructor + SetIterator() = default; + + //! Destructor + virtual ~SetIterator() = default; + + private: + // ---------------------------------------------------------------------- + // Private member functions + // ---------------------------------------------------------------------- + + //! operator= deleted in the base class + //! Behavior depends on the implementation + //! We avoid virtual user-defined operators + SetIterator& operator=(const SetIterator&) = delete; + + public: + // ---------------------------------------------------------------------- + // Public member functions + // ---------------------------------------------------------------------- + + //! Get the element associated with this iterator + //! \return The element + virtual const T& getElement() const = 0; + + //! Get the next set iterator + //! \return The set iterator, or nullptr if none + virtual const SetIterator* getNextSetIterator() const = 0; +}; + +} // namespace Fw + +#endif From d4ad155bd353536959816a8a6572a61df87653d6 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 18 Jun 2025 17:35:24 -0700 Subject: [PATCH 253/458] Add SetOrMapIterator --- Fw/DataStructures/MapIterator.hpp | 2 +- Fw/DataStructures/SetIterator.hpp | 2 +- Fw/DataStructures/SetOrMapIterator.hpp | 96 ++++++++++++++++++++++ Fw/DataStructures/docs/SetOrMapIterator.md | 16 ++-- 4 files changed, 106 insertions(+), 10 deletions(-) create mode 100644 Fw/DataStructures/SetOrMapIterator.hpp diff --git a/Fw/DataStructures/MapIterator.hpp b/Fw/DataStructures/MapIterator.hpp index 493fab709d9..15a89327879 100644 --- a/Fw/DataStructures/MapIterator.hpp +++ b/Fw/DataStructures/MapIterator.hpp @@ -1,7 +1,7 @@ // ====================================================================== // \title MapIterator // \author bocchino -// \brief An abstract class representing an iterator for a map +// \brief An abstract class template representing an iterator for a map // ====================================================================== #ifndef Fw_MapIterator_HPP diff --git a/Fw/DataStructures/SetIterator.hpp b/Fw/DataStructures/SetIterator.hpp index 8fffa30816d..5dc3deed83d 100644 --- a/Fw/DataStructures/SetIterator.hpp +++ b/Fw/DataStructures/SetIterator.hpp @@ -1,7 +1,7 @@ // ====================================================================== // \title SetIterator // \author bocchino -// \brief An abstract class representing an iterator for a set +// \brief An abstract class template representing an iterator for a set // ====================================================================== #ifndef Fw_SetIterator_HPP diff --git a/Fw/DataStructures/SetOrMapIterator.hpp b/Fw/DataStructures/SetOrMapIterator.hpp new file mode 100644 index 00000000000..672495e78ff --- /dev/null +++ b/Fw/DataStructures/SetOrMapIterator.hpp @@ -0,0 +1,96 @@ +// ====================================================================== +// \title SetOrMapIterator +// \author bocchino +// \brief A class template representing an iterator for a set or map +// ====================================================================== + +#ifndef Fw_SetOrMapIterator_HPP +#define Fw_SetOrMapIterator_HPP + +#include "Fw/DataStructures/MapIterator.hpp" +#include "Fw/DataStructures/SetIterator.hpp" +#include "Fw/FPrimeBasicTypes.hpp" + +namespace Fw { + +template +class SetOrMapIterator final : public MapIterator, SetIterator { + public: + // ---------------------------------------------------------------------- + // Public constructors and destructors + // ---------------------------------------------------------------------- + + //! Zero-argument constructor + SetOrMapIterator() = default; + + //! Constructor providing members + SetOrMapIterator(const KE& keyOrElement, //!< The key or element + const VN& valueOrNil, //!< The value or Nil + const SetOrMapIterator* next = nullptr //!< The next iterator + ) + : m_keyOrElement(keyOrElement), m_valueOrNil(valueOrNil), m_next(next) {} + + //! Copy constructor + SetOrMapIterator(const SetOrMapIterator&) = default; + + //! Destructor + ~SetOrMapIterator() override = default; + + private: + // ---------------------------------------------------------------------- + // Public member functions + // ---------------------------------------------------------------------- + + //! operator= + SetOrMapIterator& operator=(const SetOrMapIterator&) = default; + + //! Get the element associated with this iterator + //! \return The element + const KE& getElement() const override { return this->m_keyOrElement; } + + //! Get the key associated with this iterator + //! \return The key + const KE& getKey() const override { return this->m_keyOrElement; } + + //! Get the value associated with this iterator + //! \return The value + const VN& getValue() const override { return this->m_valueOrNil; } + + //! Get the next iterator + //! \return The iterator, or nullptr if none + const SetOrMapIterator* getNextIterator() const { return this->m_next; } + + //! Get the next map iterator + //! \return The map iterator, or nullptr if none + const MapIterator* getNextMapIterator() const override { return this->m_next; } + + //! Set the key or element + void setKeyOrElement(const KE& keyOrElement //!< The key or element + ) { + this->m_keyOrElement = keyOrElement; + } + + //! Set the next iterator + void setNextIterator(const SetOrMapIterator* next) { this->m_next = next; } + + //! Set the value or Nil + void setValueOrNil(const VN& valueOrNil) { this->m_valueOrNil = valueOrNil; } + + private: + // ---------------------------------------------------------------------- + // Private member variables + // ---------------------------------------------------------------------- + + //! The map key or set element + KE m_keyOrElement = {}; + + //! The value or nil + VN m_valueOrNil = {}; + + //! Pointer to the next iterator or nullptr if none + const SetOrMapIterator* m_next = nullptr; +}; + +} // namespace Fw + +#endif diff --git a/Fw/DataStructures/docs/SetOrMapIterator.md b/Fw/DataStructures/docs/SetOrMapIterator.md index 0dbfcdea898..2f2cd1a13cb 100644 --- a/Fw/DataStructures/docs/SetOrMapIterator.md +++ b/Fw/DataStructures/docs/SetOrMapIterator.md @@ -1,6 +1,6 @@ # SetOrMapIterator -`SetOrMapIterator` is a class template +`SetOrMapIterator` is a final class template defined in [`Fw/DataStructures`](sdd.md). It represents an iterator for a set or a map. @@ -36,7 +36,7 @@ classDiagram |----|----|-------|-------------| |`m_keyOrElement`|`KE`|The map key or set element|C++ default initialization| |`m_valueOrNil`|`VN`|The value or Nil|C++ default initialization| -|`m_next`|`SetOrMapIterator*`|Pointer to the next iterator or `nullptr` if none|`nullptr`| +|`m_next`|`const SetOrMapIterator*`|Pointer to the next iterator or `nullptr` if none|`nullptr`| ## 4. Public Constructors and Destructors @@ -51,7 +51,7 @@ Defined as `= default`. ### 4.2. Constructor Providing Members ```c++ -SetOrMapIterator(const KE& keyOrElement, const VN& valueOrNil, SetOrMapIterator* next = nullptr) +SetOrMapIterator(const KE& keyOrElement, const VN& valueOrNil, const SetOrMapIterator* next = nullptr) ``` 1. Set `m_keyOrElement = keyOrElement`. @@ -105,7 +105,7 @@ Return a reference to `m_keyOrElement`. ### 5.3. getValue ```c++ -const VN& getValue() const +const VN& getValue() const override ``` Return a reference to `m_valueOrNil`. @@ -129,7 +129,7 @@ Return `m_next`. ### 5.5. getNextSetIterator ```c++ -SetIterator* getNextSetIterator() +SetIterator* getNextSetIterator() override ``` Return `m_next`. @@ -145,15 +145,15 @@ Set `m_keyOrElement = keyOrElement`. ### 5.8. setNextIterator ```c++ -void setNextIterator(SetOrMapIterator* next) +void setNextIterator(const SetOrMapIterator* next) ``` Set `m_next = next`. -### 5.7. setValue +### 5.7. setValueOrNil ```c++ -void setValue(const VN& valueOrNil) const +void setValueOrNil(const VN& valueOrNil) const ``` Set `m_valueOrNil = valueOrNil`. From 0a88af23e788a542410be2c5e47871282f3aa4da Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 18 Jun 2025 18:06:14 -0700 Subject: [PATCH 254/458] Add MapBase.hpp --- Fw/DataStructures/CMakeLists.txt | 3 +- Fw/DataStructures/FifoQueueBase.hpp | 2 +- Fw/DataStructures/MapBase.hpp | 114 ++++++++++++++++++ Fw/DataStructures/SetOrMapIterator.hpp | 4 + Fw/DataStructures/StackBase.hpp | 2 +- Fw/DataStructures/docs/MapBase.md | 10 +- .../test/ut/ExternalArrayMapTest.cpp | 16 +++ 7 files changed, 143 insertions(+), 8 deletions(-) create mode 100644 Fw/DataStructures/MapBase.hpp create mode 100644 Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index 7b6188d72a3..2b9c99187fc 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -8,15 +8,16 @@ set(UT_SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" ) set(UT_MOD_DEPS diff --git a/Fw/DataStructures/FifoQueueBase.hpp b/Fw/DataStructures/FifoQueueBase.hpp index 71a71fc3919..2f4193b91ba 100644 --- a/Fw/DataStructures/FifoQueueBase.hpp +++ b/Fw/DataStructures/FifoQueueBase.hpp @@ -1,7 +1,7 @@ // ====================================================================== // \title FifoQueueBase // \author bocchino -// \brief An abstract base class for a FIFO queue +// \brief An abstract base class template for a FIFO queue // ====================================================================== #ifndef Fw_FifoQueueBase_HPP diff --git a/Fw/DataStructures/MapBase.hpp b/Fw/DataStructures/MapBase.hpp new file mode 100644 index 00000000000..7462a603241 --- /dev/null +++ b/Fw/DataStructures/MapBase.hpp @@ -0,0 +1,114 @@ +// ====================================================================== +// \title MapBase +// \author bocchino +// \brief An abstract base class template for a map +// ====================================================================== + +#ifndef Fw_MapBase_HPP +#define Fw_MapBase_HPP + +#include "Fw/DataStructures/SetOrMapIterator.hpp" +#include "Fw/FPrimeBasicTypes.hpp" +#include "Fw/Types/Assert.hpp" +#include "Fw/Types/SuccessEnumAc.hpp" + +namespace Fw { + +template +class MapBase { + private: + // ---------------------------------------------------------------------- + // Public types + // ---------------------------------------------------------------------- + + //! The type of an abstract map iterator + using Iterator = MapIterator; + + //! The type of a concrete map entry + using Entry = SetOrMapIterator; + + private: + // ---------------------------------------------------------------------- + // Private constructors + // ---------------------------------------------------------------------- + + //! Copy constructor deleted in the base class + //! Behavior depends on the implementation + MapBase(const MapBase&) = delete; + + protected: + // ---------------------------------------------------------------------- + // Protected constructors and destructors + // ---------------------------------------------------------------------- + + //! Zero-argument constructor + MapBase() = default; + + //! Destructor + virtual ~MapBase() = default; + + private: + // ---------------------------------------------------------------------- + // Private member functions + // ---------------------------------------------------------------------- + + //! operator= deleted in the base class + //! Behavior depends on the implementation + //! We avoid virtual user-defined operators + MapBase& operator=(const MapBase&) = delete; + + public: + // ---------------------------------------------------------------------- + // Public member functions + // ---------------------------------------------------------------------- + + //! Clear the map + virtual void clear() = 0; + + //! Copy data from another map + void copyDataFrom(const MapBase& map) { + if (&map != this) { + this->clear(); + const auto* e = map.getHeadIterator(); + const FwSizeType size = FW_MIN(map.getSize(), this->getCapacity()); + for (FwSizeType i = 0; i < size; i++) { + FW_ASSERT(e != nullptr); + const auto status = this->insert(e->getKey(), e->getValue()); + FW_ASSERT(status == Success::SUCCESS, static_cast(status)); + e = e->getNextMapIterator(); + } + } + } + + //! Find the value associated with a key in the map + Success find(const K& key, //!< The key (input) + V& value //!< The value (output) + ) const = 0; + + //! Get the capacity (maximum number of items stored in the map) + //! \return The capacity + virtual FwSizeType getCapacity() const = 0; + + //! Get the head iterator for the map + virtual const Iterator* getHeadIterator() const = 0; + + //! Get the size (number of items stored in the map) + //! \return The size + virtual FwSizeType getSize() const = 0; + + //! Insert a (key, value) pair in the map + //! \return Success if there is room in the map + virtual Success insert(const K& key, //!< The key + const V& value //!< The value + ) = 0; + //! Remove a (key, value) pair from the map + //! Store the value into the value parameter if the key was there + //! \return Success if the key was there + virtual Success remove(const K& key, //!< The key (input) + V& value //!< The value (output) + ) = 0; +}; + +} // namespace Fw + +#endif diff --git a/Fw/DataStructures/SetOrMapIterator.hpp b/Fw/DataStructures/SetOrMapIterator.hpp index 672495e78ff..833d90f5d61 100644 --- a/Fw/DataStructures/SetOrMapIterator.hpp +++ b/Fw/DataStructures/SetOrMapIterator.hpp @@ -64,6 +64,10 @@ class SetOrMapIterator final : public MapIterator, SetIterator { //! \return The map iterator, or nullptr if none const MapIterator* getNextMapIterator() const override { return this->m_next; } + //! Get the next set iterator + //! \return The set iterator, or nullptr if none + const SetIterator* getNextSetIterator() const override { return this->m_next; } + //! Set the key or element void setKeyOrElement(const KE& keyOrElement //!< The key or element ) { diff --git a/Fw/DataStructures/StackBase.hpp b/Fw/DataStructures/StackBase.hpp index 2a9732b4325..2db31dd3f49 100644 --- a/Fw/DataStructures/StackBase.hpp +++ b/Fw/DataStructures/StackBase.hpp @@ -1,7 +1,7 @@ // ====================================================================== // \title StackBase // \author bocchino -// \brief An abstract base class for a stack +// \brief An abstract base class template for a stack // ====================================================================== #ifndef Fw_StackBase_HPP diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index 1de3d589db0..7516a0939d9 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -97,7 +97,7 @@ void copyDataFrom(const MapBase& map) 1. Assert `e != nullptr`. - 1. Set `e1 = insert(e->getKey(), e->getValue())`. + 1. Set `status = insert(e->getKey(), e->getValue())`. 1. Assert `status == Success::SUCCESS`. @@ -122,7 +122,7 @@ void f(MapBase& m1, MapBase& m2) { ### 6.3. find ```c++ -Success find(const K& key, V& value) = 0 +Success find(const K& key, V& value) const = 0 ``` 1. If an entry `e` with value `key` exists in the map, @@ -165,7 +165,7 @@ void f(const MapBase& map) { ### 6.5. getHeadIterator ```c++ -const Iterator* getHeadIterator const = 0 +virtual const Iterator* getHeadIterator() const = 0 ``` Get a pointer to the head iterator for the map, or `nullptr` if there is none. @@ -199,7 +199,7 @@ See [**getCapacity**](MapBase.md#64-getcapacity). ### 6.7. insert ```c++ -Success insert(const K& key, const V& value) = 0 +virtual Success insert(const K& key, const V& value) = 0 ``` 1. If an entry `e` exists with the specified key, then update the @@ -226,7 +226,7 @@ void f(MapBase& map) { ### 6.8. remove ```c++ -Success remove(const K& key, V& value) = 0 +virtual Success remove(const K& key, V& value) = 0 ``` 1. If an entry `e` exists with key `key`, then diff --git a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp new file mode 100644 index 00000000000..27ea024eb0f --- /dev/null +++ b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp @@ -0,0 +1,16 @@ +// ====================================================================== +// \title ExternalArrayMapTest.cpp +// \author bocchino +// \brief cpp file for ExternalArrayMap tests +// ====================================================================== + +#include "Fw/DataStructures/SetOrMapIterator.hpp" + +namespace Fw { + +namespace MapTest { + +SetOrMapIterator iterator; + +} // namespace MapTest +} // namespace Fw From 220960144792b759440bc12b6d09cb71c1ca9144 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Fri, 20 Jun 2025 10:26:37 -0700 Subject: [PATCH 255/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/MapBase.hpp | 5 +- Fw/DataStructures/docs/ExternalArrayMap.md | 64 ++++++++++++--------- Fw/DataStructures/docs/ExternalArraySet.md | 65 +++++++++++++--------- Fw/DataStructures/docs/MapBase.md | 3 +- Fw/DataStructures/docs/SetBase.md | 1 + 5 files changed, 78 insertions(+), 60 deletions(-) diff --git a/Fw/DataStructures/MapBase.hpp b/Fw/DataStructures/MapBase.hpp index 7462a603241..0b4b02c0137 100644 --- a/Fw/DataStructures/MapBase.hpp +++ b/Fw/DataStructures/MapBase.hpp @@ -7,7 +7,7 @@ #ifndef Fw_MapBase_HPP #define Fw_MapBase_HPP -#include "Fw/DataStructures/SetOrMapIterator.hpp" +#include "Fw/DataStructures/MapIterator.hpp" #include "Fw/FPrimeBasicTypes.hpp" #include "Fw/Types/Assert.hpp" #include "Fw/Types/SuccessEnumAc.hpp" @@ -24,9 +24,6 @@ class MapBase { //! The type of an abstract map iterator using Iterator = MapIterator; - //! The type of a concrete map entry - using Entry = SetOrMapIterator; - private: // ---------------------------------------------------------------------- // Private constructors diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index 110a9a56228..b1de1582097 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -20,7 +20,15 @@ as the map implementation. `ExternalArrayMap` is publicly derived from [`MapBase`](MapBase.md). -## 3. Private Member Variables +## 3. Public Types + +`ExternalArrayMap` defines the following public types: + +|Name|Definition| +|----|----------| +|`Entry`|Alias of [`SetOrMapIterator`](SetOrMapIterator.md)| + +## 4. Private Member Variables `ExternalArrayMap` has the following private member variables. @@ -33,9 +41,9 @@ classDiagram ExternalArrayMap *-- ArraySetOrMapImpl ``` -## 4. Public Constructors and Destructors +## 5. Public Constructors and Destructors -### 4.1. Zero-Argument Constructor +### 5.1. Zero-Argument Constructor ```c++ ExternalArrayMap() @@ -48,13 +56,13 @@ _Example:_ ExternalArrayMap map; ``` -### 4.2. Constructor Providing Typed Backing Storage +### 5.2. Constructor Providing Typed Backing Storage ```c++ ExternalArrayMap(Entry* entries, FwSizeType capacity) ``` -The type `Entry` is defined [in the base class](MapBase.md#2-public-types). +The type `Entry` is defined [in the base class](MapBase.md#PublicTypes). Call `m_impl.setStorage(entries, capacity)`. @@ -65,15 +73,15 @@ ExternalArrayMap::Entry entries[capacity]; ExternalArrayMap map(entries, capacity); ``` -### 4.3. Constructor Providing Untyped Backing Storage +### 5.3. Constructor Providing Untyped Backing Storage ```c++ ExternalArrayMap(ByteArray data, FwSizeType capacity) ``` `data` must be aligned according to -[`getByteArrayAlignment()`](#61-getbytearrayalignment) and must -contain at least [`getByteArraySize(size)`](#62-getbytearraysize) bytes. +[`getByteArrayAlignment()`](#getByteArrayAlignment) and must +contain at least [`getByteArraySize(size)`](#getByteArraySize) bytes. Call `m_impl.setStorage(data, capacity)`. @@ -86,7 +94,7 @@ alignas(alignment) U8 bytes[byteArraySize]; ExternalArrayMap map(ByteArray(&bytes[0], sizeof bytes), capacity); ``` -### 4.4. Copy Constructor +### 5.4. Copy Constructor ```c++ ExternalArrayMap(const ExternalArrayMap& map) @@ -110,7 +118,7 @@ ExternalArrayMap m2(m1); ASSERT_EQ(m2.getSize(), 1); ``` -### 4.5. Destructor +### 5.5. Destructor ```c++ ~ExternalArrayMap() override @@ -118,9 +126,9 @@ ASSERT_EQ(m2.getSize(), 1); Defined as `= default`. -## 5. Public Member Functions +## 6. Public Member Functions -### 5.1. operator= +### 6.1. operator= ```c++ ExternalArrayMap& operator=(const ExternalArrayMap& map) @@ -151,7 +159,7 @@ m2 = m1; ASSERT_EQ(m2.getSize(), 1); ``` -### 5.2. at +### 6.2. at ```c++ const V& at(FwSizeType index) const @@ -170,7 +178,7 @@ ASSERT_EQ(map.at(0), 1); ASSERT_DEATH(map.at(1), "Assert"); ``` -### 5.3. clear +### 6.3. clear ```c++ void clear() override @@ -189,7 +197,7 @@ map.clear(); ASSERT_EQ(map.getSize(), 0); ``` -### 5.4. find +### 6.4. find ```c++ Success find(const K& key, V& value) override @@ -212,7 +220,7 @@ ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(value, 1); ``` -### 5.5. getCapacity +### 6.5. getCapacity ```c++ FwSizeType getCapacity() const override @@ -228,7 +236,7 @@ ExternalArrayMap map(entries, capacity); ASSERT_EQ(map.getCapacity(), capacity); ``` -### 5.6. getHeadIterator +### 6.6. getHeadIterator ```c++ const Iterator* getHeadIterator const override @@ -252,7 +260,7 @@ ASSERT_EQ(e->getKey(), 0); ASSERT_EQ(e->getValue(), 1); ``` -### 5.7. getSize +### 6.7. getSize ```c++ FwSizeType getSize() const override @@ -273,7 +281,7 @@ size = map.getSize(); ASSERT_EQ(size, 1); ``` -### 5.8. insert +### 6.8. insert ```c++ Success insert(const K& key, const V& value) override @@ -294,7 +302,7 @@ size = map.getSize(); ASSERT_EQ(size, 1); ``` -### 5.9. remove +### 6.9. remove ```c++ Success remove(const K& key, V& value) override @@ -325,7 +333,7 @@ ASSERT_EQ(size, 0); ASSERT_EQ(value, 1); ``` -### 5.10. setStorage (Typed Data) +### 6.10. setStorage (Typed Data) ```c++ void setStorage(Entry* entries, FwSizeType capacity) @@ -343,15 +351,15 @@ ExternalArrayMap::Entry entries[capacity]; map.setStorage(entries, capacity); ``` -### 5.11. setStorage (Untyped Data) +### 6.11. setStorage (Untyped Data) ```c++ void setStorage(ByteArray data, FwSizeType capacity) ``` `data` must be aligned according to -[`getByteArrayAlignment()`](#61-getbytearrayalignment) and must -contain at least [`getByteArraySize(size)`](#62-getbytearraysize) bytes. +[`getByteArrayAlignment()`](#getByteArrayAlignment) and must +contain at least [`getByteArraySize(size)`](#getByteArraySize) bytes. 1. Call `m_entries.setStorage(data, capacity)`. @@ -366,9 +374,10 @@ ExternalArrayMap map; map.setStorage(ByteArray(&bytes[0], sizeof bytes), capacity); ``` -## 6. Public Static Functions +## 7. Public Static Functions -### 6.1. getByteArrayAlignment + +### 7.1. getByteArrayAlignment ```c++ static constexpr U8 getByteArrayAlignment() @@ -376,7 +385,8 @@ static constexpr U8 getByteArrayAlignment() Return `ArraySetOrMapImpl::getByteArrayAlignment()`. -### 6.2. getByteArraySize + +### 7.2. getByteArraySize ```c++ static constexpr FwSizeType getByteArraySize(FwSizeType capacity) diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md index 071301ed96e..a68629ce1b8 100644 --- a/Fw/DataStructures/docs/ExternalArraySet.md +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -19,7 +19,16 @@ as the set implementation. `ExternalArraySet` is publicly derived from [`SetBase`](SetBase.md). -## 3. Private Member Variables + +## 3. Public Types + +`ExternalArrayMap` defines the following public types: + +|Name|Definition| +|----|----------| +|`Entry`|Alias of [`SetOrMapIterator`](SetOrMapIterator.md)| + +## 4. Private Member Variables `ExternalArraySet` has the following private member variables. @@ -27,16 +36,16 @@ as the set implementation. |----|----|-------|-------------| |`m_impl`|[`ArraySetOrMapImpl`](ArraySetOrMapImpl.md)|The set implementation|C++ default initialization| -The type `Nil` is defined [in the base class](SetBase.md#2-public-types). +The type `Nil` is defined [in the base class](SetBase.md#PublicTypes). ```mermaid classDiagram ExternalArraySet *-- ArraySetOrMapImpl ``` -## 4. Public Constructors and Destructors +## 5. Public Constructors and Destructors -### 4.1. Zero-Argument Constructor +### 5.1. Zero-Argument Constructor ```c++ ExternalArraySet() @@ -49,7 +58,7 @@ _Example:_ ExternalArraySet set; ``` -### 4.2. Constructor Providing Typed Backing Storage +### 5.2. Constructor Providing Typed Backing Storage ```c++ ExternalArraySet(Entry* entries, FwSizeType capacity) @@ -66,15 +75,15 @@ ExternalArraySet::Entry entries[capacity]; ExternalArraySet set(entries, capacity); ``` -### 4.3. Constructor Providing Untyped Backing Storage +### 5.3. Constructor Providing Untyped Backing Storage ```c++ ExternalArraySet(ByteArray data, FwSizeType capacity) ``` `data` must be aligned according to -[`getByteArrayAlignment()`](#61-getbytearrayalignment) and must -contain at least [`getByteArraySize(size)`](#62-getbytearraysize) bytes. +[`getByteArrayAlignment()`](#getByteArrayAlignment) and must +contain at least [`getByteArraySize(size)`](#getByteArraySize) bytes. Call `m_impl.setStorage(data, capacity)`. @@ -87,7 +96,7 @@ alignas(alignment) U8 bytes[byteArraySize]; ExternalArraySet set(ByteArray(&bytes[0], sizeof bytes), capacity); ``` -### 4.4. Copy Constructor +### 5.4. Copy Constructor ```c++ ExternalArraySet(const ExternalArraySet& set) @@ -109,7 +118,7 @@ ExternalArraySet m2(m1); ASSERT_EQ(m2.getSize(), 1); ``` -### 4.5. Destructor +### 5.5. Destructor ```c++ ~ExternalArraySet() override @@ -117,9 +126,9 @@ ASSERT_EQ(m2.getSize(), 1); Defined as `= default`. -## 5. Public Member Functions +## 6. Public Member Functions -### 5.1. operator= +### 6.1. operator= ```c++ ExternalArraySet& operator=(const ExternalArraySet& set) @@ -148,7 +157,7 @@ m2 = m1; ASSERT_EQ(m2.getSize(), 1); ``` -### 5.2. at +### 6.2. at ```c++ const V& at(FwSizeType index) const @@ -167,7 +176,7 @@ ASSERT_EQ(set.at(0), 42); ASSERT_DEATH(set.at(1), "Assert"); ``` -### 5.3. clear +### 6.3. clear ```c++ void clear() override @@ -186,7 +195,7 @@ set.clear(); ASSERT_EQ(set.getSize(), 0); ``` -### 5.4. find +### 6.4. find ```c++ Success find(const T& element) override @@ -207,7 +216,7 @@ status = set.find(42); ASSERT_EQ(status, Success::SUCCESS); ``` -### 5.5. getCapacity +### 6.5. getCapacity ```c++ FwSizeType getCapacity() const override @@ -223,7 +232,7 @@ ExternalArraySet set(entries, capacity); ASSERT_EQ(set.getCapacity(), capacity); ``` -### 5.6. getHeadIterator +### 6.6. getHeadIterator ```c++ const Iterator* getHeadIterator const override @@ -246,7 +255,7 @@ FW_ASSERT(e != nullptr); ASSERT_EQ(e->getElement(), 42); ``` -### 5.7. getSize +### 6.7. getSize ```c++ FwSizeType getSize() const override @@ -267,7 +276,7 @@ size = set.getSize(); ASSERT_EQ(size, 1); ``` -### 5.8. insert +### 6.8. insert ```c++ Success insert(const T& element) override @@ -288,7 +297,7 @@ size = set.getSize(); ASSERT_EQ(size, 1); ``` -### 5.9. remove +### 6.9. remove ```c++ Success remove(const T& element) override @@ -319,7 +328,7 @@ ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(size, 0); ``` -### 5.10. setStorage (Typed Data) +### 6.10. setStorage (Typed Data) ```c++ void setStorage(Entry* entries, FwSizeType capacity) @@ -337,15 +346,15 @@ ExternalArraySet::Entry entries[capacity]; set.setStorage(entries, capacity); ``` -### 5.11. setStorage (Untyped Data) +### 6.11. setStorage (Untyped Data) ```c++ void setStorage(ByteArray data, FwSizeType capacity) ``` `data` must be aligned according to -[`getByteArrayAlignment()`](#61-getbytearrayalignment) and must -contain at least [`getByteArraySize(size)`](#62-getbytearraysize) bytes. +[`getByteArrayAlignment()`](#getByteArrayAlignment) and must +contain at least [`getByteArraySize(size)`](#getByteArraySize) bytes. 1. Call `m_entries.setStorage(data, capacity)`. @@ -360,9 +369,10 @@ ExternalArraySet set; set.setStorage(ByteArray(&bytes[0], sizeof bytes), capacity); ``` -## 6. Public Static Functions +## 7. Public Static Functions -### 6.1. getByteArrayAlignment + +### 7.1. getByteArrayAlignment ```c++ static constexpr U8 getByteArrayAlignment() @@ -370,7 +380,8 @@ static constexpr U8 getByteArrayAlignment() Return `ArraySetOrMapImpl::getByteArrayAlignment()`. -### 6.2. getByteArraySize + +### 7.2. getByteArraySize ```c++ static constexpr FwSizeType getByteArraySize(FwSizeType capacity) diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index 7516a0939d9..a4453415464 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -13,6 +13,7 @@ It represents an abstract base class for a map. |`typename`|`K`|The type of a key in the map| |`typename`|`V`|The type of a value in the map| + ## 2. Public Types `MapBase` defines the following public types: @@ -20,8 +21,6 @@ It represents an abstract base class for a map. |Name|Definition| |----|----------| |`Iterator`|Alias of [`MapIterator`](MapIterator.md)| -|`Entry`|Alias of [`SetOrMapIterator`](SetOrMapIterator.md)| - ## 3. Private Constructors diff --git a/Fw/DataStructures/docs/SetBase.md b/Fw/DataStructures/docs/SetBase.md index be130d6d20a..a2db0bbd370 100644 --- a/Fw/DataStructures/docs/SetBase.md +++ b/Fw/DataStructures/docs/SetBase.md @@ -12,6 +12,7 @@ It represents an abstract base class for a set. |----|----|-------| |`typename`|`T`|The type of an element in the set| + ## 2. Public Types `SetBase` defines the following public types: From a4d5e7952a654a3210ddcadebe86ab7ca0eef1fc Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Fri, 20 Jun 2025 10:33:04 -0700 Subject: [PATCH 256/458] Revise SDD for ArraySetOrMapImpl --- Fw/DataStructures/docs/ArraySetOrMapImpl.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Fw/DataStructures/docs/ArraySetOrMapImpl.md b/Fw/DataStructures/docs/ArraySetOrMapImpl.md index ca2dab184e9..1b5cafc0055 100644 --- a/Fw/DataStructures/docs/ArraySetOrMapImpl.md +++ b/Fw/DataStructures/docs/ArraySetOrMapImpl.md @@ -36,6 +36,7 @@ storing the entries in the set or map. ```mermaid classDiagram ArraySetOrMapImpl *-- ExternalArray + ExternalArray "_n_" *-- Entry ``` ## 4. Public Constructors and Destructors From f05212a6ee7de9939ad69abacf39847cab6c0777 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Fri, 20 Jun 2025 10:33:58 -0700 Subject: [PATCH 257/458] Revise SDD for ArraySetOrMapImpl --- Fw/DataStructures/docs/ArraySetOrMapImpl.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/ArraySetOrMapImpl.md b/Fw/DataStructures/docs/ArraySetOrMapImpl.md index 1b5cafc0055..506d7502d04 100644 --- a/Fw/DataStructures/docs/ArraySetOrMapImpl.md +++ b/Fw/DataStructures/docs/ArraySetOrMapImpl.md @@ -36,7 +36,7 @@ storing the entries in the set or map. ```mermaid classDiagram ArraySetOrMapImpl *-- ExternalArray - ExternalArray "_n_" *-- Entry + ExternalArray "1..*" *-- Entry ``` ## 4. Public Constructors and Destructors From 34a293b0642f82177ede5fd7169c176b74d0a330 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Fri, 20 Jun 2025 10:40:19 -0700 Subject: [PATCH 258/458] Revise SDD for ExternalArray --- Fw/DataStructures/docs/ExternalArray.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/ExternalArray.md b/Fw/DataStructures/docs/ExternalArray.md index 91b43d47c05..103c95c743c 100644 --- a/Fw/DataStructures/docs/ExternalArray.md +++ b/Fw/DataStructures/docs/ExternalArray.md @@ -44,6 +44,9 @@ ExternalArray a; ExternalArray(T* elements, FwSizeType size) ``` +`elements` must point to a primitive array of at least `size` +elements of type `T`. + Call `setStorage(elements, size)`. _Example:_ @@ -59,11 +62,12 @@ ExternalArray a(elements, size); ExternalArray(ByteArray data, FwSizeType size) ``` -Call `setStorage(data, size)`. `data` must be aligned according to [`getByteArrayAlignment()`](#51-getbytearrayalignment) and must contain at least [`getByteArraySize(size)`](#52-getbytearraysize) bytes. +Call `setStorage(data, size)`. + _Example:_ ```c++ constexpr FwSizeType size = 3; @@ -221,6 +225,9 @@ ASSERT_EQ(size1, size); void setStorage(T* elements, FwSizeType size) ``` +`elements` must point to a primitive array of at least `size` +elements of type `T`. + Set `m_elements = elements` and `m_size = size`. _Example:_ From 97e3bb6c988766a0e51f23dfe834f25001b80a8a Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Fri, 20 Jun 2025 10:45:46 -0700 Subject: [PATCH 259/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/Array.md | 2 +- Fw/DataStructures/docs/ExternalArray.md | 1 + Fw/DataStructures/docs/ExternalArrayMap.md | 8 ++++++-- Fw/DataStructures/docs/ExternalArraySet.md | 10 +++++++--- Fw/DataStructures/docs/ExternalFifoQueue.md | 6 ++++++ Fw/DataStructures/docs/ExternalStack.md | 6 ++++++ 6 files changed, 27 insertions(+), 6 deletions(-) diff --git a/Fw/DataStructures/docs/Array.md b/Fw/DataStructures/docs/Array.md index a23cb5869ec..72ec46de707 100644 --- a/Fw/DataStructures/docs/Array.md +++ b/Fw/DataStructures/docs/Array.md @@ -173,7 +173,7 @@ ASSERT_EQ(elements2[0], 1); ExternalArray asExternalArray() ``` -Return [`ExternalArray(m_elements, S)`](ExternalArray.md#3-public-constructors-and-destructors) +Return [`ExternalArray(m_elements, S)`](ExternalArray.md#Public-Constructors-and-Destructors) _Example:_ ```c++ diff --git a/Fw/DataStructures/docs/ExternalArray.md b/Fw/DataStructures/docs/ExternalArray.md index 103c95c743c..67ae2f3d5c2 100644 --- a/Fw/DataStructures/docs/ExternalArray.md +++ b/Fw/DataStructures/docs/ExternalArray.md @@ -23,6 +23,7 @@ It stores a pointer to the backing memory _M_. |`m_elements`|`T*`|Pointer to backing memory or `nullptr`|`nullptr`| |`m_size`|`FwSizeType`|Stores the size (number of elements) of the array|0| + ## 3. Public Constructors and Destructors ### 3.1. Zero-Argument Constructor diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index b1de1582097..47cd7866bd2 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -62,6 +62,8 @@ ExternalArrayMap map; ExternalArrayMap(Entry* entries, FwSizeType capacity) ``` +`entries` must point to a primitive array of at least `capacity` +elements of type `Entry`. The type `Entry` is defined [in the base class](MapBase.md#PublicTypes). Call `m_impl.setStorage(entries, capacity)`. @@ -242,7 +244,7 @@ ASSERT_EQ(map.getCapacity(), capacity); const Iterator* getHeadIterator const override ``` -The type `Iterator` is defined [in the base class](MapBase.md#2-public-types). +The type `Iterator` is defined [in the base class](MapBase.md#PublicTypes). Return `m_impl.getHeadIterator()`. @@ -339,7 +341,9 @@ ASSERT_EQ(value, 1); void setStorage(Entry* entries, FwSizeType capacity) ``` -The type `Entry` is defined [in the base class](MapBase.md#2-public-types). +`entries` must point to a primitive array of at least `capacity` +elements of type `Entry`. +The type `Entry` is defined [in the base class](MapBase.md#PublicTypes). Call `m_impl.setStorage(entries, capacity)`. diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md index a68629ce1b8..8543ea832e0 100644 --- a/Fw/DataStructures/docs/ExternalArraySet.md +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -64,7 +64,9 @@ ExternalArraySet set; ExternalArraySet(Entry* entries, FwSizeType capacity) ``` -The type `Entry` is defined [in the base class](SetBase.md#2-public-types). +`entries` must point to a primitive array of at least `capacity` +elements of type `Entry`. +The type `Entry` is defined [in the base class](SetBase.md#2PublicTypes). Call `m_impl.setStorage(entries, capacity)`. @@ -238,7 +240,7 @@ ASSERT_EQ(set.getCapacity(), capacity); const Iterator* getHeadIterator const override ``` -The type `Iterator` is defined [in the base class](SetBase.md#2-public-types). +The type `Iterator` is defined [in the base class](SetBase.md#2PublicTypes). Return `m_impl.getHeadIterator()`. @@ -334,7 +336,9 @@ ASSERT_EQ(size, 0); void setStorage(Entry* entries, FwSizeType capacity) ``` -The type `Entry` is defined [in the base class](SetBase.md#2-public-types). +`entries` must point to a primitive array of at least `capacity` +elements of type `Entry`. +The type `Entry` is defined [in the base class](SetBase.md#PublicTypes). Call `m_impl.setStorage(entries, capacity)`. diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index 08d0fb23505..2ff4c97de0d 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -58,6 +58,9 @@ ExternalFifoQueue queue; ExternalFifoQueue(T* items, FwSizeType capacity) ``` +`items` must point to a primitive array of at least `capacity` +items of type `T`. + 1. Call `setStorage(items, capacity)`. 1. Initialize the other member variables with their default values. @@ -188,6 +191,9 @@ 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`. + 1. Call `m_items.setStorage(items, capacity)`. 1. If `capacity > 0` diff --git a/Fw/DataStructures/docs/ExternalStack.md b/Fw/DataStructures/docs/ExternalStack.md index 699ebb332ea..8d3341c0af9 100644 --- a/Fw/DataStructures/docs/ExternalStack.md +++ b/Fw/DataStructures/docs/ExternalStack.md @@ -54,6 +54,9 @@ ExternalStack stack; ExternalStack(T* items, FwSizeType capacity) ``` +`items` must point to a primitive array of at least `capacity` +items of type `T`. + 1. Call `setStorage(items, capacity)`. 1. Initialize the other member variables with their default values. @@ -176,6 +179,9 @@ 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`. + 1. Call `m_items.setStorage(items, capacity)`. 1. Call `this->clear()`. From 1208b1b1173346703b648ec85f251f6fa26d6df9 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Fri, 20 Jun 2025 10:46:47 -0700 Subject: [PATCH 260/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalArrayMap.md | 6 +++--- Fw/DataStructures/docs/ExternalArraySet.md | 8 ++++---- Fw/DataStructures/docs/MapBase.md | 2 +- Fw/DataStructures/docs/SetBase.md | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index 47cd7866bd2..0df619e1609 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -64,7 +64,7 @@ ExternalArrayMap(Entry* entries, FwSizeType capacity) `entries` must point to a primitive array of at least `capacity` elements of type `Entry`. -The type `Entry` is defined [in the base class](MapBase.md#PublicTypes). +The type `Entry` is defined [in the base class](MapBase.md#Public-Types). Call `m_impl.setStorage(entries, capacity)`. @@ -244,7 +244,7 @@ ASSERT_EQ(map.getCapacity(), capacity); const Iterator* getHeadIterator const override ``` -The type `Iterator` is defined [in the base class](MapBase.md#PublicTypes). +The type `Iterator` is defined [in the base class](MapBase.md#Public-Types). Return `m_impl.getHeadIterator()`. @@ -343,7 +343,7 @@ void setStorage(Entry* entries, FwSizeType capacity) `entries` must point to a primitive array of at least `capacity` elements of type `Entry`. -The type `Entry` is defined [in the base class](MapBase.md#PublicTypes). +The type `Entry` is defined [in the base class](MapBase.md#Public-Types). Call `m_impl.setStorage(entries, capacity)`. diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md index 8543ea832e0..c861c2e091e 100644 --- a/Fw/DataStructures/docs/ExternalArraySet.md +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -36,7 +36,7 @@ as the set implementation. |----|----|-------|-------------| |`m_impl`|[`ArraySetOrMapImpl`](ArraySetOrMapImpl.md)|The set implementation|C++ default initialization| -The type `Nil` is defined [in the base class](SetBase.md#PublicTypes). +The type `Nil` is defined [in the base class](SetBase.md#Public-Types). ```mermaid classDiagram @@ -66,7 +66,7 @@ ExternalArraySet(Entry* entries, FwSizeType capacity) `entries` must point to a primitive array of at least `capacity` elements of type `Entry`. -The type `Entry` is defined [in the base class](SetBase.md#2PublicTypes). +The type `Entry` is defined [in the base class](SetBase.md#2Public-Types). Call `m_impl.setStorage(entries, capacity)`. @@ -240,7 +240,7 @@ ASSERT_EQ(set.getCapacity(), capacity); const Iterator* getHeadIterator const override ``` -The type `Iterator` is defined [in the base class](SetBase.md#2PublicTypes). +The type `Iterator` is defined [in the base class](SetBase.md#2Public-Types). Return `m_impl.getHeadIterator()`. @@ -338,7 +338,7 @@ void setStorage(Entry* entries, FwSizeType capacity) `entries` must point to a primitive array of at least `capacity` elements of type `Entry`. -The type `Entry` is defined [in the base class](SetBase.md#PublicTypes). +The type `Entry` is defined [in the base class](SetBase.md#Public-Types). Call `m_impl.setStorage(entries, capacity)`. diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index a4453415464..25407b34abe 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -13,7 +13,7 @@ It represents an abstract base class for a map. |`typename`|`K`|The type of a key in the map| |`typename`|`V`|The type of a value in the map| - + ## 2. Public Types `MapBase` defines the following public types: diff --git a/Fw/DataStructures/docs/SetBase.md b/Fw/DataStructures/docs/SetBase.md index a2db0bbd370..9bf146e435f 100644 --- a/Fw/DataStructures/docs/SetBase.md +++ b/Fw/DataStructures/docs/SetBase.md @@ -12,7 +12,7 @@ It represents an abstract base class for a set. |----|----|-------| |`typename`|`T`|The type of an element in the set| - + ## 2. Public Types `SetBase` defines the following public types: From cb7a005587bd24e4e751537d116b8c8fdda659ce Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Fri, 20 Jun 2025 10:48:46 -0700 Subject: [PATCH 261/458] Revise MapBase --- Fw/DataStructures/MapBase.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/MapBase.hpp b/Fw/DataStructures/MapBase.hpp index 0b4b02c0137..ff530cd6ed8 100644 --- a/Fw/DataStructures/MapBase.hpp +++ b/Fw/DataStructures/MapBase.hpp @@ -94,13 +94,13 @@ class MapBase { virtual FwSizeType getSize() const = 0; //! Insert a (key, value) pair in the map - //! \return Success if there is room in the map + //! \return SUCCESS if there is room in the map virtual Success insert(const K& key, //!< The key const V& value //!< The value ) = 0; //! Remove a (key, value) pair from the map //! Store the value into the value parameter if the key was there - //! \return Success if the key was there + //! \return SUCCESS if the key was there virtual Success remove(const K& key, //!< The key (input) V& value //!< The value (output) ) = 0; From 8e2e6fecbc8fef397755f7b71557a18e0296eb35 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Fri, 20 Jun 2025 10:49:58 -0700 Subject: [PATCH 262/458] Revise MapBase --- Fw/DataStructures/MapBase.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/MapBase.hpp b/Fw/DataStructures/MapBase.hpp index ff530cd6ed8..a227aff2df4 100644 --- a/Fw/DataStructures/MapBase.hpp +++ b/Fw/DataStructures/MapBase.hpp @@ -16,7 +16,7 @@ namespace Fw { template class MapBase { - private: + public: // ---------------------------------------------------------------------- // Public types // ---------------------------------------------------------------------- From cd2c947d1d6363c0abbfb46ec759576e293654cc Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Fri, 20 Jun 2025 10:52:01 -0700 Subject: [PATCH 263/458] Revise comments --- Fw/DataStructures/ExternalFifoQueue.hpp | 6 +++--- Fw/DataStructures/ExternalStack.hpp | 6 +++--- Fw/DataStructures/FifoQueue.hpp | 6 +++--- Fw/DataStructures/FifoQueueBase.hpp | 6 +++--- Fw/DataStructures/Stack.hpp | 6 +++--- Fw/DataStructures/StackBase.hpp | 6 +++--- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Fw/DataStructures/ExternalFifoQueue.hpp b/Fw/DataStructures/ExternalFifoQueue.hpp index 8ee805fbf91..4393f99fc08 100644 --- a/Fw/DataStructures/ExternalFifoQueue.hpp +++ b/Fw/DataStructures/ExternalFifoQueue.hpp @@ -115,9 +115,9 @@ class ExternalFifoQueue final : public FifoQueueBase { return status; } - //! Get an item at an index - //! Indices go from left to right in the queue - //! Fails an assertion if the index is out of range + //! Get an item at an index. + //! Indices go from left to right in the queue. + //! Fails an assertion if the index is out of range. //! \return The item const T& at(FwSizeType index //!< The index ) const override { diff --git a/Fw/DataStructures/ExternalStack.hpp b/Fw/DataStructures/ExternalStack.hpp index ca372895d12..65a354aab9f 100644 --- a/Fw/DataStructures/ExternalStack.hpp +++ b/Fw/DataStructures/ExternalStack.hpp @@ -98,9 +98,9 @@ class ExternalStack final : public StackBase { return status; } - //! Get an item at an index - //! Indices go from left to right in the stack - //! Fails an assertion if the index is out of range + //! Get an item at an index. + //! Indices go from left to right in the stack. + //! Fails an assertion if the index is out of range. //! \return The item const T& at(FwSizeType index //!< The index ) const override { diff --git a/Fw/DataStructures/FifoQueue.hpp b/Fw/DataStructures/FifoQueue.hpp index 4ac9260f712..e24aa858fbe 100644 --- a/Fw/DataStructures/FifoQueue.hpp +++ b/Fw/DataStructures/FifoQueue.hpp @@ -71,9 +71,9 @@ class FifoQueue final : public FifoQueueBase { //! \return The capacity FwSizeType getCapacity() const override { return this->m_extQueue.getCapacity(); } - //! Get an item at an index - //! Indices go from left to right in the queue - //! Fails an assertion if the index is out of range + //! Get an item at an index. + //! Indices go from left to right in the queue. + //! Fails an assertion if the index is out of range. //! \return The item const T& at(FwSizeType index //!< The index ) const override { diff --git a/Fw/DataStructures/FifoQueueBase.hpp b/Fw/DataStructures/FifoQueueBase.hpp index 2f4193b91ba..0cf81045eda 100644 --- a/Fw/DataStructures/FifoQueueBase.hpp +++ b/Fw/DataStructures/FifoQueueBase.hpp @@ -53,9 +53,9 @@ class FifoQueueBase { //! Clear the queue virtual void clear() = 0; - //! Get an item at an index - //! Indices go from left to right in the queue - //! Fails an assertion if the index is out of range + //! Get an item at an index. + //! Indices go from left to right in the queue. + //! Fails an assertion if the index is out of range. //! \return The item virtual const T& at(FwSizeType index //!< The index ) const = 0; diff --git a/Fw/DataStructures/Stack.hpp b/Fw/DataStructures/Stack.hpp index 891beee13e5..75673b40e85 100644 --- a/Fw/DataStructures/Stack.hpp +++ b/Fw/DataStructures/Stack.hpp @@ -71,9 +71,9 @@ class Stack final : public StackBase { //! \return The capacity FwSizeType getCapacity() const override { return this->m_extStack.getCapacity(); } - //! Get an item at an index - //! Indices go from left to right in the stack - //! Fails an assertion if the index is out of range + //! Get an item at an index. + //! Indices go from left to right in the stack. + //! Fails an assertion if the index is out of range. //! \return The item const T& at(FwSizeType index //!< The index ) const override { diff --git a/Fw/DataStructures/StackBase.hpp b/Fw/DataStructures/StackBase.hpp index 2db31dd3f49..96ec2d2fd41 100644 --- a/Fw/DataStructures/StackBase.hpp +++ b/Fw/DataStructures/StackBase.hpp @@ -53,9 +53,9 @@ class StackBase { //! Clear the stack virtual void clear() = 0; - //! Get an item at an index - //! Indices go from left to right in the stack - //! Fails an assertion if the index is out of range + //! Get an item at an index. + //! Indices go from left to right in the stack. + //! Fails an assertion if the index is out of range. //! \return The item virtual const T& at(FwSizeType index //!< The index ) const = 0; From 599a2137978159a3974664856ae69a478c8163cc Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 22 Jun 2025 14:16:15 -0700 Subject: [PATCH 264/458] Revise SDD for ArraySetOrMapImpl --- Fw/DataStructures/docs/ArraySetOrMapImpl.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/docs/ArraySetOrMapImpl.md b/Fw/DataStructures/docs/ArraySetOrMapImpl.md index 506d7502d04..17b0dd3fc41 100644 --- a/Fw/DataStructures/docs/ArraySetOrMapImpl.md +++ b/Fw/DataStructures/docs/ArraySetOrMapImpl.md @@ -36,7 +36,7 @@ storing the entries in the set or map. ```mermaid classDiagram ArraySetOrMapImpl *-- ExternalArray - ExternalArray "1..*" *-- Entry + ExternalArray *-- "1..*" Entry ``` ## 4. Public Constructors and Destructors @@ -52,7 +52,7 @@ Initialize each member variable with its default value. ### 4.2. Constructor Providing Typed Backing Storage ```c++ -ArraySetOrMapImpl(Iterator* entries, FwSizeType capacity) +ArraySetOrMapImpl(Entry* entries, FwSizeType capacity) ``` 1. Call `setStorage(entries, capacity)`. From b060b4ff81fe1dfc3787af9e3242202f28ed393c Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 22 Jun 2025 14:57:06 -0700 Subject: [PATCH 265/458] Revise Fw/DataStructures --- Fw/DataStructures/ExternalArray.hpp | 6 ++++-- Fw/DataStructures/MapBase.hpp | 4 ++-- Fw/DataStructures/docs/ArraySetOrMapImpl.md | 16 +++++----------- .../test/ut/ExternalArrayMapTest.cpp | 1 + 4 files changed, 12 insertions(+), 15 deletions(-) diff --git a/Fw/DataStructures/ExternalArray.hpp b/Fw/DataStructures/ExternalArray.hpp index c7ecc92766e..3e89ebf41bd 100644 --- a/Fw/DataStructures/ExternalArray.hpp +++ b/Fw/DataStructures/ExternalArray.hpp @@ -25,14 +25,16 @@ class ExternalArray final { //! Zero-argument constructor ExternalArray() {} - //! Constructor providing typed backing storage + //! Constructor providing typed backing storage. + //! elements must point to at least size elements of type T. ExternalArray(T* elements, //!< The elements FwSizeType size //!< The array size ) : m_elements(elements), m_size(size) {} //! Constructor providing untyped backing storage. - //! Data must be aligned for T and must contain at least getByteArraySize(size) bytes. + //! data must be aligned according to getByteArrayAlignment(). + //! data must contain at least getByteArraySize(size) bytes. ExternalArray(ByteArray data, //!< The data FwSizeType size //!< The array size ) { diff --git a/Fw/DataStructures/MapBase.hpp b/Fw/DataStructures/MapBase.hpp index a227aff2df4..c0c6c01b39c 100644 --- a/Fw/DataStructures/MapBase.hpp +++ b/Fw/DataStructures/MapBase.hpp @@ -8,7 +8,6 @@ #define Fw_MapBase_HPP #include "Fw/DataStructures/MapIterator.hpp" -#include "Fw/FPrimeBasicTypes.hpp" #include "Fw/Types/Assert.hpp" #include "Fw/Types/SuccessEnumAc.hpp" @@ -21,7 +20,7 @@ class MapBase { // Public types // ---------------------------------------------------------------------- - //! The type of an abstract map iterator + //! The type of a map iterator using Iterator = MapIterator; private: @@ -78,6 +77,7 @@ class MapBase { } //! Find the value associated with a key in the map + //! SUCCESS if the item was found Success find(const K& key, //!< The key (input) V& value //!< The value (output) ) const = 0; diff --git a/Fw/DataStructures/docs/ArraySetOrMapImpl.md b/Fw/DataStructures/docs/ArraySetOrMapImpl.md index 17b0dd3fc41..7fff640ad1c 100644 --- a/Fw/DataStructures/docs/ArraySetOrMapImpl.md +++ b/Fw/DataStructures/docs/ArraySetOrMapImpl.md @@ -31,7 +31,7 @@ storing the entries in the set or map. |Name|Type|Purpose|Default Value| |----|----|-------|-------------| |`m_entries`|[`ExternalArray`](ExternalArray.md)|The array for storing the set or map entries|C++ default initialization| -|`m_size`|`FwSizeType`|The number of entries in the map|0| +|`m_size`|`FwSizeType`|The number of entries in the set or map|0| ```mermaid classDiagram @@ -55,9 +55,7 @@ Initialize each member variable with its default value. ArraySetOrMapImpl(Entry* entries, FwSizeType capacity) ``` -1. Call `setStorage(entries, capacity)`. - -1. Initialize the other member variables with their default values. +Call `setStorage(entries, capacity)`. ### 4.3. Constructor Providing Untyped Backing Storage @@ -69,9 +67,7 @@ ArraySetOrMapImpl(ByteArray data, FwSizeType capacity) [`getByteArrayAlignment()`](#61-getbytearrayalignment) and must contain at least [`getByteArraySize(size)`](#62-getbytearraysize) bytes. -1. Call `setStorage(data, capacity)`. - -1. Initialize the other member variables with their default values. +Call `setStorage(data, capacity)`. ### 4.4. Copy Constructor @@ -156,15 +152,13 @@ Return `m_entries.getSize()`. ### 5.6. getHeadIterator ```c++ -const Iterator* getHeadIterator const +const Iterator* getHeadIterator() const ``` 1. Set `result = nullptr`. 1. If `m_size > 0` - 1. Assert `m_entries != nullptr`. - 1. Set `result = &m_entries[0]`. 1. Return `result`. @@ -243,7 +237,7 @@ Success remove(const KE& keyOrElement, VN& valueOrNil) ### 5.10. setStorage (Typed Data) ```c++ -void setStorage(T* entries, FwSizeType capacity) +void setStorage(Entry* entries, FwSizeType capacity) ``` 1. Call `m_entries.setStorage(entries, capacity)`. diff --git a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp index 27ea024eb0f..2e9775fb40d 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp @@ -5,6 +5,7 @@ // ====================================================================== #include "Fw/DataStructures/SetOrMapIterator.hpp" +#include "Fw/DataStructures/ArraySetOrMapImpl.hpp" namespace Fw { From e849cf664b4980979ba26c8822e2509ba2e1d6f3 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 22 Jun 2025 16:06:06 -0700 Subject: [PATCH 266/458] Add ArraySetOrMapImpl --- Fw/DataStructures/ArraySetOrMapImpl.hpp | 218 ++++++++++++++++++++ Fw/DataStructures/docs/ArraySetOrMapImpl.md | 2 +- 2 files changed, 219 insertions(+), 1 deletion(-) create mode 100644 Fw/DataStructures/ArraySetOrMapImpl.hpp diff --git a/Fw/DataStructures/ArraySetOrMapImpl.hpp b/Fw/DataStructures/ArraySetOrMapImpl.hpp new file mode 100644 index 00000000000..586b855d01b --- /dev/null +++ b/Fw/DataStructures/ArraySetOrMapImpl.hpp @@ -0,0 +1,218 @@ +// ====================================================================== +// \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/SetOrMapIterator.hpp" +#include "Fw/Types/Assert.hpp" +#include "Fw/Types/SuccessEnumAc.hpp" + +namespace Fw { + +template +class ArraySetOrMapImpl { + public: + // ---------------------------------------------------------------------- + // Public types + // ---------------------------------------------------------------------- + + //! The type of an entry in the set or map + using Entry = SetOrMapIterator; + + //! The type of a set or map iterator + using Iterator = SetOrMapIterator; + + 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& map) { *this = map; } + + //! Destructor + virtual ~ArraySetOrMapImpl() = default; + + public: + // ---------------------------------------------------------------------- + // Public member functions + // ---------------------------------------------------------------------- + + //! operator= + ArraySetOrMapImpl& operator=(const ArraySetOrMapImpl& impl) { + if (&impl != this) { + m_entries = impl.m_entries; + m_size = impl.m_size; + } + return *this; + } + + //! Clear the set or map + void clear() { this->m_size = 0; } + + //! Get an item at an index in the array. + //! Fails an assertion if the index is out of range for the set or map. + const Iterator& at(FwSizeType index //!< The index + ) const { + FW_ASSERT(index < this->m_size, static_cast(index), static_cast(this->m_size)); + return this->m_entries[index]; + } + + //! Find a value associated with a key in the map or an element in a set + //! SUCCESS if the item was found + Success find(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++) { + 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 head iterator for the set or map + const Iterator* getHeadIterator() const { + Iterator* result = nullptr; + if (this->m_size > 0) { + result = &this->m_entries[0]; + } + return result; + } + + //! 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++) { + const auto& e = this->m_entries[i]; + if (e.getKey() == keyOrElement) { + e.setValue(valueOrNil); + status = Success::SUCCESS; + break; + } + } + if ((status == Success::FAILURE) && (this->m_size < this->getCapacity())) { + this->m_entries[this->m_size] = Iterator(keyOrElement, valueOrNil); + if (this->m_size > 0) { + this->m_entries[this->m_size - 1].setNextIterator(&this->m_entries[this->m_size]); + } + 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_entries[i].setNextIterator(&this->m_entries[i + 1]); + } else { + this->m_entries[i].setNextIterator(nullptr); + } + 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::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::getByteArraySize(capacity); + } + + private: + // ---------------------------------------------------------------------- + // Private member variables + // ---------------------------------------------------------------------- + + //! The array for storing the set or map entries + ExternalArray m_entries = {}; + + //! The number of entries in the set or map + FwSizeType m_size = 0; +}; + +} // namespace Fw + +#endif diff --git a/Fw/DataStructures/docs/ArraySetOrMapImpl.md b/Fw/DataStructures/docs/ArraySetOrMapImpl.md index 7fff640ad1c..3a552846be7 100644 --- a/Fw/DataStructures/docs/ArraySetOrMapImpl.md +++ b/Fw/DataStructures/docs/ArraySetOrMapImpl.md @@ -183,7 +183,7 @@ Success insert(const KE& keyOrElement, const VN& valueOrNil) 1. Let `auto& e = m_entries[i]`. - 1. If `e.getKey() == e.keyOrElement` + 1. If `e.getKey() == keyOrElement` 1. Call `e.setValue(valueOrNil)`. From 5bc1525e962f4d4e4afe81ed2e2062c49be4efa7 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 22 Jun 2025 16:16:11 -0700 Subject: [PATCH 267/458] Add ExternalArrayMap --- Fw/DataStructures/ExternalArrayMap.hpp | 92 +++++++++++++++++++ .../test/ut/ExternalArrayMapTest.cpp | 3 +- 2 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 Fw/DataStructures/ExternalArrayMap.hpp diff --git a/Fw/DataStructures/ExternalArrayMap.hpp b/Fw/DataStructures/ExternalArrayMap.hpp new file mode 100644 index 00000000000..bf137a361e6 --- /dev/null +++ b/Fw/DataStructures/ExternalArrayMap.hpp @@ -0,0 +1,92 @@ +// ====================================================================== +// \file ExternalArrayMap.hpp +// \author bocchino +// \brief An array-based map with external storage +// ====================================================================== + +#ifndef Fw_ExternalArrayMap_HPP +#define Fw_ExternalArrayMap_HPP + +#include "Fw/DataStructures/ArraySetOrMapImpl.hpp" +#include "Fw/DataStructures/MapBase.hpp" +#include "Fw/Types/Assert.hpp" + +namespace Fw { + +template +class ExternalArrayMap final : public MapBase { + // ---------------------------------------------------------------------- + // Friend class for testing + // ---------------------------------------------------------------------- + + template + friend class ExternalArrayMapTester; + + public: + // ---------------------------------------------------------------------- + // Public types + // ---------------------------------------------------------------------- + + //! The type of a map entry + using Entry = SetOrMapIterator; + + public: + // ---------------------------------------------------------------------- + // Public constructors and destructors + // ---------------------------------------------------------------------- + + //! Zero-argument constructor + ExternalArrayMap() = default; + + //! Constructor providing typed backing storage. + //! entries must point to at least capacity elements of type Entry. + ExternalArrayMap(Entry* entries, //!< The entries + FwSizeType capacity //!< The capacity + ) + : MapBase() { + this->m_impl.setStorage(entries, capacity); + } + + //! Constructor providing untyped backing storage. + //! data must be aligned according to getByteArrayAlignment(). + //! data must contain at least getByteArraySize(capacity) bytes. + ExternalArrayMap(ByteArray data, //!< The data, + FwSizeType capacity //!< The capacity + ) + : MapBase() { + this->m_impl.setStorage(data, capacity); + } + + //! Copy constructor + ExternalArrayMap(const ExternalArrayMap& map) : MapBase() { *this = map; } + + //! Destructor + ~ExternalArrayMap() override = default; + + public: + // ---------------------------------------------------------------------- + // Public member functions + // ---------------------------------------------------------------------- + + //! operator= + ExternalArrayMap& operator=(const ExternalArrayMap& map) { + if (&map != this) { + this->m_impl = map.m_impl; + } + return *this; + } + + // TODO + + private: + // ---------------------------------------------------------------------- + // Private member variables + // ---------------------------------------------------------------------- + + //! The map implementation + ArraySetOrMapImpl m_impl = {}; +}; + +} // namespace Fw + +#endif diff --git a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp index 2e9775fb40d..e2376a34496 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp @@ -4,8 +4,7 @@ // \brief cpp file for ExternalArrayMap tests // ====================================================================== -#include "Fw/DataStructures/SetOrMapIterator.hpp" -#include "Fw/DataStructures/ArraySetOrMapImpl.hpp" +#include "Fw/DataStructures/ExternalArrayMap.hpp" namespace Fw { From 9e6e93f4379b8e5392dee22311a9d74fb22de111 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 22 Jun 2025 16:32:23 -0700 Subject: [PATCH 268/458] Revise ExternalArrayMap --- Fw/DataStructures/ArraySetOrMapImpl.hpp | 12 ++-- Fw/DataStructures/ExternalArrayMap.hpp | 84 +++++++++++++++++++++- Fw/DataStructures/docs/ExternalArrayMap.md | 4 +- 3 files changed, 92 insertions(+), 8 deletions(-) diff --git a/Fw/DataStructures/ArraySetOrMapImpl.hpp b/Fw/DataStructures/ArraySetOrMapImpl.hpp index 586b855d01b..c05aba2c1cd 100644 --- a/Fw/DataStructures/ArraySetOrMapImpl.hpp +++ b/Fw/DataStructures/ArraySetOrMapImpl.hpp @@ -72,19 +72,20 @@ class ArraySetOrMapImpl { return *this; } - //! Clear the set or map - void clear() { this->m_size = 0; } - - //! Get an item at an index in the array. + //! Get an iterator at an index in the array. //! Fails an assertion if the index is out of range for the set or map. + //! \return The iterator const Iterator& at(FwSizeType index //!< The index ) const { FW_ASSERT(index < this->m_size, static_cast(index), static_cast(this->m_size)); return this->m_entries[index]; } + //! Clear the set or map + void clear() { this->m_size = 0; } + //! Find a value associated with a key in the map or an element in a set - //! SUCCESS if the item was found + //! \return SUCCESS if the item was found Success find(const KE& keyOrElement, //!< The key or element VN& valueOrNil //!< The value or Nil ) { @@ -105,6 +106,7 @@ class ArraySetOrMapImpl { FwSizeType getCapacity() const { return this->m_entries.getSize(); } //! Get the head iterator for the set or map + //! \return The iterator const Iterator* getHeadIterator() const { Iterator* result = nullptr; if (this->m_size > 0) { diff --git a/Fw/DataStructures/ExternalArrayMap.hpp b/Fw/DataStructures/ExternalArrayMap.hpp index bf137a361e6..db063725fb9 100644 --- a/Fw/DataStructures/ExternalArrayMap.hpp +++ b/Fw/DataStructures/ExternalArrayMap.hpp @@ -30,6 +30,9 @@ class ExternalArrayMap final : public MapBase { //! The type of a map entry using Entry = SetOrMapIterator; + //! The type of a map iterator + using Iterator = MapIterator; + public: // ---------------------------------------------------------------------- // Public constructors and destructors @@ -76,7 +79,86 @@ class ExternalArrayMap final : public MapBase { return *this; } - // TODO + //! Get an iterator at an index in the array. + //! Fails an assertion if the index is out of range for the set or map. + //! \return The iterator + const Iterator& at(FwSizeType index //!< The index + ) const { + return this->m_impl.at[index]; + } + + //! Clear the set or map + void clear() { this->m_impl.clear(); } + + //! Find a value associated with a key in the map + //! \return SUCCESS if the item was found + Success find(const K& key, //!< The key + V& value //!< The value + ) { + return this->find(key, value); + } + + //! Get the capacity of the set or map (max number of entries) + //! \return The capacity + FwSizeType getCapacity() const { return this->m_impl.getCapacity(); } + + //! Get the head iterator for the set or map + //! \return The iterator + const Iterator* getHeadIterator() const { return this->m_impl.getHeadIterator(); } + + //! Get the size (number of entries) + //! \return The size + FwSizeType getSize() const { return this->m_impl.getSize(); } + + //! Insert a (key, value) pair in the map + //! \return SUCCESS if there is room in the map + Success insert(const K& key, //!< The key + const V& value //!< The value + ) { + this->m_impl.insert(key, value); + } + + //! 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 K& key, //!< The key + V& value //!< The value + ) { + this->m_impl.remove(key, value); + } + + //! 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_impl.setStorage(entries, capacity); + } + + //! 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_impl.setStorage(data, capacity); + } + + public: + // ---------------------------------------------------------------------- + // Public static functions + // ---------------------------------------------------------------------- + + //! Get the alignment of the storage for an ArraySetOrMapImpl + //! \return The alignment + static constexpr U8 getByteArrayAlignment() { return ArraySetOrMapImpl::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 ArraySetOrMapImpl::getByteArraySize(capacity); + } private: // ---------------------------------------------------------------------- diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index 0df619e1609..fa7031e98e6 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -387,7 +387,7 @@ map.setStorage(ByteArray(&bytes[0], sizeof bytes), capacity); static constexpr U8 getByteArrayAlignment() ``` -Return `ArraySetOrMapImpl::getByteArrayAlignment()`. +Return `ArraySetOrMapImpl::getByteArrayAlignment()`. ### 7.2. getByteArraySize @@ -396,4 +396,4 @@ Return `ArraySetOrMapImpl::getByteArrayAlignment()`. static constexpr FwSizeType getByteArraySize(FwSizeType capacity) ``` -Return `ArraySetOrMapImpl::getByteArraySize(capacity)`. +Return `ArraySetOrMapImpl::getByteArraySize(capacity)`. From e98a386e4f1215338a4894ec5381d82995f05e3b Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 22 Jun 2025 19:18:45 -0700 Subject: [PATCH 269/458] Revise Fw/DataStructures --- Fw/DataStructures/ArraySetOrMapImpl.hpp | 11 +- Fw/DataStructures/ExternalArrayMap.hpp | 20 ++-- Fw/DataStructures/MapBase.hpp | 5 +- Fw/DataStructures/SetBase.hpp | 109 ++++++++++++++++++ Fw/DataStructures/SetOrMapIterator.hpp | 15 ++- Fw/DataStructures/docs/ArraySetOrMapImpl.md | 1 + Fw/DataStructures/docs/MapBase.md | 2 +- Fw/DataStructures/docs/SetBase.md | 10 +- Fw/DataStructures/docs/SetOrMapIterator.md | 10 +- .../test/ut/ExternalArrayMapTest.cpp | 2 +- 10 files changed, 156 insertions(+), 29 deletions(-) create mode 100644 Fw/DataStructures/SetBase.hpp diff --git a/Fw/DataStructures/ArraySetOrMapImpl.hpp b/Fw/DataStructures/ArraySetOrMapImpl.hpp index c05aba2c1cd..fc4652f22e5 100644 --- a/Fw/DataStructures/ArraySetOrMapImpl.hpp +++ b/Fw/DataStructures/ArraySetOrMapImpl.hpp @@ -27,6 +27,9 @@ class ArraySetOrMapImpl { //! The type of a set or map iterator using Iterator = SetOrMapIterator; + //! The Nil type + struct Nil {}; + public: // ---------------------------------------------------------------------- // Public constructors and destructors @@ -88,7 +91,7 @@ class ArraySetOrMapImpl { //! \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]; @@ -108,7 +111,7 @@ class ArraySetOrMapImpl { //! Get the head iterator for the set or map //! \return The iterator const Iterator* getHeadIterator() const { - Iterator* result = nullptr; + const Iterator* result = nullptr; if (this->m_size > 0) { result = &this->m_entries[0]; } @@ -126,9 +129,9 @@ class ArraySetOrMapImpl { ) { auto status = Success::FAILURE; for (FwSizeType i = 0; i < this->m_size; i++) { - const auto& e = this->m_entries[i]; + auto& e = this->m_entries[i]; if (e.getKey() == keyOrElement) { - e.setValue(valueOrNil); + e.setValueOrNil(valueOrNil); status = Success::SUCCESS; break; } diff --git a/Fw/DataStructures/ExternalArrayMap.hpp b/Fw/DataStructures/ExternalArrayMap.hpp index db063725fb9..b3168763997 100644 --- a/Fw/DataStructures/ExternalArrayMap.hpp +++ b/Fw/DataStructures/ExternalArrayMap.hpp @@ -88,42 +88,42 @@ class ExternalArrayMap final : public MapBase { } //! Clear the set or map - void clear() { this->m_impl.clear(); } + void clear() override { this->m_impl.clear(); } //! Find a value associated with a key in the map //! \return SUCCESS if the item was found Success find(const K& key, //!< The key V& value //!< The value - ) { - return this->find(key, value); + ) const override { + return this->m_impl.find(key, value); } //! Get the capacity of the set or map (max number of entries) //! \return The capacity - FwSizeType getCapacity() const { return this->m_impl.getCapacity(); } + FwSizeType getCapacity() const override { return this->m_impl.getCapacity(); } //! Get the head iterator for the set or map //! \return The iterator - const Iterator* getHeadIterator() const { return this->m_impl.getHeadIterator(); } + const Iterator* getHeadIterator() const override { return this->m_impl.getHeadIterator(); } //! Get the size (number of entries) //! \return The size - FwSizeType getSize() const { return this->m_impl.getSize(); } + FwSizeType getSize() const override { return this->m_impl.getSize(); } //! Insert a (key, value) pair in the map //! \return SUCCESS if there is room in the map Success insert(const K& key, //!< The key const V& value //!< The value - ) { - this->m_impl.insert(key, value); + ) override { + return this->m_impl.insert(key, value); } //! 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 K& key, //!< The key V& value //!< The value - ) { - this->m_impl.remove(key, value); + ) override { + return this->m_impl.remove(key, value); } //! Set the backing storage (typed data) diff --git a/Fw/DataStructures/MapBase.hpp b/Fw/DataStructures/MapBase.hpp index c0c6c01b39c..71cf161fc24 100644 --- a/Fw/DataStructures/MapBase.hpp +++ b/Fw/DataStructures/MapBase.hpp @@ -78,8 +78,8 @@ class MapBase { //! Find the value associated with a key in the map //! SUCCESS if the item was found - Success find(const K& key, //!< The key (input) - V& value //!< The value (output) + virtual Success find(const K& key, //!< The key (input) + V& value //!< The value (output) ) const = 0; //! Get the capacity (maximum number of items stored in the map) @@ -87,6 +87,7 @@ class MapBase { virtual FwSizeType getCapacity() const = 0; //! Get the head iterator for the map + //! \return The iterator virtual const Iterator* getHeadIterator() const = 0; //! Get the size (number of items stored in the map) diff --git a/Fw/DataStructures/SetBase.hpp b/Fw/DataStructures/SetBase.hpp new file mode 100644 index 00000000000..68b7bb82443 --- /dev/null +++ b/Fw/DataStructures/SetBase.hpp @@ -0,0 +1,109 @@ +// ====================================================================== +// \title SetBase +// \author bocchino +// \brief An abstract base class template for a set +// ====================================================================== + +#ifndef Fw_SetBase_HPP +#define Fw_SetBase_HPP + +#include "Fw/DataStructures/SetIterator.hpp" +#include "Fw/Types/Assert.hpp" +#include "Fw/Types/SuccessEnumAc.hpp" + +namespace Fw { + +template +class SetBase { + public: + // ---------------------------------------------------------------------- + // Public types + // ---------------------------------------------------------------------- + + //! The type of a set iterator + using Iterator = SetIterator; + + private: + // ---------------------------------------------------------------------- + // Private constructors + // ---------------------------------------------------------------------- + + //! Copy constructor deleted in the base class + //! Behavior depends on the implementation + SetBase(const SetBase&) = delete; + + protected: + // ---------------------------------------------------------------------- + // Protected constructors and destructors + // ---------------------------------------------------------------------- + + //! Zero-argument constructor + SetBase() = default; + + //! Destructor + virtual ~SetBase() = default; + + private: + // ---------------------------------------------------------------------- + // Private member functions + // ---------------------------------------------------------------------- + + //! operator= deleted in the base class + //! Behavior depends on the implementation + //! We avoid virtual user-defined operators + SetBase& operator=(const SetBase&) = delete; + + public: + // ---------------------------------------------------------------------- + // Public member functions + // ---------------------------------------------------------------------- + + //! Clear the set + virtual void clear() = 0; + + //! Copy data from another set + void copyDataFrom(const SetBase& set) { + if (&set != this) { + this->clear(); + const auto* e = set.getHeadIterator(); + const FwSizeType size = FW_MIN(set.getSize(), this->getCapacity()); + for (FwSizeType i = 0; i < size; i++) { + FW_ASSERT(e != nullptr); + const auto status = this->insert(e->getElement()); + FW_ASSERT(status == Success::SUCCESS, static_cast(status)); + e = e->getNextSetIterator(); + } + } + } + + //! Find the an element in a set + //! SUCCESS if the item was found + Success find(const T& element //!< The element + ) const = 0; + + //! Get the capacity (maximum number of items stored in the set) + //! \return The capacity + virtual FwSizeType getCapacity() const = 0; + + //! Get the head iterator for the set + //! \return The iterator + virtual const Iterator* getHeadIterator() const = 0; + + //! Get the size (number of items stored in the set) + //! \return The size + virtual FwSizeType getSize() const = 0; + + //! Insert an element in the set + //! \return SUCCESS if there is room in the set + virtual Success insert(const T& element //!< The element + ) = 0; + + //! Remove an element from the set + //! \return SUCCESS if the element was there + virtual Success remove(const T& element //!< The element + ) = 0; +}; + +} // namespace Fw + +#endif diff --git a/Fw/DataStructures/SetOrMapIterator.hpp b/Fw/DataStructures/SetOrMapIterator.hpp index 833d90f5d61..4b5724cafc2 100644 --- a/Fw/DataStructures/SetOrMapIterator.hpp +++ b/Fw/DataStructures/SetOrMapIterator.hpp @@ -31,18 +31,27 @@ class SetOrMapIterator final : public MapIterator, SetIterator { : m_keyOrElement(keyOrElement), m_valueOrNil(valueOrNil), m_next(next) {} //! Copy constructor - SetOrMapIterator(const SetOrMapIterator&) = default; + SetOrMapIterator(const SetOrMapIterator& iterator) { + *this = iterator; + } //! Destructor ~SetOrMapIterator() override = default; - private: + public: // ---------------------------------------------------------------------- // Public member functions // ---------------------------------------------------------------------- //! operator= - SetOrMapIterator& operator=(const SetOrMapIterator&) = default; + SetOrMapIterator& operator=(const SetOrMapIterator& iterator) { + if (this != &iterator) { + this->m_keyOrElement = iterator.m_keyOrElement; + this->m_valueOrNil = iterator.m_valueOrNil; + this->m_next = iterator.m_next; + } + return *this; + } //! Get the element associated with this iterator //! \return The element diff --git a/Fw/DataStructures/docs/ArraySetOrMapImpl.md b/Fw/DataStructures/docs/ArraySetOrMapImpl.md index 3a552846be7..292109101e3 100644 --- a/Fw/DataStructures/docs/ArraySetOrMapImpl.md +++ b/Fw/DataStructures/docs/ArraySetOrMapImpl.md @@ -23,6 +23,7 @@ storing the entries in the set or map. |----|----------| |`Entry`|Alias for [`SetOrMapIterator`](SetOrMapIterator.md)| |`Iterator`|Alias for [`SetOrMapIterator`](SetOrMapIterator.md)| +|`Nil`|`struct Nil {}`| ## 3. Private Member Variables diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index 25407b34abe..e787e4c0bf6 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -121,7 +121,7 @@ void f(MapBase& m1, MapBase& m2) { ### 6.3. find ```c++ -Success find(const K& key, V& value) const = 0 +virtual Success find(const K& key, V& value) const = 0 ``` 1. If an entry `e` with value `key` exists in the map, diff --git a/Fw/DataStructures/docs/SetBase.md b/Fw/DataStructures/docs/SetBase.md index 9bf146e435f..e4a62b399ae 100644 --- a/Fw/DataStructures/docs/SetBase.md +++ b/Fw/DataStructures/docs/SetBase.md @@ -19,9 +19,7 @@ It represents an abstract base class for a set. |Name|Definition| |----|----------| -|`Entry`|Alias of [`SetOrMapIterator`](SetOrMapIterator.md)| |`Iterator`|Alias of [`SetIterator`](SetIterator.md)| -|`Nil`|`struct Nil {}`| ## 3. Private Constructors @@ -122,7 +120,7 @@ void f(SetBase& s1, SetBase& s2) { ### 6.3. find ```c++ -Success find(const T& element) = 0 +virtual Success find(const T& element) = 0 ``` 1. If an entry `e` with element `element` exists in the set, @@ -164,7 +162,7 @@ void f(const SetBase& set) { ### 6.5. getHeadIterator ```c++ -const Iterator* getHeadIterator const = 0 +virtual const Iterator* getHeadIterator const = 0 ``` Get a pointer to the head iterator for the set, or `nullptr` if there is none. @@ -197,7 +195,7 @@ See [**getCapacity**](SetBase.md#64-getcapacity). ### 6.7. insert ```c++ -Success insert(const T& element) = 0 +virtual Success insert(const T& element) = 0 ``` 1. If an entry `e` exists with the specified element, then return `SUCCESS`. @@ -223,7 +221,7 @@ void f(SetBase& set) { ### 6.8. remove ```c++ -Success remove(const T& element) = 0 +virtual Success remove(const T& element) = 0 ``` 1. If an entry `e` exists with element `element`, then diff --git a/Fw/DataStructures/docs/SetOrMapIterator.md b/Fw/DataStructures/docs/SetOrMapIterator.md index 2f2cd1a13cb..579cb3b7dad 100644 --- a/Fw/DataStructures/docs/SetOrMapIterator.md +++ b/Fw/DataStructures/docs/SetOrMapIterator.md @@ -66,7 +66,7 @@ SetOrMapIterator(const KE& keyOrElement, const VN& valueOrNil, const SetOrMapIte SetOrMapIterator(const SetOrMapIterator& iterator) ``` -Defined as `= default`. +Set `*this = iterator`. ### 4.4. Destructor @@ -84,7 +84,13 @@ Defined as `= default`. SetOrMapIterator& operator=(const SetOrMapIterator& iterator) ``` -Defined as `= default`. +1. If `this != &iterator` + + 1. Set `m_keyOrElement = iterator.keyOrElement`. + + 1. Set `m_valueOrNil = iterator.valueOrNil`. + + 1. Set `m_next = iterator.next`. ### 5.3. getElement diff --git a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp index e2376a34496..428a1edb0df 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp @@ -10,7 +10,7 @@ namespace Fw { namespace MapTest { -SetOrMapIterator iterator; +ExternalArrayMap map; } // namespace MapTest } // namespace Fw From 6ff183327da1eaf0fb3afb13f07c3d7a5456e2bc Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 22 Jun 2025 19:20:10 -0700 Subject: [PATCH 270/458] Revise SetBase --- Fw/DataStructures/SetBase.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/SetBase.hpp b/Fw/DataStructures/SetBase.hpp index 68b7bb82443..3fa0853503c 100644 --- a/Fw/DataStructures/SetBase.hpp +++ b/Fw/DataStructures/SetBase.hpp @@ -78,7 +78,7 @@ class SetBase { //! Find the an element in a set //! SUCCESS if the item was found - Success find(const T& element //!< The element + virtual Success find(const T& element //!< The element ) const = 0; //! Get the capacity (maximum number of items stored in the set) From 7ae83cbb228c47596f5c3de65ec3a5de9a83c3a1 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 22 Jun 2025 19:29:43 -0700 Subject: [PATCH 271/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalArrayMap.md | 9 +++++---- Fw/DataStructures/docs/ExternalArraySet.md | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index fa7031e98e6..6534baae37c 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -20,6 +20,7 @@ as the map implementation. `ExternalArrayMap` is publicly derived from [`MapBase`](MapBase.md). + ## 3. Public Types `ExternalArrayMap` defines the following public types: @@ -27,6 +28,7 @@ as the map implementation. |Name|Definition| |----|----------| |`Entry`|Alias of [`SetOrMapIterator`](SetOrMapIterator.md)| +|`Iterator`|Alias of [`MapIterator`](MapIterator.md)| ## 4. Private Member Variables @@ -63,8 +65,7 @@ ExternalArrayMap(Entry* entries, FwSizeType capacity) ``` `entries` must point to a primitive array of at least `capacity` -elements of type `Entry`. -The type `Entry` is defined [in the base class](MapBase.md#Public-Types). +elements of type [`Entry`](ExternalArrayMap.md#Public-Types). Call `m_impl.setStorage(entries, capacity)`. @@ -244,7 +245,7 @@ ASSERT_EQ(map.getCapacity(), capacity); const Iterator* getHeadIterator const override ``` -The type `Iterator` is defined [in the base class](MapBase.md#Public-Types). +The type `Iterator` is defined [here](ExternalArrayMap.md#Public-Types). Return `m_impl.getHeadIterator()`. @@ -343,7 +344,7 @@ void setStorage(Entry* entries, FwSizeType capacity) `entries` must point to a primitive array of at least `capacity` elements of type `Entry`. -The type `Entry` is defined [in the base class](MapBase.md#Public-Types). +The type `Entry` is defined [here](ExternalArrayMap.md#Public-Types). Call `m_impl.setStorage(entries, capacity)`. diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md index c861c2e091e..46533f463bc 100644 --- a/Fw/DataStructures/docs/ExternalArraySet.md +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -36,7 +36,7 @@ as the set implementation. |----|----|-------|-------------| |`m_impl`|[`ArraySetOrMapImpl`](ArraySetOrMapImpl.md)|The set implementation|C++ default initialization| -The type `Nil` is defined [in the base class](SetBase.md#Public-Types). +The type `Nil` is defined [here](ArraySetOrMapImpl.md#Public-Types). ```mermaid classDiagram From 7db19616a1fd4920f40d9fab20f4761df9ea63a3 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 22 Jun 2025 19:33:41 -0700 Subject: [PATCH 272/458] Revise SDD for ExternalArraySet --- Fw/DataStructures/docs/ExternalArraySet.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md index 46533f463bc..e8fec5ca936 100644 --- a/Fw/DataStructures/docs/ExternalArraySet.md +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -19,7 +19,7 @@ as the set implementation. `ExternalArraySet` is publicly derived from [`SetBase`](SetBase.md). - + ## 3. Public Types `ExternalArrayMap` defines the following public types: @@ -27,6 +27,7 @@ as the set implementation. |Name|Definition| |----|----------| |`Entry`|Alias of [`SetOrMapIterator`](SetOrMapIterator.md)| +|`Iterator`|Alias of [`SetIterator`](SetIterator.md)| ## 4. Private Member Variables @@ -66,7 +67,7 @@ ExternalArraySet(Entry* entries, FwSizeType capacity) `entries` must point to a primitive array of at least `capacity` elements of type `Entry`. -The type `Entry` is defined [in the base class](SetBase.md#2Public-Types). +The type `Entry` is defined [here](ExternalArraySet.md#Public-Types). Call `m_impl.setStorage(entries, capacity)`. @@ -240,7 +241,7 @@ ASSERT_EQ(set.getCapacity(), capacity); const Iterator* getHeadIterator const override ``` -The type `Iterator` is defined [in the base class](SetBase.md#2Public-Types). +The type `Iterator` is defined [here](ExternalArraySet.md#Public-Types). Return `m_impl.getHeadIterator()`. @@ -338,7 +339,7 @@ void setStorage(Entry* entries, FwSizeType capacity) `entries` must point to a primitive array of at least `capacity` elements of type `Entry`. -The type `Entry` is defined [in the base class](SetBase.md#Public-Types). +The type `Entry` is defined [here](ExternalArraySet.md#Public-Types). Call `m_impl.setStorage(entries, capacity)`. From 48b3042df5d9f9ad07d20bda301a758fa828533c Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 22 Jun 2025 19:35:06 -0700 Subject: [PATCH 273/458] Revise SDD for ExternalArraySet --- Fw/DataStructures/docs/ExternalArraySet.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md index e8fec5ca936..ee5fd3500e4 100644 --- a/Fw/DataStructures/docs/ExternalArraySet.md +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -26,8 +26,10 @@ as the set implementation. |Name|Definition| |----|----------| -|`Entry`|Alias of [`SetOrMapIterator`](SetOrMapIterator.md)| -|`Iterator`|Alias of [`SetIterator`](SetIterator.md)| +|`Entry`|Alias of [`SetOrMapIterator`](SetOrMapIterator.md)| +|`Iterator`|Alias of [`SetIterator`](SetIterator.md)| + +The type `Nil` is defined [here](ArraySetOrMapImpl.md#Public-Types). ## 4. Private Member Variables From f8041c30b4c3853173763a9a55862ee1000847e4 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 22 Jun 2025 19:35:45 -0700 Subject: [PATCH 274/458] Revise SDD for ArraySetOrMapImpl --- Fw/DataStructures/docs/ArraySetOrMapImpl.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Fw/DataStructures/docs/ArraySetOrMapImpl.md b/Fw/DataStructures/docs/ArraySetOrMapImpl.md index 292109101e3..1973d73f8e6 100644 --- a/Fw/DataStructures/docs/ArraySetOrMapImpl.md +++ b/Fw/DataStructures/docs/ArraySetOrMapImpl.md @@ -15,6 +15,7 @@ storing the entries in the set or map. |`typename`|`KE`|The type of a key in a map or the element of a set| |`typename`|`VN`|The type of a value in a map or Nil for set| + ## 2. Public Types `ArraySetOrMapImpl` defines the following types: From f2d3ee64259f082d3a98b5b7ffc471e6c228f959 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 22 Jun 2025 19:57:13 -0700 Subject: [PATCH 275/458] Revise Fw/DataStructures --- Fw/DataStructures/ArraySetOrMapImpl.hpp | 3 --- Fw/DataStructures/CMakeLists.txt | 1 + Fw/DataStructures/ExternalArrayMap.hpp | 12 ++++++------ Fw/DataStructures/Nil.hpp | 16 ++++++++++++++++ Fw/DataStructures/SetOrMapIterator.hpp | 2 +- Fw/DataStructures/docs/ArraySetOrMapImpl.md | 1 - Fw/DataStructures/docs/ExternalArraySet.md | 11 ++++++----- 7 files changed, 30 insertions(+), 16 deletions(-) create mode 100644 Fw/DataStructures/Nil.hpp diff --git a/Fw/DataStructures/ArraySetOrMapImpl.hpp b/Fw/DataStructures/ArraySetOrMapImpl.hpp index fc4652f22e5..f6e7f0728af 100644 --- a/Fw/DataStructures/ArraySetOrMapImpl.hpp +++ b/Fw/DataStructures/ArraySetOrMapImpl.hpp @@ -27,9 +27,6 @@ class ArraySetOrMapImpl { //! The type of a set or map iterator using Iterator = SetOrMapIterator; - //! The Nil type - struct Nil {}; - public: // ---------------------------------------------------------------------- // Public constructors and destructors diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index 2b9c99187fc..7c5a5e28d4d 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -9,6 +9,7 @@ set(UT_SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" diff --git a/Fw/DataStructures/ExternalArrayMap.hpp b/Fw/DataStructures/ExternalArrayMap.hpp index b3168763997..385dfc977ae 100644 --- a/Fw/DataStructures/ExternalArrayMap.hpp +++ b/Fw/DataStructures/ExternalArrayMap.hpp @@ -80,14 +80,14 @@ class ExternalArrayMap final : public MapBase { } //! Get an iterator at an index in the array. - //! Fails an assertion if the index is out of range for the set or map. + //! Fails an assertion if the index is out of range for the map. //! \return The iterator const Iterator& at(FwSizeType index //!< The index ) const { return this->m_impl.at[index]; } - //! Clear the set or map + //! Clear the map void clear() override { this->m_impl.clear(); } //! Find a value associated with a key in the map @@ -98,11 +98,11 @@ class ExternalArrayMap final : public MapBase { return this->m_impl.find(key, value); } - //! Get the capacity of the set or map (max number of entries) + //! Get the capacity of the map (max number of entries) //! \return The capacity FwSizeType getCapacity() const override { return this->m_impl.getCapacity(); } - //! Get the head iterator for the set or map + //! Get the head iterator for the map //! \return The iterator const Iterator* getHeadIterator() const override { return this->m_impl.getHeadIterator(); } @@ -118,8 +118,8 @@ class ExternalArrayMap final : public MapBase { return this->m_impl.insert(key, value); } - //! Remove an element from the set or a (key, value) pair from the map - //! \return SUCCESS if the key or element was there + //! Remove a (key, value) pair from the map + //! \return SUCCESS if the key was there Success remove(const K& key, //!< The key V& value //!< The value ) override { diff --git a/Fw/DataStructures/Nil.hpp b/Fw/DataStructures/Nil.hpp new file mode 100644 index 00000000000..c62b2191662 --- /dev/null +++ b/Fw/DataStructures/Nil.hpp @@ -0,0 +1,16 @@ +// ====================================================================== +// \file Nil.hpp +// \author bocchino +// \brief The Nil type +// ====================================================================== + +#ifndef Fw_Nil_HPP +#define Fw_Nil_HPP + +namespace Fw { + +struct Nil {}; + +} // namespace Fw + +#endif diff --git a/Fw/DataStructures/SetOrMapIterator.hpp b/Fw/DataStructures/SetOrMapIterator.hpp index 4b5724cafc2..647311e1a22 100644 --- a/Fw/DataStructures/SetOrMapIterator.hpp +++ b/Fw/DataStructures/SetOrMapIterator.hpp @@ -14,7 +14,7 @@ namespace Fw { template -class SetOrMapIterator final : public MapIterator, SetIterator { +class SetOrMapIterator final : public MapIterator, public SetIterator { public: // ---------------------------------------------------------------------- // Public constructors and destructors diff --git a/Fw/DataStructures/docs/ArraySetOrMapImpl.md b/Fw/DataStructures/docs/ArraySetOrMapImpl.md index 1973d73f8e6..251023ed910 100644 --- a/Fw/DataStructures/docs/ArraySetOrMapImpl.md +++ b/Fw/DataStructures/docs/ArraySetOrMapImpl.md @@ -24,7 +24,6 @@ storing the entries in the set or map. |----|----------| |`Entry`|Alias for [`SetOrMapIterator`](SetOrMapIterator.md)| |`Iterator`|Alias for [`SetOrMapIterator`](SetOrMapIterator.md)| -|`Nil`|`struct Nil {}`| ## 3. Private Member Variables diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md index ee5fd3500e4..d91d9d325f4 100644 --- a/Fw/DataStructures/docs/ExternalArraySet.md +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -26,11 +26,10 @@ as the set implementation. |Name|Definition| |----|----------| +|`Nil`|`struct Nil {}`| |`Entry`|Alias of [`SetOrMapIterator`](SetOrMapIterator.md)| |`Iterator`|Alias of [`SetIterator`](SetIterator.md)| -The type `Nil` is defined [here](ArraySetOrMapImpl.md#Public-Types). - ## 4. Private Member Variables `ExternalArraySet` has the following private member variables. @@ -39,7 +38,7 @@ The type `Nil` is defined [here](ArraySetOrMapImpl.md#Public-Types). |----|----|-------|-------------| |`m_impl`|[`ArraySetOrMapImpl`](ArraySetOrMapImpl.md)|The set implementation|C++ default initialization| -The type `Nil` is defined [here](ArraySetOrMapImpl.md#Public-Types). +The type `Nil` is defined [here](ExternalArraySet.md#Public-Types). ```mermaid classDiagram @@ -165,7 +164,7 @@ ASSERT_EQ(m2.getSize(), 1); ### 6.2. at ```c++ -const V& at(FwSizeType index) const +const Iterator& at(FwSizeType index) const ``` Return `m_impl.at(index)`. @@ -206,7 +205,9 @@ ASSERT_EQ(set.getSize(), 0); Success find(const T& element) override ``` -Return `m_impl.find(key, Nil())`. +1. Set `Nil nil = {}`. + +1. Return `m_impl.find(key, nil)`. _Example:_ ```c++ From dc6e502515e934d02d08e95081765b269a70ae8c Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 22 Jun 2025 19:59:52 -0700 Subject: [PATCH 276/458] Revise SDD for Fw/DataStructures --- Fw/DataStructures/docs/ExternalArraySet.md | 3 +-- Fw/DataStructures/docs/Nil.md | 6 ++++++ 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 Fw/DataStructures/docs/Nil.md diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md index d91d9d325f4..ddb5f4243cd 100644 --- a/Fw/DataStructures/docs/ExternalArraySet.md +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -26,7 +26,6 @@ as the set implementation. |Name|Definition| |----|----------| -|`Nil`|`struct Nil {}`| |`Entry`|Alias of [`SetOrMapIterator`](SetOrMapIterator.md)| |`Iterator`|Alias of [`SetIterator`](SetIterator.md)| @@ -38,7 +37,7 @@ as the set implementation. |----|----|-------|-------------| |`m_impl`|[`ArraySetOrMapImpl`](ArraySetOrMapImpl.md)|The set implementation|C++ default initialization| -The type `Nil` is defined [here](ExternalArraySet.md#Public-Types). +The type `Nil` is defined [here](Nil.md). ```mermaid classDiagram diff --git a/Fw/DataStructures/docs/Nil.md b/Fw/DataStructures/docs/Nil.md new file mode 100644 index 00000000000..e5f2d73ab10 --- /dev/null +++ b/Fw/DataStructures/docs/Nil.md @@ -0,0 +1,6 @@ +# Nil + +`Nil` is an empty type. +It is a placeholder that is used as the value type +when a [`SetOrMapIterator`](SetOrMapIterator.md) +is used as a set iterator. From 88442b072f3bcbde9812a3563c48eb599ff9a47b Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Fri, 27 Jun 2025 17:18:04 -0700 Subject: [PATCH 277/458] Revise Fw/DataStructures tests --- Fw/DataStructures/ArraySetOrMapImpl.hpp | 7 + Fw/DataStructures/CMakeLists.txt | 29 +-- .../test/ut/ArraySetOrMapImplTest.cpp | 207 ++++++++++++++++++ .../test/ut/ExternalArraySetTest.cpp | 16 ++ .../ut/STest/ArraySetOrMapImplTestState.hpp | 44 ++++ 5 files changed, 289 insertions(+), 14 deletions(-) create mode 100644 Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp create mode 100644 Fw/DataStructures/test/ut/ExternalArraySetTest.cpp create mode 100644 Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp diff --git a/Fw/DataStructures/ArraySetOrMapImpl.hpp b/Fw/DataStructures/ArraySetOrMapImpl.hpp index f6e7f0728af..001ddb313e8 100644 --- a/Fw/DataStructures/ArraySetOrMapImpl.hpp +++ b/Fw/DataStructures/ArraySetOrMapImpl.hpp @@ -16,6 +16,13 @@ namespace Fw { template class ArraySetOrMapImpl { + // ---------------------------------------------------------------------- + // Friend class for testing + // ---------------------------------------------------------------------- + + template + friend class ArraySetOrMapImplTester; + public: // ---------------------------------------------------------------------- // Public types diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index 7c5a5e28d4d..7b963a02a6c 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -5,20 +5,21 @@ set(SOURCE_FILES register_fprime_module() set(UT_SOURCE_FILES - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" ) set(UT_MOD_DEPS diff --git a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp new file mode 100644 index 00000000000..99874c33e65 --- /dev/null +++ b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp @@ -0,0 +1,207 @@ +// ====================================================================== +// \title ArraySetOrMapImplTest.cpp +// \author bocchino +// \brief cpp file for ArraySetOrMapImpl tests +// ====================================================================== + +#include + +#include "Fw/DataStructures/ArraySetOrMapImpl.hpp" +#include "STest/STest/Pick/Pick.hpp" + +#include "Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp" +#if 0 +#include "Fw/DataStructures/test/ut/STest/SetOrMapTestRules.hpp" +#include "Fw/DataStructures/test/ut/STest/SetOrMapTestScenarios.hpp" +#endif + +namespace Fw { + +template +class ArraySetOrMapImplTester { + public: + using Entry = SetOrMapIterator; + + ArraySetOrMapImplTester(const ArraySetOrMapImpl& impl) : m_impl(impl) {} + + const ExternalArray& getEntries() const { return this->m_impl.m_entries; } + + private: + const ArraySetOrMapImpl& m_impl; +}; + +namespace ArraySetOrMapImplTest { + +TEST(ArraySetOrMapImpl, ZeroArgConstructor) { + ArraySetOrMapImpl impl; + ASSERT_EQ(impl.getCapacity(), 0); + ASSERT_EQ(impl.getSize(), 0); +} + +TEST(ArraySetOrMapImpl, TypedStorageConstructor) { + constexpr FwSizeType capacity = 10; + using Entry = SetOrMapIterator; + Entry entries[capacity]; + ArraySetOrMapImpl impl(entries, capacity); + ArraySetOrMapImplTester tester(impl); + ASSERT_EQ(tester.getEntries().getElements(), entries); + ASSERT_EQ(impl.getCapacity(), capacity); + ASSERT_EQ(impl.getSize(), 0); +} + +TEST(ArraySetOrMapImpl, UntypedStorageConstructor) { + constexpr FwSizeType capacity = 10; + using Entry = SetOrMapIterator; + constexpr U8 alignment = ArraySetOrMapImpl::getByteArrayAlignment(); + constexpr FwSizeType byteArraySize = ArraySetOrMapImpl::getByteArraySize(capacity); + alignas(alignment) U8 bytes[byteArraySize]; + ArraySetOrMapImpl impl(ByteArray(&bytes[0], sizeof bytes), capacity); + ArraySetOrMapImplTester tester(impl); + ASSERT_EQ(tester.getEntries().getElements(), reinterpret_cast(bytes)); + ASSERT_EQ(impl.getCapacity(), capacity); + ASSERT_EQ(impl.getSize(), 0); +} + +#if 0 +TEST(ArraySetOrMapImpl, CopyConstructor) { + constexpr FwSizeType capacity = 3; + Entry entries[capacity]; + // Call the constructor providing backing storage + ArraySetOrMapImpl q1(entries, capacity); + // Insert an item + U32 value = 42; + (void)q1.insert(value); + // Call the copy constructor + ArraySetOrMapImpl q2(q1); + ArraySetOrMapImplTester tester1(q1); + ArraySetOrMapImplTester tester2(q2); + ASSERT_EQ(tester2.getEntries().getEntries(), entries); + ASSERT_EQ(tester2.getEntries().getSize(), capacity); + ASSERT_EQ(tester2.getInsertIndex().getValue(), 1); + ASSERT_EQ(tester2.getDeimplIndex().getValue(), 0); + ASSERT_EQ(q2.getSize(), 1); +} + +TEST(ArraySetOrMapImpl, CopyAssignmentOperator) { + constexpr FwSizeType capacity = 3; + Entry entries[capacity]; + // Call the constructor providing backing storage + ArraySetOrMapImpl q1(entries, capacity); + // Insert an item + U32 value = 42; + (void)q1.insert(value); + // Call the default constructor + ArraySetOrMapImpl q2; + ASSERT_EQ(q2.getSize(), 0); + // Call the copy assignment operator + q2 = q1; + ASSERT_EQ(q2.getSize(), 1); +} + +namespace { + +void testCopyDataFrom(SetOrMapBase& q1, FwSizeType size1, SetOrMapBase& q2) { + q1.clear(); + for (FwSizeType i = 0; i < size1; i++) { + const auto status = q1.insert(static_cast(i)); + ASSERT_EQ(status, Success::SUCCESS); + } + q2.copyDataFrom(q1); + const auto capacity2 = q2.getCapacity(); + const FwSizeType size = FW_MIN(size1, capacity2); + for (FwSizeType i = 0; i < size; i++) { + U32 val1 = 0; + auto status = q1.peek(val1, i); + ASSERT_EQ(status, Success::SUCCESS); + U32 val2 = 1; + status = q2.peek(val2, i); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(val1, val2); + } +} + +} // namespace + +TEST(ArraySetOrMapImpl, CopyDataFrom) { + constexpr FwSizeType maxSize = 10; + constexpr FwSizeType smallSize = maxSize / 2; + Entry entries1[maxSize]; + Entry entries2[maxSize]; + ArraySetOrMapImpl q1(entries1, maxSize); + // size1 < capacity2 + { + ArraySetOrMapImpl q2(entries2, maxSize); + testCopyDataFrom(q1, smallSize, q2); + } + // size1 == size2 + { + ArraySetOrMapImpl q2(entries2, maxSize); + testCopyDataFrom(q1, maxSize, q2); + } + // size1 > size2 + { + ArraySetOrMapImpl q2(entries2, smallSize); + testCopyDataFrom(q1, maxSize, q2); + } +} + +TEST(ArraySetOrMapImplRules, InsertOK) { + Entry entries[State::capacity]; + State::ExternalQueue impl(entries, State::capacity); + State state(impl); + Rules::insertOK.apply(state); +} + +TEST(ArraySetOrMapImplRules, InsertFull) { + Entry entries[State::capacity]; + State::ExternalQueue impl(entries, State::capacity); + State state(impl); + for (FwSizeType i = 0; i < State::capacity; i++) { + Rules::insertOK.apply(state); + } + Rules::insertFull.apply(state); +} + +TEST(ArraySetOrMapImplRules, At) { + Entry entries[State::capacity]; + State::ExternalQueue impl(entries, State::capacity); + State state(impl); + Rules::insertOK.apply(state); + Rules::at.apply(state); +} + +TEST(ArraySetOrMapImplRules, DeimplOK) { + Entry entries[State::capacity]; + State::ExternalQueue impl(entries, State::capacity); + State state(impl); + Rules::insertOK.apply(state); + Rules::deimplOK.apply(state); +} + +TEST(ArraySetOrMapImplRules, DeimplEmpty) { + Entry entries[State::capacity]; + State::ExternalQueue impl(entries, State::capacity); + State state(impl); + Rules::deimplEmpty.apply(state); +} + +TEST(ArraySetOrMapImplRules, Clear) { + Entry entries[State::capacity]; + State::ExternalQueue impl(entries, State::capacity); + State state(impl); + Rules::insertOK.apply(state); + ASSERT_EQ(state.impl.getSize(), 1); + Rules::clear.apply(state); + ASSERT_EQ(state.impl.getSize(), 0); +} + +TEST(ArraySetOrMapImplScenarios, Random) { + Entry entries[State::capacity]; + State::ExternalQueue impl(entries, State::capacity); + State state(impl); + Scenarios::random(Fw::String("ArraySetOrMapImplRandom"), state, 1000); +} +#endif + +} // namespace ArraySetOrMapTest +} // namespace Fw diff --git a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp new file mode 100644 index 00000000000..b5086a6efbf --- /dev/null +++ b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp @@ -0,0 +1,16 @@ +// ====================================================================== +// \title ExternalArraySetTest.cpp +// \author bocchino +// \brief cpp file for ExternalArrayMap tests +// ====================================================================== + +#include "Fw/DataStructures/ExternalArraySet.hpp" + +namespace Fw { + +namespace SetTest { + +ExternalArraySet set; + +} // namespace SetTest +} // namespace Fw diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp new file mode 100644 index 00000000000..efb7fe192bc --- /dev/null +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp @@ -0,0 +1,44 @@ +// ====================================================================== +// \title ArraySetOrMapImplTestState.hpp +// \author bocchino +// \brief hpp file for ArraySetOrMapImpl test state +// ====================================================================== + +#ifndef ArraySetOrMapImplTestState_HPP +#define ArraySetOrMapImplTestState_HPP + +#include + +#include "Fw/DataStructures/ArraySetOrMapImpl.hpp" +#include "STest/STest/Pick/Pick.hpp" + +namespace Fw { + +namespace ArraySetOrMapImplTest { + +struct State { + //! The key type + using KeyType = U16; + //! The value type + using ValueType = U32; + //! The array set or map capacity + static constexpr FwSizeType capacity = 1024; + //! The ArraySetOrMapImpl type + using ArraySetOrMapImpl = ArraySetOrMapImpl; + //! Constructor + State(ArraySetOrMapImpl& a_impl) : impl(a_impl) {} + //! The array set or map under test + ArraySetOrMapImpl& impl; + //! The map for modeling correct behavior + std::map modelMap; + //! Get a random key + static KeyType getRandomKey() { return static_cast(STest::Pick::any()); } + //! Get a random value + static ValueType getRandomValue() { return static_cast(STest::Pick::any()); } +}; + +} + +} + +#endif From d583b6d5a37542335d241e43ec6fb48c7c591bd0 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Fri, 27 Jun 2025 17:45:50 -0700 Subject: [PATCH 278/458] Revise unit tests for Fw/DataStructures --- Fw/DataStructures/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index 7b963a02a6c..244f84ac18f 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -8,7 +8,7 @@ set(UT_SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" From dcdf91b93699810b522dce1d324edc11b3ac7e0a Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sat, 28 Jun 2025 10:48:31 -0700 Subject: [PATCH 279/458] Revise tests for ArraySetOrMapImpl --- Fw/DataStructures/CMakeLists.txt | 3 +- .../test/ut/ArraySetOrMapImplTest.cpp | 13 +- .../ut/STest/ArraySetOrMapImplTestRules.cpp | 33 +++++ .../ut/STest/ArraySetOrMapImplTestRules.hpp | 113 ++++++++++++++++++ .../ut/STest/ArraySetOrMapImplTestState.hpp | 10 +- 5 files changed, 161 insertions(+), 11 deletions(-) create mode 100644 Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp create mode 100644 Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index 244f84ac18f..01b35731710 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -6,9 +6,10 @@ register_fprime_module() set(UT_SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" diff --git a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp index 99874c33e65..efd422b225c 100644 --- a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp +++ b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp @@ -9,9 +9,8 @@ #include "Fw/DataStructures/ArraySetOrMapImpl.hpp" #include "STest/STest/Pick/Pick.hpp" -#include "Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp" +#include "Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp" #if 0 -#include "Fw/DataStructures/test/ut/STest/SetOrMapTestRules.hpp" #include "Fw/DataStructures/test/ut/STest/SetOrMapTestScenarios.hpp" #endif @@ -144,14 +143,16 @@ TEST(ArraySetOrMapImpl, CopyDataFrom) { testCopyDataFrom(q1, maxSize, q2); } } +#endif -TEST(ArraySetOrMapImplRules, InsertOK) { - Entry entries[State::capacity]; - State::ExternalQueue impl(entries, State::capacity); +TEST(ArraySetOrMapImplRules, InsertNotFull) { + State::Entry entries[State::capacity]; + State::Impl impl(entries, State::capacity); State state(impl); - Rules::insertOK.apply(state); + Rules::insertNotFull.apply(state); } +#if 0 TEST(ArraySetOrMapImplRules, InsertFull) { Entry entries[State::capacity]; State::ExternalQueue impl(entries, State::capacity); diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp new file mode 100644 index 00000000000..82bb02054ae --- /dev/null +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp @@ -0,0 +1,33 @@ +// ====================================================================== +// \title ArraySetOrMapImplTestRules.cpp +// \author Rob Bocchino +// \brief cpp file for ArraySetOrMapImpl test rules +// ====================================================================== + +#include "Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp" + +namespace Fw { + +namespace ArraySetOrMapImplTest { + +namespace Rules { + +InsertNotFull insertNotFull; + +#if 0 +PushFull pushFull; + +At at; + +PopOK popOK; + +PopEmpty popEmpty; + +Clear clear; +#endif + +}; // namespace Rules + +} // namespace ArraySetOrMapImplTest + +} // namespace Fw diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp new file mode 100644 index 00000000000..dbf224b32e9 --- /dev/null +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp @@ -0,0 +1,113 @@ +// ====================================================================== +// \title ArraySetOrMapImplTestRules.hpp +// \author bocchino +// \brief hpp file for ArraySetOrMapImpl test rules +// ====================================================================== + +#ifndef ArraySetOrMapImplTestRules_HPP +#define ArraySetOrMapImplTestRules_HPP + +#include + +#include "Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp" +#include "STest/STest/Pick/Pick.hpp" +#include "STest/STest/Rule/Rule.hpp" + +namespace Fw { + +namespace ArraySetOrMapImplTest { + +using Rule = STest::Rule; + +namespace Rules { + +struct InsertNotFull : public Rule { + InsertNotFull() : Rule("InsertNotFull") {} + bool precondition(const State& state) { + return static_cast(state.impl.getSize()) < State::capacity; + } + void action(State& state) { + const State::KeyType key = state.getRandomKey(); + const State::ValueType value = state.getRandomValue(); + const auto status = state.impl.insert(key, value); + ASSERT_EQ(status, Success::SUCCESS); + state.modelMap[key] = value; + } +}; + +extern InsertNotFull insertNotFull; + +#if 0 +struct PushFull : public Rule { + PushFull() : Rule("PushFull") {} + bool precondition(const State& state) { return static_cast(state.impl.getSize()) >= State::capacity; } + void action(State& state) { + const auto item = State::getRandomItem(); + const auto status = state.impl.push(item); + ASSERT_EQ(status, Success::FAILURE); + } +}; + +extern PushFull pushFull; + +struct At : public Rule { + At() : Rule("At") {} + bool precondition(const State& state) { return state.impl.getSize() > 0; } + void action(State& state) { + const auto size = state.impl.getSize(); + const auto index = STest::Pick::startLength(0, static_cast(size)); + ASSERT_EQ(state.impl.at(index), state.modelArraySetOrMapImpl.at(size - 1 - index)); + } +}; + +extern At at; + +struct PopOK : public Rule { + PopOK() : Rule("PopOK") {} + bool precondition(const State& state) { return static_cast(state.impl.getSize()) > 0; } + void action(State& state) { + const auto size = state.impl.getSize(); + U32 value = 0; + const auto status = state.impl.pop(value); + ASSERT_EQ(status, Success::SUCCESS); + const auto expectedValue = state.modelArraySetOrMapImpl.at(size - 1); + ASSERT_EQ(value, expectedValue); + state.modelArraySetOrMapImpl.pop_back(); + ASSERT_EQ(state.impl.getSize(), state.modelArraySetOrMapImpl.size()); + } +}; + +extern PopOK popOK; + +struct PopEmpty : public Rule { + PopEmpty() : Rule("PopEmpty") {} + bool precondition(const State& state) { return static_cast(state.impl.getSize()) == 0; } + void action(State& state) { + U32 value = 0; + const auto status = state.impl.pop(value); + ASSERT_EQ(status, Success::FAILURE); + } +}; + +extern PopEmpty popEmpty; + +struct Clear : public Rule { + Clear() : Rule("Clear") {} + bool precondition(const State& state) { return state.impl.getSize() > 0; } + void action(State& state) { + state.impl.clear(); + ASSERT_EQ(state.impl.getSize(), 0); + state.modelArraySetOrMapImpl.clear(); + } +}; + +extern Clear clear; + +#endif +}; // namespace Rules + +} // namespace ArraySetOrMapImplTest + +} // namespace Fw + +#endif diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp index efb7fe192bc..7d940fa7be4 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp @@ -23,12 +23,14 @@ struct State { using ValueType = U32; //! The array set or map capacity static constexpr FwSizeType capacity = 1024; - //! The ArraySetOrMapImpl type - using ArraySetOrMapImpl = ArraySetOrMapImpl; + //! The Impl type + using Impl = ArraySetOrMapImpl; + //! The entry type + using Entry = SetOrMapIterator; //! Constructor - State(ArraySetOrMapImpl& a_impl) : impl(a_impl) {} + State(Impl& a_impl) : impl(a_impl) {} //! The array set or map under test - ArraySetOrMapImpl& impl; + Impl& impl; //! The map for modeling correct behavior std::map modelMap; //! Get a random key From 4777ce23fab0f523cb726e3070c904de8bbfc647 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sat, 28 Jun 2025 11:06:50 -0700 Subject: [PATCH 280/458] Revise unit tests for Fw/DataStructures --- .../test/ut/ArraySetOrMapImplTest.cpp | 11 ++++--- .../ut/STest/ArraySetOrMapImplTestRules.cpp | 4 +-- .../ut/STest/ArraySetOrMapImplTestRules.hpp | 31 ++++++++++--------- .../ut/STest/ArraySetOrMapImplTestState.hpp | 12 +++++-- 4 files changed, 35 insertions(+), 23 deletions(-) diff --git a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp index efd422b225c..8e560b68d22 100644 --- a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp +++ b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp @@ -152,17 +152,20 @@ TEST(ArraySetOrMapImplRules, InsertNotFull) { Rules::insertNotFull.apply(state); } -#if 0 TEST(ArraySetOrMapImplRules, InsertFull) { - Entry entries[State::capacity]; - State::ExternalQueue impl(entries, State::capacity); + State::Entry entries[State::capacity]; + State::Impl impl(entries, State::capacity); State state(impl); + state.useStoredKey = true; for (FwSizeType i = 0; i < State::capacity; i++) { - Rules::insertOK.apply(state); + state.storedKey = static_cast(i); + Rules::insertNotFull.apply(state); } + state.useStoredKey = false; Rules::insertFull.apply(state); } +#if 0 TEST(ArraySetOrMapImplRules, At) { Entry entries[State::capacity]; State::ExternalQueue impl(entries, State::capacity); diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp index 82bb02054ae..9b0e33dfa98 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp @@ -14,9 +14,9 @@ namespace Rules { InsertNotFull insertNotFull; -#if 0 -PushFull pushFull; +InsertFull insertFull; +#if 0 At at; PopOK popOK; diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp index dbf224b32e9..8aec348dcdd 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp @@ -23,33 +23,34 @@ namespace Rules { struct InsertNotFull : public Rule { InsertNotFull() : Rule("InsertNotFull") {} - bool precondition(const State& state) { - return static_cast(state.impl.getSize()) < State::capacity; - } + bool precondition(const State& state) { return static_cast(state.impl.getSize()) < State::capacity; } void action(State& state) { - const State::KeyType key = state.getRandomKey(); - const State::ValueType value = state.getRandomValue(); - const auto status = state.impl.insert(key, value); - ASSERT_EQ(status, Success::SUCCESS); - state.modelMap[key] = value; + const auto key = state.getKey(); + const auto value = state.getValue(); + const auto status = state.impl.insert(key, value); + ASSERT_EQ(status, Success::SUCCESS); + state.modelMap[key] = value; } }; extern InsertNotFull insertNotFull; -#if 0 -struct PushFull : public Rule { - PushFull() : Rule("PushFull") {} +struct InsertFull : public Rule { + InsertFull() : Rule("InsertFull") {} bool precondition(const State& state) { return static_cast(state.impl.getSize()) >= State::capacity; } void action(State& state) { - const auto item = State::getRandomItem(); - const auto status = state.impl.push(item); - ASSERT_EQ(status, Success::FAILURE); + const auto key = state.getKey(); + const auto value = state.getValue(); + const auto expectedStatus = + (state.modelMap.find(key) == state.modelMap.end()) ? Success::FAILURE : Success::SUCCESS; + const auto status = state.impl.insert(key, value); + ASSERT_EQ(status, expectedStatus); } }; -extern PushFull pushFull; +extern InsertFull insertFull; +#if 0 struct At : public Rule { At() : Rule("At") {} bool precondition(const State& state) { return state.impl.getSize() > 0; } diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp index 7d940fa7be4..16db4942efa 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp @@ -33,10 +33,18 @@ struct State { Impl& impl; //! The map for modeling correct behavior std::map modelMap; + //! Whether to use the stored key + bool useStoredKey = false; + //! The stored key + KeyType storedKey = 0; + //! Whether to use the stored value + bool useStoredValue = false; + //! The stored value + ValueType storedValue = 0; //! Get a random key - static KeyType getRandomKey() { return static_cast(STest::Pick::any()); } + KeyType getKey() { return useStoredKey ? storedKey : static_cast(STest::Pick::any()); } //! Get a random value - static ValueType getRandomValue() { return static_cast(STest::Pick::any()); } + ValueType getValue() { return useStoredValue ? storedValue : static_cast(STest::Pick::any()); } }; } From a70df3b434008245ae43f35282ea37dd32ee7bec Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sat, 28 Jun 2025 11:18:11 -0700 Subject: [PATCH 281/458] Revise unit tests for Fw/DataStructures --- .../ut/STest/ArraySetOrMapImplTestRules.hpp | 8 ++- .../ut/STest/ArraySetOrMapImplTestState.hpp | 62 ++++++++++--------- 2 files changed, 38 insertions(+), 32 deletions(-) diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp index 8aec348dcdd..10be3c58cac 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp @@ -27,8 +27,11 @@ struct InsertNotFull : public Rule { void action(State& state) { const auto key = state.getKey(); const auto value = state.getValue(); + const auto size = state.impl.getSize(); + const auto expectedSize = state.modelMapContains(key) ? size : size + 1; const auto status = state.impl.insert(key, value); ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(state.impl.getSize(), expectedSize); state.modelMap[key] = value; } }; @@ -41,10 +44,11 @@ struct InsertFull : public Rule { void action(State& state) { const auto key = state.getKey(); const auto value = state.getValue(); - const auto expectedStatus = - (state.modelMap.find(key) == state.modelMap.end()) ? Success::FAILURE : Success::SUCCESS; + const auto size = state.impl.getSize(); + const auto expectedStatus = state.modelMapContains(key) ? Success::SUCCESS : Success::FAILURE; const auto status = state.impl.insert(key, value); ASSERT_EQ(status, expectedStatus); + ASSERT_EQ(state.impl.getSize(), size); } }; diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp index 16db4942efa..6f061b8d851 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp @@ -17,38 +17,40 @@ namespace Fw { namespace ArraySetOrMapImplTest { struct State { - //! The key type - using KeyType = U16; - //! The value type - using ValueType = U32; - //! The array set or map capacity - static constexpr FwSizeType capacity = 1024; - //! The Impl type - using Impl = ArraySetOrMapImpl; - //! The entry type - using Entry = SetOrMapIterator; - //! Constructor - State(Impl& a_impl) : impl(a_impl) {} - //! The array set or map under test - Impl& impl; - //! The map for modeling correct behavior - std::map modelMap; - //! Whether to use the stored key - bool useStoredKey = false; - //! The stored key - KeyType storedKey = 0; - //! Whether to use the stored value - bool useStoredValue = false; - //! The stored value - ValueType storedValue = 0; - //! Get a random key - KeyType getKey() { return useStoredKey ? storedKey : static_cast(STest::Pick::any()); } - //! Get a random value - ValueType getValue() { return useStoredValue ? storedValue : static_cast(STest::Pick::any()); } + //! The key type + using KeyType = U16; + //! The value type + using ValueType = U32; + //! The array set or map capacity + static constexpr FwSizeType capacity = 1024; + //! The Impl type + using Impl = ArraySetOrMapImpl; + //! The entry type + using Entry = SetOrMapIterator; + //! Constructor + State(Impl& a_impl) : impl(a_impl) {} + //! The array set or map under test + Impl& impl; + //! The map for modeling correct behavior + std::map modelMap; + //! Whether to use the stored key + bool useStoredKey = false; + //! The stored key + KeyType storedKey = 0; + //! Whether to use the stored value + bool useStoredValue = false; + //! The stored value + ValueType storedValue = 0; + //! Get a random key + KeyType getKey() const { return useStoredKey ? storedKey : static_cast(STest::Pick::any()); } + //! Get a random value + ValueType getValue() const { return useStoredValue ? storedValue : static_cast(STest::Pick::any()); } + //! Check whether the model map contains the specified key + bool modelMapContains(KeyType key) const { return modelMap.count(key) != 0; } }; -} +} // namespace ArraySetOrMapImplTest -} +} // namespace Fw #endif From 5239024a4ca5e476f886819913273367df8c39c3 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sat, 28 Jun 2025 12:01:47 -0700 Subject: [PATCH 282/458] Revise unit tests for ArraySetOrMapImpl --- Fw/DataStructures/ArraySetOrMapImpl.hpp | 3 ++- .../test/ut/ArraySetOrMapImplTest.cpp | 26 +++++++------------ .../ut/STest/ArraySetOrMapImplTestRules.cpp | 2 +- .../ut/STest/ArraySetOrMapImplTestRules.hpp | 13 +++++++--- .../ut/STest/ArraySetOrMapImplTestState.hpp | 7 ++++- 5 files changed, 28 insertions(+), 23 deletions(-) diff --git a/Fw/DataStructures/ArraySetOrMapImpl.hpp b/Fw/DataStructures/ArraySetOrMapImpl.hpp index 001ddb313e8..7852acf31ba 100644 --- a/Fw/DataStructures/ArraySetOrMapImpl.hpp +++ b/Fw/DataStructures/ArraySetOrMapImpl.hpp @@ -84,7 +84,8 @@ class ArraySetOrMapImpl { //! \return The iterator const Iterator& at(FwSizeType index //!< The index ) const { - FW_ASSERT(index < this->m_size, static_cast(index), static_cast(this->m_size)); + FW_ASSERT(index < this->m_size, static_cast(index), + static_cast(this->m_size)); return this->m_entries[index]; } diff --git a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp index 8e560b68d22..01e39afd2bb 100644 --- a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp +++ b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp @@ -9,6 +9,7 @@ #include "Fw/DataStructures/ArraySetOrMapImpl.hpp" #include "STest/STest/Pick/Pick.hpp" +#include "Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp" #include "Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp" #if 0 #include "Fw/DataStructures/test/ut/STest/SetOrMapTestScenarios.hpp" @@ -16,19 +17,6 @@ namespace Fw { -template -class ArraySetOrMapImplTester { - public: - using Entry = SetOrMapIterator; - - ArraySetOrMapImplTester(const ArraySetOrMapImpl& impl) : m_impl(impl) {} - - const ExternalArray& getEntries() const { return this->m_impl.m_entries; } - - private: - const ArraySetOrMapImpl& m_impl; -}; - namespace ArraySetOrMapImplTest { TEST(ArraySetOrMapImpl, ZeroArgConstructor) { @@ -165,15 +153,19 @@ TEST(ArraySetOrMapImplRules, InsertFull) { Rules::insertFull.apply(state); } -#if 0 TEST(ArraySetOrMapImplRules, At) { - Entry entries[State::capacity]; - State::ExternalQueue impl(entries, State::capacity); + State::Entry entries[State::capacity]; + State::Impl impl(entries, State::capacity); State state(impl); - Rules::insertOK.apply(state); + state.useStoredKey = true; + Rules::insertNotFull.apply(state); + Rules::insertNotFull.apply(state); + state.storedKey = 1; + Rules::insertNotFull.apply(state); Rules::at.apply(state); } +#if 0 TEST(ArraySetOrMapImplRules, DeimplOK) { Entry entries[State::capacity]; State::ExternalQueue impl(entries, State::capacity); diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp index 9b0e33dfa98..ea1583fb74c 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp @@ -16,9 +16,9 @@ InsertNotFull insertNotFull; InsertFull insertFull; -#if 0 At at; +#if 0 PopOK popOK; PopEmpty popEmpty; diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp index 10be3c58cac..afcf8dfc7dc 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp @@ -54,19 +54,26 @@ struct InsertFull : public Rule { extern InsertFull insertFull; -#if 0 struct At : public Rule { At() : Rule("At") {} bool precondition(const State& state) { return state.impl.getSize() > 0; } void action(State& state) { const auto size = state.impl.getSize(); - const auto index = STest::Pick::startLength(0, static_cast(size)); - ASSERT_EQ(state.impl.at(index), state.modelArraySetOrMapImpl.at(size - 1 - index)); + const auto* it = state.impl.getHeadIterator(); + for (FwSizeType i = 0; i < size; i++) { + const auto& it1 = state.impl.at(i); + ASSERT_NE(it, nullptr); + const auto& it2 = *it; + ASSERT_EQ(it1.getKey(), it2.getKey()); + ASSERT_EQ(it1.getValue(), it2.getValue()); + it = it->getNextIterator(); + } } }; extern At at; +#if 0 struct PopOK : public Rule { PopOK() : Rule("PopOK") {} bool precondition(const State& state) { return static_cast(state.impl.getSize()) > 0; } diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp index 6f061b8d851..3dc339e2c05 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp @@ -10,6 +10,7 @@ #include #include "Fw/DataStructures/ArraySetOrMapImpl.hpp" +#include "Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp" #include "STest/STest/Pick/Pick.hpp" namespace Fw { @@ -25,12 +26,16 @@ struct State { static constexpr FwSizeType capacity = 1024; //! The Impl type using Impl = ArraySetOrMapImpl; + //! The Tester type + using Tester = ArraySetOrMapImplTester; //! The entry type using Entry = SetOrMapIterator; //! Constructor - State(Impl& a_impl) : impl(a_impl) {} + State(Impl& a_impl) : impl(a_impl), tester(a_impl) {} //! The array set or map under test Impl& impl; + //! The tester + Tester tester; //! The map for modeling correct behavior std::map modelMap; //! Whether to use the stored key From 166e5a323289b6a27b8e27c96476a556cb0cbf81 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sat, 28 Jun 2025 14:23:49 -0700 Subject: [PATCH 283/458] Revise unit tests for ArraySetOrMapImpl --- Fw/DataStructures/CMakeLists.txt | 1 + .../test/ut/ArraySetOrMapImplTest.cpp | 10 +++--- .../STest/ArraySetOrMapImplTestScenarios.cpp | 35 +++++++++++++++++++ .../STest/ArraySetOrMapImplTestScenarios.hpp | 21 +++++++++++ 4 files changed, 61 insertions(+), 6 deletions(-) create mode 100644 Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp create mode 100644 Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.hpp diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index 01b35731710..f38c53ff91c 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -8,6 +8,7 @@ set(UT_SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" diff --git a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp index 01e39afd2bb..d1c90b1c8a3 100644 --- a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp +++ b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp @@ -11,9 +11,7 @@ #include "Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp" #include "Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp" -#if 0 -#include "Fw/DataStructures/test/ut/STest/SetOrMapTestScenarios.hpp" -#endif +#include "Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.hpp" namespace Fw { @@ -190,14 +188,14 @@ TEST(ArraySetOrMapImplRules, Clear) { Rules::clear.apply(state); ASSERT_EQ(state.impl.getSize(), 0); } +#endif TEST(ArraySetOrMapImplScenarios, Random) { - Entry entries[State::capacity]; - State::ExternalQueue impl(entries, State::capacity); + State::Entry entries[State::capacity]; + State::Impl impl(entries, State::capacity); State state(impl); Scenarios::random(Fw::String("ArraySetOrMapImplRandom"), state, 1000); } -#endif } // namespace ArraySetOrMapTest } // namespace Fw diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp new file mode 100644 index 00000000000..df6823f78c5 --- /dev/null +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp @@ -0,0 +1,35 @@ +// ====================================================================== +// \title ArraySetOrMapImplTestScenarios.cpp +// \author Rob Bocchino +// \brief ArraySetOrMapImpl test scenarios +// ====================================================================== + +#include "Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp" +#include "Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.hpp" +#include "STest/Scenario/BoundedScenario.hpp" +#include "STest/Scenario/RandomScenario.hpp" + +namespace Fw { + +namespace ArraySetOrMapImplTest { + +namespace Scenarios { + +void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { + Rule* rules[] = { + &Rules::insertNotFull, + &Rules::insertFull, + &Rules::at + }; + STest::RandomScenario scenario("RandomScenario", rules, + sizeof(rules) / sizeof(STest::RandomScenario*)); + STest::BoundedScenario boundedScenario(name.toChar(), scenario, maxNumSteps); + const U32 numSteps = boundedScenario.run(state); + printf("Ran %u steps.\n", numSteps); +} + +} // namespace Scenarios + +} // namespace ArraySetOrMapImplTest + +} // namespace Fw diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.hpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.hpp new file mode 100644 index 00000000000..d2bd005b668 --- /dev/null +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.hpp @@ -0,0 +1,21 @@ +// ====================================================================== +// \title ArraySetOrMapImplTestScenarios.hpp +// \author Rob Bocchino +// \brief ArraySetOrMapImpl test scenarios +// ====================================================================== + +#include "Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp" + +namespace Fw { + +namespace ArraySetOrMapImplTest { + +namespace Scenarios { + +void random(const Fw::StringBase& name, State& state, U32 maxNumSteps); + +} // namespace Scenarios + +} // namespace ArraySetOrMapImplTest + +} // namespace Fw From d4a6c9692bb157301b09d54230858555da164d3f Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sat, 28 Jun 2025 14:38:00 -0700 Subject: [PATCH 284/458] Revise unit tests for ArraySetOrMapImpl --- Fw/DataStructures/ExternalArraySet.hpp | 174 ++++++++++++++++++ .../test/ut/ArraySetOrMapImplTest.cpp | 23 ++- .../ut/STest/ArraySetOrMapImplTestRules.cpp | 4 +- .../ut/STest/ArraySetOrMapImplTestRules.hpp | 22 ++- .../STest/ArraySetOrMapImplTestScenarios.cpp | 3 +- 5 files changed, 202 insertions(+), 24 deletions(-) create mode 100644 Fw/DataStructures/ExternalArraySet.hpp diff --git a/Fw/DataStructures/ExternalArraySet.hpp b/Fw/DataStructures/ExternalArraySet.hpp new file mode 100644 index 00000000000..e61cdf7390a --- /dev/null +++ b/Fw/DataStructures/ExternalArraySet.hpp @@ -0,0 +1,174 @@ +// ====================================================================== +// \file ExternalArraySet.hpp +// \author bocchino +// \brief An array-based set with external storage +// ====================================================================== + +#ifndef Fw_ExternalArraySet_HPP +#define Fw_ExternalArraySet_HPP + +#include "Fw/DataStructures/ArraySetOrMapImpl.hpp" +#include "Fw/DataStructures/Nil.hpp" +#include "Fw/DataStructures/SetBase.hpp" +#include "Fw/Types/Assert.hpp" + +namespace Fw { + +template +class ExternalArraySet final : public SetBase { + // ---------------------------------------------------------------------- + // Friend class for testing + // ---------------------------------------------------------------------- + + template + friend class ExternalArraySetTester; + + public: + // ---------------------------------------------------------------------- + // Public types + // ---------------------------------------------------------------------- + + //! The type of a set entry + using Entry = SetOrMapIterator; + + //! The type of a set iterator + using Iterator = SetIterator; + + public: + // ---------------------------------------------------------------------- + // Public constructors and destructors + // ---------------------------------------------------------------------- + + //! Zero-argument constructor + ExternalArraySet() = default; + + //! Constructor providing typed backing storage. + //! entries must point to at least capacity elements of type Entry. + ExternalArraySet(Entry* entries, //!< The entries + FwSizeType capacity //!< The capacity + ) + : SetBase() { + this->m_impl.setStorage(entries, capacity); + } + + //! Constructor providing untyped backing storage. + //! data must be aligned according to getByteArrayAlignment(). + //! data must contain at least getByteArraySize(capacity) bytes. + ExternalArraySet(ByteArray data, //!< The data, + FwSizeType capacity //!< The capacity + ) + : SetBase() { + this->m_impl.setStorage(data, capacity); + } + + //! Copy constructor + ExternalArraySet(const ExternalArraySet& set) : SetBase() { *this = set; } + + //! Destructor + ~ExternalArraySet() override = default; + + public: + // ---------------------------------------------------------------------- + // Public member functions + // ---------------------------------------------------------------------- + + //! operator= + ExternalArraySet& operator=(const ExternalArraySet& set) { + if (&set != this) { + this->m_impl = set.m_impl; + } + return *this; + } + + //! Get an iterator at an index in the array. + //! Fails an assertion if the index is out of range for the set or set. + //! \return The iterator + const Iterator& at(FwSizeType index //!< The index + ) const { + return this->m_impl.at[index]; + } + + //! Clear the set or set + void clear() override { this->m_impl.clear(); } + + //! Find a value associated with an element in the set + //! \return SUCCESS if the item was found + Success find(const T& element //!< The element + ) const override { + Nil nil = {}; + return this->m_impl.find(element, nil); + } + + //! Get the capacity of the set (max number of entries) + //! \return The capacity + FwSizeType getCapacity() const override { return this->m_impl.getCapacity(); } + + //! Get the head iterator for the set + //! \return The iterator + const Iterator* getHeadIterator() const override { return this->m_impl.getHeadIterator(); } + + //! Get the size (number of entries) + //! \return The size + FwSizeType getSize() const override { return this->m_impl.getSize(); } + + //! Insert an element in the set + //! \return SUCCESS if there is room in the set + Success insert(const T& element //!< The element + ) override { + return this->m_impl.insert(element, Nil()); + } + + //! Remove an element from the set + //! \return SUCCESS if the element was there + Success remove(const T& element //!< The element + ) override { + Nil nil = {}; + return this->m_impl.remove(element, nil); + } + + //! 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_impl.setStorage(entries, capacity); + } + + //! 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_impl.setStorage(data, capacity); + } + + public: + // ---------------------------------------------------------------------- + // Public static functions + // ---------------------------------------------------------------------- + + //! Get the alignment of the storage for an ArraySetOrMapImpl + //! \return The alignment + static constexpr U8 getByteArrayAlignment() { return ArraySetOrMapImpl::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 ArraySetOrMapImpl::getByteArraySize(capacity); + } + + private: + // ---------------------------------------------------------------------- + // Private member variables + // ---------------------------------------------------------------------- + + //! The set implementation + ArraySetOrMapImpl m_impl = {}; +}; + +} // namespace Fw + +#endif diff --git a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp index d1c90b1c8a3..b976cc32c8e 100644 --- a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp +++ b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp @@ -25,10 +25,9 @@ TEST(ArraySetOrMapImpl, ZeroArgConstructor) { TEST(ArraySetOrMapImpl, TypedStorageConstructor) { constexpr FwSizeType capacity = 10; - using Entry = SetOrMapIterator; - Entry entries[capacity]; - ArraySetOrMapImpl impl(entries, capacity); - ArraySetOrMapImplTester tester(impl); + State::Entry entries[capacity]; + State::Impl impl(entries, capacity); + State::Tester tester(impl); ASSERT_EQ(tester.getEntries().getElements(), entries); ASSERT_EQ(impl.getCapacity(), capacity); ASSERT_EQ(impl.getSize(), 0); @@ -163,25 +162,25 @@ TEST(ArraySetOrMapImplRules, At) { Rules::at.apply(state); } -#if 0 -TEST(ArraySetOrMapImplRules, DeimplOK) { - Entry entries[State::capacity]; - State::ExternalQueue impl(entries, State::capacity); +TEST(ArraySetOrMapImplRules, RemoveExisting) { + State::Entry entries[State::capacity]; + State::Impl impl(entries, State::capacity); State state(impl); - Rules::insertOK.apply(state); - Rules::deimplOK.apply(state); + Rules::insertNotFull.apply(state); + Rules::removeExisting.apply(state); } +#if 0 TEST(ArraySetOrMapImplRules, DeimplEmpty) { Entry entries[State::capacity]; - State::ExternalQueue impl(entries, State::capacity); + State::Impl impl(entries, State::capacity); State state(impl); Rules::deimplEmpty.apply(state); } TEST(ArraySetOrMapImplRules, Clear) { Entry entries[State::capacity]; - State::ExternalQueue impl(entries, State::capacity); + State::Impl impl(entries, State::capacity); State state(impl); Rules::insertOK.apply(state); ASSERT_EQ(state.impl.getSize(), 1); diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp index ea1583fb74c..9c7e8167f65 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp @@ -18,9 +18,9 @@ InsertFull insertFull; At at; -#if 0 -PopOK popOK; +RemoveExisting removeExisting; +#if 0 PopEmpty popEmpty; Clear clear; diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp index afcf8dfc7dc..c58112f0c15 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp @@ -73,24 +73,28 @@ struct At : public Rule { extern At at; -#if 0 -struct PopOK : public Rule { - PopOK() : Rule("PopOK") {} +struct RemoveExisting : public Rule { + RemoveExisting() : Rule("RemoveExisting") {} bool precondition(const State& state) { return static_cast(state.impl.getSize()) > 0; } void action(State& state) { const auto size = state.impl.getSize(); - U32 value = 0; - const auto status = state.impl.pop(value); + const auto index = STest::Pick::startLength(0, static_cast(size)); + const auto& it = state.impl.at(index); + const auto key = it.getKey(); + const auto expectedValue = it.getValue(); + State::ValueType value = 0; + const auto status = state.impl.remove(key, value); ASSERT_EQ(status, Success::SUCCESS); - const auto expectedValue = state.modelArraySetOrMapImpl.at(size - 1); ASSERT_EQ(value, expectedValue); - state.modelArraySetOrMapImpl.pop_back(); - ASSERT_EQ(state.impl.getSize(), state.modelArraySetOrMapImpl.size()); + const auto n = state.modelMap.erase(key); + ASSERT_EQ(n, 1); + ASSERT_EQ(state.impl.getSize(), state.modelMap.size()); } }; -extern PopOK popOK; +extern RemoveExisting removeExisting; +#if 0 struct PopEmpty : public Rule { PopEmpty() : Rule("PopEmpty") {} bool precondition(const State& state) { return static_cast(state.impl.getSize()) == 0; } diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp index df6823f78c5..e5adf13185a 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp @@ -17,9 +17,10 @@ namespace Scenarios { void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { Rule* rules[] = { + &Rules::at, &Rules::insertNotFull, &Rules::insertFull, - &Rules::at + &Rules::removeExisting }; STest::RandomScenario scenario("RandomScenario", rules, sizeof(rules) / sizeof(STest::RandomScenario*)); From 213ea2f5027e1319f53e83fec61e962e5ee55a22 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sat, 28 Jun 2025 14:48:11 -0700 Subject: [PATCH 285/458] Revise unit tests for ArraySetOrMapImpl --- .../test/ut/ArraySetOrMapImplTest.cpp | 10 +++++++ .../ut/STest/ArraySetOrMapImplTestRules.cpp | 2 ++ .../ut/STest/ArraySetOrMapImplTestRules.hpp | 26 +++++++++++++++++++ .../STest/ArraySetOrMapImplTestScenarios.cpp | 3 ++- 4 files changed, 40 insertions(+), 1 deletion(-) diff --git a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp index b976cc32c8e..80aea73a158 100644 --- a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp +++ b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp @@ -170,6 +170,16 @@ TEST(ArraySetOrMapImplRules, RemoveExisting) { Rules::removeExisting.apply(state); } +TEST(ArraySetOrMapImplRules, Remove) { + State::Entry entries[State::capacity]; + State::Impl impl(entries, State::capacity); + State state(impl); + state.useStoredKey = true; + Rules::insertNotFull.apply(state); + Rules::remove.apply(state); + Rules::remove.apply(state); +} + #if 0 TEST(ArraySetOrMapImplRules, DeimplEmpty) { Entry entries[State::capacity]; diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp index 9c7e8167f65..bd49cd2d1d9 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp @@ -20,6 +20,8 @@ At at; RemoveExisting removeExisting; +Remove remove; + #if 0 PopEmpty popEmpty; diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp index c58112f0c15..d51f0f1844f 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp @@ -94,6 +94,32 @@ struct RemoveExisting : public Rule { extern RemoveExisting removeExisting; + +struct Remove : public Rule { + Remove() : Rule("Remove") {} + bool precondition(const State& state) { return true; } + void action(State& state) { + const auto size = state.impl.getSize(); + ASSERT_EQ(size, state.modelMap.size()); + const auto key = state.getKey(); + State::ValueType value = 0; + const auto status = state.impl.remove(key, value); + if (state.modelMap.count(key) != 0) { + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(value, state.modelMap[key]); + ASSERT_EQ(state.impl.getSize(), size - 1); + } + else { + ASSERT_EQ(status, Success::FAILURE); + ASSERT_EQ(state.impl.getSize(), size); + } + (void) state.modelMap.erase(key); + ASSERT_EQ(state.impl.getSize(), state.modelMap.size()); + } +}; + +extern Remove remove; + #if 0 struct PopEmpty : public Rule { PopEmpty() : Rule("PopEmpty") {} diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp index e5adf13185a..b8382b856cc 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp @@ -18,8 +18,9 @@ namespace Scenarios { void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { Rule* rules[] = { &Rules::at, - &Rules::insertNotFull, &Rules::insertFull, + &Rules::insertNotFull, + &Rules::remove, &Rules::removeExisting }; STest::RandomScenario scenario("RandomScenario", rules, From 92da8f6e57d22875809be22a663be0564aafc132 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sat, 28 Jun 2025 15:03:31 -0700 Subject: [PATCH 286/458] Revise unit tests for ArraySetOrMapImpl --- .../test/ut/ArraySetOrMapImplTest.cpp | 34 ++++++------------- .../ut/STest/ArraySetOrMapImplTestRules.cpp | 14 +++----- .../ut/STest/ArraySetOrMapImplTestRules.hpp | 16 +-------- 3 files changed, 17 insertions(+), 47 deletions(-) diff --git a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp index 80aea73a158..4fea2021e82 100644 --- a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp +++ b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp @@ -24,25 +24,22 @@ TEST(ArraySetOrMapImpl, ZeroArgConstructor) { } TEST(ArraySetOrMapImpl, TypedStorageConstructor) { - constexpr FwSizeType capacity = 10; - State::Entry entries[capacity]; - State::Impl impl(entries, capacity); + State::Entry entries[State::capacity]; + State::Impl impl(entries, State::capacity); State::Tester tester(impl); ASSERT_EQ(tester.getEntries().getElements(), entries); - ASSERT_EQ(impl.getCapacity(), capacity); + ASSERT_EQ(impl.getCapacity(), FwSizeType(State::capacity)); ASSERT_EQ(impl.getSize(), 0); } TEST(ArraySetOrMapImpl, UntypedStorageConstructor) { - constexpr FwSizeType capacity = 10; - using Entry = SetOrMapIterator; - constexpr U8 alignment = ArraySetOrMapImpl::getByteArrayAlignment(); - constexpr FwSizeType byteArraySize = ArraySetOrMapImpl::getByteArraySize(capacity); + constexpr auto alignment = State::Impl::getByteArrayAlignment(); + constexpr auto byteArraySize = State::Impl::getByteArraySize(State::capacity); alignas(alignment) U8 bytes[byteArraySize]; - ArraySetOrMapImpl impl(ByteArray(&bytes[0], sizeof bytes), capacity); - ArraySetOrMapImplTester tester(impl); - ASSERT_EQ(tester.getEntries().getElements(), reinterpret_cast(bytes)); - ASSERT_EQ(impl.getCapacity(), capacity); + State::Impl impl(ByteArray(&bytes[0], sizeof bytes), State::capacity); + State::Tester tester(impl); + ASSERT_EQ(tester.getEntries().getElements(), reinterpret_cast(bytes)); + ASSERT_EQ(impl.getCapacity(), FwSizeType(State::capacity)); ASSERT_EQ(impl.getSize(), 0); } @@ -180,24 +177,15 @@ TEST(ArraySetOrMapImplRules, Remove) { Rules::remove.apply(state); } -#if 0 -TEST(ArraySetOrMapImplRules, DeimplEmpty) { - Entry entries[State::capacity]; - State::Impl impl(entries, State::capacity); - State state(impl); - Rules::deimplEmpty.apply(state); -} - TEST(ArraySetOrMapImplRules, Clear) { - Entry entries[State::capacity]; + State::Entry entries[State::capacity]; State::Impl impl(entries, State::capacity); State state(impl); - Rules::insertOK.apply(state); + Rules::insertNotFull.apply(state); ASSERT_EQ(state.impl.getSize(), 1); Rules::clear.apply(state); ASSERT_EQ(state.impl.getSize(), 0); } -#endif TEST(ArraySetOrMapImplScenarios, Random) { State::Entry entries[State::capacity]; diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp index bd49cd2d1d9..9829333e498 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp @@ -12,21 +12,17 @@ namespace ArraySetOrMapImplTest { namespace Rules { -InsertNotFull insertNotFull; +At at; -InsertFull insertFull; +Clear clear; -At at; +InsertFull insertFull; -RemoveExisting removeExisting; +InsertNotFull insertNotFull; Remove remove; -#if 0 -PopEmpty popEmpty; - -Clear clear; -#endif +RemoveExisting removeExisting; }; // namespace Rules diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp index d51f0f1844f..a725dcd471f 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp @@ -120,32 +120,18 @@ struct Remove : public Rule { extern Remove remove; -#if 0 -struct PopEmpty : public Rule { - PopEmpty() : Rule("PopEmpty") {} - bool precondition(const State& state) { return static_cast(state.impl.getSize()) == 0; } - void action(State& state) { - U32 value = 0; - const auto status = state.impl.pop(value); - ASSERT_EQ(status, Success::FAILURE); - } -}; - -extern PopEmpty popEmpty; - struct Clear : public Rule { Clear() : Rule("Clear") {} bool precondition(const State& state) { return state.impl.getSize() > 0; } void action(State& state) { state.impl.clear(); ASSERT_EQ(state.impl.getSize(), 0); - state.modelArraySetOrMapImpl.clear(); + state.modelMap.clear(); } }; extern Clear clear; -#endif }; // namespace Rules } // namespace ArraySetOrMapImplTest From 7291e9bd4da65d98d28896d7dbbdab2f1b29f9ce Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sat, 28 Jun 2025 15:05:38 -0700 Subject: [PATCH 287/458] Revise unit tests for ArraySetOrMapImpl --- .../test/ut/STest/ArraySetOrMapImplTestScenarios.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp index b8382b856cc..2e62ba04e81 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp @@ -18,6 +18,7 @@ namespace Scenarios { void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { Rule* rules[] = { &Rules::at, + &Rules::clear, &Rules::insertFull, &Rules::insertNotFull, &Rules::remove, From cc8a4a7863df3a22f7ed6203e82bf00a93d6b70a Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sat, 28 Jun 2025 15:54:44 -0700 Subject: [PATCH 288/458] Revise unit tests for Fw/DataStructures --- Fw/DataStructures/CMakeLists.txt | 26 ++-- .../test/ut/ArraySetOrMapImplTest.cpp | 133 ++++++------------ .../ut/STest/ArraySetOrMapImplTestRules.cpp | 2 + .../ut/STest/ArraySetOrMapImplTestRules.hpp | 117 ++++++++------- 4 files changed, 128 insertions(+), 150 deletions(-) diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index f38c53ff91c..577aec80245 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -6,22 +6,22 @@ register_fprime_module() set(UT_SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" ) set(UT_MOD_DEPS diff --git a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp index 4fea2021e82..3012a00fe36 100644 --- a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp +++ b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp @@ -43,95 +43,69 @@ TEST(ArraySetOrMapImpl, UntypedStorageConstructor) { ASSERT_EQ(impl.getSize(), 0); } -#if 0 TEST(ArraySetOrMapImpl, CopyConstructor) { - constexpr FwSizeType capacity = 3; - Entry entries[capacity]; + State::Entry entries[State::capacity]; // Call the constructor providing backing storage - ArraySetOrMapImpl q1(entries, capacity); + State::Impl impl1(entries, State::capacity); // Insert an item - U32 value = 42; - (void)q1.insert(value); + const State::KeyType key = 0; + const State::ValueType value = 42; + const auto status = impl1.insert(key, value); + ASSERT_EQ(status, Success::SUCCESS); // Call the copy constructor - ArraySetOrMapImpl q2(q1); - ArraySetOrMapImplTester tester1(q1); - ArraySetOrMapImplTester tester2(q2); - ASSERT_EQ(tester2.getEntries().getEntries(), entries); - ASSERT_EQ(tester2.getEntries().getSize(), capacity); - ASSERT_EQ(tester2.getInsertIndex().getValue(), 1); - ASSERT_EQ(tester2.getDeimplIndex().getValue(), 0); - ASSERT_EQ(q2.getSize(), 1); + State::Impl impl2(impl1); + State::Tester tester1(impl1); + State::Tester tester2(impl2); + ASSERT_EQ(tester2.getEntries().getElements(), entries); + ASSERT_EQ(tester2.getEntries().getSize(), FwSizeType(State::capacity)); + ASSERT_EQ(impl2.getSize(), 1); } TEST(ArraySetOrMapImpl, CopyAssignmentOperator) { - constexpr FwSizeType capacity = 3; - Entry entries[capacity]; + State::Entry entries[State::capacity]; // Call the constructor providing backing storage - ArraySetOrMapImpl q1(entries, capacity); + State::Impl impl1(entries, State::capacity); // Insert an item - U32 value = 42; - (void)q1.insert(value); + const State::KeyType key = 0; + const State::ValueType value = 42; + const auto status = impl1.insert(key, value); + ASSERT_EQ(status, Success::SUCCESS); // Call the default constructor - ArraySetOrMapImpl q2; - ASSERT_EQ(q2.getSize(), 0); + State::Impl impl2; + ASSERT_EQ(impl2.getSize(), 0); // Call the copy assignment operator - q2 = q1; - ASSERT_EQ(q2.getSize(), 1); + impl2 = impl1; + ASSERT_EQ(impl2.getSize(), 1); } -namespace { - -void testCopyDataFrom(SetOrMapBase& q1, FwSizeType size1, SetOrMapBase& q2) { - q1.clear(); - for (FwSizeType i = 0; i < size1; i++) { - const auto status = q1.insert(static_cast(i)); - ASSERT_EQ(status, Success::SUCCESS); - } - q2.copyDataFrom(q1); - const auto capacity2 = q2.getCapacity(); - const FwSizeType size = FW_MIN(size1, capacity2); - for (FwSizeType i = 0; i < size; i++) { - U32 val1 = 0; - auto status = q1.peek(val1, i); - ASSERT_EQ(status, Success::SUCCESS); - U32 val2 = 1; - status = q2.peek(val2, i); - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(val1, val2); - } +TEST(ArraySetOrMapImplRules, At) { + State::Entry entries[State::capacity]; + State::Impl impl(entries, State::capacity); + State state(impl); + state.useStoredKey = true; + Rules::insertNotFull.apply(state); + Rules::insertNotFull.apply(state); + state.storedKey = 1; + Rules::insertNotFull.apply(state); + Rules::at.apply(state); } -} // namespace - -TEST(ArraySetOrMapImpl, CopyDataFrom) { - constexpr FwSizeType maxSize = 10; - constexpr FwSizeType smallSize = maxSize / 2; - Entry entries1[maxSize]; - Entry entries2[maxSize]; - ArraySetOrMapImpl q1(entries1, maxSize); - // size1 < capacity2 - { - ArraySetOrMapImpl q2(entries2, maxSize); - testCopyDataFrom(q1, smallSize, q2); - } - // size1 == size2 - { - ArraySetOrMapImpl q2(entries2, maxSize); - testCopyDataFrom(q1, maxSize, q2); - } - // size1 > size2 - { - ArraySetOrMapImpl q2(entries2, smallSize); - testCopyDataFrom(q1, maxSize, q2); - } +TEST(ArraySetOrMapImplRules, Clear) { + State::Entry entries[State::capacity]; + State::Impl impl(entries, State::capacity); + State state(impl); + Rules::insertNotFull.apply(state); + ASSERT_EQ(state.impl.getSize(), 1); + Rules::clear.apply(state); + ASSERT_EQ(state.impl.getSize(), 0); } -#endif -TEST(ArraySetOrMapImplRules, InsertNotFull) { +TEST(ArraySetOrMapImplRules, FindExisting) { State::Entry entries[State::capacity]; State::Impl impl(entries, State::capacity); State state(impl); Rules::insertNotFull.apply(state); + Rules::findExisting.apply(state); } TEST(ArraySetOrMapImplRules, InsertFull) { @@ -147,24 +121,11 @@ TEST(ArraySetOrMapImplRules, InsertFull) { Rules::insertFull.apply(state); } -TEST(ArraySetOrMapImplRules, At) { - State::Entry entries[State::capacity]; - State::Impl impl(entries, State::capacity); - State state(impl); - state.useStoredKey = true; - Rules::insertNotFull.apply(state); - Rules::insertNotFull.apply(state); - state.storedKey = 1; - Rules::insertNotFull.apply(state); - Rules::at.apply(state); -} - -TEST(ArraySetOrMapImplRules, RemoveExisting) { +TEST(ArraySetOrMapImplRules, InsertNotFull) { State::Entry entries[State::capacity]; State::Impl impl(entries, State::capacity); State state(impl); Rules::insertNotFull.apply(state); - Rules::removeExisting.apply(state); } TEST(ArraySetOrMapImplRules, Remove) { @@ -177,14 +138,12 @@ TEST(ArraySetOrMapImplRules, Remove) { Rules::remove.apply(state); } -TEST(ArraySetOrMapImplRules, Clear) { - State::Entry entries[State::capacity]; +TEST(ArraySetOrMapImplRules, RemoveExisting) { + State::Entry entries[State::capacity]; State::Impl impl(entries, State::capacity); State state(impl); Rules::insertNotFull.apply(state); - ASSERT_EQ(state.impl.getSize(), 1); - Rules::clear.apply(state); - ASSERT_EQ(state.impl.getSize(), 0); + Rules::removeExisting.apply(state); } TEST(ArraySetOrMapImplScenarios, Random) { diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp index 9829333e498..8aca985e061 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp @@ -16,6 +16,8 @@ At at; Clear clear; +FindExisting findExisting; + InsertFull insertFull; InsertNotFull insertNotFull; diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp index a725dcd471f..7053f7424fb 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp @@ -21,39 +21,6 @@ using Rule = STest::Rule; namespace Rules { -struct InsertNotFull : public Rule { - InsertNotFull() : Rule("InsertNotFull") {} - bool precondition(const State& state) { return static_cast(state.impl.getSize()) < State::capacity; } - void action(State& state) { - const auto key = state.getKey(); - const auto value = state.getValue(); - const auto size = state.impl.getSize(); - const auto expectedSize = state.modelMapContains(key) ? size : size + 1; - const auto status = state.impl.insert(key, value); - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(state.impl.getSize(), expectedSize); - state.modelMap[key] = value; - } -}; - -extern InsertNotFull insertNotFull; - -struct InsertFull : public Rule { - InsertFull() : Rule("InsertFull") {} - bool precondition(const State& state) { return static_cast(state.impl.getSize()) >= State::capacity; } - void action(State& state) { - const auto key = state.getKey(); - const auto value = state.getValue(); - const auto size = state.impl.getSize(); - const auto expectedStatus = state.modelMapContains(key) ? Success::SUCCESS : Success::FAILURE; - const auto status = state.impl.insert(key, value); - ASSERT_EQ(status, expectedStatus); - ASSERT_EQ(state.impl.getSize(), size); - } -}; - -extern InsertFull insertFull; - struct At : public Rule { At() : Rule("At") {} bool precondition(const State& state) { return state.impl.getSize() > 0; } @@ -71,29 +38,60 @@ struct At : public Rule { } }; -extern At at; +struct Clear : public Rule { + Clear() : Rule("Clear") {} + bool precondition(const State& state) { return state.impl.getSize() > 0; } + void action(State& state) { + state.impl.clear(); + ASSERT_EQ(state.impl.getSize(), 0); + state.modelMap.clear(); + } +}; -struct RemoveExisting : public Rule { - RemoveExisting() : Rule("RemoveExisting") {} +struct FindExisting : public Rule { + FindExisting() : Rule("FindExisting") {} bool precondition(const State& state) { return static_cast(state.impl.getSize()) > 0; } void action(State& state) { const auto size = state.impl.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); const auto& it = state.impl.at(index); const auto key = it.getKey(); - const auto expectedValue = it.getValue(); + const auto expectedValue = state.modelMap[key]; State::ValueType value = 0; - const auto status = state.impl.remove(key, value); + const auto status = state.impl.find(key, value); ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(value, expectedValue); - const auto n = state.modelMap.erase(key); - ASSERT_EQ(n, 1); - ASSERT_EQ(state.impl.getSize(), state.modelMap.size()); } }; -extern RemoveExisting removeExisting; +struct InsertFull : public Rule { + InsertFull() : Rule("InsertFull") {} + bool precondition(const State& state) { return static_cast(state.impl.getSize()) >= State::capacity; } + void action(State& state) { + const auto key = state.getKey(); + const auto value = state.getValue(); + const auto size = state.impl.getSize(); + const auto expectedStatus = state.modelMapContains(key) ? Success::SUCCESS : Success::FAILURE; + const auto status = state.impl.insert(key, value); + ASSERT_EQ(status, expectedStatus); + ASSERT_EQ(state.impl.getSize(), size); + } +}; +struct InsertNotFull : public Rule { + InsertNotFull() : Rule("InsertNotFull") {} + bool precondition(const State& state) { return static_cast(state.impl.getSize()) < State::capacity; } + void action(State& state) { + const auto key = state.getKey(); + const auto value = state.getValue(); + const auto size = state.impl.getSize(); + const auto expectedSize = state.modelMapContains(key) ? size : size + 1; + const auto status = state.impl.insert(key, value); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(state.impl.getSize(), expectedSize); + state.modelMap[key] = value; + } +}; struct Remove : public Rule { Remove() : Rule("Remove") {} @@ -118,20 +116,39 @@ struct Remove : public Rule { } }; -extern Remove remove; - -struct Clear : public Rule { - Clear() : Rule("Clear") {} - bool precondition(const State& state) { return state.impl.getSize() > 0; } +struct RemoveExisting : public Rule { + RemoveExisting() : Rule("RemoveExisting") {} + bool precondition(const State& state) { return static_cast(state.impl.getSize()) > 0; } void action(State& state) { - state.impl.clear(); - ASSERT_EQ(state.impl.getSize(), 0); - state.modelMap.clear(); + const auto size = state.impl.getSize(); + const auto index = STest::Pick::startLength(0, static_cast(size)); + const auto& it = state.impl.at(index); + const auto key = it.getKey(); + const auto expectedValue = state.modelMap[key]; + State::ValueType value = 0; + const auto status = state.impl.remove(key, value); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(value, expectedValue); + const auto n = state.modelMap.erase(key); + ASSERT_EQ(n, 1); + ASSERT_EQ(state.impl.getSize(), state.modelMap.size()); } }; +extern At at; + extern Clear clear; +extern FindExisting findExisting; + +extern InsertFull insertFull; + +extern InsertNotFull insertNotFull; + +extern Remove remove; + +extern RemoveExisting removeExisting; + }; // namespace Rules } // namespace ArraySetOrMapImplTest From b4aa25064cea553e072afc5175b469826b4c89a2 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sat, 5 Jul 2025 14:45:19 -0700 Subject: [PATCH 289/458] Revise SDD for SetOrMapIterator --- Fw/DataStructures/docs/SetOrMapIterator.md | 4 +-- .../test/ut/ArraySetOrMapImplTester.hpp | 32 +++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp diff --git a/Fw/DataStructures/docs/SetOrMapIterator.md b/Fw/DataStructures/docs/SetOrMapIterator.md index 579cb3b7dad..3af330de40d 100644 --- a/Fw/DataStructures/docs/SetOrMapIterator.md +++ b/Fw/DataStructures/docs/SetOrMapIterator.md @@ -11,7 +11,7 @@ It represents an iterator for a set or a map. |Kind|Name|Purpose| |----|----|-------| |`typename`|`KE`|The type of a key in a map or the element of a set| -|`typename`|`VN`|The type of a value in a map or Nil in a set| +|`typename`|`VN`|The type of a value in a map or [`Nil`](Nil.md) in a set| ## 2. Base Class @@ -35,7 +35,7 @@ classDiagram |Name|Type|Purpose|Default Value| |----|----|-------|-------------| |`m_keyOrElement`|`KE`|The map key or set element|C++ default initialization| -|`m_valueOrNil`|`VN`|The value or Nil|C++ default initialization| +|`m_valueOrNil`|`VN`|The value or [`Nil`](Nil.md)|C++ default initialization| |`m_next`|`const SetOrMapIterator*`|Pointer to the next iterator or `nullptr` if none|`nullptr`| ## 4. Public Constructors and Destructors diff --git a/Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp b/Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp new file mode 100644 index 00000000000..9e64da748b9 --- /dev/null +++ b/Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp @@ -0,0 +1,32 @@ +// ====================================================================== +// \title ArraySetOrMapImplTester.hpp +// \author bocchino +// \brief Class template for access to ArraySetOrMapImpl members +// ====================================================================== + +#ifndef ArraySetOrMapImplTester_HPP +#define ArraySetOrMapImplTester_HPP + +#include + +#include "Fw/DataStructures/ArraySetOrMapImpl.hpp" +#include "STest/STest/Pick/Pick.hpp" + +namespace Fw { + +template +class ArraySetOrMapImplTester { + public: + using Entry = SetOrMapIterator; + + ArraySetOrMapImplTester(const ArraySetOrMapImpl& impl) : m_impl(impl) {} + + const ExternalArray& getEntries() const { return this->m_impl.m_entries; } + + private: + const ArraySetOrMapImpl& m_impl; +}; + +} // namespace Fw + +#endif From d56e5d01b268e25b8387c8d435b9338672936332 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sat, 5 Jul 2025 15:04:28 -0700 Subject: [PATCH 290/458] Add ExternalArrayMapTest --- Fw/DataStructures/CMakeLists.txt | 2 + .../test/ut/ExternalArrayMapTest.cpp | 148 +++++++++++++++- .../test/ut/STest/ArrayMapTestRules.cpp | 35 ++++ .../test/ut/STest/ArrayMapTestRules.hpp | 160 ++++++++++++++++++ .../test/ut/STest/ArrayMapTestScenarios.cpp | 43 +++++ .../test/ut/STest/ArrayMapTestScenarios.hpp | 21 +++ .../test/ut/STest/ArrayMapTestState.hpp | 60 +++++++ .../ut/STest/ArraySetOrMapImplTestState.hpp | 4 +- 8 files changed, 468 insertions(+), 5 deletions(-) create mode 100644 Fw/DataStructures/test/ut/STest/ArrayMapTestRules.cpp create mode 100644 Fw/DataStructures/test/ut/STest/ArrayMapTestRules.hpp create mode 100644 Fw/DataStructures/test/ut/STest/ArrayMapTestScenarios.cpp create mode 100644 Fw/DataStructures/test/ut/STest/ArrayMapTestScenarios.hpp create mode 100644 Fw/DataStructures/test/ut/STest/ArrayMapTestState.hpp diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index 577aec80245..194dd50d96e 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -15,6 +15,8 @@ set(UT_SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArrayMapTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArrayMapTestScenarios.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" diff --git a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp index 428a1edb0df..8963b54882f 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp @@ -4,13 +4,155 @@ // \brief cpp file for ExternalArrayMap tests // ====================================================================== +#include + #include "Fw/DataStructures/ExternalArrayMap.hpp" +#include "STest/STest/Pick/Pick.hpp" + +#include "Fw/DataStructures/test/ut/STest/ArrayMapTestRules.hpp" +#include "Fw/DataStructures/test/ut/STest/ArrayMapTestScenarios.hpp" +#if 0 namespace Fw { -namespace MapTest { +namespace ExternalArrayMapTest { + +TEST(ExternalArrayMap, ZeroArgConstructor) { + ExternalArrayMap impl; + ASSERT_EQ(impl.getCapacity(), 0); + ASSERT_EQ(impl.getSize(), 0); +} + +TEST(ExternalArrayMap, TypedStorageConstructor) { + State::Entry entries[State::capacity]; + State::Impl impl(entries, State::capacity); + State::Tester tester(impl); + ASSERT_EQ(tester.getEntries().getElements(), entries); + ASSERT_EQ(impl.getCapacity(), FwSizeType(State::capacity)); + ASSERT_EQ(impl.getSize(), 0); +} + +TEST(ExternalArrayMap, UntypedStorageConstructor) { + constexpr auto alignment = State::Impl::getByteArrayAlignment(); + constexpr auto byteArraySize = State::Impl::getByteArraySize(State::capacity); + alignas(alignment) U8 bytes[byteArraySize]; + State::Impl impl(ByteArray(&bytes[0], sizeof bytes), State::capacity); + State::Tester tester(impl); + ASSERT_EQ(tester.getEntries().getElements(), reinterpret_cast(bytes)); + ASSERT_EQ(impl.getCapacity(), FwSizeType(State::capacity)); + ASSERT_EQ(impl.getSize(), 0); +} + +TEST(ExternalArrayMap, CopyConstructor) { + State::Entry entries[State::capacity]; + // Call the constructor providing backing storage + State::Impl impl1(entries, State::capacity); + // Insert an item + const State::KeyType key = 0; + const State::ValueType value = 42; + const auto status = impl1.insert(key, value); + ASSERT_EQ(status, Success::SUCCESS); + // Call the copy constructor + State::Impl impl2(impl1); + State::Tester tester1(impl1); + State::Tester tester2(impl2); + ASSERT_EQ(tester2.getEntries().getElements(), entries); + ASSERT_EQ(tester2.getEntries().getSize(), FwSizeType(State::capacity)); + ASSERT_EQ(impl2.getSize(), 1); +} + +TEST(ExternalArrayMap, CopyAssignmentOperator) { + State::Entry entries[State::capacity]; + // Call the constructor providing backing storage + State::Impl impl1(entries, State::capacity); + // Insert an item + const State::KeyType key = 0; + const State::ValueType value = 42; + const auto status = impl1.insert(key, value); + ASSERT_EQ(status, Success::SUCCESS); + // Call the default constructor + State::Impl impl2; + ASSERT_EQ(impl2.getSize(), 0); + // Call the copy assignment operator + impl2 = impl1; + ASSERT_EQ(impl2.getSize(), 1); +} + +TEST(ExternalArrayMapRules, At) { + State::Entry entries[State::capacity]; + State::Impl impl(entries, State::capacity); + State state(impl); + state.useStoredKey = true; + Rules::insertNotFull.apply(state); + Rules::insertNotFull.apply(state); + state.storedKey = 1; + Rules::insertNotFull.apply(state); + Rules::at.apply(state); +} + +TEST(ExternalArrayMapRules, Clear) { + State::Entry entries[State::capacity]; + State::Impl impl(entries, State::capacity); + State state(impl); + Rules::insertNotFull.apply(state); + ASSERT_EQ(state.impl.getSize(), 1); + Rules::clear.apply(state); + ASSERT_EQ(state.impl.getSize(), 0); +} + +TEST(ExternalArrayMapRules, FindExisting) { + State::Entry entries[State::capacity]; + State::Impl impl(entries, State::capacity); + State state(impl); + Rules::insertNotFull.apply(state); + Rules::findExisting.apply(state); +} + +TEST(ExternalArrayMapRules, InsertFull) { + State::Entry entries[State::capacity]; + State::Impl impl(entries, State::capacity); + State state(impl); + state.useStoredKey = true; + for (FwSizeType i = 0; i < State::capacity; i++) { + state.storedKey = static_cast(i); + Rules::insertNotFull.apply(state); + } + state.useStoredKey = false; + Rules::insertFull.apply(state); +} + +TEST(ExternalArrayMapRules, InsertNotFull) { + State::Entry entries[State::capacity]; + State::Impl impl(entries, State::capacity); + State state(impl); + Rules::insertNotFull.apply(state); +} + +TEST(ExternalArrayMapRules, Remove) { + State::Entry entries[State::capacity]; + State::Impl impl(entries, State::capacity); + State state(impl); + state.useStoredKey = true; + Rules::insertNotFull.apply(state); + Rules::remove.apply(state); + Rules::remove.apply(state); +} + +TEST(ExternalArrayMapRules, RemoveExisting) { + State::Entry entries[State::capacity]; + State::Impl impl(entries, State::capacity); + State state(impl); + Rules::insertNotFull.apply(state); + Rules::removeExisting.apply(state); +} -ExternalArrayMap map; +TEST(ExternalArrayMapScenarios, Random) { + State::Entry entries[State::capacity]; + State::Impl impl(entries, State::capacity); + State state(impl); + Scenarios::random(Fw::String("ExternalArrayMapRandom"), state, 1000); +} -} // namespace MapTest +} // namespace ArraySetOrMapTest } // namespace Fw +#endif diff --git a/Fw/DataStructures/test/ut/STest/ArrayMapTestRules.cpp b/Fw/DataStructures/test/ut/STest/ArrayMapTestRules.cpp new file mode 100644 index 00000000000..bce3eac98bf --- /dev/null +++ b/Fw/DataStructures/test/ut/STest/ArrayMapTestRules.cpp @@ -0,0 +1,35 @@ +// ====================================================================== +// \title ArrayMapTestRules.cpp +// \author Rob Bocchino +// \brief cpp file for ArrayMap test rules +// ====================================================================== + +#include "Fw/DataStructures/test/ut/STest/ArrayMapTestRules.hpp" + +namespace Fw { + +namespace ArrayMapTest { + +namespace Rules { + +#if 0 +At at; + +Clear clear; + +FindExisting findExisting; + +InsertFull insertFull; + +InsertNotFull insertNotFull; + +Remove remove; + +RemoveExisting removeExisting; +#endif + +}; // namespace Rules + +} // namespace ArrayMapTest + +} // namespace Fw diff --git a/Fw/DataStructures/test/ut/STest/ArrayMapTestRules.hpp b/Fw/DataStructures/test/ut/STest/ArrayMapTestRules.hpp new file mode 100644 index 00000000000..71619132aae --- /dev/null +++ b/Fw/DataStructures/test/ut/STest/ArrayMapTestRules.hpp @@ -0,0 +1,160 @@ +// ====================================================================== +// \title ArrayMapTestRules.hpp +// \author bocchino +// \brief hpp file for ArrayMap test rules +// ====================================================================== + +#ifndef ArrayMapTestRules_HPP +#define ArrayMapTestRules_HPP + +#include + +#include "Fw/DataStructures/test/ut/STest/ArrayMapTestState.hpp" +#include "STest/STest/Pick/Pick.hpp" +#include "STest/STest/Rule/Rule.hpp" + +namespace Fw { + +namespace ArrayMapTest { + +using Rule = STest::Rule; + +namespace Rules { + +#if 0 +struct At : public Rule { + At() : Rule("At") {} + bool precondition(const State& state) { return state.impl.getSize() > 0; } + void action(State& state) { + const auto size = state.impl.getSize(); + const auto* it = state.impl.getHeadIterator(); + for (FwSizeType i = 0; i < size; i++) { + const auto& it1 = state.impl.at(i); + ASSERT_NE(it, nullptr); + const auto& it2 = *it; + ASSERT_EQ(it1.getKey(), it2.getKey()); + ASSERT_EQ(it1.getValue(), it2.getValue()); + it = it->getNextIterator(); + } + } +}; + +struct Clear : public Rule { + Clear() : Rule("Clear") {} + bool precondition(const State& state) { return state.impl.getSize() > 0; } + void action(State& state) { + state.impl.clear(); + ASSERT_EQ(state.impl.getSize(), 0); + state.modelMap.clear(); + } +}; + +struct FindExisting : public Rule { + FindExisting() : Rule("FindExisting") {} + bool precondition(const State& state) { return static_cast(state.impl.getSize()) > 0; } + void action(State& state) { + const auto size = state.impl.getSize(); + const auto index = STest::Pick::startLength(0, static_cast(size)); + const auto& it = state.impl.at(index); + const auto key = it.getKey(); + const auto expectedValue = state.modelMap[key]; + State::ValueType value = 0; + const auto status = state.impl.find(key, value); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(value, expectedValue); + } +}; + +struct InsertFull : public Rule { + InsertFull() : Rule("InsertFull") {} + bool precondition(const State& state) { return static_cast(state.impl.getSize()) >= State::capacity; } + void action(State& state) { + const auto key = state.getKey(); + const auto value = state.getValue(); + const auto size = state.impl.getSize(); + const auto expectedStatus = state.modelMapContains(key) ? Success::SUCCESS : Success::FAILURE; + const auto status = state.impl.insert(key, value); + ASSERT_EQ(status, expectedStatus); + ASSERT_EQ(state.impl.getSize(), size); + } +}; + +struct InsertNotFull : public Rule { + InsertNotFull() : Rule("InsertNotFull") {} + bool precondition(const State& state) { return static_cast(state.impl.getSize()) < State::capacity; } + void action(State& state) { + const auto key = state.getKey(); + const auto value = state.getValue(); + const auto size = state.impl.getSize(); + const auto expectedSize = state.modelMapContains(key) ? size : size + 1; + const auto status = state.impl.insert(key, value); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(state.impl.getSize(), expectedSize); + state.modelMap[key] = value; + } +}; + +struct Remove : public Rule { + Remove() : Rule("Remove") {} + bool precondition(const State& state) { return true; } + void action(State& state) { + const auto size = state.impl.getSize(); + ASSERT_EQ(size, state.modelMap.size()); + const auto key = state.getKey(); + State::ValueType value = 0; + const auto status = state.impl.remove(key, value); + if (state.modelMap.count(key) != 0) { + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(value, state.modelMap[key]); + ASSERT_EQ(state.impl.getSize(), size - 1); + } + else { + ASSERT_EQ(status, Success::FAILURE); + ASSERT_EQ(state.impl.getSize(), size); + } + (void) state.modelMap.erase(key); + ASSERT_EQ(state.impl.getSize(), state.modelMap.size()); + } +}; + +struct RemoveExisting : public Rule { + RemoveExisting() : Rule("RemoveExisting") {} + bool precondition(const State& state) { return static_cast(state.impl.getSize()) > 0; } + void action(State& state) { + const auto size = state.impl.getSize(); + const auto index = STest::Pick::startLength(0, static_cast(size)); + const auto& it = state.impl.at(index); + const auto key = it.getKey(); + const auto expectedValue = state.modelMap[key]; + State::ValueType value = 0; + const auto status = state.impl.remove(key, value); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(value, expectedValue); + const auto n = state.modelMap.erase(key); + ASSERT_EQ(n, 1); + ASSERT_EQ(state.impl.getSize(), state.modelMap.size()); + } +}; + +extern At at; + +extern Clear clear; + +extern FindExisting findExisting; + +extern InsertFull insertFull; + +extern InsertNotFull insertNotFull; + +extern Remove remove; + +extern RemoveExisting removeExisting; +#endif + +}; // namespace Rules + +} // namespace ArrayMapTest + +} // namespace Fw + +#endif diff --git a/Fw/DataStructures/test/ut/STest/ArrayMapTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/ArrayMapTestScenarios.cpp new file mode 100644 index 00000000000..efb78844897 --- /dev/null +++ b/Fw/DataStructures/test/ut/STest/ArrayMapTestScenarios.cpp @@ -0,0 +1,43 @@ +// ====================================================================== +// \title ArrayMapTestScenarios.cpp +// \author Rob Bocchino +// \brief ArrayMap test scenarios +// ====================================================================== + +#include "Fw/DataStructures/test/ut/STest/ArrayMapTestRules.hpp" +#include "Fw/DataStructures/test/ut/STest/ArrayMapTestScenarios.hpp" +#include "STest/Scenario/BoundedScenario.hpp" +#include "STest/Scenario/RandomScenario.hpp" + +namespace Fw { + +namespace ArrayMapTest { + +namespace Scenarios { + +void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { + (void)name; + (void)state; + (void)maxNumSteps; +#if 0 + Rule* rules[] = { + &Rules::at, + &Rules::clear, + &Rules::insertFull, + &Rules::insertNotFull, + &Rules::remove, + &Rules::removeExisting + }; + STest::RandomScenario scenario("RandomScenario", rules, + sizeof(rules) / sizeof(STest::RandomScenario*)); + STest::BoundedScenario boundedScenario(name.toChar(), scenario, maxNumSteps); + const U32 numSteps = boundedScenario.run(state); + printf("Ran %u steps.\n", numSteps); +#endif +} + +} // namespace Scenarios + +} // namespace ArrayMapTest + +} // namespace Fw diff --git a/Fw/DataStructures/test/ut/STest/ArrayMapTestScenarios.hpp b/Fw/DataStructures/test/ut/STest/ArrayMapTestScenarios.hpp new file mode 100644 index 00000000000..69d5f95b68d --- /dev/null +++ b/Fw/DataStructures/test/ut/STest/ArrayMapTestScenarios.hpp @@ -0,0 +1,21 @@ +// ====================================================================== +// \title ArrayMapTestScenarios.hpp +// \author Rob Bocchino +// \brief ArrayMap test scenarios +// ====================================================================== + +#include "Fw/DataStructures/test/ut/STest/ArrayMapTestState.hpp" + +namespace Fw { + +namespace ArrayMapTest { + +namespace Scenarios { + +void random(const Fw::StringBase& name, State& state, U32 maxNumSteps); + +} // namespace Scenarios + +} // namespace ArrayMapTest + +} // namespace Fw diff --git a/Fw/DataStructures/test/ut/STest/ArrayMapTestState.hpp b/Fw/DataStructures/test/ut/STest/ArrayMapTestState.hpp new file mode 100644 index 00000000000..41dd5d2e8ed --- /dev/null +++ b/Fw/DataStructures/test/ut/STest/ArrayMapTestState.hpp @@ -0,0 +1,60 @@ +// ====================================================================== +// \title ArrayMapTestState.hpp +// \author bocchino +// \brief hpp file for FIFO map test state +// ====================================================================== + +#ifndef ArrayMapTestState_HPP +#define ArrayMapTestState_HPP + +#include + +#include "Fw/DataStructures/ExternalArrayMap.hpp" +#include "STest/STest/Pick/Pick.hpp" + +namespace Fw { + +namespace ArrayMapTest { + +struct State { + //! The key type + using KeyType = U16; + //! The value type + using ValueType = U32; + //! The map capacity + static constexpr FwSizeType capacity = 1024; + //! The Map type + //using Map = ArrayMap; + //! The ExternalMap type + using ExternalMap = ExternalArrayMap; + //! THe MapBase type + using MapBase = MapBase; + //! The iterator type + using Iterator = MapIterator; + //! Constructor + State(MapBase& a_map) : map(a_map) {} + //! The map under test + MapBase& map; + //! The map for modeling correct behavior + std::map modelMap; + //! Whether to use the stored key + bool useStoredKey = false; + //! The stored key + KeyType storedKey = 0; + //! Whether to use the stored value + bool useStoredValue = false; + //! The stored value + ValueType storedValue = 0; + //! Get a key + KeyType getKey() const { return useStoredKey ? storedKey : static_cast(STest::Pick::any()); } + //! Get a value + ValueType getValue() const { return useStoredValue ? storedValue : static_cast(STest::Pick::any()); } + //! Check whether the model map contains the specified key + bool modelMapContains(KeyType key) const { return modelMap.count(key) != 0; } +}; + +} // namespace ArrayMapTest + +} // namespace Fw + +#endif diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp index 3dc339e2c05..c15e7be3e8d 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp @@ -46,9 +46,9 @@ struct State { bool useStoredValue = false; //! The stored value ValueType storedValue = 0; - //! Get a random key + //! Get a key KeyType getKey() const { return useStoredKey ? storedKey : static_cast(STest::Pick::any()); } - //! Get a random value + //! Get a value ValueType getValue() const { return useStoredValue ? storedValue : static_cast(STest::Pick::any()); } //! Check whether the model map contains the specified key bool modelMapContains(KeyType key) const { return modelMap.count(key) != 0; } From 6de6d34f57df824fda28bbc9dad865f6ec211273 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sat, 5 Jul 2025 15:41:45 -0700 Subject: [PATCH 291/458] Revise ExternalArrayMapTest --- Fw/DataStructures/CMakeLists.txt | 32 ++-- .../test/ut/ExternalArrayMapTest.cpp | 148 ++++++++++-------- .../test/ut/STest/ArrayMapTestState.hpp | 6 +- 3 files changed, 101 insertions(+), 85 deletions(-) diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index 194dd50d96e..040bd194aae 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -5,25 +5,25 @@ set(SOURCE_FILES register_fprime_module() set(UT_SOURCE_FILES - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArrayMapTestRules.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArrayMapTestScenarios.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" ) set(UT_MOD_DEPS diff --git a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp index 8963b54882f..58ed74cac2c 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp @@ -4,84 +4,104 @@ // \brief cpp file for ExternalArrayMap tests // ====================================================================== -#include - #include "Fw/DataStructures/ExternalArrayMap.hpp" #include "STest/STest/Pick/Pick.hpp" +#include "Fw/DataStructures/ExternalArrayMap.hpp" +#include "Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp" #include "Fw/DataStructures/test/ut/STest/ArrayMapTestRules.hpp" #include "Fw/DataStructures/test/ut/STest/ArrayMapTestScenarios.hpp" -#if 0 namespace Fw { -namespace ExternalArrayMapTest { +template +class ExternalArrayMapTester { + public: + ExternalArrayMapTester(const ExternalArrayMap& map) : m_map(map) {} + + const ArraySetOrMapImpl& getImpl() const { return this->m_map.m_impl; } + + private: + const ExternalArrayMap& m_map; +}; + +namespace ArrayMapTest { + +using Entry = SetOrMapIterator; +using Map = ExternalArrayMap; +using MapTester = ExternalArrayMapTester; +using ImplTester = ArraySetOrMapImplTester; TEST(ExternalArrayMap, ZeroArgConstructor) { - ExternalArrayMap impl; - ASSERT_EQ(impl.getCapacity(), 0); - ASSERT_EQ(impl.getSize(), 0); + Map map; + ASSERT_EQ(map.getCapacity(), 0); + ASSERT_EQ(map.getSize(), 0); } TEST(ExternalArrayMap, TypedStorageConstructor) { - State::Entry entries[State::capacity]; - State::Impl impl(entries, State::capacity); - State::Tester tester(impl); - ASSERT_EQ(tester.getEntries().getElements(), entries); - ASSERT_EQ(impl.getCapacity(), FwSizeType(State::capacity)); - ASSERT_EQ(impl.getSize(), 0); + Entry entries[State::capacity]; + Map map(entries, State::capacity); + MapTester mapTester(map); + ImplTester implTester(mapTester.getImpl()); + ASSERT_EQ(implTester.getEntries().getElements(), entries); + ASSERT_EQ(map.getCapacity(), FwSizeType(State::capacity)); + ASSERT_EQ(map.getSize(), 0); } TEST(ExternalArrayMap, UntypedStorageConstructor) { - constexpr auto alignment = State::Impl::getByteArrayAlignment(); - constexpr auto byteArraySize = State::Impl::getByteArraySize(State::capacity); + constexpr auto alignment = Map::getByteArrayAlignment(); + constexpr auto byteArraySize = Map::getByteArraySize(State::capacity); alignas(alignment) U8 bytes[byteArraySize]; - State::Impl impl(ByteArray(&bytes[0], sizeof bytes), State::capacity); - State::Tester tester(impl); - ASSERT_EQ(tester.getEntries().getElements(), reinterpret_cast(bytes)); - ASSERT_EQ(impl.getCapacity(), FwSizeType(State::capacity)); - ASSERT_EQ(impl.getSize(), 0); + Map map(ByteArray(&bytes[0], sizeof bytes), State::capacity); + MapTester mapTester(map); + ImplTester implTester(mapTester.getImpl()); + ASSERT_EQ(implTester.getEntries().getElements(), reinterpret_cast(bytes)); + ASSERT_EQ(map.getCapacity(), FwSizeType(State::capacity)); + ASSERT_EQ(map.getSize(), 0); } TEST(ExternalArrayMap, CopyConstructor) { - State::Entry entries[State::capacity]; + Entry entries[State::capacity]; // Call the constructor providing backing storage - State::Impl impl1(entries, State::capacity); + Map map1(entries, State::capacity); // Insert an item const State::KeyType key = 0; const State::ValueType value = 42; - const auto status = impl1.insert(key, value); + const auto status = map1.insert(key, value); ASSERT_EQ(status, Success::SUCCESS); // Call the copy constructor - State::Impl impl2(impl1); - State::Tester tester1(impl1); - State::Tester tester2(impl2); - ASSERT_EQ(tester2.getEntries().getElements(), entries); - ASSERT_EQ(tester2.getEntries().getSize(), FwSizeType(State::capacity)); - ASSERT_EQ(impl2.getSize(), 1); + Map map2(map1); + MapTester mapTester1(map1); + ImplTester implTester1(mapTester1.getImpl()); + MapTester mapTester2(map2); + ImplTester implTester2(mapTester2.getImpl()); + ASSERT_EQ(implTester2.getEntries().getElements(), entries); + ASSERT_EQ(implTester2.getEntries().getSize(), FwSizeType(State::capacity)); + ASSERT_EQ(map2.getSize(), 1); } TEST(ExternalArrayMap, CopyAssignmentOperator) { - State::Entry entries[State::capacity]; + Entry entries[State::capacity]; // Call the constructor providing backing storage - State::Impl impl1(entries, State::capacity); + Map map1(entries, State::capacity); // Insert an item const State::KeyType key = 0; const State::ValueType value = 42; - const auto status = impl1.insert(key, value); + const auto status = map1.insert(key, value); ASSERT_EQ(status, Success::SUCCESS); // Call the default constructor - State::Impl impl2; - ASSERT_EQ(impl2.getSize(), 0); + Map map2; + ASSERT_EQ(map2.getSize(), 0); // Call the copy assignment operator - impl2 = impl1; - ASSERT_EQ(impl2.getSize(), 1); + map2 = map1; + ASSERT_EQ(map2.getSize(), 1); } +#if 0 TEST(ExternalArrayMapRules, At) { - State::Entry entries[State::capacity]; - State::Impl impl(entries, State::capacity); - State state(impl); + Entry entries[State::capacity]; + Map map(entries, State::capacity); + State state(map); state.useStoredKey = true; Rules::insertNotFull.apply(state); Rules::insertNotFull.apply(state); @@ -91,27 +111,27 @@ TEST(ExternalArrayMapRules, At) { } TEST(ExternalArrayMapRules, Clear) { - State::Entry entries[State::capacity]; - State::Impl impl(entries, State::capacity); - State state(impl); + Entry entries[State::capacity]; + Map map(entries, State::capacity); + State state(map); Rules::insertNotFull.apply(state); - ASSERT_EQ(state.impl.getSize(), 1); + ASSERT_EQ(state.map.getSize(), 1); Rules::clear.apply(state); - ASSERT_EQ(state.impl.getSize(), 0); + ASSERT_EQ(state.map.getSize(), 0); } TEST(ExternalArrayMapRules, FindExisting) { - State::Entry entries[State::capacity]; - State::Impl impl(entries, State::capacity); - State state(impl); + Entry entries[State::capacity]; + Map map(entries, State::capacity); + State state(map); Rules::insertNotFull.apply(state); Rules::findExisting.apply(state); } TEST(ExternalArrayMapRules, InsertFull) { - State::Entry entries[State::capacity]; - State::Impl impl(entries, State::capacity); - State state(impl); + Entry entries[State::capacity]; + Map map(entries, State::capacity); + State state(map); state.useStoredKey = true; for (FwSizeType i = 0; i < State::capacity; i++) { state.storedKey = static_cast(i); @@ -122,16 +142,16 @@ TEST(ExternalArrayMapRules, InsertFull) { } TEST(ExternalArrayMapRules, InsertNotFull) { - State::Entry entries[State::capacity]; - State::Impl impl(entries, State::capacity); - State state(impl); + Entry entries[State::capacity]; + Map map(entries, State::capacity); + State state(map); Rules::insertNotFull.apply(state); } TEST(ExternalArrayMapRules, Remove) { - State::Entry entries[State::capacity]; - State::Impl impl(entries, State::capacity); - State state(impl); + Entry entries[State::capacity]; + Map map(entries, State::capacity); + State state(map); state.useStoredKey = true; Rules::insertNotFull.apply(state); Rules::remove.apply(state); @@ -139,20 +159,20 @@ TEST(ExternalArrayMapRules, Remove) { } TEST(ExternalArrayMapRules, RemoveExisting) { - State::Entry entries[State::capacity]; - State::Impl impl(entries, State::capacity); - State state(impl); + Entry entries[State::capacity]; + Map map(entries, State::capacity); + State state(map); Rules::insertNotFull.apply(state); Rules::removeExisting.apply(state); } TEST(ExternalArrayMapScenarios, Random) { - State::Entry entries[State::capacity]; - State::Impl impl(entries, State::capacity); - State state(impl); + Entry entries[State::capacity]; + Map map(entries, State::capacity); + State state(map); Scenarios::random(Fw::String("ExternalArrayMapRandom"), state, 1000); } +#endif -} // namespace ArraySetOrMapTest +} // namespace ArrayMapTest } // namespace Fw -#endif diff --git a/Fw/DataStructures/test/ut/STest/ArrayMapTestState.hpp b/Fw/DataStructures/test/ut/STest/ArrayMapTestState.hpp index 41dd5d2e8ed..327128dd17a 100644 --- a/Fw/DataStructures/test/ut/STest/ArrayMapTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/ArrayMapTestState.hpp @@ -9,7 +9,7 @@ #include -#include "Fw/DataStructures/ExternalArrayMap.hpp" +#include "Fw/DataStructures/MapBase.hpp" #include "STest/STest/Pick/Pick.hpp" namespace Fw { @@ -23,10 +23,6 @@ struct State { using ValueType = U32; //! The map capacity static constexpr FwSizeType capacity = 1024; - //! The Map type - //using Map = ArrayMap; - //! The ExternalMap type - using ExternalMap = ExternalArrayMap; //! THe MapBase type using MapBase = MapBase; //! The iterator type From fc10a29ae5c8cffadb237edfd68e4e3b6623545c Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sat, 5 Jul 2025 16:02:00 -0700 Subject: [PATCH 292/458] Revise design for sets and maps --- Fw/DataStructures/docs/ArraySetOrMapImpl.md | 44 ++++++-- Fw/DataStructures/docs/ExternalArrayMap.md | 116 +++++++++++++------- Fw/DataStructures/docs/ExternalArraySet.md | 22 ++++ Fw/DataStructures/docs/MapBase.md | 15 +-- Fw/DataStructures/docs/SetBase.md | 15 +-- 5 files changed, 137 insertions(+), 75 deletions(-) diff --git a/Fw/DataStructures/docs/ArraySetOrMapImpl.md b/Fw/DataStructures/docs/ArraySetOrMapImpl.md index 251023ed910..e8be94404af 100644 --- a/Fw/DataStructures/docs/ArraySetOrMapImpl.md +++ b/Fw/DataStructures/docs/ArraySetOrMapImpl.md @@ -73,10 +73,10 @@ Call `setStorage(data, capacity)`. ### 4.4. Copy Constructor ```c++ -ArraySetOrMapImpl(const ArraySetOrMapImpl& map) +ArraySetOrMapImpl(const ArraySetOrMapImpl& impl) ``` -Set `*this = map`. +Set `*this = impl`. ### 4.5. Destructor @@ -120,7 +120,31 @@ void clear() Set `m_size = 0`. -### 5.4. find +### 5.4. copyDataFrom + +```c++ +void copyDataFrom(const MapBase& impl) +``` + +1. If `&impl != this` then + + 1. Call `clear()`. + + 1. Let `size` be the minimum of `impl.getSize()` and `getCapacity()`. + + 1. Set `e = impl.getHeadIterator()`. + + 1. For `i` in [0, `size`) + + 1. Assert `e != nullptr`. + + 1. Set `status = insert(e->getKey(), e->getValue())`. + + 1. Assert `status == Success::SUCCESS`. + + 1. Set `e = e->getNextIterator()` + +### 5.5. find ```c++ Success find(const KE& keyOrElement, VN& valueOrNil) @@ -142,7 +166,7 @@ Success find(const KE& keyOrElement, VN& valueOrNil) 1. Return `status`. -### 5.5. getCapacity +### 5.6. getCapacity ```c++ FwSizeType getCapacity() const @@ -150,7 +174,7 @@ FwSizeType getCapacity() const Return `m_entries.getSize()`. -### 5.6. getHeadIterator +### 5.7. getHeadIterator ```c++ const Iterator* getHeadIterator() const @@ -164,7 +188,7 @@ const Iterator* getHeadIterator() const 1. Return `result`. -### 5.7. getSize +### 5.8. getSize ```c++ FwSizeType getSize() @@ -172,7 +196,7 @@ FwSizeType getSize() Return `m_size`. -### 5.8. insert +### 5.9. insert ```c++ Success insert(const KE& keyOrElement, const VN& valueOrNil) @@ -205,7 +229,7 @@ Success insert(const KE& keyOrElement, const VN& valueOrNil) 1. Return `status`. -### 5.9. remove +### 5.10. remove ```c++ Success remove(const KE& keyOrElement, VN& valueOrNil) @@ -235,7 +259,7 @@ Success remove(const KE& keyOrElement, VN& valueOrNil) 1. Return `status`. -### 5.10. setStorage (Typed Data) +### 5.11. setStorage (Typed Data) ```c++ void setStorage(Entry* entries, FwSizeType capacity) @@ -245,7 +269,7 @@ void setStorage(Entry* entries, FwSizeType capacity) 1. Call `clear()`. -### 5.11. setStorage (Untyped Data) +### 5.12. setStorage (Untyped Data) ```c++ void setStorage(ByteArray data, FwSizeType capacity) diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index 6534baae37c..cfa32b11c9e 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -71,9 +71,10 @@ Call `m_impl.setStorage(entries, capacity)`. _Example:_ ```c++ +using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -ExternalArrayMap::Entry entries[capacity]; -ExternalArrayMap map(entries, capacity); +Map::Entry entries[capacity]; +Map map(entries, capacity); ``` ### 5.3. Constructor Providing Untyped Backing Storage @@ -90,11 +91,12 @@ Call `m_impl.setStorage(data, capacity)`. _Example:_ ```c++ +using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -constexpr U8 alignment = ExternalArrayMap::getByteArrayAlignment(); -constexpr FwSizeType byteArraySize = ExternalArrayMap::getByteArraySize(capacity); +constexpr U8 alignment = Map::getByteArrayAlignment(); +constexpr FwSizeType byteArraySize = Map::getByteArraySize(capacity); alignas(alignment) U8 bytes[byteArraySize]; -ExternalArrayMap map(ByteArray(&bytes[0], sizeof bytes), capacity); +Map map(ByteArray(&bytes[0], sizeof bytes), capacity); ``` ### 5.4. Copy Constructor @@ -107,17 +109,18 @@ Set `*this = map`. _Example:_ ```c++ +using Map = ExternalArrayMap; constexpr FwSizeType capacity = 3; -ExternalArrayMap::Entry entries[capacity]; +Map::Entry entries[capacity]; // Call the constructor providing backing storage -ExternalArrayMap m1(entries, capacity); +Map m1(entries, capacity); // Insert an item const U16 key = 0; const U32 value = 42; const auto status = m1.insert(key, value); ASSERT_EQ(status, Success::SUCCESS); // Call the copy constructor -ExternalArrayMap m2(m1); +Map m2(m1); ASSERT_EQ(m2.getSize(), 1); ``` @@ -145,17 +148,18 @@ ExternalArrayMap& operator=(const ExternalArrayMap& map) _Example:_ ```c++ +using Map = ExternalArrayMap; constexpr FwSizeType capacity = 3; -ExternalArrayMap::Entry entries[capacity]; +Map::Entry entries[capacity]; // Call the constructor providing backing storage -ExternalArrayMap m1(entries, capacity); +Map m1(entries, capacity); // Insert an item U16 key = 0; U32 value = 42; const auto status = m1.insert(value); ASSERT_EQ(status, Success::SUCCESS); // Call the default constructor -ExternalArrayMap m2; +Map m2; ASSERT_EQ(m2.getSize(), 0); // Call the copy assignment operator m2 = m1; @@ -172,9 +176,10 @@ Return `m_impl.at(index)`. _Example:_ ```c++ +using Map = ExternalArrayMap; constexpr FwSizeType capacity = 3; -ExternalArrayMap::Entry entries[capacity]; -ExternalArrayMap map(entries, capacity); +Map::Entry entries[capacity]; +Map map(entries, capacity); const auto status = map.insert(0, 1); ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(map.at(0), 1); @@ -191,16 +196,39 @@ Call `m_impl.clear()`. _Example:_ ```c++ +using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -ExternalArrayMap::Entry entries[capacity]; -ExternalArrayMap map(entries, capacity); +Map::Entry entries[capacity]; +Map map(entries, capacity); const auto status = map.insert(0, 3); ASSERT_EQ(map.getSize(), 1); map.clear(); ASSERT_EQ(map.getSize(), 0); ``` -### 6.4. find +### 6.4. copyDataFrom + +```c++ +void copyDataFrom(const MapBase& map) override +``` + +Call `m_impl.copyDataFrom(map)`. + +_Example:_ +```c++ +using Map = ExternalArrayMap; +constexpr FwSizeType capacity = 10; +Map::Entry entries1[capacity]; +Map map1(entries1, capacity); +const auto status = map1.insert(0, 3); +Map::Entry entries2[capacity]; +Map map2(entries2, capacity); +ASSERT_EQ(map2.getSize(), 0); +map2.copyDataFrom(map1); +ASSERT_EQ(map.getSize(), 1); +``` + +### 6.5. find ```c++ Success find(const K& key, V& value) override @@ -210,9 +238,10 @@ Return `m_impl.find(key, value)`. _Example:_ ```c++ +using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -ExternalArrayMap::Entry entries[capacity]; -ExternalArrayMap map(entries, capacity); +Map::Entry entries[capacity]; +Map map(entries, capacity); U32 value = 0; auto status = map.find(0, value); ASSERT_EQ(status, Success::FAILURE); @@ -223,7 +252,7 @@ ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(value, 1); ``` -### 6.5. getCapacity +### 6.6. getCapacity ```c++ FwSizeType getCapacity() const override @@ -233,13 +262,14 @@ Return `m_impl.getCapacity()`. _Example:_ ```c++ +using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -ExternalArrayMap::Entry entries[capacity]; -ExternalArrayMap map(entries, capacity); +Map::Entry entries[capacity]; +Map map(entries, capacity); ASSERT_EQ(map.getCapacity(), capacity); ``` -### 6.6. getHeadIterator +### 6.7. getHeadIterator ```c++ const Iterator* getHeadIterator const override @@ -251,9 +281,10 @@ Return `m_impl.getHeadIterator()`. _Example:_ ```c++ +using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -ExternalArrayMap::Entry entries[capacity]; -ExternalArrayMap map(entries, capacity); +Map::Entry entries[capacity]; +Map map(entries, capacity); const auto* e = map.getHeadIterator(); FW_ASSERT(e == nullptr); map.insert(0, 1); @@ -263,7 +294,7 @@ ASSERT_EQ(e->getKey(), 0); ASSERT_EQ(e->getValue(), 1); ``` -### 6.7. getSize +### 6.8. getSize ```c++ FwSizeType getSize() const override @@ -273,9 +304,10 @@ Return `m_impl.getSize()`. _Example:_ ```c++ +using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -ExternalArrayMap::Entry entries[capacity]; -ExternalArrayMap map(entries, capacity); +Map::Entry entries[capacity]; +Map map(entries, capacity); auto size = map.getSize(); ASSERT_EQ(size, 0); const auto status = map.insert(0, 3); @@ -284,7 +316,7 @@ size = map.getSize(); ASSERT_EQ(size, 1); ``` -### 6.8. insert +### 6.9. insert ```c++ Success insert(const K& key, const V& value) override @@ -294,9 +326,10 @@ Return `m_impl.insert(key, value)`. _Example:_ ```c++ +using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -ExternalArrayMap::Entry entries[capacity]; -ExternalArrayMap map(entries, capacity); +Map::Entry entries[capacity]; +Map map(entries, capacity); auto size = map.getSize(); ASSERT_EQ(size, 0); const auto status = map.insert(0, 1); @@ -305,7 +338,7 @@ size = map.getSize(); ASSERT_EQ(size, 1); ``` -### 6.9. remove +### 6.10. remove ```c++ Success remove(const K& key, V& value) override @@ -315,9 +348,10 @@ Return `m_impl.remove(key, value)`. _Example:_ ```c++ +using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -ExternalArrayMap::Entry entries[capacity]; -ExternalArrayMap map(entries, capacity); +Map::Entry entries[capacity]; +Map map(entries, capacity); auto size = map.getSize(); ASSERT_EQ(size, 0); auto status = map.insert(0, 1); @@ -336,7 +370,7 @@ ASSERT_EQ(size, 0); ASSERT_EQ(value, 1); ``` -### 6.10. setStorage (Typed Data) +### 6.11. setStorage (Typed Data) ```c++ void setStorage(Entry* entries, FwSizeType capacity) @@ -350,13 +384,14 @@ Call `m_impl.setStorage(entries, capacity)`. _Example:_ ```c++ +using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -ExternalArrayMap map; -ExternalArrayMap::Entry entries[capacity]; +Map map; +Map::Entry entries[capacity]; map.setStorage(entries, capacity); ``` -### 6.11. setStorage (Untyped Data) +### 6.12. setStorage (Untyped Data) ```c++ void setStorage(ByteArray data, FwSizeType capacity) @@ -371,11 +406,12 @@ contain at least [`getByteArraySize(size)`](#getByteArraySize) bytes. 1. Call `clear()`. ```c++ +using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -constexpr U8 alignment = ExternalArrayMap::getByteArrayAlignment(); -constexpr FwSizeType byteArraySize = ExternalArrayMap::getByteArraySize(capacity); +constexpr U8 alignment = Map::getByteArrayAlignment(); +constexpr FwSizeType byteArraySize = Map::getByteArraySize(capacity); alignas(alignment) U8 bytes[byteArraySize]; -ExternalArrayMap map; +Map map; map.setStorage(ByteArray(&bytes[0], sizeof bytes), capacity); ``` diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md index ddb5f4243cd..4230c53a165 100644 --- a/Fw/DataStructures/docs/ExternalArraySet.md +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -198,6 +198,28 @@ set.clear(); ASSERT_EQ(set.getSize(), 0); ``` +### 6.4. copyDataFrom + +```c++ +void copyDataFrom(const SetBase& set) override +``` + +Call `m_impl.copyDataFrom(set)`. + +_Example:_ +```c++ +using Set = ExternalArraySet; +constexpr FwSizeType capacity = 10; +Set::Entry entries1[capacity]; +Set set1(entries1, capacity); +const auto status = set1.insert(42); +Set::Entry entries2[capacity]; +Set set2(entries2, capacity); +ASSERT_EQ(set2.getSize(), 0); +set2.copyDataFrom(set1); +ASSERT_EQ(set.getSize(), 1); +``` + ### 6.4. find ```c++ diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index e787e4c0bf6..d6f6894f619 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -81,7 +81,7 @@ void f(MapBase& map) { ### 6.2. copyDataFrom ```c++ -void copyDataFrom(const MapBase& map) +virtual void copyDataFrom(const MapBase& map) = 0 ``` 1. If `&map != this` then @@ -90,17 +90,8 @@ void copyDataFrom(const MapBase& map) 1. Let `size` be the minimum of `map.getSize()` and `getCapacity()`. - 1. Set `e = map.getHeadIterator()`. - - 1. For `i` in [0, `size`) - - 1. Assert `e != nullptr`. - - 1. Set `status = insert(e->getKey(), e->getValue())`. - - 1. Assert `status == Success::SUCCESS`. - - 1. Set `e = e->getNextMapIterator()` + 1. For each (key, value) pair _P_ of `map` up to `size` pairs, insert _P_ + into the map. _Example:_ ```c++ diff --git a/Fw/DataStructures/docs/SetBase.md b/Fw/DataStructures/docs/SetBase.md index e4a62b399ae..af70c435c37 100644 --- a/Fw/DataStructures/docs/SetBase.md +++ b/Fw/DataStructures/docs/SetBase.md @@ -80,7 +80,7 @@ void f(SetBase& set) { ### 6.2. copyDataFrom ```c++ -void copyDataFrom(const SetBase& set) +virtual void copyDataFrom(const SetBase& set) = 0 ``` 1. If `&set != this` then @@ -89,18 +89,7 @@ void copyDataFrom(const SetBase& set) 1. Let `size` be the minimum of `set.getSize()` and `getCapacity()`. - 1. Set `e = set.getHeadIterator()`. - - 1. For `i` in [0, `size`) - - 1. Assert `e != nullptr`. - - 1. Set `status = insert(e->getElement())`. - - 1. Assert `status == Success::SUCCESS`. - - 1. Set `e = e->getNextSetIterator()` - + 1. For each element _E_ of `set`, up to `size` elements, insert `E` into the set. _Example:_ ```c++ From 5ad7e732045d0d52296661a949d9e8d7811a6de8 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sat, 5 Jul 2025 16:13:50 -0700 Subject: [PATCH 293/458] Revert changes to design --- Fw/DataStructures/docs/ArraySetOrMapImpl.md | 44 ++------ Fw/DataStructures/docs/ExternalArrayMap.md | 116 +++++++------------- Fw/DataStructures/docs/ExternalArraySet.md | 22 ---- Fw/DataStructures/docs/MapBase.md | 15 ++- Fw/DataStructures/docs/SetBase.md | 15 ++- 5 files changed, 75 insertions(+), 137 deletions(-) diff --git a/Fw/DataStructures/docs/ArraySetOrMapImpl.md b/Fw/DataStructures/docs/ArraySetOrMapImpl.md index e8be94404af..251023ed910 100644 --- a/Fw/DataStructures/docs/ArraySetOrMapImpl.md +++ b/Fw/DataStructures/docs/ArraySetOrMapImpl.md @@ -73,10 +73,10 @@ Call `setStorage(data, capacity)`. ### 4.4. Copy Constructor ```c++ -ArraySetOrMapImpl(const ArraySetOrMapImpl& impl) +ArraySetOrMapImpl(const ArraySetOrMapImpl& map) ``` -Set `*this = impl`. +Set `*this = map`. ### 4.5. Destructor @@ -120,31 +120,7 @@ void clear() Set `m_size = 0`. -### 5.4. copyDataFrom - -```c++ -void copyDataFrom(const MapBase& impl) -``` - -1. If `&impl != this` then - - 1. Call `clear()`. - - 1. Let `size` be the minimum of `impl.getSize()` and `getCapacity()`. - - 1. Set `e = impl.getHeadIterator()`. - - 1. For `i` in [0, `size`) - - 1. Assert `e != nullptr`. - - 1. Set `status = insert(e->getKey(), e->getValue())`. - - 1. Assert `status == Success::SUCCESS`. - - 1. Set `e = e->getNextIterator()` - -### 5.5. find +### 5.4. find ```c++ Success find(const KE& keyOrElement, VN& valueOrNil) @@ -166,7 +142,7 @@ Success find(const KE& keyOrElement, VN& valueOrNil) 1. Return `status`. -### 5.6. getCapacity +### 5.5. getCapacity ```c++ FwSizeType getCapacity() const @@ -174,7 +150,7 @@ FwSizeType getCapacity() const Return `m_entries.getSize()`. -### 5.7. getHeadIterator +### 5.6. getHeadIterator ```c++ const Iterator* getHeadIterator() const @@ -188,7 +164,7 @@ const Iterator* getHeadIterator() const 1. Return `result`. -### 5.8. getSize +### 5.7. getSize ```c++ FwSizeType getSize() @@ -196,7 +172,7 @@ FwSizeType getSize() Return `m_size`. -### 5.9. insert +### 5.8. insert ```c++ Success insert(const KE& keyOrElement, const VN& valueOrNil) @@ -229,7 +205,7 @@ Success insert(const KE& keyOrElement, const VN& valueOrNil) 1. Return `status`. -### 5.10. remove +### 5.9. remove ```c++ Success remove(const KE& keyOrElement, VN& valueOrNil) @@ -259,7 +235,7 @@ Success remove(const KE& keyOrElement, VN& valueOrNil) 1. Return `status`. -### 5.11. setStorage (Typed Data) +### 5.10. setStorage (Typed Data) ```c++ void setStorage(Entry* entries, FwSizeType capacity) @@ -269,7 +245,7 @@ void setStorage(Entry* entries, FwSizeType capacity) 1. Call `clear()`. -### 5.12. setStorage (Untyped Data) +### 5.11. setStorage (Untyped Data) ```c++ void setStorage(ByteArray data, FwSizeType capacity) diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index cfa32b11c9e..6534baae37c 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -71,10 +71,9 @@ Call `m_impl.setStorage(entries, capacity)`. _Example:_ ```c++ -using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -Map::Entry entries[capacity]; -Map map(entries, capacity); +ExternalArrayMap::Entry entries[capacity]; +ExternalArrayMap map(entries, capacity); ``` ### 5.3. Constructor Providing Untyped Backing Storage @@ -91,12 +90,11 @@ Call `m_impl.setStorage(data, capacity)`. _Example:_ ```c++ -using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -constexpr U8 alignment = Map::getByteArrayAlignment(); -constexpr FwSizeType byteArraySize = Map::getByteArraySize(capacity); +constexpr U8 alignment = ExternalArrayMap::getByteArrayAlignment(); +constexpr FwSizeType byteArraySize = ExternalArrayMap::getByteArraySize(capacity); alignas(alignment) U8 bytes[byteArraySize]; -Map map(ByteArray(&bytes[0], sizeof bytes), capacity); +ExternalArrayMap map(ByteArray(&bytes[0], sizeof bytes), capacity); ``` ### 5.4. Copy Constructor @@ -109,18 +107,17 @@ Set `*this = map`. _Example:_ ```c++ -using Map = ExternalArrayMap; constexpr FwSizeType capacity = 3; -Map::Entry entries[capacity]; +ExternalArrayMap::Entry entries[capacity]; // Call the constructor providing backing storage -Map m1(entries, capacity); +ExternalArrayMap m1(entries, capacity); // Insert an item const U16 key = 0; const U32 value = 42; const auto status = m1.insert(key, value); ASSERT_EQ(status, Success::SUCCESS); // Call the copy constructor -Map m2(m1); +ExternalArrayMap m2(m1); ASSERT_EQ(m2.getSize(), 1); ``` @@ -148,18 +145,17 @@ ExternalArrayMap& operator=(const ExternalArrayMap& map) _Example:_ ```c++ -using Map = ExternalArrayMap; constexpr FwSizeType capacity = 3; -Map::Entry entries[capacity]; +ExternalArrayMap::Entry entries[capacity]; // Call the constructor providing backing storage -Map m1(entries, capacity); +ExternalArrayMap m1(entries, capacity); // Insert an item U16 key = 0; U32 value = 42; const auto status = m1.insert(value); ASSERT_EQ(status, Success::SUCCESS); // Call the default constructor -Map m2; +ExternalArrayMap m2; ASSERT_EQ(m2.getSize(), 0); // Call the copy assignment operator m2 = m1; @@ -176,10 +172,9 @@ Return `m_impl.at(index)`. _Example:_ ```c++ -using Map = ExternalArrayMap; constexpr FwSizeType capacity = 3; -Map::Entry entries[capacity]; -Map map(entries, capacity); +ExternalArrayMap::Entry entries[capacity]; +ExternalArrayMap map(entries, capacity); const auto status = map.insert(0, 1); ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(map.at(0), 1); @@ -196,39 +191,16 @@ Call `m_impl.clear()`. _Example:_ ```c++ -using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -Map::Entry entries[capacity]; -Map map(entries, capacity); +ExternalArrayMap::Entry entries[capacity]; +ExternalArrayMap map(entries, capacity); const auto status = map.insert(0, 3); ASSERT_EQ(map.getSize(), 1); map.clear(); ASSERT_EQ(map.getSize(), 0); ``` -### 6.4. copyDataFrom - -```c++ -void copyDataFrom(const MapBase& map) override -``` - -Call `m_impl.copyDataFrom(map)`. - -_Example:_ -```c++ -using Map = ExternalArrayMap; -constexpr FwSizeType capacity = 10; -Map::Entry entries1[capacity]; -Map map1(entries1, capacity); -const auto status = map1.insert(0, 3); -Map::Entry entries2[capacity]; -Map map2(entries2, capacity); -ASSERT_EQ(map2.getSize(), 0); -map2.copyDataFrom(map1); -ASSERT_EQ(map.getSize(), 1); -``` - -### 6.5. find +### 6.4. find ```c++ Success find(const K& key, V& value) override @@ -238,10 +210,9 @@ Return `m_impl.find(key, value)`. _Example:_ ```c++ -using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -Map::Entry entries[capacity]; -Map map(entries, capacity); +ExternalArrayMap::Entry entries[capacity]; +ExternalArrayMap map(entries, capacity); U32 value = 0; auto status = map.find(0, value); ASSERT_EQ(status, Success::FAILURE); @@ -252,7 +223,7 @@ ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(value, 1); ``` -### 6.6. getCapacity +### 6.5. getCapacity ```c++ FwSizeType getCapacity() const override @@ -262,14 +233,13 @@ Return `m_impl.getCapacity()`. _Example:_ ```c++ -using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -Map::Entry entries[capacity]; -Map map(entries, capacity); +ExternalArrayMap::Entry entries[capacity]; +ExternalArrayMap map(entries, capacity); ASSERT_EQ(map.getCapacity(), capacity); ``` -### 6.7. getHeadIterator +### 6.6. getHeadIterator ```c++ const Iterator* getHeadIterator const override @@ -281,10 +251,9 @@ Return `m_impl.getHeadIterator()`. _Example:_ ```c++ -using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -Map::Entry entries[capacity]; -Map map(entries, capacity); +ExternalArrayMap::Entry entries[capacity]; +ExternalArrayMap map(entries, capacity); const auto* e = map.getHeadIterator(); FW_ASSERT(e == nullptr); map.insert(0, 1); @@ -294,7 +263,7 @@ ASSERT_EQ(e->getKey(), 0); ASSERT_EQ(e->getValue(), 1); ``` -### 6.8. getSize +### 6.7. getSize ```c++ FwSizeType getSize() const override @@ -304,10 +273,9 @@ Return `m_impl.getSize()`. _Example:_ ```c++ -using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -Map::Entry entries[capacity]; -Map map(entries, capacity); +ExternalArrayMap::Entry entries[capacity]; +ExternalArrayMap map(entries, capacity); auto size = map.getSize(); ASSERT_EQ(size, 0); const auto status = map.insert(0, 3); @@ -316,7 +284,7 @@ size = map.getSize(); ASSERT_EQ(size, 1); ``` -### 6.9. insert +### 6.8. insert ```c++ Success insert(const K& key, const V& value) override @@ -326,10 +294,9 @@ Return `m_impl.insert(key, value)`. _Example:_ ```c++ -using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -Map::Entry entries[capacity]; -Map map(entries, capacity); +ExternalArrayMap::Entry entries[capacity]; +ExternalArrayMap map(entries, capacity); auto size = map.getSize(); ASSERT_EQ(size, 0); const auto status = map.insert(0, 1); @@ -338,7 +305,7 @@ size = map.getSize(); ASSERT_EQ(size, 1); ``` -### 6.10. remove +### 6.9. remove ```c++ Success remove(const K& key, V& value) override @@ -348,10 +315,9 @@ Return `m_impl.remove(key, value)`. _Example:_ ```c++ -using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -Map::Entry entries[capacity]; -Map map(entries, capacity); +ExternalArrayMap::Entry entries[capacity]; +ExternalArrayMap map(entries, capacity); auto size = map.getSize(); ASSERT_EQ(size, 0); auto status = map.insert(0, 1); @@ -370,7 +336,7 @@ ASSERT_EQ(size, 0); ASSERT_EQ(value, 1); ``` -### 6.11. setStorage (Typed Data) +### 6.10. setStorage (Typed Data) ```c++ void setStorage(Entry* entries, FwSizeType capacity) @@ -384,14 +350,13 @@ Call `m_impl.setStorage(entries, capacity)`. _Example:_ ```c++ -using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -Map map; -Map::Entry entries[capacity]; +ExternalArrayMap map; +ExternalArrayMap::Entry entries[capacity]; map.setStorage(entries, capacity); ``` -### 6.12. setStorage (Untyped Data) +### 6.11. setStorage (Untyped Data) ```c++ void setStorage(ByteArray data, FwSizeType capacity) @@ -406,12 +371,11 @@ contain at least [`getByteArraySize(size)`](#getByteArraySize) bytes. 1. Call `clear()`. ```c++ -using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -constexpr U8 alignment = Map::getByteArrayAlignment(); -constexpr FwSizeType byteArraySize = Map::getByteArraySize(capacity); +constexpr U8 alignment = ExternalArrayMap::getByteArrayAlignment(); +constexpr FwSizeType byteArraySize = ExternalArrayMap::getByteArraySize(capacity); alignas(alignment) U8 bytes[byteArraySize]; -Map map; +ExternalArrayMap map; map.setStorage(ByteArray(&bytes[0], sizeof bytes), capacity); ``` diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md index 4230c53a165..ddb5f4243cd 100644 --- a/Fw/DataStructures/docs/ExternalArraySet.md +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -198,28 +198,6 @@ set.clear(); ASSERT_EQ(set.getSize(), 0); ``` -### 6.4. copyDataFrom - -```c++ -void copyDataFrom(const SetBase& set) override -``` - -Call `m_impl.copyDataFrom(set)`. - -_Example:_ -```c++ -using Set = ExternalArraySet; -constexpr FwSizeType capacity = 10; -Set::Entry entries1[capacity]; -Set set1(entries1, capacity); -const auto status = set1.insert(42); -Set::Entry entries2[capacity]; -Set set2(entries2, capacity); -ASSERT_EQ(set2.getSize(), 0); -set2.copyDataFrom(set1); -ASSERT_EQ(set.getSize(), 1); -``` - ### 6.4. find ```c++ diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index d6f6894f619..e787e4c0bf6 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -81,7 +81,7 @@ void f(MapBase& map) { ### 6.2. copyDataFrom ```c++ -virtual void copyDataFrom(const MapBase& map) = 0 +void copyDataFrom(const MapBase& map) ``` 1. If `&map != this` then @@ -90,8 +90,17 @@ virtual void copyDataFrom(const MapBase& map) = 0 1. Let `size` be the minimum of `map.getSize()` and `getCapacity()`. - 1. For each (key, value) pair _P_ of `map` up to `size` pairs, insert _P_ - into the map. + 1. Set `e = map.getHeadIterator()`. + + 1. For `i` in [0, `size`) + + 1. Assert `e != nullptr`. + + 1. Set `status = insert(e->getKey(), e->getValue())`. + + 1. Assert `status == Success::SUCCESS`. + + 1. Set `e = e->getNextMapIterator()` _Example:_ ```c++ diff --git a/Fw/DataStructures/docs/SetBase.md b/Fw/DataStructures/docs/SetBase.md index af70c435c37..e4a62b399ae 100644 --- a/Fw/DataStructures/docs/SetBase.md +++ b/Fw/DataStructures/docs/SetBase.md @@ -80,7 +80,7 @@ void f(SetBase& set) { ### 6.2. copyDataFrom ```c++ -virtual void copyDataFrom(const SetBase& set) = 0 +void copyDataFrom(const SetBase& set) ``` 1. If `&set != this` then @@ -89,7 +89,18 @@ virtual void copyDataFrom(const SetBase& set) = 0 1. Let `size` be the minimum of `set.getSize()` and `getCapacity()`. - 1. For each element _E_ of `set`, up to `size` elements, insert `E` into the set. + 1. Set `e = set.getHeadIterator()`. + + 1. For `i` in [0, `size`) + + 1. Assert `e != nullptr`. + + 1. Set `status = insert(e->getElement())`. + + 1. Assert `status == Success::SUCCESS`. + + 1. Set `e = e->getNextSetIterator()` + _Example:_ ```c++ From bb777a7750959863e2b127cca6a349cf0b342d54 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sat, 5 Jul 2025 16:35:23 -0700 Subject: [PATCH 294/458] Revise unit tests for Fw/DataStructures --- Fw/DataStructures/ArraySetOrMapImpl.hpp | 2 +- Fw/DataStructures/CMakeLists.txt | 32 +++++----- .../test/ut/ExternalArrayMapTest.cpp | 47 ++++++++++++++ .../test/ut/ExternalFifoQueueTest.cpp | 30 +-------- Fw/DataStructures/test/ut/FifoQueueTest.cpp | 30 +-------- .../test/ut/STest/FifoQueueTestState.hpp | 61 ++++++++++++------- 6 files changed, 110 insertions(+), 92 deletions(-) diff --git a/Fw/DataStructures/ArraySetOrMapImpl.hpp b/Fw/DataStructures/ArraySetOrMapImpl.hpp index 7852acf31ba..f9de4fa0c4e 100644 --- a/Fw/DataStructures/ArraySetOrMapImpl.hpp +++ b/Fw/DataStructures/ArraySetOrMapImpl.hpp @@ -60,7 +60,7 @@ class ArraySetOrMapImpl { } //! Copy constructor - ArraySetOrMapImpl(const ArraySetOrMapImpl& map) { *this = map; } + ArraySetOrMapImpl(const ArraySetOrMapImpl& impl) { *this = impl; } //! Destructor virtual ~ArraySetOrMapImpl() = default; diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index 040bd194aae..194dd50d96e 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -5,25 +5,25 @@ set(SOURCE_FILES register_fprime_module() set(UT_SOURCE_FILES -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArrayMapTestRules.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArrayMapTestScenarios.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" ) set(UT_MOD_DEPS diff --git a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp index 58ed74cac2c..94b3e862efe 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp @@ -97,6 +97,53 @@ TEST(ExternalArrayMap, CopyAssignmentOperator) { ASSERT_EQ(map2.getSize(), 1); } +namespace { + +void testCopyDataFrom(State::MapBase& m1, FwSizeType size1, State::MapBase& m2) { + m1.clear(); + for (FwSizeType i = 0; i < size1; i++) { + const auto status = m1.insert(static_cast(i), static_cast(i)); + ASSERT_EQ(status, Success::SUCCESS); + } + m2.copyDataFrom(m1); + const auto capacity2 = m2.getCapacity(); + const FwSizeType size = FW_MIN(size1, capacity2); + for (FwSizeType i = 0; i < size; i++) { + State::KeyType key = static_cast(i); + U32 val = 0; + const auto status = m2.find(key, val); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(val, static_cast(i)); + } +} + +} // namespace + +TEST(ExternalFifoQueue, CopyDataFrom) { + constexpr FwSizeType maxSize = 10; + constexpr FwSizeType smallSize = maxSize / 2; + Entry entries1[maxSize]; + Entry entries2[maxSize]; + Map m1(entries1, maxSize); + // size1 < capacity2 + { + Map m2(entries2, maxSize); + testCopyDataFrom(m1, smallSize, m2); + } +#if 0 + // size1 == size2 + { + ExternalFifoQueue m2(items2, maxSize); + testCopyDataFrom(m1, maxSize, m2); + } + // size1 > size2 + { + ExternalFifoQueue m2(items2, smallSize); + testCopyDataFrom(m1, maxSize, m2); + } +#endif +} + #if 0 TEST(ExternalArrayMapRules, At) { Entry entries[State::capacity]; diff --git a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp index 50bdaf6f346..17e3d0387ae 100644 --- a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp @@ -170,30 +170,6 @@ TEST(ExternalFifoQueue, DequeueEmpty) { ASSERT_EQ(status, Success::FAILURE); } -namespace { - -void testCopyDataFrom(FifoQueueBase& q1, FwSizeType size1, FifoQueueBase& q2) { - q1.clear(); - for (FwSizeType i = 0; i < size1; i++) { - const auto status = q1.enqueue(static_cast(i)); - ASSERT_EQ(status, Success::SUCCESS); - } - q2.copyDataFrom(q1); - const auto capacity2 = q2.getCapacity(); - const FwSizeType size = FW_MIN(size1, capacity2); - for (FwSizeType i = 0; i < size; i++) { - U32 val1 = 0; - auto status = q1.peek(val1, i); - ASSERT_EQ(status, Success::SUCCESS); - U32 val2 = 1; - status = q2.peek(val2, i); - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(val1, val2); - } -} - -} // namespace - TEST(ExternalFifoQueue, CopyDataFrom) { constexpr FwSizeType maxSize = 10; constexpr FwSizeType smallSize = maxSize / 2; @@ -203,17 +179,17 @@ TEST(ExternalFifoQueue, CopyDataFrom) { // size1 < capacity2 { ExternalFifoQueue q2(items2, maxSize); - testCopyDataFrom(q1, smallSize, q2); + State::testCopyDataFrom(q1, smallSize, q2); } // size1 == size2 { ExternalFifoQueue q2(items2, maxSize); - testCopyDataFrom(q1, maxSize, q2); + State::testCopyDataFrom(q1, maxSize, q2); } // size1 > size2 { ExternalFifoQueue q2(items2, smallSize); - testCopyDataFrom(q1, maxSize, q2); + State::testCopyDataFrom(q1, maxSize, q2); } } diff --git a/Fw/DataStructures/test/ut/FifoQueueTest.cpp b/Fw/DataStructures/test/ut/FifoQueueTest.cpp index e2b3c8ad236..fcc6d8ca9a9 100644 --- a/Fw/DataStructures/test/ut/FifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/FifoQueueTest.cpp @@ -137,30 +137,6 @@ TEST(FifoQueue, DequeueEmpty) { ASSERT_EQ(status, Success::FAILURE); } -namespace { - -void testCopyDataFrom(FifoQueueBase& q1, FwSizeType size1, FifoQueueBase& q2) { - q1.clear(); - for (FwSizeType i = 0; i < size1; i++) { - const auto status = q1.enqueue(static_cast(i)); - ASSERT_EQ(status, Success::SUCCESS); - } - q2.copyDataFrom(q1); - const auto capacity2 = q2.getCapacity(); - const FwSizeType size = FW_MIN(size1, capacity2); - for (FwSizeType i = 0; i < size; i++) { - U32 val1 = 0; - auto status = q1.peek(val1, i); - ASSERT_EQ(status, Success::SUCCESS); - U32 val2 = 1; - status = q2.peek(val2, i); - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(val1, val2); - } -} - -} // namespace - TEST(FifoQueue, CopyDataFrom) { constexpr FwSizeType maxSize = 10; constexpr FwSizeType smallSize = maxSize / 2; @@ -168,17 +144,17 @@ TEST(FifoQueue, CopyDataFrom) { // size1 < capacity2 { FifoQueue q2; - testCopyDataFrom(q1, smallSize, q2); + State::testCopyDataFrom(q1, smallSize, q2); } // size1 == size2 { FifoQueue q2; - testCopyDataFrom(q1, maxSize, q2); + State::testCopyDataFrom(q1, maxSize, q2); } // size1 > size2 { FifoQueue q2; - testCopyDataFrom(q1, maxSize, q2); + State::testCopyDataFrom(q1, maxSize, q2); } } diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp index 837ef1ce5b5..89731a17d66 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp @@ -17,28 +17,47 @@ namespace Fw { namespace FifoQueueTest { struct State { - //! The queue item type - using ItemType = U32; - //! The queue capacity - static constexpr FwSizeType capacity = 1024; - //! The Queue type - using Queue = FifoQueue; - //! The ExternalQueue type - using ExternalQueue = ExternalFifoQueue; - //! THe QueueBase type - using QueueBase = FifoQueueBase; - //! Constructor - State(QueueBase& a_queue) : queue(a_queue) {} - //! The queue under test - QueueBase& queue; - //! The queue for modeling correct behavior - std::deque modelQueue; - //! Get a random item - static ItemType getRandomItem() { return STest::Pick::any(); } + //! The queue item type + using ItemType = U32; + //! The queue capacity + static constexpr FwSizeType capacity = 1024; + //! The Queue type + using Queue = FifoQueue; + //! The ExternalQueue type + using ExternalQueue = ExternalFifoQueue; + //! THe QueueBase type + using QueueBase = FifoQueueBase; + //! Constructor + State(QueueBase& a_queue) : queue(a_queue) {} + //! The queue under test + QueueBase& queue; + //! The queue for modeling correct behavior + std::deque modelQueue; + //! Get a random item + static ItemType getRandomItem() { return STest::Pick::any(); } + //! Test copy data from + static void testCopyDataFrom(QueueBase& q1, FwSizeType size1, QueueBase& q2) { + q1.clear(); + for (FwSizeType i = 0; i < size1; i++) { + const auto status = q1.enqueue(static_cast(i)); + ASSERT_EQ(status, Success::SUCCESS); + } + q2.copyDataFrom(q1); + const auto capacity2 = q2.getCapacity(); + const FwSizeType size = FW_MIN(size1, capacity2); + for (FwSizeType i = 0; i < size; i++) { + U32 val1 = 0; + auto status = q1.peek(val1, i); + ASSERT_EQ(status, Success::SUCCESS); + U32 val2 = 1; + status = q2.peek(val2, i); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(val1, val2); + } + } }; -} - -} +} // namespace FifoQueueTest +} // namespace Fw #endif From 844d4ce29900a62eed091abdc71c29527904c968 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sat, 5 Jul 2025 16:45:45 -0700 Subject: [PATCH 295/458] Revise unit tests for Fw/DataStructures --- .../test/ut/ExternalStackTest.cpp | 24 ++------- .../test/ut/STest/StackTestState.hpp | 54 ++++++++++++------- Fw/DataStructures/test/ut/StackTest.cpp | 24 ++------- 3 files changed, 40 insertions(+), 62 deletions(-) diff --git a/Fw/DataStructures/test/ut/ExternalStackTest.cpp b/Fw/DataStructures/test/ut/ExternalStackTest.cpp index 32211c8019d..ea7f4ad0559 100644 --- a/Fw/DataStructures/test/ut/ExternalStackTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalStackTest.cpp @@ -180,24 +180,6 @@ TEST(ExternalStack, PopEmpty) { ASSERT_EQ(status, Success::FAILURE); } -namespace { - -void testCopyDataFrom(StackBase& s1, FwSizeType size1, StackBase& s2) { - s1.clear(); - for (FwSizeType i = 0; i < size1; i++) { - const auto status = s1.push(static_cast(i)); - ASSERT_EQ(status, Success::SUCCESS); - } - s2.copyDataFrom(s1); - const auto capacity2 = s2.getCapacity(); - const FwSizeType size = FW_MIN(size1, capacity2); - for (FwSizeType i = 0; i < size; i++) { - ASSERT_EQ(s1.at(i), s2.at(i)); - } -} - -} // namespace - TEST(ExternalStack, CopyDataFrom) { constexpr FwSizeType maxSize = 10; constexpr FwSizeType smallSize = maxSize / 2; @@ -207,17 +189,17 @@ TEST(ExternalStack, CopyDataFrom) { // size1 < capacity2 { ExternalStack s2(items2, maxSize); - testCopyDataFrom(s1, smallSize, s2); + State::testCopyDataFrom(s1, smallSize, s2); } // size1 == size2 { ExternalStack s2(items2, maxSize); - testCopyDataFrom(s1, maxSize, s2); + State::testCopyDataFrom(s1, maxSize, s2); } // size1 > size2 { ExternalStack s2(items2, smallSize); - testCopyDataFrom(s1, maxSize, s2); + State::testCopyDataFrom(s1, maxSize, s2); } } diff --git a/Fw/DataStructures/test/ut/STest/StackTestState.hpp b/Fw/DataStructures/test/ut/STest/StackTestState.hpp index 9f3779e7fc5..9c8eb6c9a2a 100644 --- a/Fw/DataStructures/test/ut/STest/StackTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/StackTestState.hpp @@ -17,28 +17,42 @@ namespace Fw { namespace StackTest { struct State { - //! The stack item type - using ItemType = U32; - //! The stack capacity - static constexpr FwSizeType capacity = 1024; - //! The Stack type - using Stack = Stack; - //! The ExternalStack type - using ExternalStack = ExternalStack; - //! THe StackBase type - using StackBase = StackBase; - //! Constructor - State(StackBase& a_stack) : stack(a_stack) {} - //! The stack under test - StackBase& stack; - //! The stack for modeling correct behavior - std::vector modelStack; - //! Get a random item - static ItemType getRandomItem() { return STest::Pick::any(); } + //! The stack item type + using ItemType = U32; + //! The stack capacity + static constexpr FwSizeType capacity = 1024; + //! The Stack type + using Stack = Stack; + //! The ExternalStack type + using ExternalStack = ExternalStack; + //! THe StackBase type + using StackBase = StackBase; + //! Constructor + State(StackBase& a_stack) : stack(a_stack) {} + //! The stack under test + StackBase& stack; + //! The stack for modeling correct behavior + std::vector modelStack; + //! Get a random item + static ItemType getRandomItem() { return STest::Pick::any(); } + //! Test copy data from + static void testCopyDataFrom(StackBase& s1, FwSizeType size1, StackBase& s2) { + s1.clear(); + for (FwSizeType i = 0; i < size1; i++) { + const auto status = s1.push(static_cast(i)); + ASSERT_EQ(status, Success::SUCCESS); + } + s2.copyDataFrom(s1); + const auto capacity2 = s2.getCapacity(); + const FwSizeType size = FW_MIN(size1, capacity2); + for (FwSizeType i = 0; i < size; i++) { + ASSERT_EQ(s1.at(i), s2.at(i)); + } + } }; -} +} // namespace StackTest -} +} // namespace Fw #endif diff --git a/Fw/DataStructures/test/ut/StackTest.cpp b/Fw/DataStructures/test/ut/StackTest.cpp index cac08ec79e3..8eac3361a40 100644 --- a/Fw/DataStructures/test/ut/StackTest.cpp +++ b/Fw/DataStructures/test/ut/StackTest.cpp @@ -139,24 +139,6 @@ TEST(Stack, PopEmpty) { ASSERT_EQ(status, Success::FAILURE); } -namespace { - -void testCopyDataFrom(StackBase& s1, FwSizeType size1, StackBase& s2) { - s1.clear(); - for (FwSizeType i = 0; i < size1; i++) { - const auto status = s1.push(static_cast(i)); - ASSERT_EQ(status, Success::SUCCESS); - } - s2.copyDataFrom(s1); - const auto capacity2 = s2.getCapacity(); - const FwSizeType size = FW_MIN(size1, capacity2); - for (FwSizeType i = 0; i < size; i++) { - ASSERT_EQ(s1.at(i), s2.at(i)); - } -} - -} // namespace - TEST(Stack, CopyDataFrom) { constexpr FwSizeType maxSize = 10; constexpr FwSizeType smallSize = maxSize / 2; @@ -164,17 +146,17 @@ TEST(Stack, CopyDataFrom) { // size1 < capacity2 { Stack s2; - testCopyDataFrom(s1, smallSize, s2); + State::testCopyDataFrom(s1, smallSize, s2); } // size1 == size2 { Stack s2; - testCopyDataFrom(s1, maxSize, s2); + State::testCopyDataFrom(s1, maxSize, s2); } // size1 > size2 { Stack s2; - testCopyDataFrom(s1, maxSize, s2); + State::testCopyDataFrom(s1, maxSize, s2); } } From f0c035e80286faea49ea95c14a9527c57cc05249 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sat, 5 Jul 2025 16:51:09 -0700 Subject: [PATCH 296/458] Revise ExternalArrayMapTest --- Fw/DataStructures/CMakeLists.txt | 32 ++++++++--------- .../test/ut/ExternalArrayMapTest.cpp | 34 +++---------------- .../test/ut/STest/ArrayMapTestState.hpp | 18 ++++++++++ 3 files changed, 39 insertions(+), 45 deletions(-) diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index 194dd50d96e..040bd194aae 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -5,25 +5,25 @@ set(SOURCE_FILES register_fprime_module() set(UT_SOURCE_FILES - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArrayMapTestRules.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArrayMapTestScenarios.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" ) set(UT_MOD_DEPS diff --git a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp index 94b3e862efe..d23461d62b3 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp @@ -97,28 +97,6 @@ TEST(ExternalArrayMap, CopyAssignmentOperator) { ASSERT_EQ(map2.getSize(), 1); } -namespace { - -void testCopyDataFrom(State::MapBase& m1, FwSizeType size1, State::MapBase& m2) { - m1.clear(); - for (FwSizeType i = 0; i < size1; i++) { - const auto status = m1.insert(static_cast(i), static_cast(i)); - ASSERT_EQ(status, Success::SUCCESS); - } - m2.copyDataFrom(m1); - const auto capacity2 = m2.getCapacity(); - const FwSizeType size = FW_MIN(size1, capacity2); - for (FwSizeType i = 0; i < size; i++) { - State::KeyType key = static_cast(i); - U32 val = 0; - const auto status = m2.find(key, val); - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(val, static_cast(i)); - } -} - -} // namespace - TEST(ExternalFifoQueue, CopyDataFrom) { constexpr FwSizeType maxSize = 10; constexpr FwSizeType smallSize = maxSize / 2; @@ -128,20 +106,18 @@ TEST(ExternalFifoQueue, CopyDataFrom) { // size1 < capacity2 { Map m2(entries2, maxSize); - testCopyDataFrom(m1, smallSize, m2); + State::testCopyDataFrom(m1, smallSize, m2); } -#if 0 // size1 == size2 { - ExternalFifoQueue m2(items2, maxSize); - testCopyDataFrom(m1, maxSize, m2); + Map m2(entries2, maxSize); + State::testCopyDataFrom(m1, maxSize, m2); } // size1 > size2 { - ExternalFifoQueue m2(items2, smallSize); - testCopyDataFrom(m1, maxSize, m2); + Map m2(entries2, smallSize); + State::testCopyDataFrom(m1, maxSize, m2); } -#endif } #if 0 diff --git a/Fw/DataStructures/test/ut/STest/ArrayMapTestState.hpp b/Fw/DataStructures/test/ut/STest/ArrayMapTestState.hpp index 327128dd17a..b4d273f4259 100644 --- a/Fw/DataStructures/test/ut/STest/ArrayMapTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/ArrayMapTestState.hpp @@ -47,6 +47,24 @@ struct State { ValueType getValue() const { return useStoredValue ? storedValue : static_cast(STest::Pick::any()); } //! Check whether the model map contains the specified key bool modelMapContains(KeyType key) const { return modelMap.count(key) != 0; } + //! Test copy data from + static void testCopyDataFrom(MapBase& m1, FwSizeType size1, MapBase& m2) { + m1.clear(); + for (FwSizeType i = 0; i < size1; i++) { + const auto status = m1.insert(static_cast(i), static_cast(i)); + ASSERT_EQ(status, Success::SUCCESS); + } + m2.copyDataFrom(m1); + const auto capacity2 = m2.getCapacity(); + const FwSizeType size = FW_MIN(size1, capacity2); + for (FwSizeType i = 0; i < size; i++) { + State::KeyType key = static_cast(i); + U32 val = 0; + const auto status = m2.find(key, val); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(val, static_cast(i)); + } + } }; } // namespace ArrayMapTest From cb6213b133cb2875923c38e39e90e022f018dbc7 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sat, 5 Jul 2025 16:59:21 -0700 Subject: [PATCH 297/458] Revise ExternalArrayMapTest --- .../test/ut/ExternalArrayMapTest.cpp | 6 +- .../test/ut/STest/ArrayMapTestRules.cpp | 4 ++ .../test/ut/STest/ArrayMapTestRules.hpp | 66 +++++++++++-------- .../test/ut/STest/ArrayMapTestScenarios.cpp | 10 ++- 4 files changed, 50 insertions(+), 36 deletions(-) diff --git a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp index d23461d62b3..fd309c49c29 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp @@ -132,6 +132,7 @@ TEST(ExternalArrayMapRules, At) { Rules::insertNotFull.apply(state); Rules::at.apply(state); } +#endif TEST(ExternalArrayMapRules, Clear) { Entry entries[State::capacity]; @@ -143,6 +144,7 @@ TEST(ExternalArrayMapRules, Clear) { ASSERT_EQ(state.map.getSize(), 0); } +#if 0 TEST(ExternalArrayMapRules, FindExisting) { Entry entries[State::capacity]; Map map(entries, State::capacity); @@ -150,6 +152,7 @@ TEST(ExternalArrayMapRules, FindExisting) { Rules::insertNotFull.apply(state); Rules::findExisting.apply(state); } +#endif TEST(ExternalArrayMapRules, InsertFull) { Entry entries[State::capacity]; @@ -171,6 +174,7 @@ TEST(ExternalArrayMapRules, InsertNotFull) { Rules::insertNotFull.apply(state); } +#if 0 TEST(ExternalArrayMapRules, Remove) { Entry entries[State::capacity]; Map map(entries, State::capacity); @@ -188,6 +192,7 @@ TEST(ExternalArrayMapRules, RemoveExisting) { Rules::insertNotFull.apply(state); Rules::removeExisting.apply(state); } +#endif TEST(ExternalArrayMapScenarios, Random) { Entry entries[State::capacity]; @@ -195,7 +200,6 @@ TEST(ExternalArrayMapScenarios, Random) { State state(map); Scenarios::random(Fw::String("ExternalArrayMapRandom"), state, 1000); } -#endif } // namespace ArrayMapTest } // namespace Fw diff --git a/Fw/DataStructures/test/ut/STest/ArrayMapTestRules.cpp b/Fw/DataStructures/test/ut/STest/ArrayMapTestRules.cpp index bce3eac98bf..ce5d709d610 100644 --- a/Fw/DataStructures/test/ut/STest/ArrayMapTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/ArrayMapTestRules.cpp @@ -14,15 +14,19 @@ namespace Rules { #if 0 At at; +#endif Clear clear; +#if 0 FindExisting findExisting; +#endif InsertFull insertFull; InsertNotFull insertNotFull; +#if 0 Remove remove; RemoveExisting removeExisting; diff --git a/Fw/DataStructures/test/ut/STest/ArrayMapTestRules.hpp b/Fw/DataStructures/test/ut/STest/ArrayMapTestRules.hpp index 71619132aae..d94dec24ab0 100644 --- a/Fw/DataStructures/test/ut/STest/ArrayMapTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/ArrayMapTestRules.hpp @@ -24,12 +24,12 @@ namespace Rules { #if 0 struct At : public Rule { At() : Rule("At") {} - bool precondition(const State& state) { return state.impl.getSize() > 0; } + bool precondition(const State& state) { return state.map.getSize() > 0; } void action(State& state) { - const auto size = state.impl.getSize(); - const auto* it = state.impl.getHeadIterator(); + const auto size = state.map.getSize(); + const auto* it = state.map.getHeadIterator(); for (FwSizeType i = 0; i < size; i++) { - const auto& it1 = state.impl.at(i); + const auto& it1 = state.map.at(i); ASSERT_NE(it, nullptr); const auto& it2 = *it; ASSERT_EQ(it1.getKey(), it2.getKey()); @@ -38,114 +38,122 @@ struct At : public Rule { } } }; +#endif struct Clear : public Rule { Clear() : Rule("Clear") {} - bool precondition(const State& state) { return state.impl.getSize() > 0; } + bool precondition(const State& state) { return state.map.getSize() > 0; } void action(State& state) { - state.impl.clear(); - ASSERT_EQ(state.impl.getSize(), 0); + state.map.clear(); + ASSERT_EQ(state.map.getSize(), 0); state.modelMap.clear(); } }; +#if 0 struct FindExisting : public Rule { FindExisting() : Rule("FindExisting") {} - bool precondition(const State& state) { return static_cast(state.impl.getSize()) > 0; } + bool precondition(const State& state) { return static_cast(state.map.getSize()) > 0; } void action(State& state) { - const auto size = state.impl.getSize(); + const auto size = state.map.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); - const auto& it = state.impl.at(index); + const auto& it = state.map.at(index); const auto key = it.getKey(); const auto expectedValue = state.modelMap[key]; State::ValueType value = 0; - const auto status = state.impl.find(key, value); + const auto status = state.map.find(key, value); ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(value, expectedValue); } }; +#endif struct InsertFull : public Rule { InsertFull() : Rule("InsertFull") {} - bool precondition(const State& state) { return static_cast(state.impl.getSize()) >= State::capacity; } + bool precondition(const State& state) { return static_cast(state.map.getSize()) >= State::capacity; } void action(State& state) { const auto key = state.getKey(); const auto value = state.getValue(); - const auto size = state.impl.getSize(); + const auto size = state.map.getSize(); const auto expectedStatus = state.modelMapContains(key) ? Success::SUCCESS : Success::FAILURE; - const auto status = state.impl.insert(key, value); + const auto status = state.map.insert(key, value); ASSERT_EQ(status, expectedStatus); - ASSERT_EQ(state.impl.getSize(), size); + ASSERT_EQ(state.map.getSize(), size); } }; struct InsertNotFull : public Rule { InsertNotFull() : Rule("InsertNotFull") {} - bool precondition(const State& state) { return static_cast(state.impl.getSize()) < State::capacity; } + bool precondition(const State& state) { return static_cast(state.map.getSize()) < State::capacity; } void action(State& state) { const auto key = state.getKey(); const auto value = state.getValue(); - const auto size = state.impl.getSize(); + const auto size = state.map.getSize(); const auto expectedSize = state.modelMapContains(key) ? size : size + 1; - const auto status = state.impl.insert(key, value); + const auto status = state.map.insert(key, value); ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(state.impl.getSize(), expectedSize); + ASSERT_EQ(state.map.getSize(), expectedSize); state.modelMap[key] = value; } }; +#if 0 struct Remove : public Rule { Remove() : Rule("Remove") {} bool precondition(const State& state) { return true; } void action(State& state) { - const auto size = state.impl.getSize(); + const auto size = state.map.getSize(); ASSERT_EQ(size, state.modelMap.size()); const auto key = state.getKey(); State::ValueType value = 0; - const auto status = state.impl.remove(key, value); + const auto status = state.map.remove(key, value); if (state.modelMap.count(key) != 0) { ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(value, state.modelMap[key]); - ASSERT_EQ(state.impl.getSize(), size - 1); + ASSERT_EQ(state.map.getSize(), size - 1); } else { ASSERT_EQ(status, Success::FAILURE); - ASSERT_EQ(state.impl.getSize(), size); + ASSERT_EQ(state.map.getSize(), size); } (void) state.modelMap.erase(key); - ASSERT_EQ(state.impl.getSize(), state.modelMap.size()); + ASSERT_EQ(state.map.getSize(), state.modelMap.size()); } }; struct RemoveExisting : public Rule { RemoveExisting() : Rule("RemoveExisting") {} - bool precondition(const State& state) { return static_cast(state.impl.getSize()) > 0; } + bool precondition(const State& state) { return static_cast(state.map.getSize()) > 0; } void action(State& state) { - const auto size = state.impl.getSize(); + const auto size = state.map.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); - const auto& it = state.impl.at(index); + const auto& it = state.map.at(index); const auto key = it.getKey(); const auto expectedValue = state.modelMap[key]; State::ValueType value = 0; - const auto status = state.impl.remove(key, value); + const auto status = state.map.remove(key, value); ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(value, expectedValue); const auto n = state.modelMap.erase(key); ASSERT_EQ(n, 1); - ASSERT_EQ(state.impl.getSize(), state.modelMap.size()); + ASSERT_EQ(state.map.getSize(), state.modelMap.size()); } }; extern At at; +#endif extern Clear clear; +#if 0 extern FindExisting findExisting; +#endif extern InsertFull insertFull; extern InsertNotFull insertNotFull; +#if 0 extern Remove remove; extern RemoveExisting removeExisting; diff --git a/Fw/DataStructures/test/ut/STest/ArrayMapTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/ArrayMapTestScenarios.cpp index efb78844897..93eac37a745 100644 --- a/Fw/DataStructures/test/ut/STest/ArrayMapTestScenarios.cpp +++ b/Fw/DataStructures/test/ut/STest/ArrayMapTestScenarios.cpp @@ -19,21 +19,19 @@ void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { (void)name; (void)state; (void)maxNumSteps; -#if 0 Rule* rules[] = { - &Rules::at, + //&Rules::at, &Rules::clear, &Rules::insertFull, - &Rules::insertNotFull, - &Rules::remove, - &Rules::removeExisting + &Rules::insertNotFull + //&Rules::remove, + //&Rules::removeExisting }; STest::RandomScenario scenario("RandomScenario", rules, sizeof(rules) / sizeof(STest::RandomScenario*)); STest::BoundedScenario boundedScenario(name.toChar(), scenario, maxNumSteps); const U32 numSteps = boundedScenario.run(state); printf("Ran %u steps.\n", numSteps); -#endif } } // namespace Scenarios From ff950b7ff1b0d22e59d109284dae72510ca9b977 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sat, 5 Jul 2025 17:14:01 -0700 Subject: [PATCH 298/458] Revise unit tests for ArraySetOrMapImpl --- Fw/DataStructures/CMakeLists.txt | 12 ++++++------ Fw/DataStructures/run_ut | 2 +- .../test/ut/ArraySetOrMapImplTest.cpp | 10 ++++++++++ .../ut/STest/ArraySetOrMapImplTestRules.cpp | 2 ++ .../ut/STest/ArraySetOrMapImplTestRules.hpp | 18 ++++++++++++++++++ .../STest/ArraySetOrMapImplTestScenarios.cpp | 2 ++ 6 files changed, 39 insertions(+), 7 deletions(-) diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index 040bd194aae..c31288e1eaa 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -5,20 +5,20 @@ set(SOURCE_FILES register_fprime_module() set(UT_SOURCE_FILES -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArrayMapTestRules.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArrayMapTestScenarios.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArrayMapTestRules.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArrayMapTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" diff --git a/Fw/DataStructures/run_ut b/Fw/DataStructures/run_ut index 36043aa613f..a108913eeee 100755 --- a/Fw/DataStructures/run_ut +++ b/Fw/DataStructures/run_ut @@ -1,5 +1,5 @@ #!/bin/sh -e cd `dirname $0` -./build_ut +./build_ut "$@" ./Fw_DataStructures_ut_exe diff --git a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp index 3012a00fe36..8042d1b4715 100644 --- a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp +++ b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp @@ -100,6 +100,16 @@ TEST(ArraySetOrMapImplRules, Clear) { ASSERT_EQ(state.impl.getSize(), 0); } +TEST(ArraySetOrMapImplRules, Find) { + State::Entry entries[State::capacity]; + State::Impl impl(entries, State::capacity); + State state(impl); + Rules::find.apply(state); + state.useStoredKey = true; + Rules::insertNotFull.apply(state); + Rules::find.apply(state); +} + TEST(ArraySetOrMapImplRules, FindExisting) { State::Entry entries[State::capacity]; State::Impl impl(entries, State::capacity); diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp index 8aca985e061..1a6e680f063 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp @@ -16,6 +16,8 @@ At at; Clear clear; +Find find; + FindExisting findExisting; InsertFull insertFull; diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp index 7053f7424fb..5ef2d5bce9b 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp @@ -48,6 +48,22 @@ struct Clear : public Rule { } }; +struct Find : public Rule { + Find() : Rule("Find") {} + bool precondition(const State& state) { return true; } + void action(State& state) { + const auto key = state.getKey(); + State::ValueType value = 0; + const auto status = state.impl.find(key, value); + if (state.modelMapContains(key)) { + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(value, state.modelMap[key]); + } else { + ASSERT_EQ(status, Success::FAILURE); + } + } +}; + struct FindExisting : public Rule { FindExisting() : Rule("FindExisting") {} bool precondition(const State& state) { return static_cast(state.impl.getSize()) > 0; } @@ -139,6 +155,8 @@ extern At at; extern Clear clear; +extern Find find; + extern FindExisting findExisting; extern InsertFull insertFull; diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp index 2e62ba04e81..7837f40ef83 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp @@ -19,6 +19,8 @@ void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { Rule* rules[] = { &Rules::at, &Rules::clear, + &Rules::find, + &Rules::findExisting, &Rules::insertFull, &Rules::insertNotFull, &Rules::remove, From f78334bde4a915ce79003f3047eb6b73b6842928 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sat, 5 Jul 2025 17:24:47 -0700 Subject: [PATCH 299/458] Revise ExternalArrayMapTest --- Fw/DataStructures/CMakeLists.txt | 12 ++++++------ Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp | 12 +++++++++++- .../test/ut/STest/ArrayMapTestRules.cpp | 2 -- .../test/ut/STest/ArrayMapTestRules.hpp | 13 +++++++------ 4 files changed, 24 insertions(+), 15 deletions(-) diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index c31288e1eaa..040bd194aae 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -5,20 +5,20 @@ set(SOURCE_FILES register_fprime_module() set(UT_SOURCE_FILES - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArrayMapTestRules.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArrayMapTestScenarios.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArrayMapTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArrayMapTestScenarios.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" diff --git a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp index fd309c49c29..55be00128dc 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp @@ -145,6 +145,17 @@ TEST(ExternalArrayMapRules, Clear) { } #if 0 +TEST(ExternalArraymapRules, Find) { + Entry entries[State::capacity]; + Map map(entries, State::capacity); + State state(map); + Rules::find.apply(state); + state.useStoredKey = true; + Rules::insertNotFull.apply(state); + Rules::find.apply(state); +} +#endif + TEST(ExternalArrayMapRules, FindExisting) { Entry entries[State::capacity]; Map map(entries, State::capacity); @@ -152,7 +163,6 @@ TEST(ExternalArrayMapRules, FindExisting) { Rules::insertNotFull.apply(state); Rules::findExisting.apply(state); } -#endif TEST(ExternalArrayMapRules, InsertFull) { Entry entries[State::capacity]; diff --git a/Fw/DataStructures/test/ut/STest/ArrayMapTestRules.cpp b/Fw/DataStructures/test/ut/STest/ArrayMapTestRules.cpp index ce5d709d610..4bbc94043a6 100644 --- a/Fw/DataStructures/test/ut/STest/ArrayMapTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/ArrayMapTestRules.cpp @@ -18,9 +18,7 @@ At at; Clear clear; -#if 0 FindExisting findExisting; -#endif InsertFull insertFull; diff --git a/Fw/DataStructures/test/ut/STest/ArrayMapTestRules.hpp b/Fw/DataStructures/test/ut/STest/ArrayMapTestRules.hpp index d94dec24ab0..31a39377c7a 100644 --- a/Fw/DataStructures/test/ut/STest/ArrayMapTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/ArrayMapTestRules.hpp @@ -50,15 +50,19 @@ struct Clear : public Rule { } }; -#if 0 struct FindExisting : public Rule { FindExisting() : Rule("FindExisting") {} bool precondition(const State& state) { return static_cast(state.map.getSize()) > 0; } void action(State& state) { const auto size = state.map.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); - const auto& it = state.map.at(index); - const auto key = it.getKey(); + const auto* it = state.map.getHeadIterator(); + for (FwSizeType i = 0; i < index; i++) { + ASSERT_NE(it, nullptr); + it = it->getNextMapIterator(); + } + ASSERT_NE(it, nullptr); + const auto key = it->getKey(); const auto expectedValue = state.modelMap[key]; State::ValueType value = 0; const auto status = state.map.find(key, value); @@ -66,7 +70,6 @@ struct FindExisting : public Rule { ASSERT_EQ(value, expectedValue); } }; -#endif struct InsertFull : public Rule { InsertFull() : Rule("InsertFull") {} @@ -145,9 +148,7 @@ extern At at; extern Clear clear; -#if 0 extern FindExisting findExisting; -#endif extern InsertFull insertFull; From 07b683b5bc9662e1506b01daf4432f3f4ffa0eeb Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sat, 5 Jul 2025 17:29:28 -0700 Subject: [PATCH 300/458] Revise ExternalArrayMapTest and MapTest --- Fw/DataStructures/CMakeLists.txt | 36 +++++++++---------- .../test/ut/ExternalArrayMapTest.cpp | 6 ++-- ...ArrayMapTestRules.cpp => MapTestRules.cpp} | 8 ++--- ...ArrayMapTestRules.hpp => MapTestRules.hpp} | 14 ++++---- ...TestScenarios.cpp => MapTestScenarios.cpp} | 12 +++---- ...TestScenarios.hpp => MapTestScenarios.hpp} | 10 +++--- ...ArrayMapTestState.hpp => MapTestState.hpp} | 12 +++---- 7 files changed, 49 insertions(+), 49 deletions(-) rename Fw/DataStructures/test/ut/STest/{ArrayMapTestRules.cpp => MapTestRules.cpp} (75%) rename Fw/DataStructures/test/ut/STest/{ArrayMapTestRules.hpp => MapTestRules.hpp} (95%) rename Fw/DataStructures/test/ut/STest/{ArrayMapTestScenarios.cpp => MapTestScenarios.cpp} (79%) rename Fw/DataStructures/test/ut/STest/{ArrayMapTestScenarios.hpp => MapTestScenarios.hpp} (63%) rename Fw/DataStructures/test/ut/STest/{ArrayMapTestState.hpp => MapTestState.hpp} (92%) diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index 040bd194aae..84b947b5837 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -5,25 +5,25 @@ set(SOURCE_FILES register_fprime_module() set(UT_SOURCE_FILES -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArrayMapTestRules.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArrayMapTestScenarios.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" ) set(UT_MOD_DEPS diff --git a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp index 55be00128dc..fc5a3a15a67 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp @@ -9,8 +9,8 @@ #include "Fw/DataStructures/ExternalArrayMap.hpp" #include "Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp" -#include "Fw/DataStructures/test/ut/STest/ArrayMapTestRules.hpp" -#include "Fw/DataStructures/test/ut/STest/ArrayMapTestScenarios.hpp" +#include "Fw/DataStructures/test/ut/STest/MapTestRules.hpp" +#include "Fw/DataStructures/test/ut/STest/MapTestScenarios.hpp" namespace Fw { @@ -25,7 +25,7 @@ class ExternalArrayMapTester { const ExternalArrayMap& m_map; }; -namespace ArrayMapTest { +namespace MapTest { using Entry = SetOrMapIterator; using Map = ExternalArrayMap; diff --git a/Fw/DataStructures/test/ut/STest/ArrayMapTestRules.cpp b/Fw/DataStructures/test/ut/STest/MapTestRules.cpp similarity index 75% rename from Fw/DataStructures/test/ut/STest/ArrayMapTestRules.cpp rename to Fw/DataStructures/test/ut/STest/MapTestRules.cpp index 4bbc94043a6..faa75297807 100644 --- a/Fw/DataStructures/test/ut/STest/ArrayMapTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/MapTestRules.cpp @@ -1,14 +1,14 @@ // ====================================================================== -// \title ArrayMapTestRules.cpp +// \title MapTestRules.cpp // \author Rob Bocchino // \brief cpp file for ArrayMap test rules // ====================================================================== -#include "Fw/DataStructures/test/ut/STest/ArrayMapTestRules.hpp" +#include "Fw/DataStructures/test/ut/STest/MapTestRules.hpp" namespace Fw { -namespace ArrayMapTest { +namespace MapTest { namespace Rules { @@ -32,6 +32,6 @@ RemoveExisting removeExisting; }; // namespace Rules -} // namespace ArrayMapTest +} // namespace MapTest } // namespace Fw diff --git a/Fw/DataStructures/test/ut/STest/ArrayMapTestRules.hpp b/Fw/DataStructures/test/ut/STest/MapTestRules.hpp similarity index 95% rename from Fw/DataStructures/test/ut/STest/ArrayMapTestRules.hpp rename to Fw/DataStructures/test/ut/STest/MapTestRules.hpp index 31a39377c7a..e222ffe6da9 100644 --- a/Fw/DataStructures/test/ut/STest/ArrayMapTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/MapTestRules.hpp @@ -1,21 +1,21 @@ // ====================================================================== -// \title ArrayMapTestRules.hpp +// \title MapTestRules.hpp // \author bocchino -// \brief hpp file for ArrayMap test rules +// \brief hpp file for map test rules // ====================================================================== -#ifndef ArrayMapTestRules_HPP -#define ArrayMapTestRules_HPP +#ifndef MapTestRules_HPP +#define MapTestRules_HPP #include -#include "Fw/DataStructures/test/ut/STest/ArrayMapTestState.hpp" +#include "Fw/DataStructures/test/ut/STest/MapTestState.hpp" #include "STest/STest/Pick/Pick.hpp" #include "STest/STest/Rule/Rule.hpp" namespace Fw { -namespace ArrayMapTest { +namespace MapTest { using Rule = STest::Rule; @@ -162,7 +162,7 @@ extern RemoveExisting removeExisting; }; // namespace Rules -} // namespace ArrayMapTest +} // namespace MapTest } // namespace Fw diff --git a/Fw/DataStructures/test/ut/STest/ArrayMapTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/MapTestScenarios.cpp similarity index 79% rename from Fw/DataStructures/test/ut/STest/ArrayMapTestScenarios.cpp rename to Fw/DataStructures/test/ut/STest/MapTestScenarios.cpp index 93eac37a745..636d072a380 100644 --- a/Fw/DataStructures/test/ut/STest/ArrayMapTestScenarios.cpp +++ b/Fw/DataStructures/test/ut/STest/MapTestScenarios.cpp @@ -1,17 +1,17 @@ // ====================================================================== -// \title ArrayMapTestScenarios.cpp +// \title MapTestScenarios.cpp // \author Rob Bocchino -// \brief ArrayMap test scenarios +// \brief Map test scenarios // ====================================================================== -#include "Fw/DataStructures/test/ut/STest/ArrayMapTestRules.hpp" -#include "Fw/DataStructures/test/ut/STest/ArrayMapTestScenarios.hpp" +#include "Fw/DataStructures/test/ut/STest/MapTestRules.hpp" +#include "Fw/DataStructures/test/ut/STest/MapTestScenarios.hpp" #include "STest/Scenario/BoundedScenario.hpp" #include "STest/Scenario/RandomScenario.hpp" namespace Fw { -namespace ArrayMapTest { +namespace MapTest { namespace Scenarios { @@ -36,6 +36,6 @@ void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { } // namespace Scenarios -} // namespace ArrayMapTest +} // namespace MapTest } // namespace Fw diff --git a/Fw/DataStructures/test/ut/STest/ArrayMapTestScenarios.hpp b/Fw/DataStructures/test/ut/STest/MapTestScenarios.hpp similarity index 63% rename from Fw/DataStructures/test/ut/STest/ArrayMapTestScenarios.hpp rename to Fw/DataStructures/test/ut/STest/MapTestScenarios.hpp index 69d5f95b68d..1388e055a46 100644 --- a/Fw/DataStructures/test/ut/STest/ArrayMapTestScenarios.hpp +++ b/Fw/DataStructures/test/ut/STest/MapTestScenarios.hpp @@ -1,14 +1,14 @@ // ====================================================================== -// \title ArrayMapTestScenarios.hpp +// \title MapTestScenarios.hpp // \author Rob Bocchino -// \brief ArrayMap test scenarios +// \brief Map test scenarios // ====================================================================== -#include "Fw/DataStructures/test/ut/STest/ArrayMapTestState.hpp" +#include "Fw/DataStructures/test/ut/STest/MapTestState.hpp" namespace Fw { -namespace ArrayMapTest { +namespace MapTest { namespace Scenarios { @@ -16,6 +16,6 @@ void random(const Fw::StringBase& name, State& state, U32 maxNumSteps); } // namespace Scenarios -} // namespace ArrayMapTest +} // namespace MapTest } // namespace Fw diff --git a/Fw/DataStructures/test/ut/STest/ArrayMapTestState.hpp b/Fw/DataStructures/test/ut/STest/MapTestState.hpp similarity index 92% rename from Fw/DataStructures/test/ut/STest/ArrayMapTestState.hpp rename to Fw/DataStructures/test/ut/STest/MapTestState.hpp index b4d273f4259..91b12283b17 100644 --- a/Fw/DataStructures/test/ut/STest/ArrayMapTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/MapTestState.hpp @@ -1,11 +1,11 @@ // ====================================================================== -// \title ArrayMapTestState.hpp +// \title MapTestState.hpp // \author bocchino -// \brief hpp file for FIFO map test state +// \brief hpp file for map test state // ====================================================================== -#ifndef ArrayMapTestState_HPP -#define ArrayMapTestState_HPP +#ifndef MapTestState_HPP +#define MapTestState_HPP #include @@ -14,7 +14,7 @@ namespace Fw { -namespace ArrayMapTest { +namespace MapTest { struct State { //! The key type @@ -67,7 +67,7 @@ struct State { } }; -} // namespace ArrayMapTest +} // namespace MapTest } // namespace Fw From e20fa0662d57269c5d7365b2ccf71fa50d180a20 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sat, 5 Jul 2025 17:31:09 -0700 Subject: [PATCH 301/458] Revise MapTestScenarios --- Fw/DataStructures/CMakeLists.txt | 32 +++++++++---------- .../test/ut/STest/MapTestScenarios.cpp | 4 +-- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index 84b947b5837..561dedee831 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -5,25 +5,25 @@ set(SOURCE_FILES register_fprime_module() set(UT_SOURCE_FILES - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestRules.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestScenarios.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" ) set(UT_MOD_DEPS diff --git a/Fw/DataStructures/test/ut/STest/MapTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/MapTestScenarios.cpp index 636d072a380..aeb636b703b 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestScenarios.cpp +++ b/Fw/DataStructures/test/ut/STest/MapTestScenarios.cpp @@ -16,12 +16,10 @@ namespace MapTest { namespace Scenarios { void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { - (void)name; - (void)state; - (void)maxNumSteps; Rule* rules[] = { //&Rules::at, &Rules::clear, + &Rules::findExisting, &Rules::insertFull, &Rules::insertNotFull //&Rules::remove, From 3e49c42a42d1eea417a22d8853ecc6dfb83618f5 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sat, 5 Jul 2025 17:34:21 -0700 Subject: [PATCH 302/458] Revise ExternalArrayMapTest --- .../test/ut/ExternalArrayMapTest.cpp | 2 -- .../test/ut/STest/MapTestRules.cpp | 2 ++ .../test/ut/STest/MapTestRules.hpp | 18 ++++++++++++++++++ .../test/ut/STest/MapTestScenarios.cpp | 1 + 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp index fc5a3a15a67..ddc1d10970d 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp @@ -144,7 +144,6 @@ TEST(ExternalArrayMapRules, Clear) { ASSERT_EQ(state.map.getSize(), 0); } -#if 0 TEST(ExternalArraymapRules, Find) { Entry entries[State::capacity]; Map map(entries, State::capacity); @@ -154,7 +153,6 @@ TEST(ExternalArraymapRules, Find) { Rules::insertNotFull.apply(state); Rules::find.apply(state); } -#endif TEST(ExternalArrayMapRules, FindExisting) { Entry entries[State::capacity]; diff --git a/Fw/DataStructures/test/ut/STest/MapTestRules.cpp b/Fw/DataStructures/test/ut/STest/MapTestRules.cpp index faa75297807..c64cd308fd9 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/MapTestRules.cpp @@ -18,6 +18,8 @@ At at; Clear clear; +Find find; + FindExisting findExisting; InsertFull insertFull; diff --git a/Fw/DataStructures/test/ut/STest/MapTestRules.hpp b/Fw/DataStructures/test/ut/STest/MapTestRules.hpp index e222ffe6da9..dc2fdc0cdf0 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/MapTestRules.hpp @@ -50,6 +50,22 @@ struct Clear : public Rule { } }; +struct Find : public Rule { + Find() : Rule("Find") {} + bool precondition(const State& state) { return true; } + void action(State& state) { + const auto key = state.getKey(); + State::ValueType value = 0; + const auto status = state.map.find(key, value); + if (state.modelMapContains(key)) { + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(value, state.modelMap[key]); + } else { + ASSERT_EQ(status, Success::FAILURE); + } + } +}; + struct FindExisting : public Rule { FindExisting() : Rule("FindExisting") {} bool precondition(const State& state) { return static_cast(state.map.getSize()) > 0; } @@ -148,6 +164,8 @@ extern At at; extern Clear clear; +extern Find find; + extern FindExisting findExisting; extern InsertFull insertFull; diff --git a/Fw/DataStructures/test/ut/STest/MapTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/MapTestScenarios.cpp index aeb636b703b..f46c27f6fd4 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestScenarios.cpp +++ b/Fw/DataStructures/test/ut/STest/MapTestScenarios.cpp @@ -19,6 +19,7 @@ void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { Rule* rules[] = { //&Rules::at, &Rules::clear, + &Rules::find, &Rules::findExisting, &Rules::insertFull, &Rules::insertNotFull From e4d161e7ffdb2fd9ceb15780109ac05abfdcf1b8 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sat, 5 Jul 2025 17:42:53 -0700 Subject: [PATCH 303/458] Revise ExternalArrayMapTest --- .../test/ut/ExternalArrayMapTest.cpp | 2 +- .../test/ut/STest/MapTestRules.cpp | 6 +---- .../test/ut/STest/MapTestRules.hpp | 27 +++---------------- .../test/ut/STest/MapTestScenarios.cpp | 5 ++-- 4 files changed, 7 insertions(+), 33 deletions(-) diff --git a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp index ddc1d10970d..c1b861e00dc 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp @@ -182,7 +182,6 @@ TEST(ExternalArrayMapRules, InsertNotFull) { Rules::insertNotFull.apply(state); } -#if 0 TEST(ExternalArrayMapRules, Remove) { Entry entries[State::capacity]; Map map(entries, State::capacity); @@ -193,6 +192,7 @@ TEST(ExternalArrayMapRules, Remove) { Rules::remove.apply(state); } +#if 0 TEST(ExternalArrayMapRules, RemoveExisting) { Entry entries[State::capacity]; Map map(entries, State::capacity); diff --git a/Fw/DataStructures/test/ut/STest/MapTestRules.cpp b/Fw/DataStructures/test/ut/STest/MapTestRules.cpp index c64cd308fd9..768061c7d1c 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/MapTestRules.cpp @@ -12,10 +12,6 @@ namespace MapTest { namespace Rules { -#if 0 -At at; -#endif - Clear clear; Find find; @@ -26,9 +22,9 @@ InsertFull insertFull; InsertNotFull insertNotFull; -#if 0 Remove remove; +#if 0 RemoveExisting removeExisting; #endif diff --git a/Fw/DataStructures/test/ut/STest/MapTestRules.hpp b/Fw/DataStructures/test/ut/STest/MapTestRules.hpp index dc2fdc0cdf0..b97f281d569 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/MapTestRules.hpp @@ -21,25 +21,6 @@ using Rule = STest::Rule; namespace Rules { -#if 0 -struct At : public Rule { - At() : Rule("At") {} - bool precondition(const State& state) { return state.map.getSize() > 0; } - void action(State& state) { - const auto size = state.map.getSize(); - const auto* it = state.map.getHeadIterator(); - for (FwSizeType i = 0; i < size; i++) { - const auto& it1 = state.map.at(i); - ASSERT_NE(it, nullptr); - const auto& it2 = *it; - ASSERT_EQ(it1.getKey(), it2.getKey()); - ASSERT_EQ(it1.getValue(), it2.getValue()); - it = it->getNextIterator(); - } - } -}; -#endif - struct Clear : public Rule { Clear() : Rule("Clear") {} bool precondition(const State& state) { return state.map.getSize() > 0; } @@ -116,7 +97,6 @@ struct InsertNotFull : public Rule { } }; -#if 0 struct Remove : public Rule { Remove() : Rule("Remove") {} bool precondition(const State& state) { return true; } @@ -126,7 +106,7 @@ struct Remove : public Rule { const auto key = state.getKey(); State::ValueType value = 0; const auto status = state.map.remove(key, value); - if (state.modelMap.count(key) != 0) { + if (state.modelMapContains(key)) { ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(value, state.modelMap[key]); ASSERT_EQ(state.map.getSize(), size - 1); @@ -140,6 +120,7 @@ struct Remove : public Rule { } }; +#if 0 struct RemoveExisting : public Rule { RemoveExisting() : Rule("RemoveExisting") {} bool precondition(const State& state) { return static_cast(state.map.getSize()) > 0; } @@ -158,8 +139,6 @@ struct RemoveExisting : public Rule { ASSERT_EQ(state.map.getSize(), state.modelMap.size()); } }; - -extern At at; #endif extern Clear clear; @@ -172,9 +151,9 @@ extern InsertFull insertFull; extern InsertNotFull insertNotFull; -#if 0 extern Remove remove; +#if 0 extern RemoveExisting removeExisting; #endif diff --git a/Fw/DataStructures/test/ut/STest/MapTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/MapTestScenarios.cpp index f46c27f6fd4..a2dd88b63e1 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestScenarios.cpp +++ b/Fw/DataStructures/test/ut/STest/MapTestScenarios.cpp @@ -17,13 +17,12 @@ namespace Scenarios { void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { Rule* rules[] = { - //&Rules::at, &Rules::clear, &Rules::find, &Rules::findExisting, &Rules::insertFull, - &Rules::insertNotFull - //&Rules::remove, + &Rules::insertNotFull, + &Rules::remove //&Rules::removeExisting }; STest::RandomScenario scenario("RandomScenario", rules, From 82c091a223b23198a8b702a6936fd75e0ee95db6 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sat, 5 Jul 2025 17:45:37 -0700 Subject: [PATCH 304/458] Revise ExternalArrayMapTest --- Fw/DataStructures/CMakeLists.txt | 32 +++++++++---------- .../test/ut/ExternalArrayMapTest.cpp | 2 -- .../test/ut/STest/MapTestRules.cpp | 2 -- .../test/ut/STest/MapTestRules.hpp | 13 ++++---- .../test/ut/STest/MapTestScenarios.cpp | 4 +-- 5 files changed, 25 insertions(+), 28 deletions(-) diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index 561dedee831..84b947b5837 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -5,25 +5,25 @@ set(SOURCE_FILES register_fprime_module() set(UT_SOURCE_FILES -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestRules.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestScenarios.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" ) set(UT_MOD_DEPS diff --git a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp index c1b861e00dc..5dc883ee3f1 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp @@ -192,7 +192,6 @@ TEST(ExternalArrayMapRules, Remove) { Rules::remove.apply(state); } -#if 0 TEST(ExternalArrayMapRules, RemoveExisting) { Entry entries[State::capacity]; Map map(entries, State::capacity); @@ -200,7 +199,6 @@ TEST(ExternalArrayMapRules, RemoveExisting) { Rules::insertNotFull.apply(state); Rules::removeExisting.apply(state); } -#endif TEST(ExternalArrayMapScenarios, Random) { Entry entries[State::capacity]; diff --git a/Fw/DataStructures/test/ut/STest/MapTestRules.cpp b/Fw/DataStructures/test/ut/STest/MapTestRules.cpp index 768061c7d1c..b9356a86b2c 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/MapTestRules.cpp @@ -24,9 +24,7 @@ InsertNotFull insertNotFull; Remove remove; -#if 0 RemoveExisting removeExisting; -#endif }; // namespace Rules diff --git a/Fw/DataStructures/test/ut/STest/MapTestRules.hpp b/Fw/DataStructures/test/ut/STest/MapTestRules.hpp index b97f281d569..f509db43d6c 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/MapTestRules.hpp @@ -120,15 +120,19 @@ struct Remove : public Rule { } }; -#if 0 struct RemoveExisting : public Rule { RemoveExisting() : Rule("RemoveExisting") {} bool precondition(const State& state) { return static_cast(state.map.getSize()) > 0; } void action(State& state) { const auto size = state.map.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); - const auto& it = state.map.at(index); - const auto key = it.getKey(); + const auto* it = state.map.getHeadIterator(); + for (FwSizeType i = 0; i < index; i++) { + ASSERT_NE(it, nullptr); + it = it->getNextMapIterator(); + } + ASSERT_NE(it, nullptr); + const auto key = it->getKey(); const auto expectedValue = state.modelMap[key]; State::ValueType value = 0; const auto status = state.map.remove(key, value); @@ -139,7 +143,6 @@ struct RemoveExisting : public Rule { ASSERT_EQ(state.map.getSize(), state.modelMap.size()); } }; -#endif extern Clear clear; @@ -153,9 +156,7 @@ extern InsertNotFull insertNotFull; extern Remove remove; -#if 0 extern RemoveExisting removeExisting; -#endif }; // namespace Rules diff --git a/Fw/DataStructures/test/ut/STest/MapTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/MapTestScenarios.cpp index a2dd88b63e1..ef0cc406f87 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestScenarios.cpp +++ b/Fw/DataStructures/test/ut/STest/MapTestScenarios.cpp @@ -22,8 +22,8 @@ void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { &Rules::findExisting, &Rules::insertFull, &Rules::insertNotFull, - &Rules::remove - //&Rules::removeExisting + &Rules::remove, + &Rules::removeExisting }; STest::RandomScenario scenario("RandomScenario", rules, sizeof(rules) / sizeof(STest::RandomScenario*)); From 74cc0ec875d6a335b29e5320857e472364a7d9d7 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sat, 5 Jul 2025 17:52:40 -0700 Subject: [PATCH 305/458] 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. --- Fw/DataStructures/ArraySetOrMapImpl.hpp | 10 ----- Fw/DataStructures/ExternalArrayMap.hpp | 8 ---- Fw/DataStructures/ExternalArraySet.hpp | 10 +---- Fw/DataStructures/docs/ArraySetOrMapImpl.md | 28 ++++--------- Fw/DataStructures/docs/ExternalArrayMap.md | 37 ++++------------ Fw/DataStructures/docs/ExternalArraySet.md | 37 ++++------------ .../test/ut/ArraySetOrMapImplTest.cpp | 12 ------ .../ut/STest/ArraySetOrMapImplTestRules.cpp | 2 - .../ut/STest/ArraySetOrMapImplTestRules.hpp | 42 +++++++------------ .../STest/ArraySetOrMapImplTestScenarios.cpp | 1 - 10 files changed, 44 insertions(+), 143 deletions(-) diff --git a/Fw/DataStructures/ArraySetOrMapImpl.hpp b/Fw/DataStructures/ArraySetOrMapImpl.hpp index f9de4fa0c4e..0a5eedfe6e9 100644 --- a/Fw/DataStructures/ArraySetOrMapImpl.hpp +++ b/Fw/DataStructures/ArraySetOrMapImpl.hpp @@ -79,16 +79,6 @@ class ArraySetOrMapImpl { return *this; } - //! Get an iterator at an index in the array. - //! Fails an assertion if the index is out of range for the set or map. - //! \return The iterator - const Iterator& at(FwSizeType index //!< The index - ) const { - FW_ASSERT(index < this->m_size, static_cast(index), - static_cast(this->m_size)); - return this->m_entries[index]; - } - //! Clear the set or map void clear() { this->m_size = 0; } diff --git a/Fw/DataStructures/ExternalArrayMap.hpp b/Fw/DataStructures/ExternalArrayMap.hpp index 385dfc977ae..9c1bcd0d59e 100644 --- a/Fw/DataStructures/ExternalArrayMap.hpp +++ b/Fw/DataStructures/ExternalArrayMap.hpp @@ -79,14 +79,6 @@ class ExternalArrayMap final : public MapBase { return *this; } - //! Get an iterator at an index in the array. - //! Fails an assertion if the index is out of range for the map. - //! \return The iterator - const Iterator& at(FwSizeType index //!< The index - ) const { - return this->m_impl.at[index]; - } - //! Clear the map void clear() override { this->m_impl.clear(); } diff --git a/Fw/DataStructures/ExternalArraySet.hpp b/Fw/DataStructures/ExternalArraySet.hpp index e61cdf7390a..ea123707e0b 100644 --- a/Fw/DataStructures/ExternalArraySet.hpp +++ b/Fw/DataStructures/ExternalArraySet.hpp @@ -80,15 +80,7 @@ class ExternalArraySet final : public SetBase { return *this; } - //! Get an iterator at an index in the array. - //! Fails an assertion if the index is out of range for the set or set. - //! \return The iterator - const Iterator& at(FwSizeType index //!< The index - ) const { - return this->m_impl.at[index]; - } - - //! Clear the set or set + //! Clear the set void clear() override { this->m_impl.clear(); } //! Find a value associated with an element in the set diff --git a/Fw/DataStructures/docs/ArraySetOrMapImpl.md b/Fw/DataStructures/docs/ArraySetOrMapImpl.md index 251023ed910..667749abaa8 100644 --- a/Fw/DataStructures/docs/ArraySetOrMapImpl.md +++ b/Fw/DataStructures/docs/ArraySetOrMapImpl.md @@ -102,17 +102,7 @@ ArraySetOrMapImpl& operator=(const ArraySetOrMapImpl& impl) 1. Return `*this`. -### 5.2. at - -```c++ -const Iterator& at(FwSizeType index) const -``` - -1. Assert `index < m_size`. - -1. Return `m_entries[index]`. - -### 5.3. clear +### 5.2. clear ```c++ void clear() @@ -120,7 +110,7 @@ void clear() Set `m_size = 0`. -### 5.4. find +### 5.3. find ```c++ Success find(const KE& keyOrElement, VN& valueOrNil) @@ -142,7 +132,7 @@ Success find(const KE& keyOrElement, VN& valueOrNil) 1. Return `status`. -### 5.5. getCapacity +### 5.4. getCapacity ```c++ FwSizeType getCapacity() const @@ -150,7 +140,7 @@ FwSizeType getCapacity() const Return `m_entries.getSize()`. -### 5.6. getHeadIterator +### 5.5. getHeadIterator ```c++ const Iterator* getHeadIterator() const @@ -164,7 +154,7 @@ const Iterator* getHeadIterator() const 1. Return `result`. -### 5.7. getSize +### 5.6. getSize ```c++ FwSizeType getSize() @@ -172,7 +162,7 @@ FwSizeType getSize() Return `m_size`. -### 5.8. insert +### 5.7. insert ```c++ Success insert(const KE& keyOrElement, const VN& valueOrNil) @@ -205,7 +195,7 @@ Success insert(const KE& keyOrElement, const VN& valueOrNil) 1. Return `status`. -### 5.9. remove +### 5.8. remove ```c++ Success remove(const KE& keyOrElement, VN& valueOrNil) @@ -235,7 +225,7 @@ Success remove(const KE& keyOrElement, VN& valueOrNil) 1. Return `status`. -### 5.10. setStorage (Typed Data) +### 5.9. setStorage (Typed Data) ```c++ void setStorage(Entry* entries, FwSizeType capacity) @@ -245,7 +235,7 @@ void setStorage(Entry* entries, FwSizeType capacity) 1. Call `clear()`. -### 5.11. setStorage (Untyped Data) +### 5.10. setStorage (Untyped Data) ```c++ void setStorage(ByteArray data, FwSizeType capacity) diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index 6534baae37c..7afa219bc97 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -162,26 +162,7 @@ m2 = m1; ASSERT_EQ(m2.getSize(), 1); ``` -### 6.2. at - -```c++ -const V& at(FwSizeType index) const -``` - -Return `m_impl.at(index)`. - -_Example:_ -```c++ -constexpr FwSizeType capacity = 3; -ExternalArrayMap::Entry entries[capacity]; -ExternalArrayMap map(entries, capacity); -const auto status = map.insert(0, 1); -ASSERT_EQ(status, Success::SUCCESS); -ASSERT_EQ(map.at(0), 1); -ASSERT_DEATH(map.at(1), "Assert"); -``` - -### 6.3. clear +### 6.2. clear ```c++ void clear() override @@ -200,7 +181,7 @@ map.clear(); ASSERT_EQ(map.getSize(), 0); ``` -### 6.4. find +### 6.3. find ```c++ Success find(const K& key, V& value) override @@ -223,7 +204,7 @@ ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(value, 1); ``` -### 6.5. getCapacity +### 6.4. getCapacity ```c++ FwSizeType getCapacity() const override @@ -239,7 +220,7 @@ ExternalArrayMap map(entries, capacity); ASSERT_EQ(map.getCapacity(), capacity); ``` -### 6.6. getHeadIterator +### 6.5. getHeadIterator ```c++ const Iterator* getHeadIterator const override @@ -263,7 +244,7 @@ ASSERT_EQ(e->getKey(), 0); ASSERT_EQ(e->getValue(), 1); ``` -### 6.7. getSize +### 6.6. getSize ```c++ FwSizeType getSize() const override @@ -284,7 +265,7 @@ size = map.getSize(); ASSERT_EQ(size, 1); ``` -### 6.8. insert +### 6.7. insert ```c++ Success insert(const K& key, const V& value) override @@ -305,7 +286,7 @@ size = map.getSize(); ASSERT_EQ(size, 1); ``` -### 6.9. remove +### 6.8. remove ```c++ Success remove(const K& key, V& value) override @@ -336,7 +317,7 @@ ASSERT_EQ(size, 0); ASSERT_EQ(value, 1); ``` -### 6.10. setStorage (Typed Data) +### 6.9. setStorage (Typed Data) ```c++ void setStorage(Entry* entries, FwSizeType capacity) @@ -356,7 +337,7 @@ ExternalArrayMap::Entry entries[capacity]; map.setStorage(entries, capacity); ``` -### 6.11. setStorage (Untyped Data) +### 6.10. setStorage (Untyped Data) ```c++ void setStorage(ByteArray data, FwSizeType capacity) diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md index ddb5f4243cd..971c2153920 100644 --- a/Fw/DataStructures/docs/ExternalArraySet.md +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -160,26 +160,7 @@ m2 = m1; ASSERT_EQ(m2.getSize(), 1); ``` -### 6.2. at - -```c++ -const Iterator& at(FwSizeType index) const -``` - -Return `m_impl.at(index)`. - -_Example:_ -```c++ -constexpr FwSizeType capacity = 3; -ExternalArraySet::Entry entries[capacity]; -ExternalArraySet set(entries, capacity); -const auto status = set.insert(42); -ASSERT_EQ(status, Success::SUCCESS); -ASSERT_EQ(set.at(0), 42); -ASSERT_DEATH(set.at(1), "Assert"); -``` - -### 6.3. clear +### 6.2. clear ```c++ void clear() override @@ -198,7 +179,7 @@ set.clear(); ASSERT_EQ(set.getSize(), 0); ``` -### 6.4. find +### 6.3. find ```c++ Success find(const T& element) override @@ -221,7 +202,7 @@ status = set.find(42); ASSERT_EQ(status, Success::SUCCESS); ``` -### 6.5. getCapacity +### 6.4. getCapacity ```c++ FwSizeType getCapacity() const override @@ -237,7 +218,7 @@ ExternalArraySet set(entries, capacity); ASSERT_EQ(set.getCapacity(), capacity); ``` -### 6.6. getHeadIterator +### 6.5. getHeadIterator ```c++ const Iterator* getHeadIterator const override @@ -260,7 +241,7 @@ FW_ASSERT(e != nullptr); ASSERT_EQ(e->getElement(), 42); ``` -### 6.7. getSize +### 6.6. getSize ```c++ FwSizeType getSize() const override @@ -281,7 +262,7 @@ size = set.getSize(); ASSERT_EQ(size, 1); ``` -### 6.8. insert +### 6.7. insert ```c++ Success insert(const T& element) override @@ -302,7 +283,7 @@ size = set.getSize(); ASSERT_EQ(size, 1); ``` -### 6.9. remove +### 6.8. remove ```c++ Success remove(const T& element) override @@ -333,7 +314,7 @@ ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(size, 0); ``` -### 6.10. setStorage (Typed Data) +### 6.9. setStorage (Typed Data) ```c++ void setStorage(Entry* entries, FwSizeType capacity) @@ -353,7 +334,7 @@ ExternalArraySet::Entry entries[capacity]; set.setStorage(entries, capacity); ``` -### 6.11. setStorage (Untyped Data) +### 6.10. setStorage (Untyped Data) ```c++ void setStorage(ByteArray data, FwSizeType capacity) diff --git a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp index 8042d1b4715..80b63b7ede2 100644 --- a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp +++ b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp @@ -78,18 +78,6 @@ TEST(ArraySetOrMapImpl, CopyAssignmentOperator) { ASSERT_EQ(impl2.getSize(), 1); } -TEST(ArraySetOrMapImplRules, At) { - State::Entry entries[State::capacity]; - State::Impl impl(entries, State::capacity); - State state(impl); - state.useStoredKey = true; - Rules::insertNotFull.apply(state); - Rules::insertNotFull.apply(state); - state.storedKey = 1; - Rules::insertNotFull.apply(state); - Rules::at.apply(state); -} - TEST(ArraySetOrMapImplRules, Clear) { State::Entry entries[State::capacity]; State::Impl impl(entries, State::capacity); diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp index 1a6e680f063..2d12b0529ca 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp @@ -12,8 +12,6 @@ namespace ArraySetOrMapImplTest { namespace Rules { -At at; - Clear clear; Find find; diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp index 5ef2d5bce9b..e2398205c98 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp @@ -21,23 +21,6 @@ using Rule = STest::Rule; namespace Rules { -struct At : public Rule { - At() : Rule("At") {} - bool precondition(const State& state) { return state.impl.getSize() > 0; } - void action(State& state) { - const auto size = state.impl.getSize(); - const auto* it = state.impl.getHeadIterator(); - for (FwSizeType i = 0; i < size; i++) { - const auto& it1 = state.impl.at(i); - ASSERT_NE(it, nullptr); - const auto& it2 = *it; - ASSERT_EQ(it1.getKey(), it2.getKey()); - ASSERT_EQ(it1.getValue(), it2.getValue()); - it = it->getNextIterator(); - } - } -}; - struct Clear : public Rule { Clear() : Rule("Clear") {} bool precondition(const State& state) { return state.impl.getSize() > 0; } @@ -70,8 +53,13 @@ struct FindExisting : public Rule { void action(State& state) { const auto size = state.impl.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); - const auto& it = state.impl.at(index); - const auto key = it.getKey(); + const auto* it = state.impl.getHeadIterator(); + for (FwSizeType i = 0; i < index; i++) { + ASSERT_NE(it, nullptr); + it = it->getNextIterator(); + } + ASSERT_NE(it, nullptr); + const auto key = it->getKey(); const auto expectedValue = state.modelMap[key]; State::ValueType value = 0; const auto status = state.impl.find(key, value); @@ -122,12 +110,11 @@ struct Remove : public Rule { ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(value, state.modelMap[key]); ASSERT_EQ(state.impl.getSize(), size - 1); - } - else { + } else { ASSERT_EQ(status, Success::FAILURE); ASSERT_EQ(state.impl.getSize(), size); } - (void) state.modelMap.erase(key); + (void)state.modelMap.erase(key); ASSERT_EQ(state.impl.getSize(), state.modelMap.size()); } }; @@ -138,8 +125,13 @@ struct RemoveExisting : public Rule { void action(State& state) { const auto size = state.impl.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); - const auto& it = state.impl.at(index); - const auto key = it.getKey(); + const auto* it = state.impl.getHeadIterator(); + for (FwSizeType i = 0; i < index; i++) { + ASSERT_NE(it, nullptr); + it = it->getNextIterator(); + } + ASSERT_NE(it, nullptr); + const auto key = it->getKey(); const auto expectedValue = state.modelMap[key]; State::ValueType value = 0; const auto status = state.impl.remove(key, value); @@ -151,8 +143,6 @@ struct RemoveExisting : public Rule { } }; -extern At at; - extern Clear clear; extern Find find; diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp index 7837f40ef83..2d2e962f499 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp @@ -17,7 +17,6 @@ namespace Scenarios { void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { Rule* rules[] = { - &Rules::at, &Rules::clear, &Rules::find, &Rules::findExisting, From a656c7f51690f7126593745d2450b9ebd38bfc2e Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sat, 5 Jul 2025 17:55:02 -0700 Subject: [PATCH 306/458] Revise ExternalArrayMapTest --- Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp index 5dc883ee3f1..05415ea0a74 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp @@ -120,20 +120,6 @@ TEST(ExternalFifoQueue, CopyDataFrom) { } } -#if 0 -TEST(ExternalArrayMapRules, At) { - Entry entries[State::capacity]; - Map map(entries, State::capacity); - State state(map); - state.useStoredKey = true; - Rules::insertNotFull.apply(state); - Rules::insertNotFull.apply(state); - state.storedKey = 1; - Rules::insertNotFull.apply(state); - Rules::at.apply(state); -} -#endif - TEST(ExternalArrayMapRules, Clear) { Entry entries[State::capacity]; Map map(entries, State::capacity); From e316d8fe574f647f85bb090049d44dcfd10c63dd Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 6 Jul 2025 15:02:33 -0700 Subject: [PATCH 307/458] Add ExternalArraySetTest --- Fw/DataStructures/CMakeLists.txt | 2 + .../test/ut/ExternalArraySetTest.cpp | 189 +++++++++++++++++- .../STest/ArraySetOrMapImplTestScenarios.hpp | 5 + .../test/ut/STest/FifoQueueTestScenarios.hpp | 5 + .../test/ut/STest/MapTestScenarios.hpp | 5 + .../test/ut/STest/SetTestRules.cpp | 35 ++++ .../test/ut/STest/SetTestRules.hpp | 167 ++++++++++++++++ .../test/ut/STest/SetTestScenarios.cpp | 41 ++++ .../test/ut/STest/SetTestScenarios.hpp | 26 +++ .../test/ut/STest/SetTestState.hpp | 68 +++++++ .../test/ut/STest/StackTestScenarios.hpp | 5 + 11 files changed, 545 insertions(+), 3 deletions(-) create mode 100644 Fw/DataStructures/test/ut/STest/SetTestRules.cpp create mode 100644 Fw/DataStructures/test/ut/STest/SetTestRules.hpp create mode 100644 Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp create mode 100644 Fw/DataStructures/test/ut/STest/SetTestScenarios.hpp create mode 100644 Fw/DataStructures/test/ut/STest/SetTestState.hpp diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index 84b947b5837..804e625f60c 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -21,6 +21,8 @@ set(UT_SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestRules.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/SetTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/SetTestScenarios.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" diff --git a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp index b5086a6efbf..d7da2510c63 100644 --- a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp @@ -1,16 +1,199 @@ // ====================================================================== // \title ExternalArraySetTest.cpp // \author bocchino -// \brief cpp file for ExternalArrayMap tests +// \brief cpp file for ExternalArraySet tests // ====================================================================== #include "Fw/DataStructures/ExternalArraySet.hpp" +#include "STest/STest/Pick/Pick.hpp" +#include "Fw/DataStructures/ExternalArraySet.hpp" +#include "Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp" +#include "Fw/DataStructures/test/ut/STest/SetTestRules.hpp" +#include "Fw/DataStructures/test/ut/STest/SetTestScenarios.hpp" + +#if 0 namespace Fw { +template +class ExternalArraySetTester { + public: + ExternalArraySetTester<, V>(const ExternalArraySet& set) : m_set(set) {} + + const ArraySetOrMapImpl<, V>& getImpl() const { return this->m_set.m_impl; } + + private: + const ExternalArraySet<, V>& m_set; +}; + namespace SetTest { -ExternalArraySet set; +using Entry = SetOrMapIterator; +using Set = ExternalArraySet; +using SetTester = ExternalArraySetTester; +using ImplTester = ArraySetOrMapImplTester; + +TEST(ExternalArraySet, ZeroArgConstructor) { + Set set; + ASSERT_EQ(set.getCapacity(), 0); + ASSERT_EQ(set.getSize(), 0); +} + +TEST(ExternalArraySet, TypedStorageConstructor) { + Entry entries[State::capacity]; + Set set(entries, State::capacity); + SetTester setTester(set); + ImplTester implTester(setTester.getImpl()); + ASSERT_EQ(implTester.getEntries().getElements(), entries); + ASSERT_EQ(set.getCapacity(), FwSizeType(State::capacity)); + ASSERT_EQ(set.getSize(), 0); +} + +TEST(ExternalArraySet, UntypedStorageConstructor) { + constexpr auto alignment = Set::getByteArrayAlignment(); + constexpr auto byteArraySize = Set::getByteArraySize(State::capacity); + alignas(alignment) U8 bytes[byteArraySize]; + Set set(ByteArray(&bytes[0], sizeof bytes), State::capacity); + SetTester setTester(set); + ImplTester implTester(setTester.getImpl()); + ASSERT_EQ(implTester.getEntries().getElements(), reinterpret_cast(bytes)); + ASSERT_EQ(set.getCapacity(), FwSizeType(State::capacity)); + ASSERT_EQ(set.getSize(), 0); +} + +TEST(ExternalArraySet, CopyConstructor) { + Entry entries[State::capacity]; + // Call the constructor providing backing storage + Set set1(entries, State::capacity); + // Insert an item + const State::eyType key = 0; + const State::ValueType value = 42; + const auto status = set1.insert(key, value); + ASSERT_EQ(status, Success::SUCCESS); + // Call the copy constructor + Set set2(set1); + SetTester setTester1(set1); + ImplTester implTester1(setTester1.getImpl()); + SetTester setTester2(set2); + ImplTester implTester2(setTester2.getImpl()); + ASSERT_EQ(implTester2.getEntries().getElements(), entries); + ASSERT_EQ(implTester2.getEntries().getSize(), FwSizeType(State::capacity)); + ASSERT_EQ(set2.getSize(), 1); +} + +TEST(ExternalArraySet, CopyAssignmentOperator) { + Entry entries[State::capacity]; + // Call the constructor providing backing storage + Set set1(entries, State::capacity); + // Insert an item + const State::eyType key = 0; + const State::ValueType value = 42; + const auto status = set1.insert(key, value); + ASSERT_EQ(status, Success::SUCCESS); + // Call the default constructor + Set set2; + ASSERT_EQ(set2.getSize(), 0); + // Call the copy assignment operator + set2 = set1; + ASSERT_EQ(set2.getSize(), 1); +} + +TEST(ExternalFifoQueue, CopyDataFrom) { + constexpr FwSizeType maxSize = 10; + constexpr FwSizeType smallSize = maxSize / 2; + Entry entries1[maxSize]; + Entry entries2[maxSize]; + Set m1(entries1, maxSize); + // size1 < capacity2 + { + Set m2(entries2, maxSize); + State::testCopyDataFrom(m1, smallSize, m2); + } + // size1 == size2 + { + Set m2(entries2, maxSize); + State::testCopyDataFrom(m1, maxSize, m2); + } + // size1 > size2 + { + Set m2(entries2, smallSize); + State::testCopyDataFrom(m1, maxSize, m2); + } +} + +TEST(ExternalArraySetRules, Clear) { + Entry entries[State::capacity]; + Set set(entries, State::capacity); + State state(set); + Rules::insertNotFull.apply(state); + ASSERT_EQ(state.set.getSize(), 1); + Rules::clear.apply(state); + ASSERT_EQ(state.set.getSize(), 0); +} + +TEST(ExternalArraysetRules, Find) { + Entry entries[State::capacity]; + Set set(entries, State::capacity); + State state(set); + Rules::find.apply(state); + state.useStoredey = true; + Rules::insertNotFull.apply(state); + Rules::find.apply(state); +} + +TEST(ExternalArraySetRules, FindExisting) { + Entry entries[State::capacity]; + Set set(entries, State::capacity); + State state(set); + Rules::insertNotFull.apply(state); + Rules::findExisting.apply(state); +} + +TEST(ExternalArraySetRules, InsertFull) { + Entry entries[State::capacity]; + Set set(entries, State::capacity); + State state(set); + state.useStoredey = true; + for (FwSizeType i = 0; i < State::capacity; i++) { + state.storedey = static_cast(i); + Rules::insertNotFull.apply(state); + } + state.useStoredey = false; + Rules::insertFull.apply(state); +} + +TEST(ExternalArraySetRules, InsertNotFull) { + Entry entries[State::capacity]; + Set set(entries, State::capacity); + State state(set); + Rules::insertNotFull.apply(state); +} + +TEST(ExternalArraySetRules, Remove) { + Entry entries[State::capacity]; + Set set(entries, State::capacity); + State state(set); + state.useStoredey = true; + Rules::insertNotFull.apply(state); + Rules::remove.apply(state); + Rules::remove.apply(state); +} + +TEST(ExternalArraySetRules, RemoveExisting) { + Entry entries[State::capacity]; + Set set(entries, State::capacity); + State state(set); + Rules::insertNotFull.apply(state); + Rules::removeExisting.apply(state); +} + +TEST(ExternalArraySetScenarios, Random) { + Entry entries[State::capacity]; + Set set(entries, State::capacity); + State state(set); + Scenarios::random(Fw::String("ExternalArraySetRandom"), state, 1000); +} -} // namespace SetTest +} // namespace ArraySetTest } // namespace Fw +#endif diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.hpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.hpp index d2bd005b668..311684d5b16 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.hpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.hpp @@ -4,6 +4,9 @@ // \brief ArraySetOrMapImpl test scenarios // ====================================================================== +#ifndef ArraySetOrMapImplTestScenarios_HPP +#define ArraySetOrMapImplTestScenarios_HPP + #include "Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp" namespace Fw { @@ -19,3 +22,5 @@ void random(const Fw::StringBase& name, State& state, U32 maxNumSteps); } // namespace ArraySetOrMapImplTest } // namespace Fw + +#endif diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp index 2747776338a..fae0eb6fb5f 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp @@ -4,6 +4,9 @@ // \brief FifoQueue test scenarios // ====================================================================== +#ifndef FifoQueueTestScenarios_HPP +#define FifoQueueTestScenarios_HPP + #include "Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp" namespace Fw { @@ -19,3 +22,5 @@ void random(const Fw::StringBase& name, State& state, U32 maxNumSteps); } // namespace FifoQueueTest } // namespace Fw + +#endif diff --git a/Fw/DataStructures/test/ut/STest/MapTestScenarios.hpp b/Fw/DataStructures/test/ut/STest/MapTestScenarios.hpp index 1388e055a46..e9553fc5094 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestScenarios.hpp +++ b/Fw/DataStructures/test/ut/STest/MapTestScenarios.hpp @@ -4,6 +4,9 @@ // \brief Map test scenarios // ====================================================================== +#ifndef MapTestScenarios_HPP +#define MapTestScenarios_HPP + #include "Fw/DataStructures/test/ut/STest/MapTestState.hpp" namespace Fw { @@ -19,3 +22,5 @@ void random(const Fw::StringBase& name, State& state, U32 maxNumSteps); } // namespace MapTest } // namespace Fw + +#endif diff --git a/Fw/DataStructures/test/ut/STest/SetTestRules.cpp b/Fw/DataStructures/test/ut/STest/SetTestRules.cpp new file mode 100644 index 00000000000..db9e3efb62c --- /dev/null +++ b/Fw/DataStructures/test/ut/STest/SetTestRules.cpp @@ -0,0 +1,35 @@ +// ====================================================================== +// \title SetTestRules.cpp +// \author Rob Bocchino +// \brief cpp file for ArraySet test rules +// ====================================================================== + +#include "Fw/DataStructures/test/ut/STest/SetTestRules.hpp" + +namespace Fw { + +namespace SetTest { + +namespace Rules { + +#if 0 +Clear clear; + +Find find; + +FindExisting findExisting; + +InsertFull insertFull; + +InsertNotFull insertNotFull; + +Remove remove; + +RemoveExisting removeExisting; +#endif + +}; // namespace Rules + +} // namespace SetTest + +} // namespace Fw diff --git a/Fw/DataStructures/test/ut/STest/SetTestRules.hpp b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp new file mode 100644 index 00000000000..5952b92f427 --- /dev/null +++ b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp @@ -0,0 +1,167 @@ +// ====================================================================== +// \title SetTestRules.hpp +// \author bocchino +// \brief hpp file for set test rules +// ====================================================================== + +#ifndef SetTestRules_HPP +#define SetTestRules_HPP + +#include "Fw/DataStructures/test/ut/STest/SetTestState.hpp" +#include "STest/STest/Pick/Pick.hpp" +#include "STest/STest/Rule/Rule.hpp" + +namespace Fw { + +namespace SetTest { + +using Rule = STest::Rule; + +namespace Rules { + +#if 0 +struct Clear : public Rule { + Clear() : Rule("Clear") {} + bool precondition(const State& state) { return state.set.getSize() > 0; } + void action(State& state) { + state.set.clear(); + ASSERT_EQ(state.set.getSize(), 0); + state.modelSet.clear(); + } +}; + +struct Find : public Rule { + Find() : Rule("Find") {} + bool precondition(const State& state) { return true; } + void action(State& state) { + const auto key = state.getKey(); + State::ValueType value = 0; + const auto status = state.set.find(key, value); + if (state.modelSetContains(key)) { + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(value, state.modelSet[key]); + } else { + ASSERT_EQ(status, Success::FAILURE); + } + } +}; + +struct FindExisting : public Rule { + FindExisting() : Rule("FindExisting") {} + bool precondition(const State& state) { return static_cast(state.set.getSize()) > 0; } + void action(State& state) { + const auto size = state.set.getSize(); + const auto index = STest::Pick::startLength(0, static_cast(size)); + const auto* it = state.set.getHeadIterator(); + for (FwSizeType i = 0; i < index; i++) { + ASSERT_NE(it, nullptr); + it = it->getNextSetIterator(); + } + ASSERT_NE(it, nullptr); + const auto key = it->getKey(); + const auto expectedValue = state.modelSet[key]; + State::ValueType value = 0; + const auto status = state.set.find(key, value); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(value, expectedValue); + } +}; + +struct InsertFull : public Rule { + InsertFull() : Rule("InsertFull") {} + bool precondition(const State& state) { return static_cast(state.set.getSize()) >= State::capacity; } + void action(State& state) { + const auto key = state.getKey(); + const auto value = state.getValue(); + const auto size = state.set.getSize(); + const auto expectedStatus = state.modelSetContains(key) ? Success::SUCCESS : Success::FAILURE; + const auto status = state.set.insert(key, value); + ASSERT_EQ(status, expectedStatus); + ASSERT_EQ(state.set.getSize(), size); + } +}; + +struct InsertNotFull : public Rule { + InsertNotFull() : Rule("InsertNotFull") {} + bool precondition(const State& state) { return static_cast(state.set.getSize()) < State::capacity; } + void action(State& state) { + const auto key = state.getKey(); + const auto value = state.getValue(); + const auto size = state.set.getSize(); + const auto expectedSize = state.modelSetContains(key) ? size : size + 1; + const auto status = state.set.insert(key, value); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(state.set.getSize(), expectedSize); + state.modelSet[key] = value; + } +}; + +struct Remove : public Rule { + Remove() : Rule("Remove") {} + bool precondition(const State& state) { return true; } + void action(State& state) { + const auto size = state.set.getSize(); + ASSERT_EQ(size, state.modelSet.size()); + const auto key = state.getKey(); + State::ValueType value = 0; + const auto status = state.set.remove(key, value); + if (state.modelSetContains(key)) { + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(value, state.modelSet[key]); + ASSERT_EQ(state.set.getSize(), size - 1); + } + else { + ASSERT_EQ(status, Success::FAILURE); + ASSERT_EQ(state.set.getSize(), size); + } + (void) state.modelSet.erase(key); + ASSERT_EQ(state.set.getSize(), state.modelSet.size()); + } +}; + +struct RemoveExisting : public Rule { + RemoveExisting() : Rule("RemoveExisting") {} + bool precondition(const State& state) { return static_cast(state.set.getSize()) > 0; } + void action(State& state) { + const auto size = state.set.getSize(); + const auto index = STest::Pick::startLength(0, static_cast(size)); + const auto* it = state.set.getHeadIterator(); + for (FwSizeType i = 0; i < index; i++) { + ASSERT_NE(it, nullptr); + it = it->getNextSetIterator(); + } + ASSERT_NE(it, nullptr); + const auto key = it->getKey(); + const auto expectedValue = state.modelSet[key]; + State::ValueType value = 0; + const auto status = state.set.remove(key, value); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(value, expectedValue); + const auto n = state.modelSet.erase(key); + ASSERT_EQ(n, 1); + ASSERT_EQ(state.set.getSize(), state.modelSet.size()); + } +}; + +extern Clear clear; + +extern Find find; + +extern FindExisting findExisting; + +extern InsertFull insertFull; + +extern InsertNotFull insertNotFull; + +extern Remove remove; + +extern RemoveExisting removeExisting; +#endif + +}; // namespace Rules + +} // namespace SetTest + +} // namespace Fw + +#endif diff --git a/Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp new file mode 100644 index 00000000000..5b96cfac10d --- /dev/null +++ b/Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp @@ -0,0 +1,41 @@ +// ====================================================================== +// \title SetTestScenarios.cpp +// \author Rob Bocchino +// \brief Set test scenarios +// ====================================================================== + +#include "Fw/DataStructures/test/ut/STest/SetTestRules.hpp" +#include "Fw/DataStructures/test/ut/STest/SetTestScenarios.hpp" +#include "STest/Scenario/BoundedScenario.hpp" +#include "STest/Scenario/RandomScenario.hpp" + +namespace Fw { + +namespace SetTest { + +namespace Scenarios { + +void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { +#if 0 + Rule* rules[] = { + &Rules::clear, + &Rules::find, + &Rules::findExisting, + &Rules::insertFull, + &Rules::insertNotFull, + &Rules::remove, + &Rules::removeExisting + }; + STest::RandomScenario scenario("RandomScenario", rules, + sizeof(rules) / sizeof(STest::RandomScenario*)); + STest::BoundedScenario boundedScenario(name.toChar(), scenario, maxNumSteps); + const U32 numSteps = boundedScenario.run(state); + printf("Ran %u steps.\n", numSteps); +#endif +} + +} // namespace Scenarios + +} // namespace SetTest + +} // namespace Fw diff --git a/Fw/DataStructures/test/ut/STest/SetTestScenarios.hpp b/Fw/DataStructures/test/ut/STest/SetTestScenarios.hpp new file mode 100644 index 00000000000..88cb31bee19 --- /dev/null +++ b/Fw/DataStructures/test/ut/STest/SetTestScenarios.hpp @@ -0,0 +1,26 @@ +// ====================================================================== +// \title SetTestScenarios.hpp +// \author Rob Bocchino +// \brief Set test scenarios +// ====================================================================== + +#ifndef SetTestScenarios_HPP +#define SetTestScenarios_HPP + +#include "Fw/DataStructures/test/ut/STest/SetTestState.hpp" + +namespace Fw { + +namespace SetTest { + +namespace Scenarios { + +void random(const Fw::StringBase& name, State& state, U32 maxNumSteps); + +} // namespace Scenarios + +} // namespace SetTest + +} // namespace Fw + +#endif diff --git a/Fw/DataStructures/test/ut/STest/SetTestState.hpp b/Fw/DataStructures/test/ut/STest/SetTestState.hpp new file mode 100644 index 00000000000..c5aa2e4992d --- /dev/null +++ b/Fw/DataStructures/test/ut/STest/SetTestState.hpp @@ -0,0 +1,68 @@ +// ====================================================================== +// \title SetTestState.hpp +// \author bocchino +// \brief hpp file for set test state +// ====================================================================== + +#ifndef SetTestState_HPP +#define SetTestState_HPP + +#include + +#include + +#include "Fw/DataStructures/SetBase.hpp" +#include "STest/STest/Pick/Pick.hpp" + +namespace Fw { + +namespace SetTest { + +struct State { + //! The element type + using ElementType = U32; + //! The set capacity + static constexpr FwSizeType capacity = 1024; + //! THe SetBase type + using SetBase = SetBase; + //! The iterator type + using Iterator = SetIterator; + //! Constructor + State(SetBase& a_set) : set(a_set) {} + //! The set under test + SetBase& set; + //! The set for modeling correct behavior + std::set modelSet; + //! Whether to use the stored element + bool useStoredElement = false; + //! The stored element + ElementType storedElement = 0; + //! Get an element + ElementType getElement() const { + return useStoredElement ? storedElement : static_cast(STest::Pick::any()); + } + //! Check whether the model set contains the specified element + bool modelSetContains(ElementType e) const { return modelSet.count(e) != 0; } + //! Test copy data from + static void testCopyDataFrom(SetBase& m1, FwSizeType size1, SetBase& m2) { + m1.clear(); + for (FwSizeType i = 0; i < size1; i++) { + const auto status = m1.insert(static_cast(i)); + ASSERT_EQ(status, Success::SUCCESS); + } + m2.copyDataFrom(m1); + const auto capacity2 = m2.getCapacity(); + const FwSizeType size = FW_MIN(size1, capacity2); + for (FwSizeType i = 0; i < size; i++) { + const auto e = static_cast(i); + const auto status = m2.find(e); + ASSERT_EQ(status, Success::SUCCESS); + } + } +}; + +} // namespace SetTest + +} // namespace Fw + +#endif diff --git a/Fw/DataStructures/test/ut/STest/StackTestScenarios.hpp b/Fw/DataStructures/test/ut/STest/StackTestScenarios.hpp index bfd567ff202..7d7221be580 100644 --- a/Fw/DataStructures/test/ut/STest/StackTestScenarios.hpp +++ b/Fw/DataStructures/test/ut/STest/StackTestScenarios.hpp @@ -4,6 +4,9 @@ // \brief Stack test scenarios // ====================================================================== +#ifndef StackTestScenarios_HPP +#define StackTestScenarios_HPP + #include "Fw/DataStructures/test/ut/STest/StackTestState.hpp" namespace Fw { @@ -19,3 +22,5 @@ void random(const Fw::StringBase& name, State& state, U32 maxNumSteps); } // namespace StackTest } // namespace Fw + +#endif From 8abe38fd94cd8520030502bf7c4caba009bc4820 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 6 Jul 2025 15:16:01 -0700 Subject: [PATCH 308/458] Revise ExternalArraySet and ExternalArrayMap --- Fw/DataStructures/ExternalArrayMap.hpp | 4 +-- Fw/DataStructures/ExternalArraySet.hpp | 4 +-- Fw/DataStructures/docs/ExternalArrayMap.md | 4 +-- Fw/DataStructures/docs/ExternalArraySet.md | 4 +-- .../test/ut/ExternalArrayMapTest.cpp | 4 +-- .../test/ut/ExternalArraySetTest.cpp | 34 +++++++++---------- 6 files changed, 27 insertions(+), 27 deletions(-) diff --git a/Fw/DataStructures/ExternalArrayMap.hpp b/Fw/DataStructures/ExternalArrayMap.hpp index 9c1bcd0d59e..0382e8603cd 100644 --- a/Fw/DataStructures/ExternalArrayMap.hpp +++ b/Fw/DataStructures/ExternalArrayMap.hpp @@ -47,7 +47,7 @@ class ExternalArrayMap final : public MapBase { FwSizeType capacity //!< The capacity ) : MapBase() { - this->m_impl.setStorage(entries, capacity); + this->setStorage(entries, capacity); } //! Constructor providing untyped backing storage. @@ -57,7 +57,7 @@ class ExternalArrayMap final : public MapBase { FwSizeType capacity //!< The capacity ) : MapBase() { - this->m_impl.setStorage(data, capacity); + this->setStorage(data, capacity); } //! Copy constructor diff --git a/Fw/DataStructures/ExternalArraySet.hpp b/Fw/DataStructures/ExternalArraySet.hpp index ea123707e0b..bdc1561c9b9 100644 --- a/Fw/DataStructures/ExternalArraySet.hpp +++ b/Fw/DataStructures/ExternalArraySet.hpp @@ -48,7 +48,7 @@ class ExternalArraySet final : public SetBase { FwSizeType capacity //!< The capacity ) : SetBase() { - this->m_impl.setStorage(entries, capacity); + this->setStorage(entries, capacity); } //! Constructor providing untyped backing storage. @@ -58,7 +58,7 @@ class ExternalArraySet final : public SetBase { FwSizeType capacity //!< The capacity ) : SetBase() { - this->m_impl.setStorage(data, capacity); + this->setStorage(data, capacity); } //! Copy constructor diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index 7afa219bc97..52f8e62799d 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -67,7 +67,7 @@ ExternalArrayMap(Entry* entries, FwSizeType capacity) `entries` must point to a primitive array of at least `capacity` elements of type [`Entry`](ExternalArrayMap.md#Public-Types). -Call `m_impl.setStorage(entries, capacity)`. +Call `setStorage(entries, capacity)`. _Example:_ ```c++ @@ -86,7 +86,7 @@ ExternalArrayMap(ByteArray data, FwSizeType capacity) [`getByteArrayAlignment()`](#getByteArrayAlignment) and must contain at least [`getByteArraySize(size)`](#getByteArraySize) bytes. -Call `m_impl.setStorage(data, capacity)`. +Call `setStorage(data, capacity)`. _Example:_ ```c++ diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md index 971c2153920..e032b67b31f 100644 --- a/Fw/DataStructures/docs/ExternalArraySet.md +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -69,7 +69,7 @@ ExternalArraySet(Entry* entries, FwSizeType capacity) elements of type `Entry`. The type `Entry` is defined [here](ExternalArraySet.md#Public-Types). -Call `m_impl.setStorage(entries, capacity)`. +Call `setStorage(entries, capacity)`. _Example:_ ```c++ @@ -88,7 +88,7 @@ ExternalArraySet(ByteArray data, FwSizeType capacity) [`getByteArrayAlignment()`](#getByteArrayAlignment) and must contain at least [`getByteArraySize(size)`](#getByteArraySize) bytes. -Call `m_impl.setStorage(data, capacity)`. +Call `setStorage(data, capacity)`. _Example:_ ```c++ diff --git a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp index 05415ea0a74..49f12319b72 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp @@ -121,7 +121,7 @@ TEST(ExternalFifoQueue, CopyDataFrom) { } TEST(ExternalArrayMapRules, Clear) { - Entry entries[State::capacity]; + Entry entries[State::capacity]; Map map(entries, State::capacity); State state(map); Rules::insertNotFull.apply(state); @@ -193,5 +193,5 @@ TEST(ExternalArrayMapScenarios, Random) { Scenarios::random(Fw::String("ExternalArrayMapRandom"), state, 1000); } -} // namespace ArrayMapTest +} // namespace MapTest } // namespace Fw diff --git a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp index d7da2510c63..927f9215288 100644 --- a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp @@ -12,26 +12,25 @@ #include "Fw/DataStructures/test/ut/STest/SetTestRules.hpp" #include "Fw/DataStructures/test/ut/STest/SetTestScenarios.hpp" -#if 0 namespace Fw { -template +template class ExternalArraySetTester { public: - ExternalArraySetTester<, V>(const ExternalArraySet& set) : m_set(set) {} + ExternalArraySetTester(const ExternalArraySet& set) : m_set(set) {} - const ArraySetOrMapImpl<, V>& getImpl() const { return this->m_set.m_impl; } + const ArraySetOrMapImpl& getImpl() const { return this->m_set.m_impl; } private: - const ExternalArraySet<, V>& m_set; + const ExternalArraySet& m_set; }; namespace SetTest { -using Entry = SetOrMapIterator; -using Set = ExternalArraySet; -using SetTester = ExternalArraySetTester; -using ImplTester = ArraySetOrMapImplTester; +using Entry = SetOrMapIterator; +using Set = ExternalArraySet; +using SetTester = ExternalArraySetTester; +using ImplTester = ArraySetOrMapImplTester; TEST(ExternalArraySet, ZeroArgConstructor) { Set set; @@ -66,9 +65,8 @@ TEST(ExternalArraySet, CopyConstructor) { // Call the constructor providing backing storage Set set1(entries, State::capacity); // Insert an item - const State::eyType key = 0; - const State::ValueType value = 42; - const auto status = set1.insert(key, value); + const State::ElementType e = 42; + const auto status = set1.insert(e); ASSERT_EQ(status, Success::SUCCESS); // Call the copy constructor Set set2(set1); @@ -86,9 +84,8 @@ TEST(ExternalArraySet, CopyAssignmentOperator) { // Call the constructor providing backing storage Set set1(entries, State::capacity); // Insert an item - const State::eyType key = 0; - const State::ValueType value = 42; - const auto status = set1.insert(key, value); + const State::ElementType e = 42; + const auto status = set1.insert(e); ASSERT_EQ(status, Success::SUCCESS); // Call the default constructor Set set2; @@ -98,6 +95,7 @@ TEST(ExternalArraySet, CopyAssignmentOperator) { ASSERT_EQ(set2.getSize(), 1); } +#if 0 TEST(ExternalFifoQueue, CopyDataFrom) { constexpr FwSizeType maxSize = 10; constexpr FwSizeType smallSize = maxSize / 2; @@ -120,7 +118,9 @@ TEST(ExternalFifoQueue, CopyDataFrom) { State::testCopyDataFrom(m1, maxSize, m2); } } +#endif +#if 0 TEST(ExternalArraySetRules, Clear) { Entry entries[State::capacity]; Set set(entries, State::capacity); @@ -193,7 +193,7 @@ TEST(ExternalArraySetScenarios, Random) { State state(set); Scenarios::random(Fw::String("ExternalArraySetRandom"), state, 1000); } +#endif -} // namespace ArraySetTest +} // namespace SetTest } // namespace Fw -#endif From aa8cd51e289187a8d9e097a22d30f8134db1d5a6 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 6 Jul 2025 15:27:48 -0700 Subject: [PATCH 309/458] Revise ExternalArraySetTest --- Fw/DataStructures/CMakeLists.txt | 36 +++++++++---------- .../test/ut/ExternalArraySetTest.cpp | 12 ++++--- .../test/ut/STest/SetTestRules.cpp | 2 ++ .../test/ut/STest/SetTestRules.hpp | 20 ++++++----- 4 files changed, 38 insertions(+), 32 deletions(-) diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index 804e625f60c..d5f9de696d8 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -5,27 +5,27 @@ set(SOURCE_FILES register_fprime_module() set(UT_SOURCE_FILES - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestRules.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestScenarios.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestRules.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestScenarios.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/SetTestRules.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/SetTestScenarios.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" ) set(UT_MOD_DEPS diff --git a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp index 927f9215288..59295003253 100644 --- a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp @@ -136,7 +136,7 @@ TEST(ExternalArraysetRules, Find) { Set set(entries, State::capacity); State state(set); Rules::find.apply(state); - state.useStoredey = true; + state.useStoredElement = true; Rules::insertNotFull.apply(state); Rules::find.apply(state); } @@ -148,17 +148,18 @@ TEST(ExternalArraySetRules, FindExisting) { Rules::insertNotFull.apply(state); Rules::findExisting.apply(state); } +#endif TEST(ExternalArraySetRules, InsertFull) { Entry entries[State::capacity]; Set set(entries, State::capacity); State state(set); - state.useStoredey = true; + state.useStoredElement = true; for (FwSizeType i = 0; i < State::capacity; i++) { - state.storedey = static_cast(i); + state.storedElement = static_cast(i); Rules::insertNotFull.apply(state); } - state.useStoredey = false; + state.useStoredElement = false; Rules::insertFull.apply(state); } @@ -169,11 +170,12 @@ TEST(ExternalArraySetRules, InsertNotFull) { Rules::insertNotFull.apply(state); } +#if 0 TEST(ExternalArraySetRules, Remove) { Entry entries[State::capacity]; Set set(entries, State::capacity); State state(set); - state.useStoredey = true; + state.useStoredElement = true; Rules::insertNotFull.apply(state); Rules::remove.apply(state); Rules::remove.apply(state); diff --git a/Fw/DataStructures/test/ut/STest/SetTestRules.cpp b/Fw/DataStructures/test/ut/STest/SetTestRules.cpp index db9e3efb62c..e78e7a471e0 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/SetTestRules.cpp @@ -18,11 +18,13 @@ Clear clear; Find find; FindExisting findExisting; +#endif InsertFull insertFull; InsertNotFull insertNotFull; +#if 0 Remove remove; RemoveExisting removeExisting; diff --git a/Fw/DataStructures/test/ut/STest/SetTestRules.hpp b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp index 5952b92f427..24102da95b7 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp @@ -66,16 +66,16 @@ struct FindExisting : public Rule { ASSERT_EQ(value, expectedValue); } }; +#endif struct InsertFull : public Rule { InsertFull() : Rule("InsertFull") {} bool precondition(const State& state) { return static_cast(state.set.getSize()) >= State::capacity; } void action(State& state) { - const auto key = state.getKey(); - const auto value = state.getValue(); + const auto e = state.getElement(); const auto size = state.set.getSize(); - const auto expectedStatus = state.modelSetContains(key) ? Success::SUCCESS : Success::FAILURE; - const auto status = state.set.insert(key, value); + const auto expectedStatus = state.modelSetContains(e) ? Success::SUCCESS : Success::FAILURE; + const auto status = state.set.insert(e); ASSERT_EQ(status, expectedStatus); ASSERT_EQ(state.set.getSize(), size); } @@ -85,17 +85,17 @@ struct InsertNotFull : public Rule { InsertNotFull() : Rule("InsertNotFull") {} bool precondition(const State& state) { return static_cast(state.set.getSize()) < State::capacity; } void action(State& state) { - const auto key = state.getKey(); - const auto value = state.getValue(); + const auto e = state.getElement(); const auto size = state.set.getSize(); - const auto expectedSize = state.modelSetContains(key) ? size : size + 1; - const auto status = state.set.insert(key, value); + const auto expectedSize = state.modelSetContains(e) ? size : size + 1; + const auto status = state.set.insert(e); ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(state.set.getSize(), expectedSize); - state.modelSet[key] = value; + state.modelSet.insert(e); } }; +#if 0 struct Remove : public Rule { Remove() : Rule("Remove") {} bool precondition(const State& state) { return true; } @@ -148,11 +148,13 @@ extern Clear clear; extern Find find; extern FindExisting findExisting; +#endif extern InsertFull insertFull; extern InsertNotFull insertNotFull; +#if 0 extern Remove remove; extern RemoveExisting removeExisting; From 2c4437e0d129e605ded73d7b3a70645b2c4ed174 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 6 Jul 2025 15:30:50 -0700 Subject: [PATCH 310/458] Revise ExternalArraySetTest --- .../test/ut/ExternalArraySetTest.cpp | 4 ++-- Fw/DataStructures/test/ut/STest/SetTestRules.cpp | 2 +- Fw/DataStructures/test/ut/STest/SetTestRules.hpp | 4 +++- .../test/ut/STest/SetTestScenarios.cpp | 15 ++++++--------- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp index 59295003253..18cf088b9ac 100644 --- a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp @@ -120,7 +120,6 @@ TEST(ExternalFifoQueue, CopyDataFrom) { } #endif -#if 0 TEST(ExternalArraySetRules, Clear) { Entry entries[State::capacity]; Set set(entries, State::capacity); @@ -131,6 +130,7 @@ TEST(ExternalArraySetRules, Clear) { ASSERT_EQ(state.set.getSize(), 0); } +#if 0 TEST(ExternalArraysetRules, Find) { Entry entries[State::capacity]; Set set(entries, State::capacity); @@ -188,6 +188,7 @@ TEST(ExternalArraySetRules, RemoveExisting) { Rules::insertNotFull.apply(state); Rules::removeExisting.apply(state); } +#endif TEST(ExternalArraySetScenarios, Random) { Entry entries[State::capacity]; @@ -195,7 +196,6 @@ TEST(ExternalArraySetScenarios, Random) { State state(set); Scenarios::random(Fw::String("ExternalArraySetRandom"), state, 1000); } -#endif } // namespace SetTest } // namespace Fw diff --git a/Fw/DataStructures/test/ut/STest/SetTestRules.cpp b/Fw/DataStructures/test/ut/STest/SetTestRules.cpp index e78e7a471e0..1fb139ed222 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/SetTestRules.cpp @@ -12,9 +12,9 @@ namespace SetTest { namespace Rules { -#if 0 Clear clear; +#if 0 Find find; FindExisting findExisting; diff --git a/Fw/DataStructures/test/ut/STest/SetTestRules.hpp b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp index 24102da95b7..2f81952abe5 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp @@ -19,7 +19,6 @@ using Rule = STest::Rule; namespace Rules { -#if 0 struct Clear : public Rule { Clear() : Rule("Clear") {} bool precondition(const State& state) { return state.set.getSize() > 0; } @@ -30,6 +29,7 @@ struct Clear : public Rule { } }; +#if 0 struct Find : public Rule { Find() : Rule("Find") {} bool precondition(const State& state) { return true; } @@ -142,9 +142,11 @@ struct RemoveExisting : public Rule { ASSERT_EQ(state.set.getSize(), state.modelSet.size()); } }; +#endif extern Clear clear; +#if 0 extern Find find; extern FindExisting findExisting; diff --git a/Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp index 5b96cfac10d..8562e801494 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp +++ b/Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp @@ -16,22 +16,19 @@ namespace SetTest { namespace Scenarios { void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { -#if 0 Rule* rules[] = { - &Rules::clear, - &Rules::find, - &Rules::findExisting, - &Rules::insertFull, - &Rules::insertNotFull, - &Rules::remove, - &Rules::removeExisting + &Rules::clear, + //&Rules::find, + //&Rules::findExisting, + &Rules::insertFull, &Rules::insertNotFull + //&Rules::remove, + //&Rules::removeExisting }; STest::RandomScenario scenario("RandomScenario", rules, sizeof(rules) / sizeof(STest::RandomScenario*)); STest::BoundedScenario boundedScenario(name.toChar(), scenario, maxNumSteps); const U32 numSteps = boundedScenario.run(state); printf("Ran %u steps.\n", numSteps); -#endif } } // namespace Scenarios From ebaa070c5b0a7a311887fd13b31d787e64e4f04c Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 6 Jul 2025 15:36:38 -0700 Subject: [PATCH 311/458] Revise ExternalArraySetTest --- .../test/ut/ExternalArraySetTest.cpp | 2 +- .../test/ut/STest/SetTestRules.cpp | 2 +- .../test/ut/STest/SetTestRules.hpp | 41 ++++++++----------- .../test/ut/STest/SetTestScenarios.cpp | 2 +- 4 files changed, 21 insertions(+), 26 deletions(-) diff --git a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp index 18cf088b9ac..9f6967bf263 100644 --- a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp @@ -130,7 +130,6 @@ TEST(ExternalArraySetRules, Clear) { ASSERT_EQ(state.set.getSize(), 0); } -#if 0 TEST(ExternalArraysetRules, Find) { Entry entries[State::capacity]; Set set(entries, State::capacity); @@ -141,6 +140,7 @@ TEST(ExternalArraysetRules, Find) { Rules::find.apply(state); } +#if 0 TEST(ExternalArraySetRules, FindExisting) { Entry entries[State::capacity]; Set set(entries, State::capacity); diff --git a/Fw/DataStructures/test/ut/STest/SetTestRules.cpp b/Fw/DataStructures/test/ut/STest/SetTestRules.cpp index 1fb139ed222..93c5f24c861 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/SetTestRules.cpp @@ -14,9 +14,9 @@ namespace Rules { Clear clear; -#if 0 Find find; +#if 0 FindExisting findExisting; #endif diff --git a/Fw/DataStructures/test/ut/STest/SetTestRules.hpp b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp index 2f81952abe5..60cbf80353d 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp @@ -29,23 +29,18 @@ struct Clear : public Rule { } }; -#if 0 struct Find : public Rule { Find() : Rule("Find") {} bool precondition(const State& state) { return true; } void action(State& state) { - const auto key = state.getKey(); - State::ValueType value = 0; - const auto status = state.set.find(key, value); - if (state.modelSetContains(key)) { - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(value, state.modelSet[key]); - } else { - ASSERT_EQ(status, Success::FAILURE); - } + const auto e = state.getElement(); + const auto status = state.set.find(e); + const auto expectedStatus = state.modelSetContains(e) ? Success::SUCCESS : Success::FAILURE; + ASSERT_EQ(status, expectedStatus); } }; +#if 0 struct FindExisting : public Rule { FindExisting() : Rule("FindExisting") {} bool precondition(const State& state) { return static_cast(state.set.getSize()) > 0; } @@ -58,10 +53,10 @@ struct FindExisting : public Rule { it = it->getNextSetIterator(); } ASSERT_NE(it, nullptr); - const auto key = it->getKey(); - const auto expectedValue = state.modelSet[key]; + const auto e = it->getElement(); + const auto expectedValue = state.modelSet[e]; State::ValueType value = 0; - const auto status = state.set.find(key, value); + const auto status = state.set.find(e, value); ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(value, expectedValue); } @@ -102,19 +97,19 @@ struct Remove : public Rule { void action(State& state) { const auto size = state.set.getSize(); ASSERT_EQ(size, state.modelSet.size()); - const auto key = state.getKey(); + const auto e = state.getElement(); State::ValueType value = 0; - const auto status = state.set.remove(key, value); - if (state.modelSetContains(key)) { + const auto status = state.set.remove(e, value); + if (state.modelSetContains(e)) { ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(value, state.modelSet[key]); + ASSERT_EQ(value, state.modelSet[e]); ASSERT_EQ(state.set.getSize(), size - 1); } else { ASSERT_EQ(status, Success::FAILURE); ASSERT_EQ(state.set.getSize(), size); } - (void) state.modelSet.erase(key); + (void) state.modelSet.erase(e); ASSERT_EQ(state.set.getSize(), state.modelSet.size()); } }; @@ -131,13 +126,13 @@ struct RemoveExisting : public Rule { it = it->getNextSetIterator(); } ASSERT_NE(it, nullptr); - const auto key = it->getKey(); - const auto expectedValue = state.modelSet[key]; + const auto e = it->getElement(); + const auto expectedValue = state.modelSet[e]; State::ValueType value = 0; - const auto status = state.set.remove(key, value); + const auto status = state.set.remove(e, value); ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(value, expectedValue); - const auto n = state.modelSet.erase(key); + const auto n = state.modelSet.erase(e); ASSERT_EQ(n, 1); ASSERT_EQ(state.set.getSize(), state.modelSet.size()); } @@ -146,9 +141,9 @@ struct RemoveExisting : public Rule { extern Clear clear; -#if 0 extern Find find; +#if 0 extern FindExisting findExisting; #endif diff --git a/Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp index 8562e801494..3256bfda3b1 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp +++ b/Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp @@ -18,7 +18,7 @@ namespace Scenarios { void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { Rule* rules[] = { &Rules::clear, - //&Rules::find, + &Rules::find, //&Rules::findExisting, &Rules::insertFull, &Rules::insertNotFull //&Rules::remove, From 48ecedafc3e46e5daa3b1622187be906a83144dd Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 6 Jul 2025 15:44:50 -0700 Subject: [PATCH 312/458] Revise ExternalArraySetTest --- Fw/DataStructures/CMakeLists.txt | 36 +++++++++---------- .../test/ut/ExternalArrayMapTest.cpp | 2 +- .../test/ut/ExternalArraySetTest.cpp | 4 +-- .../test/ut/STest/SetTestRules.cpp | 2 -- .../test/ut/STest/SetTestRules.hpp | 19 ++++------ 5 files changed, 26 insertions(+), 37 deletions(-) diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index d5f9de696d8..804e625f60c 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -5,27 +5,27 @@ set(SOURCE_FILES register_fprime_module() set(UT_SOURCE_FILES -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestRules.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestScenarios.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/SetTestRules.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/SetTestScenarios.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" ) set(UT_MOD_DEPS diff --git a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp index 49f12319b72..063b08472a9 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp @@ -130,7 +130,7 @@ TEST(ExternalArrayMapRules, Clear) { ASSERT_EQ(state.map.getSize(), 0); } -TEST(ExternalArraymapRules, Find) { +TEST(ExternalArrayMapRules, Find) { Entry entries[State::capacity]; Map map(entries, State::capacity); State state(map); diff --git a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp index 9f6967bf263..d4d89cf31c2 100644 --- a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp @@ -130,7 +130,7 @@ TEST(ExternalArraySetRules, Clear) { ASSERT_EQ(state.set.getSize(), 0); } -TEST(ExternalArraysetRules, Find) { +TEST(ExternalArraySetRules, Find) { Entry entries[State::capacity]; Set set(entries, State::capacity); State state(set); @@ -140,7 +140,6 @@ TEST(ExternalArraysetRules, Find) { Rules::find.apply(state); } -#if 0 TEST(ExternalArraySetRules, FindExisting) { Entry entries[State::capacity]; Set set(entries, State::capacity); @@ -148,7 +147,6 @@ TEST(ExternalArraySetRules, FindExisting) { Rules::insertNotFull.apply(state); Rules::findExisting.apply(state); } -#endif TEST(ExternalArraySetRules, InsertFull) { Entry entries[State::capacity]; diff --git a/Fw/DataStructures/test/ut/STest/SetTestRules.cpp b/Fw/DataStructures/test/ut/STest/SetTestRules.cpp index 93c5f24c861..921006c76ea 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/SetTestRules.cpp @@ -16,9 +16,7 @@ Clear clear; Find find; -#if 0 FindExisting findExisting; -#endif InsertFull insertFull; diff --git a/Fw/DataStructures/test/ut/STest/SetTestRules.hpp b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp index 60cbf80353d..2966670ddb0 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp @@ -40,7 +40,6 @@ struct Find : public Rule { } }; -#if 0 struct FindExisting : public Rule { FindExisting() : Rule("FindExisting") {} bool precondition(const State& state) { return static_cast(state.set.getSize()) > 0; } @@ -49,19 +48,15 @@ struct FindExisting : public Rule { const auto index = STest::Pick::startLength(0, static_cast(size)); const auto* it = state.set.getHeadIterator(); for (FwSizeType i = 0; i < index; i++) { - ASSERT_NE(it, nullptr); - it = it->getNextSetIterator(); + ASSERT_NE(it, nullptr); + const auto e = it->getElement(); + const auto status = state.set.find(e); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_TRUE(state.modelSetContains(e)); + it = it->getNextSetIterator(); } - ASSERT_NE(it, nullptr); - const auto e = it->getElement(); - const auto expectedValue = state.modelSet[e]; - State::ValueType value = 0; - const auto status = state.set.find(e, value); - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(value, expectedValue); } }; -#endif struct InsertFull : public Rule { InsertFull() : Rule("InsertFull") {} @@ -143,9 +138,7 @@ extern Clear clear; extern Find find; -#if 0 extern FindExisting findExisting; -#endif extern InsertFull insertFull; From 6f72cdf01665a435a951d47b00b1f8504bc947b4 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 6 Jul 2025 16:00:49 -0700 Subject: [PATCH 313/458] Revise ExternalArraySetTest --- Fw/DataStructures/CMakeLists.txt | 36 ++++++++--------- .../test/ut/ExternalArraySetTest.cpp | 2 +- .../test/ut/STest/SetTestRules.cpp | 2 +- .../test/ut/STest/SetTestRules.hpp | 39 ++++++++++++------- .../test/ut/STest/SetTestScenarios.cpp | 6 +-- 5 files changed, 48 insertions(+), 37 deletions(-) diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index 804e625f60c..d5f9de696d8 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -5,27 +5,27 @@ set(SOURCE_FILES register_fprime_module() set(UT_SOURCE_FILES - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestRules.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestScenarios.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestRules.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestScenarios.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/SetTestRules.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/SetTestScenarios.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" ) set(UT_MOD_DEPS diff --git a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp index d4d89cf31c2..b6455c69fb0 100644 --- a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp @@ -168,7 +168,6 @@ TEST(ExternalArraySetRules, InsertNotFull) { Rules::insertNotFull.apply(state); } -#if 0 TEST(ExternalArraySetRules, Remove) { Entry entries[State::capacity]; Set set(entries, State::capacity); @@ -179,6 +178,7 @@ TEST(ExternalArraySetRules, Remove) { Rules::remove.apply(state); } +#if 0 TEST(ExternalArraySetRules, RemoveExisting) { Entry entries[State::capacity]; Set set(entries, State::capacity); diff --git a/Fw/DataStructures/test/ut/STest/SetTestRules.cpp b/Fw/DataStructures/test/ut/STest/SetTestRules.cpp index 921006c76ea..c74b59254aa 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/SetTestRules.cpp @@ -22,9 +22,9 @@ InsertFull insertFull; InsertNotFull insertNotFull; -#if 0 Remove remove; +#if 0 RemoveExisting removeExisting; #endif diff --git a/Fw/DataStructures/test/ut/STest/SetTestRules.hpp b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp index 2966670ddb0..d1fb4e1a3a1 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp @@ -44,16 +44,29 @@ struct FindExisting : public Rule { FindExisting() : Rule("FindExisting") {} bool precondition(const State& state) { return static_cast(state.set.getSize()) > 0; } void action(State& state) { + // Check that sizes match const auto size = state.set.getSize(); - const auto index = STest::Pick::startLength(0, static_cast(size)); - const auto* it = state.set.getHeadIterator(); - for (FwSizeType i = 0; i < index; i++) { - ASSERT_NE(it, nullptr); - const auto e = it->getElement(); - const auto status = state.set.find(e); - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_TRUE(state.modelSetContains(e)); - it = it->getNextSetIterator(); + const auto modelSize = state.modelSet.size(); + ASSERT_EQ(size, modelSize); + // Check that all elements of set are in modelSet + { + const auto* it = state.set.getHeadIterator(); + for (FwSizeType i = 0; i < size; i++) { + ASSERT_NE(it, nullptr); + const auto e = it->getElement(); + ASSERT_TRUE(state.modelSetContains(e)); + it = it->getNextSetIterator(); + } + } + // Check that all elements of modelSet are in set + { + auto it = state.modelSet.begin(); + for (FwSizeType i = 0; i < modelSize; i++) { + ASSERT_NE(it, state.modelSet.end()); + const auto status = state.set.find(*it); + ASSERT_EQ(status, Success::SUCCESS); + it++; + } } } }; @@ -85,7 +98,6 @@ struct InsertNotFull : public Rule { } }; -#if 0 struct Remove : public Rule { Remove() : Rule("Remove") {} bool precondition(const State& state) { return true; } @@ -93,11 +105,9 @@ struct Remove : public Rule { const auto size = state.set.getSize(); ASSERT_EQ(size, state.modelSet.size()); const auto e = state.getElement(); - State::ValueType value = 0; - const auto status = state.set.remove(e, value); + const auto status = state.set.remove(e); if (state.modelSetContains(e)) { ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(value, state.modelSet[e]); ASSERT_EQ(state.set.getSize(), size - 1); } else { @@ -109,6 +119,7 @@ struct Remove : public Rule { } }; +#if 0 struct RemoveExisting : public Rule { RemoveExisting() : Rule("RemoveExisting") {} bool precondition(const State& state) { return static_cast(state.set.getSize()) > 0; } @@ -144,9 +155,9 @@ extern InsertFull insertFull; extern InsertNotFull insertNotFull; -#if 0 extern Remove remove; +#if 0 extern RemoveExisting removeExisting; #endif diff --git a/Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp index 3256bfda3b1..07ec0e5ba91 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp +++ b/Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp @@ -19,9 +19,9 @@ void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { Rule* rules[] = { &Rules::clear, &Rules::find, - //&Rules::findExisting, - &Rules::insertFull, &Rules::insertNotFull - //&Rules::remove, + &Rules::findExisting, + &Rules::insertFull, &Rules::insertNotFull, + &Rules::remove //&Rules::removeExisting }; STest::RandomScenario scenario("RandomScenario", rules, From 0f2ea2b967cd20e378365aa66c513059d4b29696 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 6 Jul 2025 16:03:00 -0700 Subject: [PATCH 314/458] Revise ExternalArraySetTest --- .../test/ut/ExternalArraySetTest.cpp | 2 - .../test/ut/STest/SetTestRules.cpp | 2 - .../test/ut/STest/SetTestRules.hpp | 46 ++++++++----------- .../test/ut/STest/SetTestScenarios.cpp | 4 +- 4 files changed, 21 insertions(+), 33 deletions(-) diff --git a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp index b6455c69fb0..807fee998b6 100644 --- a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp @@ -178,7 +178,6 @@ TEST(ExternalArraySetRules, Remove) { Rules::remove.apply(state); } -#if 0 TEST(ExternalArraySetRules, RemoveExisting) { Entry entries[State::capacity]; Set set(entries, State::capacity); @@ -186,7 +185,6 @@ TEST(ExternalArraySetRules, RemoveExisting) { Rules::insertNotFull.apply(state); Rules::removeExisting.apply(state); } -#endif TEST(ExternalArraySetScenarios, Random) { Entry entries[State::capacity]; diff --git a/Fw/DataStructures/test/ut/STest/SetTestRules.cpp b/Fw/DataStructures/test/ut/STest/SetTestRules.cpp index c74b59254aa..eb53aa70b1b 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/SetTestRules.cpp @@ -24,9 +24,7 @@ InsertNotFull insertNotFull; Remove remove; -#if 0 RemoveExisting removeExisting; -#endif }; // namespace Rules diff --git a/Fw/DataStructures/test/ut/STest/SetTestRules.hpp b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp index d1fb4e1a3a1..c1467bed456 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp @@ -50,23 +50,23 @@ struct FindExisting : public Rule { ASSERT_EQ(size, modelSize); // Check that all elements of set are in modelSet { - const auto* it = state.set.getHeadIterator(); - for (FwSizeType i = 0; i < size; i++) { - ASSERT_NE(it, nullptr); - const auto e = it->getElement(); - ASSERT_TRUE(state.modelSetContains(e)); - it = it->getNextSetIterator(); - } + const auto* it = state.set.getHeadIterator(); + for (FwSizeType i = 0; i < size; i++) { + ASSERT_NE(it, nullptr); + const auto e = it->getElement(); + ASSERT_TRUE(state.modelSetContains(e)); + it = it->getNextSetIterator(); + } } // Check that all elements of modelSet are in set { - auto it = state.modelSet.begin(); - for (FwSizeType i = 0; i < modelSize; i++) { - ASSERT_NE(it, state.modelSet.end()); - const auto status = state.set.find(*it); - ASSERT_EQ(status, Success::SUCCESS); - it++; - } + auto it = state.modelSet.begin(); + for (FwSizeType i = 0; i < modelSize; i++) { + ASSERT_NE(it, state.modelSet.end()); + const auto status = state.set.find(*it); + ASSERT_EQ(status, Success::SUCCESS); + it++; + } } } }; @@ -109,17 +109,15 @@ struct Remove : public Rule { if (state.modelSetContains(e)) { ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(state.set.getSize(), size - 1); - } - else { + } else { ASSERT_EQ(status, Success::FAILURE); ASSERT_EQ(state.set.getSize(), size); } - (void) state.modelSet.erase(e); + (void)state.modelSet.erase(e); ASSERT_EQ(state.set.getSize(), state.modelSet.size()); } }; -#if 0 struct RemoveExisting : public Rule { RemoveExisting() : Rule("RemoveExisting") {} bool precondition(const State& state) { return static_cast(state.set.getSize()) > 0; } @@ -128,22 +126,18 @@ struct RemoveExisting : public Rule { const auto index = STest::Pick::startLength(0, static_cast(size)); const auto* it = state.set.getHeadIterator(); for (FwSizeType i = 0; i < index; i++) { - ASSERT_NE(it, nullptr); - it = it->getNextSetIterator(); + ASSERT_NE(it, nullptr); + it = it->getNextSetIterator(); } ASSERT_NE(it, nullptr); const auto e = it->getElement(); - const auto expectedValue = state.modelSet[e]; - State::ValueType value = 0; - const auto status = state.set.remove(e, value); + const auto status = state.set.remove(e); ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(value, expectedValue); const auto n = state.modelSet.erase(e); ASSERT_EQ(n, 1); ASSERT_EQ(state.set.getSize(), state.modelSet.size()); } }; -#endif extern Clear clear; @@ -157,9 +151,7 @@ extern InsertNotFull insertNotFull; extern Remove remove; -#if 0 extern RemoveExisting removeExisting; -#endif }; // namespace Rules diff --git a/Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp index 07ec0e5ba91..7558184ad53 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp +++ b/Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp @@ -21,8 +21,8 @@ void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { &Rules::find, &Rules::findExisting, &Rules::insertFull, &Rules::insertNotFull, - &Rules::remove - //&Rules::removeExisting + &Rules::remove, + &Rules::removeExisting }; STest::RandomScenario scenario("RandomScenario", rules, sizeof(rules) / sizeof(STest::RandomScenario*)); From 7d5fd72cecb8ab3473791f348238eaf644972f1b Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 6 Jul 2025 16:08:11 -0700 Subject: [PATCH 315/458] Revise ExternalArraySetTest and ExternalArrayMapTest --- Fw/DataStructures/CMakeLists.txt | 36 +++++++++---------- .../test/ut/ExternalArrayMapTest.cpp | 2 +- .../test/ut/ExternalArraySetTest.cpp | 4 +-- 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index d5f9de696d8..804e625f60c 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -5,27 +5,27 @@ set(SOURCE_FILES register_fprime_module() set(UT_SOURCE_FILES -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestRules.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestScenarios.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/SetTestRules.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/SetTestScenarios.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" ) set(UT_MOD_DEPS diff --git a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp index 063b08472a9..e38e913b121 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp @@ -97,7 +97,7 @@ TEST(ExternalArrayMap, CopyAssignmentOperator) { ASSERT_EQ(map2.getSize(), 1); } -TEST(ExternalFifoQueue, CopyDataFrom) { +TEST(ExternalArrayMap, CopyDataFrom) { constexpr FwSizeType maxSize = 10; constexpr FwSizeType smallSize = maxSize / 2; Entry entries1[maxSize]; diff --git a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp index 807fee998b6..c2dad186de6 100644 --- a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp @@ -95,8 +95,7 @@ TEST(ExternalArraySet, CopyAssignmentOperator) { ASSERT_EQ(set2.getSize(), 1); } -#if 0 -TEST(ExternalFifoQueue, CopyDataFrom) { +TEST(ExternalArraySet, CopyDataFrom) { constexpr FwSizeType maxSize = 10; constexpr FwSizeType smallSize = maxSize / 2; Entry entries1[maxSize]; @@ -118,7 +117,6 @@ TEST(ExternalFifoQueue, CopyDataFrom) { State::testCopyDataFrom(m1, maxSize, m2); } } -#endif TEST(ExternalArraySetRules, Clear) { Entry entries[State::capacity]; From d5cac21f0f2497b103afc9b99612a093323e5027 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 6 Jul 2025 16:20:40 -0700 Subject: [PATCH 316/458] Revise ArraySetOrMapImplTest --- .../test/ut/ArraySetOrMapImplTest.cpp | 8 +++++++ .../ut/STest/ArraySetOrMapImplTestRules.cpp | 2 ++ .../ut/STest/ArraySetOrMapImplTestRules.hpp | 23 +++++++++++++++++++ .../STest/ArraySetOrMapImplTestScenarios.cpp | 1 + 4 files changed, 34 insertions(+) diff --git a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp index 80b63b7ede2..ad4c4640e60 100644 --- a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp +++ b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp @@ -106,6 +106,14 @@ TEST(ArraySetOrMapImplRules, FindExisting) { Rules::findExisting.apply(state); } +TEST(ArraySetOrMapImplRules, InsertExisting) { + State::Entry entries[State::capacity]; + State::Impl impl(entries, State::capacity); + State state(impl); + Rules::insertNotFull.apply(state); + Rules::insertExisting.apply(state); +} + TEST(ArraySetOrMapImplRules, InsertFull) { State::Entry entries[State::capacity]; State::Impl impl(entries, State::capacity); diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp index 2d12b0529ca..cb56eea1ee7 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp @@ -18,6 +18,8 @@ Find find; FindExisting findExisting; +InsertExisting insertExisting; + InsertFull insertFull; InsertNotFull insertNotFull; diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp index e2398205c98..bebdd45c877 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp @@ -68,6 +68,27 @@ struct FindExisting : public Rule { } }; +struct InsertExisting : public Rule { + InsertExisting() : Rule("InsertExisting") {} + bool precondition(const State& state) { return static_cast(state.impl.getSize()) > 0; } + void action(State& state) { + const auto size = state.impl.getSize(); + const auto index = STest::Pick::startLength(0, static_cast(size)); + const auto* it = state.impl.getHeadIterator(); + for (FwSizeType i = 0; i < index; i++) { + ASSERT_NE(it, nullptr); + it = it->getNextIterator(); + } + ASSERT_NE(it, nullptr); + const auto key = it->getKey(); + const auto value = state.getValue(); + const auto status = state.impl.insert(key, value); + ASSERT_EQ(status, Success::SUCCESS); + state.modelMap[key] = value; + ASSERT_EQ(state.impl.getSize(), size); + } +}; + struct InsertFull : public Rule { InsertFull() : Rule("InsertFull") {} bool precondition(const State& state) { return static_cast(state.impl.getSize()) >= State::capacity; } @@ -149,6 +170,8 @@ extern Find find; extern FindExisting findExisting; +extern InsertExisting insertExisting; + extern InsertFull insertFull; extern InsertNotFull insertNotFull; diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp index 2d2e962f499..9d5a7e91d5e 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp @@ -20,6 +20,7 @@ void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { &Rules::clear, &Rules::find, &Rules::findExisting, + &Rules::insertExisting, &Rules::insertFull, &Rules::insertNotFull, &Rules::remove, From 322980985d6d4c9be591f33a4af6774176ffc5a9 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 6 Jul 2025 16:53:17 -0700 Subject: [PATCH 317/458] Revise ExternalArrayMapTest --- .../test/ut/ExternalArrayMapTest.cpp | 8 +++++++ .../test/ut/STest/MapTestRules.cpp | 2 ++ .../test/ut/STest/MapTestRules.hpp | 23 +++++++++++++++++++ .../test/ut/STest/MapTestScenarios.cpp | 1 + 4 files changed, 34 insertions(+) diff --git a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp index e38e913b121..338b7ffa301 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp @@ -148,6 +148,14 @@ TEST(ExternalArrayMapRules, FindExisting) { Rules::findExisting.apply(state); } +TEST(ExternalArrayMapRules, InsertExisting) { + Entry entries[State::capacity]; + Map map(entries, State::capacity); + State state(map); + Rules::insertNotFull.apply(state); + Rules::insertExisting.apply(state); +} + TEST(ExternalArrayMapRules, InsertFull) { Entry entries[State::capacity]; Map map(entries, State::capacity); diff --git a/Fw/DataStructures/test/ut/STest/MapTestRules.cpp b/Fw/DataStructures/test/ut/STest/MapTestRules.cpp index b9356a86b2c..10a139b83a1 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/MapTestRules.cpp @@ -18,6 +18,8 @@ Find find; FindExisting findExisting; +InsertExisting insertExisting; + InsertFull insertFull; InsertNotFull insertNotFull; diff --git a/Fw/DataStructures/test/ut/STest/MapTestRules.hpp b/Fw/DataStructures/test/ut/STest/MapTestRules.hpp index f509db43d6c..783dbb488a0 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/MapTestRules.hpp @@ -68,6 +68,27 @@ struct FindExisting : public Rule { } }; +struct InsertExisting : public Rule { + InsertExisting() : Rule("InsertExisting") {} + bool precondition(const State& state) { return static_cast(state.map.getSize()) > 0; } + void action(State& state) { + const auto size = state.map.getSize(); + const auto index = STest::Pick::startLength(0, static_cast(size)); + const auto* it = state.map.getHeadIterator(); + for (FwSizeType i = 0; i < index; i++) { + ASSERT_NE(it, nullptr); + it = it->getNextMapIterator(); + } + ASSERT_NE(it, nullptr); + const auto key = it->getKey(); + const auto value = state.getValue(); + const auto status = state.map.insert(key, value); + ASSERT_EQ(status, Success::SUCCESS); + state.modelMap[key] = value; + ASSERT_EQ(state.map.getSize(), size); + } +}; + struct InsertFull : public Rule { InsertFull() : Rule("InsertFull") {} bool precondition(const State& state) { return static_cast(state.map.getSize()) >= State::capacity; } @@ -150,6 +171,8 @@ extern Find find; extern FindExisting findExisting; +extern InsertExisting insertExisting; + extern InsertFull insertFull; extern InsertNotFull insertNotFull; diff --git a/Fw/DataStructures/test/ut/STest/MapTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/MapTestScenarios.cpp index ef0cc406f87..c902f5323a5 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestScenarios.cpp +++ b/Fw/DataStructures/test/ut/STest/MapTestScenarios.cpp @@ -20,6 +20,7 @@ void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { &Rules::clear, &Rules::find, &Rules::findExisting, + &Rules::insertExisting, &Rules::insertFull, &Rules::insertNotFull, &Rules::remove, From 036000a4e75afa833e39e80fd261809b6cdd7341 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 6 Jul 2025 16:58:27 -0700 Subject: [PATCH 318/458] Revise ExternalArraySetTest --- .../test/ut/ExternalArraySetTest.cpp | 8 +++++++ .../test/ut/STest/SetTestRules.cpp | 2 ++ .../test/ut/STest/SetTestRules.hpp | 21 +++++++++++++++++++ .../test/ut/STest/SetTestScenarios.cpp | 4 +++- 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp index c2dad186de6..23591664095 100644 --- a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp @@ -146,6 +146,14 @@ TEST(ExternalArraySetRules, FindExisting) { Rules::findExisting.apply(state); } +TEST(ExternalArraySetRules, InsertExisting) { + Entry entries[State::capacity]; + Set set(entries, State::capacity); + State state(set); + Rules::insertNotFull.apply(state); + Rules::insertExisting.apply(state); +} + TEST(ExternalArraySetRules, InsertFull) { Entry entries[State::capacity]; Set set(entries, State::capacity); diff --git a/Fw/DataStructures/test/ut/STest/SetTestRules.cpp b/Fw/DataStructures/test/ut/STest/SetTestRules.cpp index eb53aa70b1b..13429099ace 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/SetTestRules.cpp @@ -18,6 +18,8 @@ Find find; FindExisting findExisting; +InsertExisting insertExisting; + InsertFull insertFull; InsertNotFull insertNotFull; diff --git a/Fw/DataStructures/test/ut/STest/SetTestRules.hpp b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp index c1467bed456..f43d32dcaa2 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp @@ -71,6 +71,25 @@ struct FindExisting : public Rule { } }; +struct InsertExisting : public Rule { + InsertExisting() : Rule("InsertExisting") {} + bool precondition(const State& state) { return static_cast(state.set.getSize()) > 0; } + void action(State& state) { + const auto size = state.set.getSize(); + const auto index = STest::Pick::startLength(0, static_cast(size)); + const auto* it = state.set.getHeadIterator(); + for (FwSizeType i = 0; i < index; i++) { + ASSERT_NE(it, nullptr); + it = it->getNextSetIterator(); + } + ASSERT_NE(it, nullptr); + const auto e = it->getElement(); + const auto status = state.set.insert(e); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(state.set.getSize(), size); + } +}; + struct InsertFull : public Rule { InsertFull() : Rule("InsertFull") {} bool precondition(const State& state) { return static_cast(state.set.getSize()) >= State::capacity; } @@ -145,6 +164,8 @@ extern Find find; extern FindExisting findExisting; +extern InsertExisting insertExisting; + extern InsertFull insertFull; extern InsertNotFull insertNotFull; diff --git a/Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp index 7558184ad53..48cf6fd3366 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp +++ b/Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp @@ -20,7 +20,9 @@ void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { &Rules::clear, &Rules::find, &Rules::findExisting, - &Rules::insertFull, &Rules::insertNotFull, + &Rules::insertExisting, + &Rules::insertFull, + &Rules::insertNotFull, &Rules::remove, &Rules::removeExisting }; From 920d3b4fb6a79193c4979249e900c24b84b4d289 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 7 Jul 2025 17:28:21 -0700 Subject: [PATCH 319/458] Revise SDD for ArrayMap --- Fw/DataStructures/docs/ArrayMap.md | 195 ++++++++++++++++++++- Fw/DataStructures/docs/ExternalArrayMap.md | 6 +- Fw/DataStructures/docs/FifoQueue.md | 8 +- 3 files changed, 203 insertions(+), 6 deletions(-) diff --git a/Fw/DataStructures/docs/ArrayMap.md b/Fw/DataStructures/docs/ArrayMap.md index e6fbbbd654a..f772cdcb8df 100644 --- a/Fw/DataStructures/docs/ArrayMap.md +++ b/Fw/DataStructures/docs/ArrayMap.md @@ -1,4 +1,197 @@ # ArrayMap -TODO +`ArrayMap` is a `final` class template +defined in [`Fw/DataStructures`](sdd.md). +It represents an array-based map with internal storage. +## 1. Template Parameters + +`ArrayMap` has the following template parameters. + +|Kind|Name|Purpose| +|----|----|-------| +|`typename`|`K`|The type of a key in the map| +|`typename`|`V`|The type of a value in the map| +|`FwSizeType`|`C`|The capacity, i.e., the maximum number of keys that the map can store| + +`ArrayMap` statically asserts that `C > 0`. + +## 2. Base Class + +`ArrayMap` is publicly derived from +[`MapBase`](MapBase.md). + + +## 3. Public Types + +`ArrayMap` defines the following public types: + +|Name|Definition| +|----|----------| +|`Entry`|Alias of [`SetOrMapIterator`](SetOrMapIterator.md)| +|`Iterator`|Alias of [`MapIterator`](MapIterator.md)| + +## 4. Private Member Variables + +`ArrayMap` has the following private member variables. + +|Name|Type|Purpose|Default Value| +|----|----|-------|-------------| +|`m_extMap`|[`ExternalArrayMap`](ExternalArrayMap.md)|The external map implementation|C++ default initialization| +|`m_entries`|`Entry[C]`|The array providing the backing memory for `m_extMap`|C++ default initialization| + +The type `Entry` is defined [here](ArrayMap.md#Public-Types). + +```mermaid +classDiagram + ArrayMap *-- ExternalArrayMap +``` + +## 5. Public Constructors and Destructors + +### 5.1. Zero-Argument Constructor + +```c++ +ArrayMap() +``` + +Initialize each member variable with its default value. + +_Example:_ +```c++ +ArrayMap map; +``` + +### 5.2. Copy Constructor + +```c++ +ArrayMap(const ArrayMap& map) +``` + +Set `*this = map`. + +_Example:_ +```c++ +ArrayMap m1(entries, capacity); +// Insert an item +const U16 key = 0; +const U32 value = 42; +const auto status = m1.insert(key, value); +ASSERT_EQ(status, Success::SUCCESS); +// Call the copy constructor +ArrayMap m2(m1); +ASSERT_EQ(m2.getSize(), 1); +``` + +### 5.3. Destructor + +```c++ +~ArrayMap() override +``` + +Defined as `= default`. + +## 6. Public Member Functions + +### 6.1. operator= + +```c++ +ArrayMap& operator=(const ArrayMap& map) +``` + +Return `m_extMap.copyDataFrom(map)`. + +_Example:_ +```c++ +ArrayMap m1(entries, capacity); +// Insert an item +U16 key = 0; +U32 value = 42; +const auto status = m1.insert(key, value); +ASSERT_EQ(status, Success::SUCCESS); +// Call the default constructor +ArrayMap m2; +ASSERT_EQ(m2.getSize(), 0); +// Call the copy assignment operator +m2 = m1; +ASSERT_EQ(m2.getSize(), 1); +value = 0; +status = m2.find(key, value); +ASSERT_EQ(status, Success::SUCCESS); +ASSERT_EQ(value, 42); +``` + +### 6.2. clear + +```c++ +void clear() override +``` + +Call `m_extMap.clear()`. + +### 6.3. find + +```c++ +Success find(const K& key, V& value) override +``` + +Return `m_extMap.find(key, value)`. + +### 6.4. getCapacity + +```c++ +FwSizeType getCapacity() const override +``` + +Return `m_extMap.getCapacity()`. + +### 6.5. getHeadIterator + +```c++ +const Iterator* getHeadIterator const override +``` + +The type `Iterator` is defined [here](ArrayMap.md#Public-Types). + +Return `m_extMap.getHeadIterator()`. + +### 6.6. getSize + +```c++ +FwSizeType getSize() const override +``` + +Return `m_extMap.getSize()`. + +### 6.7. insert + +```c++ +Success insert(const K& key, const V& value) override +``` + +Return `m_extMap.insert(key, value)`. + +### 6.8. remove + +```c++ +Success remove(const K& key, V& value) override +``` + +Return `m_extMap.remove(key, value)`. + +## 7. Public Static Functions + +### 7.1. getStaticCapacity + +```c++ +static constexpr FwSizeType getStaticCapacity() +``` + +Return the static capacity `C`. + +_Example:_ +```c++ +using Map = ArrayMap; +const auto capacity = Map::getStaticCapacity(); +ASSERT_EQ(capacity, 3); +``` diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index 52f8e62799d..85b2daff9df 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -152,7 +152,7 @@ ExternalArrayMap m1(entries, capacity); // Insert an item U16 key = 0; U32 value = 42; -const auto status = m1.insert(value); +const auto status = m1.insert(key, value); ASSERT_EQ(status, Success::SUCCESS); // Call the default constructor ExternalArrayMap m2; @@ -160,6 +160,10 @@ ASSERT_EQ(m2.getSize(), 0); // Call the copy assignment operator m2 = m1; ASSERT_EQ(m2.getSize(), 1); +value = 0; +status = m2.find(key, value); +ASSERT_EQ(status, Success::SUCCESS); +ASSERT_EQ(value, 42); ``` ### 6.2. clear diff --git a/Fw/DataStructures/docs/FifoQueue.md b/Fw/DataStructures/docs/FifoQueue.md index 4505fdabb56..51e0e7f0afa 100644 --- a/Fw/DataStructures/docs/FifoQueue.md +++ b/Fw/DataStructures/docs/FifoQueue.md @@ -17,7 +17,7 @@ It represents a FIFO queue with internal storage. ## 2. Base Class -`FifoQueue` is publicly derived from +`FifoQueue` is publicly derived from [`FifoQueueBase`](FifoQueueBase.md). ## 3. Private Member Variables @@ -52,7 +52,7 @@ FifoQueue queue; ### 4.2. Copy Constructor ```c++ -FifoQueue(const FifoQueue& queue) +FifoQueue(const FifoQueue& queue) ``` Set `*this = queue`. @@ -83,10 +83,10 @@ Defined as `= default`. ### 5.1. operator= ```c++ -FifoQueue& operator=(const FifoQueue& queue) +FifoQueue& operator=(const FifoQueue& queue) ``` -Call `m_extQueue.copyDataFrom(queue)`. +Return `m_extQueue.copyDataFrom(queue)`. _Example:_ ```c++ From f0ed5b7f0189eb8d1547a6131e7fb1dd0c2e4fa3 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 7 Jul 2025 17:49:44 -0700 Subject: [PATCH 320/458] Revise SDD for ArraySet --- Fw/DataStructures/docs/ArraySet.md | 192 ++++++++++++++++++++- Fw/DataStructures/docs/ExternalArraySet.md | 2 + 2 files changed, 193 insertions(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/ArraySet.md b/Fw/DataStructures/docs/ArraySet.md index e0b4e7ee1c0..eb26ef4b3e7 100644 --- a/Fw/DataStructures/docs/ArraySet.md +++ b/Fw/DataStructures/docs/ArraySet.md @@ -1,4 +1,194 @@ # ArraySet -TODO +`ArraySet` is a `final` class template +defined in [`Fw/DataStructures`](sdd.md). +It represents an array-based set with internal storage. +## 1. Template Parameters + +`ArraySet` has the following template parameters. + +|Kind|Name|Purpose| +|----|----|-------| +|`typename`|`T`|The type of an element in the set| +|`FwSizeType`|`C`|The capacity, i.e., the maximum number of elements that the set can store| + +`ArraySet` statically asserts that `C > 0`. + +## 2. Base Class + +`ArraySet` is publicly derived from +[`SetBase`](SetBase.md). + + +## 3. Public Types + +`ArraySet` defines the following public types: + +|Name|Definition| +|----|----------| +|`Entry`|Alias of [`SetOrMapIterator`](SetOrMapIterator.md)| +|`Iterator`|Alias of [`MapIterator`](MapIterator.md)| + +The type `Nil` is defined [here](Nil.md). + +## 4. Private Member Variables + +`ArraySet` has the following private member variables. + +|Name|Type|Purpose|Default Value| +|----|----|-------|-------------| +|`m_extSet`|[`ExternalArraySet`](ExternalArraySet.md)|The external set implementation|C++ default initialization| +|`m_entries`|`Entry[C]`|The array providing the backing memory for `m_extSet`|C++ default initialization| + +The type `Entry` is defined [here](ArraySet.md#Public-Types). + +```mermaid +classDiagram + ArraySet *-- ExternalArraySet +``` + +## 5. Public Constructors and Destructors + +### 5.1. Zero-Argument Constructor + +```c++ +ArraySet() +``` + +Initialize each member variable with its default value. + +_Example:_ +```c++ +ArraySet set; +``` + +### 5.2. Copy Constructor + +```c++ +ArraySet(const ArraySet& set) +``` + +Set `*this = set`. + +_Example:_ +```c++ +ArraySet m1(entries, capacity); +// Insert an item +const U32 element = 42; +const auto status = m1.insert(element); +ASSERT_EQ(status, Success::SUCCESS); +// Call the copy constructor +ArraySet m2(m1); +ASSERT_EQ(m2.getSize(), 1); +``` + +### 5.3. Destructor + +```c++ +~ArraySet() override +``` + +Defined as `= default`. + +## 6. Public Member Functions + +### 6.1. operator= + +```c++ +ArraySet& operator=(const ArraySet& set) +``` + +Return `m_extSet.copyDataFrom(set)`. + +_Example:_ +```c++ +ArraySet m1(entries, capacity); +// Insert an item +U32 element = 42; +const auto status = m1.insert(element, value); +ASSERT_EQ(status, Success::SUCCESS); +// Call the default constructor +ArraySet m2; +ASSERT_EQ(m2.getSize(), 0); +// Call the copy assignment operator +m2 = m1; +ASSERT_EQ(m2.getSize(), 1); +status = m2.find(element); +ASSERT_EQ(status, Success::SUCCESS); +``` + +### 6.2. clear + +```c++ +void clear() override +``` + +Call `m_extSet.clear()`. + +### 6.3. find + +```c++ +Success find(const K& element, V& value) override +``` + +Return `m_extSet.find(element, value)`. + +### 6.4. getCapacity + +```c++ +FwSizeType getCapacity() const override +``` + +Return `m_extSet.getCapacity()`. + +### 6.5. getHeadIterator + +```c++ +const Iterator* getHeadIterator const override +``` + +The type `Iterator` is defined [here](ArraySet.md#Public-Types). + +Return `m_extSet.getHeadIterator()`. + +### 6.6. getSize + +```c++ +FwSizeType getSize() const override +``` + +Return `m_extSet.getSize()`. + +### 6.7. insert + +```c++ +Success insert(const T& element) override +``` + +Return `m_extSet.insert(element)`. + +### 6.8. remove + +```c++ +Success remove(const T& element) override +``` + +Return `m_extSet.remove(element)`. + +## 7. Public Static Functions + +### 7.1. getStaticCapacity + +```c++ +static constexpr FwSizeType getStaticCapacity() +``` + +Return the static capacity `C`. + +_Example:_ +```c++ +using Set = ArraySet; +const auto capacity = Set::getStaticCapacity(); +ASSERT_EQ(capacity, 3); +``` diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md index e032b67b31f..efc6cb0bea5 100644 --- a/Fw/DataStructures/docs/ExternalArraySet.md +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -29,6 +29,8 @@ as the set implementation. |`Entry`|Alias of [`SetOrMapIterator`](SetOrMapIterator.md)| |`Iterator`|Alias of [`SetIterator`](SetIterator.md)| +The type `Nil` is defined [here](Nil.md). + ## 4. Private Member Variables `ExternalArraySet` has the following private member variables. From c963008a9c5ae608fa66aa9d55cb8ad634f67e6a Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 7 Jul 2025 17:50:38 -0700 Subject: [PATCH 321/458] Revise SDD for ArraySet --- Fw/DataStructures/docs/ArraySet.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/ArraySet.md b/Fw/DataStructures/docs/ArraySet.md index eb26ef4b3e7..1acd7c847c3 100644 --- a/Fw/DataStructures/docs/ArraySet.md +++ b/Fw/DataStructures/docs/ArraySet.md @@ -28,7 +28,7 @@ It represents an array-based set with internal storage. |Name|Definition| |----|----------| |`Entry`|Alias of [`SetOrMapIterator`](SetOrMapIterator.md)| -|`Iterator`|Alias of [`MapIterator`](MapIterator.md)| +|`Iterator`|Alias of [`SetIterator`](SetIterator.md)| The type `Nil` is defined [here](Nil.md). From 1942f6b6bed3c52d83740c28703f2a5b38a765f7 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 7 Jul 2025 18:09:17 -0700 Subject: [PATCH 322/458] Add ArrayMap --- Fw/DataStructures/CMakeLists.txt | 1 + Fw/DataStructures/docs/ArrayMap.md | 17 ----------------- .../test/ut/ExternalArrayMapTest.cpp | 4 +--- 3 files changed, 2 insertions(+), 20 deletions(-) diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index 804e625f60c..d478bfc9bea 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -5,6 +5,7 @@ set(SOURCE_FILES register_fprime_module() set(UT_SOURCE_FILES + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayMapTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" diff --git a/Fw/DataStructures/docs/ArrayMap.md b/Fw/DataStructures/docs/ArrayMap.md index f772cdcb8df..fcab56cafa2 100644 --- a/Fw/DataStructures/docs/ArrayMap.md +++ b/Fw/DataStructures/docs/ArrayMap.md @@ -178,20 +178,3 @@ Success remove(const K& key, V& value) override ``` Return `m_extMap.remove(key, value)`. - -## 7. Public Static Functions - -### 7.1. getStaticCapacity - -```c++ -static constexpr FwSizeType getStaticCapacity() -``` - -Return the static capacity `C`. - -_Example:_ -```c++ -using Map = ArrayMap; -const auto capacity = Map::getStaticCapacity(); -ASSERT_EQ(capacity, 3); -``` diff --git a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp index 338b7ffa301..cc5f81bff34 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp @@ -4,13 +4,11 @@ // \brief cpp file for ExternalArrayMap tests // ====================================================================== -#include "Fw/DataStructures/ExternalArrayMap.hpp" -#include "STest/STest/Pick/Pick.hpp" - #include "Fw/DataStructures/ExternalArrayMap.hpp" #include "Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp" #include "Fw/DataStructures/test/ut/STest/MapTestRules.hpp" #include "Fw/DataStructures/test/ut/STest/MapTestScenarios.hpp" +#include "STest/STest/Pick/Pick.hpp" namespace Fw { From 41b914f9ce1633a831ac8dbbf90690493b3a620b Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 7 Jul 2025 21:44:05 -0700 Subject: [PATCH 323/458] Revise ArrayMapTest --- Fw/DataStructures/CMakeLists.txt | 38 ++--- Fw/DataStructures/docs/ArrayMap.md | 13 +- Fw/DataStructures/docs/FifoQueue.md | 4 +- Fw/DataStructures/test/ut/ArrayMapTest.cpp | 168 +++++++++++++++++++++ 4 files changed, 198 insertions(+), 25 deletions(-) create mode 100644 Fw/DataStructures/test/ut/ArrayMapTest.cpp diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index d478bfc9bea..ec849c19ff6 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -6,27 +6,27 @@ register_fprime_module() set(UT_SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayMapTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestRules.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestScenarios.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/SetTestRules.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/SetTestScenarios.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/SetTestRules.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/SetTestScenarios.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" ) set(UT_MOD_DEPS diff --git a/Fw/DataStructures/docs/ArrayMap.md b/Fw/DataStructures/docs/ArrayMap.md index fcab56cafa2..6daef0d2e42 100644 --- a/Fw/DataStructures/docs/ArrayMap.md +++ b/Fw/DataStructures/docs/ArrayMap.md @@ -55,7 +55,7 @@ classDiagram ArrayMap() ``` -Initialize each member variable with its default value. +Initialize `m_extMap` with `ExternalArrayMap(m_entries, C)`. _Example:_ ```c++ @@ -68,7 +68,9 @@ ArrayMap map; ArrayMap(const ArrayMap& map) ``` -Set `*this = map`. +1. Initialize `m_extMap` with `ExternalArrayMap(m_entries, C)`. + +1. Set `*this = map`. _Example:_ ```c++ @@ -103,14 +105,15 @@ Return `m_extMap.copyDataFrom(map)`. _Example:_ ```c++ -ArrayMap m1(entries, capacity); +using Map = ArrayMap; +Map m1; // Insert an item U16 key = 0; U32 value = 42; -const auto status = m1.insert(key, value); +auto status = m1.insert(key, value); ASSERT_EQ(status, Success::SUCCESS); // Call the default constructor -ArrayMap m2; +Map m2; ASSERT_EQ(m2.getSize(), 0); // Call the copy assignment operator m2 = m1; diff --git a/Fw/DataStructures/docs/FifoQueue.md b/Fw/DataStructures/docs/FifoQueue.md index 51e0e7f0afa..4e945b95e08 100644 --- a/Fw/DataStructures/docs/FifoQueue.md +++ b/Fw/DataStructures/docs/FifoQueue.md @@ -55,7 +55,9 @@ FifoQueue queue; FifoQueue(const FifoQueue& queue) ``` -Set `*this = queue`. +1. Initialize `m_extQueue` with `ExternalFifoQueue(m_items, C)`. + +1. Set `*this = queue`. _Example:_ ```c++ diff --git a/Fw/DataStructures/test/ut/ArrayMapTest.cpp b/Fw/DataStructures/test/ut/ArrayMapTest.cpp new file mode 100644 index 00000000000..1d4d5d38866 --- /dev/null +++ b/Fw/DataStructures/test/ut/ArrayMapTest.cpp @@ -0,0 +1,168 @@ +// ====================================================================== +// \title ArrayMapTest.cpp +// \author bocchino +// \brief cpp file for ArrayMap tests +// ====================================================================== + +#include "Fw/DataStructures/ArrayMap.hpp" +#include "STest/STest/Pick/Pick.hpp" + +#include "Fw/DataStructures/ArrayMap.hpp" +#include "Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp" +#include "Fw/DataStructures/test/ut/STest/MapTestRules.hpp" +#include "Fw/DataStructures/test/ut/STest/MapTestScenarios.hpp" + +namespace Fw { + +template +class ArrayMapTester { + public: + ArrayMapTester(const ArrayMap& map) : m_map(map) {} + + const ExternalArrayMap getExtMap() const { return this->m_map.extMap; } + + const typename ArrayMap::Entries& getEntries() const { return this->m_map.m_entries; } + + private: + const ArrayMap& m_map; +}; + +namespace MapTest { + +using Entry = SetOrMapIterator; +using Map = ArrayMap; +using MapTester = ArrayMapTester; +using ImplTester = ArraySetOrMapImplTester; + +TEST(ArrayMap, ZeroArgConstructor) { + Map map; + ASSERT_EQ(map.getCapacity(), FwSizeType(State::capacity)); + ASSERT_EQ(map.getSize(), 0); +} + +TEST(ArrayMap, CopyConstructor) { + Map m1; + // Insert an item + const State::KeyType key = 0; + const State::ValueType value = 42; + const auto status = m1.insert(key, value); + ASSERT_EQ(status, Success::SUCCESS); + // Call the copy constructor + Map m2(m1); + ASSERT_EQ(m2.getSize(), 1); +} + +TEST(ArrayMap, CopyAssignmentOperator) { + Map m1; + // Insert an item + const State::KeyType key = 0; + State::ValueType value = 42; + auto status = m1.insert(key, value); + ASSERT_EQ(status, Success::SUCCESS); + // Call the default constructor + Map m2; + ASSERT_EQ(m2.getSize(), 0); + // Call the copy assignment operator + m2 = m1; + ASSERT_EQ(m2.getSize(), 1); + value = 0; + status = m2.find(key, value); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(value, 42); +} + +TEST(ArrayMap, CopyDataFrom) { + constexpr FwSizeType maxSize = State::capacity; + constexpr FwSizeType smallSize = maxSize / 2; + Map m1; + // size1 < capacity2 + { + Map m2; + State::testCopyDataFrom(m1, smallSize, m2); + } + // size1 == capacity2 + { + Map m2; + State::testCopyDataFrom(m1, maxSize, m2); + } + // size1 > capacity2 + { + ArrayMap m2; + State::testCopyDataFrom(m1, maxSize, m2); + } +} + +TEST(ArrayMapRules, Clear) { + Map map; + State state(map); + Rules::insertNotFull.apply(state); + ASSERT_EQ(state.map.getSize(), 1); + Rules::clear.apply(state); + ASSERT_EQ(state.map.getSize(), 0); +} + +TEST(ArrayMapRules, Find) { + Map map; + State state(map); + Rules::find.apply(state); + state.useStoredKey = true; + Rules::insertNotFull.apply(state); + Rules::find.apply(state); +} + +TEST(ArrayMapRules, FindExisting) { + Map map; + State state(map); + Rules::insertNotFull.apply(state); + Rules::findExisting.apply(state); +} + +TEST(ArrayMapRules, InsertExisting) { + Map map; + State state(map); + Rules::insertNotFull.apply(state); + Rules::insertExisting.apply(state); +} + +TEST(ArrayMapRules, InsertFull) { + Map map; + State state(map); + state.useStoredKey = true; + for (FwSizeType i = 0; i < State::capacity; i++) { + state.storedKey = static_cast(i); + Rules::insertNotFull.apply(state); + } + state.useStoredKey = false; + Rules::insertFull.apply(state); +} + +TEST(ArrayMapRules, InsertNotFull) { + Map map; + State state(map); + Rules::insertNotFull.apply(state); +} + +TEST(ArrayMapRules, Remove) { + Map map; + State state(map); + state.useStoredKey = true; + Rules::insertNotFull.apply(state); + Rules::remove.apply(state); + Rules::remove.apply(state); +} + +TEST(ArrayMapRules, RemoveExisting) { + Map map; + State state(map); + Rules::insertNotFull.apply(state); + Rules::removeExisting.apply(state); +} + +TEST(ArrayMapScenarios, Random) { + Map map; + State state(map); + Scenarios::random(Fw::String("ArrayMapRandom"), state, 1000); +} + +} // namespace MapTest +} // namespace Fw From ede83c9dd8ba48a22530f521e6ae35162b1ee4d2 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 7 Jul 2025 21:47:04 -0700 Subject: [PATCH 324/458] Revise Fw/DataStructures --- Fw/DataStructures/CMakeLists.txt | 38 ++++++++++++++++---------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index ec849c19ff6..d478bfc9bea 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -6,27 +6,27 @@ register_fprime_module() set(UT_SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayMapTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestRules.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestScenarios.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/SetTestRules.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/SetTestScenarios.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/SetTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/SetTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" ) set(UT_MOD_DEPS From 0fba764435900b46fe0570f82750529438f3b0d1 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 7 Jul 2025 21:49:17 -0700 Subject: [PATCH 325/458] Revise SDDs for ArrayMap and ArraySet --- Fw/DataStructures/docs/ArrayMap.md | 5 +++-- Fw/DataStructures/docs/ArraySet.md | 16 ++++++++++------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/Fw/DataStructures/docs/ArrayMap.md b/Fw/DataStructures/docs/ArrayMap.md index 6daef0d2e42..cf7546737e3 100644 --- a/Fw/DataStructures/docs/ArrayMap.md +++ b/Fw/DataStructures/docs/ArrayMap.md @@ -74,14 +74,15 @@ ArrayMap(const ArrayMap& map) _Example:_ ```c++ -ArrayMap m1(entries, capacity); +using Map = ArrayMap; +Map m1(entries, capacity); // Insert an item const U16 key = 0; const U32 value = 42; const auto status = m1.insert(key, value); ASSERT_EQ(status, Success::SUCCESS); // Call the copy constructor -ArrayMap m2(m1); +Map m2(m1); ASSERT_EQ(m2.getSize(), 1); ``` diff --git a/Fw/DataStructures/docs/ArraySet.md b/Fw/DataStructures/docs/ArraySet.md index 1acd7c847c3..2f474f4ffc3 100644 --- a/Fw/DataStructures/docs/ArraySet.md +++ b/Fw/DataStructures/docs/ArraySet.md @@ -56,7 +56,7 @@ classDiagram ArraySet() ``` -Initialize each member variable with its default value. +Initialize `m_extSet` with `ExternalArraySet(m_entries, C)`. _Example:_ ```c++ @@ -69,17 +69,20 @@ ArraySet set; ArraySet(const ArraySet& set) ``` -Set `*this = set`. +1. Initialize `m_extSet` with `ExternalArraySet(m_entries, C)`. + +2. Set `*this = set`. _Example:_ ```c++ -ArraySet m1(entries, capacity); +using Set = ArraySet; +Set m1; // Insert an item const U32 element = 42; const auto status = m1.insert(element); ASSERT_EQ(status, Success::SUCCESS); // Call the copy constructor -ArraySet m2(m1); +Set m2; ASSERT_EQ(m2.getSize(), 1); ``` @@ -103,13 +106,14 @@ Return `m_extSet.copyDataFrom(set)`. _Example:_ ```c++ -ArraySet m1(entries, capacity); +using Set = ArraySet; +Set m1; // Insert an item U32 element = 42; const auto status = m1.insert(element, value); ASSERT_EQ(status, Success::SUCCESS); // Call the default constructor -ArraySet m2; +Set m2; ASSERT_EQ(m2.getSize(), 0); // Call the copy assignment operator m2 = m1; From 2aac77de56323845b734919621a3da0885df8267 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 7 Jul 2025 22:14:44 -0700 Subject: [PATCH 326/458] Revise Fw/DataStructures --- Fw/DataStructures/ArrayMap.hpp | 115 +++++++++++++++ Fw/DataStructures/ArraySet.hpp | 112 ++++++++++++++ Fw/DataStructures/CMakeLists.txt | 1 + Fw/DataStructures/FifoQueueBase.hpp | 2 +- Fw/DataStructures/MapBase.hpp | 2 +- Fw/DataStructures/MapIterator.hpp | 2 +- Fw/DataStructures/SetBase.hpp | 2 +- Fw/DataStructures/SetIterator.hpp | 2 +- Fw/DataStructures/SetOrMapIterator.hpp | 18 +-- Fw/DataStructures/StackBase.hpp | 2 +- Fw/DataStructures/docs/CircularIndex.md | 2 +- Fw/DataStructures/docs/FifoQueueBase.md | 2 +- Fw/DataStructures/docs/MapBase.md | 2 +- Fw/DataStructures/docs/MapIterator.md | 2 +- Fw/DataStructures/docs/SetBase.md | 2 +- Fw/DataStructures/docs/SetIterator.md | 2 +- Fw/DataStructures/docs/SetOrMapIterator.md | 2 +- Fw/DataStructures/docs/StackBase.md | 2 +- Fw/DataStructures/test/ut/ArraySetTest.cpp | 164 +++++++++++++++++++++ 19 files changed, 414 insertions(+), 24 deletions(-) create mode 100644 Fw/DataStructures/ArrayMap.hpp create mode 100644 Fw/DataStructures/ArraySet.hpp create mode 100644 Fw/DataStructures/test/ut/ArraySetTest.cpp diff --git a/Fw/DataStructures/ArrayMap.hpp b/Fw/DataStructures/ArrayMap.hpp new file mode 100644 index 00000000000..25c28e4bb9e --- /dev/null +++ b/Fw/DataStructures/ArrayMap.hpp @@ -0,0 +1,115 @@ +// ====================================================================== +// \file ArrayMap.hpp +// \author bocchino +// \brief An array-based map with internal storage +// ====================================================================== + +#ifndef Fw_ArrayMap_HPP +#define Fw_ArrayMap_HPP + +#include "Fw/DataStructures/ExternalArrayMap.hpp" + +namespace Fw { + +template +class ArrayMap final : public MapBase { + // ---------------------------------------------------------------------- + // Friend class for testing + // ---------------------------------------------------------------------- + + template + friend class ArrayMapTester; + + public: + // ---------------------------------------------------------------------- + // Public types + // ---------------------------------------------------------------------- + + //! The type of a map entry + using Entry = SetOrMapIterator; + + //! The type of a map iterator + using Iterator = MapIterator; + + //! The type of the map entries + using Entries = Entry[C]; + + public: + // ---------------------------------------------------------------------- + // Public constructors and destructors + // ---------------------------------------------------------------------- + + //! Zero-argument constructor + ArrayMap() : MapBase(), m_extMap(m_entries, C) {} + + //! Copy constructor + ArrayMap(const ArrayMap& map) : MapBase(), m_extMap(m_entries, C) { *this = map; } + + //! Destructor + ~ArrayMap() override = default; + + public: + // ---------------------------------------------------------------------- + // Public member functions + // ---------------------------------------------------------------------- + + //! operator= + ArrayMap& operator=(const ArrayMap& map) { + this->m_extMap.copyDataFrom(map); + return *this; + } + + //! Clear the map + void clear() override { this->m_extMap.clear(); } + + //! Find a value associated with a key in the map + //! \return SUCCESS if the item was found + Success find(const K& key, //!< The key + V& value //!< The value + ) const override { + return this->m_extMap.find(key, value); + } + + //! Get the capacity of the map (max number of entries) + //! \return The capacity + FwSizeType getCapacity() const override { return this->m_extMap.getCapacity(); } + + //! Get the head iterator for the map + //! \return The iterator + const Iterator* getHeadIterator() const override { return this->m_extMap.getHeadIterator(); } + + //! Get the size (number of entries) + //! \return The size + FwSizeType getSize() const override { return this->m_extMap.getSize(); } + + //! Insert a (key, value) pair in the map + //! \return SUCCESS if there is room in the map + Success insert(const K& key, //!< The key + const V& value //!< The value + ) override { + return this->m_extMap.insert(key, value); + } + + //! Remove a (key, value) pair from the map + //! \return SUCCESS if the key was there + Success remove(const K& key, //!< The key + V& value //!< The value + ) override { + return this->m_extMap.remove(key, value); + } + + private: + // ---------------------------------------------------------------------- + // Private member variables + // ---------------------------------------------------------------------- + + //! The external map implementation + ExternalArrayMap m_extMap = {}; + + //! The array providing the backing memory for m_extMap + Entries m_entries = {}; +}; + +} // namespace Fw + +#endif diff --git a/Fw/DataStructures/ArraySet.hpp b/Fw/DataStructures/ArraySet.hpp new file mode 100644 index 00000000000..fddf37e7038 --- /dev/null +++ b/Fw/DataStructures/ArraySet.hpp @@ -0,0 +1,112 @@ +// ====================================================================== +// \file ArraySet.hpp +// \author bocchino +// \brief An array-based set with internal storage +// ====================================================================== + +#ifndef Fw_ArraySet_HPP +#define Fw_ArraySet_HPP + +#include "Fw/DataStructures/ExternalArraySet.hpp" + +namespace Fw { + +template +class ArraySet final : public SetBase { + // ---------------------------------------------------------------------- + // Friend class for testing + // ---------------------------------------------------------------------- + + template + friend class ArraySetTester; + + public: + // ---------------------------------------------------------------------- + // Public types + // ---------------------------------------------------------------------- + + //! The type of a set entry + using Entry = SetOrMapIterator; + + //! The type of a set iterator + using Iterator = SetIterator; + + //! The type of the set entries + using Entries = Entry[C]; + + public: + // ---------------------------------------------------------------------- + // Public constructors and destructors + // ---------------------------------------------------------------------- + + //! Zero-argument constructor + ArraySet() : SetBase(), m_extSet(m_entries, C) {} + + //! Copy constructor + ArraySet(const ArraySet& set) : SetBase(), m_extSet(m_entries, C) { *this = set; } + + //! Destructor + ~ArraySet() override = default; + + public: + // ---------------------------------------------------------------------- + // Public member functions + // ---------------------------------------------------------------------- + + //! operator= + ArraySet& operator=(const ArraySet& set) { + this->m_extSet.copyDataFrom(set); + return *this; + } + + //! Clear the set + void clear() override { this->m_extSet.clear(); } + + //! Find an element in the set + //! \return SUCCESS if the element was found + Success find(const T& element //!< The element + ) const override { + return this->m_extSet.find(element); + } + + //! Get the capacity of the set (max number of entries) + //! \return The capacity + FwSizeType getCapacity() const override { return this->m_extSet.getCapacity(); } + + //! Get the head iterator for the set + //! \return The iterator + const Iterator* getHeadIterator() const override { return this->m_extSet.getHeadIterator(); } + + //! Get the size (number of entries) + //! \return The size + FwSizeType getSize() const override { return this->m_extSet.getSize(); } + + //! Insert an element in the set + //! \return SUCCESS if there is room in the set + Success insert(const T& element //!< The element + ) override { + return this->m_extSet.insert(element); + } + + //! Remove an element from the set + //! \return SUCCESS if the key was there + Success remove(const T& element //!< The element + ) override { + return this->m_extSet.remove(element); + } + + private: + // ---------------------------------------------------------------------- + // Private member variables + // ---------------------------------------------------------------------- + + //! The external set implementation + ExternalArraySet m_extSet = {}; + + //! The array providing the backing memory for m_extSet + Entries m_entries = {}; +}; + +} // namespace Fw + +#endif diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index d478bfc9bea..2c408d1ba90 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -7,6 +7,7 @@ register_fprime_module() set(UT_SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayMapTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" diff --git a/Fw/DataStructures/FifoQueueBase.hpp b/Fw/DataStructures/FifoQueueBase.hpp index 0cf81045eda..c151b643636 100644 --- a/Fw/DataStructures/FifoQueueBase.hpp +++ b/Fw/DataStructures/FifoQueueBase.hpp @@ -30,7 +30,7 @@ class FifoQueueBase { // ---------------------------------------------------------------------- //! Zero-argument constructor - FifoQueueBase() = default; + FifoQueueBase() {} //! Destructor virtual ~FifoQueueBase() = default; diff --git a/Fw/DataStructures/MapBase.hpp b/Fw/DataStructures/MapBase.hpp index 71cf161fc24..417453a59a8 100644 --- a/Fw/DataStructures/MapBase.hpp +++ b/Fw/DataStructures/MapBase.hpp @@ -38,7 +38,7 @@ class MapBase { // ---------------------------------------------------------------------- //! Zero-argument constructor - MapBase() = default; + MapBase() {} //! Destructor virtual ~MapBase() = default; diff --git a/Fw/DataStructures/MapIterator.hpp b/Fw/DataStructures/MapIterator.hpp index 15a89327879..1dd7b8a8611 100644 --- a/Fw/DataStructures/MapIterator.hpp +++ b/Fw/DataStructures/MapIterator.hpp @@ -28,7 +28,7 @@ class MapIterator { // ---------------------------------------------------------------------- //! Zero-argument constructor - MapIterator() = default; + MapIterator() {} //! Destructor virtual ~MapIterator() = default; diff --git a/Fw/DataStructures/SetBase.hpp b/Fw/DataStructures/SetBase.hpp index 3fa0853503c..81b66af7ab6 100644 --- a/Fw/DataStructures/SetBase.hpp +++ b/Fw/DataStructures/SetBase.hpp @@ -38,7 +38,7 @@ class SetBase { // ---------------------------------------------------------------------- //! Zero-argument constructor - SetBase() = default; + SetBase() {} //! Destructor virtual ~SetBase() = default; diff --git a/Fw/DataStructures/SetIterator.hpp b/Fw/DataStructures/SetIterator.hpp index 5dc3deed83d..201d1a56ed3 100644 --- a/Fw/DataStructures/SetIterator.hpp +++ b/Fw/DataStructures/SetIterator.hpp @@ -28,7 +28,7 @@ class SetIterator { // ---------------------------------------------------------------------- //! Zero-argument constructor - SetIterator() = default; + SetIterator() {} //! Destructor virtual ~SetIterator() = default; diff --git a/Fw/DataStructures/SetOrMapIterator.hpp b/Fw/DataStructures/SetOrMapIterator.hpp index 647311e1a22..d843133f818 100644 --- a/Fw/DataStructures/SetOrMapIterator.hpp +++ b/Fw/DataStructures/SetOrMapIterator.hpp @@ -21,7 +21,7 @@ class SetOrMapIterator final : public MapIterator, public SetIterator() {} //! Constructor providing members SetOrMapIterator(const KE& keyOrElement, //!< The key or element @@ -31,9 +31,7 @@ class SetOrMapIterator final : public MapIterator, public SetIterator& iterator) { - *this = iterator; - } + SetOrMapIterator(const SetOrMapIterator& iterator) { *this = iterator; } //! Destructor ~SetOrMapIterator() override = default; @@ -45,12 +43,12 @@ class SetOrMapIterator final : public MapIterator, public SetIterator& operator=(const SetOrMapIterator& iterator) { - if (this != &iterator) { - this->m_keyOrElement = iterator.m_keyOrElement; - this->m_valueOrNil = iterator.m_valueOrNil; - this->m_next = iterator.m_next; - } - return *this; + if (this != &iterator) { + this->m_keyOrElement = iterator.m_keyOrElement; + this->m_valueOrNil = iterator.m_valueOrNil; + this->m_next = iterator.m_next; + } + return *this; } //! Get the element associated with this iterator diff --git a/Fw/DataStructures/StackBase.hpp b/Fw/DataStructures/StackBase.hpp index 96ec2d2fd41..bd9379f715f 100644 --- a/Fw/DataStructures/StackBase.hpp +++ b/Fw/DataStructures/StackBase.hpp @@ -30,7 +30,7 @@ class StackBase { // ---------------------------------------------------------------------- //! Zero-argument constructor - StackBase() = default; + StackBase() {} //! Destructor virtual ~StackBase() = default; diff --git a/Fw/DataStructures/docs/CircularIndex.md b/Fw/DataStructures/docs/CircularIndex.md index d417259b01e..13afeaad127 100644 --- a/Fw/DataStructures/docs/CircularIndex.md +++ b/Fw/DataStructures/docs/CircularIndex.md @@ -22,7 +22,7 @@ wraps around modulo an integer. CircularIndex() ``` -Defined as `= default`. +Use default initialization of members. ### 2.2. Constructor with Specified Members diff --git a/Fw/DataStructures/docs/FifoQueueBase.md b/Fw/DataStructures/docs/FifoQueueBase.md index b68c6d413f9..49ca34b0fa8 100644 --- a/Fw/DataStructures/docs/FifoQueueBase.md +++ b/Fw/DataStructures/docs/FifoQueueBase.md @@ -30,7 +30,7 @@ Defined as `= delete`. FifoQueueBase() ``` -Defined as `= default`. +Use default initialization of members. ### 3.2. Destructor diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index e787e4c0bf6..d7805e72357 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -40,7 +40,7 @@ Defined as `= delete`. MapBase() ``` -Defined as `= default`. +Use default initialization of members. ### 4.2. Destructor diff --git a/Fw/DataStructures/docs/MapIterator.md b/Fw/DataStructures/docs/MapIterator.md index 87384e0a863..9cecd162603 100644 --- a/Fw/DataStructures/docs/MapIterator.md +++ b/Fw/DataStructures/docs/MapIterator.md @@ -31,7 +31,7 @@ Defined as `= delete`. MapIterator() ``` -Defined as `= default`. +Use default initialization of members. ### 3.2. Destructor diff --git a/Fw/DataStructures/docs/SetBase.md b/Fw/DataStructures/docs/SetBase.md index e4a62b399ae..42c2a5f63c9 100644 --- a/Fw/DataStructures/docs/SetBase.md +++ b/Fw/DataStructures/docs/SetBase.md @@ -39,7 +39,7 @@ Defined as `= delete`. SetBase() ``` -Defined as `= default`. +Use default initialization of members. ### 4.2. Destructor diff --git a/Fw/DataStructures/docs/SetIterator.md b/Fw/DataStructures/docs/SetIterator.md index 2290529c5ae..29e00fe5543 100644 --- a/Fw/DataStructures/docs/SetIterator.md +++ b/Fw/DataStructures/docs/SetIterator.md @@ -30,7 +30,7 @@ Defined as `= delete`. SetIterator() ``` -Defined as `= default`. +Use default initialization of members. ### 3.2. Destructor diff --git a/Fw/DataStructures/docs/SetOrMapIterator.md b/Fw/DataStructures/docs/SetOrMapIterator.md index 3af330de40d..e2786970ab2 100644 --- a/Fw/DataStructures/docs/SetOrMapIterator.md +++ b/Fw/DataStructures/docs/SetOrMapIterator.md @@ -46,7 +46,7 @@ classDiagram SetOrMapIterator() ``` -Defined as `= default`. +Use default initialization of members. ### 4.2. Constructor Providing Members diff --git a/Fw/DataStructures/docs/StackBase.md b/Fw/DataStructures/docs/StackBase.md index 184e3ceabab..aec66bb55e2 100644 --- a/Fw/DataStructures/docs/StackBase.md +++ b/Fw/DataStructures/docs/StackBase.md @@ -30,7 +30,7 @@ Defined as `= delete`. StackBase() ``` -Defined as `= default`. +Use default initialization of members. ### 3.2. Destructor diff --git a/Fw/DataStructures/test/ut/ArraySetTest.cpp b/Fw/DataStructures/test/ut/ArraySetTest.cpp new file mode 100644 index 00000000000..61dda9610a3 --- /dev/null +++ b/Fw/DataStructures/test/ut/ArraySetTest.cpp @@ -0,0 +1,164 @@ +// ====================================================================== +// \title ArraySetTest.cpp +// \author bocchino +// \brief cpp file for ArraySet tests +// ====================================================================== + +#include "Fw/DataStructures/ArraySet.hpp" +#include "STest/STest/Pick/Pick.hpp" + +#include "Fw/DataStructures/ArraySet.hpp" +#include "Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp" +#include "Fw/DataStructures/test/ut/STest/SetTestRules.hpp" +#include "Fw/DataStructures/test/ut/STest/SetTestScenarios.hpp" + +namespace Fw { + +template +class ArraySetTester { + public: + ArraySetTester(const ArraySet& set) : m_set(set) {} + + const ExternalArraySet getExtSet() const { return this->m_set.extSet; } + + const typename ArraySet::Entries& getEntries() const { return this->m_set.m_entries; } + + private: + const ArraySet& m_set; +}; + +namespace SetTest { + +using Entry = SetOrMapIterator; +using Set = ArraySet; +using SetTester = ArraySetTester; +using ImplTester = ArraySetOrMapImplTester; + +TEST(ArraySet, ZeroArgConstructor) { + Set set; + ASSERT_EQ(set.getCapacity(), FwSizeType(State::capacity)); + ASSERT_EQ(set.getSize(), 0); +} + +TEST(ArraySet, CopyConstructor) { + Set m1; + // Insert an item + const State::ElementType e = 42; + const auto status = m1.insert(e); + ASSERT_EQ(status, Success::SUCCESS); + // Call the copy constructor + Set m2(m1); + ASSERT_EQ(m2.getSize(), 1); +} + +TEST(ArraySet, CopyAssignmentOperator) { + Set m1; + // Insert an item + const State::ElementType e = 42; + auto status = m1.insert(e); + ASSERT_EQ(status, Success::SUCCESS); + // Call the default constructor + Set m2; + ASSERT_EQ(m2.getSize(), 0); + // Call the copy assignment operator + m2 = m1; + ASSERT_EQ(m2.getSize(), 1); + status = m2.find(e); + ASSERT_EQ(status, Success::SUCCESS); +} + +TEST(ArraySet, CopyDataFrom) { + constexpr FwSizeType maxSize = State::capacity; + constexpr FwSizeType smallSize = maxSize / 2; + Set m1; + // size1 < capacity2 + { + Set m2; + State::testCopyDataFrom(m1, smallSize, m2); + } + // size1 == capacity2 + { + Set m2; + State::testCopyDataFrom(m1, maxSize, m2); + } + // size1 > capacity2 + { + ArraySet m2; + State::testCopyDataFrom(m1, maxSize, m2); + } +} + +TEST(ArraySetRules, Clear) { + Set set; + State state(set); + Rules::insertNotFull.apply(state); + ASSERT_EQ(state.set.getSize(), 1); + Rules::clear.apply(state); + ASSERT_EQ(state.set.getSize(), 0); +} + +TEST(ArraySetRules, Find) { + Set set; + State state(set); + Rules::find.apply(state); + state.useStoredElement = true; + Rules::insertNotFull.apply(state); + Rules::find.apply(state); +} + +TEST(ArraySetRules, FindExisting) { + Set set; + State state(set); + Rules::insertNotFull.apply(state); + Rules::findExisting.apply(state); +} + +TEST(ArraySetRules, InsertExisting) { + Set set; + State state(set); + Rules::insertNotFull.apply(state); + Rules::insertExisting.apply(state); +} + +TEST(ArraySetRules, InsertFull) { + Set set; + State state(set); + state.useStoredElement = true; + for (FwSizeType i = 0; i < State::capacity; i++) { + state.storedElement = static_cast(i); + Rules::insertNotFull.apply(state); + } + state.useStoredElement = false; + Rules::insertFull.apply(state); +} + +TEST(ArraySetRules, InsertNotFull) { + Set set; + State state(set); + Rules::insertNotFull.apply(state); +} + +TEST(ArraySetRules, Remove) { + Set set; + State state(set); + state.useStoredElement = true; + Rules::insertNotFull.apply(state); + Rules::remove.apply(state); + Rules::remove.apply(state); +} + +TEST(ArraySetRules, RemoveExisting) { + Set set; + State state(set); + Rules::insertNotFull.apply(state); + Rules::removeExisting.apply(state); +} + +TEST(ArraySetScenarios, Random) { + Set set; + State state(set); + Scenarios::random(Fw::String("ArraySetRandom"), state, 1000); +} + +} // namespace SetTest +} // namespace Fw From d1a38c0e2392554b5f498d92571ec58356832e3a Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 8 Jul 2025 08:50:23 -0700 Subject: [PATCH 327/458] Refactor map test scenarios --- Fw/DataStructures/test/ut/ArrayMapTest.cpp | 50 ++++++----------- .../test/ut/ExternalArrayMapTest.cpp | 54 +++++++------------ .../test/ut/STest/MapTestScenarios.cpp | 50 +++++++++++++++++ .../test/ut/STest/MapTestScenarios.hpp | 16 ++++++ 4 files changed, 100 insertions(+), 70 deletions(-) diff --git a/Fw/DataStructures/test/ut/ArrayMapTest.cpp b/Fw/DataStructures/test/ut/ArrayMapTest.cpp index 1d4d5d38866..0a6dd2354c9 100644 --- a/Fw/DataStructures/test/ut/ArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ArrayMapTest.cpp @@ -92,70 +92,52 @@ TEST(ArrayMap, CopyDataFrom) { } } -TEST(ArrayMapRules, Clear) { +TEST(ArrayMapScenarios, Clear) { Map map; State state(map); - Rules::insertNotFull.apply(state); - ASSERT_EQ(state.map.getSize(), 1); - Rules::clear.apply(state); - ASSERT_EQ(state.map.getSize(), 0); + Scenarios::clear(state); } -TEST(ArrayMapRules, Find) { +TEST(ArrayMapScenarios, Find) { Map map; State state(map); - Rules::find.apply(state); - state.useStoredKey = true; - Rules::insertNotFull.apply(state); - Rules::find.apply(state); + Scenarios::find(state); } -TEST(ArrayMapRules, FindExisting) { +TEST(ArrayMapScenarios, FindExisting) { Map map; State state(map); - Rules::insertNotFull.apply(state); - Rules::findExisting.apply(state); + Scenarios::findExisting(state); } -TEST(ArrayMapRules, InsertExisting) { +TEST(ArrayMapScenarios, InsertExisting) { Map map; State state(map); - Rules::insertNotFull.apply(state); - Rules::insertExisting.apply(state); + Scenarios::insertExisting(state); } -TEST(ArrayMapRules, InsertFull) { +TEST(ArrayMapScenarios, InsertFull) { Map map; State state(map); - state.useStoredKey = true; - for (FwSizeType i = 0; i < State::capacity; i++) { - state.storedKey = static_cast(i); - Rules::insertNotFull.apply(state); - } - state.useStoredKey = false; - Rules::insertFull.apply(state); + Scenarios::insertFull(state); } -TEST(ArrayMapRules, InsertNotFull) { +TEST(ArrayMapScenarios, InsertNotFull) { Map map; State state(map); - Rules::insertNotFull.apply(state); + Scenarios::insertNotFull(state); } -TEST(ArrayMapRules, Remove) { +TEST(ArrayMapScenarios, Remove) { Map map; State state(map); - state.useStoredKey = true; - Rules::insertNotFull.apply(state); - Rules::remove.apply(state); - Rules::remove.apply(state); + Scenarios::remove(state); } -TEST(ArrayMapRules, RemoveExisting) { +TEST(ArrayMapScenarios, RemoveExisting) { Map map; State state(map); - Rules::insertNotFull.apply(state); - Rules::removeExisting.apply(state); + Scenarios::removeExisting(state); } TEST(ArrayMapScenarios, Random) { diff --git a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp index cc5f81bff34..81e7072b4f9 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp @@ -106,90 +106,72 @@ TEST(ExternalArrayMap, CopyDataFrom) { Map m2(entries2, maxSize); State::testCopyDataFrom(m1, smallSize, m2); } - // size1 == size2 + // size1 == capacity2 { Map m2(entries2, maxSize); State::testCopyDataFrom(m1, maxSize, m2); } - // size1 > size2 + // size1 > capacity2 { Map m2(entries2, smallSize); State::testCopyDataFrom(m1, maxSize, m2); } } -TEST(ExternalArrayMapRules, Clear) { +TEST(ExternalArrayMapScenarios, Clear) { Entry entries[State::capacity]; Map map(entries, State::capacity); State state(map); - Rules::insertNotFull.apply(state); - ASSERT_EQ(state.map.getSize(), 1); - Rules::clear.apply(state); - ASSERT_EQ(state.map.getSize(), 0); + Scenarios::clear(state); } -TEST(ExternalArrayMapRules, Find) { +TEST(ExternalArrayMapScenarios, Find) { Entry entries[State::capacity]; Map map(entries, State::capacity); State state(map); - Rules::find.apply(state); - state.useStoredKey = true; - Rules::insertNotFull.apply(state); - Rules::find.apply(state); + Scenarios::find(state); } -TEST(ExternalArrayMapRules, FindExisting) { +TEST(ExternalArrayMapScenarios, FindExisting) { Entry entries[State::capacity]; Map map(entries, State::capacity); State state(map); - Rules::insertNotFull.apply(state); - Rules::findExisting.apply(state); + Scenarios::findExisting(state); } -TEST(ExternalArrayMapRules, InsertExisting) { +TEST(ExternalArrayMapScenarios, InsertExisting) { Entry entries[State::capacity]; Map map(entries, State::capacity); State state(map); - Rules::insertNotFull.apply(state); - Rules::insertExisting.apply(state); + Scenarios::insertExisting(state); } -TEST(ExternalArrayMapRules, InsertFull) { +TEST(ExternalArrayMapScenarios, InsertFull) { Entry entries[State::capacity]; Map map(entries, State::capacity); State state(map); - state.useStoredKey = true; - for (FwSizeType i = 0; i < State::capacity; i++) { - state.storedKey = static_cast(i); - Rules::insertNotFull.apply(state); - } - state.useStoredKey = false; - Rules::insertFull.apply(state); + Scenarios::insertFull(state); } -TEST(ExternalArrayMapRules, InsertNotFull) { +TEST(ExternalArrayMapScenarios, InsertNotFull) { Entry entries[State::capacity]; Map map(entries, State::capacity); State state(map); - Rules::insertNotFull.apply(state); + Scenarios::insertNotFull(state); } -TEST(ExternalArrayMapRules, Remove) { +TEST(ExternalArrayMapScenarios, Remove) { Entry entries[State::capacity]; Map map(entries, State::capacity); State state(map); - state.useStoredKey = true; - Rules::insertNotFull.apply(state); - Rules::remove.apply(state); - Rules::remove.apply(state); + Scenarios::remove(state); } -TEST(ExternalArrayMapRules, RemoveExisting) { +TEST(ExternalArrayMapScenarios, RemoveExisting) { Entry entries[State::capacity]; Map map(entries, State::capacity); State state(map); - Rules::insertNotFull.apply(state); - Rules::removeExisting.apply(state); + Scenarios::removeExisting(state); } TEST(ExternalArrayMapScenarios, Random) { diff --git a/Fw/DataStructures/test/ut/STest/MapTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/MapTestScenarios.cpp index c902f5323a5..a32a288eaf0 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestScenarios.cpp +++ b/Fw/DataStructures/test/ut/STest/MapTestScenarios.cpp @@ -15,6 +15,56 @@ namespace MapTest { namespace Scenarios { +void clear(State& state) { + Rules::insertNotFull.apply(state); + ASSERT_EQ(state.map.getSize(), 1); + Rules::clear.apply(state); + ASSERT_EQ(state.map.getSize(), 0); +} + +void find(State& state) { + Rules::find.apply(state); + state.useStoredKey = true; + Rules::insertNotFull.apply(state); + Rules::find.apply(state); +} + +void findExisting(State& state) { + Rules::insertNotFull.apply(state); + Rules::findExisting.apply(state); +} + +void insertExisting(State& state) { + Rules::insertNotFull.apply(state); + Rules::insertExisting.apply(state); +} + +void insertFull(State& state) { + state.useStoredKey = true; + for (FwSizeType i = 0; i < State::capacity; i++) { + state.storedKey = static_cast(i); + Rules::insertNotFull.apply(state); + } + state.useStoredKey = false; + Rules::insertFull.apply(state); +} + +void insertNotFull(State& state) { + Rules::insertNotFull.apply(state); +} + +void remove(State& state) { + state.useStoredKey = true; + Rules::insertNotFull.apply(state); + Rules::remove.apply(state); + Rules::remove.apply(state); +} + +void removeExisting(State& state) { + Rules::insertNotFull.apply(state); + Rules::removeExisting.apply(state); +} + void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { Rule* rules[] = { &Rules::clear, diff --git a/Fw/DataStructures/test/ut/STest/MapTestScenarios.hpp b/Fw/DataStructures/test/ut/STest/MapTestScenarios.hpp index e9553fc5094..09b7c08850b 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestScenarios.hpp +++ b/Fw/DataStructures/test/ut/STest/MapTestScenarios.hpp @@ -15,6 +15,22 @@ namespace MapTest { namespace Scenarios { +void clear(State& state); + +void find(State& state); + +void findExisting(State& state); + +void insertExisting(State& state); + +void insertFull(State& state); + +void insertNotFull(State& state); + +void remove(State& state); + +void removeExisting(State& state); + void random(const Fw::StringBase& name, State& state, U32 maxNumSteps); } // namespace Scenarios From add68b3ada1d41c93ebb7b550a8dffa47d9c4c53 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 8 Jul 2025 08:56:22 -0700 Subject: [PATCH 328/458] Refactor data structures tests --- .../test/ut/ArraySetOrMapImplTest.cpp | 16 ++++++++-------- Fw/DataStructures/test/ut/ArraySetTest.cpp | 16 ++++++++-------- .../test/ut/ExternalArraySetTest.cpp | 16 ++++++++-------- .../test/ut/ExternalFifoQueueTest.cpp | 12 ++++++------ Fw/DataStructures/test/ut/ExternalStackTest.cpp | 12 ++++++------ Fw/DataStructures/test/ut/FifoQueueTest.cpp | 12 ++++++------ Fw/DataStructures/test/ut/StackTest.cpp | 12 ++++++------ 7 files changed, 48 insertions(+), 48 deletions(-) diff --git a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp index ad4c4640e60..5b0c7696b5e 100644 --- a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp +++ b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp @@ -78,7 +78,7 @@ TEST(ArraySetOrMapImpl, CopyAssignmentOperator) { ASSERT_EQ(impl2.getSize(), 1); } -TEST(ArraySetOrMapImplRules, Clear) { +TEST(ArraySetOrMapImplScenarios, Clear) { State::Entry entries[State::capacity]; State::Impl impl(entries, State::capacity); State state(impl); @@ -88,7 +88,7 @@ TEST(ArraySetOrMapImplRules, Clear) { ASSERT_EQ(state.impl.getSize(), 0); } -TEST(ArraySetOrMapImplRules, Find) { +TEST(ArraySetOrMapImplScenarios, Find) { State::Entry entries[State::capacity]; State::Impl impl(entries, State::capacity); State state(impl); @@ -98,7 +98,7 @@ TEST(ArraySetOrMapImplRules, Find) { Rules::find.apply(state); } -TEST(ArraySetOrMapImplRules, FindExisting) { +TEST(ArraySetOrMapImplScenarios, FindExisting) { State::Entry entries[State::capacity]; State::Impl impl(entries, State::capacity); State state(impl); @@ -106,7 +106,7 @@ TEST(ArraySetOrMapImplRules, FindExisting) { Rules::findExisting.apply(state); } -TEST(ArraySetOrMapImplRules, InsertExisting) { +TEST(ArraySetOrMapImplScenarios, InsertExisting) { State::Entry entries[State::capacity]; State::Impl impl(entries, State::capacity); State state(impl); @@ -114,7 +114,7 @@ TEST(ArraySetOrMapImplRules, InsertExisting) { Rules::insertExisting.apply(state); } -TEST(ArraySetOrMapImplRules, InsertFull) { +TEST(ArraySetOrMapImplScenarios, InsertFull) { State::Entry entries[State::capacity]; State::Impl impl(entries, State::capacity); State state(impl); @@ -127,14 +127,14 @@ TEST(ArraySetOrMapImplRules, InsertFull) { Rules::insertFull.apply(state); } -TEST(ArraySetOrMapImplRules, InsertNotFull) { +TEST(ArraySetOrMapImplScenarios, InsertNotFull) { State::Entry entries[State::capacity]; State::Impl impl(entries, State::capacity); State state(impl); Rules::insertNotFull.apply(state); } -TEST(ArraySetOrMapImplRules, Remove) { +TEST(ArraySetOrMapImplScenarios, Remove) { State::Entry entries[State::capacity]; State::Impl impl(entries, State::capacity); State state(impl); @@ -144,7 +144,7 @@ TEST(ArraySetOrMapImplRules, Remove) { Rules::remove.apply(state); } -TEST(ArraySetOrMapImplRules, RemoveExisting) { +TEST(ArraySetOrMapImplScenarios, RemoveExisting) { State::Entry entries[State::capacity]; State::Impl impl(entries, State::capacity); State state(impl); diff --git a/Fw/DataStructures/test/ut/ArraySetTest.cpp b/Fw/DataStructures/test/ut/ArraySetTest.cpp index 61dda9610a3..e2138222184 100644 --- a/Fw/DataStructures/test/ut/ArraySetTest.cpp +++ b/Fw/DataStructures/test/ut/ArraySetTest.cpp @@ -88,7 +88,7 @@ TEST(ArraySet, CopyDataFrom) { } } -TEST(ArraySetRules, Clear) { +TEST(ArraySetScenarios, Clear) { Set set; State state(set); Rules::insertNotFull.apply(state); @@ -97,7 +97,7 @@ TEST(ArraySetRules, Clear) { ASSERT_EQ(state.set.getSize(), 0); } -TEST(ArraySetRules, Find) { +TEST(ArraySetScenarios, Find) { Set set; State state(set); Rules::find.apply(state); @@ -106,21 +106,21 @@ TEST(ArraySetRules, Find) { Rules::find.apply(state); } -TEST(ArraySetRules, FindExisting) { +TEST(ArraySetScenarios, FindExisting) { Set set; State state(set); Rules::insertNotFull.apply(state); Rules::findExisting.apply(state); } -TEST(ArraySetRules, InsertExisting) { +TEST(ArraySetScenarios, InsertExisting) { Set set; State state(set); Rules::insertNotFull.apply(state); Rules::insertExisting.apply(state); } -TEST(ArraySetRules, InsertFull) { +TEST(ArraySetScenarios, InsertFull) { Set set; State state(set); state.useStoredElement = true; @@ -132,13 +132,13 @@ TEST(ArraySetRules, InsertFull) { Rules::insertFull.apply(state); } -TEST(ArraySetRules, InsertNotFull) { +TEST(ArraySetScenarios, InsertNotFull) { Set set; State state(set); Rules::insertNotFull.apply(state); } -TEST(ArraySetRules, Remove) { +TEST(ArraySetScenarios, Remove) { Set set; State state(set); state.useStoredElement = true; @@ -147,7 +147,7 @@ TEST(ArraySetRules, Remove) { Rules::remove.apply(state); } -TEST(ArraySetRules, RemoveExisting) { +TEST(ArraySetScenarios, RemoveExisting) { Set set; State state(set); Rules::insertNotFull.apply(state); diff --git a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp index 23591664095..d6af83eba5c 100644 --- a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp @@ -118,7 +118,7 @@ TEST(ExternalArraySet, CopyDataFrom) { } } -TEST(ExternalArraySetRules, Clear) { +TEST(ExternalArraySetScenarios, Clear) { Entry entries[State::capacity]; Set set(entries, State::capacity); State state(set); @@ -128,7 +128,7 @@ TEST(ExternalArraySetRules, Clear) { ASSERT_EQ(state.set.getSize(), 0); } -TEST(ExternalArraySetRules, Find) { +TEST(ExternalArraySetScenarios, Find) { Entry entries[State::capacity]; Set set(entries, State::capacity); State state(set); @@ -138,7 +138,7 @@ TEST(ExternalArraySetRules, Find) { Rules::find.apply(state); } -TEST(ExternalArraySetRules, FindExisting) { +TEST(ExternalArraySetScenarios, FindExisting) { Entry entries[State::capacity]; Set set(entries, State::capacity); State state(set); @@ -146,7 +146,7 @@ TEST(ExternalArraySetRules, FindExisting) { Rules::findExisting.apply(state); } -TEST(ExternalArraySetRules, InsertExisting) { +TEST(ExternalArraySetScenarios, InsertExisting) { Entry entries[State::capacity]; Set set(entries, State::capacity); State state(set); @@ -154,7 +154,7 @@ TEST(ExternalArraySetRules, InsertExisting) { Rules::insertExisting.apply(state); } -TEST(ExternalArraySetRules, InsertFull) { +TEST(ExternalArraySetScenarios, InsertFull) { Entry entries[State::capacity]; Set set(entries, State::capacity); State state(set); @@ -167,14 +167,14 @@ TEST(ExternalArraySetRules, InsertFull) { Rules::insertFull.apply(state); } -TEST(ExternalArraySetRules, InsertNotFull) { +TEST(ExternalArraySetScenarios, InsertNotFull) { Entry entries[State::capacity]; Set set(entries, State::capacity); State state(set); Rules::insertNotFull.apply(state); } -TEST(ExternalArraySetRules, Remove) { +TEST(ExternalArraySetScenarios, Remove) { Entry entries[State::capacity]; Set set(entries, State::capacity); State state(set); @@ -184,7 +184,7 @@ TEST(ExternalArraySetRules, Remove) { Rules::remove.apply(state); } -TEST(ExternalArraySetRules, RemoveExisting) { +TEST(ExternalArraySetScenarios, RemoveExisting) { Entry entries[State::capacity]; Set set(entries, State::capacity); State state(set); diff --git a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp index 17e3d0387ae..32ea40b0f5c 100644 --- a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp @@ -193,14 +193,14 @@ TEST(ExternalFifoQueue, CopyDataFrom) { } } -TEST(ExternalFifoQueueRules, EnqueueOK) { +TEST(ExternalFifoQueueScenarios, EnqueueOK) { U32 items[State::capacity]; State::ExternalQueue queue(items, State::capacity); State state(queue); Rules::enqueueOK.apply(state); } -TEST(ExternalFifoQueueRules, EnqueueFull) { +TEST(ExternalFifoQueueScenarios, EnqueueFull) { U32 items[State::capacity]; State::ExternalQueue queue(items, State::capacity); State state(queue); @@ -210,7 +210,7 @@ TEST(ExternalFifoQueueRules, EnqueueFull) { Rules::enqueueFull.apply(state); } -TEST(ExternalFifoQueueRules, At) { +TEST(ExternalFifoQueueScenarios, At) { U32 items[State::capacity]; State::ExternalQueue queue(items, State::capacity); State state(queue); @@ -218,7 +218,7 @@ TEST(ExternalFifoQueueRules, At) { Rules::at.apply(state); } -TEST(ExternalFifoQueueRules, DequeueOK) { +TEST(ExternalFifoQueueScenarios, DequeueOK) { U32 items[State::capacity]; State::ExternalQueue queue(items, State::capacity); State state(queue); @@ -226,14 +226,14 @@ TEST(ExternalFifoQueueRules, DequeueOK) { Rules::dequeueOK.apply(state); } -TEST(ExternalFifoQueueRules, DequeueEmpty) { +TEST(ExternalFifoQueueScenarios, DequeueEmpty) { U32 items[State::capacity]; State::ExternalQueue queue(items, State::capacity); State state(queue); Rules::dequeueEmpty.apply(state); } -TEST(ExternalFifoQueueRules, Clear) { +TEST(ExternalFifoQueueScenarios, Clear) { U32 items[State::capacity]; State::ExternalQueue queue(items, State::capacity); State state(queue); diff --git a/Fw/DataStructures/test/ut/ExternalStackTest.cpp b/Fw/DataStructures/test/ut/ExternalStackTest.cpp index ea7f4ad0559..78c28a3a9f5 100644 --- a/Fw/DataStructures/test/ut/ExternalStackTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalStackTest.cpp @@ -203,14 +203,14 @@ TEST(ExternalStack, CopyDataFrom) { } } -TEST(ExternalStackRules, PushOK) { +TEST(ExternalStackScenarios, PushOK) { U32 items[State::capacity]; State::ExternalStack stack(items, State::capacity); State state(stack); Rules::pushOK.apply(state); } -TEST(ExternalStackRules, PushFull) { +TEST(ExternalStackScenarios, PushFull) { U32 items[State::capacity]; State::ExternalStack stack(items, State::capacity); State state(stack); @@ -220,7 +220,7 @@ TEST(ExternalStackRules, PushFull) { Rules::pushFull.apply(state); } -TEST(ExternalStackRules, At) { +TEST(ExternalStackScenarios, At) { U32 items[State::capacity]; State::ExternalStack stack(items, State::capacity); State state(stack); @@ -230,7 +230,7 @@ TEST(ExternalStackRules, At) { Rules::at.apply(state); } -TEST(ExternalStackRules, PopOK) { +TEST(ExternalStackScenarios, PopOK) { U32 items[State::capacity]; State::ExternalStack stack(items, State::capacity); State state(stack); @@ -240,14 +240,14 @@ TEST(ExternalStackRules, PopOK) { Rules::popOK.apply(state); } -TEST(ExternalStackRules, PopEmpty) { +TEST(ExternalStackScenarios, PopEmpty) { U32 items[State::capacity]; State::ExternalStack stack(items, State::capacity); State state(stack); Rules::popEmpty.apply(state); } -TEST(ExternalStackRules, Clear) { +TEST(ExternalStackScenarios, Clear) { U32 items[State::capacity]; State::ExternalStack stack(items, State::capacity); State state(stack); diff --git a/Fw/DataStructures/test/ut/FifoQueueTest.cpp b/Fw/DataStructures/test/ut/FifoQueueTest.cpp index fcc6d8ca9a9..7f804885448 100644 --- a/Fw/DataStructures/test/ut/FifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/FifoQueueTest.cpp @@ -158,13 +158,13 @@ TEST(FifoQueue, CopyDataFrom) { } } -TEST(FifoQueueRules, EnqueueOK) { +TEST(FifoQueueTestScenarios, EnqueueOK) { State::Queue queue; State state(queue); Rules::enqueueOK.apply(state); } -TEST(FifoQueueRules, EnqueueFull) { +TEST(FifoQueueTestScenarios, EnqueueFull) { State::Queue queue; State state(queue); for (FwSizeType i = 0; i < State::capacity; i++) { @@ -173,27 +173,27 @@ TEST(FifoQueueRules, EnqueueFull) { Rules::enqueueFull.apply(state); } -TEST(FifoQueueRules, At) { +TEST(FifoQueueTestScenarios, At) { State::Queue queue; State state(queue); Rules::enqueueOK.apply(state); Rules::at.apply(state); } -TEST(FifoQueueRules, DequeueOK) { +TEST(FifoQueueTestScenarios, DequeueOK) { State::Queue queue; State state(queue); Rules::enqueueOK.apply(state); Rules::dequeueOK.apply(state); } -TEST(FifoQueueRules, DequeueEmpty) { +TEST(FifoQueueTestScenarios, DequeueEmpty) { State::Queue queue; State state(queue); Rules::dequeueEmpty.apply(state); } -TEST(FifoQueueRules, Clear) { +TEST(FifoQueueTestScenarios, Clear) { State::Queue queue; State state(queue); Rules::enqueueOK.apply(state); diff --git a/Fw/DataStructures/test/ut/StackTest.cpp b/Fw/DataStructures/test/ut/StackTest.cpp index 8eac3361a40..974cbd2c4d3 100644 --- a/Fw/DataStructures/test/ut/StackTest.cpp +++ b/Fw/DataStructures/test/ut/StackTest.cpp @@ -160,13 +160,13 @@ TEST(Stack, CopyDataFrom) { } } -TEST(StackRules, PushOK) { +TEST(StackScenarios, PushOK) { State::Stack stack; State state(stack); Rules::pushOK.apply(state); } -TEST(StackRules, PushFull) { +TEST(StackScenarios, PushFull) { State::Stack stack; State state(stack); for (FwSizeType i = 0; i < State::capacity; i++) { @@ -175,7 +175,7 @@ TEST(StackRules, PushFull) { Rules::pushFull.apply(state); } -TEST(StackRules, At) { +TEST(StackScenarios, At) { State::Stack stack; State state(stack); Rules::pushOK.apply(state); @@ -184,20 +184,20 @@ TEST(StackRules, At) { } } -TEST(StackRules, PopOK) { +TEST(StackScenarios, PopOK) { State::Stack stack; State state(stack); Rules::pushOK.apply(state); Rules::popOK.apply(state); } -TEST(StackRules, PopEmpty) { +TEST(StackScenarios, PopEmpty) { State::Stack stack; State state(stack); Rules::popEmpty.apply(state); } -TEST(StackRules, Clear) { +TEST(StackScenarios, Clear) { State::Stack stack; State state(stack); Rules::pushOK.apply(state); From bf01d81c013d0811735b20a3851a2e92e849c3eb Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 8 Jul 2025 10:19:17 -0700 Subject: [PATCH 329/458] Refactor SetTestScenarios --- Fw/DataStructures/test/ut/ArraySetTest.cpp | 34 +++---------- .../test/ut/ExternalArraySetTest.cpp | 36 ++++--------- .../test/ut/STest/SetTestScenarios.cpp | 51 +++++++++++++++++++ .../test/ut/STest/SetTestScenarios.hpp | 16 ++++++ 4 files changed, 84 insertions(+), 53 deletions(-) diff --git a/Fw/DataStructures/test/ut/ArraySetTest.cpp b/Fw/DataStructures/test/ut/ArraySetTest.cpp index e2138222184..44c65eab2c4 100644 --- a/Fw/DataStructures/test/ut/ArraySetTest.cpp +++ b/Fw/DataStructures/test/ut/ArraySetTest.cpp @@ -91,67 +91,49 @@ TEST(ArraySet, CopyDataFrom) { TEST(ArraySetScenarios, Clear) { Set set; State state(set); - Rules::insertNotFull.apply(state); - ASSERT_EQ(state.set.getSize(), 1); - Rules::clear.apply(state); - ASSERT_EQ(state.set.getSize(), 0); + Scenarios::clear(state); } TEST(ArraySetScenarios, Find) { Set set; State state(set); - Rules::find.apply(state); - state.useStoredElement = true; - Rules::insertNotFull.apply(state); - Rules::find.apply(state); + Scenarios::find(state); } TEST(ArraySetScenarios, FindExisting) { Set set; State state(set); - Rules::insertNotFull.apply(state); - Rules::findExisting.apply(state); + Scenarios::findExisting(state); } TEST(ArraySetScenarios, InsertExisting) { Set set; State state(set); - Rules::insertNotFull.apply(state); - Rules::insertExisting.apply(state); + Scenarios::insertExisting(state); } TEST(ArraySetScenarios, InsertFull) { Set set; State state(set); - state.useStoredElement = true; - for (FwSizeType i = 0; i < State::capacity; i++) { - state.storedElement = static_cast(i); - Rules::insertNotFull.apply(state); - } - state.useStoredElement = false; - Rules::insertFull.apply(state); + Scenarios::insertFull(state); } TEST(ArraySetScenarios, InsertNotFull) { Set set; State state(set); - Rules::insertNotFull.apply(state); + Scenarios::insertNotFull(state); } TEST(ArraySetScenarios, Remove) { Set set; State state(set); - state.useStoredElement = true; - Rules::insertNotFull.apply(state); - Rules::remove.apply(state); - Rules::remove.apply(state); + Scenarios::remove(state); } TEST(ArraySetScenarios, RemoveExisting) { Set set; State state(set); - Rules::insertNotFull.apply(state); - Rules::removeExisting.apply(state); + Scenarios::removeExisting(state); } TEST(ArraySetScenarios, Random) { diff --git a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp index d6af83eba5c..6efc60994ee 100644 --- a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp @@ -119,77 +119,59 @@ TEST(ExternalArraySet, CopyDataFrom) { } TEST(ExternalArraySetScenarios, Clear) { - Entry entries[State::capacity]; + Entry entries[State::capacity]; Set set(entries, State::capacity); State state(set); - Rules::insertNotFull.apply(state); - ASSERT_EQ(state.set.getSize(), 1); - Rules::clear.apply(state); - ASSERT_EQ(state.set.getSize(), 0); + Scenarios::clear(state); } TEST(ExternalArraySetScenarios, Find) { Entry entries[State::capacity]; Set set(entries, State::capacity); State state(set); - Rules::find.apply(state); - state.useStoredElement = true; - Rules::insertNotFull.apply(state); - Rules::find.apply(state); + Scenarios::find(state); } TEST(ExternalArraySetScenarios, FindExisting) { Entry entries[State::capacity]; Set set(entries, State::capacity); State state(set); - Rules::insertNotFull.apply(state); - Rules::findExisting.apply(state); + Scenarios::findExisting(state); } TEST(ExternalArraySetScenarios, InsertExisting) { Entry entries[State::capacity]; Set set(entries, State::capacity); State state(set); - Rules::insertNotFull.apply(state); - Rules::insertExisting.apply(state); + Scenarios::insertExisting(state); } TEST(ExternalArraySetScenarios, InsertFull) { Entry entries[State::capacity]; Set set(entries, State::capacity); State state(set); - state.useStoredElement = true; - for (FwSizeType i = 0; i < State::capacity; i++) { - state.storedElement = static_cast(i); - Rules::insertNotFull.apply(state); - } - state.useStoredElement = false; - Rules::insertFull.apply(state); + Scenarios::insertFull(state); } TEST(ExternalArraySetScenarios, InsertNotFull) { Entry entries[State::capacity]; Set set(entries, State::capacity); State state(set); - Rules::insertNotFull.apply(state); + Scenarios::insertNotFull(state); } TEST(ExternalArraySetScenarios, Remove) { Entry entries[State::capacity]; Set set(entries, State::capacity); State state(set); - state.useStoredElement = true; - Rules::insertNotFull.apply(state); - Rules::remove.apply(state); - Rules::remove.apply(state); + Scenarios::remove(state); } TEST(ExternalArraySetScenarios, RemoveExisting) { Entry entries[State::capacity]; Set set(entries, State::capacity); State state(set); - Rules::insertNotFull.apply(state); - Rules::removeExisting.apply(state); + Scenarios::removeExisting(state); } TEST(ExternalArraySetScenarios, Random) { diff --git a/Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp index 48cf6fd3366..641edbcbf74 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp +++ b/Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp @@ -15,6 +15,57 @@ namespace SetTest { namespace Scenarios { + +void clear(State& state) { + Rules::insertNotFull.apply(state); + ASSERT_EQ(state.set.getSize(), 1); + Rules::clear.apply(state); + ASSERT_EQ(state.set.getSize(), 0); +} + +void find(State& state) { + Rules::find.apply(state); + state.useStoredElement = true; + Rules::insertNotFull.apply(state); + Rules::find.apply(state); +} + +void findExisting(State& state) { + Rules::insertNotFull.apply(state); + Rules::findExisting.apply(state); +} + +void insertExisting(State& state) { + Rules::insertNotFull.apply(state); + Rules::insertExisting.apply(state); +} + +void insertFull(State& state) { + state.useStoredElement = true; + for (FwSizeType i = 0; i < State::capacity; i++) { + state.storedElement = static_cast(i); + Rules::insertNotFull.apply(state); + } + state.useStoredElement = false; + Rules::insertFull.apply(state); +} + +void insertNotFull(State& state) { + Rules::insertNotFull.apply(state); +} + +void remove(State& state) { + state.useStoredElement = true; + Rules::insertNotFull.apply(state); + Rules::remove.apply(state); + Rules::remove.apply(state); +} + +void removeExisting(State& state) { + Rules::insertNotFull.apply(state); + Rules::removeExisting.apply(state); +} + void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { Rule* rules[] = { &Rules::clear, diff --git a/Fw/DataStructures/test/ut/STest/SetTestScenarios.hpp b/Fw/DataStructures/test/ut/STest/SetTestScenarios.hpp index 88cb31bee19..2f44e8b16d4 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestScenarios.hpp +++ b/Fw/DataStructures/test/ut/STest/SetTestScenarios.hpp @@ -15,6 +15,22 @@ namespace SetTest { namespace Scenarios { +void clear(State& state); + +void find(State& state); + +void findExisting(State& state); + +void insertExisting(State& state); + +void insertFull(State& state); + +void insertNotFull(State& state); + +void remove(State& state); + +void removeExisting(State& state); + void random(const Fw::StringBase& name, State& state, U32 maxNumSteps); } // namespace Scenarios From 4eab013bd9092a4405947d5cdc002be451730da1 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 8 Jul 2025 10:55:03 -0700 Subject: [PATCH 330/458] Refactor FifoQueueTestScenarios --- Fw/DataStructures/test/ut/FifoQueueTest.cpp | 30 +++++++---------- .../test/ut/STest/FifoQueueTestScenarios.cpp | 32 +++++++++++++++++++ .../test/ut/STest/FifoQueueTestScenarios.hpp | 12 +++++++ 3 files changed, 55 insertions(+), 19 deletions(-) diff --git a/Fw/DataStructures/test/ut/FifoQueueTest.cpp b/Fw/DataStructures/test/ut/FifoQueueTest.cpp index 7f804885448..c157d76112b 100644 --- a/Fw/DataStructures/test/ut/FifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/FifoQueueTest.cpp @@ -158,48 +158,40 @@ TEST(FifoQueue, CopyDataFrom) { } } -TEST(FifoQueueTestScenarios, EnqueueOK) { +TEST(FifoQueueTestScenarios, At) { State::Queue queue; State state(queue); - Rules::enqueueOK.apply(state); + Scenarios::at(state); } -TEST(FifoQueueTestScenarios, EnqueueFull) { +TEST(FifoQueueTestScenarios, Clear) { State::Queue queue; State state(queue); - for (FwSizeType i = 0; i < State::capacity; i++) { - Rules::enqueueOK.apply(state); - } - Rules::enqueueFull.apply(state); + Scenarios::clear(state); } -TEST(FifoQueueTestScenarios, At) { +TEST(FifoQueueTestScenarios, DequeueEmpty) { State::Queue queue; State state(queue); - Rules::enqueueOK.apply(state); - Rules::at.apply(state); + Scenarios::dequeueEmpty(state); } TEST(FifoQueueTestScenarios, DequeueOK) { State::Queue queue; State state(queue); - Rules::enqueueOK.apply(state); - Rules::dequeueOK.apply(state); + Scenarios::dequeueOK(state); } -TEST(FifoQueueTestScenarios, DequeueEmpty) { +TEST(FifoQueueTestScenarios, EnqueueFull) { State::Queue queue; State state(queue); - Rules::dequeueEmpty.apply(state); + Scenarios::enqueueFull(state); } -TEST(FifoQueueTestScenarios, Clear) { +TEST(FifoQueueTestScenarios, EnqueueOK) { State::Queue queue; State state(queue); - Rules::enqueueOK.apply(state); - ASSERT_EQ(state.queue.getSize(), 1); - Rules::clear.apply(state); - ASSERT_EQ(state.queue.getSize(), 0); + Scenarios::enqueueOK(state); } TEST(FifoQueueScenarios, Random) { diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.cpp index 90a204e1557..1fb706081ef 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.cpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.cpp @@ -15,6 +15,38 @@ namespace FifoQueueTest { namespace Scenarios { +void at(State& state) { + Rules::enqueueOK.apply(state); + Rules::at.apply(state); +} + +void clear(State& state) { + Rules::enqueueOK.apply(state); + ASSERT_EQ(state.queue.getSize(), 1); + Rules::clear.apply(state); + ASSERT_EQ(state.queue.getSize(), 0); +} + +void dequeueEmpty(State& state) { + Rules::dequeueEmpty.apply(state); +} + +void dequeueOK(State& state) { + Rules::enqueueOK.apply(state); + Rules::dequeueOK.apply(state); +} + +void enqueueFull(State& state) { + for (FwSizeType i = 0; i < State::capacity; i++) { + Rules::enqueueOK.apply(state); + } + Rules::enqueueFull.apply(state); +} + +void enqueueOK(State& state) { + Rules::enqueueOK.apply(state); +} + void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { Rule* rules[] = {&Rules::enqueueOK, &Rules::enqueueFull, &Rules::at, &Rules::dequeueOK, &Rules::dequeueEmpty, &Rules::clear}; diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp index fae0eb6fb5f..437e9238e3e 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp @@ -15,6 +15,18 @@ namespace FifoQueueTest { namespace Scenarios { +void at(State& state); + +void clear(State& state); + +void dequeueEmpty(State& state); + +void dequeueOK(State& state); + +void enqueueFull(State& state); + +void enqueueOK(State& state); + void random(const Fw::StringBase& name, State& state, U32 maxNumSteps); } // namespace Scenarios From 7ba06bdb1e2910d6c9cf982faf69ea74f0204385 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 8 Jul 2025 11:19:18 -0700 Subject: [PATCH 331/458] Refactor ExternalFifoQueueTest --- .../test/ut/ExternalFifoQueueTest.cpp | 153 +++++++++--------- 1 file changed, 74 insertions(+), 79 deletions(-) diff --git a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp index 32ea40b0f5c..d1501a2b4d2 100644 --- a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp @@ -26,17 +26,20 @@ class ExternalFifoQueueTester { namespace FifoQueueTest { +using Queue = ExternalFifoQueue; +using QueueTester = ExternalFifoQueueTester; + TEST(ExternalFifoQueue, ZeroArgConstructor) { - ExternalFifoQueue queue; + Queue queue; ASSERT_EQ(queue.getCapacity(), 0); ASSERT_EQ(queue.getSize(), 0); } TEST(ExternalFifoQueue, TypedStorageConstructor) { constexpr FwSizeType capacity = 10; - U32 items[capacity]; - ExternalFifoQueue queue(items, capacity); - ExternalFifoQueueTester tester(queue); + State::ItemType items[capacity]; + Queue queue(items, capacity); + QueueTester tester(queue); ASSERT_EQ(tester.getItems().getElements(), items); ASSERT_EQ(queue.getCapacity(), capacity); ASSERT_EQ(queue.getSize(), 0); @@ -44,12 +47,12 @@ TEST(ExternalFifoQueue, TypedStorageConstructor) { TEST(ExternalFifoQueue, UntypedStorageConstructor) { constexpr FwSizeType capacity = 10; - constexpr U8 alignment = ExternalFifoQueue::getByteArrayAlignment(); - constexpr FwSizeType byteArraySize = ExternalFifoQueue::getByteArraySize(capacity); + constexpr U8 alignment = Queue::getByteArrayAlignment(); + constexpr FwSizeType byteArraySize = Queue::getByteArraySize(capacity); alignas(alignment) U8 bytes[byteArraySize]; - ExternalFifoQueue queue(ByteArray(&bytes[0], sizeof bytes), capacity); - ExternalFifoQueueTester tester(queue); - ASSERT_EQ(tester.getItems().getElements(), reinterpret_cast(bytes)); + Queue queue(ByteArray(&bytes[0], sizeof bytes), capacity); + QueueTester tester(queue); + ASSERT_EQ(tester.getItems().getElements(), reinterpret_cast(bytes)); ASSERT_EQ(queue.getCapacity(), capacity); ASSERT_EQ(queue.getSize(), 0); } @@ -57,21 +60,21 @@ TEST(ExternalFifoQueue, UntypedStorageConstructor) { TEST(ExternalFifoQueue, EnqueueOK) { constexpr const FwSizeType capacity = 1000; const FwSizeType size = STest::Pick::lowerUpper(1, capacity); - U32 elts[capacity]; - ExternalFifoQueue queue(elts, capacity); + State::ItemType elts[capacity]; + Queue queue(elts, capacity); ASSERT_EQ(queue.getCapacity(), capacity); ASSERT_EQ(queue.getSize(), 0); for (FwSizeType i = 0; i < size; i++) { - // Pick a value - const U32 val = STest::Pick::any(); + // Pick an item + const auto item = State::getRandomItem(); // Enqueue it - auto status = queue.enqueue(val); + auto status = queue.enqueue(item); ASSERT_EQ(status, Success::SUCCESS); // Peek it - U32 val1 = 0; - status = queue.peek(val1, i); + State::ItemType item1 = 0; + status = queue.peek(item1, i); ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(val1, val); + ASSERT_EQ(item1, item); // Check the size ASSERT_EQ(queue.getSize(), i + 1); } @@ -81,32 +84,32 @@ TEST(ExternalFifoQueue, EnqueueOK) { TEST(ExternalFifoQueue, EnqueueFull) { constexpr const FwSizeType capacity = 1000; - U32 elts[capacity]; - ExternalFifoQueue queue(elts, capacity); + State::ItemType elts[capacity]; + Queue queue(elts, capacity); // Fill up the FIFO for (FwSizeType i = 0; i < capacity; i++) { const auto status = queue.enqueue(0); ASSERT_EQ(status, Success::SUCCESS); } // Now try to push another element - const U32 val = STest::Pick::any(); - const auto status = queue.enqueue(val); + const auto item = State::getRandomItem(); + const auto status = queue.enqueue(item); // Push should fail ASSERT_EQ(status, Success::FAILURE); } TEST(ExternalFifoQueue, CopyConstructor) { constexpr FwSizeType capacity = 3; - U32 items[capacity]; + State::ItemType items[capacity]; // Call the constructor providing backing storage - ExternalFifoQueue q1(items, capacity); + Queue q1(items, capacity); // Enqueue an item - U32 value = 42; - (void)q1.enqueue(value); + State::ItemType item = State::getRandomItem(); + (void)q1.enqueue(item); // Call the copy constructor - ExternalFifoQueue q2(q1); - ExternalFifoQueueTester tester1(q1); - ExternalFifoQueueTester tester2(q2); + Queue q2(q1); + QueueTester tester1(q1); + QueueTester tester2(q2); ASSERT_EQ(tester2.getItems().getElements(), items); ASSERT_EQ(tester2.getItems().getSize(), capacity); ASSERT_EQ(tester2.getEnqueueIndex().getValue(), 1); @@ -116,14 +119,14 @@ TEST(ExternalFifoQueue, CopyConstructor) { TEST(ExternalFifoQueue, CopyAssignmentOperator) { constexpr FwSizeType capacity = 3; - U32 items[capacity]; + State::ItemType items[capacity]; // Call the constructor providing backing storage - ExternalFifoQueue q1(items, capacity); + Queue q1(items, capacity); // Enqueue an item - U32 value = 42; - (void)q1.enqueue(value); + State::ItemType item = State::getRandomItem(); + (void)q1.enqueue(item); // Call the default constructor - ExternalFifoQueue q2; + Queue q2; ASSERT_EQ(q2.getSize(), 0); // Call the copy assignment operator q2 = q1; @@ -133,29 +136,29 @@ TEST(ExternalFifoQueue, CopyAssignmentOperator) { TEST(ExternalFifoQueue, DequeueOK) { constexpr const FwSizeType capacity = 1000; const FwSizeType size = STest::Pick::lowerUpper(1, capacity); - U32 items[capacity]; - ExternalFifoQueue queue(items, capacity); + State::ItemType items[capacity]; + Queue queue(items, capacity); ASSERT_EQ(queue.getCapacity(), capacity); ASSERT_EQ(queue.getSize(), 0); for (FwSizeType i = 0; i < size; i++) { - // Pick a value - const U32 val = STest::Pick::any(); + // Pick an item + const auto item = State::getRandomItem(); // Enqueue it - const auto status = queue.enqueue(val); - ASSERT_EQ(val, items[i]); + const auto status = queue.enqueue(item); + ASSERT_EQ(item, items[i]); ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(queue.getSize(), i + 1); } for (FwSizeType i = 0; i < size; i++) { - U32 val = 0; + State::ItemType item = 0; // Peek - auto status = queue.peek(val); + auto status = queue.peek(item); ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(val, items[i]); + ASSERT_EQ(item, items[i]); // Dequeue it - status = queue.dequeue(val); + status = queue.dequeue(item); ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(val, items[i]); + ASSERT_EQ(item, items[i]); ASSERT_EQ(queue.getSize(), size - i - 1); } ASSERT_EQ(queue.getSize(), 0); @@ -163,88 +166,80 @@ TEST(ExternalFifoQueue, DequeueOK) { TEST(ExternalFifoQueue, DequeueEmpty) { constexpr const FwSizeType capacity = 1000; - U32 items[capacity]; - ExternalFifoQueue queue(items, capacity); - U32 val = 0; - const auto status = queue.dequeue(val); + State::ItemType items[capacity]; + Queue queue(items, capacity); + State::ItemType item = 0; + const auto status = queue.dequeue(item); ASSERT_EQ(status, Success::FAILURE); } TEST(ExternalFifoQueue, CopyDataFrom) { constexpr FwSizeType maxSize = 10; constexpr FwSizeType smallSize = maxSize / 2; - U32 items1[maxSize]; - U32 items2[maxSize]; - ExternalFifoQueue q1(items1, maxSize); + State::ItemType items1[maxSize]; + State::ItemType items2[maxSize]; + Queue q1(items1, maxSize); // size1 < capacity2 { - ExternalFifoQueue q2(items2, maxSize); + Queue q2(items2, maxSize); State::testCopyDataFrom(q1, smallSize, q2); } // size1 == size2 { - ExternalFifoQueue q2(items2, maxSize); + Queue q2(items2, maxSize); State::testCopyDataFrom(q1, maxSize, q2); } // size1 > size2 { - ExternalFifoQueue q2(items2, smallSize); + Queue q2(items2, smallSize); State::testCopyDataFrom(q1, maxSize, q2); } } -TEST(ExternalFifoQueueScenarios, EnqueueOK) { - U32 items[State::capacity]; +TEST(ExternalFifoQueueScenarios, At) { + State::ItemType items[State::capacity]; State::ExternalQueue queue(items, State::capacity); State state(queue); - Rules::enqueueOK.apply(state); + Scenarios::enqueueOK(state); } -TEST(ExternalFifoQueueScenarios, EnqueueFull) { - U32 items[State::capacity]; +TEST(ExternalFifoQueueScenarios, Clear) { + State::ItemType items[State::capacity]; State::ExternalQueue queue(items, State::capacity); State state(queue); - for (FwSizeType i = 0; i < State::capacity; i++) { - Rules::enqueueOK.apply(state); - } - Rules::enqueueFull.apply(state); + Scenarios::clear(state); } -TEST(ExternalFifoQueueScenarios, At) { - U32 items[State::capacity]; +TEST(ExternalFifoQueueScenarios, DequeueEmpty) { + State::ItemType items[State::capacity]; State::ExternalQueue queue(items, State::capacity); State state(queue); - Rules::enqueueOK.apply(state); - Rules::at.apply(state); + Scenarios::dequeueEmpty(state); } TEST(ExternalFifoQueueScenarios, DequeueOK) { - U32 items[State::capacity]; + State::ItemType items[State::capacity]; State::ExternalQueue queue(items, State::capacity); State state(queue); - Rules::enqueueOK.apply(state); - Rules::dequeueOK.apply(state); + Scenarios::dequeueOK(state); } -TEST(ExternalFifoQueueScenarios, DequeueEmpty) { - U32 items[State::capacity]; +TEST(ExternalFifoQueueScenarios, EnqueueFull) { + State::ItemType items[State::capacity]; State::ExternalQueue queue(items, State::capacity); State state(queue); - Rules::dequeueEmpty.apply(state); + Scenarios::enqueueFull(state); } -TEST(ExternalFifoQueueScenarios, Clear) { - U32 items[State::capacity]; +TEST(ExternalFifoQueueScenarios, EnqueueOK) { + State::ItemType items[State::capacity]; State::ExternalQueue queue(items, State::capacity); State state(queue); Rules::enqueueOK.apply(state); - ASSERT_EQ(state.queue.getSize(), 1); - Rules::clear.apply(state); - ASSERT_EQ(state.queue.getSize(), 0); } TEST(ExternalFifoQueueScenarios, Random) { - U32 items[State::capacity]; + State::ItemType items[State::capacity]; State::ExternalQueue queue(items, State::capacity); State state(queue); Scenarios::random(Fw::String("ExternalFifoQueueRandom"), state, 1000); From 3b6c1dfc655ac944d8d9df4faa603a4cb7773d80 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 8 Jul 2025 11:58:28 -0700 Subject: [PATCH 332/458] Revise Fifo Queue tests --- .../test/ut/ExternalFifoQueueTest.cpp | 9 ++ Fw/DataStructures/test/ut/FifoQueueTest.cpp | 103 +++++++++--------- .../test/ut/STest/FifoQueueTestRules.cpp | 12 +- .../test/ut/STest/FifoQueueTestRules.hpp | 96 +++++++++------- .../test/ut/STest/FifoQueueTestScenarios.cpp | 15 ++- .../test/ut/STest/FifoQueueTestScenarios.hpp | 2 + 6 files changed, 140 insertions(+), 97 deletions(-) diff --git a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp index d1501a2b4d2..7d1dd9658e8 100644 --- a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp @@ -238,6 +238,15 @@ TEST(ExternalFifoQueueScenarios, EnqueueOK) { Rules::enqueueOK.apply(state); } +TEST(ExternalFifoQueueTestScenarios, Peek) { + State::ItemType items[State::capacity]; + State::ExternalQueue queue(items, State::capacity); + State state(queue); + Scenarios::enqueueOK(state); + Scenarios::enqueueOK(state); + Scenarios::peek(state); +} + TEST(ExternalFifoQueueScenarios, Random) { State::ItemType items[State::capacity]; State::ExternalQueue queue(items, State::capacity); diff --git a/Fw/DataStructures/test/ut/FifoQueueTest.cpp b/Fw/DataStructures/test/ut/FifoQueueTest.cpp index c157d76112b..3bbd58f3092 100644 --- a/Fw/DataStructures/test/ut/FifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/FifoQueueTest.cpp @@ -24,43 +24,44 @@ class FifoQueueTester { namespace FifoQueueTest { +using Queue = FifoQueue; +using QueueTester = FifoQueueTester; + TEST(FifoQueue, ZeroArgConstructor) { - constexpr FwSizeType C = 10; - FifoQueue queue; - ASSERT_EQ(queue.getCapacity(), C); + Queue queue; + ASSERT_EQ(queue.getCapacity(), FwSizeType(State::capacity)); ASSERT_EQ(queue.getSize(), 0); } TEST(FifoQueue, CopyConstructor) { - constexpr FwSizeType capacity = 3; // Construct q1 - FifoQueue q1; + Queue q1; // Enqueue an item - U32 value = 42; - (void)q1.enqueue(value); + const auto item = State::getRandomItem(); + const auto status = q1.enqueue(item); + ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(q1.getSize(), 1); // Use the copy constructor to construct q2 - FifoQueue q2(q1); + Queue q2(q1); ASSERT_EQ(q2.getSize(), 1); } TEST(FifoQueue, EnqueueOK) { - constexpr const FwSizeType capacity = 1000; - const FwSizeType size = STest::Pick::lowerUpper(1, capacity); - FifoQueue queue; - ASSERT_EQ(queue.getCapacity(), capacity); + const FwSizeType size = STest::Pick::lowerUpper(1, State::capacity); + Queue queue; + ASSERT_EQ(queue.getCapacity(), FwSizeType(State::capacity)); ASSERT_EQ(queue.getSize(), 0); for (FwSizeType i = 0; i < size; i++) { // Pick a value - const U32 val = STest::Pick::any(); + const auto item = State::getRandomItem(); // Enqueue it - auto status = queue.enqueue(val); + auto status = queue.enqueue(item); ASSERT_EQ(status, Success::SUCCESS); // Peek it - U32 val1 = 0; - status = queue.peek(val1, i); + State::ItemType item1 = 0; + status = queue.peek(item1, i); ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(val1, val); + ASSERT_EQ(item1, item); // Check the size ASSERT_EQ(queue.getSize(), i + 1); } @@ -69,10 +70,9 @@ TEST(FifoQueue, EnqueueOK) { } TEST(FifoQueue, EnqueueFull) { - constexpr const FwSizeType capacity = 1000; - FifoQueue queue; + Queue queue; // Fill up the FIFO - for (FwSizeType i = 0; i < capacity; i++) { + for (FwSizeType i = 0; i < State::capacity; i++) { const auto status = queue.enqueue(0); ASSERT_EQ(status, Success::SUCCESS); } @@ -84,14 +84,13 @@ TEST(FifoQueue, EnqueueFull) { } TEST(FifoQueue, CopyAssignmentOperator) { - constexpr FwSizeType capacity = 3; // Call the constructor providing backing storage - FifoQueue q1; + Queue q1; // Enqueue an item - U32 value = 42; - (void)q1.enqueue(value); + const auto item = State::getRandomItem(); + (void)q1.enqueue(item); // Call the default constructor - FifoQueue q2; + Queue q2; ASSERT_EQ(q2.getSize(), 0); // Call the copy assignment operator q2 = q1; @@ -99,61 +98,59 @@ TEST(FifoQueue, CopyAssignmentOperator) { } TEST(FifoQueue, DequeueOK) { - constexpr const FwSizeType capacity = 1000; - const FwSizeType size = STest::Pick::lowerUpper(1, capacity); - U32 items[capacity]; - FifoQueue queue; - ASSERT_EQ(queue.getCapacity(), capacity); + const FwSizeType size = STest::Pick::lowerUpper(1, State::capacity); + State::ItemType items[State::capacity]; + Queue queue; + ASSERT_EQ(queue.getCapacity(), FwSizeType(State::capacity)); ASSERT_EQ(queue.getSize(), 0); for (FwSizeType i = 0; i < size; i++) { // Pick a value - const U32 val = STest::Pick::any(); + const auto item = State::getRandomItem(); // Enqueue it - const auto status = queue.enqueue(val); - items[i] = val; + const auto status = queue.enqueue(item); + items[i] = item; ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(queue.getSize(), i + 1); } for (FwSizeType i = 0; i < size; i++) { - U32 val = 0; + State::ItemType item = 0; // Peek - auto status = queue.peek(val); + auto status = queue.peek(item); ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(val, items[i]); + ASSERT_EQ(item, items[i]); // Dequeue it - status = queue.dequeue(val); + status = queue.dequeue(item); ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(val, items[i]); + ASSERT_EQ(item, items[i]); ASSERT_EQ(queue.getSize(), size - i - 1); } ASSERT_EQ(queue.getSize(), 0); } TEST(FifoQueue, DequeueEmpty) { - constexpr const FwSizeType capacity = 1000; - FifoQueue queue; - U32 val = 0; - const auto status = queue.dequeue(val); + Queue queue; + State::ItemType item = 0; + const auto status = queue.dequeue(item); ASSERT_EQ(status, Success::FAILURE); } TEST(FifoQueue, CopyDataFrom) { - constexpr FwSizeType maxSize = 10; + constexpr FwSizeType maxSize = State::capacity; constexpr FwSizeType smallSize = maxSize / 2; - FifoQueue q1; + Queue q1; // size1 < capacity2 { - FifoQueue q2; + Queue q2; State::testCopyDataFrom(q1, smallSize, q2); } - // size1 == size2 + // size1 == capacity2 { - FifoQueue q2; + Queue q2; State::testCopyDataFrom(q1, maxSize, q2); } - // size1 > size2 + // size1 > capacity2 { - FifoQueue q2; + FifoQueue q2; State::testCopyDataFrom(q1, maxSize, q2); } } @@ -194,6 +191,14 @@ TEST(FifoQueueTestScenarios, EnqueueOK) { Scenarios::enqueueOK(state); } +TEST(FifoQueueTestScenarios, Peek) { + State::Queue queue; + State state(queue); + Scenarios::enqueueOK(state); + Scenarios::enqueueOK(state); + Scenarios::peek(state); +} + TEST(FifoQueueScenarios, Random) { State::Queue queue; State state(queue); diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.cpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.cpp index 8f86c270235..d6214f23f41 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.cpp @@ -12,17 +12,19 @@ namespace FifoQueueTest { namespace Rules { -EnqueueOK enqueueOK; +At at; -EnqueueFull enqueueFull; +Clear clear; -At at; +DequeueEmpty dequeueEmpty; DequeueOK dequeueOK; -DequeueEmpty dequeueEmpty; +EnqueueFull enqueueFull; -Clear clear; +EnqueueOK enqueueOK; + +Peek peek; }; // namespace Rules diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp index e813268a138..2ac2ee29524 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp @@ -21,82 +21,96 @@ using Rule = STest::Rule; namespace Rules { -struct EnqueueOK : public Rule { - EnqueueOK() : Rule("EnqueueOK") {} - bool precondition(const State& state) { return static_cast(state.queue.getSize()) < State::capacity; } +struct At : public Rule { + At() : Rule("At") {} + bool precondition(const State& state) { return state.queue.getSize() > 0; } void action(State& state) { - const U32 value = STest::Pick::any(); - const auto status = state.queue.enqueue(value); - ASSERT_EQ(status, Success::SUCCESS); - state.modelQueue.push_back(value); + const auto index = STest::Pick::startLength(0, static_cast(state.queue.getSize())); + ASSERT_EQ(state.queue.at(index), state.modelQueue.at(index)); } }; -extern EnqueueOK enqueueOK; - -struct EnqueueFull : public Rule { - EnqueueFull() : Rule("EnqueueFull") {} - bool precondition(const State& state) { return static_cast(state.queue.getSize()) >= State::capacity; } +struct Clear : public Rule { + Clear() : Rule("Clear") {} + bool precondition(const State& state) { return state.queue.getSize() > 0; } void action(State& state) { - const auto item = State::getRandomItem(); - const auto status = state.queue.enqueue(item); - ASSERT_EQ(status, Success::FAILURE); + state.queue.clear(); + ASSERT_EQ(state.queue.getSize(), 0); + state.modelQueue.clear(); } }; -extern EnqueueFull enqueueFull; - -struct At : public Rule { - At() : Rule("At") {} - bool precondition(const State& state) { return state.queue.getSize() > 0; } +struct DequeueEmpty : public Rule { + DequeueEmpty() : Rule("DequeueEmpty") {} + bool precondition(const State& state) { return static_cast(state.queue.getSize()) == 0; } void action(State& state) { - const auto index = STest::Pick::startLength(0, static_cast(state.queue.getSize())); - ASSERT_EQ(state.queue.at(index), state.modelQueue.at(index)); + State::ItemType item = 0; + const auto status = state.queue.dequeue(item); + ASSERT_EQ(status, Success::FAILURE); } }; -extern At at; - struct DequeueOK : public Rule { DequeueOK() : Rule("DequeueOK") {} bool precondition(const State& state) { return static_cast(state.queue.getSize()) > 0; } void action(State& state) { - U32 value = 0; - const auto status = state.queue.dequeue(value); + State::ItemType item = 0; + const auto status = state.queue.dequeue(item); ASSERT_EQ(status, Success::SUCCESS); - const auto expectedValue = state.modelQueue.at(0); - ASSERT_EQ(value, expectedValue); + const auto expectedItem = state.modelQueue.at(0); + ASSERT_EQ(item, expectedItem); state.modelQueue.pop_front(); ASSERT_EQ(state.queue.getSize(), state.modelQueue.size()); } }; -extern DequeueOK dequeueOK; - -struct DequeueEmpty : public Rule { - DequeueEmpty() : Rule("DequeueEmpty") {} - bool precondition(const State& state) { return static_cast(state.queue.getSize()) == 0; } +struct EnqueueFull : public Rule { + EnqueueFull() : Rule("EnqueueFull") {} + bool precondition(const State& state) { return static_cast(state.queue.getSize()) >= State::capacity; } void action(State& state) { - U32 value = 0; - const auto status = state.queue.dequeue(value); + const auto item = State::getRandomItem(); + const auto status = state.queue.enqueue(item); ASSERT_EQ(status, Success::FAILURE); } }; -extern DequeueEmpty dequeueEmpty; +struct EnqueueOK : public Rule { + EnqueueOK() : Rule("EnqueueOK") {} + bool precondition(const State& state) { return static_cast(state.queue.getSize()) < State::capacity; } + void action(State& state) { + const auto item = State::getRandomItem(); + const auto status = state.queue.enqueue(item); + ASSERT_EQ(status, Success::SUCCESS); + state.modelQueue.push_back(item); + } +}; -struct Clear : public Rule { - Clear() : Rule("Clear") {} +struct Peek : public Rule { + Peek() : Rule("Peek") {} bool precondition(const State& state) { return state.queue.getSize() > 0; } void action(State& state) { - state.queue.clear(); - ASSERT_EQ(state.queue.getSize(), 0); - state.modelQueue.clear(); + const auto index = STest::Pick::startLength(0, static_cast(state.queue.getSize())); + State::ItemType item; + const auto status = state.queue.peek(item, index); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(item, state.modelQueue.at(index)); } }; +extern At at; + extern Clear clear; +extern DequeueEmpty dequeueEmpty; + +extern DequeueOK dequeueOK; + +extern EnqueueFull enqueueFull; + +extern EnqueueOK enqueueOK; + +extern Peek peek; + }; // namespace Rules } // namespace FifoQueueTest diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.cpp index 1fb706081ef..535cac41128 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.cpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.cpp @@ -47,9 +47,20 @@ void enqueueOK(State& state) { Rules::enqueueOK.apply(state); } +void peek(State& state) { + Rules::peek.apply(state); +} + void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { - Rule* rules[] = {&Rules::enqueueOK, &Rules::enqueueFull, &Rules::at, - &Rules::dequeueOK, &Rules::dequeueEmpty, &Rules::clear}; + Rule* rules[] = { + &Rules::at, + &Rules::clear, + &Rules::dequeueEmpty, + &Rules::dequeueOK, + &Rules::enqueueFull, + &Rules::enqueueOK, + &Rules::peek + }; STest::RandomScenario scenario("RandomScenario", rules, sizeof(rules) / sizeof(STest::RandomScenario*)); STest::BoundedScenario boundedScenario(name.toChar(), scenario, maxNumSteps); diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp index 437e9238e3e..bb89fbb1811 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp @@ -27,6 +27,8 @@ void enqueueFull(State& state); void enqueueOK(State& state); +void peek(State& state); + void random(const Fw::StringBase& name, State& state, U32 maxNumSteps); } // namespace Scenarios From c5734f59cdc46006c3d3202b167fd042263f7fb3 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 8 Jul 2025 15:58:46 -0700 Subject: [PATCH 333/458] Refactor ExternalFifoQueueTest --- .../test/ut/ExternalFifoQueueTest.cpp | 70 +++++++++---------- 1 file changed, 32 insertions(+), 38 deletions(-) diff --git a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp index 7d1dd9658e8..4f7cc08369c 100644 --- a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp @@ -36,33 +36,30 @@ TEST(ExternalFifoQueue, ZeroArgConstructor) { } TEST(ExternalFifoQueue, TypedStorageConstructor) { - constexpr FwSizeType capacity = 10; - State::ItemType items[capacity]; - Queue queue(items, capacity); + State::ItemType items[State::capacity]; + Queue queue(items, State::capacity); QueueTester tester(queue); ASSERT_EQ(tester.getItems().getElements(), items); - ASSERT_EQ(queue.getCapacity(), capacity); + ASSERT_EQ(queue.getCapacity(), FwSizeType(State::capacity)); ASSERT_EQ(queue.getSize(), 0); } TEST(ExternalFifoQueue, UntypedStorageConstructor) { - constexpr FwSizeType capacity = 10; constexpr U8 alignment = Queue::getByteArrayAlignment(); - constexpr FwSizeType byteArraySize = Queue::getByteArraySize(capacity); + constexpr FwSizeType byteArraySize = Queue::getByteArraySize(State::capacity); alignas(alignment) U8 bytes[byteArraySize]; - Queue queue(ByteArray(&bytes[0], sizeof bytes), capacity); + Queue queue(ByteArray(&bytes[0], sizeof bytes), State::capacity); QueueTester tester(queue); ASSERT_EQ(tester.getItems().getElements(), reinterpret_cast(bytes)); - ASSERT_EQ(queue.getCapacity(), capacity); + ASSERT_EQ(queue.getCapacity(), FwSizeType(State::capacity)); ASSERT_EQ(queue.getSize(), 0); } TEST(ExternalFifoQueue, EnqueueOK) { - constexpr const FwSizeType capacity = 1000; - const FwSizeType size = STest::Pick::lowerUpper(1, capacity); - State::ItemType elts[capacity]; - Queue queue(elts, capacity); - ASSERT_EQ(queue.getCapacity(), capacity); + const FwSizeType size = STest::Pick::lowerUpper(1, State::capacity); + State::ItemType elts[State::capacity]; + Queue queue(elts, State::capacity); + ASSERT_EQ(queue.getCapacity(), FwSizeType(State::capacity)); ASSERT_EQ(queue.getSize(), 0); for (FwSizeType i = 0; i < size; i++) { // Pick an item @@ -83,11 +80,10 @@ TEST(ExternalFifoQueue, EnqueueOK) { } TEST(ExternalFifoQueue, EnqueueFull) { - constexpr const FwSizeType capacity = 1000; - State::ItemType elts[capacity]; - Queue queue(elts, capacity); + State::ItemType elts[State::capacity]; + Queue queue(elts, State::capacity); // Fill up the FIFO - for (FwSizeType i = 0; i < capacity; i++) { + for (FwSizeType i = 0; i < State::capacity; i++) { const auto status = queue.enqueue(0); ASSERT_EQ(status, Success::SUCCESS); } @@ -99,32 +95,32 @@ TEST(ExternalFifoQueue, EnqueueFull) { } TEST(ExternalFifoQueue, CopyConstructor) { - constexpr FwSizeType capacity = 3; - State::ItemType items[capacity]; + State::ItemType items[State::capacity]; // Call the constructor providing backing storage - Queue q1(items, capacity); + Queue q1(items, State::capacity); // Enqueue an item State::ItemType item = State::getRandomItem(); - (void)q1.enqueue(item); + const auto status = q1.enqueue(item); + ASSERT_EQ(status, Success::SUCCESS); // Call the copy constructor Queue q2(q1); QueueTester tester1(q1); QueueTester tester2(q2); ASSERT_EQ(tester2.getItems().getElements(), items); - ASSERT_EQ(tester2.getItems().getSize(), capacity); + ASSERT_EQ(tester2.getItems().getSize(), FwSizeType(State::capacity)); ASSERT_EQ(tester2.getEnqueueIndex().getValue(), 1); ASSERT_EQ(tester2.getDequeueIndex().getValue(), 0); ASSERT_EQ(q2.getSize(), 1); } TEST(ExternalFifoQueue, CopyAssignmentOperator) { - constexpr FwSizeType capacity = 3; - State::ItemType items[capacity]; + State::ItemType items[State::capacity]; // Call the constructor providing backing storage - Queue q1(items, capacity); + Queue q1(items, State::capacity); // Enqueue an item - State::ItemType item = State::getRandomItem(); - (void)q1.enqueue(item); + const State::ItemType item = State::getRandomItem(); + const auto status = q1.enqueue(item); + ASSERT_EQ(status, Success::SUCCESS); // Call the default constructor Queue q2; ASSERT_EQ(q2.getSize(), 0); @@ -134,11 +130,10 @@ TEST(ExternalFifoQueue, CopyAssignmentOperator) { } TEST(ExternalFifoQueue, DequeueOK) { - constexpr const FwSizeType capacity = 1000; - const FwSizeType size = STest::Pick::lowerUpper(1, capacity); - State::ItemType items[capacity]; - Queue queue(items, capacity); - ASSERT_EQ(queue.getCapacity(), capacity); + const FwSizeType size = STest::Pick::lowerUpper(1, State::capacity); + State::ItemType items[State::capacity]; + Queue queue(items, State::capacity); + ASSERT_EQ(queue.getCapacity(), FwSizeType(State::capacity)); ASSERT_EQ(queue.getSize(), 0); for (FwSizeType i = 0; i < size; i++) { // Pick an item @@ -165,16 +160,15 @@ TEST(ExternalFifoQueue, DequeueOK) { } TEST(ExternalFifoQueue, DequeueEmpty) { - constexpr const FwSizeType capacity = 1000; - State::ItemType items[capacity]; - Queue queue(items, capacity); + State::ItemType items[State::capacity]; + Queue queue(items, State::capacity); State::ItemType item = 0; const auto status = queue.dequeue(item); ASSERT_EQ(status, Success::FAILURE); } TEST(ExternalFifoQueue, CopyDataFrom) { - constexpr FwSizeType maxSize = 10; + constexpr FwSizeType maxSize = State::capacity; constexpr FwSizeType smallSize = maxSize / 2; State::ItemType items1[maxSize]; State::ItemType items2[maxSize]; @@ -184,12 +178,12 @@ TEST(ExternalFifoQueue, CopyDataFrom) { Queue q2(items2, maxSize); State::testCopyDataFrom(q1, smallSize, q2); } - // size1 == size2 + // size1 == capacity2 { Queue q2(items2, maxSize); State::testCopyDataFrom(q1, maxSize, q2); } - // size1 > size2 + // size1 > capacity2 { Queue q2(items2, smallSize); State::testCopyDataFrom(q1, maxSize, q2); From 463dab2737eb69e7511b3d5a02d65b5457f9ea4b Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 8 Jul 2025 17:20:49 -0700 Subject: [PATCH 334/458] Revise comments --- Fw/DataStructures/ExternalStack.hpp | 3 ++- Fw/DataStructures/Stack.hpp | 3 ++- Fw/DataStructures/StackBase.hpp | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Fw/DataStructures/ExternalStack.hpp b/Fw/DataStructures/ExternalStack.hpp index 65a354aab9f..fbad3fa35cb 100644 --- a/Fw/DataStructures/ExternalStack.hpp +++ b/Fw/DataStructures/ExternalStack.hpp @@ -99,7 +99,8 @@ class ExternalStack final : public StackBase { } //! Get an item at an index. - //! Indices go from left to right in the stack. + //! Index 0 is the rightmost (latest) element in the stack. + //! Increasing indices go from right to left. //! Fails an assertion if the index is out of range. //! \return The item const T& at(FwSizeType index //!< The index diff --git a/Fw/DataStructures/Stack.hpp b/Fw/DataStructures/Stack.hpp index 75673b40e85..b971bf5b1de 100644 --- a/Fw/DataStructures/Stack.hpp +++ b/Fw/DataStructures/Stack.hpp @@ -72,7 +72,8 @@ class Stack final : public StackBase { FwSizeType getCapacity() const override { return this->m_extStack.getCapacity(); } //! Get an item at an index. - //! Indices go from left to right in the stack. + //! Index 0 is the rightmost (latest) element in the stack. + //! Increasing indices go from right to left. //! Fails an assertion if the index is out of range. //! \return The item const T& at(FwSizeType index //!< The index diff --git a/Fw/DataStructures/StackBase.hpp b/Fw/DataStructures/StackBase.hpp index bd9379f715f..70308f7bd48 100644 --- a/Fw/DataStructures/StackBase.hpp +++ b/Fw/DataStructures/StackBase.hpp @@ -54,7 +54,8 @@ class StackBase { virtual void clear() = 0; //! Get an item at an index. - //! Indices go from left to right in the stack. + //! Index 0 is the rightmost (latest) element in the stack. + //! Increasing indices go from right to left. //! Fails an assertion if the index is out of range. //! \return The item virtual const T& at(FwSizeType index //!< The index From 1de1c5c0db2a5d961b186cbe23ce93f6bffff291 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 8 Jul 2025 17:29:19 -0700 Subject: [PATCH 335/458] Revise Stack tests --- .../test/ut/ExternalStackTest.cpp | 8 ++ .../test/ut/STest/StackTestRules.cpp | 12 +-- .../test/ut/STest/StackTestRules.hpp | 87 +++++++++++-------- .../test/ut/STest/StackTestScenarios.cpp | 1 + Fw/DataStructures/test/ut/StackTest.cpp | 8 ++ 5 files changed, 75 insertions(+), 41 deletions(-) diff --git a/Fw/DataStructures/test/ut/ExternalStackTest.cpp b/Fw/DataStructures/test/ut/ExternalStackTest.cpp index 78c28a3a9f5..89849c22fe8 100644 --- a/Fw/DataStructures/test/ut/ExternalStackTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalStackTest.cpp @@ -230,6 +230,14 @@ TEST(ExternalStackScenarios, At) { Rules::at.apply(state); } +TEST(ExternalStackScenarios, Peek) { + State::Stack stack; + State state(stack); + Rules::pushOK.apply(state); + Rules::pushOK.apply(state); + Rules::peek.apply(state); +} + TEST(ExternalStackScenarios, PopOK) { U32 items[State::capacity]; State::ExternalStack stack(items, State::capacity); diff --git a/Fw/DataStructures/test/ut/STest/StackTestRules.cpp b/Fw/DataStructures/test/ut/STest/StackTestRules.cpp index b6abf2df22d..dc93c8b761d 100644 --- a/Fw/DataStructures/test/ut/STest/StackTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/StackTestRules.cpp @@ -12,17 +12,19 @@ namespace StackTest { namespace Rules { -PushOK pushOK; +At at; -PushFull pushFull; +Clear clear; -At at; +Peek peek; + +PopEmpty popEmpty; PopOK popOK; -PopEmpty popEmpty; +PushFull pushFull; -Clear clear; +PushOK pushOK; }; // namespace Rules diff --git a/Fw/DataStructures/test/ut/STest/StackTestRules.hpp b/Fw/DataStructures/test/ut/STest/StackTestRules.hpp index 78ddddb3698..b77c572eb7c 100644 --- a/Fw/DataStructures/test/ut/STest/StackTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/StackTestRules.hpp @@ -21,42 +21,48 @@ using Rule = STest::Rule; namespace Rules { -struct PushOK : public Rule { - PushOK() : Rule("PushOK") {} - bool precondition(const State& state) { return static_cast(state.stack.getSize()) < State::capacity; } +struct At : public Rule { + At() : Rule("At") {} + bool precondition(const State& state) { return state.stack.getSize() > 0; } void action(State& state) { - const U32 value = STest::Pick::any(); - const auto status = state.stack.push(value); - ASSERT_EQ(status, Success::SUCCESS); - state.modelStack.push_back(value); + const auto size = state.stack.getSize(); + const auto index = STest::Pick::startLength(0, static_cast(size)); + ASSERT_EQ(state.stack.at(index), state.modelStack.at(size - 1 - index)); } }; -extern PushOK pushOK; - -struct PushFull : public Rule { - PushFull() : Rule("PushFull") {} - bool precondition(const State& state) { return static_cast(state.stack.getSize()) >= State::capacity; } +struct Clear : public Rule { + Clear() : Rule("Clear") {} + bool precondition(const State& state) { return state.stack.getSize() > 0; } void action(State& state) { - const auto item = State::getRandomItem(); - const auto status = state.stack.push(item); - ASSERT_EQ(status, Success::FAILURE); + state.stack.clear(); + ASSERT_EQ(state.stack.getSize(), 0); + state.modelStack.clear(); } }; -extern PushFull pushFull; - -struct At : public Rule { - At() : Rule("At") {} +struct Peek : public Rule { + Peek() : Rule("Peek") {} bool precondition(const State& state) { return state.stack.getSize() > 0; } void action(State& state) { const auto size = state.stack.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); - ASSERT_EQ(state.stack.at(index), state.modelStack.at(size - 1 - index)); + State::ItemType item; + const auto status = state.stack.peek(item, index); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(item, state.modelStack.at(size - 1 - index)); } }; -extern At at; +struct PopEmpty : public Rule { + PopEmpty() : Rule("PopEmpty") {} + bool precondition(const State& state) { return static_cast(state.stack.getSize()) == 0; } + void action(State& state) { + U32 value = 0; + const auto status = state.stack.pop(value); + ASSERT_EQ(status, Success::FAILURE); + } +}; struct PopOK : public Rule { PopOK() : Rule("PopOK") {} @@ -73,32 +79,41 @@ struct PopOK : public Rule { } }; -extern PopOK popOK; - -struct PopEmpty : public Rule { - PopEmpty() : Rule("PopEmpty") {} - bool precondition(const State& state) { return static_cast(state.stack.getSize()) == 0; } +struct PushFull : public Rule { + PushFull() : Rule("PushFull") {} + bool precondition(const State& state) { return static_cast(state.stack.getSize()) >= State::capacity; } void action(State& state) { - U32 value = 0; - const auto status = state.stack.pop(value); + const auto item = State::getRandomItem(); + const auto status = state.stack.push(item); ASSERT_EQ(status, Success::FAILURE); } }; -extern PopEmpty popEmpty; - -struct Clear : public Rule { - Clear() : Rule("Clear") {} - bool precondition(const State& state) { return state.stack.getSize() > 0; } +struct PushOK : public Rule { + PushOK() : Rule("PushOK") {} + bool precondition(const State& state) { return static_cast(state.stack.getSize()) < State::capacity; } void action(State& state) { - state.stack.clear(); - ASSERT_EQ(state.stack.getSize(), 0); - state.modelStack.clear(); + const U32 value = STest::Pick::any(); + const auto status = state.stack.push(value); + ASSERT_EQ(status, Success::SUCCESS); + state.modelStack.push_back(value); } }; +extern At at; + extern Clear clear; +extern Peek peek; + +extern PopEmpty popEmpty; + +extern PopOK popOK; + +extern PushFull pushFull; + +extern PushOK pushOK; + }; // namespace Rules } // namespace StackTest diff --git a/Fw/DataStructures/test/ut/STest/StackTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/StackTestScenarios.cpp index 284ee8518f7..cea89e38707 100644 --- a/Fw/DataStructures/test/ut/STest/StackTestScenarios.cpp +++ b/Fw/DataStructures/test/ut/STest/StackTestScenarios.cpp @@ -20,6 +20,7 @@ void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { &Rules::pushOK, &Rules::pushFull, &Rules::at, + &Rules::peek, &Rules::popOK, &Rules::popEmpty, &Rules::clear diff --git a/Fw/DataStructures/test/ut/StackTest.cpp b/Fw/DataStructures/test/ut/StackTest.cpp index 974cbd2c4d3..e4c1316fe51 100644 --- a/Fw/DataStructures/test/ut/StackTest.cpp +++ b/Fw/DataStructures/test/ut/StackTest.cpp @@ -184,6 +184,14 @@ TEST(StackScenarios, At) { } } +TEST(StackScenarios, Peek) { + State::Stack stack; + State state(stack); + Rules::pushOK.apply(state); + Rules::pushOK.apply(state); + Rules::peek.apply(state); +} + TEST(StackScenarios, PopOK) { State::Stack stack; State state(stack); From 23dcffe91703a8122b47fe5ce5a4a55749671cb1 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 8 Jul 2025 17:50:08 -0700 Subject: [PATCH 336/458] Revise Stack tests --- .../test/ut/ExternalStackTest.cpp | 3 +- .../test/ut/STest/StackTestScenarios.cpp | 38 +++++ .../test/ut/STest/StackTestScenarios.hpp | 14 ++ .../test/ut/STest/StackTestState.hpp | 4 +- Fw/DataStructures/test/ut/StackTest.cpp | 144 ++++++++---------- 5 files changed, 121 insertions(+), 82 deletions(-) diff --git a/Fw/DataStructures/test/ut/ExternalStackTest.cpp b/Fw/DataStructures/test/ut/ExternalStackTest.cpp index 89849c22fe8..d6f1c4b3d43 100644 --- a/Fw/DataStructures/test/ut/ExternalStackTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalStackTest.cpp @@ -231,7 +231,8 @@ TEST(ExternalStackScenarios, At) { } TEST(ExternalStackScenarios, Peek) { - State::Stack stack; + U32 items[State::capacity]; + State::ExternalStack stack(items, State::capacity); State state(stack); Rules::pushOK.apply(state); Rules::pushOK.apply(state); diff --git a/Fw/DataStructures/test/ut/STest/StackTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/StackTestScenarios.cpp index cea89e38707..54315d27afc 100644 --- a/Fw/DataStructures/test/ut/STest/StackTestScenarios.cpp +++ b/Fw/DataStructures/test/ut/STest/StackTestScenarios.cpp @@ -15,6 +15,44 @@ namespace StackTest { namespace Scenarios { +void at(State& state) { + Rules::pushOK.apply(state); + for (FwSizeType i = 0; i < State::capacity; i++) { + Rules::at.apply(state); + } +} + +void clear(State& state) { + Rules::pushOK.apply(state); + Rules::clear.apply(state); +} + +void peek(State& state) { + Rules::pushOK.apply(state); + Rules::pushOK.apply(state); + Rules::peek.apply(state); +} + +void popEmpty(State& state) { + Rules::popEmpty.apply(state); +} + +void popOK(State& state) { + Rules::pushOK.apply(state); + Rules::popOK.apply(state); +} + +void pushFull(State& state) { + for (FwSizeType i = 0; i < State::capacity; i++) { + Rules::pushOK.apply(state); + } + Rules::pushFull.apply(state); +} + +void pushOK(State& state) { + Rules::pushOK.apply(state); +} + void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { Rule* rules[] = { &Rules::pushOK, diff --git a/Fw/DataStructures/test/ut/STest/StackTestScenarios.hpp b/Fw/DataStructures/test/ut/STest/StackTestScenarios.hpp index 7d7221be580..578916ba3d2 100644 --- a/Fw/DataStructures/test/ut/STest/StackTestScenarios.hpp +++ b/Fw/DataStructures/test/ut/STest/StackTestScenarios.hpp @@ -15,6 +15,20 @@ namespace StackTest { namespace Scenarios { +void at(State& state); + +void clear(State& state); + +void peek(State& state); + +void popEmpty(State& state); + +void popOK(State& state); + +void pushFull(State& state); + +void pushOK(State& state); + void random(const Fw::StringBase& name, State& state, U32 maxNumSteps); } // namespace Scenarios diff --git a/Fw/DataStructures/test/ut/STest/StackTestState.hpp b/Fw/DataStructures/test/ut/STest/StackTestState.hpp index 9c8eb6c9a2a..f838bd1cfc9 100644 --- a/Fw/DataStructures/test/ut/STest/StackTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/StackTestState.hpp @@ -9,7 +9,7 @@ #include -#include "Fw/DataStructures/Stack.hpp" +#include "Fw/DataStructures/ExternalStack.hpp" #include "STest/STest/Pick/Pick.hpp" namespace Fw { @@ -21,8 +21,6 @@ struct State { using ItemType = U32; //! The stack capacity static constexpr FwSizeType capacity = 1024; - //! The Stack type - using Stack = Stack; //! The ExternalStack type using ExternalStack = ExternalStack; //! THe StackBase type diff --git a/Fw/DataStructures/test/ut/StackTest.cpp b/Fw/DataStructures/test/ut/StackTest.cpp index e4c1316fe51..4b7e40656df 100644 --- a/Fw/DataStructures/test/ut/StackTest.cpp +++ b/Fw/DataStructures/test/ut/StackTest.cpp @@ -4,6 +4,7 @@ // \brief cpp file for Stack tests // ====================================================================== +#include "Fw/DataStructures/Stack.hpp" #include "Fw/DataStructures/test/ut/STest/StackTestRules.hpp" #include "Fw/DataStructures/test/ut/STest/StackTestScenarios.hpp" @@ -24,32 +25,32 @@ class StackTester { namespace StackTest { +using TestStack = Stack; +using StackTester = StackTester; + TEST(Stack, ZeroArgConstructor) { - constexpr FwSizeType C = 10; - Stack stack; - ASSERT_EQ(stack.getCapacity(), C); + TestStack stack; + ASSERT_EQ(stack.getCapacity(), FwSizeType(State::capacity)); ASSERT_EQ(stack.getSize(), 0); } TEST(Stack, CopyConstructor) { - constexpr FwSizeType capacity = 3; // Construct s1 - Stack s1; + TestStack s1; // Push an item - U32 value = 42; - const auto status = s1.push(value); + const auto item = State::getRandomItem(); + const auto status = s1.push(item); ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(s1.getSize(), 1); // Use the copy constructor to construct s2 - Stack s2(s1); + TestStack s2(s1); ASSERT_EQ(s2.getSize(), 1); } TEST(Stack, PushOK) { - constexpr const FwSizeType capacity = 1000; - const FwSizeType size = STest::Pick::lowerUpper(1, capacity); - Stack stack; - ASSERT_EQ(stack.getCapacity(), capacity); + const FwSizeType size = STest::Pick::lowerUpper(1, State::capacity); + TestStack stack; + ASSERT_EQ(stack.getCapacity(), FwSizeType(State::capacity)); ASSERT_EQ(stack.getSize(), 0); for (FwSizeType i = 0; i < size; i++) { // Pick a value @@ -70,29 +71,28 @@ TEST(Stack, PushOK) { } TEST(Stack, PushFull) { - constexpr const FwSizeType capacity = 1000; - Stack stack; - // Fill up the FIFO - for (FwSizeType i = 0; i < capacity; i++) { + TestStack stack; + // Fill up the stack + for (FwSizeType i = 0; i < State::capacity; i++) { const auto status = stack.push(0); ASSERT_EQ(status, Success::SUCCESS); } // Now try to push another element - const U32 val = STest::Pick::any(); - const auto status = stack.push(val); + const auto item = State::getRandomItem(); + const auto status = stack.push(item); // Push should fail ASSERT_EQ(status, Success::FAILURE); } TEST(Stack, CopyAssignmentOperator) { - constexpr FwSizeType capacity = 3; // Call the constructor providing backing storage - Stack s1; + TestStack s1; // Push an item - U32 value = 42; - (void)s1.push(value); + const auto item = State::getRandomItem(); + const auto status = s1.push(item); + ASSERT_EQ(status, Success::SUCCESS); // Call the default constructor - Stack s2; + TestStack s2; ASSERT_EQ(s2.getSize(), 0); // Call the copy assignment operator s2 = s1; @@ -100,120 +100,108 @@ TEST(Stack, CopyAssignmentOperator) { } TEST(Stack, PopOK) { - constexpr const FwSizeType capacity = 1000; - const FwSizeType size = STest::Pick::lowerUpper(1, capacity); - U32 items[capacity]; - Stack stack; - ASSERT_EQ(stack.getCapacity(), capacity); + const FwSizeType size = STest::Pick::lowerUpper(1, State::capacity); + State::ItemType items[State::capacity]; + TestStack stack; + ASSERT_EQ(stack.getCapacity(), FwSizeType(State::capacity)); ASSERT_EQ(stack.getSize(), 0); for (FwSizeType i = 0; i < size; i++) { // Pick a value - const U32 val = STest::Pick::any(); + const auto item = State::getRandomItem(); // Push it - const auto status = stack.push(val); - items[i] = val; + const auto status = stack.push(item); + items[i] = item; ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(stack.getSize(), i + 1); } for (FwSizeType i = 0; i < size; i++) { const FwSizeType stackIndex = size - 1 - i; - U32 val = 0; + State::ItemType item = 0; // Peek - auto status = stack.peek(val); + auto status = stack.peek(item); ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(val, items[stackIndex]); + ASSERT_EQ(item, items[stackIndex]); // Pop it - status = stack.pop(val); + status = stack.pop(item); ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(val, items[stackIndex]); + ASSERT_EQ(item, items[stackIndex]); ASSERT_EQ(stack.getSize(), stackIndex); } ASSERT_EQ(stack.getSize(), 0); } TEST(Stack, PopEmpty) { - constexpr const FwSizeType capacity = 1000; - Stack stack; - U32 val = 0; - const auto status = stack.pop(val); + TestStack stack; + State::ItemType item = 0; + const auto status = stack.pop(item); ASSERT_EQ(status, Success::FAILURE); } TEST(Stack, CopyDataFrom) { - constexpr FwSizeType maxSize = 10; + constexpr FwSizeType maxSize = State::capacity; constexpr FwSizeType smallSize = maxSize / 2; - Stack s1; + TestStack s1; // size1 < capacity2 { - Stack s2; + TestStack s2; State::testCopyDataFrom(s1, smallSize, s2); } - // size1 == size2 + // size1 == capacity2 { - Stack s2; + TestStack s2; State::testCopyDataFrom(s1, maxSize, s2); } - // size1 > size2 + // size1 > capacity2 { - Stack s2; + Stack s2; State::testCopyDataFrom(s1, maxSize, s2); } } -TEST(StackScenarios, PushOK) { - State::Stack stack; +TEST(StackScenarios, At) { + TestStack stack; State state(stack); - Rules::pushOK.apply(state); + Scenarios::at(state); } -TEST(StackScenarios, PushFull) { - State::Stack stack; +TEST(StackScenarios, Clear) { + TestStack stack; State state(stack); - for (FwSizeType i = 0; i < State::capacity; i++) { - Rules::pushOK.apply(state); - } - Rules::pushFull.apply(state); + Scenarios::clear(state); } -TEST(StackScenarios, At) { - State::Stack stack; +TEST(StackScenarios, Peek) { + TestStack stack; State state(stack); - Rules::pushOK.apply(state); - for (FwSizeType i = 0; i < State::capacity; i++) { - Rules::at.apply(state); - } + Scenarios::peek(state); } -TEST(StackScenarios, Peek) { - State::Stack stack; +TEST(StackScenarios, PopEmpty) { + TestStack stack; State state(stack); - Rules::pushOK.apply(state); - Rules::pushOK.apply(state); - Rules::peek.apply(state); + Scenarios::popEmpty(state); } TEST(StackScenarios, PopOK) { - State::Stack stack; + TestStack stack; State state(stack); - Rules::pushOK.apply(state); - Rules::popOK.apply(state); + Scenarios::popOK(state); } -TEST(StackScenarios, PopEmpty) { - State::Stack stack; +TEST(StackScenarios, PushFull) { + TestStack stack; State state(stack); - Rules::popEmpty.apply(state); + Scenarios::pushFull(state); } -TEST(StackScenarios, Clear) { - State::Stack stack; +TEST(StackScenarios, PushOK) { + TestStack stack; State state(stack); - Rules::pushOK.apply(state); - Rules::clear.apply(state); + Scenarios::pushOK(state); } TEST(StackScenarios, Random) { - State::Stack stack; + TestStack stack; State state(stack); Scenarios::random(Fw::String("StackRandom"), state, 1000); } From 1d46d0f52a2ec2ea592540d270437224d977f55e Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 8 Jul 2025 17:53:06 -0700 Subject: [PATCH 337/458] Refactor Stack tests --- Fw/DataStructures/test/ut/StackTest.cpp | 75 ------------------------- 1 file changed, 75 deletions(-) diff --git a/Fw/DataStructures/test/ut/StackTest.cpp b/Fw/DataStructures/test/ut/StackTest.cpp index 4b7e40656df..28c8dcc2e6f 100644 --- a/Fw/DataStructures/test/ut/StackTest.cpp +++ b/Fw/DataStructures/test/ut/StackTest.cpp @@ -47,43 +47,6 @@ TEST(Stack, CopyConstructor) { ASSERT_EQ(s2.getSize(), 1); } -TEST(Stack, PushOK) { - const FwSizeType size = STest::Pick::lowerUpper(1, State::capacity); - TestStack stack; - ASSERT_EQ(stack.getCapacity(), FwSizeType(State::capacity)); - ASSERT_EQ(stack.getSize(), 0); - for (FwSizeType i = 0; i < size; i++) { - // Pick a value - const U32 val = STest::Pick::any(); - // Push it - auto status = stack.push(val); - ASSERT_EQ(status, Success::SUCCESS); - // Peek it - U32 val1 = 0; - status = stack.peek(val1); - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(val1, val); - // Check the size - ASSERT_EQ(stack.getSize(), i + 1); - } - stack.clear(); - ASSERT_EQ(stack.getSize(), 0); -} - -TEST(Stack, PushFull) { - TestStack stack; - // Fill up the stack - for (FwSizeType i = 0; i < State::capacity; i++) { - const auto status = stack.push(0); - ASSERT_EQ(status, Success::SUCCESS); - } - // Now try to push another element - const auto item = State::getRandomItem(); - const auto status = stack.push(item); - // Push should fail - ASSERT_EQ(status, Success::FAILURE); -} - TEST(Stack, CopyAssignmentOperator) { // Call the constructor providing backing storage TestStack s1; @@ -99,44 +62,6 @@ TEST(Stack, CopyAssignmentOperator) { ASSERT_EQ(s2.getSize(), 1); } -TEST(Stack, PopOK) { - const FwSizeType size = STest::Pick::lowerUpper(1, State::capacity); - State::ItemType items[State::capacity]; - TestStack stack; - ASSERT_EQ(stack.getCapacity(), FwSizeType(State::capacity)); - ASSERT_EQ(stack.getSize(), 0); - for (FwSizeType i = 0; i < size; i++) { - // Pick a value - const auto item = State::getRandomItem(); - // Push it - const auto status = stack.push(item); - items[i] = item; - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(stack.getSize(), i + 1); - } - for (FwSizeType i = 0; i < size; i++) { - const FwSizeType stackIndex = size - 1 - i; - State::ItemType item = 0; - // Peek - auto status = stack.peek(item); - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(item, items[stackIndex]); - // Pop it - status = stack.pop(item); - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(item, items[stackIndex]); - ASSERT_EQ(stack.getSize(), stackIndex); - } - ASSERT_EQ(stack.getSize(), 0); -} - -TEST(Stack, PopEmpty) { - TestStack stack; - State::ItemType item = 0; - const auto status = stack.pop(item); - ASSERT_EQ(status, Success::FAILURE); -} - TEST(Stack, CopyDataFrom) { constexpr FwSizeType maxSize = State::capacity; constexpr FwSizeType smallSize = maxSize / 2; From f9b2ae2a3b0a0b0fef9fd57eb3c65a01f9f24fb9 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 8 Jul 2025 18:08:21 -0700 Subject: [PATCH 338/458] Revise Stack tests --- .../test/ut/ExternalStackTest.cpp | 239 +++++------------- .../test/ut/STest/StackTestState.hpp | 4 +- 2 files changed, 67 insertions(+), 176 deletions(-) diff --git a/Fw/DataStructures/test/ut/ExternalStackTest.cpp b/Fw/DataStructures/test/ut/ExternalStackTest.cpp index d6f1c4b3d43..8666ca92e18 100644 --- a/Fw/DataStructures/test/ut/ExternalStackTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalStackTest.cpp @@ -4,6 +4,7 @@ // \brief cpp file for ExternalStack tests // ====================================================================== +#include "Fw/DataStructures/ExternalStack.hpp" #include "Fw/DataStructures/test/ut/STest/StackTestRules.hpp" #include "Fw/DataStructures/test/ut/STest/StackTestScenarios.hpp" @@ -22,251 +23,143 @@ class ExternalStackTester { namespace StackTest { +using TestStack = ExternalStack; +using StackTester = ExternalStackTester; + TEST(ExternalStack, ZeroArgConstructor) { - ExternalStack stack; + TestStack stack; ASSERT_EQ(stack.getCapacity(), 0); ASSERT_EQ(stack.getSize(), 0); } TEST(ExternalStack, TypedStorageConstructor) { - constexpr FwSizeType capacity = 10; - U32 items[capacity]; - ExternalStack stack(items, capacity); - ExternalStackTester tester(stack); + State::ItemType items[State::capacity]; + TestStack stack(items, State::capacity); + StackTester tester(stack); ASSERT_EQ(tester.getItems().getElements(), items); - ASSERT_EQ(stack.getCapacity(), capacity); + ASSERT_EQ(stack.getCapacity(), FwSizeType(State::capacity)); ASSERT_EQ(stack.getSize(), 0); } TEST(ExternalStack, UntypedStorageConstructor) { - constexpr FwSizeType capacity = 10; - constexpr U8 alignment = ExternalStack::getByteArrayAlignment(); - constexpr FwSizeType byteArraySize = ExternalStack::getByteArraySize(capacity); + constexpr U8 alignment = TestStack::getByteArrayAlignment(); + constexpr FwSizeType byteArraySize = TestStack::getByteArraySize(State::capacity); alignas(alignment) U8 bytes[byteArraySize]; - ExternalStack stack(ByteArray(&bytes[0], sizeof bytes), capacity); - ExternalStackTester tester(stack); - ASSERT_EQ(tester.getItems().getElements(), reinterpret_cast(bytes)); - ASSERT_EQ(stack.getCapacity(), capacity); - ASSERT_EQ(stack.getSize(), 0); -} - -TEST(ExternalStack, At) { - constexpr FwSizeType capacity = 10; - U32 items[capacity]; - ExternalStack stack(items, capacity); - auto status = stack.push(3); - ASSERT_EQ(status, Success::SUCCESS); - status = stack.push(4); - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(stack.at(0), 4); - ASSERT_EQ(stack.at(1), 3); - ASSERT_DEATH(stack.at(2), "Assert"); -} - -TEST(ExternalStack, PushOK) { - constexpr const FwSizeType capacity = 1000; - const FwSizeType size = STest::Pick::lowerUpper(1, capacity); - U32 elts[capacity]; - ExternalStack stack(elts, capacity); - ASSERT_EQ(stack.getCapacity(), capacity); - ASSERT_EQ(stack.getSize(), 0); - for (FwSizeType i = 0; i < size; i++) { - // Pick a value - const U32 val = STest::Pick::any(); - // Push it - auto status = stack.push(val); - ASSERT_EQ(status, Success::SUCCESS); - // Peek it - U32 val1 = 0; - status = stack.peek(val1); - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(val1, val); - // Check the size - ASSERT_EQ(stack.getSize(), i + 1); - } - stack.clear(); + TestStack stack(ByteArray(&bytes[0], sizeof bytes), State::capacity); + StackTester tester(stack); + ASSERT_EQ(tester.getItems().getElements(), reinterpret_cast(bytes)); + ASSERT_EQ(stack.getCapacity(), FwSizeType(State::capacity)); ASSERT_EQ(stack.getSize(), 0); } -TEST(ExternalStack, PushFull) { - constexpr const FwSizeType capacity = 1000; - U32 elts[capacity]; - ExternalStack stack(elts, capacity); - // Fill up the stack - for (FwSizeType i = 0; i < capacity; i++) { - const auto status = stack.push(0); - ASSERT_EQ(status, Success::SUCCESS); - } - // Now try to push another element - const U32 val = STest::Pick::any(); - const auto status = stack.push(val); - // Push should fail - ASSERT_EQ(status, Success::FAILURE); -} - TEST(ExternalStack, CopyConstructor) { - constexpr FwSizeType capacity = 3; - U32 items[capacity]; + State::ItemType items[State::capacity]; // Call the constructor providing backing storage - ExternalStack s1(items, capacity); + TestStack s1(items, State::capacity); // Push an item - U32 value = 42; - const auto status = s1.push(value); + const auto item = State::getRandomItem(); + const auto status = s1.push(item); ASSERT_EQ(status, Success::SUCCESS); // Call the copy constructor - ExternalStack s2(s1); - ExternalStackTester tester1(s1); - ExternalStackTester tester2(s2); + TestStack s2(s1); + StackTester tester1(s1); + StackTester tester2(s2); ASSERT_EQ(tester2.getItems().getElements(), items); - ASSERT_EQ(tester2.getItems().getSize(), capacity); + ASSERT_EQ(tester2.getItems().getSize(), FwSizeType(State::capacity)); ASSERT_EQ(s2.getSize(), 1); } TEST(ExternalStack, CopyAssignmentOperator) { - constexpr FwSizeType capacity = 3; - U32 items[capacity]; + State::ItemType items[State::capacity]; // Call the constructor providing backing storage - ExternalStack s1(items, capacity); + TestStack s1(items, State::capacity); // Push an item - U32 value = 42; - const auto status = s1.push(value); + const auto item = State::getRandomItem(); + const auto status = s1.push(item); ASSERT_EQ(status, Success::SUCCESS); // Call the default constructor - ExternalStack s2; + TestStack s2; ASSERT_EQ(s2.getSize(), 0); // Call the copy assignment operator s2 = s1; ASSERT_EQ(s2.getSize(), 1); } -TEST(ExternalStack, PopOK) { - constexpr const FwSizeType capacity = 1000; - const FwSizeType size = STest::Pick::lowerUpper(1, capacity); - U32 items[capacity]; - ExternalStack stack(items, capacity); - ASSERT_EQ(stack.getCapacity(), capacity); - ASSERT_EQ(stack.getSize(), 0); - for (FwSizeType i = 0; i < size; i++) { - // Pick a value - const U32 val = STest::Pick::any(); - // Push it - const auto status = stack.push(val); - ASSERT_EQ(val, items[i]); - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(stack.getSize(), i + 1); - } - for (FwSizeType i = 0; i < size; i++) { - const FwSizeType stackIndex = size - 1 - i; - U32 val = 0; - // Peek - auto status = stack.peek(val); - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(val, items[stackIndex]); - // Pop it - status = stack.pop(val); - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(val, items[stackIndex]); - ASSERT_EQ(stack.getSize(), stackIndex); - } - ASSERT_EQ(stack.getSize(), 0); -} - -TEST(ExternalStack, PopEmpty) { - constexpr const FwSizeType capacity = 1000; - U32 items[capacity]; - ExternalStack stack(items, capacity); - U32 val = 0; - const auto status = stack.pop(val); - ASSERT_EQ(status, Success::FAILURE); -} - TEST(ExternalStack, CopyDataFrom) { - constexpr FwSizeType maxSize = 10; + constexpr FwSizeType maxSize = State::capacity; constexpr FwSizeType smallSize = maxSize / 2; - U32 items1[maxSize]; - U32 items2[maxSize]; - ExternalStack s1(items1, maxSize); + State::ItemType items1[maxSize]; + State::ItemType items2[maxSize]; + TestStack s1(items1, maxSize); // size1 < capacity2 { - ExternalStack s2(items2, maxSize); + TestStack s2(items2, maxSize); State::testCopyDataFrom(s1, smallSize, s2); } - // size1 == size2 + // size1 == capacity2 { - ExternalStack s2(items2, maxSize); + TestStack s2(items2, maxSize); State::testCopyDataFrom(s1, maxSize, s2); } - // size1 > size2 + // size1 > capacity2 { - ExternalStack s2(items2, smallSize); + ExternalStack s2(items2, smallSize); State::testCopyDataFrom(s1, maxSize, s2); } } -TEST(ExternalStackScenarios, PushOK) { - U32 items[State::capacity]; - State::ExternalStack stack(items, State::capacity); +TEST(ExternalStackScenarios, At) { + State::ItemType items[State::capacity]; + TestStack stack(items, State::capacity); State state(stack); - Rules::pushOK.apply(state); + Scenarios::at(state); } -TEST(ExternalStackScenarios, PushFull) { - U32 items[State::capacity]; - State::ExternalStack stack(items, State::capacity); +TEST(ExternalStackScenarios, Clear) { + State::ItemType items[State::capacity]; + TestStack stack(items, State::capacity); State state(stack); - for (FwSizeType i = 0; i < State::capacity; i++) { - Rules::pushOK.apply(state); - } - Rules::pushFull.apply(state); + Scenarios::clear(state); } -TEST(ExternalStackScenarios, At) { - U32 items[State::capacity]; - State::ExternalStack stack(items, State::capacity); +TEST(ExternalStackScenarios, Peek) { + State::ItemType items[State::capacity]; + TestStack stack(items, State::capacity); State state(stack); - for (FwSizeType i = 0; i < State::capacity; i++) { - Rules::pushOK.apply(state); - } - Rules::at.apply(state); + Scenarios::peek(state); } -TEST(ExternalStackScenarios, Peek) { - U32 items[State::capacity]; - State::ExternalStack stack(items, State::capacity); +TEST(ExternalStackScenarios, PopEmpty) { + State::ItemType items[State::capacity]; + TestStack stack(items, State::capacity); State state(stack); - Rules::pushOK.apply(state); - Rules::pushOK.apply(state); - Rules::peek.apply(state); + Rules::popEmpty.apply(state); } TEST(ExternalStackScenarios, PopOK) { - U32 items[State::capacity]; - State::ExternalStack stack(items, State::capacity); + State::ItemType items[State::capacity]; + TestStack stack(items, State::capacity); State state(stack); - Rules::pushOK.apply(state); - Rules::pushOK.apply(state); - Rules::popOK.apply(state); - Rules::popOK.apply(state); + Scenarios::popOK(state); } -TEST(ExternalStackScenarios, PopEmpty) { - U32 items[State::capacity]; - State::ExternalStack stack(items, State::capacity); +TEST(ExternalStackScenarios, PushFull) { + State::ItemType items[State::capacity]; + TestStack stack(items, State::capacity); State state(stack); - Rules::popEmpty.apply(state); + Scenarios::pushFull(state); } -TEST(ExternalStackScenarios, Clear) { - U32 items[State::capacity]; - State::ExternalStack stack(items, State::capacity); +TEST(ExternalStackScenarios, PushOK) { + State::ItemType items[State::capacity]; + TestStack stack(items, State::capacity); State state(stack); - Rules::pushOK.apply(state); - Rules::clear.apply(state); + Scenarios::pushOK(state); } TEST(ExternalStackScenarios, Random) { - U32 items[State::capacity]; - State::ExternalStack stack(items, State::capacity); + State::ItemType items[State::capacity]; + TestStack stack(items, State::capacity); State state(stack); Scenarios::random(Fw::String("ExternalStackRandom"), state, 1000); } diff --git a/Fw/DataStructures/test/ut/STest/StackTestState.hpp b/Fw/DataStructures/test/ut/STest/StackTestState.hpp index f838bd1cfc9..08e097c2406 100644 --- a/Fw/DataStructures/test/ut/STest/StackTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/StackTestState.hpp @@ -9,7 +9,7 @@ #include -#include "Fw/DataStructures/ExternalStack.hpp" +#include "Fw/DataStructures/StackBase.hpp" #include "STest/STest/Pick/Pick.hpp" namespace Fw { @@ -21,8 +21,6 @@ struct State { using ItemType = U32; //! The stack capacity static constexpr FwSizeType capacity = 1024; - //! The ExternalStack type - using ExternalStack = ExternalStack; //! THe StackBase type using StackBase = StackBase; //! Constructor From a4dd40df4d92f17ac11a015a3fcc0b58fe7999e1 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 8 Jul 2025 20:33:51 -0700 Subject: [PATCH 339/458] Revise Array Remove getStaticSize --- Fw/DataStructures/Array.hpp | 9 --------- Fw/DataStructures/docs/Array.md | 16 ---------------- Fw/DataStructures/test/ut/ArrayTest.cpp | 5 ----- 3 files changed, 30 deletions(-) diff --git a/Fw/DataStructures/Array.hpp b/Fw/DataStructures/Array.hpp index 7a749d0e9d4..1a178b80b65 100644 --- a/Fw/DataStructures/Array.hpp +++ b/Fw/DataStructures/Array.hpp @@ -110,15 +110,6 @@ class Array final { // \return The ExternalArray ExternalArray asExternalArray() { return ExternalArray(this->m_elements, S); } - public: - // ---------------------------------------------------------------------- - // Public static functions - // ---------------------------------------------------------------------- - - //! Get the static array size - //! \return The size - static constexpr FwSizeType getStaticSize() { return S; } - private: // ---------------------------------------------------------------------- // Private member variables diff --git a/Fw/DataStructures/docs/Array.md b/Fw/DataStructures/docs/Array.md index 72ec46de707..9f0078c2cdf 100644 --- a/Fw/DataStructures/docs/Array.md +++ b/Fw/DataStructures/docs/Array.md @@ -182,19 +182,3 @@ Array a = { 1, 2, 3 }; ExternalArray ea = a.asExternalArray(); ASSERT_EQ(ea[0], 1); ``` - -## 6. Public Static Functions - -### 6.1. getStaticSize - -```c++ -static constexpr FwSizeType getStaticSize() -``` - -Return the static size `S` of the array. - -_Example:_ -```c++ -const auto size = Array::getStaticSize(); -ASSERT_EQ(size, 3); -``` diff --git a/Fw/DataStructures/test/ut/ArrayTest.cpp b/Fw/DataStructures/test/ut/ArrayTest.cpp index e7a51e1404e..f4f6de73d17 100644 --- a/Fw/DataStructures/test/ut/ArrayTest.cpp +++ b/Fw/DataStructures/test/ut/ArrayTest.cpp @@ -88,11 +88,6 @@ TEST(Array, GetElements) { ASSERT_EQ(elements2[0], 1); } -TEST(Array, GetStaticSize) { - const auto size = Array::getStaticSize(); - ASSERT_EQ(size, 3); -} - TEST(Array, AsExternalArray) { Array a = { 1, 2, 3 }; ExternalArray ea = a.asExternalArray(); From ec578a72acfed816709be20c0de62ce0e81449a3 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 8 Jul 2025 20:36:43 -0700 Subject: [PATCH 340/458] Refactor Fifo tests --- .../test/ut/ExternalFifoQueueTest.cpp | 77 ------------------- Fw/DataStructures/test/ut/FifoQueueTest.cpp | 74 ------------------ 2 files changed, 151 deletions(-) diff --git a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp index 4f7cc08369c..c35f6ab439b 100644 --- a/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalFifoQueueTest.cpp @@ -55,45 +55,6 @@ TEST(ExternalFifoQueue, UntypedStorageConstructor) { ASSERT_EQ(queue.getSize(), 0); } -TEST(ExternalFifoQueue, EnqueueOK) { - const FwSizeType size = STest::Pick::lowerUpper(1, State::capacity); - State::ItemType elts[State::capacity]; - Queue queue(elts, State::capacity); - ASSERT_EQ(queue.getCapacity(), FwSizeType(State::capacity)); - ASSERT_EQ(queue.getSize(), 0); - for (FwSizeType i = 0; i < size; i++) { - // Pick an item - const auto item = State::getRandomItem(); - // Enqueue it - auto status = queue.enqueue(item); - ASSERT_EQ(status, Success::SUCCESS); - // Peek it - State::ItemType item1 = 0; - status = queue.peek(item1, i); - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(item1, item); - // Check the size - ASSERT_EQ(queue.getSize(), i + 1); - } - queue.clear(); - ASSERT_EQ(queue.getSize(), 0); -} - -TEST(ExternalFifoQueue, EnqueueFull) { - State::ItemType elts[State::capacity]; - Queue queue(elts, State::capacity); - // Fill up the FIFO - for (FwSizeType i = 0; i < State::capacity; i++) { - const auto status = queue.enqueue(0); - ASSERT_EQ(status, Success::SUCCESS); - } - // Now try to push another element - const auto item = State::getRandomItem(); - const auto status = queue.enqueue(item); - // Push should fail - ASSERT_EQ(status, Success::FAILURE); -} - TEST(ExternalFifoQueue, CopyConstructor) { State::ItemType items[State::capacity]; // Call the constructor providing backing storage @@ -129,44 +90,6 @@ TEST(ExternalFifoQueue, CopyAssignmentOperator) { ASSERT_EQ(q2.getSize(), 1); } -TEST(ExternalFifoQueue, DequeueOK) { - const FwSizeType size = STest::Pick::lowerUpper(1, State::capacity); - State::ItemType items[State::capacity]; - Queue queue(items, State::capacity); - ASSERT_EQ(queue.getCapacity(), FwSizeType(State::capacity)); - ASSERT_EQ(queue.getSize(), 0); - for (FwSizeType i = 0; i < size; i++) { - // Pick an item - const auto item = State::getRandomItem(); - // Enqueue it - const auto status = queue.enqueue(item); - ASSERT_EQ(item, items[i]); - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(queue.getSize(), i + 1); - } - for (FwSizeType i = 0; i < size; i++) { - State::ItemType item = 0; - // Peek - auto status = queue.peek(item); - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(item, items[i]); - // Dequeue it - status = queue.dequeue(item); - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(item, items[i]); - ASSERT_EQ(queue.getSize(), size - i - 1); - } - ASSERT_EQ(queue.getSize(), 0); -} - -TEST(ExternalFifoQueue, DequeueEmpty) { - State::ItemType items[State::capacity]; - Queue queue(items, State::capacity); - State::ItemType item = 0; - const auto status = queue.dequeue(item); - ASSERT_EQ(status, Success::FAILURE); -} - TEST(ExternalFifoQueue, CopyDataFrom) { constexpr FwSizeType maxSize = State::capacity; constexpr FwSizeType smallSize = maxSize / 2; diff --git a/Fw/DataStructures/test/ut/FifoQueueTest.cpp b/Fw/DataStructures/test/ut/FifoQueueTest.cpp index 3bbd58f3092..f98c2f8832d 100644 --- a/Fw/DataStructures/test/ut/FifoQueueTest.cpp +++ b/Fw/DataStructures/test/ut/FifoQueueTest.cpp @@ -46,43 +46,6 @@ TEST(FifoQueue, CopyConstructor) { ASSERT_EQ(q2.getSize(), 1); } -TEST(FifoQueue, EnqueueOK) { - const FwSizeType size = STest::Pick::lowerUpper(1, State::capacity); - Queue queue; - ASSERT_EQ(queue.getCapacity(), FwSizeType(State::capacity)); - ASSERT_EQ(queue.getSize(), 0); - for (FwSizeType i = 0; i < size; i++) { - // Pick a value - const auto item = State::getRandomItem(); - // Enqueue it - auto status = queue.enqueue(item); - ASSERT_EQ(status, Success::SUCCESS); - // Peek it - State::ItemType item1 = 0; - status = queue.peek(item1, i); - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(item1, item); - // Check the size - ASSERT_EQ(queue.getSize(), i + 1); - } - queue.clear(); - ASSERT_EQ(queue.getSize(), 0); -} - -TEST(FifoQueue, EnqueueFull) { - Queue queue; - // Fill up the FIFO - for (FwSizeType i = 0; i < State::capacity; i++) { - const auto status = queue.enqueue(0); - ASSERT_EQ(status, Success::SUCCESS); - } - // Now try to push another element - const U32 val = STest::Pick::any(); - const auto status = queue.enqueue(val); - // Push should fail - ASSERT_EQ(status, Success::FAILURE); -} - TEST(FifoQueue, CopyAssignmentOperator) { // Call the constructor providing backing storage Queue q1; @@ -97,43 +60,6 @@ TEST(FifoQueue, CopyAssignmentOperator) { ASSERT_EQ(q2.getSize(), 1); } -TEST(FifoQueue, DequeueOK) { - const FwSizeType size = STest::Pick::lowerUpper(1, State::capacity); - State::ItemType items[State::capacity]; - Queue queue; - ASSERT_EQ(queue.getCapacity(), FwSizeType(State::capacity)); - ASSERT_EQ(queue.getSize(), 0); - for (FwSizeType i = 0; i < size; i++) { - // Pick a value - const auto item = State::getRandomItem(); - // Enqueue it - const auto status = queue.enqueue(item); - items[i] = item; - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(queue.getSize(), i + 1); - } - for (FwSizeType i = 0; i < size; i++) { - State::ItemType item = 0; - // Peek - auto status = queue.peek(item); - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(item, items[i]); - // Dequeue it - status = queue.dequeue(item); - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(item, items[i]); - ASSERT_EQ(queue.getSize(), size - i - 1); - } - ASSERT_EQ(queue.getSize(), 0); -} - -TEST(FifoQueue, DequeueEmpty) { - Queue queue; - State::ItemType item = 0; - const auto status = queue.dequeue(item); - ASSERT_EQ(status, Success::FAILURE); -} - TEST(FifoQueue, CopyDataFrom) { constexpr FwSizeType maxSize = State::capacity; constexpr FwSizeType smallSize = maxSize / 2; From 2a1af088859796319064c218ca360e976277cf5e Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 8 Jul 2025 20:40:05 -0700 Subject: [PATCH 341/458] Refactor ArraySetOrMapImplTest --- Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp index 5b0c7696b5e..8b37c521a06 100644 --- a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp +++ b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp @@ -18,7 +18,7 @@ namespace Fw { namespace ArraySetOrMapImplTest { TEST(ArraySetOrMapImpl, ZeroArgConstructor) { - ArraySetOrMapImpl impl; + State::Impl impl; ASSERT_EQ(impl.getCapacity(), 0); ASSERT_EQ(impl.getSize(), 0); } From 447b91286c253debed45cdbd7ccce4877d764efd Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 13 Jul 2025 11:41:26 -0700 Subject: [PATCH 342/458] Revise data structures design Rename Iterator to Entry --- Fw/DataStructures/docs/ArrayMap.md | 12 ++--- Fw/DataStructures/docs/ArraySet.md | 12 ++--- Fw/DataStructures/docs/ArraySetOrMapImpl.md | 15 +++--- Fw/DataStructures/docs/ExternalArrayMap.md | 16 +++---- Fw/DataStructures/docs/ExternalArraySet.md | 16 +++---- Fw/DataStructures/docs/MapBase.md | 14 +++--- .../docs/{MapIterator.md => MapEntry.md} | 18 ++++---- Fw/DataStructures/docs/Nil.md | 2 +- Fw/DataStructures/docs/SetBase.md | 14 +++--- .../docs/{SetIterator.md => SetEntry.md} | 18 ++++---- .../{SetOrMapIterator.md => SetOrMapEntry.md} | 46 +++++++++---------- 11 files changed, 91 insertions(+), 92 deletions(-) rename Fw/DataStructures/docs/{MapIterator.md => MapEntry.md} (74%) rename Fw/DataStructures/docs/{SetIterator.md => SetEntry.md} (72%) rename Fw/DataStructures/docs/{SetOrMapIterator.md => SetOrMapEntry.md} (63%) diff --git a/Fw/DataStructures/docs/ArrayMap.md b/Fw/DataStructures/docs/ArrayMap.md index cf7546737e3..1c6dcdcad6c 100644 --- a/Fw/DataStructures/docs/ArrayMap.md +++ b/Fw/DataStructures/docs/ArrayMap.md @@ -28,8 +28,8 @@ It represents an array-based map with internal storage. |Name|Definition| |----|----------| -|`Entry`|Alias of [`SetOrMapIterator`](SetOrMapIterator.md)| -|`Iterator`|Alias of [`MapIterator`](MapIterator.md)| +|`Entry`|Alias of [`SetOrMapEntry`](SetOrMapEntry.md)| +|`MapEntry`|Alias of [`MapEntry`](MapEntry.md)| ## 4. Private Member Variables @@ -149,15 +149,15 @@ FwSizeType getCapacity() const override Return `m_extMap.getCapacity()`. -### 6.5. getHeadIterator +### 6.5. getHeadMapEntry ```c++ -const Iterator* getHeadIterator const override +const MapEntry* getHeadMapEntry const override ``` -The type `Iterator` is defined [here](ArrayMap.md#Public-Types). +The type `MapEntry` is defined [here](ArrayMap.md#Public-Types). -Return `m_extMap.getHeadIterator()`. +Return `m_extMap.getHeadMapEntry()`. ### 6.6. getSize diff --git a/Fw/DataStructures/docs/ArraySet.md b/Fw/DataStructures/docs/ArraySet.md index 2f474f4ffc3..f92b1efd43d 100644 --- a/Fw/DataStructures/docs/ArraySet.md +++ b/Fw/DataStructures/docs/ArraySet.md @@ -27,8 +27,8 @@ It represents an array-based set with internal storage. |Name|Definition| |----|----------| -|`Entry`|Alias of [`SetOrMapIterator`](SetOrMapIterator.md)| -|`Iterator`|Alias of [`SetIterator`](SetIterator.md)| +|`Entry`|Alias of [`SetOrMapEntry`](SetOrMapEntry.md)| +|`SetEntry`|Alias of [`SetEntry`](SetEntry.md)| The type `Nil` is defined [here](Nil.md). @@ -146,15 +146,15 @@ FwSizeType getCapacity() const override Return `m_extSet.getCapacity()`. -### 6.5. getHeadIterator +### 6.5. getHeadSetEntry ```c++ -const Iterator* getHeadIterator const override +const SetEntry* getHeadSetEntry const override ``` -The type `Iterator` is defined [here](ArraySet.md#Public-Types). +The type `SetEntry` is defined [here](ArraySet.md#Public-Types). -Return `m_extSet.getHeadIterator()`. +Return `m_extSet.getHeadSetEntry()`. ### 6.6. getSize diff --git a/Fw/DataStructures/docs/ArraySetOrMapImpl.md b/Fw/DataStructures/docs/ArraySetOrMapImpl.md index 667749abaa8..4a951641e94 100644 --- a/Fw/DataStructures/docs/ArraySetOrMapImpl.md +++ b/Fw/DataStructures/docs/ArraySetOrMapImpl.md @@ -22,8 +22,7 @@ storing the entries in the set or map. |Name|Definition| |----|----------| -|`Entry`|Alias for [`SetOrMapIterator`](SetOrMapIterator.md)| -|`Iterator`|Alias for [`SetOrMapIterator`](SetOrMapIterator.md)| +|`Entry`|Alias for [`SetOrMapEntry`](SetOrMapEntry.md)| ## 3. Private Member Variables @@ -140,10 +139,10 @@ FwSizeType getCapacity() const Return `m_entries.getSize()`. -### 5.5. getHeadIterator +### 5.5. getHeadEntry ```c++ -const Iterator* getHeadIterator() const +const Entry* getHeadEntry() const ``` 1. Set `result = nullptr`. @@ -184,10 +183,10 @@ Success insert(const KE& keyOrElement, const VN& valueOrNil) 1. If `(status == Success::FAILURE) && (m_size < getCapacity())` - 1. Set `m_entries[m_size] = Iterator(keyOrElement, valueOrNil)`. + 1. Set `m_entries[m_size] = Entry(keyOrElement, valueOrNil)`. 1. If `m_size > 0` then - call `m_entries[m_size - 1].setNextIterator(&m_entries[m_size])`. + call `m_entries[m_size - 1].setNextEntry(&m_entries[m_size])`. 1. Increment `m_size`. @@ -213,9 +212,9 @@ Success remove(const KE& keyOrElement, VN& valueOrNil) 1. `m_entries[i] = m_entries[m_size - 1]`. - 1. Call `m_entries[i].setNextIterator(&m_entries[i + 1])`. + 1. Call `m_entries[i].setNextEntry(&m_entries[i + 1])`. - 1. Otherwise call `m_entries[i].setNextIterator(nullptr)`. + 1. Otherwise call `m_entries[i].setNextEntry(nullptr)`. 1. Decrement `size`. diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index 85b2daff9df..83ad9b4f89f 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -27,8 +27,8 @@ as the map implementation. |Name|Definition| |----|----------| -|`Entry`|Alias of [`SetOrMapIterator`](SetOrMapIterator.md)| -|`Iterator`|Alias of [`MapIterator`](MapIterator.md)| +|`Entry`|Alias of [`SetOrMapEntry`](SetOrMapEntry.md)| +|`Entry`|Alias of [`MapEntry`](MapEntry.md)| ## 4. Private Member Variables @@ -224,25 +224,25 @@ ExternalArrayMap map(entries, capacity); ASSERT_EQ(map.getCapacity(), capacity); ``` -### 6.5. getHeadIterator +### 6.5. getHeadEntry ```c++ -const Iterator* getHeadIterator const override +const Entry* getHeadEntry const override ``` -The type `Iterator` is defined [here](ExternalArrayMap.md#Public-Types). +The type `Entry` is defined [here](ExternalArrayMap.md#Public-Types). -Return `m_impl.getHeadIterator()`. +Return `m_impl.getHeadEntry()`. _Example:_ ```c++ constexpr FwSizeType capacity = 10; ExternalArrayMap::Entry entries[capacity]; ExternalArrayMap map(entries, capacity); -const auto* e = map.getHeadIterator(); +const auto* e = map.getHeadEntry(); FW_ASSERT(e == nullptr); map.insert(0, 1); -e = map.getHeadIterator(); +e = map.getHeadEntry(); FW_ASSERT(e != nullptr); ASSERT_EQ(e->getKey(), 0); ASSERT_EQ(e->getValue(), 1); diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md index efc6cb0bea5..9c64b554d36 100644 --- a/Fw/DataStructures/docs/ExternalArraySet.md +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -26,8 +26,8 @@ as the set implementation. |Name|Definition| |----|----------| -|`Entry`|Alias of [`SetOrMapIterator`](SetOrMapIterator.md)| -|`Iterator`|Alias of [`SetIterator`](SetIterator.md)| +|`Entry`|Alias of [`SetOrMapEntry`](SetOrMapEntry.md)| +|`Entry`|Alias of [`SetEntry`](SetEntry.md)| The type `Nil` is defined [here](Nil.md). @@ -220,25 +220,25 @@ ExternalArraySet set(entries, capacity); ASSERT_EQ(set.getCapacity(), capacity); ``` -### 6.5. getHeadIterator +### 6.5. getHeadEntry ```c++ -const Iterator* getHeadIterator const override +const Entry* getHeadEntry const override ``` -The type `Iterator` is defined [here](ExternalArraySet.md#Public-Types). +The type `Entry` is defined [here](ExternalArraySet.md#Public-Types). -Return `m_impl.getHeadIterator()`. +Return `m_impl.getHeadEntry()`. _Example:_ ```c++ constexpr FwSizeType capacity = 10; ExternalArraySet::Entry entries[capacity]; ExternalArraySet set(entries, capacity); -const auto* e = set.getHeadIterator(); +const auto* e = set.getHeadEntry(); FW_ASSERT(e == nullptr); set.insert(42); -e = set.getHeadIterator(); +e = set.getHeadEntry(); FW_ASSERT(e != nullptr); ASSERT_EQ(e->getElement(), 42); ``` diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index d7805e72357..f43b3780dea 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -20,7 +20,7 @@ It represents an abstract base class for a map. |Name|Definition| |----|----------| -|`Iterator`|Alias of [`MapIterator`](MapIterator.md)| +|`Entry`|Alias of [`MapEntry`](MapEntry.md)| ## 3. Private Constructors @@ -90,7 +90,7 @@ void copyDataFrom(const MapBase& map) 1. Let `size` be the minimum of `map.getSize()` and `getCapacity()`. - 1. Set `e = map.getHeadIterator()`. + 1. Set `e = map.getHeadEntry()`. 1. For `i` in [0, `size`) @@ -100,7 +100,7 @@ void copyDataFrom(const MapBase& map) 1. Assert `status == Success::SUCCESS`. - 1. Set `e = e->getNextMapIterator()` + 1. Set `e = e->getNextMapEntry()` _Example:_ ```c++ @@ -161,10 +161,10 @@ void f(const MapBase& map) { } ``` -### 6.5. getHeadIterator +### 6.5. getHeadEntry ```c++ -virtual const Iterator* getHeadIterator() const = 0 +virtual const Entry* getHeadEntry() const = 0 ``` Get a pointer to the head iterator for the map, or `nullptr` if there is none. @@ -173,10 +173,10 @@ _Example:_ ```c++ void f(const MapBase& map) { map.clear(); - const auto* e = map.getHeadIterator(); + const auto* e = map.getHeadEntry(); ASSERT_EQ(e, nullptr); map.insert(0, 1); - e = map.getHeadIterator(); + e = map.getHeadEntry(); ASSERT_EQ(e, nullptr); ASSERT_EQ(e->getKey(), 0); ASSERT_EQ(e->getValue(), 1); diff --git a/Fw/DataStructures/docs/MapIterator.md b/Fw/DataStructures/docs/MapEntry.md similarity index 74% rename from Fw/DataStructures/docs/MapIterator.md rename to Fw/DataStructures/docs/MapEntry.md index 9cecd162603..25b95b6cca9 100644 --- a/Fw/DataStructures/docs/MapIterator.md +++ b/Fw/DataStructures/docs/MapEntry.md @@ -1,12 +1,12 @@ -# MapIterator +# MapEntry -`MapIterator` is an abstract class template +`MapEntry` is an abstract class template defined in [`Fw/DataStructures`](sdd.md). It represents an iterator for a map. ## 1. Template Parameters -`MapIterator` has the following template parameters. +`MapEntry` has the following template parameters. |Kind|Name|Purpose| |----|----|-------| @@ -18,7 +18,7 @@ It represents an iterator for a map. ### 2.1. Copy Constructor ```c++ -MapIterator(const MapIterator& map) +MapEntry(const MapEntry& map) ``` Defined as `= delete`. @@ -28,7 +28,7 @@ Defined as `= delete`. ### 3.1. Zero-Argument Constructor ```c++ -MapIterator() +MapEntry() ``` Use default initialization of members. @@ -36,7 +36,7 @@ Use default initialization of members. ### 3.2. Destructor ```c++ -virtual ~MapIterator() +virtual ~MapEntry() ``` Defined as `= default`. @@ -46,7 +46,7 @@ Defined as `= default`. ### 4.1. operator= ```c++ -MapIterator& operator=(const MapIterator&) +MapEntry& operator=(const MapEntry&) ``` Defined as `= delete`. @@ -69,10 +69,10 @@ virtual const V& getValue() const = 0 Return a reference to the value. -### 5.3. getNextMapIterator +### 5.3. getNextMapEntry ```c++ -virtual const MapIterator* getNextMapIterator() = 0 +virtual const MapEntry* getNextMapEntry() = 0 ``` Return a pointer to the next map iterator, or `nullptr` if there is none. diff --git a/Fw/DataStructures/docs/Nil.md b/Fw/DataStructures/docs/Nil.md index e5f2d73ab10..6f804858d4f 100644 --- a/Fw/DataStructures/docs/Nil.md +++ b/Fw/DataStructures/docs/Nil.md @@ -2,5 +2,5 @@ `Nil` is an empty type. It is a placeholder that is used as the value type -when a [`SetOrMapIterator`](SetOrMapIterator.md) +when a [`SetOrMapEntry`](SetOrMapEntry.md) is used as a set iterator. diff --git a/Fw/DataStructures/docs/SetBase.md b/Fw/DataStructures/docs/SetBase.md index 42c2a5f63c9..6b0e3f6b47e 100644 --- a/Fw/DataStructures/docs/SetBase.md +++ b/Fw/DataStructures/docs/SetBase.md @@ -19,7 +19,7 @@ It represents an abstract base class for a set. |Name|Definition| |----|----------| -|`Iterator`|Alias of [`SetIterator`](SetIterator.md)| +|`Entry`|Alias of [`SetEntry`](SetEntry.md)| ## 3. Private Constructors @@ -89,7 +89,7 @@ void copyDataFrom(const SetBase& set) 1. Let `size` be the minimum of `set.getSize()` and `getCapacity()`. - 1. Set `e = set.getHeadIterator()`. + 1. Set `e = set.getHeadEntry()`. 1. For `i` in [0, `size`) @@ -99,7 +99,7 @@ void copyDataFrom(const SetBase& set) 1. Assert `status == Success::SUCCESS`. - 1. Set `e = e->getNextSetIterator()` + 1. Set `e = e->getNextSetEntry()` _Example:_ @@ -159,10 +159,10 @@ void f(const SetBase& set) { } ``` -### 6.5. getHeadIterator +### 6.5. getHeadEntry ```c++ -virtual const Iterator* getHeadIterator const = 0 +virtual const Entry* getHeadEntry const = 0 ``` Get a pointer to the head iterator for the set, or `nullptr` if there is none. @@ -171,10 +171,10 @@ _Example:_ ```c++ void f(const SetBase& set) { set.clear(); - const auto* e = set.getHeadIterator(); + const auto* e = set.getHeadEntry(); ASSERT_EQ(e, nullptr); set.insert(42); - e = set.getHeadIterator(); + e = set.getHeadEntry(); ASSERT_NE(e, nullptr); ASSERT_EQ(e->getElement(), 42); } diff --git a/Fw/DataStructures/docs/SetIterator.md b/Fw/DataStructures/docs/SetEntry.md similarity index 72% rename from Fw/DataStructures/docs/SetIterator.md rename to Fw/DataStructures/docs/SetEntry.md index 29e00fe5543..8a3192af5f6 100644 --- a/Fw/DataStructures/docs/SetIterator.md +++ b/Fw/DataStructures/docs/SetEntry.md @@ -1,12 +1,12 @@ -# SetIterator +# SetEntry -`SetIterator` is an abstract class template +`SetEntry` is an abstract class template defined in [`Fw/DataStructures`](sdd.md). It represents an iterator for a set. ## 1. Template Parameters -`SetIterator` has the following template parameters. +`SetEntry` has the following template parameters. |Kind|Name|Purpose| |----|----|-------| @@ -17,7 +17,7 @@ It represents an iterator for a set. ### 2.1. Copy Constructor ```c++ -SetIterator(const SetIterator& set) +SetEntry(const SetEntry& set) ``` Defined as `= delete`. @@ -27,7 +27,7 @@ Defined as `= delete`. ### 3.1. Zero-Argument Constructor ```c++ -SetIterator() +SetEntry() ``` Use default initialization of members. @@ -35,7 +35,7 @@ Use default initialization of members. ### 3.2. Destructor ```c++ -virtual ~SetIterator() +virtual ~SetEntry() ``` Defined as `= default`. @@ -45,7 +45,7 @@ Defined as `= default`. ### 4.1. operator= ```c++ -SetIterator& operator=(const SetIterator& setIterator) +SetEntry& operator=(const SetEntry& setEntry) ``` Defined as `= delete`. @@ -60,10 +60,10 @@ virtual const T& getElement() const = 0 Return a reference to the set element stored in the iterator. -### 5.2. getNextSetIterator +### 5.2. getNextSetEntry ```c++ -virtual const SetIterator* getNextSetIterator() = 0 +virtual const SetEntry* getNextSetEntry() = 0 ``` Return a pointer to the next iterator for the set, or `nullptr` if diff --git a/Fw/DataStructures/docs/SetOrMapIterator.md b/Fw/DataStructures/docs/SetOrMapEntry.md similarity index 63% rename from Fw/DataStructures/docs/SetOrMapIterator.md rename to Fw/DataStructures/docs/SetOrMapEntry.md index e2786970ab2..e7db0517c3b 100644 --- a/Fw/DataStructures/docs/SetOrMapIterator.md +++ b/Fw/DataStructures/docs/SetOrMapEntry.md @@ -1,12 +1,12 @@ -# SetOrMapIterator +# SetOrMapEntry -`SetOrMapIterator` is a final class template +`SetOrMapEntry` is a final class template defined in [`Fw/DataStructures`](sdd.md). It represents an iterator for a set or a map. ## 1. Template Parameters -`SetOrMapIterator` has the following template parameters. +`SetOrMapEntry` has the following template parameters. |Kind|Name|Purpose| |----|----|-------| @@ -15,35 +15,35 @@ It represents an iterator for a set or a map. ## 2. Base Class -`SetOrMapIterator` is publicly derived from the following +`SetOrMapEntry` is publicly derived from the following templates: -1. [`MapIterator`](MapIterator.md). +1. [`MapEntry`](MapEntry.md). -1. [`SetIterator`](SetIterator.md). +1. [`SetEntry`](SetEntry.md). ```mermaid classDiagram - MapIterator <|-- SetOrMapIterator - SetIterator <|-- SetOrMapIterator + MapEntry <|-- SetOrMapEntry + SetEntry <|-- SetOrMapEntry ``` ## 3. Private Member Variables -`SetOrMapIterator` has the following private member variables. +`SetOrMapEntry` has the following private member variables. |Name|Type|Purpose|Default Value| |----|----|-------|-------------| |`m_keyOrElement`|`KE`|The map key or set element|C++ default initialization| |`m_valueOrNil`|`VN`|The value or [`Nil`](Nil.md)|C++ default initialization| -|`m_next`|`const SetOrMapIterator*`|Pointer to the next iterator or `nullptr` if none|`nullptr`| +|`m_next`|`const SetOrMapEntry*`|Pointer to the next iterator or `nullptr` if none|`nullptr`| ## 4. Public Constructors and Destructors ### 4.1. Zero-Argument Constructor ```c++ -SetOrMapIterator() +SetOrMapEntry() ``` Use default initialization of members. @@ -51,7 +51,7 @@ Use default initialization of members. ### 4.2. Constructor Providing Members ```c++ -SetOrMapIterator(const KE& keyOrElement, const VN& valueOrNil, const SetOrMapIterator* next = nullptr) +SetOrMapEntry(const KE& keyOrElement, const VN& valueOrNil, const SetOrMapEntry* next = nullptr) ``` 1. Set `m_keyOrElement = keyOrElement`. @@ -63,7 +63,7 @@ SetOrMapIterator(const KE& keyOrElement, const VN& valueOrNil, const SetOrMapIte ### 4.3. Copy Constructor ```c++ -SetOrMapIterator(const SetOrMapIterator& iterator) +SetOrMapEntry(const SetOrMapEntry& iterator) ``` Set `*this = iterator`. @@ -71,7 +71,7 @@ Set `*this = iterator`. ### 4.4. Destructor ```c++ -~SetOrMapIterator() override +~SetOrMapEntry() override ``` Defined as `= default`. @@ -81,7 +81,7 @@ Defined as `= default`. ### 5.1. operator= ```c++ -SetOrMapIterator& operator=(const SetOrMapIterator& iterator) +SetOrMapEntry& operator=(const SetOrMapEntry& iterator) ``` 1. If `this != &iterator` @@ -116,26 +116,26 @@ const VN& getValue() const override Return a reference to `m_valueOrNil`. -### 5.4. getNextIterator +### 5.4. getNextEntry ```c++ -SetOrMapIterator* getNextIterator() +SetOrMapEntry* getNextEntry() ``` Return `m_next`. -### 5.4. getNextMapIterator +### 5.4. getNextMapEntry ```c++ -MapIterator* getNextMapIterator() override +MapEntry* getNextMapEntry() override ``` Return `m_next`. -### 5.5. getNextSetIterator +### 5.5. getNextSetEntry ```c++ -SetIterator* getNextSetIterator() override +SetEntry* getNextSetEntry() override ``` Return `m_next`. @@ -148,10 +148,10 @@ void setKeyOrElement(const KE& keyOrElement) const Set `m_keyOrElement = keyOrElement`. -### 5.8. setNextIterator +### 5.8. setNextEntry ```c++ -void setNextIterator(const SetOrMapIterator* next) +void setNextEntry(const SetOrMapEntry* next) ``` Set `m_next = next`. From fc7553a098f006fa69cc1d25e7e3c26713cf63d4 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 13 Jul 2025 11:44:07 -0700 Subject: [PATCH 343/458] Revise data structures implementation Rename Iterator to Entry --- Fw/DataStructures/ArrayMap.hpp | 4 +-- Fw/DataStructures/ArraySet.hpp | 4 +-- Fw/DataStructures/ArraySetOrMapImpl.hpp | 6 ++-- Fw/DataStructures/ExternalArrayMap.hpp | 4 +-- Fw/DataStructures/ExternalArraySet.hpp | 4 +-- Fw/DataStructures/MapBase.hpp | 6 ++-- .../{MapIterator.hpp => MapEntry.hpp} | 18 +++++----- Fw/DataStructures/SetBase.hpp | 6 ++-- .../{SetIterator.hpp => SetEntry.hpp} | 18 +++++----- ...SetOrMapIterator.hpp => SetOrMapEntry.hpp} | 34 +++++++++---------- Fw/DataStructures/test/ut/ArrayMapTest.cpp | 2 +- .../test/ut/ArraySetOrMapImplTester.hpp | 2 +- Fw/DataStructures/test/ut/ArraySetTest.cpp | 2 +- .../test/ut/ExternalArrayMapTest.cpp | 2 +- .../test/ut/ExternalArraySetTest.cpp | 2 +- .../ut/STest/ArraySetOrMapImplTestState.hpp | 2 +- .../test/ut/STest/MapTestRules.hpp | 6 ++-- .../test/ut/STest/MapTestState.hpp | 2 +- .../test/ut/STest/SetTestRules.hpp | 6 ++-- .../test/ut/STest/SetTestState.hpp | 2 +- 20 files changed, 66 insertions(+), 66 deletions(-) rename Fw/DataStructures/{MapIterator.hpp => MapEntry.hpp} (83%) rename Fw/DataStructures/{SetIterator.hpp => SetEntry.hpp} (83%) rename Fw/DataStructures/{SetOrMapIterator.hpp => SetOrMapEntry.hpp} (70%) diff --git a/Fw/DataStructures/ArrayMap.hpp b/Fw/DataStructures/ArrayMap.hpp index 25c28e4bb9e..11bde26d7f7 100644 --- a/Fw/DataStructures/ArrayMap.hpp +++ b/Fw/DataStructures/ArrayMap.hpp @@ -26,10 +26,10 @@ class ArrayMap final : public MapBase { // ---------------------------------------------------------------------- //! The type of a map entry - using Entry = SetOrMapIterator; + using Entry = SetOrMapEntry; //! The type of a map iterator - using Iterator = MapIterator; + using Iterator = MapEntry; //! The type of the map entries using Entries = Entry[C]; diff --git a/Fw/DataStructures/ArraySet.hpp b/Fw/DataStructures/ArraySet.hpp index fddf37e7038..94bcc85cfc9 100644 --- a/Fw/DataStructures/ArraySet.hpp +++ b/Fw/DataStructures/ArraySet.hpp @@ -26,10 +26,10 @@ class ArraySet final : public SetBase { // ---------------------------------------------------------------------- //! The type of a set entry - using Entry = SetOrMapIterator; + using Entry = SetOrMapEntry; //! The type of a set iterator - using Iterator = SetIterator; + using Iterator = SetEntry; //! The type of the set entries using Entries = Entry[C]; diff --git a/Fw/DataStructures/ArraySetOrMapImpl.hpp b/Fw/DataStructures/ArraySetOrMapImpl.hpp index 0a5eedfe6e9..1083ce3c843 100644 --- a/Fw/DataStructures/ArraySetOrMapImpl.hpp +++ b/Fw/DataStructures/ArraySetOrMapImpl.hpp @@ -8,7 +8,7 @@ #define Fw_ArraySetOrMapImpl_HPP #include "Fw/DataStructures/ExternalArray.hpp" -#include "Fw/DataStructures/SetOrMapIterator.hpp" +#include "Fw/DataStructures/SetOrMapEntry.hpp" #include "Fw/Types/Assert.hpp" #include "Fw/Types/SuccessEnumAc.hpp" @@ -29,10 +29,10 @@ class ArraySetOrMapImpl { // ---------------------------------------------------------------------- //! The type of an entry in the set or map - using Entry = SetOrMapIterator; + using Entry = SetOrMapEntry; //! The type of a set or map iterator - using Iterator = SetOrMapIterator; + using Iterator = SetOrMapEntry; public: // ---------------------------------------------------------------------- diff --git a/Fw/DataStructures/ExternalArrayMap.hpp b/Fw/DataStructures/ExternalArrayMap.hpp index 0382e8603cd..f24c2621983 100644 --- a/Fw/DataStructures/ExternalArrayMap.hpp +++ b/Fw/DataStructures/ExternalArrayMap.hpp @@ -28,10 +28,10 @@ class ExternalArrayMap final : public MapBase { // ---------------------------------------------------------------------- //! The type of a map entry - using Entry = SetOrMapIterator; + using Entry = SetOrMapEntry; //! The type of a map iterator - using Iterator = MapIterator; + using Iterator = MapEntry; public: // ---------------------------------------------------------------------- diff --git a/Fw/DataStructures/ExternalArraySet.hpp b/Fw/DataStructures/ExternalArraySet.hpp index bdc1561c9b9..43dc1983fb8 100644 --- a/Fw/DataStructures/ExternalArraySet.hpp +++ b/Fw/DataStructures/ExternalArraySet.hpp @@ -29,10 +29,10 @@ class ExternalArraySet final : public SetBase { // ---------------------------------------------------------------------- //! The type of a set entry - using Entry = SetOrMapIterator; + using Entry = SetOrMapEntry; //! The type of a set iterator - using Iterator = SetIterator; + using Iterator = SetEntry; public: // ---------------------------------------------------------------------- diff --git a/Fw/DataStructures/MapBase.hpp b/Fw/DataStructures/MapBase.hpp index 417453a59a8..929a523b9b9 100644 --- a/Fw/DataStructures/MapBase.hpp +++ b/Fw/DataStructures/MapBase.hpp @@ -7,7 +7,7 @@ #ifndef Fw_MapBase_HPP #define Fw_MapBase_HPP -#include "Fw/DataStructures/MapIterator.hpp" +#include "Fw/DataStructures/MapEntry.hpp" #include "Fw/Types/Assert.hpp" #include "Fw/Types/SuccessEnumAc.hpp" @@ -21,7 +21,7 @@ class MapBase { // ---------------------------------------------------------------------- //! The type of a map iterator - using Iterator = MapIterator; + using Iterator = MapEntry; private: // ---------------------------------------------------------------------- @@ -71,7 +71,7 @@ class MapBase { FW_ASSERT(e != nullptr); const auto status = this->insert(e->getKey(), e->getValue()); FW_ASSERT(status == Success::SUCCESS, static_cast(status)); - e = e->getNextMapIterator(); + e = e->getNextMapEntry(); } } } diff --git a/Fw/DataStructures/MapIterator.hpp b/Fw/DataStructures/MapEntry.hpp similarity index 83% rename from Fw/DataStructures/MapIterator.hpp rename to Fw/DataStructures/MapEntry.hpp index 1dd7b8a8611..0f4dc0e8abb 100644 --- a/Fw/DataStructures/MapIterator.hpp +++ b/Fw/DataStructures/MapEntry.hpp @@ -1,18 +1,18 @@ // ====================================================================== -// \title MapIterator +// \title MapEntry // \author bocchino // \brief An abstract class template representing an iterator for a map // ====================================================================== -#ifndef Fw_MapIterator_HPP -#define Fw_MapIterator_HPP +#ifndef Fw_MapEntry_HPP +#define Fw_MapEntry_HPP #include "Fw/FPrimeBasicTypes.hpp" namespace Fw { template -class MapIterator { +class MapEntry { private: // ---------------------------------------------------------------------- // Private constructors @@ -20,7 +20,7 @@ class MapIterator { //! Copy constructor deleted in the base class //! Behavior depends on the implementation - MapIterator(const MapIterator&) = delete; + MapEntry(const MapEntry&) = delete; protected: // ---------------------------------------------------------------------- @@ -28,10 +28,10 @@ class MapIterator { // ---------------------------------------------------------------------- //! Zero-argument constructor - MapIterator() {} + MapEntry() {} //! Destructor - virtual ~MapIterator() = default; + virtual ~MapEntry() = default; private: // ---------------------------------------------------------------------- @@ -41,7 +41,7 @@ class MapIterator { //! operator= deleted in the base class //! Behavior depends on the implementation //! We avoid virtual user-defined operators - MapIterator& operator=(const MapIterator&) = delete; + MapEntry& operator=(const MapEntry&) = delete; public: // ---------------------------------------------------------------------- @@ -58,7 +58,7 @@ class MapIterator { //! Get the next map iterator //! \return The map iterator, or nullptr if none - virtual const MapIterator* getNextMapIterator() const = 0; + virtual const MapEntry* getNextMapEntry() const = 0; }; } // namespace Fw diff --git a/Fw/DataStructures/SetBase.hpp b/Fw/DataStructures/SetBase.hpp index 81b66af7ab6..fd30099477c 100644 --- a/Fw/DataStructures/SetBase.hpp +++ b/Fw/DataStructures/SetBase.hpp @@ -7,7 +7,7 @@ #ifndef Fw_SetBase_HPP #define Fw_SetBase_HPP -#include "Fw/DataStructures/SetIterator.hpp" +#include "Fw/DataStructures/SetEntry.hpp" #include "Fw/Types/Assert.hpp" #include "Fw/Types/SuccessEnumAc.hpp" @@ -21,7 +21,7 @@ class SetBase { // ---------------------------------------------------------------------- //! The type of a set iterator - using Iterator = SetIterator; + using Iterator = SetEntry; private: // ---------------------------------------------------------------------- @@ -71,7 +71,7 @@ class SetBase { FW_ASSERT(e != nullptr); const auto status = this->insert(e->getElement()); FW_ASSERT(status == Success::SUCCESS, static_cast(status)); - e = e->getNextSetIterator(); + e = e->getNextSetEntry(); } } } diff --git a/Fw/DataStructures/SetIterator.hpp b/Fw/DataStructures/SetEntry.hpp similarity index 83% rename from Fw/DataStructures/SetIterator.hpp rename to Fw/DataStructures/SetEntry.hpp index 201d1a56ed3..768a07f5b00 100644 --- a/Fw/DataStructures/SetIterator.hpp +++ b/Fw/DataStructures/SetEntry.hpp @@ -1,18 +1,18 @@ // ====================================================================== -// \title SetIterator +// \title SetEntry // \author bocchino // \brief An abstract class template representing an iterator for a set // ====================================================================== -#ifndef Fw_SetIterator_HPP -#define Fw_SetIterator_HPP +#ifndef Fw_SetEntry_HPP +#define Fw_SetEntry_HPP #include "Fw/FPrimeBasicTypes.hpp" namespace Fw { template -class SetIterator { +class SetEntry { private: // ---------------------------------------------------------------------- // Private constructors @@ -20,7 +20,7 @@ class SetIterator { //! Copy constructor deleted in the base class //! Behavior depends on the implementation - SetIterator(const SetIterator&) = delete; + SetEntry(const SetEntry&) = delete; protected: // ---------------------------------------------------------------------- @@ -28,10 +28,10 @@ class SetIterator { // ---------------------------------------------------------------------- //! Zero-argument constructor - SetIterator() {} + SetEntry() {} //! Destructor - virtual ~SetIterator() = default; + virtual ~SetEntry() = default; private: // ---------------------------------------------------------------------- @@ -41,7 +41,7 @@ class SetIterator { //! operator= deleted in the base class //! Behavior depends on the implementation //! We avoid virtual user-defined operators - SetIterator& operator=(const SetIterator&) = delete; + SetEntry& operator=(const SetEntry&) = delete; public: // ---------------------------------------------------------------------- @@ -54,7 +54,7 @@ class SetIterator { //! Get the next set iterator //! \return The set iterator, or nullptr if none - virtual const SetIterator* getNextSetIterator() const = 0; + virtual const SetEntry* getNextSetEntry() const = 0; }; } // namespace Fw diff --git a/Fw/DataStructures/SetOrMapIterator.hpp b/Fw/DataStructures/SetOrMapEntry.hpp similarity index 70% rename from Fw/DataStructures/SetOrMapIterator.hpp rename to Fw/DataStructures/SetOrMapEntry.hpp index d843133f818..282ce3d2f4c 100644 --- a/Fw/DataStructures/SetOrMapIterator.hpp +++ b/Fw/DataStructures/SetOrMapEntry.hpp @@ -1,40 +1,40 @@ // ====================================================================== -// \title SetOrMapIterator +// \title SetOrMapEntry // \author bocchino // \brief A class template representing an iterator for a set or map // ====================================================================== -#ifndef Fw_SetOrMapIterator_HPP -#define Fw_SetOrMapIterator_HPP +#ifndef Fw_SetOrMapEntry_HPP +#define Fw_SetOrMapEntry_HPP -#include "Fw/DataStructures/MapIterator.hpp" -#include "Fw/DataStructures/SetIterator.hpp" +#include "Fw/DataStructures/MapEntry.hpp" +#include "Fw/DataStructures/SetEntry.hpp" #include "Fw/FPrimeBasicTypes.hpp" namespace Fw { template -class SetOrMapIterator final : public MapIterator, public SetIterator { +class SetOrMapEntry final : public MapEntry, public SetEntry { public: // ---------------------------------------------------------------------- // Public constructors and destructors // ---------------------------------------------------------------------- //! Zero-argument constructor - SetOrMapIterator() : MapIterator() {} + SetOrMapEntry() : MapEntry() {} //! Constructor providing members - SetOrMapIterator(const KE& keyOrElement, //!< The key or element + SetOrMapEntry(const KE& keyOrElement, //!< The key or element const VN& valueOrNil, //!< The value or Nil - const SetOrMapIterator* next = nullptr //!< The next iterator + const SetOrMapEntry* next = nullptr //!< The next iterator ) : m_keyOrElement(keyOrElement), m_valueOrNil(valueOrNil), m_next(next) {} //! Copy constructor - SetOrMapIterator(const SetOrMapIterator& iterator) { *this = iterator; } + SetOrMapEntry(const SetOrMapEntry& iterator) { *this = iterator; } //! Destructor - ~SetOrMapIterator() override = default; + ~SetOrMapEntry() override = default; public: // ---------------------------------------------------------------------- @@ -42,7 +42,7 @@ class SetOrMapIterator final : public MapIterator, public SetIterator& operator=(const SetOrMapIterator& iterator) { + SetOrMapEntry& operator=(const SetOrMapEntry& iterator) { if (this != &iterator) { this->m_keyOrElement = iterator.m_keyOrElement; this->m_valueOrNil = iterator.m_valueOrNil; @@ -65,15 +65,15 @@ class SetOrMapIterator final : public MapIterator, public SetIterator* getNextIterator() const { return this->m_next; } + const SetOrMapEntry* getNextIterator() const { return this->m_next; } //! Get the next map iterator //! \return The map iterator, or nullptr if none - const MapIterator* getNextMapIterator() const override { return this->m_next; } + const MapEntry* getNextMapEntry() const override { return this->m_next; } //! Get the next set iterator //! \return The set iterator, or nullptr if none - const SetIterator* getNextSetIterator() const override { return this->m_next; } + const SetEntry* getNextSetEntry() const override { return this->m_next; } //! Set the key or element void setKeyOrElement(const KE& keyOrElement //!< The key or element @@ -82,7 +82,7 @@ class SetOrMapIterator final : public MapIterator, public SetIterator* next) { this->m_next = next; } + void setNextIterator(const SetOrMapEntry* next) { this->m_next = next; } //! Set the value or Nil void setValueOrNil(const VN& valueOrNil) { this->m_valueOrNil = valueOrNil; } @@ -99,7 +99,7 @@ class SetOrMapIterator final : public MapIterator, public SetIterator* m_next = nullptr; + const SetOrMapEntry* m_next = nullptr; }; } // namespace Fw diff --git a/Fw/DataStructures/test/ut/ArrayMapTest.cpp b/Fw/DataStructures/test/ut/ArrayMapTest.cpp index 0a6dd2354c9..e10a3971a22 100644 --- a/Fw/DataStructures/test/ut/ArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ArrayMapTest.cpp @@ -29,7 +29,7 @@ class ArrayMapTester { namespace MapTest { -using Entry = SetOrMapIterator; +using Entry = SetOrMapEntry; using Map = ArrayMap; using MapTester = ArrayMapTester; using ImplTester = ArraySetOrMapImplTester; diff --git a/Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp b/Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp index 9e64da748b9..f725e227f3b 100644 --- a/Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp +++ b/Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp @@ -17,7 +17,7 @@ namespace Fw { template class ArraySetOrMapImplTester { public: - using Entry = SetOrMapIterator; + using Entry = SetOrMapEntry; ArraySetOrMapImplTester(const ArraySetOrMapImpl& impl) : m_impl(impl) {} diff --git a/Fw/DataStructures/test/ut/ArraySetTest.cpp b/Fw/DataStructures/test/ut/ArraySetTest.cpp index 44c65eab2c4..1af200ede14 100644 --- a/Fw/DataStructures/test/ut/ArraySetTest.cpp +++ b/Fw/DataStructures/test/ut/ArraySetTest.cpp @@ -29,7 +29,7 @@ class ArraySetTester { namespace SetTest { -using Entry = SetOrMapIterator; +using Entry = SetOrMapEntry; using Set = ArraySet; using SetTester = ArraySetTester; using ImplTester = ArraySetOrMapImplTester; diff --git a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp index 81e7072b4f9..9426ff07bb5 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp @@ -25,7 +25,7 @@ class ExternalArrayMapTester { namespace MapTest { -using Entry = SetOrMapIterator; +using Entry = SetOrMapEntry; using Map = ExternalArrayMap; using MapTester = ExternalArrayMapTester; using ImplTester = ArraySetOrMapImplTester; diff --git a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp index 6efc60994ee..b2e0babddd7 100644 --- a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp @@ -27,7 +27,7 @@ class ExternalArraySetTester { namespace SetTest { -using Entry = SetOrMapIterator; +using Entry = SetOrMapEntry; using Set = ExternalArraySet; using SetTester = ExternalArraySetTester; using ImplTester = ArraySetOrMapImplTester; diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp index c15e7be3e8d..4f9b3b53316 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp @@ -29,7 +29,7 @@ struct State { //! The Tester type using Tester = ArraySetOrMapImplTester; //! The entry type - using Entry = SetOrMapIterator; + using Entry = SetOrMapEntry; //! Constructor State(Impl& a_impl) : impl(a_impl), tester(a_impl) {} //! The array set or map under test diff --git a/Fw/DataStructures/test/ut/STest/MapTestRules.hpp b/Fw/DataStructures/test/ut/STest/MapTestRules.hpp index 783dbb488a0..27bd949aefb 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/MapTestRules.hpp @@ -56,7 +56,7 @@ struct FindExisting : public Rule { const auto* it = state.map.getHeadIterator(); for (FwSizeType i = 0; i < index; i++) { ASSERT_NE(it, nullptr); - it = it->getNextMapIterator(); + it = it->getNextMapEntry(); } ASSERT_NE(it, nullptr); const auto key = it->getKey(); @@ -77,7 +77,7 @@ struct InsertExisting : public Rule { const auto* it = state.map.getHeadIterator(); for (FwSizeType i = 0; i < index; i++) { ASSERT_NE(it, nullptr); - it = it->getNextMapIterator(); + it = it->getNextMapEntry(); } ASSERT_NE(it, nullptr); const auto key = it->getKey(); @@ -150,7 +150,7 @@ struct RemoveExisting : public Rule { const auto* it = state.map.getHeadIterator(); for (FwSizeType i = 0; i < index; i++) { ASSERT_NE(it, nullptr); - it = it->getNextMapIterator(); + it = it->getNextMapEntry(); } ASSERT_NE(it, nullptr); const auto key = it->getKey(); diff --git a/Fw/DataStructures/test/ut/STest/MapTestState.hpp b/Fw/DataStructures/test/ut/STest/MapTestState.hpp index 91b12283b17..688546529a5 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/MapTestState.hpp @@ -26,7 +26,7 @@ struct State { //! THe MapBase type using MapBase = MapBase; //! The iterator type - using Iterator = MapIterator; + using Iterator = MapEntry; //! Constructor State(MapBase& a_map) : map(a_map) {} //! The map under test diff --git a/Fw/DataStructures/test/ut/STest/SetTestRules.hpp b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp index f43d32dcaa2..0ef46c86f8e 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp @@ -55,7 +55,7 @@ struct FindExisting : public Rule { ASSERT_NE(it, nullptr); const auto e = it->getElement(); ASSERT_TRUE(state.modelSetContains(e)); - it = it->getNextSetIterator(); + it = it->getNextSetEntry(); } } // Check that all elements of modelSet are in set @@ -80,7 +80,7 @@ struct InsertExisting : public Rule { const auto* it = state.set.getHeadIterator(); for (FwSizeType i = 0; i < index; i++) { ASSERT_NE(it, nullptr); - it = it->getNextSetIterator(); + it = it->getNextSetEntry(); } ASSERT_NE(it, nullptr); const auto e = it->getElement(); @@ -146,7 +146,7 @@ struct RemoveExisting : public Rule { const auto* it = state.set.getHeadIterator(); for (FwSizeType i = 0; i < index; i++) { ASSERT_NE(it, nullptr); - it = it->getNextSetIterator(); + it = it->getNextSetEntry(); } ASSERT_NE(it, nullptr); const auto e = it->getElement(); diff --git a/Fw/DataStructures/test/ut/STest/SetTestState.hpp b/Fw/DataStructures/test/ut/STest/SetTestState.hpp index c5aa2e4992d..c1d3a9a23bc 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/SetTestState.hpp @@ -26,7 +26,7 @@ struct State { //! THe SetBase type using SetBase = SetBase; //! The iterator type - using Iterator = SetIterator; + using Iterator = SetEntry; //! Constructor State(SetBase& a_set) : set(a_set) {} //! The set under test From 2afdbce9258032143661d36c13ab8ba8072d215d Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 13 Jul 2025 12:05:34 -0700 Subject: [PATCH 344/458] Revise data structures impl and test Rename Iterator to Entry throughout --- Fw/DataStructures/ArrayMap.hpp | 14 +++---- Fw/DataStructures/ArraySet.hpp | 10 ++--- Fw/DataStructures/ArraySetOrMapImpl.hpp | 15 +++---- Fw/DataStructures/ExternalArrayMap.hpp | 10 ++--- Fw/DataStructures/ExternalArraySet.hpp | 8 ++-- Fw/DataStructures/MapBase.hpp | 6 +-- Fw/DataStructures/SetBase.hpp | 12 +++--- Fw/DataStructures/SetOrMapEntry.hpp | 42 +++++++++---------- Fw/DataStructures/docs/MapBase.md | 14 +++---- .../ut/STest/ArraySetOrMapImplTestRules.hpp | 30 ++++++------- .../test/ut/STest/MapTestRules.hpp | 30 ++++++------- .../test/ut/STest/MapTestState.hpp | 2 - .../test/ut/STest/SetTestRules.hpp | 36 ++++++++-------- .../test/ut/STest/SetTestState.hpp | 2 - 14 files changed, 112 insertions(+), 119 deletions(-) diff --git a/Fw/DataStructures/ArrayMap.hpp b/Fw/DataStructures/ArrayMap.hpp index 11bde26d7f7..bc0fcaa434a 100644 --- a/Fw/DataStructures/ArrayMap.hpp +++ b/Fw/DataStructures/ArrayMap.hpp @@ -25,13 +25,13 @@ class ArrayMap final : public MapBase { // Public types // ---------------------------------------------------------------------- - //! The type of a map entry + //! The type of an entry using Entry = SetOrMapEntry; - //! The type of a map iterator - using Iterator = MapEntry; + //! The type of a map entry + using MapEntry = MapEntry; - //! The type of the map entries + //! The type of the entries using Entries = Entry[C]; public: @@ -74,9 +74,9 @@ class ArrayMap final : public MapBase { //! \return The capacity FwSizeType getCapacity() const override { return this->m_extMap.getCapacity(); } - //! Get the head iterator for the map - //! \return The iterator - const Iterator* getHeadIterator() const override { return this->m_extMap.getHeadIterator(); } + //! Get the head map entry for the map + //! \return The map entry + const MapEntry* getHeadMapEntry() const override { return this->m_extMap.getHeadMapEntry(); } //! Get the size (number of entries) //! \return The size diff --git a/Fw/DataStructures/ArraySet.hpp b/Fw/DataStructures/ArraySet.hpp index 94bcc85cfc9..dc36376f1a9 100644 --- a/Fw/DataStructures/ArraySet.hpp +++ b/Fw/DataStructures/ArraySet.hpp @@ -28,8 +28,8 @@ class ArraySet final : public SetBase { //! The type of a set entry using Entry = SetOrMapEntry; - //! The type of a set iterator - using Iterator = SetEntry; + //! The type of a set entry + using SetEntry = SetEntry; //! The type of the set entries using Entries = Entry[C]; @@ -73,9 +73,9 @@ class ArraySet final : public SetBase { //! \return The capacity FwSizeType getCapacity() const override { return this->m_extSet.getCapacity(); } - //! Get the head iterator for the set - //! \return The iterator - const Iterator* getHeadIterator() const override { return this->m_extSet.getHeadIterator(); } + //! Get the head set entry for the set + //! \return The set entry + const SetEntry* getHeadSetEntry() const override { return this->m_extSet.getHeadSetEntry(); } //! Get the size (number of entries) //! \return The size diff --git a/Fw/DataStructures/ArraySetOrMapImpl.hpp b/Fw/DataStructures/ArraySetOrMapImpl.hpp index 1083ce3c843..6a805155026 100644 --- a/Fw/DataStructures/ArraySetOrMapImpl.hpp +++ b/Fw/DataStructures/ArraySetOrMapImpl.hpp @@ -31,9 +31,6 @@ class ArraySetOrMapImpl { //! The type of an entry in the set or map using Entry = SetOrMapEntry; - //! The type of a set or map iterator - using Iterator = SetOrMapEntry; - public: // ---------------------------------------------------------------------- // Public constructors and destructors @@ -105,8 +102,8 @@ class ArraySetOrMapImpl { //! Get the head iterator for the set or map //! \return The iterator - const Iterator* getHeadIterator() const { - const Iterator* result = nullptr; + const Entry* getHeadEntry() const { + const Entry* result = nullptr; if (this->m_size > 0) { result = &this->m_entries[0]; } @@ -132,9 +129,9 @@ class ArraySetOrMapImpl { } } if ((status == Success::FAILURE) && (this->m_size < this->getCapacity())) { - this->m_entries[this->m_size] = Iterator(keyOrElement, valueOrNil); + this->m_entries[this->m_size] = Entry(keyOrElement, valueOrNil); if (this->m_size > 0) { - this->m_entries[this->m_size - 1].setNextIterator(&this->m_entries[this->m_size]); + this->m_entries[this->m_size - 1].setNextEntry(&this->m_entries[this->m_size]); } this->m_size++; status = Success::SUCCESS; @@ -153,9 +150,9 @@ class ArraySetOrMapImpl { 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_entries[i].setNextIterator(&this->m_entries[i + 1]); + this->m_entries[i].setNextEntry(&this->m_entries[i + 1]); } else { - this->m_entries[i].setNextIterator(nullptr); + this->m_entries[i].setNextEntry(nullptr); } this->m_size--; status = Success::SUCCESS; diff --git a/Fw/DataStructures/ExternalArrayMap.hpp b/Fw/DataStructures/ExternalArrayMap.hpp index f24c2621983..10a54035004 100644 --- a/Fw/DataStructures/ExternalArrayMap.hpp +++ b/Fw/DataStructures/ExternalArrayMap.hpp @@ -30,8 +30,8 @@ class ExternalArrayMap final : public MapBase { //! The type of a map entry using Entry = SetOrMapEntry; - //! The type of a map iterator - using Iterator = MapEntry; + //! The type of a map entry + using MapEntry = MapEntry; public: // ---------------------------------------------------------------------- @@ -94,9 +94,9 @@ class ExternalArrayMap final : public MapBase { //! \return The capacity FwSizeType getCapacity() const override { return this->m_impl.getCapacity(); } - //! Get the head iterator for the map - //! \return The iterator - const Iterator* getHeadIterator() const override { return this->m_impl.getHeadIterator(); } + //! Get the head map entry for the map + //! \return The map entry + const MapEntry* getHeadMapEntry() const override { return this->m_impl.getHeadEntry(); } //! Get the size (number of entries) //! \return The size diff --git a/Fw/DataStructures/ExternalArraySet.hpp b/Fw/DataStructures/ExternalArraySet.hpp index 43dc1983fb8..839ba542763 100644 --- a/Fw/DataStructures/ExternalArraySet.hpp +++ b/Fw/DataStructures/ExternalArraySet.hpp @@ -32,7 +32,7 @@ class ExternalArraySet final : public SetBase { using Entry = SetOrMapEntry; //! The type of a set iterator - using Iterator = SetEntry; + using SetEntry = SetEntry; public: // ---------------------------------------------------------------------- @@ -95,9 +95,9 @@ class ExternalArraySet final : public SetBase { //! \return The capacity FwSizeType getCapacity() const override { return this->m_impl.getCapacity(); } - //! Get the head iterator for the set - //! \return The iterator - const Iterator* getHeadIterator() const override { return this->m_impl.getHeadIterator(); } + //! Get the head set entry for the set + //! \return The set entry + const SetEntry* getHeadSetEntry() const override { return this->m_impl.getHeadEntry(); } //! Get the size (number of entries) //! \return The size diff --git a/Fw/DataStructures/MapBase.hpp b/Fw/DataStructures/MapBase.hpp index 929a523b9b9..16fe22e0db6 100644 --- a/Fw/DataStructures/MapBase.hpp +++ b/Fw/DataStructures/MapBase.hpp @@ -21,7 +21,7 @@ class MapBase { // ---------------------------------------------------------------------- //! The type of a map iterator - using Iterator = MapEntry; + using MapEntry = MapEntry; private: // ---------------------------------------------------------------------- @@ -65,7 +65,7 @@ class MapBase { void copyDataFrom(const MapBase& map) { if (&map != this) { this->clear(); - const auto* e = map.getHeadIterator(); + const auto* e = map.getHeadMapEntry(); const FwSizeType size = FW_MIN(map.getSize(), this->getCapacity()); for (FwSizeType i = 0; i < size; i++) { FW_ASSERT(e != nullptr); @@ -88,7 +88,7 @@ class MapBase { //! Get the head iterator for the map //! \return The iterator - virtual const Iterator* getHeadIterator() const = 0; + virtual const MapEntry* getHeadMapEntry() const = 0; //! Get the size (number of items stored in the map) //! \return The size diff --git a/Fw/DataStructures/SetBase.hpp b/Fw/DataStructures/SetBase.hpp index fd30099477c..0861a723735 100644 --- a/Fw/DataStructures/SetBase.hpp +++ b/Fw/DataStructures/SetBase.hpp @@ -20,8 +20,8 @@ class SetBase { // Public types // ---------------------------------------------------------------------- - //! The type of a set iterator - using Iterator = SetEntry; + //! The type of a set entry + using SetEntry = SetEntry; private: // ---------------------------------------------------------------------- @@ -65,7 +65,7 @@ class SetBase { void copyDataFrom(const SetBase& set) { if (&set != this) { this->clear(); - const auto* e = set.getHeadIterator(); + const auto* e = set.getHeadSetEntry(); const FwSizeType size = FW_MIN(set.getSize(), this->getCapacity()); for (FwSizeType i = 0; i < size; i++) { FW_ASSERT(e != nullptr); @@ -85,9 +85,9 @@ class SetBase { //! \return The capacity virtual FwSizeType getCapacity() const = 0; - //! Get the head iterator for the set - //! \return The iterator - virtual const Iterator* getHeadIterator() const = 0; + //! Get the head set entry for the set + //! \return The set entry + virtual const SetEntry* getHeadSetEntry() const = 0; //! Get the size (number of items stored in the set) //! \return The size diff --git a/Fw/DataStructures/SetOrMapEntry.hpp b/Fw/DataStructures/SetOrMapEntry.hpp index 282ce3d2f4c..2f2388595dd 100644 --- a/Fw/DataStructures/SetOrMapEntry.hpp +++ b/Fw/DataStructures/SetOrMapEntry.hpp @@ -1,7 +1,7 @@ // ====================================================================== // \title SetOrMapEntry // \author bocchino -// \brief A class template representing an iterator for a set or map +// \brief A class template representing an entry for a set or map // ====================================================================== #ifndef Fw_SetOrMapEntry_HPP @@ -26,12 +26,12 @@ class SetOrMapEntry final : public MapEntry, public SetEntry { //! Constructor providing members SetOrMapEntry(const KE& keyOrElement, //!< The key or element const VN& valueOrNil, //!< The value or Nil - const SetOrMapEntry* next = nullptr //!< The next iterator + const SetOrMapEntry* next = nullptr //!< The next entry ) : m_keyOrElement(keyOrElement), m_valueOrNil(valueOrNil), m_next(next) {} //! Copy constructor - SetOrMapEntry(const SetOrMapEntry& iterator) { *this = iterator; } + SetOrMapEntry(const SetOrMapEntry& entry) { *this = entry; } //! Destructor ~SetOrMapEntry() override = default; @@ -42,37 +42,37 @@ class SetOrMapEntry final : public MapEntry, public SetEntry { // ---------------------------------------------------------------------- //! operator= - SetOrMapEntry& operator=(const SetOrMapEntry& iterator) { - if (this != &iterator) { - this->m_keyOrElement = iterator.m_keyOrElement; - this->m_valueOrNil = iterator.m_valueOrNil; - this->m_next = iterator.m_next; + SetOrMapEntry& operator=(const SetOrMapEntry& entry) { + if (this != &entry) { + this->m_keyOrElement = entry.m_keyOrElement; + this->m_valueOrNil = entry.m_valueOrNil; + this->m_next = entry.m_next; } return *this; } - //! Get the element associated with this iterator + //! Get the element associated with this entry //! \return The element const KE& getElement() const override { return this->m_keyOrElement; } - //! Get the key associated with this iterator + //! Get the key associated with this entry //! \return The key const KE& getKey() const override { return this->m_keyOrElement; } - //! Get the value associated with this iterator + //! Get the value associated with this entry //! \return The value const VN& getValue() const override { return this->m_valueOrNil; } - //! Get the next iterator - //! \return The iterator, or nullptr if none - const SetOrMapEntry* getNextIterator() const { return this->m_next; } + //! Get the next entry + //! \return The entry, or nullptr if none + const SetOrMapEntry* getNextEntry() const { return this->m_next; } - //! Get the next map iterator - //! \return The map iterator, or nullptr if none + //! Get the next map entry + //! \return The map entry, or nullptr if none const MapEntry* getNextMapEntry() const override { return this->m_next; } - //! Get the next set iterator - //! \return The set iterator, or nullptr if none + //! Get the next set entry + //! \return The set entry, or nullptr if none const SetEntry* getNextSetEntry() const override { return this->m_next; } //! Set the key or element @@ -81,8 +81,8 @@ class SetOrMapEntry final : public MapEntry, public SetEntry { this->m_keyOrElement = keyOrElement; } - //! Set the next iterator - void setNextIterator(const SetOrMapEntry* next) { this->m_next = next; } + //! Set the next entry + void setNextEntry(const SetOrMapEntry* next) { this->m_next = next; } //! Set the value or Nil void setValueOrNil(const VN& valueOrNil) { this->m_valueOrNil = valueOrNil; } @@ -98,7 +98,7 @@ class SetOrMapEntry final : public MapEntry, public SetEntry { //! The value or nil VN m_valueOrNil = {}; - //! Pointer to the next iterator or nullptr if none + //! Pointer to the next entry or nullptr if none const SetOrMapEntry* m_next = nullptr; }; diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index f43b3780dea..8b3eb462737 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -20,7 +20,7 @@ It represents an abstract base class for a map. |Name|Definition| |----|----------| -|`Entry`|Alias of [`MapEntry`](MapEntry.md)| +|`MapEntry`|Alias of [`MapEntry`](MapEntry.md)| ## 3. Private Constructors @@ -90,7 +90,7 @@ void copyDataFrom(const MapBase& map) 1. Let `size` be the minimum of `map.getSize()` and `getCapacity()`. - 1. Set `e = map.getHeadEntry()`. + 1. Set `e = map.getHeadMapEntry()`. 1. For `i` in [0, `size`) @@ -161,10 +161,10 @@ void f(const MapBase& map) { } ``` -### 6.5. getHeadEntry +### 6.5. getHeadMapEntry ```c++ -virtual const Entry* getHeadEntry() const = 0 +virtual const MapEntry* getHeadMapEntry() const = 0 ``` Get a pointer to the head iterator for the map, or `nullptr` if there is none. @@ -173,11 +173,11 @@ _Example:_ ```c++ void f(const MapBase& map) { map.clear(); - const auto* e = map.getHeadEntry(); + const auto* e = map.getHeadMapEntry(); ASSERT_EQ(e, nullptr); map.insert(0, 1); - e = map.getHeadEntry(); - ASSERT_EQ(e, nullptr); + e = map.getHeadMapEntry(); + ASSERT_NE(e, nullptr); ASSERT_EQ(e->getKey(), 0); ASSERT_EQ(e->getValue(), 1); } diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp index bebdd45c877..acd04a4c42e 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp @@ -53,13 +53,13 @@ struct FindExisting : public Rule { void action(State& state) { const auto size = state.impl.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); - const auto* it = state.impl.getHeadIterator(); + const auto* entry = state.impl.getHeadEntry(); for (FwSizeType i = 0; i < index; i++) { - ASSERT_NE(it, nullptr); - it = it->getNextIterator(); + ASSERT_NE(entry, nullptr); + entry = entry->getNextEntry(); } - ASSERT_NE(it, nullptr); - const auto key = it->getKey(); + ASSERT_NE(entry, nullptr); + const auto key = entry->getKey(); const auto expectedValue = state.modelMap[key]; State::ValueType value = 0; const auto status = state.impl.find(key, value); @@ -74,13 +74,13 @@ struct InsertExisting : public Rule { void action(State& state) { const auto size = state.impl.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); - const auto* it = state.impl.getHeadIterator(); + const auto* entry = state.impl.getHeadEntry(); for (FwSizeType i = 0; i < index; i++) { - ASSERT_NE(it, nullptr); - it = it->getNextIterator(); + ASSERT_NE(entry, nullptr); + entry = entry->getNextEntry(); } - ASSERT_NE(it, nullptr); - const auto key = it->getKey(); + ASSERT_NE(entry, nullptr); + const auto key = entry->getKey(); const auto value = state.getValue(); const auto status = state.impl.insert(key, value); ASSERT_EQ(status, Success::SUCCESS); @@ -146,13 +146,13 @@ struct RemoveExisting : public Rule { void action(State& state) { const auto size = state.impl.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); - const auto* it = state.impl.getHeadIterator(); + const auto* entry = state.impl.getHeadEntry(); for (FwSizeType i = 0; i < index; i++) { - ASSERT_NE(it, nullptr); - it = it->getNextIterator(); + ASSERT_NE(entry, nullptr); + entry = entry->getNextEntry(); } - ASSERT_NE(it, nullptr); - const auto key = it->getKey(); + ASSERT_NE(entry, nullptr); + const auto key = entry->getKey(); const auto expectedValue = state.modelMap[key]; State::ValueType value = 0; const auto status = state.impl.remove(key, value); diff --git a/Fw/DataStructures/test/ut/STest/MapTestRules.hpp b/Fw/DataStructures/test/ut/STest/MapTestRules.hpp index 27bd949aefb..e3cfc8fa928 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/MapTestRules.hpp @@ -53,13 +53,13 @@ struct FindExisting : public Rule { void action(State& state) { const auto size = state.map.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); - const auto* it = state.map.getHeadIterator(); + const auto* entry = state.map.getHeadMapEntry(); for (FwSizeType i = 0; i < index; i++) { - ASSERT_NE(it, nullptr); - it = it->getNextMapEntry(); + ASSERT_NE(entry, nullptr); + entry = entry->getNextMapEntry(); } - ASSERT_NE(it, nullptr); - const auto key = it->getKey(); + ASSERT_NE(entry, nullptr); + const auto key = entry->getKey(); const auto expectedValue = state.modelMap[key]; State::ValueType value = 0; const auto status = state.map.find(key, value); @@ -74,13 +74,13 @@ struct InsertExisting : public Rule { void action(State& state) { const auto size = state.map.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); - const auto* it = state.map.getHeadIterator(); + const auto* entry = state.map.getHeadMapEntry(); for (FwSizeType i = 0; i < index; i++) { - ASSERT_NE(it, nullptr); - it = it->getNextMapEntry(); + ASSERT_NE(entry, nullptr); + entry = entry->getNextMapEntry(); } - ASSERT_NE(it, nullptr); - const auto key = it->getKey(); + ASSERT_NE(entry, nullptr); + const auto key = entry->getKey(); const auto value = state.getValue(); const auto status = state.map.insert(key, value); ASSERT_EQ(status, Success::SUCCESS); @@ -147,13 +147,13 @@ struct RemoveExisting : public Rule { void action(State& state) { const auto size = state.map.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); - const auto* it = state.map.getHeadIterator(); + const auto* entry = state.map.getHeadMapEntry(); for (FwSizeType i = 0; i < index; i++) { - ASSERT_NE(it, nullptr); - it = it->getNextMapEntry(); + ASSERT_NE(entry, nullptr); + entry = entry->getNextMapEntry(); } - ASSERT_NE(it, nullptr); - const auto key = it->getKey(); + ASSERT_NE(entry, nullptr); + const auto key = entry->getKey(); const auto expectedValue = state.modelMap[key]; State::ValueType value = 0; const auto status = state.map.remove(key, value); diff --git a/Fw/DataStructures/test/ut/STest/MapTestState.hpp b/Fw/DataStructures/test/ut/STest/MapTestState.hpp index 688546529a5..e24efd01670 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/MapTestState.hpp @@ -25,8 +25,6 @@ struct State { static constexpr FwSizeType capacity = 1024; //! THe MapBase type using MapBase = MapBase; - //! The iterator type - using Iterator = MapEntry; //! Constructor State(MapBase& a_map) : map(a_map) {} //! The map under test diff --git a/Fw/DataStructures/test/ut/STest/SetTestRules.hpp b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp index 0ef46c86f8e..93386891a00 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp @@ -50,22 +50,22 @@ struct FindExisting : public Rule { ASSERT_EQ(size, modelSize); // Check that all elements of set are in modelSet { - const auto* it = state.set.getHeadIterator(); + const auto* entry = state.set.getHeadSetEntry(); for (FwSizeType i = 0; i < size; i++) { - ASSERT_NE(it, nullptr); - const auto e = it->getElement(); + ASSERT_NE(entry, nullptr); + const auto e = entry->getElement(); ASSERT_TRUE(state.modelSetContains(e)); - it = it->getNextSetEntry(); + entry = entry->getNextSetEntry(); } } // Check that all elements of modelSet are in set { - auto it = state.modelSet.begin(); + auto entry = state.modelSet.begin(); for (FwSizeType i = 0; i < modelSize; i++) { - ASSERT_NE(it, state.modelSet.end()); - const auto status = state.set.find(*it); + ASSERT_NE(entry, state.modelSet.end()); + const auto status = state.set.find(*entry); ASSERT_EQ(status, Success::SUCCESS); - it++; + entry++; } } } @@ -77,13 +77,13 @@ struct InsertExisting : public Rule { void action(State& state) { const auto size = state.set.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); - const auto* it = state.set.getHeadIterator(); + const auto* entry = state.set.getHeadSetEntry(); for (FwSizeType i = 0; i < index; i++) { - ASSERT_NE(it, nullptr); - it = it->getNextSetEntry(); + ASSERT_NE(entry, nullptr); + entry = entry->getNextSetEntry(); } - ASSERT_NE(it, nullptr); - const auto e = it->getElement(); + ASSERT_NE(entry, nullptr); + const auto e = entry->getElement(); const auto status = state.set.insert(e); ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(state.set.getSize(), size); @@ -143,13 +143,13 @@ struct RemoveExisting : public Rule { void action(State& state) { const auto size = state.set.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); - const auto* it = state.set.getHeadIterator(); + const auto* entry = state.set.getHeadSetEntry(); for (FwSizeType i = 0; i < index; i++) { - ASSERT_NE(it, nullptr); - it = it->getNextSetEntry(); + ASSERT_NE(entry, nullptr); + entry = entry->getNextSetEntry(); } - ASSERT_NE(it, nullptr); - const auto e = it->getElement(); + ASSERT_NE(entry, nullptr); + const auto e = entry->getElement(); const auto status = state.set.remove(e); ASSERT_EQ(status, Success::SUCCESS); const auto n = state.modelSet.erase(e); diff --git a/Fw/DataStructures/test/ut/STest/SetTestState.hpp b/Fw/DataStructures/test/ut/STest/SetTestState.hpp index c1d3a9a23bc..630ea10b2c8 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/SetTestState.hpp @@ -25,8 +25,6 @@ struct State { static constexpr FwSizeType capacity = 1024; //! THe SetBase type using SetBase = SetBase; - //! The iterator type - using Iterator = SetEntry; //! Constructor State(SetBase& a_set) : set(a_set) {} //! The set under test From 107b9a4cf1ec1d35f9aa7de4eddfb518e559daf7 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 13 Jul 2025 12:12:02 -0700 Subject: [PATCH 345/458] Revise data structures implementation Rename SetOrMapEntry to SetOrMapImplEntry --- Fw/DataStructures/ArrayMap.hpp | 2 +- Fw/DataStructures/ArraySet.hpp | 2 +- Fw/DataStructures/ArraySetOrMapImpl.hpp | 4 +-- Fw/DataStructures/ExternalArrayMap.hpp | 2 +- Fw/DataStructures/ExternalArraySet.hpp | 2 +- ...etOrMapEntry.hpp => SetOrMapImplEntry.hpp} | 34 +++++++++---------- Fw/DataStructures/test/ut/ArrayMapTest.cpp | 2 +- .../test/ut/ArraySetOrMapImplTester.hpp | 2 +- Fw/DataStructures/test/ut/ArraySetTest.cpp | 2 +- .../test/ut/ExternalArrayMapTest.cpp | 2 +- .../test/ut/ExternalArraySetTest.cpp | 2 +- .../ut/STest/ArraySetOrMapImplTestState.hpp | 2 +- 12 files changed, 29 insertions(+), 29 deletions(-) rename Fw/DataStructures/{SetOrMapEntry.hpp => SetOrMapImplEntry.hpp} (71%) diff --git a/Fw/DataStructures/ArrayMap.hpp b/Fw/DataStructures/ArrayMap.hpp index bc0fcaa434a..072f336404b 100644 --- a/Fw/DataStructures/ArrayMap.hpp +++ b/Fw/DataStructures/ArrayMap.hpp @@ -26,7 +26,7 @@ class ArrayMap final : public MapBase { // ---------------------------------------------------------------------- //! The type of an entry - using Entry = SetOrMapEntry; + using Entry = SetOrMapImplEntry; //! The type of a map entry using MapEntry = MapEntry; diff --git a/Fw/DataStructures/ArraySet.hpp b/Fw/DataStructures/ArraySet.hpp index dc36376f1a9..315b43e9ef4 100644 --- a/Fw/DataStructures/ArraySet.hpp +++ b/Fw/DataStructures/ArraySet.hpp @@ -26,7 +26,7 @@ class ArraySet final : public SetBase { // ---------------------------------------------------------------------- //! The type of a set entry - using Entry = SetOrMapEntry; + using Entry = SetOrMapImplEntry; //! The type of a set entry using SetEntry = SetEntry; diff --git a/Fw/DataStructures/ArraySetOrMapImpl.hpp b/Fw/DataStructures/ArraySetOrMapImpl.hpp index 6a805155026..4454acb83e8 100644 --- a/Fw/DataStructures/ArraySetOrMapImpl.hpp +++ b/Fw/DataStructures/ArraySetOrMapImpl.hpp @@ -8,7 +8,7 @@ #define Fw_ArraySetOrMapImpl_HPP #include "Fw/DataStructures/ExternalArray.hpp" -#include "Fw/DataStructures/SetOrMapEntry.hpp" +#include "Fw/DataStructures/SetOrMapImplEntry.hpp" #include "Fw/Types/Assert.hpp" #include "Fw/Types/SuccessEnumAc.hpp" @@ -29,7 +29,7 @@ class ArraySetOrMapImpl { // ---------------------------------------------------------------------- //! The type of an entry in the set or map - using Entry = SetOrMapEntry; + using Entry = SetOrMapImplEntry; public: // ---------------------------------------------------------------------- diff --git a/Fw/DataStructures/ExternalArrayMap.hpp b/Fw/DataStructures/ExternalArrayMap.hpp index 10a54035004..3ddf566d0a4 100644 --- a/Fw/DataStructures/ExternalArrayMap.hpp +++ b/Fw/DataStructures/ExternalArrayMap.hpp @@ -28,7 +28,7 @@ class ExternalArrayMap final : public MapBase { // ---------------------------------------------------------------------- //! The type of a map entry - using Entry = SetOrMapEntry; + using Entry = SetOrMapImplEntry; //! The type of a map entry using MapEntry = MapEntry; diff --git a/Fw/DataStructures/ExternalArraySet.hpp b/Fw/DataStructures/ExternalArraySet.hpp index 839ba542763..5384f390ef5 100644 --- a/Fw/DataStructures/ExternalArraySet.hpp +++ b/Fw/DataStructures/ExternalArraySet.hpp @@ -29,7 +29,7 @@ class ExternalArraySet final : public SetBase { // ---------------------------------------------------------------------- //! The type of a set entry - using Entry = SetOrMapEntry; + using Entry = SetOrMapImplEntry; //! The type of a set iterator using SetEntry = SetEntry; diff --git a/Fw/DataStructures/SetOrMapEntry.hpp b/Fw/DataStructures/SetOrMapImplEntry.hpp similarity index 71% rename from Fw/DataStructures/SetOrMapEntry.hpp rename to Fw/DataStructures/SetOrMapImplEntry.hpp index 2f2388595dd..dc3cc0caa5a 100644 --- a/Fw/DataStructures/SetOrMapEntry.hpp +++ b/Fw/DataStructures/SetOrMapImplEntry.hpp @@ -1,11 +1,11 @@ // ====================================================================== -// \title SetOrMapEntry +// \title SetOrMapImplEntry // \author bocchino -// \brief A class template representing an entry for a set or map +// \brief A class template representing an entry for a set or map implementation // ====================================================================== -#ifndef Fw_SetOrMapEntry_HPP -#define Fw_SetOrMapEntry_HPP +#ifndef Fw_SetOrMapImplEntry_HPP +#define Fw_SetOrMapImplEntry_HPP #include "Fw/DataStructures/MapEntry.hpp" #include "Fw/DataStructures/SetEntry.hpp" @@ -14,27 +14,27 @@ namespace Fw { template -class SetOrMapEntry final : public MapEntry, public SetEntry { +class SetOrMapImplEntry final : public MapEntry, public SetEntry { public: // ---------------------------------------------------------------------- // Public constructors and destructors // ---------------------------------------------------------------------- //! Zero-argument constructor - SetOrMapEntry() : MapEntry() {} + SetOrMapImplEntry() : MapEntry(), SetEntry() {} //! Constructor providing members - SetOrMapEntry(const KE& keyOrElement, //!< The key or element - const VN& valueOrNil, //!< The value or Nil - const SetOrMapEntry* next = nullptr //!< The next entry - ) - : m_keyOrElement(keyOrElement), m_valueOrNil(valueOrNil), m_next(next) {} + SetOrMapImplEntry(const KE& keyOrElement, //!< The key or element + const VN& valueOrNil, //!< The value or Nil + const SetOrMapImplEntry* next = nullptr //!< The next entry + ) + : MapEntry(), SetEntry(), m_keyOrElement(keyOrElement), m_valueOrNil(valueOrNil), m_next(next) {} //! Copy constructor - SetOrMapEntry(const SetOrMapEntry& entry) { *this = entry; } + SetOrMapImplEntry(const SetOrMapImplEntry& entry) { *this = entry; } //! Destructor - ~SetOrMapEntry() override = default; + ~SetOrMapImplEntry() override = default; public: // ---------------------------------------------------------------------- @@ -42,7 +42,7 @@ class SetOrMapEntry final : public MapEntry, public SetEntry { // ---------------------------------------------------------------------- //! operator= - SetOrMapEntry& operator=(const SetOrMapEntry& entry) { + SetOrMapImplEntry& operator=(const SetOrMapImplEntry& entry) { if (this != &entry) { this->m_keyOrElement = entry.m_keyOrElement; this->m_valueOrNil = entry.m_valueOrNil; @@ -65,7 +65,7 @@ class SetOrMapEntry final : public MapEntry, public SetEntry { //! Get the next entry //! \return The entry, or nullptr if none - const SetOrMapEntry* getNextEntry() const { return this->m_next; } + const SetOrMapImplEntry* getNextEntry() const { return this->m_next; } //! Get the next map entry //! \return The map entry, or nullptr if none @@ -82,7 +82,7 @@ class SetOrMapEntry final : public MapEntry, public SetEntry { } //! Set the next entry - void setNextEntry(const SetOrMapEntry* next) { this->m_next = next; } + void setNextEntry(const SetOrMapImplEntry* next) { this->m_next = next; } //! Set the value or Nil void setValueOrNil(const VN& valueOrNil) { this->m_valueOrNil = valueOrNil; } @@ -99,7 +99,7 @@ class SetOrMapEntry final : public MapEntry, public SetEntry { VN m_valueOrNil = {}; //! Pointer to the next entry or nullptr if none - const SetOrMapEntry* m_next = nullptr; + const SetOrMapImplEntry* m_next = nullptr; }; } // namespace Fw diff --git a/Fw/DataStructures/test/ut/ArrayMapTest.cpp b/Fw/DataStructures/test/ut/ArrayMapTest.cpp index e10a3971a22..e4514e3e1d2 100644 --- a/Fw/DataStructures/test/ut/ArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ArrayMapTest.cpp @@ -29,7 +29,7 @@ class ArrayMapTester { namespace MapTest { -using Entry = SetOrMapEntry; +using Entry = SetOrMapImplEntry; using Map = ArrayMap; using MapTester = ArrayMapTester; using ImplTester = ArraySetOrMapImplTester; diff --git a/Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp b/Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp index f725e227f3b..fd5b4726e47 100644 --- a/Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp +++ b/Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp @@ -17,7 +17,7 @@ namespace Fw { template class ArraySetOrMapImplTester { public: - using Entry = SetOrMapEntry; + using Entry = SetOrMapImplEntry; ArraySetOrMapImplTester(const ArraySetOrMapImpl& impl) : m_impl(impl) {} diff --git a/Fw/DataStructures/test/ut/ArraySetTest.cpp b/Fw/DataStructures/test/ut/ArraySetTest.cpp index 1af200ede14..d902f0fce9e 100644 --- a/Fw/DataStructures/test/ut/ArraySetTest.cpp +++ b/Fw/DataStructures/test/ut/ArraySetTest.cpp @@ -29,7 +29,7 @@ class ArraySetTester { namespace SetTest { -using Entry = SetOrMapEntry; +using Entry = SetOrMapImplEntry; using Set = ArraySet; using SetTester = ArraySetTester; using ImplTester = ArraySetOrMapImplTester; diff --git a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp index 9426ff07bb5..0d2112e4629 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp @@ -25,7 +25,7 @@ class ExternalArrayMapTester { namespace MapTest { -using Entry = SetOrMapEntry; +using Entry = SetOrMapImplEntry; using Map = ExternalArrayMap; using MapTester = ExternalArrayMapTester; using ImplTester = ArraySetOrMapImplTester; diff --git a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp index b2e0babddd7..d1c809c4117 100644 --- a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp @@ -27,7 +27,7 @@ class ExternalArraySetTester { namespace SetTest { -using Entry = SetOrMapEntry; +using Entry = SetOrMapImplEntry; using Set = ExternalArraySet; using SetTester = ExternalArraySetTester; using ImplTester = ArraySetOrMapImplTester; diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp index 4f9b3b53316..10131e3f9f7 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp @@ -29,7 +29,7 @@ struct State { //! The Tester type using Tester = ArraySetOrMapImplTester; //! The entry type - using Entry = SetOrMapEntry; + using Entry = SetOrMapImplEntry; //! Constructor State(Impl& a_impl) : impl(a_impl), tester(a_impl) {} //! The array set or map under test From cf1e35cfec84b95f492901b9aaf2b1bfa457cfb6 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 13 Jul 2025 12:24:15 -0700 Subject: [PATCH 346/458] Revise data structure implementation Rename Entry to ImplEntry --- Fw/DataStructures/ArrayMap.hpp | 10 +++++----- Fw/DataStructures/ArraySet.hpp | 10 +++++----- Fw/DataStructures/ExternalArrayMap.hpp | 16 ++++++++-------- Fw/DataStructures/ExternalArraySet.hpp | 4 ++-- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Fw/DataStructures/ArrayMap.hpp b/Fw/DataStructures/ArrayMap.hpp index 072f336404b..e9448035b21 100644 --- a/Fw/DataStructures/ArrayMap.hpp +++ b/Fw/DataStructures/ArrayMap.hpp @@ -25,14 +25,14 @@ class ArrayMap final : public MapBase { // Public types // ---------------------------------------------------------------------- - //! The type of an entry - using Entry = SetOrMapImplEntry; + //! The type of an implementation entry + using ImplEntry = SetOrMapImplEntry; //! The type of a map entry using MapEntry = MapEntry; - //! The type of the entries - using Entries = Entry[C]; + //! The type of the implementation entries + using ImplEntries = ImplEntry[C]; public: // ---------------------------------------------------------------------- @@ -107,7 +107,7 @@ class ArrayMap final : public MapBase { ExternalArrayMap m_extMap = {}; //! The array providing the backing memory for m_extMap - Entries m_entries = {}; + ImplEntries m_entries = {}; }; } // namespace Fw diff --git a/Fw/DataStructures/ArraySet.hpp b/Fw/DataStructures/ArraySet.hpp index 315b43e9ef4..4fcdf6c677f 100644 --- a/Fw/DataStructures/ArraySet.hpp +++ b/Fw/DataStructures/ArraySet.hpp @@ -25,14 +25,14 @@ class ArraySet final : public SetBase { // Public types // ---------------------------------------------------------------------- - //! The type of a set entry - using Entry = SetOrMapImplEntry; + //! The type of animplementation entry + using ImplEntry = SetOrMapImplEntry; //! The type of a set entry using SetEntry = SetEntry; - //! The type of the set entries - using Entries = Entry[C]; + //! The type of the implementation entries + using ImplEntries = ImplEntry[C]; public: // ---------------------------------------------------------------------- @@ -104,7 +104,7 @@ class ArraySet final : public SetBase { ExternalArraySet m_extSet = {}; //! The array providing the backing memory for m_extSet - Entries m_entries = {}; + ImplEntries m_entries = {}; }; } // namespace Fw diff --git a/Fw/DataStructures/ExternalArrayMap.hpp b/Fw/DataStructures/ExternalArrayMap.hpp index 3ddf566d0a4..297e0d08a37 100644 --- a/Fw/DataStructures/ExternalArrayMap.hpp +++ b/Fw/DataStructures/ExternalArrayMap.hpp @@ -27,8 +27,8 @@ class ExternalArrayMap final : public MapBase { // Public types // ---------------------------------------------------------------------- - //! The type of a map entry - using Entry = SetOrMapImplEntry; + //! The type of a map implementation entry + using ImplEntry = SetOrMapImplEntry; //! The type of a map entry using MapEntry = MapEntry; @@ -42,8 +42,8 @@ class ExternalArrayMap final : public MapBase { ExternalArrayMap() = default; //! Constructor providing typed backing storage. - //! entries must point to at least capacity elements of type Entry. - ExternalArrayMap(Entry* entries, //!< The entries + //! entries must point to at least capacity elements of type ImplEntry. + ExternalArrayMap(ImplEntry* entries, //!< The entries FwSizeType capacity //!< The capacity ) : MapBase() { @@ -106,7 +106,7 @@ class ExternalArrayMap final : public MapBase { //! \return SUCCESS if there is room in the map Success insert(const K& key, //!< The key const V& value //!< The value - ) override { + ) override { return this->m_impl.insert(key, value); } @@ -114,13 +114,13 @@ class ExternalArrayMap final : public MapBase { //! \return SUCCESS if the key was there Success remove(const K& key, //!< The key V& value //!< The value - ) override { + ) override { return this->m_impl.remove(key, value); } //! Set the backing storage (typed data) - //! entries must point to at least capacity elements of type Entry. - void setStorage(Entry* entries, //!< The entries + //! entries must point to at least capacity elements of type ImplEntry. + void setStorage(ImplEntry* entries, //!< The entries FwSizeType capacity //!< The capacity ) { this->m_impl.setStorage(entries, capacity); diff --git a/Fw/DataStructures/ExternalArraySet.hpp b/Fw/DataStructures/ExternalArraySet.hpp index 5384f390ef5..6cbb9827759 100644 --- a/Fw/DataStructures/ExternalArraySet.hpp +++ b/Fw/DataStructures/ExternalArraySet.hpp @@ -43,7 +43,7 @@ class ExternalArraySet final : public SetBase { ExternalArraySet() = default; //! Constructor providing typed backing storage. - //! entries must point to at least capacity elements of type Entry. + //! entries must point to at least capacity elements of type ImplEntry. ExternalArraySet(Entry* entries, //!< The entries FwSizeType capacity //!< The capacity ) @@ -119,7 +119,7 @@ class ExternalArraySet final : public SetBase { } //! Set the backing storage (typed data) - //! entries must point to at least capacity elements of type Entry. + //! entries must point to at least capacity elements of type ImplEntry. void setStorage(Entry* entries, //!< The entries FwSizeType capacity //!< The capacity ) { From 39ea851b3030c5548440cc40904bc3e7eb1e3904 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 13 Jul 2025 12:32:44 -0700 Subject: [PATCH 347/458] Revise data structures design Rename symbols to match implementation --- Fw/DataStructures/docs/ArrayMap.md | 9 +- Fw/DataStructures/docs/ArraySet.md | 24 ++-- Fw/DataStructures/docs/ArraySetOrMapImpl.md | 2 +- Fw/DataStructures/docs/ExternalArrayMap.md | 95 +++++++++------- Fw/DataStructures/docs/ExternalArraySet.md | 103 ++++++++++-------- Fw/DataStructures/docs/Nil.md | 2 +- Fw/DataStructures/docs/SetBase.md | 10 +- ...{SetOrMapEntry.md => SetOrMapImplEntry.md} | 30 ++--- 8 files changed, 151 insertions(+), 124 deletions(-) rename Fw/DataStructures/docs/{SetOrMapEntry.md => SetOrMapImplEntry.md} (72%) diff --git a/Fw/DataStructures/docs/ArrayMap.md b/Fw/DataStructures/docs/ArrayMap.md index 1c6dcdcad6c..4a674eba0e1 100644 --- a/Fw/DataStructures/docs/ArrayMap.md +++ b/Fw/DataStructures/docs/ArrayMap.md @@ -28,8 +28,9 @@ It represents an array-based map with internal storage. |Name|Definition| |----|----------| -|`Entry`|Alias of [`SetOrMapEntry`](SetOrMapEntry.md)| +|`ImplEntry`|Alias of [`SetOrMapImplEntry`](SetOrMapImplEntry.md)| |`MapEntry`|Alias of [`MapEntry`](MapEntry.md)| +|`ImplEntries`|Alias of `ImplEntry[C]`| ## 4. Private Member Variables @@ -38,9 +39,9 @@ It represents an array-based map with internal storage. |Name|Type|Purpose|Default Value| |----|----|-------|-------------| |`m_extMap`|[`ExternalArrayMap`](ExternalArrayMap.md)|The external map implementation|C++ default initialization| -|`m_entries`|`Entry[C]`|The array providing the backing memory for `m_extMap`|C++ default initialization| +|`m_entries`|`ImplEntries`|The array providing the backing memory for `m_extMap`|C++ default initialization| -The type `Entry` is defined [here](ArrayMap.md#Public-Types). +The type `ImplEntry` is defined [here](ArrayMap.md#Public-Types). ```mermaid classDiagram @@ -75,7 +76,7 @@ ArrayMap(const ArrayMap& map) _Example:_ ```c++ using Map = ArrayMap; -Map m1(entries, capacity); +Map m1; // Insert an item const U16 key = 0; const U32 value = 42; diff --git a/Fw/DataStructures/docs/ArraySet.md b/Fw/DataStructures/docs/ArraySet.md index f92b1efd43d..7a329bb631b 100644 --- a/Fw/DataStructures/docs/ArraySet.md +++ b/Fw/DataStructures/docs/ArraySet.md @@ -27,7 +27,7 @@ It represents an array-based set with internal storage. |Name|Definition| |----|----------| -|`Entry`|Alias of [`SetOrMapEntry`](SetOrMapEntry.md)| +|`Entry`|Alias of [`SetOrMapImplEntry`](SetOrMapImplEntry.md)| |`SetEntry`|Alias of [`SetEntry`](SetEntry.md)| The type `Nil` is defined [here](Nil.md). @@ -76,14 +76,14 @@ ArraySet(const ArraySet& set) _Example:_ ```c++ using Set = ArraySet; -Set m1; +Set s1; // Insert an item const U32 element = 42; -const auto status = m1.insert(element); +const auto status = s1.insert(element); ASSERT_EQ(status, Success::SUCCESS); // Call the copy constructor -Set m2; -ASSERT_EQ(m2.getSize(), 1); +Set s2; +ASSERT_EQ(s2.getSize(), 1); ``` ### 5.3. Destructor @@ -107,18 +107,18 @@ Return `m_extSet.copyDataFrom(set)`. _Example:_ ```c++ using Set = ArraySet; -Set m1; +Set s1; // Insert an item U32 element = 42; -const auto status = m1.insert(element, value); +const auto status = s1.insert(element, value); ASSERT_EQ(status, Success::SUCCESS); // Call the default constructor -Set m2; -ASSERT_EQ(m2.getSize(), 0); +Set s2; +ASSERT_EQ(s2.getSize(), 0); // Call the copy assignment operator -m2 = m1; -ASSERT_EQ(m2.getSize(), 1); -status = m2.find(element); +s2 = s1; +ASSERT_EQ(s2.getSize(), 1); +status = s2.find(element); ASSERT_EQ(status, Success::SUCCESS); ``` diff --git a/Fw/DataStructures/docs/ArraySetOrMapImpl.md b/Fw/DataStructures/docs/ArraySetOrMapImpl.md index 4a951641e94..5e71cc091dd 100644 --- a/Fw/DataStructures/docs/ArraySetOrMapImpl.md +++ b/Fw/DataStructures/docs/ArraySetOrMapImpl.md @@ -22,7 +22,7 @@ storing the entries in the set or map. |Name|Definition| |----|----------| -|`Entry`|Alias for [`SetOrMapEntry`](SetOrMapEntry.md)| +|`Entry`|Alias for [`SetOrMapImplEntry`](SetOrMapImplEntry.md)| ## 3. Private Member Variables diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index 83ad9b4f89f..d9095508d00 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -27,8 +27,8 @@ as the map implementation. |Name|Definition| |----|----------| -|`Entry`|Alias of [`SetOrMapEntry`](SetOrMapEntry.md)| -|`Entry`|Alias of [`MapEntry`](MapEntry.md)| +|`ImplEntry`|Alias of [`SetOrMapImplEntry`](SetOrMapImplEntry.md)| +|`MapEntry`|Alias of [`MapEntry`](MapEntry.md)| ## 4. Private Member Variables @@ -61,19 +61,20 @@ ExternalArrayMap map; ### 5.2. Constructor Providing Typed Backing Storage ```c++ -ExternalArrayMap(Entry* entries, FwSizeType capacity) +ExternalArrayMap(ImplEntry* entries, FwSizeType capacity) ``` `entries` must point to a primitive array of at least `capacity` -elements of type [`Entry`](ExternalArrayMap.md#Public-Types). +elements of type [`ImplEntry`](ExternalArrayMap.md#Public-Types). Call `setStorage(entries, capacity)`. _Example:_ ```c++ +using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -ExternalArrayMap::Entry entries[capacity]; -ExternalArrayMap map(entries, capacity); +Map::ImplEntry entries[capacity]; +Map map(entries, capacity); ``` ### 5.3. Constructor Providing Untyped Backing Storage @@ -90,11 +91,12 @@ Call `setStorage(data, capacity)`. _Example:_ ```c++ +using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -constexpr U8 alignment = ExternalArrayMap::getByteArrayAlignment(); -constexpr FwSizeType byteArraySize = ExternalArrayMap::getByteArraySize(capacity); +constexpr U8 alignment = Map::getByteArrayAlignment(); +constexpr FwSizeType byteArraySize = Map::getByteArraySize(capacity); alignas(alignment) U8 bytes[byteArraySize]; -ExternalArrayMap map(ByteArray(&bytes[0], sizeof bytes), capacity); +Map map(ByteArray(&bytes[0], sizeof bytes), capacity); ``` ### 5.4. Copy Constructor @@ -107,17 +109,18 @@ Set `*this = map`. _Example:_ ```c++ +using Map = ExternalArrayMap; constexpr FwSizeType capacity = 3; -ExternalArrayMap::Entry entries[capacity]; +Map::ImplEntry entries[capacity]; // Call the constructor providing backing storage -ExternalArrayMap m1(entries, capacity); +Map m1(entries, capacity); // Insert an item const U16 key = 0; const U32 value = 42; const auto status = m1.insert(key, value); ASSERT_EQ(status, Success::SUCCESS); // Call the copy constructor -ExternalArrayMap m2(m1); +Map m2(m1); ASSERT_EQ(m2.getSize(), 1); ``` @@ -145,10 +148,11 @@ ExternalArrayMap& operator=(const ExternalArrayMap& map) _Example:_ ```c++ +using Map = ExternalArrayMap; constexpr FwSizeType capacity = 3; -ExternalArrayMap::Entry entries[capacity]; +Map::ImplEntry entries[capacity]; // Call the constructor providing backing storage -ExternalArrayMap m1(entries, capacity); +Map m1(entries, capacity); // Insert an item U16 key = 0; U32 value = 42; @@ -176,9 +180,10 @@ Call `m_impl.clear()`. _Example:_ ```c++ +using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -ExternalArrayMap::Entry entries[capacity]; -ExternalArrayMap map(entries, capacity); +Map::ImplEntry entries[capacity]; +Map map(entries, capacity); const auto status = map.insert(0, 3); ASSERT_EQ(map.getSize(), 1); map.clear(); @@ -195,9 +200,10 @@ Return `m_impl.find(key, value)`. _Example:_ ```c++ +using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -ExternalArrayMap::Entry entries[capacity]; -ExternalArrayMap map(entries, capacity); +Map::ImplEntry entries[capacity]; +Map map(entries, capacity); U32 value = 0; auto status = map.find(0, value); ASSERT_EQ(status, Success::FAILURE); @@ -218,31 +224,33 @@ Return `m_impl.getCapacity()`. _Example:_ ```c++ +using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -ExternalArrayMap::Entry entries[capacity]; -ExternalArrayMap map(entries, capacity); +Map::ImplEntry entries[capacity]; +Map map(entries, capacity); ASSERT_EQ(map.getCapacity(), capacity); ``` -### 6.5. getHeadEntry +### 6.5. getHeadMapEntry ```c++ -const Entry* getHeadEntry const override +const MapEntry* getHeadMapEntry const override ``` -The type `Entry` is defined [here](ExternalArrayMap.md#Public-Types). +The type `MapEntry` is defined [here](ExternalArrayMap.md#Public-Types). Return `m_impl.getHeadEntry()`. _Example:_ ```c++ +using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -ExternalArrayMap::Entry entries[capacity]; -ExternalArrayMap map(entries, capacity); -const auto* e = map.getHeadEntry(); +Map::ImplEntry entries[capacity]; +Map map(entries, capacity); +const auto* e = map.getHeadMapEntry(); FW_ASSERT(e == nullptr); map.insert(0, 1); -e = map.getHeadEntry(); +e = map.getHeadMapEntry(); FW_ASSERT(e != nullptr); ASSERT_EQ(e->getKey(), 0); ASSERT_EQ(e->getValue(), 1); @@ -258,9 +266,10 @@ Return `m_impl.getSize()`. _Example:_ ```c++ +using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -ExternalArrayMap::Entry entries[capacity]; -ExternalArrayMap map(entries, capacity); +Map::ImplEntry entries[capacity]; +Map map(entries, capacity); auto size = map.getSize(); ASSERT_EQ(size, 0); const auto status = map.insert(0, 3); @@ -279,9 +288,10 @@ Return `m_impl.insert(key, value)`. _Example:_ ```c++ +using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -ExternalArrayMap::Entry entries[capacity]; -ExternalArrayMap map(entries, capacity); +Map::ImplEntry entries[capacity]; +Map map(entries, capacity); auto size = map.getSize(); ASSERT_EQ(size, 0); const auto status = map.insert(0, 1); @@ -300,9 +310,10 @@ Return `m_impl.remove(key, value)`. _Example:_ ```c++ +using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -ExternalArrayMap::Entry entries[capacity]; -ExternalArrayMap map(entries, capacity); +Map::ImplEntry entries[capacity]; +Map map(entries, capacity); auto size = map.getSize(); ASSERT_EQ(size, 0); auto status = map.insert(0, 1); @@ -324,20 +335,21 @@ ASSERT_EQ(value, 1); ### 6.9. setStorage (Typed Data) ```c++ -void setStorage(Entry* entries, FwSizeType capacity) +void setStorage(ImplEntry* entries, FwSizeType capacity) ``` `entries` must point to a primitive array of at least `capacity` -elements of type `Entry`. -The type `Entry` is defined [here](ExternalArrayMap.md#Public-Types). +elements of type `ImplEntry`. +The type `ImplEntry` is defined [here](ExternalArrayMap.md#Public-Types). Call `m_impl.setStorage(entries, capacity)`. _Example:_ ```c++ +using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -ExternalArrayMap map; -ExternalArrayMap::Entry entries[capacity]; +Map map; +Map::ImplEntry entries[capacity]; map.setStorage(entries, capacity); ``` @@ -356,11 +368,12 @@ contain at least [`getByteArraySize(size)`](#getByteArraySize) bytes. 1. Call `clear()`. ```c++ +using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -constexpr U8 alignment = ExternalArrayMap::getByteArrayAlignment(); -constexpr FwSizeType byteArraySize = ExternalArrayMap::getByteArraySize(capacity); +constexpr U8 alignment = Map::getByteArrayAlignment(); +constexpr FwSizeType byteArraySize = Map::getByteArraySize(capacity); alignas(alignment) U8 bytes[byteArraySize]; -ExternalArrayMap map; +Map map; map.setStorage(ByteArray(&bytes[0], sizeof bytes), capacity); ``` diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md index 9c64b554d36..88899f4d463 100644 --- a/Fw/DataStructures/docs/ExternalArraySet.md +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -26,8 +26,8 @@ as the set implementation. |Name|Definition| |----|----------| -|`Entry`|Alias of [`SetOrMapEntry`](SetOrMapEntry.md)| -|`Entry`|Alias of [`SetEntry`](SetEntry.md)| +|`ImplEntry`|Alias of [`SetOrMapImplEntry`](SetOrMapImplEntry.md)| +|`SetEntry`|Alias of [`SetEntry`](SetEntry.md)| The type `Nil` is defined [here](Nil.md). @@ -64,20 +64,21 @@ ExternalArraySet set; ### 5.2. Constructor Providing Typed Backing Storage ```c++ -ExternalArraySet(Entry* entries, FwSizeType capacity) +ExternalArraySet(ImplEntry* entries, FwSizeType capacity) ``` `entries` must point to a primitive array of at least `capacity` -elements of type `Entry`. -The type `Entry` is defined [here](ExternalArraySet.md#Public-Types). +elements of type `ImplEntry`. +The type `ImplEntry` is defined [here](ExternalArraySet.md#Public-Types). Call `setStorage(entries, capacity)`. _Example:_ ```c++ +using Set = ExternalArraySet; constexpr FwSizeType capacity = 10; -ExternalArraySet::Entry entries[capacity]; -ExternalArraySet set(entries, capacity); +Set::ImplEntry entries[capacity]; +Set set(entries, capacity); ``` ### 5.3. Constructor Providing Untyped Backing Storage @@ -94,9 +95,10 @@ Call `setStorage(data, capacity)`. _Example:_ ```c++ +using Set = ExternalArraySet; constexpr FwSizeType capacity = 10; -constexpr U8 alignment = ExternalArraySet::getByteArrayAlignment(); -constexpr FwSizeType byteArraySize = ExternalArraySet::getByteArraySize(capacity); +constexpr U8 alignment = Set::getByteArrayAlignment(); +constexpr FwSizeType byteArraySize = Set::getByteArraySize(capacity); alignas(alignment) U8 bytes[byteArraySize]; ExternalArraySet set(ByteArray(&bytes[0], sizeof bytes), capacity); ``` @@ -111,15 +113,16 @@ Set `*this = set`. _Example:_ ```c++ +using Set = ExternalArraySet; constexpr FwSizeType capacity = 3; -ExternalArraySet::Entry entries[capacity]; +Set::ImplEntry entries[capacity]; // Call the constructor providing backing storage -ExternalArraySet m1(entries, capacity); +Set m1(entries, capacity); // Insert an item const auto status = m1.insert(42); ASSERT_EQ(status, Success::SUCCESS); // Call the copy constructor -ExternalArraySet m2(m1); +Set m2(m1); ASSERT_EQ(m2.getSize(), 1); ``` @@ -147,15 +150,16 @@ ExternalArraySet& operator=(const ExternalArraySet& set) _Example:_ ```c++ +using Set = ExternalArraySet; constexpr FwSizeType capacity = 3; -ExternalArraySet::Entry entries[capacity]; +Set::ImplEntry entries[capacity]; // Call the constructor providing backing storage -ExternalArraySet m1(entries, capacity); +Set m1(entries, capacity); // Insert an item const auto status = m1.insert(42); ASSERT_EQ(status, Success::SUCCESS); // Call the default constructor -ExternalArraySet m2; +Set m2; ASSERT_EQ(m2.getSize(), 0); // Call the copy assignment operator m2 = m1; @@ -172,9 +176,10 @@ Call `m_impl.clear()`. _Example:_ ```c++ +using Set = ExternalArraySet; constexpr FwSizeType capacity = 10; -ExternalArraySet::Entry entries[capacity]; -ExternalArraySet set(entries, capacity); +Set::ImplEntry entries[capacity]; +Set set(entries, capacity); const auto status = set.insert(42); ASSERT_EQ(set.getSize(), 1); set.clear(); @@ -193,9 +198,10 @@ Success find(const T& element) override _Example:_ ```c++ +using Set = ExternalArraySet; constexpr FwSizeType capacity = 10; -ExternalArraySet::Entry entries[capacity]; -ExternalArraySet set(entries, capacity); +Set::ImplEntry entries[capacity]; +Set set(entries, capacity); auto status = set.find(42); ASSERT_EQ(status, Success::FAILURE); status = set.insert(42); @@ -214,31 +220,33 @@ Return `m_impl.getCapacity()`. _Example:_ ```c++ +using Set = ExternalArraySet; constexpr FwSizeType capacity = 10; -ExternalArraySet::Entry entries[capacity]; -ExternalArraySet set(entries, capacity); +Set::ImplEntry entries[capacity]; +Set set(entries, capacity); ASSERT_EQ(set.getCapacity(), capacity); ``` -### 6.5. getHeadEntry +### 6.5. getHeadSetEntry ```c++ -const Entry* getHeadEntry const override +const SetEntry* getHeadSetEntry const override ``` -The type `Entry` is defined [here](ExternalArraySet.md#Public-Types). +The type `SetEntry` is defined [here](ExternalArraySet.md#Public-Types). -Return `m_impl.getHeadEntry()`. +Return `m_impl.getHeadSetEntry()`. _Example:_ ```c++ +using Set = ExternalArraySet; constexpr FwSizeType capacity = 10; -ExternalArraySet::Entry entries[capacity]; -ExternalArraySet set(entries, capacity); -const auto* e = set.getHeadEntry(); +Set::ImplEntry entries[capacity]; +Set set(entries, capacity); +const auto* e = set.getHeadSetEntry(); FW_ASSERT(e == nullptr); set.insert(42); -e = set.getHeadEntry(); +e = set.getHeadSetEntry(); FW_ASSERT(e != nullptr); ASSERT_EQ(e->getElement(), 42); ``` @@ -253,9 +261,10 @@ Return `m_impl.getSize()`. _Example:_ ```c++ +using Set = ExternalArraySet; constexpr FwSizeType capacity = 10; -ExternalArraySet::Entry entries[capacity]; -ExternalArraySet set(entries, capacity); +Set::ImplEntry entries[capacity]; +Set set(entries, capacity); auto size = set.getSize(); ASSERT_EQ(size, 0); const auto status = set.insert(42); @@ -274,9 +283,10 @@ Return `m_impl.insert(key, Nil())`. _Example:_ ```c++ +using Set = ExternalArraySet; constexpr FwSizeType capacity = 10; -ExternalArraySet::Entry entries[capacity]; -ExternalArraySet set(entries, capacity); +Set::ImplEntry entries[capacity]; +Set set(entries, capacity); auto size = set.getSize(); ASSERT_EQ(size, 0); const auto status = set.insert(42); @@ -297,9 +307,10 @@ Success remove(const T& element) override _Example:_ ```c++ +using Set = ExternalArraySet; constexpr FwSizeType capacity = 10; -ExternalArraySet::Entry entries[capacity]; -ExternalArraySet set(entries, capacity); +Set::ImplEntry entries[capacity]; +Set set(entries, capacity); auto size = set.getSize(); ASSERT_EQ(size, 0); auto status = set.insert(42); @@ -319,20 +330,21 @@ ASSERT_EQ(size, 0); ### 6.9. setStorage (Typed Data) ```c++ -void setStorage(Entry* entries, FwSizeType capacity) +void setStorage(ImplEntry* entries, FwSizeType capacity) ``` `entries` must point to a primitive array of at least `capacity` -elements of type `Entry`. -The type `Entry` is defined [here](ExternalArraySet.md#Public-Types). +elements of type `ImplEntry`. +The type `ImplEntry` is defined [here](ExternalArraySet.md#Public-Types). Call `m_impl.setStorage(entries, capacity)`. _Example:_ ```c++ +using Set = ExternalArraySet; constexpr FwSizeType capacity = 10; -ExternalArraySet set; -ExternalArraySet::Entry entries[capacity]; +Set set; +Set::ImplEntry entries[capacity]; set.setStorage(entries, capacity); ``` @@ -351,11 +363,12 @@ contain at least [`getByteArraySize(size)`](#getByteArraySize) bytes. 1. Call `clear()`. ```c++ +using Set = ExternalArraySet; constexpr FwSizeType capacity = 10; -constexpr U8 alignment = ExternalArraySet::getByteArrayAlignment(); -constexpr FwSizeType byteArraySize = ExternalArraySet::getByteArraySize(capacity); +constexpr U8 alignment = Set::getByteArrayAlignment(); +constexpr FwSizeType byteArraySize = Set::getByteArraySize(capacity); alignas(alignment) U8 bytes[byteArraySize]; -ExternalArraySet set; +Set set; set.setStorage(ByteArray(&bytes[0], sizeof bytes), capacity); ``` @@ -368,7 +381,7 @@ set.setStorage(ByteArray(&bytes[0], sizeof bytes), capacity); static constexpr U8 getByteArrayAlignment() ``` -Return `ArraySetOrMapImpl::getByteArrayAlignment()`. +Return `ArraySetOrMapImpl::getByteArrayAlignment()`. ### 7.2. getByteArraySize @@ -377,4 +390,4 @@ Return `ArraySetOrMapImpl::getByteArrayAlignment()`. static constexpr FwSizeType getByteArraySize(FwSizeType capacity) ``` -Return `ArraySetOrMapImpl::getByteArraySize(capacity)`. +Return `ArraySetOrMapImpl::getByteArraySize(capacity)`. diff --git a/Fw/DataStructures/docs/Nil.md b/Fw/DataStructures/docs/Nil.md index 6f804858d4f..1600881b9ed 100644 --- a/Fw/DataStructures/docs/Nil.md +++ b/Fw/DataStructures/docs/Nil.md @@ -2,5 +2,5 @@ `Nil` is an empty type. It is a placeholder that is used as the value type -when a [`SetOrMapEntry`](SetOrMapEntry.md) +when a [`SetOrMapImplEntry`](SetOrMapImplEntry.md) is used as a set iterator. diff --git a/Fw/DataStructures/docs/SetBase.md b/Fw/DataStructures/docs/SetBase.md index 6b0e3f6b47e..d36168bfa7c 100644 --- a/Fw/DataStructures/docs/SetBase.md +++ b/Fw/DataStructures/docs/SetBase.md @@ -89,7 +89,7 @@ void copyDataFrom(const SetBase& set) 1. Let `size` be the minimum of `set.getSize()` and `getCapacity()`. - 1. Set `e = set.getHeadEntry()`. + 1. Set `e = set.getHeadSetEntry()`. 1. For `i` in [0, `size`) @@ -159,10 +159,10 @@ void f(const SetBase& set) { } ``` -### 6.5. getHeadEntry +### 6.5. getHeadSetEntry ```c++ -virtual const Entry* getHeadEntry const = 0 +virtual const Entry* getHeadSetEntry const = 0 ``` Get a pointer to the head iterator for the set, or `nullptr` if there is none. @@ -171,10 +171,10 @@ _Example:_ ```c++ void f(const SetBase& set) { set.clear(); - const auto* e = set.getHeadEntry(); + const auto* e = set.getHeadSetEntry(); ASSERT_EQ(e, nullptr); set.insert(42); - e = set.getHeadEntry(); + e = set.getHeadSetEntry(); ASSERT_NE(e, nullptr); ASSERT_EQ(e->getElement(), 42); } diff --git a/Fw/DataStructures/docs/SetOrMapEntry.md b/Fw/DataStructures/docs/SetOrMapImplEntry.md similarity index 72% rename from Fw/DataStructures/docs/SetOrMapEntry.md rename to Fw/DataStructures/docs/SetOrMapImplEntry.md index e7db0517c3b..5def76c5fef 100644 --- a/Fw/DataStructures/docs/SetOrMapEntry.md +++ b/Fw/DataStructures/docs/SetOrMapImplEntry.md @@ -1,12 +1,12 @@ -# SetOrMapEntry +# SetOrMapImplEntry -`SetOrMapEntry` is a final class template +`SetOrMapImplEntry` is a final class template defined in [`Fw/DataStructures`](sdd.md). It represents an iterator for a set or a map. ## 1. Template Parameters -`SetOrMapEntry` has the following template parameters. +`SetOrMapImplEntry` has the following template parameters. |Kind|Name|Purpose| |----|----|-------| @@ -15,7 +15,7 @@ It represents an iterator for a set or a map. ## 2. Base Class -`SetOrMapEntry` is publicly derived from the following +`SetOrMapImplEntry` is publicly derived from the following templates: 1. [`MapEntry`](MapEntry.md). @@ -24,26 +24,26 @@ templates: ```mermaid classDiagram - MapEntry <|-- SetOrMapEntry - SetEntry <|-- SetOrMapEntry + MapEntry <|-- SetOrMapImplEntry + SetEntry <|-- SetOrMapImplEntry ``` ## 3. Private Member Variables -`SetOrMapEntry` has the following private member variables. +`SetOrMapImplEntry` has the following private member variables. |Name|Type|Purpose|Default Value| |----|----|-------|-------------| |`m_keyOrElement`|`KE`|The map key or set element|C++ default initialization| |`m_valueOrNil`|`VN`|The value or [`Nil`](Nil.md)|C++ default initialization| -|`m_next`|`const SetOrMapEntry*`|Pointer to the next iterator or `nullptr` if none|`nullptr`| +|`m_next`|`const SetOrMapImplEntry*`|Pointer to the next iterator or `nullptr` if none|`nullptr`| ## 4. Public Constructors and Destructors ### 4.1. Zero-Argument Constructor ```c++ -SetOrMapEntry() +SetOrMapImplEntry() ``` Use default initialization of members. @@ -51,7 +51,7 @@ Use default initialization of members. ### 4.2. Constructor Providing Members ```c++ -SetOrMapEntry(const KE& keyOrElement, const VN& valueOrNil, const SetOrMapEntry* next = nullptr) +SetOrMapImplEntry(const KE& keyOrElement, const VN& valueOrNil, const SetOrMapImplEntry* next = nullptr) ``` 1. Set `m_keyOrElement = keyOrElement`. @@ -63,7 +63,7 @@ SetOrMapEntry(const KE& keyOrElement, const VN& valueOrNil, const SetOrMapEntry< ### 4.3. Copy Constructor ```c++ -SetOrMapEntry(const SetOrMapEntry& iterator) +SetOrMapImplEntry(const SetOrMapImplEntry& iterator) ``` Set `*this = iterator`. @@ -71,7 +71,7 @@ Set `*this = iterator`. ### 4.4. Destructor ```c++ -~SetOrMapEntry() override +~SetOrMapImplEntry() override ``` Defined as `= default`. @@ -81,7 +81,7 @@ Defined as `= default`. ### 5.1. operator= ```c++ -SetOrMapEntry& operator=(const SetOrMapEntry& iterator) +SetOrMapImplEntry& operator=(const SetOrMapImplEntry& iterator) ``` 1. If `this != &iterator` @@ -119,7 +119,7 @@ Return a reference to `m_valueOrNil`. ### 5.4. getNextEntry ```c++ -SetOrMapEntry* getNextEntry() +SetOrMapImplEntry* getNextEntry() ``` Return `m_next`. @@ -151,7 +151,7 @@ Set `m_keyOrElement = keyOrElement`. ### 5.8. setNextEntry ```c++ -void setNextEntry(const SetOrMapEntry* next) +void setNextEntry(const SetOrMapImplEntry* next) ``` Set `m_next = next`. From 6acbd8246f680249dfdd4175c445ff783e2c2c29 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 13 Jul 2025 14:56:53 -0700 Subject: [PATCH 348/458] Revise design for data structures Add ConstIterator to Map --- Fw/DataStructures/docs/ArrayMap.md | 30 +++- Fw/DataStructures/docs/ArraySetOrMapImpl.md | 155 +++++++++++++++++-- Fw/DataStructures/docs/ExternalArrayMap.md | 34 +++-- Fw/DataStructures/docs/MapBase.md | 157 ++++++++++++++++++-- 4 files changed, 339 insertions(+), 37 deletions(-) diff --git a/Fw/DataStructures/docs/ArrayMap.md b/Fw/DataStructures/docs/ArrayMap.md index 4a674eba0e1..56d219e5108 100644 --- a/Fw/DataStructures/docs/ArrayMap.md +++ b/Fw/DataStructures/docs/ArrayMap.md @@ -126,7 +126,15 @@ ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(value, 42); ``` -### 6.2. clear +### 6.2. begin + +```c++ +ConstIterator begin() const +``` + +Return `m_extMap.begin()`. + +### 6.3. clear ```c++ void clear() override @@ -134,7 +142,15 @@ void clear() override Call `m_extMap.clear()`. -### 6.3. find +### 6.4. end + +```c++ +ConstIterator end() const +``` + +Return `m_extMap.end()`. + +### 6.5. find ```c++ Success find(const K& key, V& value) override @@ -142,7 +158,7 @@ Success find(const K& key, V& value) override Return `m_extMap.find(key, value)`. -### 6.4. getCapacity +### 6.6. getCapacity ```c++ FwSizeType getCapacity() const override @@ -150,7 +166,7 @@ FwSizeType getCapacity() const override Return `m_extMap.getCapacity()`. -### 6.5. getHeadMapEntry +### 6.7. getHeadMapEntry ```c++ const MapEntry* getHeadMapEntry const override @@ -160,7 +176,7 @@ The type `MapEntry` is defined [here](ArrayMap.md#Public-Types). Return `m_extMap.getHeadMapEntry()`. -### 6.6. getSize +### 6.8. getSize ```c++ FwSizeType getSize() const override @@ -168,7 +184,7 @@ FwSizeType getSize() const override Return `m_extMap.getSize()`. -### 6.7. insert +### 6.9. insert ```c++ Success insert(const K& key, const V& value) override @@ -176,7 +192,7 @@ Success insert(const K& key, const V& value) override Return `m_extMap.insert(key, value)`. -### 6.8. remove +### 6.10. remove ```c++ Success remove(const K& key, V& value) override diff --git a/Fw/DataStructures/docs/ArraySetOrMapImpl.md b/Fw/DataStructures/docs/ArraySetOrMapImpl.md index 5e71cc091dd..47bb601e26d 100644 --- a/Fw/DataStructures/docs/ArraySetOrMapImpl.md +++ b/Fw/DataStructures/docs/ArraySetOrMapImpl.md @@ -18,12 +18,122 @@ storing the entries in the set or map. ## 2. Public Types -`ArraySetOrMapImpl` defines the following types: + +### 2.1. Type Aliases + +`ArraySetOrMapImpl` defines the following type aliases: |Name|Definition| |----|----------| |`Entry`|Alias for [`SetOrMapImplEntry`](SetOrMapImplEntry.md)| +### 2.2. ConstIterator + +`ConstIterator` is a public inner class of `ArraySetOrMapImpl`. +It provides non-modifying iteration over the elements of an `ArraySetOrMapImpl` +instance. + +#### 2.2.1. Private Member Variables + +`ConstIterator` has the following private member variables. + +|Name|Type|Purpose|Default Value| +|----|----|-------|-------------| +|`m_impl`|[`const ArraySetOrMapImpl&`]|The implementation over which to iterate|None (must be set by the constructor)| +|`m_index`|`FwSizeType`|The current iteration index|0| + +#### 2.2.2. Public Constructors and Destructors + +##### 2.2.2.1. Constructor Providing the Implementation + +```c++ +ConstIterator(const ArraySetOrMapImpl& impl) +``` + +1. Set `m_impl = impl`. + +1. Call `reset()`. + +##### 2.2.2.2. Copy Constructor + +```c++ +ConstIterator(const ConstIterator& it) +``` + +Defined as `= delete`. + +##### 2.2.2.3. Destructor + +```c++ +~ConstIterator() +``` + +Defined as `= default`. + +#### 2.2.3. Public Member Functions + +##### 2.2.3.1. operator= + +```c++ +ConstIterator& operator=(const ConstIterator& it) +``` + +Defined as `= delete`. + +##### 2.2.3.2. operator== + +```c++ +bool operator==(const ConstIterator& it) +``` + +1. Set `result = false`. + +1. If `&this->m_impl == &it.m_impl` + + 1. If `this->m_index == it.m_index` then set `result = true`. + + 1. Otherwise `!this->isInRange()` and `!it.isInRange()` then set `result = true`. + +1. Return `result`. + +##### 2.2.3.3. operator++ + +```c++ +ConstIterator& operator++() +``` + +1. If `m_index < m_size` then increment `m_index`. + +1. Return `*this`. + +##### 2.2.3.4. getKeyOrElement + +```c++ +const KE& getKeyOrElement() const +``` + +1. Assert `m_index < m_size`. + +1. Return `m_entries[index].getKeyOrElement()`. + +##### 2.2.3.5. getValueOrNil + +```c++ +const KE& getValueOrNil() const +``` + +1. Assert `m_index < m_size`. + +1. Return `m_entries[index].getValueOrNil()`. + +##### 2.2.3.6. reset + +```c++ +void reset() +``` + +Set `m_index = 0`. + ## 3. Private Member Variables `ArraySetOrMapImpl` has the following private member variables. @@ -63,7 +173,7 @@ Call `setStorage(entries, capacity)`. ArraySetOrMapImpl(ByteArray data, FwSizeType capacity) ``` -`data` must be aligned according to +`data` must be aligned according to [`getByteArrayAlignment()`](#61-getbytearrayalignment) and must contain at least [`getByteArraySize(size)`](#62-getbytearraysize) bytes. @@ -101,7 +211,15 @@ ArraySetOrMapImpl& operator=(const ArraySetOrMapImpl& impl) 1. Return `*this`. -### 5.2. clear +### 5.2. begin + +```c++ +ConstIterator begin() const +``` + +1. Return `ConstIterator(*this)`. + +### 5.3. clear ```c++ void clear() @@ -109,7 +227,20 @@ void clear() Set `m_size = 0`. -### 5.3. find +### 5.4. end + +```c++ +ConstIterator end() const +``` + +1. Set `it = ConstIterator(*this)`. + +1. Set `it.m_index = m_size`. + +1. Return `it`. + + +### 5.5. find ```c++ Success find(const KE& keyOrElement, VN& valueOrNil) @@ -131,7 +262,7 @@ Success find(const KE& keyOrElement, VN& valueOrNil) 1. Return `status`. -### 5.4. getCapacity +### 5.6. getCapacity ```c++ FwSizeType getCapacity() const @@ -139,7 +270,7 @@ FwSizeType getCapacity() const Return `m_entries.getSize()`. -### 5.5. getHeadEntry +### 5.7. getHeadEntry ```c++ const Entry* getHeadEntry() const @@ -153,7 +284,7 @@ const Entry* getHeadEntry() const 1. Return `result`. -### 5.6. getSize +### 5.8. getSize ```c++ FwSizeType getSize() @@ -161,7 +292,7 @@ FwSizeType getSize() Return `m_size`. -### 5.7. insert +### 5.9. insert ```c++ Success insert(const KE& keyOrElement, const VN& valueOrNil) @@ -194,7 +325,7 @@ Success insert(const KE& keyOrElement, const VN& valueOrNil) 1. Return `status`. -### 5.8. remove +### 5.10. remove ```c++ Success remove(const KE& keyOrElement, VN& valueOrNil) @@ -224,7 +355,7 @@ Success remove(const KE& keyOrElement, VN& valueOrNil) 1. Return `status`. -### 5.9. setStorage (Typed Data) +### 5.11. setStorage (Typed Data) ```c++ void setStorage(Entry* entries, FwSizeType capacity) @@ -234,13 +365,13 @@ void setStorage(Entry* entries, FwSizeType capacity) 1. Call `clear()`. -### 5.10. setStorage (Untyped Data) +### 5.12. setStorage (Untyped Data) ```c++ void setStorage(ByteArray data, FwSizeType capacity) ``` -`data` must be aligned according to +`data` must be aligned according to [`getByteArrayAlignment()`](#61-getbytearrayalignment) and must contain at least [`getByteArraySize(size)`](#62-getbytearraysize) bytes. diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index d9095508d00..15fa4684c77 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -170,7 +170,15 @@ ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(value, 42); ``` -### 6.2. clear +### 6.2. begin + +```c++ +ConstIterator begin() const +``` + +Return `m_impl.begin()`. + +### 6.3. clear ```c++ void clear() override @@ -190,7 +198,15 @@ map.clear(); ASSERT_EQ(map.getSize(), 0); ``` -### 6.3. find +### 6.4. end + +```c++ +ConstIterator end() const +``` + +Return `m_impl.end()`. + +### 6.5. find ```c++ Success find(const K& key, V& value) override @@ -214,7 +230,7 @@ ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(value, 1); ``` -### 6.4. getCapacity +### 6.6. getCapacity ```c++ FwSizeType getCapacity() const override @@ -231,7 +247,7 @@ Map map(entries, capacity); ASSERT_EQ(map.getCapacity(), capacity); ``` -### 6.5. getHeadMapEntry +### 6.7. getHeadMapEntry ```c++ const MapEntry* getHeadMapEntry const override @@ -256,7 +272,7 @@ ASSERT_EQ(e->getKey(), 0); ASSERT_EQ(e->getValue(), 1); ``` -### 6.6. getSize +### 6.8. getSize ```c++ FwSizeType getSize() const override @@ -278,7 +294,7 @@ size = map.getSize(); ASSERT_EQ(size, 1); ``` -### 6.7. insert +### 6.9. insert ```c++ Success insert(const K& key, const V& value) override @@ -300,7 +316,7 @@ size = map.getSize(); ASSERT_EQ(size, 1); ``` -### 6.8. remove +### 6.10. remove ```c++ Success remove(const K& key, V& value) override @@ -332,7 +348,7 @@ ASSERT_EQ(size, 0); ASSERT_EQ(value, 1); ``` -### 6.9. setStorage (Typed Data) +### 6.11. setStorage (Typed Data) ```c++ void setStorage(ImplEntry* entries, FwSizeType capacity) @@ -353,7 +369,7 @@ Map::ImplEntry entries[capacity]; map.setStorage(entries, capacity); ``` -### 6.10. setStorage (Untyped Data) +### 6.12. setStorage (Untyped Data) ```c++ void setStorage(ByteArray data, FwSizeType capacity) diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index 8b3eb462737..07e17583fe2 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -16,12 +16,135 @@ It represents an abstract base class for a map. ## 2. Public Types -`MapBase` defines the following public types: + +### 2.1. Type Aliases + +`MapBase` defines the following public type aliases. |Name|Definition| |----|----------| |`MapEntry`|Alias of [`MapEntry`](MapEntry.md)| +### 2.2. ConstIterator + +`ConstIterator` is a public inner class of `MapBase`. It provides +non-modifying iteration over the elements of a `MapBase` instance. + +#### 2.2.1. Private Enumerations + +`ConstIterator` defines the following private enumerations. + +|Name|Definition| +|----|----------| +|ImplKind|An enumeration with values `ARRAY` and `RED_BLACK_TREE`| + +#### 2.2.2. Private Type Aliases + +`ConstIterator` defines the following private type aliases. + +|Name|Definition| +|----|----------| +|ImplIterator|A union with member variables `array` of type `ArraySetOrMapImpl::ConstIterator` and `redBlackTree` of type `RedBlackTreeSetOrMapImpl::ConstIterator`| + +#### 2.2.3. Private Member Variables + +`ConstIterator` has the following private member variables. + +|Name|Type|Purpose|Default Value| +|----|----|-------|-------------| +|`m_implKind`|`ImplKind`|The implementation kind|None (must be set by the constructor)| +|`m_impl`|`ImplIterator`|The iterator for the implementation|C++ default initialization| + +#### 2.2.4. Public Constructors and Destructors + +##### 2.2.4.1. Constructor Providing an Array Implementation + +```c++ +ConstIterator(const ArraySetOrMapImpl::ConstIterator& it) +``` + +1. Set `m_implKind = ARRAY`. + +1. Set `m_implIterator.array = it; + +##### 2.2.4.2. Constructor Providing a Red-Black Tree Implementation + +```c++ +ConstIterator(const RedBlackTreeSetOrMapImpl::ConstIterator& it) +``` + +1. Set `m_implKind = RED_BLACK_TREE`. + +1. Set `m_implIterator.array = it; + +##### 2.2.4.3. Copy Constructor + +```c++ +ConstIterator(const ConstIterator& it) +``` + +Defined as `= delete`. + +##### 2.2.4.4. Destructor + +```c++ +~ConstIterator() +``` + +Defined as `= default`. + +#### 2.2.5. Public Member Functions + +##### 2.2.5.1. operator= + +```c++ +ConstIterator& operator=(const ConstIterator& it) +``` + +Defined as `= delete`. + +##### 2.2.5.2. operator== + +```c++ +bool operator==(const ConstIterator& it) +``` + +1. If the implementations don't match, then return `false`. + +1. Otherwise delegate to the implementations. + +##### 2.2.5.3. operator++ + +```c++ +ConstIterator& operator++() +``` + +Delegated to the implementation. + +##### 2.2.5.4. getKeyOrElement + +```c++ +const KE& getKeyOrElement() const +``` + +Delegated to the implementation. + +##### 2.2.5.5. getValueOrNil + +```c++ +const KE& getValueOrNil() const +``` + +Delegated to the implementation. + +##### 2.2.5.6. reset + +```c++ +void reset() +``` + +Delegated to the implementation. + ## 3. Private Constructors ### 3.1. Copy Constructor @@ -62,7 +185,15 @@ Defined as `= delete`. ## 6. Public Member Functions -### 6.1. clear +### 6.1. begin + +```c++ +ConstIterator begin() const = 0. +``` + +Return the iterator for the implementation. + +### 6.2. clear ```c++ virtual void clear() = 0 @@ -78,7 +209,7 @@ void f(MapBase& map) { } ``` -### 6.2. copyDataFrom +### 6.3. copyDataFrom ```c++ void copyDataFrom(const MapBase& map) @@ -118,7 +249,15 @@ void f(MapBase& m1, MapBase& m2) { } ``` -### 6.3. find +### 6.4. end + +```c++ +ConstIterator end() const = 0 +``` + +Return the iterator for the implementation. + +### 6.5. find ```c++ virtual Success find(const K& key, V& value) const = 0 @@ -144,7 +283,7 @@ void f(const MapBase& map) { } ``` -### 6.4. getCapacity +### 6.6. getCapacity ```c++ virtual FwSizeType getCapacity() const = 0 @@ -161,7 +300,7 @@ void f(const MapBase& map) { } ``` -### 6.5. getHeadMapEntry +### 6.7. getHeadMapEntry ```c++ virtual const MapEntry* getHeadMapEntry() const = 0 @@ -184,7 +323,7 @@ void f(const MapBase& map) { ``` -### 6.6. getSize +### 6.8. getSize ```c++ virtual FwSizeType getSize() const = 0 @@ -195,7 +334,7 @@ Return the current size. _Example:_ See [**getCapacity**](MapBase.md#64-getcapacity). -### 6.7. insert +### 6.9. insert ```c++ virtual Success insert(const K& key, const V& value) = 0 @@ -222,7 +361,7 @@ void f(MapBase& map) { } ``` -### 6.8. remove +### 6.10. remove ```c++ virtual Success remove(const K& key, V& value) = 0 From 9aa3a84f6757ad878e52409b4329da5f6d1f28ec Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 13 Jul 2025 15:35:42 -0700 Subject: [PATCH 349/458] Revise ArraySetOrMapImpl Add ConstIterator --- Fw/DataStructures/ArraySetOrMapImpl.hpp | 72 +++++++++++++++++++++ Fw/DataStructures/SetOrMapImplEntry.hpp | 6 ++ Fw/DataStructures/docs/ArraySetOrMapImpl.md | 24 ++++--- 3 files changed, 94 insertions(+), 8 deletions(-) diff --git a/Fw/DataStructures/ArraySetOrMapImpl.hpp b/Fw/DataStructures/ArraySetOrMapImpl.hpp index 4454acb83e8..75b842a0e08 100644 --- a/Fw/DataStructures/ArraySetOrMapImpl.hpp +++ b/Fw/DataStructures/ArraySetOrMapImpl.hpp @@ -31,6 +31,68 @@ class ArraySetOrMapImpl { //! The type of an entry in the set or map using Entry = SetOrMapImplEntry; + //! Const iterator + class ConstIterator { + public: + //! Constructor providing the implementation + ConstIterator(const ArraySetOrMapImpl& impl) : m_impl(impl) { this->reset(); } + + //! Copy constructor + ConstIterator(const ConstIterator& it) = delete; + + //! Destructor + ~ConstIterator() = default; + + public: + //! Copy assignment operator + ConstIterator& operator=(const ConstIterator&) = delete; + + //! Equality comparison operator + bool operator==(const ConstIterator& it) { + bool result = false; + if (&this->m_impl == &it.m_impl) { + result |= (this->m_index == it.m_index); + result |= (!this->isInRange() and !it.isInRange()); + } + return result; + } + + //! Increment operator + ConstIterator& operator++() { + if (this->isInRange()) { + this->m_index++; + } + return *this; + } + + //! Get the key or element in the entry pointed to by this iterator + const KE& getKeyOrElement() const { + FW_ASSERT(this->isInRange(), static_cast(this->m_index), + static_cast(this->m_impl.m_size)); + return this->m_impl.m_entries[this->m_index].getKeyOrElement(); + } + + //! Get the value in the entry pointed to by this iterator, or nil for a set + const VN& getValueOrNil() const { + FW_ASSERT(this->isInRange(), static_cast(this->m_index), + static_cast(this->m_impl.m_size)); + return this->m_impl.m_entries[this->m_index].getValueOrNil(); + } + + //! Check whether the iterator is in range + bool isInRange() const { return this->m_index < this->m_impl.m_size; } + + //! Reset the iterator + void reset() { this->m_index = 0; } + + private: + //! The implementation over which to iterate + const ArraySetOrMapImpl& m_impl; + + //! The current iteration index + FwSizeType m_index = 0; + }; + public: // ---------------------------------------------------------------------- // Public constructors and destructors @@ -76,9 +138,19 @@ class ArraySetOrMapImpl { 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.m_index = this->m_size; + 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 diff --git a/Fw/DataStructures/SetOrMapImplEntry.hpp b/Fw/DataStructures/SetOrMapImplEntry.hpp index dc3cc0caa5a..ac4358d7ea6 100644 --- a/Fw/DataStructures/SetOrMapImplEntry.hpp +++ b/Fw/DataStructures/SetOrMapImplEntry.hpp @@ -59,10 +59,16 @@ class SetOrMapImplEntry final : public MapEntry, public SetEntry { //! \return The key const KE& getKey() const override { return this->m_keyOrElement; } + // TODO + const KE& getKeyOrelement() const { return this->m_keyOrElement; } + //! Get the value associated with this entry //! \return The value const VN& getValue() const override { return this->m_valueOrNil; } + // TODO + const KE& getValueOrNil() const { return this->m_valueOrNil; } + //! Get the next entry //! \return The entry, or nullptr if none const SetOrMapImplEntry* getNextEntry() const { return this->m_next; } diff --git a/Fw/DataStructures/docs/ArraySetOrMapImpl.md b/Fw/DataStructures/docs/ArraySetOrMapImpl.md index 47bb601e26d..f167a40e9c9 100644 --- a/Fw/DataStructures/docs/ArraySetOrMapImpl.md +++ b/Fw/DataStructures/docs/ArraySetOrMapImpl.md @@ -57,7 +57,7 @@ ConstIterator(const ArraySetOrMapImpl& impl) ##### 2.2.2.2. Copy Constructor ```c++ -ConstIterator(const ConstIterator& it) +ConstIterator(const ConstIterator& it) ``` Defined as `= delete`. @@ -102,7 +102,7 @@ bool operator==(const ConstIterator& it) ConstIterator& operator++() ``` -1. If `m_index < m_size` then increment `m_index`. +1. If `isInRange()` then increment `m_index`. 1. Return `*this`. @@ -112,9 +112,9 @@ ConstIterator& operator++() const KE& getKeyOrElement() const ``` -1. Assert `m_index < m_size`. +1. Assert `isInRange()`. -1. Return `m_entries[index].getKeyOrElement()`. +1. Return `m_impl.m_entries[m_index].getKeyOrElement()`. ##### 2.2.3.5. getValueOrNil @@ -122,11 +122,19 @@ const KE& getKeyOrElement() const const KE& getValueOrNil() const ``` -1. Assert `m_index < m_size`. +1. Assert `m_index < m_impl.m_size`. -1. Return `m_entries[index].getValueOrNil()`. +1. Return `m_impl.m_entries[index].getValueOrNil()`. -##### 2.2.3.6. reset +##### 2.2.3.6. isInRange + +```c++ +bool isInRange() const +``` + +Return `m_index < m_impl.m_size`. + +##### 2.2.3.7. reset ```c++ void reset() @@ -233,7 +241,7 @@ Set `m_size = 0`. ConstIterator end() const ``` -1. Set `it = ConstIterator(*this)`. +1. Set `it = begin()`. 1. Set `it.m_index = m_size`. From c5f4d6362f1cd41e278cba8abd7570539ca2c140 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 13 Jul 2025 17:33:13 -0700 Subject: [PATCH 350/458] Add iterators to DS implementation --- Fw/DataStructures/ArraySetOrMapImpl.hpp | 34 +++---- Fw/DataStructures/ExternalArrayMap.hpp | 4 + Fw/DataStructures/MapBase.hpp | 1 + Fw/DataStructures/MapConstIterator.hpp | 96 +++++++++++++++++++ .../SetOrMapImplConstIterator.hpp | 68 +++++++++++++ Fw/DataStructures/SetOrMapImplEntry.hpp | 4 +- Fw/DataStructures/docs/MapBase.md | 57 +++++++---- .../test/ut/ArraySetOrMapImplTest.cpp | 2 + 8 files changed, 228 insertions(+), 38 deletions(-) create mode 100644 Fw/DataStructures/MapConstIterator.hpp create mode 100644 Fw/DataStructures/SetOrMapImplConstIterator.hpp diff --git a/Fw/DataStructures/ArraySetOrMapImpl.hpp b/Fw/DataStructures/ArraySetOrMapImpl.hpp index 75b842a0e08..f5bfcfe75db 100644 --- a/Fw/DataStructures/ArraySetOrMapImpl.hpp +++ b/Fw/DataStructures/ArraySetOrMapImpl.hpp @@ -8,6 +8,7 @@ #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" @@ -32,23 +33,25 @@ class ArraySetOrMapImpl { using Entry = SetOrMapImplEntry; //! Const iterator - class ConstIterator { + class ConstIterator final : public SetOrMapImplConstIterator { public: //! Constructor providing the implementation - ConstIterator(const ArraySetOrMapImpl& impl) : m_impl(impl) { this->reset(); } + ConstIterator(const ArraySetOrMapImpl& impl) : SetOrMapImplConstIterator(), m_impl(impl) { + this->reset(); + } //! Copy constructor - ConstIterator(const ConstIterator& it) = delete; + ConstIterator(const ConstIterator& it) = default; //! Destructor - ~ConstIterator() = default; + ~ConstIterator() override = default; public: //! Copy assignment operator - ConstIterator& operator=(const ConstIterator&) = delete; + ConstIterator& operator=(const ConstIterator&) = default; //! Equality comparison operator - bool operator==(const ConstIterator& it) { + bool compareEqual(const ConstIterator& it) const { bool result = false; if (&this->m_impl == &it.m_impl) { result |= (this->m_index == it.m_index); @@ -58,32 +61,31 @@ class ArraySetOrMapImpl { } //! Increment operator - ConstIterator& operator++() { + void increment() override { if (this->isInRange()) { this->m_index++; } - return *this; } //! Get the key or element in the entry pointed to by this iterator - const KE& getKeyOrElement() const { + const KE& getKeyOrElement() const override { FW_ASSERT(this->isInRange(), static_cast(this->m_index), static_cast(this->m_impl.m_size)); return this->m_impl.m_entries[this->m_index].getKeyOrElement(); } //! Get the value in the entry pointed to by this iterator, or nil for a set - const VN& getValueOrNil() const { + const VN& getValueOrNil() const override { FW_ASSERT(this->isInRange(), static_cast(this->m_index), static_cast(this->m_impl.m_size)); return this->m_impl.m_entries[this->m_index].getValueOrNil(); } //! Check whether the iterator is in range - bool isInRange() const { return this->m_index < this->m_impl.m_size; } + bool isInRange() const override { return this->m_index < this->m_impl.m_size; } //! Reset the iterator - void reset() { this->m_index = 0; } + void reset() override { this->m_index = 0; } private: //! The implementation over which to iterate @@ -145,10 +147,10 @@ class ArraySetOrMapImpl { void clear() { this->m_size = 0; } //! Get the end iterator - ConstIterator end() const { - auto it = begin(); - it.m_index = this->m_size; - return it; + ConstIterator end() const { + auto it = begin(); + it.m_index = this->m_size; + return it; } //! Find a value associated with a key in the map or an element in a set diff --git a/Fw/DataStructures/ExternalArrayMap.hpp b/Fw/DataStructures/ExternalArrayMap.hpp index 297e0d08a37..4a85c4db8d8 100644 --- a/Fw/DataStructures/ExternalArrayMap.hpp +++ b/Fw/DataStructures/ExternalArrayMap.hpp @@ -79,6 +79,10 @@ class ExternalArrayMap final : public MapBase { return *this; } + //! Get the begin iterator + //! \return The iterator + MapConstIterator begin() const { return MapConstIterator(this->m_impl.begin()); } + //! Clear the map void clear() override { this->m_impl.clear(); } diff --git a/Fw/DataStructures/MapBase.hpp b/Fw/DataStructures/MapBase.hpp index 16fe22e0db6..c48577e268e 100644 --- a/Fw/DataStructures/MapBase.hpp +++ b/Fw/DataStructures/MapBase.hpp @@ -7,6 +7,7 @@ #ifndef Fw_MapBase_HPP #define Fw_MapBase_HPP +#include "Fw/DataStructures/MapConstIterator.hpp" #include "Fw/DataStructures/MapEntry.hpp" #include "Fw/Types/Assert.hpp" #include "Fw/Types/SuccessEnumAc.hpp" diff --git a/Fw/DataStructures/MapConstIterator.hpp b/Fw/DataStructures/MapConstIterator.hpp new file mode 100644 index 00000000000..71ed73a585e --- /dev/null +++ b/Fw/DataStructures/MapConstIterator.hpp @@ -0,0 +1,96 @@ +// ====================================================================== +// \title MapConstIterator +// \author bocchino +// \brief An abstract class template representing an iterator for a map +// ====================================================================== + +#ifndef Fw_MapConstIterator_HPP +#define Fw_MapConstIterator_HPP + +#include "Fw/DataStructures/ArraySetOrMapImpl.hpp" +#include "Fw/FPrimeBasicTypes.hpp" + +namespace Fw { + +template +class MapConstIterator { + public: + //! The type of an array iterator + using ArrayIterator = typename ArraySetOrMapImpl::ConstIterator; + + private: + //! The type of an implementation kind + enum class ImplKind { ARRAY, RED_BLACK_TREE }; + + //! The type of an implementation + union Impl { + //! An array iterator + ArrayIterator arrayIterator; + // TODO: Add red-black tree implementation + }; + + public: + //! Constructor providing an array implementation + MapConstIterator(const ArrayIterator& it) : m_implKind(ImplKind::ARRAY), m_implIterator(m_impl.array) { + this->m_impl.array = it; + } + + //! Copy constructor + MapConstIterator(const MapConstIterator& it) = delete; + + //! Destructor + ~MapConstIterator() = default; + + public: + //! Copy assignment operator + MapConstIterator& operator=(const MapConstIterator&) = delete; + + //! Equality comparison operator + bool operator==(const MapConstIterator& it) { + bool result = false; + switch (this->m_implKind) { + case ImplKind::ARRAY: + result = this->m_impl.array.compareEqual(it.m_impl.array); + break; + case ImplKind::RED_BLACK_TREE: + // TODO + break; + default: + FW_ASSERT(0, static_cast(this->m_implKind)); + break; + } + return result; + } + + //! Increment operator + MapConstIterator& operator++() { + this->m_implIterator.increment(); + return *this; + } + + //! Get the key or element in the entry pointed to by this iterator + const K& getKey() const { return this->m_implIterator.getKeyOrElement(); } + + //! Get the value in the entry pointed to by this iterator, or nil for a set + const V& getValue() const { return this->m_implIterator.getValueOrNil(); } + + //! Check whether the iterator is in range + bool isInRange() const { return this->m_implIterator.isInRange(); } + + //! Reset the iterator + void reset() { return this->m_implIterator.reset(); } + + private: + //! The implementation kind + ImplKind m_implKind; + + //! The implementation + Impl m_impl; + + //! The impl iterator + SetOrMapImplConstIterator& m_implIterator; +}; + +} // namespace Fw + +#endif diff --git a/Fw/DataStructures/SetOrMapImplConstIterator.hpp b/Fw/DataStructures/SetOrMapImplConstIterator.hpp new file mode 100644 index 00000000000..85d428820ac --- /dev/null +++ b/Fw/DataStructures/SetOrMapImplConstIterator.hpp @@ -0,0 +1,68 @@ +// ====================================================================== +// \title SetOrMapImplConstIterator +// \author bocchino +// \brief A class template representing a const iterator for a set or map implementation +// ====================================================================== + +#ifndef Fw_SetOrMapImplConstIterator_HPP +#define Fw_SetOrMapImplConstIterator_HPP + +#include "Fw/FPrimeBasicTypes.hpp" + +namespace Fw { + +template +class SetOrMapImplConstIterator { + + // ---------------------------------------------------------------------- + // Deleted elements + // ---------------------------------------------------------------------- + + private: + //! Copy constructor + SetOrMapImplConstIterator(const SetOrMapImplConstIterator& it) = delete; + + private: + //! Copy assignment operator + SetOrMapImplConstIterator& operator=(const SetOrMapImplConstIterator&) = delete; + + // ---------------------------------------------------------------------- + // Constructors and destructors + // ---------------------------------------------------------------------- + + public: + //! Zero-argument constructor + SetOrMapImplConstIterator() = default; + + public: + //! Destructor + virtual ~SetOrMapImplConstIterator() = default; + + // ---------------------------------------------------------------------- + // Public member functions + // ---------------------------------------------------------------------- + + public: + //! Increment the iterator + virtual void increment() = 0; + + //! Get the key or element in the entry pointed to by this iterator + //! \return The key or element + virtual const KE& getKeyOrElement() const = 0; + + //! Get the value in the entry pointed to by this iterator, or nil for a set + //! \return The value or nil + virtual const VN& getValueOrNil() const = 0; + + //! Check whether the iterator is in range + //! \return True if the iterator is in range + virtual bool isInRange() const = 0; + + //! Reset the iterator + virtual void reset() = 0; + +}; + +} // namespace Fw + +#endif diff --git a/Fw/DataStructures/SetOrMapImplEntry.hpp b/Fw/DataStructures/SetOrMapImplEntry.hpp index ac4358d7ea6..b22b4e8fe38 100644 --- a/Fw/DataStructures/SetOrMapImplEntry.hpp +++ b/Fw/DataStructures/SetOrMapImplEntry.hpp @@ -60,14 +60,14 @@ class SetOrMapImplEntry final : public MapEntry, public SetEntry { const KE& getKey() const override { return this->m_keyOrElement; } // TODO - const KE& getKeyOrelement() const { return this->m_keyOrElement; } + const KE& getKeyOrElement() const { return this->m_keyOrElement; } //! Get the value associated with this entry //! \return The value const VN& getValue() const override { return this->m_valueOrNil; } // TODO - const KE& getValueOrNil() const { return this->m_valueOrNil; } + const VN& getValueOrNil() const { return this->m_valueOrNil; } //! Get the next entry //! \return The entry, or nullptr if none diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index 07e17583fe2..369ba78a846 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -30,7 +30,16 @@ It represents an abstract base class for a map. `ConstIterator` is a public inner class of `MapBase`. It provides non-modifying iteration over the elements of a `MapBase` instance. -#### 2.2.1. Private Enumerations +#### 2.2.1. Public Type Aliases + +`ConstIterator` defines the following public type aliases. + +|Name|Definition| +|----|----------| +|ArrayIterator|An alias for `ArraySetOrMapImpl::ConstIterator`. +|RedBlackTreeIterator|An alias for `RedBlackTreeSetOrMapImpl::ConstIterator`. + +#### 2.2.2. Private Enumerations `ConstIterator` defines the following private enumerations. @@ -38,15 +47,15 @@ non-modifying iteration over the elements of a `MapBase` instance. |----|----------| |ImplKind|An enumeration with values `ARRAY` and `RED_BLACK_TREE`| -#### 2.2.2. Private Type Aliases +#### 2.2.3. Private Type Aliases `ConstIterator` defines the following private type aliases. |Name|Definition| |----|----------| -|ImplIterator|A union with member variables `array` of type `ArraySetOrMapImpl::ConstIterator` and `redBlackTree` of type `RedBlackTreeSetOrMapImpl::ConstIterator`| +|ImplIterator|A union with member variables `arrayIterator` of type `ArrayIterator` and `redBlackTreeIterator` of type `RedBlackTreeIterator`| -#### 2.2.3. Private Member Variables +#### 2.2.4. Private Member Variables `ConstIterator` has the following private member variables. @@ -55,29 +64,29 @@ non-modifying iteration over the elements of a `MapBase` instance. |`m_implKind`|`ImplKind`|The implementation kind|None (must be set by the constructor)| |`m_impl`|`ImplIterator`|The iterator for the implementation|C++ default initialization| -#### 2.2.4. Public Constructors and Destructors +#### 2.2.5. Public Constructors and Destructors -##### 2.2.4.1. Constructor Providing an Array Implementation +##### 2.2.5.1. Constructor Providing an Array Implementation ```c++ -ConstIterator(const ArraySetOrMapImpl::ConstIterator& it) +ConstIterator(const ArraySetOrMapImpl& impl) ``` 1. Set `m_implKind = ARRAY`. -1. Set `m_implIterator.array = it; +1. Set `m_implIterator.arrayIterator = ArrayIterator(impl);` -##### 2.2.4.2. Constructor Providing a Red-Black Tree Implementation +##### 2.2.5.2. Constructor Providing a Red-Black Tree Implementation ```c++ -ConstIterator(const RedBlackTreeSetOrMapImpl::ConstIterator& it) +ConstIterator(const RedBlackTreeSetOrMapImpl& impl) ``` 1. Set `m_implKind = RED_BLACK_TREE`. -1. Set `m_implIterator.array = it; +1. Set `m_implIterator.array = RedBlackTreeIterator(impl);` -##### 2.2.4.3. Copy Constructor +##### 2.2.5.3. Copy Constructor ```c++ ConstIterator(const ConstIterator& it) @@ -85,7 +94,7 @@ ConstIterator(const ConstIterator& it) Defined as `= delete`. -##### 2.2.4.4. Destructor +##### 2.2.5.4. Destructor ```c++ ~ConstIterator() @@ -93,9 +102,9 @@ Defined as `= delete`. Defined as `= default`. -#### 2.2.5. Public Member Functions +#### 2.2.6. Public Member Functions -##### 2.2.5.1. operator= +##### 2.2.6.1. operator= ```c++ ConstIterator& operator=(const ConstIterator& it) @@ -103,7 +112,7 @@ ConstIterator& operator=(const ConstIterator& it) Defined as `= delete`. -##### 2.2.5.2. operator== +##### 2.2.6.2. operator== ```c++ bool operator==(const ConstIterator& it) @@ -113,7 +122,7 @@ bool operator==(const ConstIterator& it) 1. Otherwise delegate to the implementations. -##### 2.2.5.3. operator++ +##### 2.2.6.3. operator++ ```c++ ConstIterator& operator++() @@ -121,7 +130,7 @@ ConstIterator& operator++() Delegated to the implementation. -##### 2.2.5.4. getKeyOrElement +##### 2.2.6.4. getKeyOrElement ```c++ const KE& getKeyOrElement() const @@ -129,7 +138,7 @@ const KE& getKeyOrElement() const Delegated to the implementation. -##### 2.2.5.5. getValueOrNil +##### 2.2.6.5. getValueOrNil ```c++ const KE& getValueOrNil() const @@ -137,7 +146,15 @@ const KE& getValueOrNil() const Delegated to the implementation. -##### 2.2.5.6. reset +##### 2.2.6.6. isInRange() + +```c++ +bool isInRange() const +``` + +Delegated to the implementation. + +##### 2.2.6.7. reset ```c++ void reset() diff --git a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp index 8b37c521a06..eabbcc347d4 100644 --- a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp +++ b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp @@ -17,6 +17,8 @@ namespace Fw { namespace ArraySetOrMapImplTest { +State::Impl impl_; +State::Impl::ConstIterator it(impl_); TEST(ArraySetOrMapImpl, ZeroArgConstructor) { State::Impl impl; ASSERT_EQ(impl.getCapacity(), 0); From 6b916417d1373555404a0d9835caccdc318c7925 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 13 Jul 2025 18:06:57 -0700 Subject: [PATCH 351/458] Revise map iteration --- Fw/DataStructures/ArrayMap.hpp | 8 ++++++ Fw/DataStructures/ArraySetOrMapImpl.hpp | 11 +++++--- Fw/DataStructures/ExternalArrayMap.hpp | 6 ++++- Fw/DataStructures/MapBase.hpp | 8 ++++++ Fw/DataStructures/MapConstIterator.hpp | 35 ++++++++++++++----------- Fw/DataStructures/SetOrMapImplEntry.hpp | 8 +++--- 6 files changed, 51 insertions(+), 25 deletions(-) diff --git a/Fw/DataStructures/ArrayMap.hpp b/Fw/DataStructures/ArrayMap.hpp index e9448035b21..bdd934ec427 100644 --- a/Fw/DataStructures/ArrayMap.hpp +++ b/Fw/DataStructures/ArrayMap.hpp @@ -59,9 +59,17 @@ class ArrayMap final : public MapBase { return *this; } + //! Get the begin iterator + //! \return The iterator + MapConstIterator begin() const override { return this->m_extMap.begin(); } + //! Clear the map void clear() override { this->m_extMap.clear(); } + //! Get the end iterator + //! \return The iterator + MapConstIterator end() const override { return this->m_extMap.end(); } + //! Find a value associated with a key in the map //! \return SUCCESS if the item was found Success find(const K& key, //!< The key diff --git a/Fw/DataStructures/ArraySetOrMapImpl.hpp b/Fw/DataStructures/ArraySetOrMapImpl.hpp index f5bfcfe75db..81bc15a4fb2 100644 --- a/Fw/DataStructures/ArraySetOrMapImpl.hpp +++ b/Fw/DataStructures/ArraySetOrMapImpl.hpp @@ -16,7 +16,7 @@ namespace Fw { template -class ArraySetOrMapImpl { +class ArraySetOrMapImpl final { // ---------------------------------------------------------------------- // Friend class for testing // ---------------------------------------------------------------------- @@ -41,7 +41,7 @@ class ArraySetOrMapImpl { } //! Copy constructor - ConstIterator(const ConstIterator& it) = default; + ConstIterator(const ConstIterator& it) : m_impl(it.m_impl), m_index(it.m_index) {} //! Destructor ~ConstIterator() override = default; @@ -87,6 +87,9 @@ class ArraySetOrMapImpl { //! Reset the iterator void reset() override { this->m_index = 0; } + //! Set the index value + void setIndex(FwSizeType index) { this->m_index = index; } + private: //! The implementation over which to iterate const ArraySetOrMapImpl& m_impl; @@ -124,7 +127,7 @@ class ArraySetOrMapImpl { ArraySetOrMapImpl(const ArraySetOrMapImpl& impl) { *this = impl; } //! Destructor - virtual ~ArraySetOrMapImpl() = default; + ~ArraySetOrMapImpl() = default; public: // ---------------------------------------------------------------------- @@ -149,7 +152,7 @@ class ArraySetOrMapImpl { //! Get the end iterator ConstIterator end() const { auto it = begin(); - it.m_index = this->m_size; + it.setIndex(this->m_size); return it; } diff --git a/Fw/DataStructures/ExternalArrayMap.hpp b/Fw/DataStructures/ExternalArrayMap.hpp index 4a85c4db8d8..07f748fcfe4 100644 --- a/Fw/DataStructures/ExternalArrayMap.hpp +++ b/Fw/DataStructures/ExternalArrayMap.hpp @@ -81,11 +81,15 @@ class ExternalArrayMap final : public MapBase { //! Get the begin iterator //! \return The iterator - MapConstIterator begin() const { return MapConstIterator(this->m_impl.begin()); } + MapConstIterator begin() const override { return MapConstIterator(this->m_impl.begin()); } //! Clear the map void clear() override { this->m_impl.clear(); } + //! Get the end iterator + //! \return The iterator + MapConstIterator end() const override { return MapConstIterator(this->m_impl.end()); } + //! Find a value associated with a key in the map //! \return SUCCESS if the item was found Success find(const K& key, //!< The key diff --git a/Fw/DataStructures/MapBase.hpp b/Fw/DataStructures/MapBase.hpp index c48577e268e..d7cb45f4fb7 100644 --- a/Fw/DataStructures/MapBase.hpp +++ b/Fw/DataStructures/MapBase.hpp @@ -59,9 +59,17 @@ class MapBase { // Public member functions // ---------------------------------------------------------------------- + //! Get the begin iterator + //! \return The iterator + virtual MapConstIterator begin() const = 0; + //! Clear the map virtual void clear() = 0; + //! Get the end iterator + //! \return The iterator + virtual MapConstIterator end() const = 0; + //! Copy data from another map void copyDataFrom(const MapBase& map) { if (&map != this) { diff --git a/Fw/DataStructures/MapConstIterator.hpp b/Fw/DataStructures/MapConstIterator.hpp index 71ed73a585e..16c2b3a259a 100644 --- a/Fw/DataStructures/MapConstIterator.hpp +++ b/Fw/DataStructures/MapConstIterator.hpp @@ -24,40 +24,43 @@ class MapConstIterator { //! The type of an implementation union Impl { + Impl(const ArrayIterator& it) : array(it) {} //! An array iterator - ArrayIterator arrayIterator; + ArrayIterator array; // TODO: Add red-black tree implementation + ~Impl() {} }; public: //! Constructor providing an array implementation - MapConstIterator(const ArrayIterator& it) : m_implKind(ImplKind::ARRAY), m_implIterator(m_impl.array) { - this->m_impl.array = it; - } + MapConstIterator(const ArrayIterator& it) : m_implKind(ImplKind::ARRAY), m_impl(it), m_implIterator(m_impl.array) {} //! Copy constructor - MapConstIterator(const MapConstIterator& it) = delete; + MapConstIterator(const MapConstIterator& it) + : m_implKind(it.m_implKind), m_impl(it.m_impl.array), m_implIterator(it.m_implIterator) { + // TODO: Handle tree case + } //! Destructor - ~MapConstIterator() = default; + ~MapConstIterator() {} public: //! Copy assignment operator - MapConstIterator& operator=(const MapConstIterator&) = delete; + MapConstIterator& operator=(const MapConstIterator&) = default; //! Equality comparison operator bool operator==(const MapConstIterator& it) { bool result = false; switch (this->m_implKind) { - case ImplKind::ARRAY: - result = this->m_impl.array.compareEqual(it.m_impl.array); - break; - case ImplKind::RED_BLACK_TREE: - // TODO - break; - default: - FW_ASSERT(0, static_cast(this->m_implKind)); - break; + case ImplKind::ARRAY: + result = this->m_impl.array.compareEqual(it.m_impl.array); + break; + case ImplKind::RED_BLACK_TREE: + // TODO + break; + default: + FW_ASSERT(0, static_cast(this->m_implKind)); + break; } return result; } diff --git a/Fw/DataStructures/SetOrMapImplEntry.hpp b/Fw/DataStructures/SetOrMapImplEntry.hpp index b22b4e8fe38..0b08b10dcbf 100644 --- a/Fw/DataStructures/SetOrMapImplEntry.hpp +++ b/Fw/DataStructures/SetOrMapImplEntry.hpp @@ -24,10 +24,10 @@ class SetOrMapImplEntry final : public MapEntry, public SetEntry { SetOrMapImplEntry() : MapEntry(), SetEntry() {} //! Constructor providing members - SetOrMapImplEntry(const KE& keyOrElement, //!< The key or element - const VN& valueOrNil, //!< The value or Nil - const SetOrMapImplEntry* next = nullptr //!< The next entry - ) + SetOrMapImplEntry(const KE& keyOrElement, //!< The key or element + const VN& valueOrNil, //!< The value or Nil + const SetOrMapImplEntry* next = nullptr //!< The next entry + ) : MapEntry(), SetEntry(), m_keyOrElement(keyOrElement), m_valueOrNil(valueOrNil), m_next(next) {} //! Copy constructor From 1c7e0d050702a92c3fc235854f1edb7e0d121753 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 13 Jul 2025 19:39:40 -0700 Subject: [PATCH 352/458] Revise unit tests Use iterators for maps --- Fw/DataStructures/ArraySetOrMapImpl.hpp | 7 +++-- Fw/DataStructures/MapBase.hpp | 7 ++--- Fw/DataStructures/MapConstIterator.hpp | 19 +++++++++++- Fw/DataStructures/test/ut/ArrayMapTest.cpp | 3 ++ .../ut/STest/ArraySetOrMapImplTestRules.hpp | 30 +++++++++--------- .../test/ut/STest/MapTestRules.hpp | 31 ++++++++++--------- 6 files changed, 60 insertions(+), 37 deletions(-) diff --git a/Fw/DataStructures/ArraySetOrMapImpl.hpp b/Fw/DataStructures/ArraySetOrMapImpl.hpp index 81bc15a4fb2..91ed480ad03 100644 --- a/Fw/DataStructures/ArraySetOrMapImpl.hpp +++ b/Fw/DataStructures/ArraySetOrMapImpl.hpp @@ -48,7 +48,10 @@ class ArraySetOrMapImpl final { public: //! Copy assignment operator - ConstIterator& operator=(const ConstIterator&) = default; + ConstIterator& operator=(const ConstIterator& it) { + this->m_impl = it.m_impl; + this->m_index = it.m_index; + } //! Equality comparison operator bool compareEqual(const ConstIterator& it) const { @@ -152,7 +155,7 @@ class ArraySetOrMapImpl final { //! Get the end iterator ConstIterator end() const { auto it = begin(); - it.setIndex(this->m_size); + it.setIndex(this->m_size + 1); return it; } diff --git a/Fw/DataStructures/MapBase.hpp b/Fw/DataStructures/MapBase.hpp index d7cb45f4fb7..e5fe6f90b10 100644 --- a/Fw/DataStructures/MapBase.hpp +++ b/Fw/DataStructures/MapBase.hpp @@ -74,13 +74,12 @@ class MapBase { void copyDataFrom(const MapBase& map) { if (&map != this) { this->clear(); - const auto* e = map.getHeadMapEntry(); const FwSizeType size = FW_MIN(map.getSize(), this->getCapacity()); + auto it = map.begin(); for (FwSizeType i = 0; i < size; i++) { - FW_ASSERT(e != nullptr); - const auto status = this->insert(e->getKey(), e->getValue()); + const auto status = this->insert(it.getKey(), it.getValue()); FW_ASSERT(status == Success::SUCCESS, static_cast(status)); - e = e->getNextMapEntry(); + it++; } } } diff --git a/Fw/DataStructures/MapConstIterator.hpp b/Fw/DataStructures/MapConstIterator.hpp index 16c2b3a259a..9efe094f82d 100644 --- a/Fw/DataStructures/MapConstIterator.hpp +++ b/Fw/DataStructures/MapConstIterator.hpp @@ -65,12 +65,23 @@ class MapConstIterator { return result; } - //! Increment operator + //! Inequality comparison operator + bool operator!=(const MapConstIterator& it) { return !(*this == it); }; + + //! Prefix increment MapConstIterator& operator++() { this->m_implIterator.increment(); return *this; } + //! Prefix increment + MapConstIterator operator++(int) { MapConstIterator tmp = *this; ++(*this); return tmp; } + + //! Postfix increment + void increment() { + this->m_implIterator.increment(); + } + //! Get the key or element in the entry pointed to by this iterator const K& getKey() const { return this->m_implIterator.getKeyOrElement(); } @@ -83,6 +94,12 @@ class MapConstIterator { //! Reset the iterator void reset() { return this->m_implIterator.reset(); } + //! Dereference + const MapConstIterator& operator*() const { return *this; } + + //! Pointer + const MapConstIterator* operator->() const { return this; } + private: //! The implementation kind ImplKind m_implKind; diff --git a/Fw/DataStructures/test/ut/ArrayMapTest.cpp b/Fw/DataStructures/test/ut/ArrayMapTest.cpp index e4514e3e1d2..9ae8069954d 100644 --- a/Fw/DataStructures/test/ut/ArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ArrayMapTest.cpp @@ -29,6 +29,7 @@ class ArrayMapTester { namespace MapTest { +using ConstIterator = MapConstIterator; using Entry = SetOrMapImplEntry; using Map = ArrayMap; using MapTester = ArrayMapTester; @@ -92,6 +93,7 @@ TEST(ArrayMap, CopyDataFrom) { } } +#if 0 TEST(ArrayMapScenarios, Clear) { Map map; State state(map); @@ -103,6 +105,7 @@ TEST(ArrayMapScenarios, Find) { State state(map); Scenarios::find(state); } +#endif TEST(ArrayMapScenarios, FindExisting) { Map map; diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp index acd04a4c42e..29ee6df651e 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp @@ -53,13 +53,13 @@ struct FindExisting : public Rule { void action(State& state) { const auto size = state.impl.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); - const auto* entry = state.impl.getHeadEntry(); + auto it = state.impl.begin(); for (FwSizeType i = 0; i < index; i++) { - ASSERT_NE(entry, nullptr); - entry = entry->getNextEntry(); + ASSERT_TRUE(it.isInRange()); + it.increment(); } - ASSERT_NE(entry, nullptr); - const auto key = entry->getKey(); + ASSERT_TRUE(it.isInRange()); + const auto key = it.getKeyOrElement(); const auto expectedValue = state.modelMap[key]; State::ValueType value = 0; const auto status = state.impl.find(key, value); @@ -74,13 +74,13 @@ struct InsertExisting : public Rule { void action(State& state) { const auto size = state.impl.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); - const auto* entry = state.impl.getHeadEntry(); + auto it = state.impl.begin(); for (FwSizeType i = 0; i < index; i++) { - ASSERT_NE(entry, nullptr); - entry = entry->getNextEntry(); + ASSERT_TRUE(it.isInRange()); + it.increment(); } - ASSERT_NE(entry, nullptr); - const auto key = entry->getKey(); + ASSERT_TRUE(it.isInRange()); + const auto key = it.getKeyOrElement(); const auto value = state.getValue(); const auto status = state.impl.insert(key, value); ASSERT_EQ(status, Success::SUCCESS); @@ -146,13 +146,13 @@ struct RemoveExisting : public Rule { void action(State& state) { const auto size = state.impl.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); - const auto* entry = state.impl.getHeadEntry(); + auto it = state.impl.begin(); for (FwSizeType i = 0; i < index; i++) { - ASSERT_NE(entry, nullptr); - entry = entry->getNextEntry(); + ASSERT_TRUE(it.isInRange()); + it.increment(); } - ASSERT_NE(entry, nullptr); - const auto key = entry->getKey(); + ASSERT_TRUE(it.isInRange()); + const auto key = it.getKeyOrElement(); const auto expectedValue = state.modelMap[key]; State::ValueType value = 0; const auto status = state.impl.remove(key, value); diff --git a/Fw/DataStructures/test/ut/STest/MapTestRules.hpp b/Fw/DataStructures/test/ut/STest/MapTestRules.hpp index e3cfc8fa928..8bcd8eaa4b7 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/MapTestRules.hpp @@ -53,13 +53,14 @@ struct FindExisting : public Rule { void action(State& state) { const auto size = state.map.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); - const auto* entry = state.map.getHeadMapEntry(); + auto it = state.map.begin(); for (FwSizeType i = 0; i < index; i++) { - ASSERT_NE(entry, nullptr); - entry = entry->getNextMapEntry(); + ASSERT_TRUE(it.isInRange()); + it++; + } - ASSERT_NE(entry, nullptr); - const auto key = entry->getKey(); + ASSERT_TRUE(it.isInRange()); + const auto key = it.getKey(); const auto expectedValue = state.modelMap[key]; State::ValueType value = 0; const auto status = state.map.find(key, value); @@ -74,13 +75,13 @@ struct InsertExisting : public Rule { void action(State& state) { const auto size = state.map.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); - const auto* entry = state.map.getHeadMapEntry(); + auto it = state.map.begin(); for (FwSizeType i = 0; i < index; i++) { - ASSERT_NE(entry, nullptr); - entry = entry->getNextMapEntry(); + ASSERT_TRUE(it.isInRange()); + it++; } - ASSERT_NE(entry, nullptr); - const auto key = entry->getKey(); + ASSERT_TRUE(it.isInRange()); + const auto key = it.getKey(); const auto value = state.getValue(); const auto status = state.map.insert(key, value); ASSERT_EQ(status, Success::SUCCESS); @@ -147,13 +148,13 @@ struct RemoveExisting : public Rule { void action(State& state) { const auto size = state.map.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); - const auto* entry = state.map.getHeadMapEntry(); + auto it = state.map.begin(); for (FwSizeType i = 0; i < index; i++) { - ASSERT_NE(entry, nullptr); - entry = entry->getNextMapEntry(); + ASSERT_TRUE(it.isInRange()); + it++; } - ASSERT_NE(entry, nullptr); - const auto key = entry->getKey(); + ASSERT_TRUE(it.isInRange()); + const auto key = it.getKey(); const auto expectedValue = state.modelMap[key]; State::ValueType value = 0; const auto status = state.map.remove(key, value); From de6982241515026470f9276e0f7af1eb357c3cf3 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 13 Jul 2025 19:52:53 -0700 Subject: [PATCH 353/458] Revise iterators --- Fw/DataStructures/ArraySetOrMapImpl.hpp | 8 ++++++++ Fw/DataStructures/MapConstIterator.hpp | 5 +++-- Fw/DataStructures/MapEntry.hpp | 10 +++------- Fw/DataStructures/SetOrMapImplConstIterator.hpp | 11 ++++++++--- Fw/DataStructures/SetOrMapImplEntry.hpp | 14 ++++---------- 5 files changed, 26 insertions(+), 22 deletions(-) diff --git a/Fw/DataStructures/ArraySetOrMapImpl.hpp b/Fw/DataStructures/ArraySetOrMapImpl.hpp index 91ed480ad03..da056111906 100644 --- a/Fw/DataStructures/ArraySetOrMapImpl.hpp +++ b/Fw/DataStructures/ArraySetOrMapImpl.hpp @@ -63,6 +63,14 @@ class ArraySetOrMapImpl final { return result; } + //! 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->isInRange(), static_cast(this->m_index), + static_cast(this->m_impl.m_size)); + return this->m_impl.m_entries[this->m_index]; + } + //! Increment operator void increment() override { if (this->isInRange()) { diff --git a/Fw/DataStructures/MapConstIterator.hpp b/Fw/DataStructures/MapConstIterator.hpp index 9efe094f82d..1b4ec447c52 100644 --- a/Fw/DataStructures/MapConstIterator.hpp +++ b/Fw/DataStructures/MapConstIterator.hpp @@ -8,6 +8,7 @@ #define Fw_MapConstIterator_HPP #include "Fw/DataStructures/ArraySetOrMapImpl.hpp" +#include "Fw/DataStructures/MapEntry.hpp" #include "Fw/FPrimeBasicTypes.hpp" namespace Fw { @@ -95,10 +96,10 @@ class MapConstIterator { void reset() { return this->m_implIterator.reset(); } //! Dereference - const MapConstIterator& operator*() const { return *this; } + const MapEntry& operator*() const { return this->m_implIterator.getEntry(); } //! Pointer - const MapConstIterator* operator->() const { return this; } + const MapEntry& operator->() const { return &this->m_implIterator.getEntry(); } private: //! The implementation kind diff --git a/Fw/DataStructures/MapEntry.hpp b/Fw/DataStructures/MapEntry.hpp index 0f4dc0e8abb..7907ed52b3a 100644 --- a/Fw/DataStructures/MapEntry.hpp +++ b/Fw/DataStructures/MapEntry.hpp @@ -1,7 +1,7 @@ // ====================================================================== // \title MapEntry // \author bocchino -// \brief An abstract class template representing an iterator for a map +// \brief An abstract class template representing an entry for a map // ====================================================================== #ifndef Fw_MapEntry_HPP @@ -48,17 +48,13 @@ class MapEntry { // Public member functions // ---------------------------------------------------------------------- - //! Get the key associated with this iterator + //! Get the key associated with this entry //! \return The key virtual const K& getKey() const = 0; - //! Get the value associated with this iterator + //! Get the value associated with this entry //! \return The value virtual const V& getValue() const = 0; - - //! Get the next map iterator - //! \return The map iterator, or nullptr if none - virtual const MapEntry* getNextMapEntry() const = 0; }; } // namespace Fw diff --git a/Fw/DataStructures/SetOrMapImplConstIterator.hpp b/Fw/DataStructures/SetOrMapImplConstIterator.hpp index 85d428820ac..22c535629cd 100644 --- a/Fw/DataStructures/SetOrMapImplConstIterator.hpp +++ b/Fw/DataStructures/SetOrMapImplConstIterator.hpp @@ -7,6 +7,7 @@ #ifndef Fw_SetOrMapImplConstIterator_HPP #define Fw_SetOrMapImplConstIterator_HPP +#include "Fw/DataStructures/SetOrMapImplEntry.hpp" #include "Fw/FPrimeBasicTypes.hpp" namespace Fw { @@ -46,6 +47,10 @@ class SetOrMapImplConstIterator { //! Increment the iterator virtual void increment() = 0; + //! Check whether the iterator is in range + //! \return True if the iterator is in range + virtual bool isInRange() const = 0; + //! Get the key or element in the entry pointed to by this iterator //! \return The key or element virtual const KE& getKeyOrElement() const = 0; @@ -54,9 +59,9 @@ class SetOrMapImplConstIterator { //! \return The value or nil virtual const VN& getValueOrNil() const = 0; - //! Check whether the iterator is in range - //! \return True if the iterator is in range - virtual bool isInRange() const = 0; + //! Get the set or map impl entry pointed to by this iterator + //! \return The set or map impl entry + virtual const SetOrMapImplEntry& getEntry() const = 0; //! Reset the iterator virtual void reset() = 0; diff --git a/Fw/DataStructures/SetOrMapImplEntry.hpp b/Fw/DataStructures/SetOrMapImplEntry.hpp index 0b08b10dcbf..2421fc79eb4 100644 --- a/Fw/DataStructures/SetOrMapImplEntry.hpp +++ b/Fw/DataStructures/SetOrMapImplEntry.hpp @@ -59,24 +59,18 @@ class SetOrMapImplEntry final : public MapEntry, public SetEntry { //! \return The key const KE& getKey() const override { return this->m_keyOrElement; } - // TODO + //! Get the key or element associated with this entry + //! \return The key or element const KE& getKeyOrElement() const { return this->m_keyOrElement; } //! Get the value associated with this entry //! \return The value const VN& getValue() const override { return this->m_valueOrNil; } - // TODO + //! Get the value or nil associated with this entry + //! \return The value or nil const VN& getValueOrNil() const { return this->m_valueOrNil; } - //! Get the next entry - //! \return The entry, or nullptr if none - const SetOrMapImplEntry* getNextEntry() const { return this->m_next; } - - //! Get the next map entry - //! \return The map entry, or nullptr if none - const MapEntry* getNextMapEntry() const override { return this->m_next; } - //! Get the next set entry //! \return The set entry, or nullptr if none const SetEntry* getNextSetEntry() const override { return this->m_next; } From d3500f835c46759d9586f00a446698bf002e5c32 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 13 Jul 2025 19:58:56 -0700 Subject: [PATCH 354/458] Revise iterators --- Fw/DataStructures/ArraySetOrMapImpl.hpp | 14 -------------- Fw/DataStructures/MapBase.hpp | 2 +- Fw/DataStructures/MapConstIterator.hpp | 8 +------- Fw/DataStructures/SetOrMapImplConstIterator.hpp | 8 -------- .../test/ut/STest/ArraySetOrMapImplTestRules.hpp | 6 +++--- Fw/DataStructures/test/ut/STest/MapTestRules.hpp | 6 +++--- 6 files changed, 8 insertions(+), 36 deletions(-) diff --git a/Fw/DataStructures/ArraySetOrMapImpl.hpp b/Fw/DataStructures/ArraySetOrMapImpl.hpp index da056111906..2eb84b9005d 100644 --- a/Fw/DataStructures/ArraySetOrMapImpl.hpp +++ b/Fw/DataStructures/ArraySetOrMapImpl.hpp @@ -78,20 +78,6 @@ class ArraySetOrMapImpl final { } } - //! Get the key or element in the entry pointed to by this iterator - const KE& getKeyOrElement() const override { - FW_ASSERT(this->isInRange(), static_cast(this->m_index), - static_cast(this->m_impl.m_size)); - return this->m_impl.m_entries[this->m_index].getKeyOrElement(); - } - - //! Get the value in the entry pointed to by this iterator, or nil for a set - const VN& getValueOrNil() const override { - FW_ASSERT(this->isInRange(), static_cast(this->m_index), - static_cast(this->m_impl.m_size)); - return this->m_impl.m_entries[this->m_index].getValueOrNil(); - } - //! Check whether the iterator is in range bool isInRange() const override { return this->m_index < this->m_impl.m_size; } diff --git a/Fw/DataStructures/MapBase.hpp b/Fw/DataStructures/MapBase.hpp index e5fe6f90b10..4c97201ae57 100644 --- a/Fw/DataStructures/MapBase.hpp +++ b/Fw/DataStructures/MapBase.hpp @@ -77,7 +77,7 @@ class MapBase { const FwSizeType size = FW_MIN(map.getSize(), this->getCapacity()); auto it = map.begin(); for (FwSizeType i = 0; i < size; i++) { - const auto status = this->insert(it.getKey(), it.getValue()); + const auto status = this->insert(it->getKey(), it->getValue()); FW_ASSERT(status == Success::SUCCESS, static_cast(status)); it++; } diff --git a/Fw/DataStructures/MapConstIterator.hpp b/Fw/DataStructures/MapConstIterator.hpp index 1b4ec447c52..9bf4241d585 100644 --- a/Fw/DataStructures/MapConstIterator.hpp +++ b/Fw/DataStructures/MapConstIterator.hpp @@ -83,12 +83,6 @@ class MapConstIterator { this->m_implIterator.increment(); } - //! Get the key or element in the entry pointed to by this iterator - const K& getKey() const { return this->m_implIterator.getKeyOrElement(); } - - //! Get the value in the entry pointed to by this iterator, or nil for a set - const V& getValue() const { return this->m_implIterator.getValueOrNil(); } - //! Check whether the iterator is in range bool isInRange() const { return this->m_implIterator.isInRange(); } @@ -99,7 +93,7 @@ class MapConstIterator { const MapEntry& operator*() const { return this->m_implIterator.getEntry(); } //! Pointer - const MapEntry& operator->() const { return &this->m_implIterator.getEntry(); } + const MapEntry* operator->() const { return &this->m_implIterator.getEntry(); } private: //! The implementation kind diff --git a/Fw/DataStructures/SetOrMapImplConstIterator.hpp b/Fw/DataStructures/SetOrMapImplConstIterator.hpp index 22c535629cd..0f8b47eda0e 100644 --- a/Fw/DataStructures/SetOrMapImplConstIterator.hpp +++ b/Fw/DataStructures/SetOrMapImplConstIterator.hpp @@ -51,14 +51,6 @@ class SetOrMapImplConstIterator { //! \return True if the iterator is in range virtual bool isInRange() const = 0; - //! Get the key or element in the entry pointed to by this iterator - //! \return The key or element - virtual const KE& getKeyOrElement() const = 0; - - //! Get the value in the entry pointed to by this iterator, or nil for a set - //! \return The value or nil - virtual const VN& getValueOrNil() const = 0; - //! Get the set or map impl entry pointed to by this iterator //! \return The set or map impl entry virtual const SetOrMapImplEntry& getEntry() const = 0; diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp index 29ee6df651e..b0c999e0254 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp @@ -59,7 +59,7 @@ struct FindExisting : public Rule { it.increment(); } ASSERT_TRUE(it.isInRange()); - const auto key = it.getKeyOrElement(); + const auto key = it.getEntry().getKeyOrElement(); const auto expectedValue = state.modelMap[key]; State::ValueType value = 0; const auto status = state.impl.find(key, value); @@ -80,7 +80,7 @@ struct InsertExisting : public Rule { it.increment(); } ASSERT_TRUE(it.isInRange()); - const auto key = it.getKeyOrElement(); + const auto key = it.getEntry().getKeyOrElement(); const auto value = state.getValue(); const auto status = state.impl.insert(key, value); ASSERT_EQ(status, Success::SUCCESS); @@ -152,7 +152,7 @@ struct RemoveExisting : public Rule { it.increment(); } ASSERT_TRUE(it.isInRange()); - const auto key = it.getKeyOrElement(); + const auto key = it.getEntry().getKeyOrElement(); const auto expectedValue = state.modelMap[key]; State::ValueType value = 0; const auto status = state.impl.remove(key, value); diff --git a/Fw/DataStructures/test/ut/STest/MapTestRules.hpp b/Fw/DataStructures/test/ut/STest/MapTestRules.hpp index 8bcd8eaa4b7..ab092834b9e 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/MapTestRules.hpp @@ -60,7 +60,7 @@ struct FindExisting : public Rule { } ASSERT_TRUE(it.isInRange()); - const auto key = it.getKey(); + const auto key = it->getKey(); const auto expectedValue = state.modelMap[key]; State::ValueType value = 0; const auto status = state.map.find(key, value); @@ -81,7 +81,7 @@ struct InsertExisting : public Rule { it++; } ASSERT_TRUE(it.isInRange()); - const auto key = it.getKey(); + const auto key = it->getKey(); const auto value = state.getValue(); const auto status = state.map.insert(key, value); ASSERT_EQ(status, Success::SUCCESS); @@ -154,7 +154,7 @@ struct RemoveExisting : public Rule { it++; } ASSERT_TRUE(it.isInRange()); - const auto key = it.getKey(); + const auto key = it->getKey(); const auto expectedValue = state.modelMap[key]; State::ValueType value = 0; const auto status = state.map.remove(key, value); From 49532af0a3c3f7221a1bdf82aa783831b30f776b Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 13 Jul 2025 20:01:19 -0700 Subject: [PATCH 355/458] Rename MapEntry to MapConstEntry --- Fw/DataStructures/ArrayMap.hpp | 4 ++-- Fw/DataStructures/ExternalArrayMap.hpp | 4 ++-- Fw/DataStructures/MapBase.hpp | 6 +++--- .../{MapEntry.hpp => MapConstEntry.hpp} | 18 +++++++++--------- Fw/DataStructures/MapConstIterator.hpp | 6 +++--- Fw/DataStructures/SetOrMapImplEntry.hpp | 8 ++++---- 6 files changed, 23 insertions(+), 23 deletions(-) rename Fw/DataStructures/{MapEntry.hpp => MapConstEntry.hpp} (81%) diff --git a/Fw/DataStructures/ArrayMap.hpp b/Fw/DataStructures/ArrayMap.hpp index bdd934ec427..96ec860e6b7 100644 --- a/Fw/DataStructures/ArrayMap.hpp +++ b/Fw/DataStructures/ArrayMap.hpp @@ -29,7 +29,7 @@ class ArrayMap final : public MapBase { using ImplEntry = SetOrMapImplEntry; //! The type of a map entry - using MapEntry = MapEntry; + using MapConstEntry = MapConstEntry; //! The type of the implementation entries using ImplEntries = ImplEntry[C]; @@ -84,7 +84,7 @@ class ArrayMap final : public MapBase { //! Get the head map entry for the map //! \return The map entry - const MapEntry* getHeadMapEntry() const override { return this->m_extMap.getHeadMapEntry(); } + const MapConstEntry* getHeadMapConstEntry() const override { return this->m_extMap.getHeadMapConstEntry(); } //! Get the size (number of entries) //! \return The size diff --git a/Fw/DataStructures/ExternalArrayMap.hpp b/Fw/DataStructures/ExternalArrayMap.hpp index 07f748fcfe4..1dcf0ae392e 100644 --- a/Fw/DataStructures/ExternalArrayMap.hpp +++ b/Fw/DataStructures/ExternalArrayMap.hpp @@ -31,7 +31,7 @@ class ExternalArrayMap final : public MapBase { using ImplEntry = SetOrMapImplEntry; //! The type of a map entry - using MapEntry = MapEntry; + using MapConstEntry = MapConstEntry; public: // ---------------------------------------------------------------------- @@ -104,7 +104,7 @@ class ExternalArrayMap final : public MapBase { //! Get the head map entry for the map //! \return The map entry - const MapEntry* getHeadMapEntry() const override { return this->m_impl.getHeadEntry(); } + const MapConstEntry* getHeadMapConstEntry() const override { return this->m_impl.getHeadEntry(); } //! Get the size (number of entries) //! \return The size diff --git a/Fw/DataStructures/MapBase.hpp b/Fw/DataStructures/MapBase.hpp index 4c97201ae57..1caf9274530 100644 --- a/Fw/DataStructures/MapBase.hpp +++ b/Fw/DataStructures/MapBase.hpp @@ -8,7 +8,7 @@ #define Fw_MapBase_HPP #include "Fw/DataStructures/MapConstIterator.hpp" -#include "Fw/DataStructures/MapEntry.hpp" +#include "Fw/DataStructures/MapConstEntry.hpp" #include "Fw/Types/Assert.hpp" #include "Fw/Types/SuccessEnumAc.hpp" @@ -22,7 +22,7 @@ class MapBase { // ---------------------------------------------------------------------- //! The type of a map iterator - using MapEntry = MapEntry; + using MapConstEntry = MapConstEntry; private: // ---------------------------------------------------------------------- @@ -96,7 +96,7 @@ class MapBase { //! Get the head iterator for the map //! \return The iterator - virtual const MapEntry* getHeadMapEntry() const = 0; + virtual const MapConstEntry* getHeadMapConstEntry() const = 0; //! Get the size (number of items stored in the map) //! \return The size diff --git a/Fw/DataStructures/MapEntry.hpp b/Fw/DataStructures/MapConstEntry.hpp similarity index 81% rename from Fw/DataStructures/MapEntry.hpp rename to Fw/DataStructures/MapConstEntry.hpp index 7907ed52b3a..a6767a4bb6c 100644 --- a/Fw/DataStructures/MapEntry.hpp +++ b/Fw/DataStructures/MapConstEntry.hpp @@ -1,18 +1,18 @@ // ====================================================================== -// \title MapEntry +// \title MapConstEntry // \author bocchino -// \brief An abstract class template representing an entry for a map +// \brief An abstract class template representing a constant entry for a map // ====================================================================== -#ifndef Fw_MapEntry_HPP -#define Fw_MapEntry_HPP +#ifndef Fw_MapConstEntry_HPP +#define Fw_MapConstEntry_HPP #include "Fw/FPrimeBasicTypes.hpp" namespace Fw { template -class MapEntry { +class MapConstEntry { private: // ---------------------------------------------------------------------- // Private constructors @@ -20,7 +20,7 @@ class MapEntry { //! Copy constructor deleted in the base class //! Behavior depends on the implementation - MapEntry(const MapEntry&) = delete; + MapConstEntry(const MapConstEntry&) = delete; protected: // ---------------------------------------------------------------------- @@ -28,10 +28,10 @@ class MapEntry { // ---------------------------------------------------------------------- //! Zero-argument constructor - MapEntry() {} + MapConstEntry() {} //! Destructor - virtual ~MapEntry() = default; + virtual ~MapConstEntry() = default; private: // ---------------------------------------------------------------------- @@ -41,7 +41,7 @@ class MapEntry { //! operator= deleted in the base class //! Behavior depends on the implementation //! We avoid virtual user-defined operators - MapEntry& operator=(const MapEntry&) = delete; + MapConstEntry& operator=(const MapConstEntry&) = delete; public: // ---------------------------------------------------------------------- diff --git a/Fw/DataStructures/MapConstIterator.hpp b/Fw/DataStructures/MapConstIterator.hpp index 9bf4241d585..838b9db02f6 100644 --- a/Fw/DataStructures/MapConstIterator.hpp +++ b/Fw/DataStructures/MapConstIterator.hpp @@ -8,7 +8,7 @@ #define Fw_MapConstIterator_HPP #include "Fw/DataStructures/ArraySetOrMapImpl.hpp" -#include "Fw/DataStructures/MapEntry.hpp" +#include "Fw/DataStructures/MapConstEntry.hpp" #include "Fw/FPrimeBasicTypes.hpp" namespace Fw { @@ -90,10 +90,10 @@ class MapConstIterator { void reset() { return this->m_implIterator.reset(); } //! Dereference - const MapEntry& operator*() const { return this->m_implIterator.getEntry(); } + const MapConstEntry& operator*() const { return this->m_implIterator.getEntry(); } //! Pointer - const MapEntry* operator->() const { return &this->m_implIterator.getEntry(); } + const MapConstEntry* operator->() const { return &this->m_implIterator.getEntry(); } private: //! The implementation kind diff --git a/Fw/DataStructures/SetOrMapImplEntry.hpp b/Fw/DataStructures/SetOrMapImplEntry.hpp index 2421fc79eb4..23660a1c5f2 100644 --- a/Fw/DataStructures/SetOrMapImplEntry.hpp +++ b/Fw/DataStructures/SetOrMapImplEntry.hpp @@ -7,28 +7,28 @@ #ifndef Fw_SetOrMapImplEntry_HPP #define Fw_SetOrMapImplEntry_HPP -#include "Fw/DataStructures/MapEntry.hpp" +#include "Fw/DataStructures/MapConstEntry.hpp" #include "Fw/DataStructures/SetEntry.hpp" #include "Fw/FPrimeBasicTypes.hpp" namespace Fw { template -class SetOrMapImplEntry final : public MapEntry, public SetEntry { +class SetOrMapImplEntry final : public MapConstEntry, public SetEntry { public: // ---------------------------------------------------------------------- // Public constructors and destructors // ---------------------------------------------------------------------- //! Zero-argument constructor - SetOrMapImplEntry() : MapEntry(), SetEntry() {} + SetOrMapImplEntry() : MapConstEntry(), SetEntry() {} //! Constructor providing members SetOrMapImplEntry(const KE& keyOrElement, //!< The key or element const VN& valueOrNil, //!< The value or Nil const SetOrMapImplEntry* next = nullptr //!< The next entry ) - : MapEntry(), SetEntry(), m_keyOrElement(keyOrElement), m_valueOrNil(valueOrNil), m_next(next) {} + : MapConstEntry(), SetEntry(), m_keyOrElement(keyOrElement), m_valueOrNil(valueOrNil), m_next(next) {} //! Copy constructor SetOrMapImplEntry(const SetOrMapImplEntry& entry) { *this = entry; } From e4792b233a28ef9a855ffa538016cfc92e2ef4e7 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 13 Jul 2025 20:02:53 -0700 Subject: [PATCH 356/458] Revise map interface --- Fw/DataStructures/ArrayMap.hpp | 4 ---- Fw/DataStructures/ExternalArrayMap.hpp | 4 ---- Fw/DataStructures/MapBase.hpp | 4 ---- 3 files changed, 12 deletions(-) diff --git a/Fw/DataStructures/ArrayMap.hpp b/Fw/DataStructures/ArrayMap.hpp index 96ec860e6b7..a2f4c6bfdb3 100644 --- a/Fw/DataStructures/ArrayMap.hpp +++ b/Fw/DataStructures/ArrayMap.hpp @@ -82,10 +82,6 @@ class ArrayMap final : public MapBase { //! \return The capacity FwSizeType getCapacity() const override { return this->m_extMap.getCapacity(); } - //! Get the head map entry for the map - //! \return The map entry - const MapConstEntry* getHeadMapConstEntry() const override { return this->m_extMap.getHeadMapConstEntry(); } - //! Get the size (number of entries) //! \return The size FwSizeType getSize() const override { return this->m_extMap.getSize(); } diff --git a/Fw/DataStructures/ExternalArrayMap.hpp b/Fw/DataStructures/ExternalArrayMap.hpp index 1dcf0ae392e..e3ff803d655 100644 --- a/Fw/DataStructures/ExternalArrayMap.hpp +++ b/Fw/DataStructures/ExternalArrayMap.hpp @@ -102,10 +102,6 @@ class ExternalArrayMap final : public MapBase { //! \return The capacity FwSizeType getCapacity() const override { return this->m_impl.getCapacity(); } - //! Get the head map entry for the map - //! \return The map entry - const MapConstEntry* getHeadMapConstEntry() const override { return this->m_impl.getHeadEntry(); } - //! Get the size (number of entries) //! \return The size FwSizeType getSize() const override { return this->m_impl.getSize(); } diff --git a/Fw/DataStructures/MapBase.hpp b/Fw/DataStructures/MapBase.hpp index 1caf9274530..be92acf4fb4 100644 --- a/Fw/DataStructures/MapBase.hpp +++ b/Fw/DataStructures/MapBase.hpp @@ -94,10 +94,6 @@ class MapBase { //! \return The capacity virtual FwSizeType getCapacity() const = 0; - //! Get the head iterator for the map - //! \return The iterator - virtual const MapConstEntry* getHeadMapConstEntry() const = 0; - //! Get the size (number of items stored in the map) //! \return The size virtual FwSizeType getSize() const = 0; From cc6371d03c8f65fa130212d589812cf4ab3714fe Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 13 Jul 2025 20:04:34 -0700 Subject: [PATCH 357/458] Rename SetOrMapImplEntry to SetOrMapImplConstEntry --- Fw/DataStructures/ArrayMap.hpp | 2 +- Fw/DataStructures/ArraySet.hpp | 2 +- Fw/DataStructures/ArraySetOrMapImpl.hpp | 4 +-- Fw/DataStructures/ExternalArrayMap.hpp | 2 +- Fw/DataStructures/ExternalArraySet.hpp | 2 +- ...plEntry.hpp => SetOrMapImplConstEntry.hpp} | 33 +++++++++++-------- .../SetOrMapImplConstIterator.hpp | 4 +-- Fw/DataStructures/test/ut/ArrayMapTest.cpp | 2 +- .../test/ut/ArraySetOrMapImplTester.hpp | 2 +- Fw/DataStructures/test/ut/ArraySetTest.cpp | 2 +- .../test/ut/ExternalArrayMapTest.cpp | 2 +- .../test/ut/ExternalArraySetTest.cpp | 2 +- .../ut/STest/ArraySetOrMapImplTestState.hpp | 2 +- 13 files changed, 33 insertions(+), 28 deletions(-) rename Fw/DataStructures/{SetOrMapImplEntry.hpp => SetOrMapImplConstEntry.hpp} (71%) diff --git a/Fw/DataStructures/ArrayMap.hpp b/Fw/DataStructures/ArrayMap.hpp index a2f4c6bfdb3..7dd2cdceb83 100644 --- a/Fw/DataStructures/ArrayMap.hpp +++ b/Fw/DataStructures/ArrayMap.hpp @@ -26,7 +26,7 @@ class ArrayMap final : public MapBase { // ---------------------------------------------------------------------- //! The type of an implementation entry - using ImplEntry = SetOrMapImplEntry; + using ImplEntry = SetOrMapImplConstEntry; //! The type of a map entry using MapConstEntry = MapConstEntry; diff --git a/Fw/DataStructures/ArraySet.hpp b/Fw/DataStructures/ArraySet.hpp index 4fcdf6c677f..c18fa192072 100644 --- a/Fw/DataStructures/ArraySet.hpp +++ b/Fw/DataStructures/ArraySet.hpp @@ -26,7 +26,7 @@ class ArraySet final : public SetBase { // ---------------------------------------------------------------------- //! The type of animplementation entry - using ImplEntry = SetOrMapImplEntry; + using ImplEntry = SetOrMapImplConstEntry; //! The type of a set entry using SetEntry = SetEntry; diff --git a/Fw/DataStructures/ArraySetOrMapImpl.hpp b/Fw/DataStructures/ArraySetOrMapImpl.hpp index 2eb84b9005d..0abff9a64ac 100644 --- a/Fw/DataStructures/ArraySetOrMapImpl.hpp +++ b/Fw/DataStructures/ArraySetOrMapImpl.hpp @@ -9,7 +9,7 @@ #include "Fw/DataStructures/ExternalArray.hpp" #include "Fw/DataStructures/SetOrMapImplConstIterator.hpp" -#include "Fw/DataStructures/SetOrMapImplEntry.hpp" +#include "Fw/DataStructures/SetOrMapImplConstEntry.hpp" #include "Fw/Types/Assert.hpp" #include "Fw/Types/SuccessEnumAc.hpp" @@ -30,7 +30,7 @@ class ArraySetOrMapImpl final { // ---------------------------------------------------------------------- //! The type of an entry in the set or map - using Entry = SetOrMapImplEntry; + using Entry = SetOrMapImplConstEntry; //! Const iterator class ConstIterator final : public SetOrMapImplConstIterator { diff --git a/Fw/DataStructures/ExternalArrayMap.hpp b/Fw/DataStructures/ExternalArrayMap.hpp index e3ff803d655..bef9ac36c57 100644 --- a/Fw/DataStructures/ExternalArrayMap.hpp +++ b/Fw/DataStructures/ExternalArrayMap.hpp @@ -28,7 +28,7 @@ class ExternalArrayMap final : public MapBase { // ---------------------------------------------------------------------- //! The type of a map implementation entry - using ImplEntry = SetOrMapImplEntry; + using ImplEntry = SetOrMapImplConstEntry; //! The type of a map entry using MapConstEntry = MapConstEntry; diff --git a/Fw/DataStructures/ExternalArraySet.hpp b/Fw/DataStructures/ExternalArraySet.hpp index 6cbb9827759..bfd632f4d4f 100644 --- a/Fw/DataStructures/ExternalArraySet.hpp +++ b/Fw/DataStructures/ExternalArraySet.hpp @@ -29,7 +29,7 @@ class ExternalArraySet final : public SetBase { // ---------------------------------------------------------------------- //! The type of a set entry - using Entry = SetOrMapImplEntry; + using Entry = SetOrMapImplConstEntry; //! The type of a set iterator using SetEntry = SetEntry; diff --git a/Fw/DataStructures/SetOrMapImplEntry.hpp b/Fw/DataStructures/SetOrMapImplConstEntry.hpp similarity index 71% rename from Fw/DataStructures/SetOrMapImplEntry.hpp rename to Fw/DataStructures/SetOrMapImplConstEntry.hpp index 23660a1c5f2..75a95f0c614 100644 --- a/Fw/DataStructures/SetOrMapImplEntry.hpp +++ b/Fw/DataStructures/SetOrMapImplConstEntry.hpp @@ -1,11 +1,12 @@ // ====================================================================== -// \title SetOrMapImplEntry +// \title SetOrMapImplConstEntry // \author bocchino -// \brief A class template representing an entry for a set or map implementation +// \brief A class template representing a const entry for a set or map +// implementation // ====================================================================== -#ifndef Fw_SetOrMapImplEntry_HPP -#define Fw_SetOrMapImplEntry_HPP +#ifndef Fw_SetOrMapImplConstEntry_HPP +#define Fw_SetOrMapImplConstEntry_HPP #include "Fw/DataStructures/MapConstEntry.hpp" #include "Fw/DataStructures/SetEntry.hpp" @@ -14,27 +15,31 @@ namespace Fw { template -class SetOrMapImplEntry final : public MapConstEntry, public SetEntry { +class SetOrMapImplConstEntry final : public MapConstEntry, public SetEntry { public: // ---------------------------------------------------------------------- // Public constructors and destructors // ---------------------------------------------------------------------- //! Zero-argument constructor - SetOrMapImplEntry() : MapConstEntry(), SetEntry() {} + SetOrMapImplConstEntry() : MapConstEntry(), SetEntry() {} //! Constructor providing members - SetOrMapImplEntry(const KE& keyOrElement, //!< The key or element + SetOrMapImplConstEntry(const KE& keyOrElement, //!< The key or element const VN& valueOrNil, //!< The value or Nil - const SetOrMapImplEntry* next = nullptr //!< The next entry + const SetOrMapImplConstEntry* next = nullptr //!< The next entry ) - : MapConstEntry(), SetEntry(), m_keyOrElement(keyOrElement), m_valueOrNil(valueOrNil), m_next(next) {} + : MapConstEntry(), + SetEntry(), + m_keyOrElement(keyOrElement), + m_valueOrNil(valueOrNil), + m_next(next) {} //! Copy constructor - SetOrMapImplEntry(const SetOrMapImplEntry& entry) { *this = entry; } + SetOrMapImplConstEntry(const SetOrMapImplConstEntry& entry) { *this = entry; } //! Destructor - ~SetOrMapImplEntry() override = default; + ~SetOrMapImplConstEntry() override = default; public: // ---------------------------------------------------------------------- @@ -42,7 +47,7 @@ class SetOrMapImplEntry final : public MapConstEntry, public SetEntry& operator=(const SetOrMapImplEntry& entry) { + SetOrMapImplConstEntry& operator=(const SetOrMapImplConstEntry& entry) { if (this != &entry) { this->m_keyOrElement = entry.m_keyOrElement; this->m_valueOrNil = entry.m_valueOrNil; @@ -82,7 +87,7 @@ class SetOrMapImplEntry final : public MapConstEntry, public SetEntry* next) { this->m_next = next; } + void setNextEntry(const SetOrMapImplConstEntry* next) { this->m_next = next; } //! Set the value or Nil void setValueOrNil(const VN& valueOrNil) { this->m_valueOrNil = valueOrNil; } @@ -99,7 +104,7 @@ class SetOrMapImplEntry final : public MapConstEntry, public SetEntry* m_next = nullptr; + const SetOrMapImplConstEntry* m_next = nullptr; }; } // namespace Fw diff --git a/Fw/DataStructures/SetOrMapImplConstIterator.hpp b/Fw/DataStructures/SetOrMapImplConstIterator.hpp index 0f8b47eda0e..0e249fac19c 100644 --- a/Fw/DataStructures/SetOrMapImplConstIterator.hpp +++ b/Fw/DataStructures/SetOrMapImplConstIterator.hpp @@ -7,7 +7,7 @@ #ifndef Fw_SetOrMapImplConstIterator_HPP #define Fw_SetOrMapImplConstIterator_HPP -#include "Fw/DataStructures/SetOrMapImplEntry.hpp" +#include "Fw/DataStructures/SetOrMapImplConstEntry.hpp" #include "Fw/FPrimeBasicTypes.hpp" namespace Fw { @@ -53,7 +53,7 @@ class SetOrMapImplConstIterator { //! Get the set or map impl entry pointed to by this iterator //! \return The set or map impl entry - virtual const SetOrMapImplEntry& getEntry() const = 0; + virtual const SetOrMapImplConstEntry& getEntry() const = 0; //! Reset the iterator virtual void reset() = 0; diff --git a/Fw/DataStructures/test/ut/ArrayMapTest.cpp b/Fw/DataStructures/test/ut/ArrayMapTest.cpp index 9ae8069954d..a7c3d303a77 100644 --- a/Fw/DataStructures/test/ut/ArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ArrayMapTest.cpp @@ -30,7 +30,7 @@ class ArrayMapTester { namespace MapTest { using ConstIterator = MapConstIterator; -using Entry = SetOrMapImplEntry; +using Entry = SetOrMapImplConstEntry; using Map = ArrayMap; using MapTester = ArrayMapTester; using ImplTester = ArraySetOrMapImplTester; diff --git a/Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp b/Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp index fd5b4726e47..8832be95152 100644 --- a/Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp +++ b/Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp @@ -17,7 +17,7 @@ namespace Fw { template class ArraySetOrMapImplTester { public: - using Entry = SetOrMapImplEntry; + using Entry = SetOrMapImplConstEntry; ArraySetOrMapImplTester(const ArraySetOrMapImpl& impl) : m_impl(impl) {} diff --git a/Fw/DataStructures/test/ut/ArraySetTest.cpp b/Fw/DataStructures/test/ut/ArraySetTest.cpp index d902f0fce9e..858d8c4f114 100644 --- a/Fw/DataStructures/test/ut/ArraySetTest.cpp +++ b/Fw/DataStructures/test/ut/ArraySetTest.cpp @@ -29,7 +29,7 @@ class ArraySetTester { namespace SetTest { -using Entry = SetOrMapImplEntry; +using Entry = SetOrMapImplConstEntry; using Set = ArraySet; using SetTester = ArraySetTester; using ImplTester = ArraySetOrMapImplTester; diff --git a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp index 0d2112e4629..ac12af6e96f 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp @@ -25,7 +25,7 @@ class ExternalArrayMapTester { namespace MapTest { -using Entry = SetOrMapImplEntry; +using Entry = SetOrMapImplConstEntry; using Map = ExternalArrayMap; using MapTester = ExternalArrayMapTester; using ImplTester = ArraySetOrMapImplTester; diff --git a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp index d1c809c4117..74bce91781d 100644 --- a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp @@ -27,7 +27,7 @@ class ExternalArraySetTester { namespace SetTest { -using Entry = SetOrMapImplEntry; +using Entry = SetOrMapImplConstEntry; using Set = ExternalArraySet; using SetTester = ExternalArraySetTester; using ImplTester = ArraySetOrMapImplTester; diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp index 10131e3f9f7..af9e2e7a325 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp @@ -29,7 +29,7 @@ struct State { //! The Tester type using Tester = ArraySetOrMapImplTester; //! The entry type - using Entry = SetOrMapImplEntry; + using Entry = SetOrMapImplConstEntry; //! Constructor State(Impl& a_impl) : impl(a_impl), tester(a_impl) {} //! The array set or map under test From eb016be0b125c7f11608f553fb1223908ef64544 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 13 Jul 2025 20:06:25 -0700 Subject: [PATCH 358/458] Revert "Rename SetOrMapImplEntry to SetOrMapImplConstEntry" This reverts commit cc6371d03c8f65fa130212d589812cf4ab3714fe. --- Fw/DataStructures/ArrayMap.hpp | 2 +- Fw/DataStructures/ArraySet.hpp | 2 +- Fw/DataStructures/ArraySetOrMapImpl.hpp | 4 +-- Fw/DataStructures/ExternalArrayMap.hpp | 2 +- Fw/DataStructures/ExternalArraySet.hpp | 2 +- .../SetOrMapImplConstIterator.hpp | 4 +-- ...plConstEntry.hpp => SetOrMapImplEntry.hpp} | 33 ++++++++----------- Fw/DataStructures/test/ut/ArrayMapTest.cpp | 2 +- .../test/ut/ArraySetOrMapImplTester.hpp | 2 +- Fw/DataStructures/test/ut/ArraySetTest.cpp | 2 +- .../test/ut/ExternalArrayMapTest.cpp | 2 +- .../test/ut/ExternalArraySetTest.cpp | 2 +- .../ut/STest/ArraySetOrMapImplTestState.hpp | 2 +- 13 files changed, 28 insertions(+), 33 deletions(-) rename Fw/DataStructures/{SetOrMapImplConstEntry.hpp => SetOrMapImplEntry.hpp} (71%) diff --git a/Fw/DataStructures/ArrayMap.hpp b/Fw/DataStructures/ArrayMap.hpp index 7dd2cdceb83..a2f4c6bfdb3 100644 --- a/Fw/DataStructures/ArrayMap.hpp +++ b/Fw/DataStructures/ArrayMap.hpp @@ -26,7 +26,7 @@ class ArrayMap final : public MapBase { // ---------------------------------------------------------------------- //! The type of an implementation entry - using ImplEntry = SetOrMapImplConstEntry; + using ImplEntry = SetOrMapImplEntry; //! The type of a map entry using MapConstEntry = MapConstEntry; diff --git a/Fw/DataStructures/ArraySet.hpp b/Fw/DataStructures/ArraySet.hpp index c18fa192072..4fcdf6c677f 100644 --- a/Fw/DataStructures/ArraySet.hpp +++ b/Fw/DataStructures/ArraySet.hpp @@ -26,7 +26,7 @@ class ArraySet final : public SetBase { // ---------------------------------------------------------------------- //! The type of animplementation entry - using ImplEntry = SetOrMapImplConstEntry; + using ImplEntry = SetOrMapImplEntry; //! The type of a set entry using SetEntry = SetEntry; diff --git a/Fw/DataStructures/ArraySetOrMapImpl.hpp b/Fw/DataStructures/ArraySetOrMapImpl.hpp index 0abff9a64ac..2eb84b9005d 100644 --- a/Fw/DataStructures/ArraySetOrMapImpl.hpp +++ b/Fw/DataStructures/ArraySetOrMapImpl.hpp @@ -9,7 +9,7 @@ #include "Fw/DataStructures/ExternalArray.hpp" #include "Fw/DataStructures/SetOrMapImplConstIterator.hpp" -#include "Fw/DataStructures/SetOrMapImplConstEntry.hpp" +#include "Fw/DataStructures/SetOrMapImplEntry.hpp" #include "Fw/Types/Assert.hpp" #include "Fw/Types/SuccessEnumAc.hpp" @@ -30,7 +30,7 @@ class ArraySetOrMapImpl final { // ---------------------------------------------------------------------- //! The type of an entry in the set or map - using Entry = SetOrMapImplConstEntry; + using Entry = SetOrMapImplEntry; //! Const iterator class ConstIterator final : public SetOrMapImplConstIterator { diff --git a/Fw/DataStructures/ExternalArrayMap.hpp b/Fw/DataStructures/ExternalArrayMap.hpp index bef9ac36c57..e3ff803d655 100644 --- a/Fw/DataStructures/ExternalArrayMap.hpp +++ b/Fw/DataStructures/ExternalArrayMap.hpp @@ -28,7 +28,7 @@ class ExternalArrayMap final : public MapBase { // ---------------------------------------------------------------------- //! The type of a map implementation entry - using ImplEntry = SetOrMapImplConstEntry; + using ImplEntry = SetOrMapImplEntry; //! The type of a map entry using MapConstEntry = MapConstEntry; diff --git a/Fw/DataStructures/ExternalArraySet.hpp b/Fw/DataStructures/ExternalArraySet.hpp index bfd632f4d4f..6cbb9827759 100644 --- a/Fw/DataStructures/ExternalArraySet.hpp +++ b/Fw/DataStructures/ExternalArraySet.hpp @@ -29,7 +29,7 @@ class ExternalArraySet final : public SetBase { // ---------------------------------------------------------------------- //! The type of a set entry - using Entry = SetOrMapImplConstEntry; + using Entry = SetOrMapImplEntry; //! The type of a set iterator using SetEntry = SetEntry; diff --git a/Fw/DataStructures/SetOrMapImplConstIterator.hpp b/Fw/DataStructures/SetOrMapImplConstIterator.hpp index 0e249fac19c..0f8b47eda0e 100644 --- a/Fw/DataStructures/SetOrMapImplConstIterator.hpp +++ b/Fw/DataStructures/SetOrMapImplConstIterator.hpp @@ -7,7 +7,7 @@ #ifndef Fw_SetOrMapImplConstIterator_HPP #define Fw_SetOrMapImplConstIterator_HPP -#include "Fw/DataStructures/SetOrMapImplConstEntry.hpp" +#include "Fw/DataStructures/SetOrMapImplEntry.hpp" #include "Fw/FPrimeBasicTypes.hpp" namespace Fw { @@ -53,7 +53,7 @@ class SetOrMapImplConstIterator { //! Get the set or map impl entry pointed to by this iterator //! \return The set or map impl entry - virtual const SetOrMapImplConstEntry& getEntry() const = 0; + virtual const SetOrMapImplEntry& getEntry() const = 0; //! Reset the iterator virtual void reset() = 0; diff --git a/Fw/DataStructures/SetOrMapImplConstEntry.hpp b/Fw/DataStructures/SetOrMapImplEntry.hpp similarity index 71% rename from Fw/DataStructures/SetOrMapImplConstEntry.hpp rename to Fw/DataStructures/SetOrMapImplEntry.hpp index 75a95f0c614..23660a1c5f2 100644 --- a/Fw/DataStructures/SetOrMapImplConstEntry.hpp +++ b/Fw/DataStructures/SetOrMapImplEntry.hpp @@ -1,12 +1,11 @@ // ====================================================================== -// \title SetOrMapImplConstEntry +// \title SetOrMapImplEntry // \author bocchino -// \brief A class template representing a const entry for a set or map -// implementation +// \brief A class template representing an entry for a set or map implementation // ====================================================================== -#ifndef Fw_SetOrMapImplConstEntry_HPP -#define Fw_SetOrMapImplConstEntry_HPP +#ifndef Fw_SetOrMapImplEntry_HPP +#define Fw_SetOrMapImplEntry_HPP #include "Fw/DataStructures/MapConstEntry.hpp" #include "Fw/DataStructures/SetEntry.hpp" @@ -15,31 +14,27 @@ namespace Fw { template -class SetOrMapImplConstEntry final : public MapConstEntry, public SetEntry { +class SetOrMapImplEntry final : public MapConstEntry, public SetEntry { public: // ---------------------------------------------------------------------- // Public constructors and destructors // ---------------------------------------------------------------------- //! Zero-argument constructor - SetOrMapImplConstEntry() : MapConstEntry(), SetEntry() {} + SetOrMapImplEntry() : MapConstEntry(), SetEntry() {} //! Constructor providing members - SetOrMapImplConstEntry(const KE& keyOrElement, //!< The key or element + SetOrMapImplEntry(const KE& keyOrElement, //!< The key or element const VN& valueOrNil, //!< The value or Nil - const SetOrMapImplConstEntry* next = nullptr //!< The next entry + const SetOrMapImplEntry* next = nullptr //!< The next entry ) - : MapConstEntry(), - SetEntry(), - m_keyOrElement(keyOrElement), - m_valueOrNil(valueOrNil), - m_next(next) {} + : MapConstEntry(), SetEntry(), m_keyOrElement(keyOrElement), m_valueOrNil(valueOrNil), m_next(next) {} //! Copy constructor - SetOrMapImplConstEntry(const SetOrMapImplConstEntry& entry) { *this = entry; } + SetOrMapImplEntry(const SetOrMapImplEntry& entry) { *this = entry; } //! Destructor - ~SetOrMapImplConstEntry() override = default; + ~SetOrMapImplEntry() override = default; public: // ---------------------------------------------------------------------- @@ -47,7 +42,7 @@ class SetOrMapImplConstEntry final : public MapConstEntry, public SetEnt // ---------------------------------------------------------------------- //! operator= - SetOrMapImplConstEntry& operator=(const SetOrMapImplConstEntry& entry) { + SetOrMapImplEntry& operator=(const SetOrMapImplEntry& entry) { if (this != &entry) { this->m_keyOrElement = entry.m_keyOrElement; this->m_valueOrNil = entry.m_valueOrNil; @@ -87,7 +82,7 @@ class SetOrMapImplConstEntry final : public MapConstEntry, public SetEnt } //! Set the next entry - void setNextEntry(const SetOrMapImplConstEntry* next) { this->m_next = next; } + void setNextEntry(const SetOrMapImplEntry* next) { this->m_next = next; } //! Set the value or Nil void setValueOrNil(const VN& valueOrNil) { this->m_valueOrNil = valueOrNil; } @@ -104,7 +99,7 @@ class SetOrMapImplConstEntry final : public MapConstEntry, public SetEnt VN m_valueOrNil = {}; //! Pointer to the next entry or nullptr if none - const SetOrMapImplConstEntry* m_next = nullptr; + const SetOrMapImplEntry* m_next = nullptr; }; } // namespace Fw diff --git a/Fw/DataStructures/test/ut/ArrayMapTest.cpp b/Fw/DataStructures/test/ut/ArrayMapTest.cpp index a7c3d303a77..9ae8069954d 100644 --- a/Fw/DataStructures/test/ut/ArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ArrayMapTest.cpp @@ -30,7 +30,7 @@ class ArrayMapTester { namespace MapTest { using ConstIterator = MapConstIterator; -using Entry = SetOrMapImplConstEntry; +using Entry = SetOrMapImplEntry; using Map = ArrayMap; using MapTester = ArrayMapTester; using ImplTester = ArraySetOrMapImplTester; diff --git a/Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp b/Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp index 8832be95152..fd5b4726e47 100644 --- a/Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp +++ b/Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp @@ -17,7 +17,7 @@ namespace Fw { template class ArraySetOrMapImplTester { public: - using Entry = SetOrMapImplConstEntry; + using Entry = SetOrMapImplEntry; ArraySetOrMapImplTester(const ArraySetOrMapImpl& impl) : m_impl(impl) {} diff --git a/Fw/DataStructures/test/ut/ArraySetTest.cpp b/Fw/DataStructures/test/ut/ArraySetTest.cpp index 858d8c4f114..d902f0fce9e 100644 --- a/Fw/DataStructures/test/ut/ArraySetTest.cpp +++ b/Fw/DataStructures/test/ut/ArraySetTest.cpp @@ -29,7 +29,7 @@ class ArraySetTester { namespace SetTest { -using Entry = SetOrMapImplConstEntry; +using Entry = SetOrMapImplEntry; using Set = ArraySet; using SetTester = ArraySetTester; using ImplTester = ArraySetOrMapImplTester; diff --git a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp index ac12af6e96f..0d2112e4629 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp @@ -25,7 +25,7 @@ class ExternalArrayMapTester { namespace MapTest { -using Entry = SetOrMapImplConstEntry; +using Entry = SetOrMapImplEntry; using Map = ExternalArrayMap; using MapTester = ExternalArrayMapTester; using ImplTester = ArraySetOrMapImplTester; diff --git a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp index 74bce91781d..d1c809c4117 100644 --- a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp @@ -27,7 +27,7 @@ class ExternalArraySetTester { namespace SetTest { -using Entry = SetOrMapImplConstEntry; +using Entry = SetOrMapImplEntry; using Set = ExternalArraySet; using SetTester = ExternalArraySetTester; using ImplTester = ArraySetOrMapImplTester; diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp index af9e2e7a325..10131e3f9f7 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp @@ -29,7 +29,7 @@ struct State { //! The Tester type using Tester = ArraySetOrMapImplTester; //! The entry type - using Entry = SetOrMapImplConstEntry; + using Entry = SetOrMapImplEntry; //! Constructor State(Impl& a_impl) : impl(a_impl), tester(a_impl) {} //! The array set or map under test From bd582c5920219c4e6d20e0ac999adc09636fa16d Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 13 Jul 2025 20:08:09 -0700 Subject: [PATCH 359/458] Rename SetEntry to SetConstEntry --- Fw/DataStructures/ArraySet.hpp | 4 +-- Fw/DataStructures/ExternalArraySet.hpp | 4 +-- Fw/DataStructures/SetBase.hpp | 10 +++---- .../{SetEntry.hpp => SetConstEntry.hpp} | 26 +++++++++---------- Fw/DataStructures/SetOrMapImplEntry.hpp | 10 +++---- .../test/ut/STest/SetTestRules.hpp | 12 ++++----- 6 files changed, 33 insertions(+), 33 deletions(-) rename Fw/DataStructures/{SetEntry.hpp => SetConstEntry.hpp} (72%) diff --git a/Fw/DataStructures/ArraySet.hpp b/Fw/DataStructures/ArraySet.hpp index 4fcdf6c677f..81c3b84b5c4 100644 --- a/Fw/DataStructures/ArraySet.hpp +++ b/Fw/DataStructures/ArraySet.hpp @@ -29,7 +29,7 @@ class ArraySet final : public SetBase { using ImplEntry = SetOrMapImplEntry; //! The type of a set entry - using SetEntry = SetEntry; + using SetConstEntry = SetConstEntry; //! The type of the implementation entries using ImplEntries = ImplEntry[C]; @@ -75,7 +75,7 @@ class ArraySet final : public SetBase { //! Get the head set entry for the set //! \return The set entry - const SetEntry* getHeadSetEntry() const override { return this->m_extSet.getHeadSetEntry(); } + const SetConstEntry* getHeadSetConstEntry() const override { return this->m_extSet.getHeadSetConstEntry(); } //! Get the size (number of entries) //! \return The size diff --git a/Fw/DataStructures/ExternalArraySet.hpp b/Fw/DataStructures/ExternalArraySet.hpp index 6cbb9827759..f5268eb9241 100644 --- a/Fw/DataStructures/ExternalArraySet.hpp +++ b/Fw/DataStructures/ExternalArraySet.hpp @@ -32,7 +32,7 @@ class ExternalArraySet final : public SetBase { using Entry = SetOrMapImplEntry; //! The type of a set iterator - using SetEntry = SetEntry; + using SetConstEntry = SetConstEntry; public: // ---------------------------------------------------------------------- @@ -97,7 +97,7 @@ class ExternalArraySet final : public SetBase { //! Get the head set entry for the set //! \return The set entry - const SetEntry* getHeadSetEntry() const override { return this->m_impl.getHeadEntry(); } + const SetConstEntry* getHeadSetConstEntry() const override { return this->m_impl.getHeadEntry(); } //! Get the size (number of entries) //! \return The size diff --git a/Fw/DataStructures/SetBase.hpp b/Fw/DataStructures/SetBase.hpp index 0861a723735..59e29e05def 100644 --- a/Fw/DataStructures/SetBase.hpp +++ b/Fw/DataStructures/SetBase.hpp @@ -7,7 +7,7 @@ #ifndef Fw_SetBase_HPP #define Fw_SetBase_HPP -#include "Fw/DataStructures/SetEntry.hpp" +#include "Fw/DataStructures/SetConstEntry.hpp" #include "Fw/Types/Assert.hpp" #include "Fw/Types/SuccessEnumAc.hpp" @@ -21,7 +21,7 @@ class SetBase { // ---------------------------------------------------------------------- //! The type of a set entry - using SetEntry = SetEntry; + using SetConstEntry = SetConstEntry; private: // ---------------------------------------------------------------------- @@ -65,13 +65,13 @@ class SetBase { void copyDataFrom(const SetBase& set) { if (&set != this) { this->clear(); - const auto* e = set.getHeadSetEntry(); + const auto* e = set.getHeadSetConstEntry(); const FwSizeType size = FW_MIN(set.getSize(), this->getCapacity()); for (FwSizeType i = 0; i < size; i++) { FW_ASSERT(e != nullptr); const auto status = this->insert(e->getElement()); FW_ASSERT(status == Success::SUCCESS, static_cast(status)); - e = e->getNextSetEntry(); + e = e->getNextSetConstEntry(); } } } @@ -87,7 +87,7 @@ class SetBase { //! Get the head set entry for the set //! \return The set entry - virtual const SetEntry* getHeadSetEntry() const = 0; + virtual const SetConstEntry* getHeadSetConstEntry() const = 0; //! Get the size (number of items stored in the set) //! \return The size diff --git a/Fw/DataStructures/SetEntry.hpp b/Fw/DataStructures/SetConstEntry.hpp similarity index 72% rename from Fw/DataStructures/SetEntry.hpp rename to Fw/DataStructures/SetConstEntry.hpp index 768a07f5b00..e60c39566c1 100644 --- a/Fw/DataStructures/SetEntry.hpp +++ b/Fw/DataStructures/SetConstEntry.hpp @@ -1,18 +1,18 @@ // ====================================================================== -// \title SetEntry +// \title SetConstEntry // \author bocchino -// \brief An abstract class template representing an iterator for a set +// \brief An abstract class template representing a const entry for a set // ====================================================================== -#ifndef Fw_SetEntry_HPP -#define Fw_SetEntry_HPP +#ifndef Fw_SetConstEntry_HPP +#define Fw_SetConstEntry_HPP #include "Fw/FPrimeBasicTypes.hpp" namespace Fw { template -class SetEntry { +class SetConstEntry { private: // ---------------------------------------------------------------------- // Private constructors @@ -20,7 +20,7 @@ class SetEntry { //! Copy constructor deleted in the base class //! Behavior depends on the implementation - SetEntry(const SetEntry&) = delete; + SetConstEntry(const SetConstEntry&) = delete; protected: // ---------------------------------------------------------------------- @@ -28,10 +28,10 @@ class SetEntry { // ---------------------------------------------------------------------- //! Zero-argument constructor - SetEntry() {} + SetConstEntry() {} //! Destructor - virtual ~SetEntry() = default; + virtual ~SetConstEntry() = default; private: // ---------------------------------------------------------------------- @@ -41,20 +41,20 @@ class SetEntry { //! operator= deleted in the base class //! Behavior depends on the implementation //! We avoid virtual user-defined operators - SetEntry& operator=(const SetEntry&) = delete; + SetConstEntry& operator=(const SetConstEntry&) = delete; public: // ---------------------------------------------------------------------- // Public member functions // ---------------------------------------------------------------------- - //! Get the element associated with this iterator + //! Get the element associated with this entry //! \return The element virtual const T& getElement() const = 0; - //! Get the next set iterator - //! \return The set iterator, or nullptr if none - virtual const SetEntry* getNextSetEntry() const = 0; + //! Get the next set entry + //! \return The set entry, or nullptr if none + virtual const SetConstEntry* getNextSetConstEntry() const = 0; }; } // namespace Fw diff --git a/Fw/DataStructures/SetOrMapImplEntry.hpp b/Fw/DataStructures/SetOrMapImplEntry.hpp index 23660a1c5f2..9fa3677f45e 100644 --- a/Fw/DataStructures/SetOrMapImplEntry.hpp +++ b/Fw/DataStructures/SetOrMapImplEntry.hpp @@ -8,27 +8,27 @@ #define Fw_SetOrMapImplEntry_HPP #include "Fw/DataStructures/MapConstEntry.hpp" -#include "Fw/DataStructures/SetEntry.hpp" +#include "Fw/DataStructures/SetConstEntry.hpp" #include "Fw/FPrimeBasicTypes.hpp" namespace Fw { template -class SetOrMapImplEntry final : public MapConstEntry, public SetEntry { +class SetOrMapImplEntry final : public MapConstEntry, public SetConstEntry { public: // ---------------------------------------------------------------------- // Public constructors and destructors // ---------------------------------------------------------------------- //! Zero-argument constructor - SetOrMapImplEntry() : MapConstEntry(), SetEntry() {} + SetOrMapImplEntry() : MapConstEntry(), SetConstEntry() {} //! Constructor providing members SetOrMapImplEntry(const KE& keyOrElement, //!< The key or element const VN& valueOrNil, //!< The value or Nil const SetOrMapImplEntry* next = nullptr //!< The next entry ) - : MapConstEntry(), SetEntry(), m_keyOrElement(keyOrElement), m_valueOrNil(valueOrNil), m_next(next) {} + : MapConstEntry(), SetConstEntry(), m_keyOrElement(keyOrElement), m_valueOrNil(valueOrNil), m_next(next) {} //! Copy constructor SetOrMapImplEntry(const SetOrMapImplEntry& entry) { *this = entry; } @@ -73,7 +73,7 @@ class SetOrMapImplEntry final : public MapConstEntry, public SetEntry* getNextSetEntry() const override { return this->m_next; } + const SetConstEntry* getNextSetConstEntry() const override { return this->m_next; } //! Set the key or element void setKeyOrElement(const KE& keyOrElement //!< The key or element diff --git a/Fw/DataStructures/test/ut/STest/SetTestRules.hpp b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp index 93386891a00..8d01fb7f9c5 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp @@ -50,12 +50,12 @@ struct FindExisting : public Rule { ASSERT_EQ(size, modelSize); // Check that all elements of set are in modelSet { - const auto* entry = state.set.getHeadSetEntry(); + const auto* entry = state.set.getHeadSetConstEntry(); for (FwSizeType i = 0; i < size; i++) { ASSERT_NE(entry, nullptr); const auto e = entry->getElement(); ASSERT_TRUE(state.modelSetContains(e)); - entry = entry->getNextSetEntry(); + entry = entry->getNextSetConstEntry(); } } // Check that all elements of modelSet are in set @@ -77,10 +77,10 @@ struct InsertExisting : public Rule { void action(State& state) { const auto size = state.set.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); - const auto* entry = state.set.getHeadSetEntry(); + const auto* entry = state.set.getHeadSetConstEntry(); for (FwSizeType i = 0; i < index; i++) { ASSERT_NE(entry, nullptr); - entry = entry->getNextSetEntry(); + entry = entry->getNextSetConstEntry(); } ASSERT_NE(entry, nullptr); const auto e = entry->getElement(); @@ -143,10 +143,10 @@ struct RemoveExisting : public Rule { void action(State& state) { const auto size = state.set.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); - const auto* entry = state.set.getHeadSetEntry(); + const auto* entry = state.set.getHeadSetConstEntry(); for (FwSizeType i = 0; i < index; i++) { ASSERT_NE(entry, nullptr); - entry = entry->getNextSetEntry(); + entry = entry->getNextSetConstEntry(); } ASSERT_NE(entry, nullptr); const auto e = entry->getElement(); From 157ed34e073a6aff35c5aec66a4f29379fe19a5c Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 13 Jul 2025 20:23:17 -0700 Subject: [PATCH 360/458] Add SetConstIterator --- Fw/DataStructures/MapBase.hpp | 2 +- Fw/DataStructures/MapConstIterator.hpp | 2 +- Fw/DataStructures/SetBase.hpp | 1 + Fw/DataStructures/SetConstIterator.hpp | 112 +++++++++++++++++++++++++ 4 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 Fw/DataStructures/SetConstIterator.hpp diff --git a/Fw/DataStructures/MapBase.hpp b/Fw/DataStructures/MapBase.hpp index be92acf4fb4..18049e0b340 100644 --- a/Fw/DataStructures/MapBase.hpp +++ b/Fw/DataStructures/MapBase.hpp @@ -7,8 +7,8 @@ #ifndef Fw_MapBase_HPP #define Fw_MapBase_HPP -#include "Fw/DataStructures/MapConstIterator.hpp" #include "Fw/DataStructures/MapConstEntry.hpp" +#include "Fw/DataStructures/MapConstIterator.hpp" #include "Fw/Types/Assert.hpp" #include "Fw/Types/SuccessEnumAc.hpp" diff --git a/Fw/DataStructures/MapConstIterator.hpp b/Fw/DataStructures/MapConstIterator.hpp index 838b9db02f6..0ef50e9c700 100644 --- a/Fw/DataStructures/MapConstIterator.hpp +++ b/Fw/DataStructures/MapConstIterator.hpp @@ -1,7 +1,7 @@ // ====================================================================== // \title MapConstIterator // \author bocchino -// \brief An abstract class template representing an iterator for a map +// \brief An abstract class template representing a const iterator for a map // ====================================================================== #ifndef Fw_MapConstIterator_HPP diff --git a/Fw/DataStructures/SetBase.hpp b/Fw/DataStructures/SetBase.hpp index 59e29e05def..fb84c291643 100644 --- a/Fw/DataStructures/SetBase.hpp +++ b/Fw/DataStructures/SetBase.hpp @@ -8,6 +8,7 @@ #define Fw_SetBase_HPP #include "Fw/DataStructures/SetConstEntry.hpp" +#include "Fw/DataStructures/SetConstIterator.hpp" #include "Fw/Types/Assert.hpp" #include "Fw/Types/SuccessEnumAc.hpp" diff --git a/Fw/DataStructures/SetConstIterator.hpp b/Fw/DataStructures/SetConstIterator.hpp new file mode 100644 index 00000000000..ded1c854d44 --- /dev/null +++ b/Fw/DataStructures/SetConstIterator.hpp @@ -0,0 +1,112 @@ +// ====================================================================== +// \title SetConstIterator +// \author bocchino +// \brief An abstract class template representing a const iterator for a set +// ====================================================================== + +#ifndef Fw_SetConstIterator_HPP +#define Fw_SetConstIterator_HPP + +#include "Fw/DataStructures/ArraySetOrMapImpl.hpp" +#include "Fw/DataStructures/Nil.hpp" +#include "Fw/DataStructures/SetConstEntry.hpp" +#include "Fw/FPrimeBasicTypes.hpp" + +namespace Fw { + +template +class SetConstIterator { + public: + //! The type of an array iterator + using ArrayIterator = typename ArraySetOrMapImpl::ConstIterator; + + private: + //! The type of an implementation kind + enum class ImplKind { ARRAY, RED_BLACK_TREE }; + + //! The type of an implementation + union Impl { + Impl(const ArrayIterator& it) : array(it) {} + //! An array iterator + ArrayIterator array; + // TODO: Add red-black tree implementation + ~Impl() {} + }; + + public: + //! Constructor providing an array implementation + SetConstIterator(const ArrayIterator& it) : m_implKind(ImplKind::ARRAY), m_impl(it), m_implIterator(m_impl.array) {} + + //! Copy constructor + SetConstIterator(const SetConstIterator& it) + : m_implKind(it.m_implKind), m_impl(it.m_impl.array), m_implIterator(it.m_implIterator) { + // TODO: Handle tree case + } + + //! Destructor + ~SetConstIterator() {} + + public: + //! Copy assignment operator + SetConstIterator& operator=(const SetConstIterator&) = default; + + //! Equality comparison operator + bool operator==(const SetConstIterator& it) { + bool result = false; + switch (this->m_implKind) { + case ImplKind::ARRAY: + result = this->m_impl.array.compareEqual(it.m_impl.array); + break; + case ImplKind::RED_BLACK_TREE: + // TODO + break; + default: + FW_ASSERT(0, static_cast(this->m_implKind)); + break; + } + return result; + } + + //! Inequality comparison operator + bool operator!=(const SetConstIterator& it) { return !(*this == it); }; + + //! Prefix increment + SetConstIterator& operator++() { + this->m_implIterator.increment(); + return *this; + } + + //! Prefix increment + SetConstIterator operator++(int) { SetConstIterator tmp = *this; ++(*this); return tmp; } + + //! Postfix increment + void increment() { + this->m_implIterator.increment(); + } + + //! Check whether the iterator is in range + bool isInRange() const { return this->m_implIterator.isInRange(); } + + //! Reset the iterator + void reset() { return this->m_implIterator.reset(); } + + //! Dereference + const SetConstEntry& operator*() const { return this->m_implIterator.getEntry(); } + + //! Pointer + const SetConstEntry* operator->() const { return &this->m_implIterator.getEntry(); } + + private: + //! The implementation kind + ImplKind m_implKind; + + //! The implementation + Impl m_impl; + + //! The impl iterator + SetOrMapImplConstIterator& m_implIterator; +}; + +} // namespace Fw + +#endif From 346a8898a9c39258910202760ec12915147ddc00 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 13 Jul 2025 20:36:34 -0700 Subject: [PATCH 361/458] Revise SetBase and unit tests Use iterators --- Fw/DataStructures/ArraySet.hpp | 8 ++++++ Fw/DataStructures/ExternalArraySet.hpp | 8 ++++++ Fw/DataStructures/SetBase.hpp | 15 +++++++--- .../test/ut/STest/SetTestRules.hpp | 28 +++++++++---------- 4 files changed, 41 insertions(+), 18 deletions(-) diff --git a/Fw/DataStructures/ArraySet.hpp b/Fw/DataStructures/ArraySet.hpp index 81c3b84b5c4..2a779247c34 100644 --- a/Fw/DataStructures/ArraySet.hpp +++ b/Fw/DataStructures/ArraySet.hpp @@ -59,9 +59,17 @@ class ArraySet final : public SetBase { return *this; } + //! Get the begin iterator + //! \return The iterator + SetConstIterator begin() const override { return this->m_extSet.begin(); } + //! Clear the set void clear() override { this->m_extSet.clear(); } + //! Get the end iterator + //! \return The iterator + SetConstIterator end() const override { return this->m_extSet.end(); } + //! Find an element in the set //! \return SUCCESS if the element was found Success find(const T& element //!< The element diff --git a/Fw/DataStructures/ExternalArraySet.hpp b/Fw/DataStructures/ExternalArraySet.hpp index f5268eb9241..e16fd870e09 100644 --- a/Fw/DataStructures/ExternalArraySet.hpp +++ b/Fw/DataStructures/ExternalArraySet.hpp @@ -80,9 +80,17 @@ class ExternalArraySet final : public SetBase { return *this; } + //! Get the begin iterator + //! \return The iterator + SetConstIterator begin() const override { return SetConstIterator(this->m_impl.begin()); } + //! Clear the set void clear() override { this->m_impl.clear(); } + //! Get the end iterator + //! \return The iterator + SetConstIterator end() const override { return SetConstIterator(this->m_impl.end()); } + //! Find a value associated with an element in the set //! \return SUCCESS if the item was found Success find(const T& element //!< The element diff --git a/Fw/DataStructures/SetBase.hpp b/Fw/DataStructures/SetBase.hpp index fb84c291643..1a11e833ee0 100644 --- a/Fw/DataStructures/SetBase.hpp +++ b/Fw/DataStructures/SetBase.hpp @@ -59,20 +59,27 @@ class SetBase { // Public member functions // ---------------------------------------------------------------------- + //! Get the begin iterator + //! \return The iterator + virtual SetConstIterator begin() const = 0; + //! Clear the set virtual void clear() = 0; + //! Get the end iterator + //! \return The iterator + virtual SetConstIterator end() const = 0; + //! Copy data from another set void copyDataFrom(const SetBase& set) { if (&set != this) { this->clear(); - const auto* e = set.getHeadSetConstEntry(); const FwSizeType size = FW_MIN(set.getSize(), this->getCapacity()); + auto it = set.begin(); for (FwSizeType i = 0; i < size; i++) { - FW_ASSERT(e != nullptr); - const auto status = this->insert(e->getElement()); + const auto status = this->insert(it->getElement()); FW_ASSERT(status == Success::SUCCESS, static_cast(status)); - e = e->getNextSetConstEntry(); + it++; } } } diff --git a/Fw/DataStructures/test/ut/STest/SetTestRules.hpp b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp index 8d01fb7f9c5..c857660977b 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp @@ -50,12 +50,12 @@ struct FindExisting : public Rule { ASSERT_EQ(size, modelSize); // Check that all elements of set are in modelSet { - const auto* entry = state.set.getHeadSetConstEntry(); + auto it = state.set.begin(); for (FwSizeType i = 0; i < size; i++) { - ASSERT_NE(entry, nullptr); - const auto e = entry->getElement(); + ASSERT_TRUE(it.isInRange()); + const auto e = it->getElement(); ASSERT_TRUE(state.modelSetContains(e)); - entry = entry->getNextSetConstEntry(); + it++; } } // Check that all elements of modelSet are in set @@ -77,13 +77,13 @@ struct InsertExisting : public Rule { void action(State& state) { const auto size = state.set.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); - const auto* entry = state.set.getHeadSetConstEntry(); + auto it = state.set.begin(); for (FwSizeType i = 0; i < index; i++) { - ASSERT_NE(entry, nullptr); - entry = entry->getNextSetConstEntry(); + ASSERT_TRUE(it.isInRange()); + it++; } - ASSERT_NE(entry, nullptr); - const auto e = entry->getElement(); + ASSERT_TRUE(it.isInRange()); + const auto e = it->getElement(); const auto status = state.set.insert(e); ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(state.set.getSize(), size); @@ -143,13 +143,13 @@ struct RemoveExisting : public Rule { void action(State& state) { const auto size = state.set.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); - const auto* entry = state.set.getHeadSetConstEntry(); + auto it = state.set.begin(); for (FwSizeType i = 0; i < index; i++) { - ASSERT_NE(entry, nullptr); - entry = entry->getNextSetConstEntry(); + ASSERT_TRUE(it.isInRange()); + it++; } - ASSERT_NE(entry, nullptr); - const auto e = entry->getElement(); + ASSERT_TRUE(it.isInRange()); + const auto e = it->getElement(); const auto status = state.set.remove(e); ASSERT_EQ(status, Success::SUCCESS); const auto n = state.modelSet.erase(e); From 8b70d13b143524e5078a31227e3cd537fbc85a67 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 13 Jul 2025 20:38:41 -0700 Subject: [PATCH 362/458] Revise set interface --- Fw/DataStructures/ArraySet.hpp | 4 ---- Fw/DataStructures/ArraySetOrMapImpl.hpp | 10 ---------- Fw/DataStructures/ExternalArraySet.hpp | 8 ++------ Fw/DataStructures/SetBase.hpp | 4 ---- 4 files changed, 2 insertions(+), 24 deletions(-) diff --git a/Fw/DataStructures/ArraySet.hpp b/Fw/DataStructures/ArraySet.hpp index 2a779247c34..d140e15a54a 100644 --- a/Fw/DataStructures/ArraySet.hpp +++ b/Fw/DataStructures/ArraySet.hpp @@ -81,10 +81,6 @@ class ArraySet final : public SetBase { //! \return The capacity FwSizeType getCapacity() const override { return this->m_extSet.getCapacity(); } - //! Get the head set entry for the set - //! \return The set entry - const SetConstEntry* getHeadSetConstEntry() const override { return this->m_extSet.getHeadSetConstEntry(); } - //! Get the size (number of entries) //! \return The size FwSizeType getSize() const override { return this->m_extSet.getSize(); } diff --git a/Fw/DataStructures/ArraySetOrMapImpl.hpp b/Fw/DataStructures/ArraySetOrMapImpl.hpp index 2eb84b9005d..f35934f0813 100644 --- a/Fw/DataStructures/ArraySetOrMapImpl.hpp +++ b/Fw/DataStructures/ArraySetOrMapImpl.hpp @@ -174,16 +174,6 @@ class ArraySetOrMapImpl final { //! \return The capacity FwSizeType getCapacity() const { return this->m_entries.getSize(); } - //! Get the head iterator for the set or map - //! \return The iterator - const Entry* getHeadEntry() const { - const Entry* result = nullptr; - if (this->m_size > 0) { - result = &this->m_entries[0]; - } - return result; - } - //! Get the size (number of entries) //! \return The size FwSizeType getSize() const { return this->m_size; } diff --git a/Fw/DataStructures/ExternalArraySet.hpp b/Fw/DataStructures/ExternalArraySet.hpp index e16fd870e09..46a3380c356 100644 --- a/Fw/DataStructures/ExternalArraySet.hpp +++ b/Fw/DataStructures/ExternalArraySet.hpp @@ -103,10 +103,6 @@ class ExternalArraySet final : public SetBase { //! \return The capacity FwSizeType getCapacity() const override { return this->m_impl.getCapacity(); } - //! Get the head set entry for the set - //! \return The set entry - const SetConstEntry* getHeadSetConstEntry() const override { return this->m_impl.getHeadEntry(); } - //! Get the size (number of entries) //! \return The size FwSizeType getSize() const override { return this->m_impl.getSize(); } @@ -114,14 +110,14 @@ class ExternalArraySet final : public SetBase { //! Insert an element in the set //! \return SUCCESS if there is room in the set Success insert(const T& element //!< The element - ) override { + ) override { return this->m_impl.insert(element, Nil()); } //! Remove an element from the set //! \return SUCCESS if the element was there Success remove(const T& element //!< The element - ) override { + ) override { Nil nil = {}; return this->m_impl.remove(element, nil); } diff --git a/Fw/DataStructures/SetBase.hpp b/Fw/DataStructures/SetBase.hpp index 1a11e833ee0..d4c77940730 100644 --- a/Fw/DataStructures/SetBase.hpp +++ b/Fw/DataStructures/SetBase.hpp @@ -93,10 +93,6 @@ class SetBase { //! \return The capacity virtual FwSizeType getCapacity() const = 0; - //! Get the head set entry for the set - //! \return The set entry - virtual const SetConstEntry* getHeadSetConstEntry() const = 0; - //! Get the size (number of items stored in the set) //! \return The size virtual FwSizeType getSize() const = 0; From c9114fbc53c27631ddb04362e8682b78a39988ea Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 13 Jul 2025 20:43:34 -0700 Subject: [PATCH 363/458] Revise comments --- Fw/DataStructures/MapConstIterator.hpp | 12 ++++++++++++ Fw/DataStructures/SetConstIterator.hpp | 21 +++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/Fw/DataStructures/MapConstIterator.hpp b/Fw/DataStructures/MapConstIterator.hpp index 0ef50e9c700..f1ae8535020 100644 --- a/Fw/DataStructures/MapConstIterator.hpp +++ b/Fw/DataStructures/MapConstIterator.hpp @@ -16,10 +16,18 @@ namespace Fw { template class MapConstIterator { public: + // ---------------------------------------------------------------------- + // Public + // ---------------------------------------------------------------------- + //! The type of an array iterator using ArrayIterator = typename ArraySetOrMapImpl::ConstIterator; private: + // ---------------------------------------------------------------------- + // Private types + // ---------------------------------------------------------------------- + //! The type of an implementation kind enum class ImplKind { ARRAY, RED_BLACK_TREE }; @@ -33,6 +41,10 @@ class MapConstIterator { }; public: + // ---------------------------------------------------------------------- + // Constructors and destructors + // ---------------------------------------------------------------------- + //! Constructor providing an array implementation MapConstIterator(const ArrayIterator& it) : m_implKind(ImplKind::ARRAY), m_impl(it), m_implIterator(m_impl.array) {} diff --git a/Fw/DataStructures/SetConstIterator.hpp b/Fw/DataStructures/SetConstIterator.hpp index ded1c854d44..bd7f59a9355 100644 --- a/Fw/DataStructures/SetConstIterator.hpp +++ b/Fw/DataStructures/SetConstIterator.hpp @@ -16,11 +16,20 @@ namespace Fw { template class SetConstIterator { + public: + // ---------------------------------------------------------------------- + // Public types + // ---------------------------------------------------------------------- + //! The type of an array iterator using ArrayIterator = typename ArraySetOrMapImpl::ConstIterator; private: + // ---------------------------------------------------------------------- + // Private types + // ---------------------------------------------------------------------- + //! The type of an implementation kind enum class ImplKind { ARRAY, RED_BLACK_TREE }; @@ -34,6 +43,10 @@ class SetConstIterator { }; public: + // ---------------------------------------------------------------------- + // Constructors and destructors + // ---------------------------------------------------------------------- + //! Constructor providing an array implementation SetConstIterator(const ArrayIterator& it) : m_implKind(ImplKind::ARRAY), m_impl(it), m_implIterator(m_impl.array) {} @@ -47,6 +60,10 @@ class SetConstIterator { ~SetConstIterator() {} public: + // ---------------------------------------------------------------------- + // Public member functions + // ---------------------------------------------------------------------- + //! Copy assignment operator SetConstIterator& operator=(const SetConstIterator&) = default; @@ -97,6 +114,10 @@ class SetConstIterator { const SetConstEntry* operator->() const { return &this->m_implIterator.getEntry(); } private: + // ---------------------------------------------------------------------- + // Private member variables + // ---------------------------------------------------------------------- + //! The implementation kind ImplKind m_implKind; From 3071630fc9f9d267fc00a83a3052500d9a79a547 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 13 Jul 2025 20:44:21 -0700 Subject: [PATCH 364/458] Reformat code --- Fw/DataStructures/ExternalArray.hpp | 4 +--- Fw/DataStructures/ExternalFifoQueue.hpp | 6 ++---- Fw/DataStructures/FifoQueueBase.hpp | 1 - Fw/DataStructures/MapConstIterator.hpp | 12 +++++++----- Fw/DataStructures/SetConstIterator.hpp | 13 +++++++------ Fw/DataStructures/SetOrMapImplConstIterator.hpp | 2 -- Fw/DataStructures/SetOrMapImplEntry.hpp | 6 +++++- 7 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Fw/DataStructures/ExternalArray.hpp b/Fw/DataStructures/ExternalArray.hpp index 3e89ebf41bd..e55a5d3816c 100644 --- a/Fw/DataStructures/ExternalArray.hpp +++ b/Fw/DataStructures/ExternalArray.hpp @@ -131,9 +131,7 @@ class ExternalArray final { //! Get the alignment of the storage for an ExternalArray //! \return The alignment - static constexpr U8 getByteArrayAlignment() { - return alignof(T); - } + static constexpr U8 getByteArrayAlignment() { return alignof(T); } //! Get the size of the storage for an ExternalArray of the specified size, //! as a byte array diff --git a/Fw/DataStructures/ExternalFifoQueue.hpp b/Fw/DataStructures/ExternalFifoQueue.hpp index 4393f99fc08..74938f82482 100644 --- a/Fw/DataStructures/ExternalFifoQueue.hpp +++ b/Fw/DataStructures/ExternalFifoQueue.hpp @@ -157,11 +157,9 @@ class ExternalFifoQueue final : public FifoQueueBase { //! Get the alignment of the storage for an ExternalFifoQueue //! \return The alignment - static constexpr U8 getByteArrayAlignment() { - return ExternalArray::getByteArrayAlignment(); - } + static constexpr U8 getByteArrayAlignment() { return ExternalArray::getByteArrayAlignment(); } - //! Get the size of the storage for an ExternalFifoQueue of the specified + //! Get the size of the storage for an ExternalFifoQueue of the specified //! capacity, as a byte array //! \return The byte array size static constexpr FwSizeType getByteArraySize(FwSizeType capacity //!< The capacity diff --git a/Fw/DataStructures/FifoQueueBase.hpp b/Fw/DataStructures/FifoQueueBase.hpp index c151b643636..17a124dcd5a 100644 --- a/Fw/DataStructures/FifoQueueBase.hpp +++ b/Fw/DataStructures/FifoQueueBase.hpp @@ -105,7 +105,6 @@ class FifoQueueBase { //! Get the capacity (maximum number of items stored in the queue) //! \return The capacity virtual FwSizeType getCapacity() const = 0; - }; } // namespace Fw diff --git a/Fw/DataStructures/MapConstIterator.hpp b/Fw/DataStructures/MapConstIterator.hpp index f1ae8535020..af1d26c156a 100644 --- a/Fw/DataStructures/MapConstIterator.hpp +++ b/Fw/DataStructures/MapConstIterator.hpp @@ -51,7 +51,7 @@ class MapConstIterator { //! Copy constructor MapConstIterator(const MapConstIterator& it) : m_implKind(it.m_implKind), m_impl(it.m_impl.array), m_implIterator(it.m_implIterator) { - // TODO: Handle tree case + // TODO: Handle tree case } //! Destructor @@ -88,12 +88,14 @@ class MapConstIterator { } //! Prefix increment - MapConstIterator operator++(int) { MapConstIterator tmp = *this; ++(*this); return tmp; } + MapConstIterator operator++(int) { + MapConstIterator tmp = *this; + ++(*this); + return tmp; + } //! Postfix increment - void increment() { - this->m_implIterator.increment(); - } + void increment() { this->m_implIterator.increment(); } //! Check whether the iterator is in range bool isInRange() const { return this->m_implIterator.isInRange(); } diff --git a/Fw/DataStructures/SetConstIterator.hpp b/Fw/DataStructures/SetConstIterator.hpp index bd7f59a9355..5f132161d9d 100644 --- a/Fw/DataStructures/SetConstIterator.hpp +++ b/Fw/DataStructures/SetConstIterator.hpp @@ -16,7 +16,6 @@ namespace Fw { template class SetConstIterator { - public: // ---------------------------------------------------------------------- // Public types @@ -53,7 +52,7 @@ class SetConstIterator { //! Copy constructor SetConstIterator(const SetConstIterator& it) : m_implKind(it.m_implKind), m_impl(it.m_impl.array), m_implIterator(it.m_implIterator) { - // TODO: Handle tree case + // TODO: Handle tree case } //! Destructor @@ -94,12 +93,14 @@ class SetConstIterator { } //! Prefix increment - SetConstIterator operator++(int) { SetConstIterator tmp = *this; ++(*this); return tmp; } + SetConstIterator operator++(int) { + SetConstIterator tmp = *this; + ++(*this); + return tmp; + } //! Postfix increment - void increment() { - this->m_implIterator.increment(); - } + void increment() { this->m_implIterator.increment(); } //! Check whether the iterator is in range bool isInRange() const { return this->m_implIterator.isInRange(); } diff --git a/Fw/DataStructures/SetOrMapImplConstIterator.hpp b/Fw/DataStructures/SetOrMapImplConstIterator.hpp index 0f8b47eda0e..469c8382fef 100644 --- a/Fw/DataStructures/SetOrMapImplConstIterator.hpp +++ b/Fw/DataStructures/SetOrMapImplConstIterator.hpp @@ -14,7 +14,6 @@ namespace Fw { template class SetOrMapImplConstIterator { - // ---------------------------------------------------------------------- // Deleted elements // ---------------------------------------------------------------------- @@ -57,7 +56,6 @@ class SetOrMapImplConstIterator { //! Reset the iterator virtual void reset() = 0; - }; } // namespace Fw diff --git a/Fw/DataStructures/SetOrMapImplEntry.hpp b/Fw/DataStructures/SetOrMapImplEntry.hpp index 9fa3677f45e..0b9378777eb 100644 --- a/Fw/DataStructures/SetOrMapImplEntry.hpp +++ b/Fw/DataStructures/SetOrMapImplEntry.hpp @@ -28,7 +28,11 @@ class SetOrMapImplEntry final : public MapConstEntry, public SetConstEnt const VN& valueOrNil, //!< The value or Nil const SetOrMapImplEntry* next = nullptr //!< The next entry ) - : MapConstEntry(), SetConstEntry(), m_keyOrElement(keyOrElement), m_valueOrNil(valueOrNil), m_next(next) {} + : MapConstEntry(), + SetConstEntry(), + m_keyOrElement(keyOrElement), + m_valueOrNil(valueOrNil), + m_next(next) {} //! Copy constructor SetOrMapImplEntry(const SetOrMapImplEntry& entry) { *this = entry; } From 63568bf77ea869df04ff42a7d8540441a6da39aa Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 13 Jul 2025 20:48:13 -0700 Subject: [PATCH 365/458] Revise array set and map impl Remove forward links --- Fw/DataStructures/ArraySetOrMapImpl.hpp | 6 ------ Fw/DataStructures/SetConstEntry.hpp | 4 ---- Fw/DataStructures/SetOrMapImplEntry.hpp | 22 +++------------------- 3 files changed, 3 insertions(+), 29 deletions(-) diff --git a/Fw/DataStructures/ArraySetOrMapImpl.hpp b/Fw/DataStructures/ArraySetOrMapImpl.hpp index f35934f0813..236ec8332e5 100644 --- a/Fw/DataStructures/ArraySetOrMapImpl.hpp +++ b/Fw/DataStructures/ArraySetOrMapImpl.hpp @@ -194,9 +194,6 @@ class ArraySetOrMapImpl final { } if ((status == Success::FAILURE) && (this->m_size < this->getCapacity())) { this->m_entries[this->m_size] = Entry(keyOrElement, valueOrNil); - if (this->m_size > 0) { - this->m_entries[this->m_size - 1].setNextEntry(&this->m_entries[this->m_size]); - } this->m_size++; status = Success::SUCCESS; } @@ -214,9 +211,6 @@ class ArraySetOrMapImpl final { 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_entries[i].setNextEntry(&this->m_entries[i + 1]); - } else { - this->m_entries[i].setNextEntry(nullptr); } this->m_size--; status = Success::SUCCESS; diff --git a/Fw/DataStructures/SetConstEntry.hpp b/Fw/DataStructures/SetConstEntry.hpp index e60c39566c1..1915eb6bbb4 100644 --- a/Fw/DataStructures/SetConstEntry.hpp +++ b/Fw/DataStructures/SetConstEntry.hpp @@ -51,10 +51,6 @@ class SetConstEntry { //! Get the element associated with this entry //! \return The element virtual const T& getElement() const = 0; - - //! Get the next set entry - //! \return The set entry, or nullptr if none - virtual const SetConstEntry* getNextSetConstEntry() const = 0; }; } // namespace Fw diff --git a/Fw/DataStructures/SetOrMapImplEntry.hpp b/Fw/DataStructures/SetOrMapImplEntry.hpp index 0b9378777eb..b4f490e6312 100644 --- a/Fw/DataStructures/SetOrMapImplEntry.hpp +++ b/Fw/DataStructures/SetOrMapImplEntry.hpp @@ -24,15 +24,10 @@ class SetOrMapImplEntry final : public MapConstEntry, public SetConstEnt SetOrMapImplEntry() : MapConstEntry(), SetConstEntry() {} //! Constructor providing members - SetOrMapImplEntry(const KE& keyOrElement, //!< The key or element - const VN& valueOrNil, //!< The value or Nil - const SetOrMapImplEntry* next = nullptr //!< The next entry + SetOrMapImplEntry(const KE& keyOrElement, //!< The key or element + const VN& valueOrNil //!< The value or Nil ) - : MapConstEntry(), - SetConstEntry(), - m_keyOrElement(keyOrElement), - m_valueOrNil(valueOrNil), - m_next(next) {} + : MapConstEntry(), SetConstEntry(), m_keyOrElement(keyOrElement), m_valueOrNil(valueOrNil) {} //! Copy constructor SetOrMapImplEntry(const SetOrMapImplEntry& entry) { *this = entry; } @@ -50,7 +45,6 @@ class SetOrMapImplEntry final : public MapConstEntry, public SetConstEnt if (this != &entry) { this->m_keyOrElement = entry.m_keyOrElement; this->m_valueOrNil = entry.m_valueOrNil; - this->m_next = entry.m_next; } return *this; } @@ -75,19 +69,12 @@ class SetOrMapImplEntry final : public MapConstEntry, public SetConstEnt //! \return The value or nil const VN& getValueOrNil() const { return this->m_valueOrNil; } - //! Get the next set entry - //! \return The set entry, or nullptr if none - const SetConstEntry* getNextSetConstEntry() const override { return this->m_next; } - //! Set the key or element void setKeyOrElement(const KE& keyOrElement //!< The key or element ) { this->m_keyOrElement = keyOrElement; } - //! Set the next entry - void setNextEntry(const SetOrMapImplEntry* next) { this->m_next = next; } - //! Set the value or Nil void setValueOrNil(const VN& valueOrNil) { this->m_valueOrNil = valueOrNil; } @@ -101,9 +88,6 @@ class SetOrMapImplEntry final : public MapConstEntry, public SetConstEnt //! The value or nil VN m_valueOrNil = {}; - - //! Pointer to the next entry or nullptr if none - const SetOrMapImplEntry* m_next = nullptr; }; } // namespace Fw From c3e78493673e08b7a7924852a0a8cdc3854d55a6 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 13 Jul 2025 21:19:23 -0700 Subject: [PATCH 366/458] Revise data structures tests --- .../test/ut/STest/MapTestRules.hpp | 21 +++++++------------ .../test/ut/STest/SetTestRules.hpp | 14 ++++--------- 2 files changed, 11 insertions(+), 24 deletions(-) diff --git a/Fw/DataStructures/test/ut/STest/MapTestRules.hpp b/Fw/DataStructures/test/ut/STest/MapTestRules.hpp index ab092834b9e..7a766b928d4 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/MapTestRules.hpp @@ -51,21 +51,14 @@ struct FindExisting : public Rule { FindExisting() : Rule("FindExisting") {} bool precondition(const State& state) { return static_cast(state.map.getSize()) > 0; } void action(State& state) { - const auto size = state.map.getSize(); - const auto index = STest::Pick::startLength(0, static_cast(size)); - auto it = state.map.begin(); - for (FwSizeType i = 0; i < index; i++) { - ASSERT_TRUE(it.isInRange()); - it++; - + for (auto& entry : state.map) { + const auto key = entry.getKey(); + const auto expectedValue = state.modelMap[key]; + State::ValueType value = 0; + const auto status = state.map.find(key, value); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(value, expectedValue); } - ASSERT_TRUE(it.isInRange()); - const auto key = it->getKey(); - const auto expectedValue = state.modelMap[key]; - State::ValueType value = 0; - const auto status = state.map.find(key, value); - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(value, expectedValue); } }; diff --git a/Fw/DataStructures/test/ut/STest/SetTestRules.hpp b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp index c857660977b..86dcb31812f 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp @@ -50,22 +50,16 @@ struct FindExisting : public Rule { ASSERT_EQ(size, modelSize); // Check that all elements of set are in modelSet { - auto it = state.set.begin(); - for (FwSizeType i = 0; i < size; i++) { - ASSERT_TRUE(it.isInRange()); - const auto e = it->getElement(); + for (auto& entry : state.set) { + const auto e = entry.getElement(); ASSERT_TRUE(state.modelSetContains(e)); - it++; } } // Check that all elements of modelSet are in set { - auto entry = state.modelSet.begin(); - for (FwSizeType i = 0; i < modelSize; i++) { - ASSERT_NE(entry, state.modelSet.end()); - const auto status = state.set.find(*entry); + for (auto& e : state.modelSet) { + const auto status = state.set.find(e); ASSERT_EQ(status, Success::SUCCESS); - entry++; } } } From 3ead1496961d2092fc9a6c8963105791664f70e9 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 13 Jul 2025 21:26:07 -0700 Subject: [PATCH 367/458] Revise Set iterator --- Fw/DataStructures/SetBase.hpp | 2 +- Fw/DataStructures/SetConstIterator.hpp | 4 ++-- Fw/DataStructures/test/ut/STest/SetTestRules.hpp | 8 +++----- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/Fw/DataStructures/SetBase.hpp b/Fw/DataStructures/SetBase.hpp index d4c77940730..16af09e7b97 100644 --- a/Fw/DataStructures/SetBase.hpp +++ b/Fw/DataStructures/SetBase.hpp @@ -77,7 +77,7 @@ class SetBase { const FwSizeType size = FW_MIN(set.getSize(), this->getCapacity()); auto it = set.begin(); for (FwSizeType i = 0; i < size; i++) { - const auto status = this->insert(it->getElement()); + const auto status = this->insert(*it); FW_ASSERT(status == Success::SUCCESS, static_cast(status)); it++; } diff --git a/Fw/DataStructures/SetConstIterator.hpp b/Fw/DataStructures/SetConstIterator.hpp index 5f132161d9d..ca7e69cc8a1 100644 --- a/Fw/DataStructures/SetConstIterator.hpp +++ b/Fw/DataStructures/SetConstIterator.hpp @@ -109,10 +109,10 @@ class SetConstIterator { void reset() { return this->m_implIterator.reset(); } //! Dereference - const SetConstEntry& operator*() const { return this->m_implIterator.getEntry(); } + const T& operator*() const { return this->m_implIterator.getEntry().getKeyOrElement(); } //! Pointer - const SetConstEntry* operator->() const { return &this->m_implIterator.getEntry(); } + const T* operator->() const { return &this->m_implIterator.getEntry().getKeyOrElement(); } private: // ---------------------------------------------------------------------- diff --git a/Fw/DataStructures/test/ut/STest/SetTestRules.hpp b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp index 86dcb31812f..c4e094deda6 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp @@ -50,8 +50,7 @@ struct FindExisting : public Rule { ASSERT_EQ(size, modelSize); // Check that all elements of set are in modelSet { - for (auto& entry : state.set) { - const auto e = entry.getElement(); + for (auto& e : state.set) { ASSERT_TRUE(state.modelSetContains(e)); } } @@ -77,8 +76,7 @@ struct InsertExisting : public Rule { it++; } ASSERT_TRUE(it.isInRange()); - const auto e = it->getElement(); - const auto status = state.set.insert(e); + const auto status = state.set.insert(*it); ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(state.set.getSize(), size); } @@ -143,7 +141,7 @@ struct RemoveExisting : public Rule { it++; } ASSERT_TRUE(it.isInRange()); - const auto e = it->getElement(); + const auto e = *it; const auto status = state.set.remove(e); ASSERT_EQ(status, Success::SUCCESS); const auto n = state.modelSet.erase(e); From ff88c63ca220e4d82aaba2a4e9a6ecfd315741de Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 13 Jul 2025 21:29:28 -0700 Subject: [PATCH 368/458] Remove SetConstEntry --- Fw/DataStructures/ArraySet.hpp | 3 -- Fw/DataStructures/ExternalArraySet.hpp | 3 -- Fw/DataStructures/SetBase.hpp | 8 ---- Fw/DataStructures/SetConstEntry.hpp | 58 ------------------------- Fw/DataStructures/SetConstIterator.hpp | 1 - Fw/DataStructures/SetOrMapImplEntry.hpp | 11 ++--- 6 files changed, 3 insertions(+), 81 deletions(-) delete mode 100644 Fw/DataStructures/SetConstEntry.hpp diff --git a/Fw/DataStructures/ArraySet.hpp b/Fw/DataStructures/ArraySet.hpp index d140e15a54a..db7aea8a23d 100644 --- a/Fw/DataStructures/ArraySet.hpp +++ b/Fw/DataStructures/ArraySet.hpp @@ -28,9 +28,6 @@ class ArraySet final : public SetBase { //! The type of animplementation entry using ImplEntry = SetOrMapImplEntry; - //! The type of a set entry - using SetConstEntry = SetConstEntry; - //! The type of the implementation entries using ImplEntries = ImplEntry[C]; diff --git a/Fw/DataStructures/ExternalArraySet.hpp b/Fw/DataStructures/ExternalArraySet.hpp index 46a3380c356..f576d31e606 100644 --- a/Fw/DataStructures/ExternalArraySet.hpp +++ b/Fw/DataStructures/ExternalArraySet.hpp @@ -31,9 +31,6 @@ class ExternalArraySet final : public SetBase { //! The type of a set entry using Entry = SetOrMapImplEntry; - //! The type of a set iterator - using SetConstEntry = SetConstEntry; - public: // ---------------------------------------------------------------------- // Public constructors and destructors diff --git a/Fw/DataStructures/SetBase.hpp b/Fw/DataStructures/SetBase.hpp index 16af09e7b97..b3ebd98f271 100644 --- a/Fw/DataStructures/SetBase.hpp +++ b/Fw/DataStructures/SetBase.hpp @@ -7,7 +7,6 @@ #ifndef Fw_SetBase_HPP #define Fw_SetBase_HPP -#include "Fw/DataStructures/SetConstEntry.hpp" #include "Fw/DataStructures/SetConstIterator.hpp" #include "Fw/Types/Assert.hpp" #include "Fw/Types/SuccessEnumAc.hpp" @@ -16,13 +15,6 @@ namespace Fw { template class SetBase { - public: - // ---------------------------------------------------------------------- - // Public types - // ---------------------------------------------------------------------- - - //! The type of a set entry - using SetConstEntry = SetConstEntry; private: // ---------------------------------------------------------------------- diff --git a/Fw/DataStructures/SetConstEntry.hpp b/Fw/DataStructures/SetConstEntry.hpp deleted file mode 100644 index 1915eb6bbb4..00000000000 --- a/Fw/DataStructures/SetConstEntry.hpp +++ /dev/null @@ -1,58 +0,0 @@ -// ====================================================================== -// \title SetConstEntry -// \author bocchino -// \brief An abstract class template representing a const entry for a set -// ====================================================================== - -#ifndef Fw_SetConstEntry_HPP -#define Fw_SetConstEntry_HPP - -#include "Fw/FPrimeBasicTypes.hpp" - -namespace Fw { - -template -class SetConstEntry { - private: - // ---------------------------------------------------------------------- - // Private constructors - // ---------------------------------------------------------------------- - - //! Copy constructor deleted in the base class - //! Behavior depends on the implementation - SetConstEntry(const SetConstEntry&) = delete; - - protected: - // ---------------------------------------------------------------------- - // Protected constructors and destructors - // ---------------------------------------------------------------------- - - //! Zero-argument constructor - SetConstEntry() {} - - //! Destructor - virtual ~SetConstEntry() = default; - - private: - // ---------------------------------------------------------------------- - // Private member functions - // ---------------------------------------------------------------------- - - //! operator= deleted in the base class - //! Behavior depends on the implementation - //! We avoid virtual user-defined operators - SetConstEntry& operator=(const SetConstEntry&) = delete; - - public: - // ---------------------------------------------------------------------- - // Public member functions - // ---------------------------------------------------------------------- - - //! Get the element associated with this entry - //! \return The element - virtual const T& getElement() const = 0; -}; - -} // namespace Fw - -#endif diff --git a/Fw/DataStructures/SetConstIterator.hpp b/Fw/DataStructures/SetConstIterator.hpp index ca7e69cc8a1..4b50a2fa76d 100644 --- a/Fw/DataStructures/SetConstIterator.hpp +++ b/Fw/DataStructures/SetConstIterator.hpp @@ -9,7 +9,6 @@ #include "Fw/DataStructures/ArraySetOrMapImpl.hpp" #include "Fw/DataStructures/Nil.hpp" -#include "Fw/DataStructures/SetConstEntry.hpp" #include "Fw/FPrimeBasicTypes.hpp" namespace Fw { diff --git a/Fw/DataStructures/SetOrMapImplEntry.hpp b/Fw/DataStructures/SetOrMapImplEntry.hpp index b4f490e6312..43e8e805d29 100644 --- a/Fw/DataStructures/SetOrMapImplEntry.hpp +++ b/Fw/DataStructures/SetOrMapImplEntry.hpp @@ -8,26 +8,25 @@ #define Fw_SetOrMapImplEntry_HPP #include "Fw/DataStructures/MapConstEntry.hpp" -#include "Fw/DataStructures/SetConstEntry.hpp" #include "Fw/FPrimeBasicTypes.hpp" namespace Fw { template -class SetOrMapImplEntry final : public MapConstEntry, public SetConstEntry { +class SetOrMapImplEntry final : public MapConstEntry { public: // ---------------------------------------------------------------------- // Public constructors and destructors // ---------------------------------------------------------------------- //! Zero-argument constructor - SetOrMapImplEntry() : MapConstEntry(), SetConstEntry() {} + SetOrMapImplEntry() : MapConstEntry() {} //! Constructor providing members SetOrMapImplEntry(const KE& keyOrElement, //!< The key or element const VN& valueOrNil //!< The value or Nil ) - : MapConstEntry(), SetConstEntry(), m_keyOrElement(keyOrElement), m_valueOrNil(valueOrNil) {} + : MapConstEntry(), m_keyOrElement(keyOrElement), m_valueOrNil(valueOrNil) {} //! Copy constructor SetOrMapImplEntry(const SetOrMapImplEntry& entry) { *this = entry; } @@ -49,10 +48,6 @@ class SetOrMapImplEntry final : public MapConstEntry, public SetConstEnt return *this; } - //! Get the element associated with this entry - //! \return The element - const KE& getElement() const override { return this->m_keyOrElement; } - //! Get the key associated with this entry //! \return The key const KE& getKey() const override { return this->m_keyOrElement; } From f3ec687b37cda8c38d79a43d33a08c8c07f2d8c7 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Sun, 13 Jul 2025 21:35:42 -0700 Subject: [PATCH 369/458] Refactor SetOrMapImplEntry --- Fw/DataStructures/SetOrMapImplEntry.hpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/Fw/DataStructures/SetOrMapImplEntry.hpp b/Fw/DataStructures/SetOrMapImplEntry.hpp index 43e8e805d29..1dfdfd905d3 100644 --- a/Fw/DataStructures/SetOrMapImplEntry.hpp +++ b/Fw/DataStructures/SetOrMapImplEntry.hpp @@ -48,18 +48,10 @@ class SetOrMapImplEntry final : public MapConstEntry { return *this; } - //! Get the key associated with this entry - //! \return The key - const KE& getKey() const override { return this->m_keyOrElement; } - //! Get the key or element associated with this entry //! \return The key or element const KE& getKeyOrElement() const { return this->m_keyOrElement; } - //! Get the value associated with this entry - //! \return The value - const VN& getValue() const override { return this->m_valueOrNil; } - //! Get the value or nil associated with this entry //! \return The value or nil const VN& getValueOrNil() const { return this->m_valueOrNil; } @@ -73,6 +65,19 @@ class SetOrMapImplEntry final : public MapConstEntry { //! Set the value or Nil void setValueOrNil(const VN& valueOrNil) { this->m_valueOrNil = valueOrNil; } + public: + // ---------------------------------------------------------------------- + // MapConstEntry implementation + // ---------------------------------------------------------------------- + + //! Get the key associated with this entry + //! \return The key + const KE& getKey() const override { return this->m_keyOrElement; } + + //! Get the value associated with this entry + //! \return The value + const VN& getValue() const override { return this->m_valueOrNil; } + private: // ---------------------------------------------------------------------- // Private member variables From e66d25e51173dd2d1029a23a920b1123fa106f2f Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 00:00:41 -0700 Subject: [PATCH 370/458] Pull in changes from rb-tree branch --- Fw/DataStructures/ArraySetOrMapImpl.hpp | 33 +++++-- Fw/DataStructures/MapConstIterator.hpp | 93 +++++++++++++------ Fw/DataStructures/SetBase.hpp | 1 - Fw/DataStructures/SetConstIterator.hpp | 85 +++++++++++------ .../SetOrMapImplConstIterator.hpp | 20 +++- Fw/DataStructures/SetOrMapImplEntry.hpp | 2 +- Fw/DataStructures/docs/ArraySetOrMapImpl.md | 2 +- 7 files changed, 167 insertions(+), 69 deletions(-) diff --git a/Fw/DataStructures/ArraySetOrMapImpl.hpp b/Fw/DataStructures/ArraySetOrMapImpl.hpp index 236ec8332e5..779bc33b3fa 100644 --- a/Fw/DataStructures/ArraySetOrMapImpl.hpp +++ b/Fw/DataStructures/ArraySetOrMapImpl.hpp @@ -35,13 +35,21 @@ class ArraySetOrMapImpl final { //! Const iterator class ConstIterator final : public SetOrMapImplConstIterator { public: + using ImplKind = typename SetOrMapImplConstIterator::ImplKind; + + public: + //! Default constructor + ConstIterator() {} + //! Constructor providing the implementation - ConstIterator(const ArraySetOrMapImpl& impl) : SetOrMapImplConstIterator(), m_impl(impl) { + ConstIterator(const ArraySetOrMapImpl& impl) : SetOrMapImplConstIterator(), m_impl(&impl) { this->reset(); } //! Copy constructor - ConstIterator(const ConstIterator& it) : m_impl(it.m_impl), m_index(it.m_index) {} + ConstIterator(const ConstIterator& it) : SetOrMapImplConstIterator(), m_impl(it.m_impl) { + this->reset(); + } //! Destructor ~ConstIterator() override = default; @@ -51,24 +59,32 @@ class ArraySetOrMapImpl final { 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 == &it.m_impl) { + 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(this->m_index), - static_cast(this->m_impl.m_size)); - return this->m_impl.m_entries[this->m_index]; + static_cast(this->m_impl->m_size)); + return this->m_impl->m_entries[this->m_index]; } //! Increment operator @@ -79,7 +95,10 @@ class ArraySetOrMapImpl final { } //! Check whether the iterator is in range - bool isInRange() const override { return this->m_index < this->m_impl.m_size; } + bool isInRange() const override { + FW_ASSERT(this->m_impl != nullptr); + return this->m_index < this->m_impl->m_size; + } //! Reset the iterator void reset() override { this->m_index = 0; } @@ -89,7 +108,7 @@ class ArraySetOrMapImpl final { private: //! The implementation over which to iterate - const ArraySetOrMapImpl& m_impl; + const ArraySetOrMapImpl* m_impl = nullptr; //! The current iteration index FwSizeType m_index = 0; diff --git a/Fw/DataStructures/MapConstIterator.hpp b/Fw/DataStructures/MapConstIterator.hpp index af1d26c156a..bbbfd6e13de 100644 --- a/Fw/DataStructures/MapConstIterator.hpp +++ b/Fw/DataStructures/MapConstIterator.hpp @@ -7,6 +7,8 @@ #ifndef Fw_MapConstIterator_HPP #define Fw_MapConstIterator_HPP +#include + #include "Fw/DataStructures/ArraySetOrMapImpl.hpp" #include "Fw/DataStructures/MapConstEntry.hpp" #include "Fw/FPrimeBasicTypes.hpp" @@ -17,7 +19,7 @@ template class MapConstIterator { public: // ---------------------------------------------------------------------- - // Public + // Public types // ---------------------------------------------------------------------- //! The type of an array iterator @@ -29,14 +31,18 @@ class MapConstIterator { // ---------------------------------------------------------------------- //! The type of an implementation kind - enum class ImplKind { ARRAY, RED_BLACK_TREE }; + using ImplKind = typename SetOrMapImplConstIterator::ImplKind; //! The type of an implementation union Impl { + //! Default constructor + Impl() {} + //! Array constructor Impl(const ArrayIterator& it) : array(it) {} //! An array iterator ArrayIterator array; // TODO: Add red-black tree implementation + // ! Destructor ~Impl() {} }; @@ -46,34 +52,52 @@ class MapConstIterator { // ---------------------------------------------------------------------- //! Constructor providing an array implementation - MapConstIterator(const ArrayIterator& it) : m_implKind(ImplKind::ARRAY), m_impl(it), m_implIterator(m_impl.array) {} + MapConstIterator(const ArrayIterator& it) : m_impl(it), m_implIterator(&m_impl.array) {} //! Copy constructor - MapConstIterator(const MapConstIterator& it) - : m_implKind(it.m_implKind), m_impl(it.m_impl.array), m_implIterator(it.m_implIterator) { - // TODO: Handle tree case + MapConstIterator(const MapConstIterator& it) : m_impl(), m_implIterator() { + const auto implKind = it.getImplIterator().implKind(); + switch (implKind) { + case ImplKind::ARRAY: + this->m_implIterator = new (&this->m_impl.array) ArrayIterator(it.m_impl.array); + break; + case ImplKind::RED_BLACK_TREE: + // TODO + break; + default: + FW_ASSERT(0, static_cast(implKind)); + break; + } } //! Destructor ~MapConstIterator() {} public: + // ---------------------------------------------------------------------- + // Public member functions + // ---------------------------------------------------------------------- + //! Copy assignment operator MapConstIterator& operator=(const MapConstIterator&) = default; //! Equality comparison operator bool operator==(const MapConstIterator& it) { bool result = false; - switch (this->m_implKind) { - case ImplKind::ARRAY: - result = this->m_impl.array.compareEqual(it.m_impl.array); - break; - case ImplKind::RED_BLACK_TREE: - // TODO - break; - default: - FW_ASSERT(0, static_cast(this->m_implKind)); - break; + const auto implKind1 = this->getImplIterator().implKind(); + const auto implKind2 = it.getImplIterator().implKind(); + if (implKind1 == implKind2) { + switch (implKind1) { + case ImplKind::ARRAY: + result = this->m_impl.array.compareEqual(it.m_impl.array); + break; + case ImplKind::RED_BLACK_TREE: + // TODO + break; + default: + FW_ASSERT(0, static_cast(implKind1)); + break; + } } return result; } @@ -83,7 +107,7 @@ class MapConstIterator { //! Prefix increment MapConstIterator& operator++() { - this->m_implIterator.increment(); + this->getImplIterator().increment(); return *this; } @@ -94,30 +118,45 @@ class MapConstIterator { return tmp; } - //! Postfix increment - void increment() { this->m_implIterator.increment(); } - //! Check whether the iterator is in range - bool isInRange() const { return this->m_implIterator.isInRange(); } + bool isInRange() const { return this->getImplIterator().isInRange(); } //! Reset the iterator - void reset() { return this->m_implIterator.reset(); } + void reset() { return this->getImplIterator().reset(); } //! Dereference - const MapConstEntry& operator*() const { return this->m_implIterator.getEntry(); } + const MapConstEntry& operator*() const { return this->getImplIterator().getEntry(); } //! Pointer - const MapConstEntry* operator->() const { return &this->m_implIterator.getEntry(); } + const MapConstEntry* operator->() const { return &this->getImplIterator().getEntry(); } private: - //! The implementation kind - ImplKind m_implKind; + // ---------------------------------------------------------------------- + // Private helper functions + // ---------------------------------------------------------------------- + + //! Assert and get the impl iterator + SetOrMapImplConstIterator& getImplIterator() { + FW_ASSERT(this->m_implIterator != nullptr); + return *this->m_implIterator; + } + + //! Assert and get the impl iterator (const) + const SetOrMapImplConstIterator& getImplIterator() const { + FW_ASSERT(this->m_implIterator != nullptr); + return *this->m_implIterator; + } + + private: + // ---------------------------------------------------------------------- + // Private member variables + // ---------------------------------------------------------------------- //! The implementation Impl m_impl; //! The impl iterator - SetOrMapImplConstIterator& m_implIterator; + SetOrMapImplConstIterator* m_implIterator = nullptr; }; } // namespace Fw diff --git a/Fw/DataStructures/SetBase.hpp b/Fw/DataStructures/SetBase.hpp index b3ebd98f271..7a54b7ccd1d 100644 --- a/Fw/DataStructures/SetBase.hpp +++ b/Fw/DataStructures/SetBase.hpp @@ -15,7 +15,6 @@ namespace Fw { template class SetBase { - private: // ---------------------------------------------------------------------- // Private constructors diff --git a/Fw/DataStructures/SetConstIterator.hpp b/Fw/DataStructures/SetConstIterator.hpp index 4b50a2fa76d..d226df13496 100644 --- a/Fw/DataStructures/SetConstIterator.hpp +++ b/Fw/DataStructures/SetConstIterator.hpp @@ -7,6 +7,8 @@ #ifndef Fw_SetConstIterator_HPP #define Fw_SetConstIterator_HPP +#include + #include "Fw/DataStructures/ArraySetOrMapImpl.hpp" #include "Fw/DataStructures/Nil.hpp" #include "Fw/FPrimeBasicTypes.hpp" @@ -29,14 +31,18 @@ class SetConstIterator { // ---------------------------------------------------------------------- //! The type of an implementation kind - enum class ImplKind { ARRAY, RED_BLACK_TREE }; + using ImplKind = typename SetOrMapImplConstIterator::ImplKind; //! The type of an implementation union Impl { + //! Default constructor + Impl() {} + //! Array constructor Impl(const ArrayIterator& it) : array(it) {} //! An array iterator ArrayIterator array; // TODO: Add red-black tree implementation + // ! Destructor ~Impl() {} }; @@ -46,12 +52,22 @@ class SetConstIterator { // ---------------------------------------------------------------------- //! Constructor providing an array implementation - SetConstIterator(const ArrayIterator& it) : m_implKind(ImplKind::ARRAY), m_impl(it), m_implIterator(m_impl.array) {} + SetConstIterator(const ArrayIterator& it) : m_impl(it), m_implIterator(&m_impl.array) {} //! Copy constructor - SetConstIterator(const SetConstIterator& it) - : m_implKind(it.m_implKind), m_impl(it.m_impl.array), m_implIterator(it.m_implIterator) { - // TODO: Handle tree case + SetConstIterator(const SetConstIterator& it) : m_impl(), m_implIterator() { + const auto implKind = it.getImplIterator().implKind(); + switch (implKind) { + case ImplKind::ARRAY: + this->m_implIterator = new (&this->m_impl.array) ArrayIterator(it.m_impl.array); + break; + case ImplKind::RED_BLACK_TREE: + // TODO + break; + default: + FW_ASSERT(0, static_cast(implKind)); + break; + } } //! Destructor @@ -68,16 +84,20 @@ class SetConstIterator { //! Equality comparison operator bool operator==(const SetConstIterator& it) { bool result = false; - switch (this->m_implKind) { - case ImplKind::ARRAY: - result = this->m_impl.array.compareEqual(it.m_impl.array); - break; - case ImplKind::RED_BLACK_TREE: - // TODO - break; - default: - FW_ASSERT(0, static_cast(this->m_implKind)); - break; + const auto implKind1 = this->getImplIterator().implKind(); + const auto implKind2 = it.getImplIterator().implKind(); + if (implKind1 == implKind2) { + switch (implKind1) { + case ImplKind::ARRAY: + result = this->m_impl.array.compareEqual(it.m_impl.array); + break; + case ImplKind::RED_BLACK_TREE: + // TODO + break; + default: + FW_ASSERT(0, static_cast(implKind1)); + break; + } } return result; } @@ -87,7 +107,7 @@ class SetConstIterator { //! Prefix increment SetConstIterator& operator++() { - this->m_implIterator.increment(); + this->getImplIterator().increment(); return *this; } @@ -98,34 +118,45 @@ class SetConstIterator { return tmp; } - //! Postfix increment - void increment() { this->m_implIterator.increment(); } - //! Check whether the iterator is in range - bool isInRange() const { return this->m_implIterator.isInRange(); } + bool isInRange() const { return this->getImplIterator().isInRange(); } //! Reset the iterator - void reset() { return this->m_implIterator.reset(); } + void reset() { return this->getImplIterator().reset(); } //! Dereference - const T& operator*() const { return this->m_implIterator.getEntry().getKeyOrElement(); } + const T& operator*() const { return this->getImplIterator().getEntry().getKeyOrElement(); } //! Pointer - const T* operator->() const { return &this->m_implIterator.getEntry().getKeyOrElement(); } + const T* operator->() const { return &this->getImplIterator().getEntry().getKeyOrElement(); } private: // ---------------------------------------------------------------------- - // Private member variables + // Private helper functions // ---------------------------------------------------------------------- - //! The implementation kind - ImplKind m_implKind; + //! Assert and get the impl iterator + SetOrMapImplConstIterator& getImplIterator() { + FW_ASSERT(this->m_implIterator != nullptr); + return *this->m_implIterator; + } + + //! Assert and get the impl iterator (const) + const SetOrMapImplConstIterator& getImplIterator() const { + FW_ASSERT(this->m_implIterator != nullptr); + return *this->m_implIterator; + } + + private: + // ---------------------------------------------------------------------- + // Private member variables + // ---------------------------------------------------------------------- //! The implementation Impl m_impl; //! The impl iterator - SetOrMapImplConstIterator& m_implIterator; + SetOrMapImplConstIterator* m_implIterator = nullptr; }; } // namespace Fw diff --git a/Fw/DataStructures/SetOrMapImplConstIterator.hpp b/Fw/DataStructures/SetOrMapImplConstIterator.hpp index 469c8382fef..4c996de9683 100644 --- a/Fw/DataStructures/SetOrMapImplConstIterator.hpp +++ b/Fw/DataStructures/SetOrMapImplConstIterator.hpp @@ -14,35 +14,45 @@ namespace Fw { template class SetOrMapImplConstIterator { + private: // ---------------------------------------------------------------------- // Deleted elements // ---------------------------------------------------------------------- - private: //! Copy constructor SetOrMapImplConstIterator(const SetOrMapImplConstIterator& it) = delete; - private: //! Copy assignment operator SetOrMapImplConstIterator& operator=(const SetOrMapImplConstIterator&) = delete; + public: // ---------------------------------------------------------------------- - // Constructors and destructors + // Types // ---------------------------------------------------------------------- + //! The kind of a const iterator implementation + enum class ImplKind { ARRAY, RED_BLACK_TREE }; + public: + // ---------------------------------------------------------------------- + // Constructors and destructors + // ---------------------------------------------------------------------- + //! Zero-argument constructor SetOrMapImplConstIterator() = default; - public: //! Destructor virtual ~SetOrMapImplConstIterator() = default; + public: // ---------------------------------------------------------------------- // Public member functions // ---------------------------------------------------------------------- - public: + //! Return the impl kind + //! \return The impl kind + virtual ImplKind implKind() const = 0; + //! Increment the iterator virtual void increment() = 0; diff --git a/Fw/DataStructures/SetOrMapImplEntry.hpp b/Fw/DataStructures/SetOrMapImplEntry.hpp index 1dfdfd905d3..6e7d658a6b2 100644 --- a/Fw/DataStructures/SetOrMapImplEntry.hpp +++ b/Fw/DataStructures/SetOrMapImplEntry.hpp @@ -67,7 +67,7 @@ class SetOrMapImplEntry final : public MapConstEntry { public: // ---------------------------------------------------------------------- - // MapConstEntry implementation + // MapConstEntry implementation // ---------------------------------------------------------------------- //! Get the key associated with this entry diff --git a/Fw/DataStructures/docs/ArraySetOrMapImpl.md b/Fw/DataStructures/docs/ArraySetOrMapImpl.md index f167a40e9c9..565357d98f4 100644 --- a/Fw/DataStructures/docs/ArraySetOrMapImpl.md +++ b/Fw/DataStructures/docs/ArraySetOrMapImpl.md @@ -251,7 +251,7 @@ ConstIterator end() const ### 5.5. find ```c++ -Success find(const KE& keyOrElement, VN& valueOrNil) +Success find(const KE& keyOrElement, VN& valueOrNil) const ``` 1. Set `status = Success::FAILURE`. From 3d9c75a683dcb3ed127a699d2fab06b8f50ed11b Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 08:08:20 -0700 Subject: [PATCH 371/458] Revise MapBase --- Fw/DataStructures/MapBase.hpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/Fw/DataStructures/MapBase.hpp b/Fw/DataStructures/MapBase.hpp index 18049e0b340..365c3e6c14a 100644 --- a/Fw/DataStructures/MapBase.hpp +++ b/Fw/DataStructures/MapBase.hpp @@ -7,7 +7,6 @@ #ifndef Fw_MapBase_HPP #define Fw_MapBase_HPP -#include "Fw/DataStructures/MapConstEntry.hpp" #include "Fw/DataStructures/MapConstIterator.hpp" #include "Fw/Types/Assert.hpp" #include "Fw/Types/SuccessEnumAc.hpp" @@ -16,14 +15,6 @@ namespace Fw { template class MapBase { - public: - // ---------------------------------------------------------------------- - // Public types - // ---------------------------------------------------------------------- - - //! The type of a map iterator - using MapConstEntry = MapConstEntry; - private: // ---------------------------------------------------------------------- // Private constructors From 93373c9b9fc32d01bd6d5c5d4fd21ef211b6e350 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 08:36:15 -0700 Subject: [PATCH 372/458] Revise MapBase and docs --- Fw/DataStructures/ArraySetOrMapImpl.hpp | 2 +- Fw/DataStructures/MapBase.hpp | 35 +- Fw/DataStructures/docs/MapBase.md | 261 +++---------- Fw/DataStructures/docs/MapConstIterator.md | 417 +++++++++++++++++++++ 4 files changed, 499 insertions(+), 216 deletions(-) create mode 100644 Fw/DataStructures/docs/MapConstIterator.md diff --git a/Fw/DataStructures/ArraySetOrMapImpl.hpp b/Fw/DataStructures/ArraySetOrMapImpl.hpp index 779bc33b3fa..402f1b6c609 100644 --- a/Fw/DataStructures/ArraySetOrMapImpl.hpp +++ b/Fw/DataStructures/ArraySetOrMapImpl.hpp @@ -168,7 +168,7 @@ class ArraySetOrMapImpl final { //! Get the end iterator ConstIterator end() const { auto it = begin(); - it.setIndex(this->m_size + 1); + it.setIndex(this->m_size); return it; } diff --git a/Fw/DataStructures/MapBase.hpp b/Fw/DataStructures/MapBase.hpp index 365c3e6c14a..a0b51a26be0 100644 --- a/Fw/DataStructures/MapBase.hpp +++ b/Fw/DataStructures/MapBase.hpp @@ -17,13 +17,26 @@ template class MapBase { private: // ---------------------------------------------------------------------- - // Private constructors + // Deleted elements // ---------------------------------------------------------------------- //! Copy constructor deleted in the base class //! Behavior depends on the implementation MapBase(const MapBase&) = delete; + //! operator= deleted in the base class + //! Behavior depends on the implementation + //! We avoid virtual user-defined operators + MapBase& operator=(const MapBase&) = delete; + + public: + // ---------------------------------------------------------------------- + // Public types + // ---------------------------------------------------------------------- + + //! The type of a map const iterator + using ConstIterator = MapConstIterator; + protected: // ---------------------------------------------------------------------- // Protected constructors and destructors @@ -35,16 +48,6 @@ class MapBase { //! Destructor virtual ~MapBase() = default; - private: - // ---------------------------------------------------------------------- - // Private member functions - // ---------------------------------------------------------------------- - - //! operator= deleted in the base class - //! Behavior depends on the implementation - //! We avoid virtual user-defined operators - MapBase& operator=(const MapBase&) = delete; - public: // ---------------------------------------------------------------------- // Public member functions @@ -52,15 +55,11 @@ class MapBase { //! Get the begin iterator //! \return The iterator - virtual MapConstIterator begin() const = 0; + virtual ConstIterator begin() const = 0; //! Clear the map virtual void clear() = 0; - //! Get the end iterator - //! \return The iterator - virtual MapConstIterator end() const = 0; - //! Copy data from another map void copyDataFrom(const MapBase& map) { if (&map != this) { @@ -75,6 +74,10 @@ class MapBase { } } + //! Get the end iterator + //! \return The iterator + virtual ConstIterator end() const = 0; + //! Find the value associated with a key in the map //! SUCCESS if the item was found virtual Success find(const K& key, //!< The key (input) diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index 369ba78a846..d5ae3fb4958 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -13,164 +13,27 @@ It represents an abstract base class for a map. |`typename`|`K`|The type of a key in the map| |`typename`|`V`|The type of a value in the map| - -## 2. Public Types +## 2. Deleted Elements - -### 2.1. Type Aliases +The following elements are defined `= delete`: -`MapBase` defines the following public type aliases. +1. The copy constructor. + ```c++ + MapBase(const MapBase& map) + ``` -|Name|Definition| -|----|----------| -|`MapEntry`|Alias of [`MapEntry`](MapEntry.md)| - -### 2.2. ConstIterator - -`ConstIterator` is a public inner class of `MapBase`. It provides -non-modifying iteration over the elements of a `MapBase` instance. +1. The assignment operator. + ```c++ + MapBase& operator=(const MapBase&) + ``` -#### 2.2.1. Public Type Aliases +## 3. Public Types -`ConstIterator` defines the following public type aliases. +`MapBase` defines the following public types: |Name|Definition| |----|----------| -|ArrayIterator|An alias for `ArraySetOrMapImpl::ConstIterator`. -|RedBlackTreeIterator|An alias for `RedBlackTreeSetOrMapImpl::ConstIterator`. - -#### 2.2.2. Private Enumerations - -`ConstIterator` defines the following private enumerations. - -|Name|Definition| -|----|----------| -|ImplKind|An enumeration with values `ARRAY` and `RED_BLACK_TREE`| - -#### 2.2.3. Private Type Aliases - -`ConstIterator` defines the following private type aliases. - -|Name|Definition| -|----|----------| -|ImplIterator|A union with member variables `arrayIterator` of type `ArrayIterator` and `redBlackTreeIterator` of type `RedBlackTreeIterator`| - -#### 2.2.4. Private Member Variables - -`ConstIterator` has the following private member variables. - -|Name|Type|Purpose|Default Value| -|----|----|-------|-------------| -|`m_implKind`|`ImplKind`|The implementation kind|None (must be set by the constructor)| -|`m_impl`|`ImplIterator`|The iterator for the implementation|C++ default initialization| - -#### 2.2.5. Public Constructors and Destructors - -##### 2.2.5.1. Constructor Providing an Array Implementation - -```c++ -ConstIterator(const ArraySetOrMapImpl& impl) -``` - -1. Set `m_implKind = ARRAY`. - -1. Set `m_implIterator.arrayIterator = ArrayIterator(impl);` - -##### 2.2.5.2. Constructor Providing a Red-Black Tree Implementation - -```c++ -ConstIterator(const RedBlackTreeSetOrMapImpl& impl) -``` - -1. Set `m_implKind = RED_BLACK_TREE`. - -1. Set `m_implIterator.array = RedBlackTreeIterator(impl);` - -##### 2.2.5.3. Copy Constructor - -```c++ -ConstIterator(const ConstIterator& it) -``` - -Defined as `= delete`. - -##### 2.2.5.4. Destructor - -```c++ -~ConstIterator() -``` - -Defined as `= default`. - -#### 2.2.6. Public Member Functions - -##### 2.2.6.1. operator= - -```c++ -ConstIterator& operator=(const ConstIterator& it) -``` - -Defined as `= delete`. - -##### 2.2.6.2. operator== - -```c++ -bool operator==(const ConstIterator& it) -``` - -1. If the implementations don't match, then return `false`. - -1. Otherwise delegate to the implementations. - -##### 2.2.6.3. operator++ - -```c++ -ConstIterator& operator++() -``` - -Delegated to the implementation. - -##### 2.2.6.4. getKeyOrElement - -```c++ -const KE& getKeyOrElement() const -``` - -Delegated to the implementation. - -##### 2.2.6.5. getValueOrNil - -```c++ -const KE& getValueOrNil() const -``` - -Delegated to the implementation. - -##### 2.2.6.6. isInRange() - -```c++ -bool isInRange() const -``` - -Delegated to the implementation. - -##### 2.2.6.7. reset - -```c++ -void reset() -``` - -Delegated to the implementation. - -## 3. Private Constructors - -### 3.1. Copy Constructor - -```c++ -MapBase(const MapBase& map) -``` - -Defined as `= delete`. +|`ConstItrator`|Alias of [`MapConstIterator`](MapConstIterator.md)| ## 4. Protected Constructors and Destructors @@ -190,27 +53,34 @@ virtual ~MapBase() Defined as `= default`. -## 5. Private Member Functions +## 5. Public Member Functions -### 5.1. operator= +### 5.1. begin ```c++ -MapBase& operator=(const MapBase&) +virtual ConstIterator begin() const = 0. ``` -Defined as `= delete`. - -## 6. Public Member Functions - -### 6.1. begin +Return the iterator for the implementation. -```c++ -ConstIterator begin() const = 0. +_Example:_ +``c++ +void f(MapBase& map) { + map.clear(); + // Insert an entry in the map + auto status = map.insert(0, 1); + ASSERT_EQ(status, Fw::Success::SUCCESS); + // Get a map const iterator object + auto it = map.begin(); + // Use the iterator to access the underlying map const entry + const key = it->getKey(); + const value = it->getValue(); + ASSERT_EQ(key, 0); + ASSERT_EQ(value, 1); +} ``` -Return the iterator for the implementation. - -### 6.2. clear +### 5.2. clear ```c++ virtual void clear() = 0 @@ -226,7 +96,7 @@ void f(MapBase& map) { } ``` -### 6.3. copyDataFrom +### 5.3. copyDataFrom ```c++ void copyDataFrom(const MapBase& map) @@ -238,17 +108,15 @@ void copyDataFrom(const MapBase& map) 1. Let `size` be the minimum of `map.getSize()` and `getCapacity()`. - 1. Set `e = map.getHeadMapEntry()`. + 1. Set `it = map.begin()`. 1. For `i` in [0, `size`) - 1. Assert `e != nullptr`. - - 1. Set `status = insert(e->getKey(), e->getValue())`. + 1. Set `status = insert(it->getKey(), it->getValue())`. 1. Assert `status == Success::SUCCESS`. - 1. Set `e = e->getNextMapEntry()` + 1. Call `it++`. _Example:_ ```c++ @@ -266,15 +134,33 @@ void f(MapBase& m1, MapBase& m2) { } ``` -### 6.4. end +### 5.4. end ```c++ -ConstIterator end() const = 0 +virtual ConstIterator end() const = 0 ``` Return the iterator for the implementation. -### 6.5. find +_Example:_ +``c++ +void f(MapBase& map) { + map.clear(); + // Insert an entry in the map + auto status = map.insert(0, 1); + ASSERT_EQ(status, Fw::Success::SUCCESS); + // Get a map const iterator object + auto iter = map.begin(); + // Check that iter is not at the end + ASSERT_NE(iter, map.end()); + // Increment iter + it++; + // Check that iter is at the end + ASSERT_EQ(iter, map.end()); +} +`` + +### 5.5. find ```c++ virtual Success find(const K& key, V& value) const = 0 @@ -300,7 +186,7 @@ void f(const MapBase& map) { } ``` -### 6.6. getCapacity +### 5.6. getCapacity ```c++ virtual FwSizeType getCapacity() const = 0 @@ -317,30 +203,7 @@ void f(const MapBase& map) { } ``` -### 6.7. getHeadMapEntry - -```c++ -virtual const MapEntry* getHeadMapEntry() const = 0 -``` - -Get a pointer to the head iterator for the map, or `nullptr` if there is none. - -_Example:_ -```c++ -void f(const MapBase& map) { - map.clear(); - const auto* e = map.getHeadMapEntry(); - ASSERT_EQ(e, nullptr); - map.insert(0, 1); - e = map.getHeadMapEntry(); - ASSERT_NE(e, nullptr); - ASSERT_EQ(e->getKey(), 0); - ASSERT_EQ(e->getValue(), 1); -} - -``` - -### 6.8. getSize +### 5.7. getSize ```c++ virtual FwSizeType getSize() const = 0 @@ -351,7 +214,7 @@ Return the current size. _Example:_ See [**getCapacity**](MapBase.md#64-getcapacity). -### 6.9. insert +### 5.8. insert ```c++ virtual Success insert(const K& key, const V& value) = 0 @@ -378,7 +241,7 @@ void f(MapBase& map) { } ``` -### 6.10. remove +### 5.9. remove ```c++ virtual Success remove(const K& key, V& value) = 0 diff --git a/Fw/DataStructures/docs/MapConstIterator.md b/Fw/DataStructures/docs/MapConstIterator.md new file mode 100644 index 00000000000..eb18f21568b --- /dev/null +++ b/Fw/DataStructures/docs/MapConstIterator.md @@ -0,0 +1,417 @@ +# MapConstIterator + +TODO + +`MapBase` is an abstract class template +defined in [`Fw/DataStructures`](sdd.md). +It represents an abstract base class for a map. + +## 1. Template Parameters + +`MapBase` has the following template parameters. + +|Kind|Name|Purpose| +|----|----|-------| +|`typename`|`K`|The type of a key in the map| +|`typename`|`V`|The type of a value in the map| + + +## 2. Public Types + + +### 2.1. Type Aliases + +`MapBase` defines the following public type aliases. + +|Name|Definition| +|----|----------| +|`MapEntry`|Alias of [`MapEntry`](MapEntry.md)| + +### 2.2. ConstIterator + +`ConstIterator` is a public inner class of `MapBase`. It provides +non-modifying iteration over the elements of a `MapBase` instance. + +#### 2.2.1. Public Type Aliases + +`ConstIterator` defines the following public type aliases. + +|Name|Definition| +|----|----------| +|ArrayIterator|An alias for `ArraySetOrMapImpl::ConstIterator`. +|RedBlackTreeIterator|An alias for `RedBlackTreeSetOrMapImpl::ConstIterator`. + +#### 2.2.2. Private Enumerations + +`ConstIterator` defines the following private enumerations. + +|Name|Definition| +|----|----------| +|ImplKind|An enumeration with values `ARRAY` and `RED_BLACK_TREE`| + +#### 2.2.3. Private Type Aliases + +`ConstIterator` defines the following private type aliases. + +|Name|Definition| +|----|----------| +|ImplIterator|A union with member variables `arrayIterator` of type `ArrayIterator` and `redBlackTreeIterator` of type `RedBlackTreeIterator`| + +#### 2.2.4. Private Member Variables + +`ConstIterator` has the following private member variables. + +|Name|Type|Purpose|Default Value| +|----|----|-------|-------------| +|`m_implKind`|`ImplKind`|The implementation kind|None (must be set by the constructor)| +|`m_impl`|`ImplIterator`|The iterator for the implementation|C++ default initialization| + +#### 2.2.5. Public Constructors and Destructors + +##### 2.2.5.1. Constructor Providing an Array Implementation + +```c++ +ConstIterator(const ArraySetOrMapImpl& impl) +``` + +1. Set `m_implKind = ARRAY`. + +1. Set `m_implIterator.arrayIterator = ArrayIterator(impl);` + +##### 2.2.5.2. Constructor Providing a Red-Black Tree Implementation + +```c++ +ConstIterator(const RedBlackTreeSetOrMapImpl& impl) +``` + +1. Set `m_implKind = RED_BLACK_TREE`. + +1. Set `m_implIterator.array = RedBlackTreeIterator(impl);` + +##### 2.2.5.3. Copy Constructor + +```c++ +ConstIterator(const ConstIterator& it) +``` + +Defined as `= delete`. + +##### 2.2.5.4. Destructor + +```c++ +~ConstIterator() +``` + +Defined as `= default`. + +#### 2.2.6. Public Member Functions + +##### 2.2.6.1. operator= + +```c++ +ConstIterator& operator=(const ConstIterator& it) +``` + +Defined as `= delete`. + +##### 2.2.6.2. operator== + +```c++ +bool operator==(const ConstIterator& it) +``` + +1. If the implementations don't match, then return `false`. + +1. Otherwise delegate to the implementations. + +##### 2.2.6.3. operator++ + +```c++ +ConstIterator& operator++() +``` + +Delegated to the implementation. + +##### 2.2.6.4. getKeyOrElement + +```c++ +const KE& getKeyOrElement() const +``` + +Delegated to the implementation. + +##### 2.2.6.5. getValueOrNil + +```c++ +const KE& getValueOrNil() const +``` + +Delegated to the implementation. + +##### 2.2.6.6. isInRange() + +```c++ +bool isInRange() const +``` + +Delegated to the implementation. + +##### 2.2.6.7. reset + +```c++ +void reset() +``` + +Delegated to the implementation. + +## 3. Private Constructors + +### 3.1. Copy Constructor + +```c++ +MapBase(const MapBase& map) +``` + +Defined as `= delete`. + +## 4. Protected Constructors and Destructors + +### 4.1. Zero-Argument Constructor + +```c++ +MapBase() +``` + +Use default initialization of members. + +### 4.2. Destructor + +```c++ +virtual ~MapBase() +``` + +Defined as `= default`. + +## 5. Private Member Functions + +### 5.1. operator= + +```c++ +MapBase& operator=(const MapBase&) +``` + +Defined as `= delete`. + +## 6. Public Member Functions + +### 6.1. begin + +```c++ +ConstIterator begin() const = 0. +``` + +Return the iterator for the implementation. + +### 6.2. clear + +```c++ +virtual void clear() = 0 +``` + +Clear the map. + +_Example:_ +```c++ +void f(MapBase& map) { + map.clear(); + ASSERT_EQ(map.getSize(), 0); +} +``` + +### 6.3. copyDataFrom + +```c++ +void copyDataFrom(const MapBase& map) +``` + +1. If `&map != this` then + + 1. Call `clear()`. + + 1. Let `size` be the minimum of `map.getSize()` and `getCapacity()`. + + 1. Set `e = map.getHeadMapEntry()`. + + 1. For `i` in [0, `size`) + + 1. Assert `e != nullptr`. + + 1. Set `status = insert(e->getKey(), e->getValue())`. + + 1. Assert `status == Success::SUCCESS`. + + 1. Set `e = e->getNextMapEntry()` + +_Example:_ +```c++ +void f(MapBase& m1, MapBase& m2) { + m1.clear(); + // Insert an entry + const U16 key = 0 + const U32 value = 42; + const auto status = m1.insert(key, value); + ASSERT_EQ(status, Success::SUCCESS); + m2.clear(); + ASSERT_EQ(m2.getSize(), 0); + m2.copyDataFrom(q1); + ASSERT_EQ(m2.getSize(), 1); +} +``` + +### 6.4. end + +```c++ +ConstIterator end() const = 0 +``` + +Return the iterator for the implementation. + +### 6.5. find + +```c++ +virtual Success find(const K& key, V& value) const = 0 +``` + +1. If an entry `e` with value `key` exists in the map, +then set `value = e.getValue()` and return `SUCCESS`. + +1. Otherwise return `FAILURE`. + +_Example:_ +```c++ +void f(const MapBase& map) { + map.clear(); + U32 value = 0; + auto status = map.find(0, value); + ASSERT_EQ(status, Success::FAILURE); + status = map.insert(0, 1); + ASSERT_EQ(status, Success::SUCCESS); + status = map.find(0, value); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(value, 1); +} +``` + +### 6.6. getCapacity + +```c++ +virtual FwSizeType getCapacity() const = 0 +``` + +Return the current capacity. + +_Example:_ +```c++ +void f(const MapBase& map) { + const auto size = map.getSize(); + const auto capacity = map.getCapacity(); + ASSERT_LE(size, capacity); +} +``` + +### 6.7. getHeadMapEntry + +```c++ +virtual const MapEntry* getHeadMapEntry() const = 0 +``` + +Get a pointer to the head iterator for the map, or `nullptr` if there is none. + +_Example:_ +```c++ +void f(const MapBase& map) { + map.clear(); + const auto* e = map.getHeadMapEntry(); + ASSERT_EQ(e, nullptr); + map.insert(0, 1); + e = map.getHeadMapEntry(); + ASSERT_NE(e, nullptr); + ASSERT_EQ(e->getKey(), 0); + ASSERT_EQ(e->getValue(), 1); +} + +``` + +### 6.8. getSize + +```c++ +virtual FwSizeType getSize() const = 0 +``` + +Return the current size. + +_Example:_ +See [**getCapacity**](MapBase.md#64-getcapacity). + +### 6.9. insert + +```c++ +virtual Success insert(const K& key, const V& value) = 0 +``` + +1. If an entry `e` exists with the specified key, then update the + value in `e` and return `SUCCESS`. + +1. Otherwise if there is room in the map, then add a new entry `e` with the +specified key-value pair and return `SUCCESS`. + +1. Otherwise return `FAILURE`. + +_Example:_ +```c++ +void f(MapBase& map) { + map.clear(); + auto size = map.getSize(); + ASSERT_EQ(size, 0); + const auto status = map.insert(0, 1); + ASSERT_EQ(status, Success::SUCCESS); + size = map.getSize(); + ASSERT_EQ(size, 1); +} +``` + +### 6.10. remove + +```c++ +virtual Success remove(const K& key, V& value) = 0 +``` + +1. If an entry `e` exists with key `key`, then +store the value of `e` into `value`, +remove `e` from the map, and return `SUCCESS`. + +1. Otherwise return `FAILURE`. + +_Example:_ +```c++ +void f(MapBase& map) { + map.clear(); + auto size = map.getSize(); + ASSERT_EQ(size, 0); + auto status = map.insert(0, 1); + ASSERT_EQ(status, Success::SUCCESS); + size = map.getSize(); + ASSERT_EQ(size, 1); + // Key does not exist + U32 value = 0; + status = map.remove(10, value); + ASSERT_EQ(status, Success::FAILURE); + ASSERT_EQ(size, 1); + // Key exists + status = map.remove(0, value); + ASSERT_EQ(status, Success::SUCCESS); + ASSERT_EQ(size, 0); + ASSERT_EQ(value, 1); +} +``` + From 46006bbd08a6d053480bc31ae0dc6c30a7951e54 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 08:38:30 -0700 Subject: [PATCH 373/458] Revise MapBase --- Fw/DataStructures/docs/MapBase.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index d5ae3fb4958..63a09771392 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -15,7 +15,7 @@ It represents an abstract base class for a map. ## 2. Deleted Elements -The following elements are defined `= delete`: +The following elements are private and are defined `= delete`: 1. The copy constructor. ```c++ @@ -64,7 +64,7 @@ virtual ConstIterator begin() const = 0. Return the iterator for the implementation. _Example:_ -``c++ +```c++ void f(MapBase& map) { map.clear(); // Insert an entry in the map @@ -143,7 +143,7 @@ virtual ConstIterator end() const = 0 Return the iterator for the implementation. _Example:_ -``c++ +```c++ void f(MapBase& map) { map.clear(); // Insert an entry in the map From 6fe99dd244afaed476f05e3ef3043a3373392672 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 08:39:38 -0700 Subject: [PATCH 374/458] Revise MapBase --- Fw/DataStructures/docs/MapBase.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index 63a09771392..c1b0df84a7d 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -33,7 +33,7 @@ The following elements are private and are defined `= delete`: |Name|Definition| |----|----------| -|`ConstItrator`|Alias of [`MapConstIterator`](MapConstIterator.md)| +|`ConstIterator`|Alias of [`MapConstIterator`](MapConstIterator.md)| ## 4. Protected Constructors and Destructors From 6a1eca5adf8a6336fe50d422d88cdce00d2f97c4 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 09:02:21 -0700 Subject: [PATCH 375/458] Revise iterators --- Fw/DataStructures/ArraySetOrMapImpl.hpp | 7 +- Fw/DataStructures/MapConstIterator.hpp | 3 - Fw/DataStructures/SetConstIterator.hpp | 3 - .../SetOrMapImplConstIterator.hpp | 2 - Fw/DataStructures/docs/MapConstIterator.md | 397 +----------------- 5 files changed, 25 insertions(+), 387 deletions(-) diff --git a/Fw/DataStructures/ArraySetOrMapImpl.hpp b/Fw/DataStructures/ArraySetOrMapImpl.hpp index 402f1b6c609..3f9d66d0fb2 100644 --- a/Fw/DataStructures/ArraySetOrMapImpl.hpp +++ b/Fw/DataStructures/ArraySetOrMapImpl.hpp @@ -43,12 +43,12 @@ class ArraySetOrMapImpl final { //! Constructor providing the implementation ConstIterator(const ArraySetOrMapImpl& impl) : SetOrMapImplConstIterator(), m_impl(&impl) { - this->reset(); + this->m_index = 0; } //! Copy constructor ConstIterator(const ConstIterator& it) : SetOrMapImplConstIterator(), m_impl(it.m_impl) { - this->reset(); + this->m_index = 0; } //! Destructor @@ -100,9 +100,6 @@ class ArraySetOrMapImpl final { return this->m_index < this->m_impl->m_size; } - //! Reset the iterator - void reset() override { this->m_index = 0; } - //! Set the index value void setIndex(FwSizeType index) { this->m_index = index; } diff --git a/Fw/DataStructures/MapConstIterator.hpp b/Fw/DataStructures/MapConstIterator.hpp index bbbfd6e13de..fe4ebb60eb0 100644 --- a/Fw/DataStructures/MapConstIterator.hpp +++ b/Fw/DataStructures/MapConstIterator.hpp @@ -121,9 +121,6 @@ class MapConstIterator { //! Check whether the iterator is in range bool isInRange() const { return this->getImplIterator().isInRange(); } - //! Reset the iterator - void reset() { return this->getImplIterator().reset(); } - //! Dereference const MapConstEntry& operator*() const { return this->getImplIterator().getEntry(); } diff --git a/Fw/DataStructures/SetConstIterator.hpp b/Fw/DataStructures/SetConstIterator.hpp index d226df13496..cb08d849ed3 100644 --- a/Fw/DataStructures/SetConstIterator.hpp +++ b/Fw/DataStructures/SetConstIterator.hpp @@ -121,9 +121,6 @@ class SetConstIterator { //! Check whether the iterator is in range bool isInRange() const { return this->getImplIterator().isInRange(); } - //! Reset the iterator - void reset() { return this->getImplIterator().reset(); } - //! Dereference const T& operator*() const { return this->getImplIterator().getEntry().getKeyOrElement(); } diff --git a/Fw/DataStructures/SetOrMapImplConstIterator.hpp b/Fw/DataStructures/SetOrMapImplConstIterator.hpp index 4c996de9683..f3c59e0d503 100644 --- a/Fw/DataStructures/SetOrMapImplConstIterator.hpp +++ b/Fw/DataStructures/SetOrMapImplConstIterator.hpp @@ -64,8 +64,6 @@ class SetOrMapImplConstIterator { //! \return The set or map impl entry virtual const SetOrMapImplEntry& getEntry() const = 0; - //! Reset the iterator - virtual void reset() = 0; }; } // namespace Fw diff --git a/Fw/DataStructures/docs/MapConstIterator.md b/Fw/DataStructures/docs/MapConstIterator.md index eb18f21568b..46bda618b4b 100644 --- a/Fw/DataStructures/docs/MapConstIterator.md +++ b/Fw/DataStructures/docs/MapConstIterator.md @@ -1,10 +1,6 @@ # MapConstIterator -TODO - -`MapBase` is an abstract class template -defined in [`Fw/DataStructures`](sdd.md). -It represents an abstract base class for a map. +`MapConstIterator` is a class for iterating over a map. ## 1. Template Parameters @@ -15,403 +11,56 @@ It represents an abstract base class for a map. |`typename`|`K`|The type of a key in the map| |`typename`|`V`|The type of a value in the map| - -## 2. Public Types - - -### 2.1. Type Aliases - -`MapBase` defines the following public type aliases. - -|Name|Definition| -|----|----------| -|`MapEntry`|Alias of [`MapEntry`](MapEntry.md)| - -### 2.2. ConstIterator - -`ConstIterator` is a public inner class of `MapBase`. It provides -non-modifying iteration over the elements of a `MapBase` instance. - -#### 2.2.1. Public Type Aliases - -`ConstIterator` defines the following public type aliases. - -|Name|Definition| -|----|----------| -|ArrayIterator|An alias for `ArraySetOrMapImpl::ConstIterator`. -|RedBlackTreeIterator|An alias for `RedBlackTreeSetOrMapImpl::ConstIterator`. - -#### 2.2.2. Private Enumerations - -`ConstIterator` defines the following private enumerations. - -|Name|Definition| -|----|----------| -|ImplKind|An enumeration with values `ARRAY` and `RED_BLACK_TREE`| - -#### 2.2.3. Private Type Aliases - -`ConstIterator` defines the following private type aliases. - -|Name|Definition| -|----|----------| -|ImplIterator|A union with member variables `arrayIterator` of type `ArrayIterator` and `redBlackTreeIterator` of type `RedBlackTreeIterator`| - -#### 2.2.4. Private Member Variables - -`ConstIterator` has the following private member variables. - -|Name|Type|Purpose|Default Value| -|----|----|-------|-------------| -|`m_implKind`|`ImplKind`|The implementation kind|None (must be set by the constructor)| -|`m_impl`|`ImplIterator`|The iterator for the implementation|C++ default initialization| - -#### 2.2.5. Public Constructors and Destructors - -##### 2.2.5.1. Constructor Providing an Array Implementation +## 2. Constructors and Destructors -```c++ -ConstIterator(const ArraySetOrMapImpl& impl) -``` - -1. Set `m_implKind = ARRAY`. - -1. Set `m_implIterator.arrayIterator = ArrayIterator(impl);` - -##### 2.2.5.2. Constructor Providing a Red-Black Tree Implementation - -```c++ -ConstIterator(const RedBlackTreeSetOrMapImpl& impl) -``` - -1. Set `m_implKind = RED_BLACK_TREE`. - -1. Set `m_implIterator.array = RedBlackTreeIterator(impl);` +`MapConstIterator` provides the following constructors and destructors: -##### 2.2.5.3. Copy Constructor +1. One constructor for each map implementation. +1. A copy constructor. +1. A destructor. -```c++ -ConstIterator(const ConstIterator& it) -``` - -Defined as `= delete`. +## 3. Public Member Functions -##### 2.2.5.4. Destructor +`MapConstIterator` provides the following member functions. -```c++ -~ConstIterator() -``` +### 3.1. operator= Defined as `= default`. -#### 2.2.6. Public Member Functions - -##### 2.2.6.1. operator= +### 3.2. operator== ```c++ -ConstIterator& operator=(const ConstIterator& it) +bool operator==(const MapConstIterator& it) ``` -Defined as `= delete`. - -##### 2.2.6.2. operator== - -```c++ -bool operator==(const ConstIterator& it) -``` +Compare two `MapConstIterator` instances for equality. -1. If the implementations don't match, then return `false`. +1. If the implementations differ, then return `false`. -1. Otherwise delegate to the implementations. +1. Otherwise delegate the comparison to the common implementation. -##### 2.2.6.3. operator++ +### operator != ```c++ -ConstIterator& operator++() +bool operator!=(const MapConstIterator& it) ``` -Delegated to the implementation. +Defined as the negation of `operator=`. -##### 2.2.6.4. getKeyOrElement -```c++ -const KE& getKeyOrElement() const -``` - -Delegated to the implementation. - -##### 2.2.6.5. getValueOrNil +### 3.3. operator++ ```c++ -const KE& getValueOrNil() const +MapConstIterator& operator++() +MapConstIterator& operator++(int) ``` -Delegated to the implementation. +Increment the iterator. -##### 2.2.6.6. isInRange() +### 3.4. isInRange() ```c++ bool isInRange() const ``` -Delegated to the implementation. - -##### 2.2.6.7. reset - -```c++ -void reset() -``` - -Delegated to the implementation. - -## 3. Private Constructors - -### 3.1. Copy Constructor - -```c++ -MapBase(const MapBase& map) -``` - -Defined as `= delete`. - -## 4. Protected Constructors and Destructors - -### 4.1. Zero-Argument Constructor - -```c++ -MapBase() -``` - -Use default initialization of members. - -### 4.2. Destructor - -```c++ -virtual ~MapBase() -``` - -Defined as `= default`. - -## 5. Private Member Functions - -### 5.1. operator= - -```c++ -MapBase& operator=(const MapBase&) -``` - -Defined as `= delete`. - -## 6. Public Member Functions - -### 6.1. begin - -```c++ -ConstIterator begin() const = 0. -``` - -Return the iterator for the implementation. - -### 6.2. clear - -```c++ -virtual void clear() = 0 -``` - -Clear the map. - -_Example:_ -```c++ -void f(MapBase& map) { - map.clear(); - ASSERT_EQ(map.getSize(), 0); -} -``` - -### 6.3. copyDataFrom - -```c++ -void copyDataFrom(const MapBase& map) -``` - -1. If `&map != this` then - - 1. Call `clear()`. - - 1. Let `size` be the minimum of `map.getSize()` and `getCapacity()`. - - 1. Set `e = map.getHeadMapEntry()`. - - 1. For `i` in [0, `size`) - - 1. Assert `e != nullptr`. - - 1. Set `status = insert(e->getKey(), e->getValue())`. - - 1. Assert `status == Success::SUCCESS`. - - 1. Set `e = e->getNextMapEntry()` - -_Example:_ -```c++ -void f(MapBase& m1, MapBase& m2) { - m1.clear(); - // Insert an entry - const U16 key = 0 - const U32 value = 42; - const auto status = m1.insert(key, value); - ASSERT_EQ(status, Success::SUCCESS); - m2.clear(); - ASSERT_EQ(m2.getSize(), 0); - m2.copyDataFrom(q1); - ASSERT_EQ(m2.getSize(), 1); -} -``` - -### 6.4. end - -```c++ -ConstIterator end() const = 0 -``` - -Return the iterator for the implementation. - -### 6.5. find - -```c++ -virtual Success find(const K& key, V& value) const = 0 -``` - -1. If an entry `e` with value `key` exists in the map, -then set `value = e.getValue()` and return `SUCCESS`. - -1. Otherwise return `FAILURE`. - -_Example:_ -```c++ -void f(const MapBase& map) { - map.clear(); - U32 value = 0; - auto status = map.find(0, value); - ASSERT_EQ(status, Success::FAILURE); - status = map.insert(0, 1); - ASSERT_EQ(status, Success::SUCCESS); - status = map.find(0, value); - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(value, 1); -} -``` - -### 6.6. getCapacity - -```c++ -virtual FwSizeType getCapacity() const = 0 -``` - -Return the current capacity. - -_Example:_ -```c++ -void f(const MapBase& map) { - const auto size = map.getSize(); - const auto capacity = map.getCapacity(); - ASSERT_LE(size, capacity); -} -``` - -### 6.7. getHeadMapEntry - -```c++ -virtual const MapEntry* getHeadMapEntry() const = 0 -``` - -Get a pointer to the head iterator for the map, or `nullptr` if there is none. - -_Example:_ -```c++ -void f(const MapBase& map) { - map.clear(); - const auto* e = map.getHeadMapEntry(); - ASSERT_EQ(e, nullptr); - map.insert(0, 1); - e = map.getHeadMapEntry(); - ASSERT_NE(e, nullptr); - ASSERT_EQ(e->getKey(), 0); - ASSERT_EQ(e->getValue(), 1); -} - -``` - -### 6.8. getSize - -```c++ -virtual FwSizeType getSize() const = 0 -``` - -Return the current size. - -_Example:_ -See [**getCapacity**](MapBase.md#64-getcapacity). - -### 6.9. insert - -```c++ -virtual Success insert(const K& key, const V& value) = 0 -``` - -1. If an entry `e` exists with the specified key, then update the - value in `e` and return `SUCCESS`. - -1. Otherwise if there is room in the map, then add a new entry `e` with the -specified key-value pair and return `SUCCESS`. - -1. Otherwise return `FAILURE`. - -_Example:_ -```c++ -void f(MapBase& map) { - map.clear(); - auto size = map.getSize(); - ASSERT_EQ(size, 0); - const auto status = map.insert(0, 1); - ASSERT_EQ(status, Success::SUCCESS); - size = map.getSize(); - ASSERT_EQ(size, 1); -} -``` - -### 6.10. remove - -```c++ -virtual Success remove(const K& key, V& value) = 0 -``` - -1. If an entry `e` exists with key `key`, then -store the value of `e` into `value`, -remove `e` from the map, and return `SUCCESS`. - -1. Otherwise return `FAILURE`. - -_Example:_ -```c++ -void f(MapBase& map) { - map.clear(); - auto size = map.getSize(); - ASSERT_EQ(size, 0); - auto status = map.insert(0, 1); - ASSERT_EQ(status, Success::SUCCESS); - size = map.getSize(); - ASSERT_EQ(size, 1); - // Key does not exist - U32 value = 0; - status = map.remove(10, value); - ASSERT_EQ(status, Success::FAILURE); - ASSERT_EQ(size, 1); - // Key exists - status = map.remove(0, value); - ASSERT_EQ(status, Success::SUCCESS); - ASSERT_EQ(size, 0); - ASSERT_EQ(value, 1); -} -``` - +Check whether the iterator is in range. From 0b79030d44a9a2ae367759943f723b290d7c2fc8 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 09:13:09 -0700 Subject: [PATCH 376/458] Revise MapConstIterator docs --- Fw/DataStructures/MapConstIterator.hpp | 5 ++- Fw/DataStructures/docs/MapConstIterator.md | 46 +++++++++++++++++----- 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/Fw/DataStructures/MapConstIterator.hpp b/Fw/DataStructures/MapConstIterator.hpp index fe4ebb60eb0..2d609c07c6b 100644 --- a/Fw/DataStructures/MapConstIterator.hpp +++ b/Fw/DataStructures/MapConstIterator.hpp @@ -24,6 +24,7 @@ class MapConstIterator { //! The type of an array iterator using ArrayIterator = typename ArraySetOrMapImpl::ConstIterator; + using MapConstEntry = MapConstEntry; private: // ---------------------------------------------------------------------- @@ -122,10 +123,10 @@ class MapConstIterator { bool isInRange() const { return this->getImplIterator().isInRange(); } //! Dereference - const MapConstEntry& operator*() const { return this->getImplIterator().getEntry(); } + const MapConstEntry& operator*() const { return this->getImplIterator().getEntry(); } //! Pointer - const MapConstEntry* operator->() const { return &this->getImplIterator().getEntry(); } + const MapConstEntry* operator->() const { return &this->getImplIterator().getEntry(); } private: // ---------------------------------------------------------------------- diff --git a/Fw/DataStructures/docs/MapConstIterator.md b/Fw/DataStructures/docs/MapConstIterator.md index 46bda618b4b..4bb0b4fc13b 100644 --- a/Fw/DataStructures/docs/MapConstIterator.md +++ b/Fw/DataStructures/docs/MapConstIterator.md @@ -1,6 +1,6 @@ # MapConstIterator -`MapConstIterator` is a class for iterating over a map. +`MapConstIterator` is a class for performing const iteration over a map. ## 1. Template Parameters @@ -11,23 +11,34 @@ |`typename`|`K`|The type of a key in the map| |`typename`|`V`|The type of a value in the map| -## 2. Constructors and Destructors +## 2. Public Types + +`MapConstIterator` defines the following public types: + +|Name|Definition| +|----|----------| +|`MapEntry`|Alias of [`MapEntry`](MapEntry.md)| + +## 3. Constructors and Destructors `MapConstIterator` provides the following constructors and destructors: 1. One constructor for each map implementation. + The map implementations use these constructors to provide iterators. + 1. A copy constructor. + 1. A destructor. -## 3. Public Member Functions +## 4. Public Member Functions `MapConstIterator` provides the following member functions. -### 3.1. operator= +### 4.1. operator= Defined as `= default`. -### 3.2. operator== +### 4.2. operator== ```c++ bool operator==(const MapConstIterator& it) @@ -39,7 +50,7 @@ Compare two `MapConstIterator` instances for equality. 1. Otherwise delegate the comparison to the common implementation. -### operator != +### 4.3. operator != ```c++ bool operator!=(const MapConstIterator& it) @@ -47,8 +58,7 @@ bool operator!=(const MapConstIterator& it) Defined as the negation of `operator=`. - -### 3.3. operator++ +### 4.4. operator++ ```c++ MapConstIterator& operator++() @@ -57,10 +67,28 @@ MapConstIterator& operator++(int) Increment the iterator. -### 3.4. isInRange() +### 4.5. isInRange() ```c++ bool isInRange() const ``` Check whether the iterator is in range. + +### 4.6. operator* + +```c++ +const MapEntry& operator*() const +``` + +Return a const reference to the `MapEntry` object +pointed to by the itertor. + +### 4.7. operator-> + +```c++ +const MapEntry* operator->() const +``` + +Return a pointer to the const `MapEntry` object +pointed to by the iterator. From a97ff4f7f0f3b59550e1d3de4adc80a6397c7375 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 09:15:03 -0700 Subject: [PATCH 377/458] Rename MapConstEntry to MapEntry --- Fw/DataStructures/ArrayMap.hpp | 2 +- Fw/DataStructures/ExternalArrayMap.hpp | 2 +- Fw/DataStructures/MapConstIterator.hpp | 8 ++--- .../{MapConstEntry.hpp => MapEntry.hpp} | 33 ++++++++----------- Fw/DataStructures/SetOrMapImplEntry.hpp | 10 +++--- 5 files changed, 25 insertions(+), 30 deletions(-) rename Fw/DataStructures/{MapConstEntry.hpp => MapEntry.hpp} (69%) diff --git a/Fw/DataStructures/ArrayMap.hpp b/Fw/DataStructures/ArrayMap.hpp index a2f4c6bfdb3..a6673c67a83 100644 --- a/Fw/DataStructures/ArrayMap.hpp +++ b/Fw/DataStructures/ArrayMap.hpp @@ -29,7 +29,7 @@ class ArrayMap final : public MapBase { using ImplEntry = SetOrMapImplEntry; //! The type of a map entry - using MapConstEntry = MapConstEntry; + using MapEntry = MapEntry; //! The type of the implementation entries using ImplEntries = ImplEntry[C]; diff --git a/Fw/DataStructures/ExternalArrayMap.hpp b/Fw/DataStructures/ExternalArrayMap.hpp index e3ff803d655..43e2bd1b624 100644 --- a/Fw/DataStructures/ExternalArrayMap.hpp +++ b/Fw/DataStructures/ExternalArrayMap.hpp @@ -31,7 +31,7 @@ class ExternalArrayMap final : public MapBase { using ImplEntry = SetOrMapImplEntry; //! The type of a map entry - using MapConstEntry = MapConstEntry; + using MapEntry = MapEntry; public: // ---------------------------------------------------------------------- diff --git a/Fw/DataStructures/MapConstIterator.hpp b/Fw/DataStructures/MapConstIterator.hpp index 2d609c07c6b..a7acc8eb52e 100644 --- a/Fw/DataStructures/MapConstIterator.hpp +++ b/Fw/DataStructures/MapConstIterator.hpp @@ -10,7 +10,7 @@ #include #include "Fw/DataStructures/ArraySetOrMapImpl.hpp" -#include "Fw/DataStructures/MapConstEntry.hpp" +#include "Fw/DataStructures/MapEntry.hpp" #include "Fw/FPrimeBasicTypes.hpp" namespace Fw { @@ -24,7 +24,7 @@ class MapConstIterator { //! The type of an array iterator using ArrayIterator = typename ArraySetOrMapImpl::ConstIterator; - using MapConstEntry = MapConstEntry; + using MapEntry = MapEntry; private: // ---------------------------------------------------------------------- @@ -123,10 +123,10 @@ class MapConstIterator { bool isInRange() const { return this->getImplIterator().isInRange(); } //! Dereference - const MapConstEntry& operator*() const { return this->getImplIterator().getEntry(); } + const MapEntry& operator*() const { return this->getImplIterator().getEntry(); } //! Pointer - const MapConstEntry* operator->() const { return &this->getImplIterator().getEntry(); } + const MapEntry* operator->() const { return &this->getImplIterator().getEntry(); } private: // ---------------------------------------------------------------------- diff --git a/Fw/DataStructures/MapConstEntry.hpp b/Fw/DataStructures/MapEntry.hpp similarity index 69% rename from Fw/DataStructures/MapConstEntry.hpp rename to Fw/DataStructures/MapEntry.hpp index a6767a4bb6c..69b481fbceb 100644 --- a/Fw/DataStructures/MapConstEntry.hpp +++ b/Fw/DataStructures/MapEntry.hpp @@ -1,26 +1,31 @@ // ====================================================================== -// \title MapConstEntry +// \title MapEntry // \author bocchino -// \brief An abstract class template representing a constant entry for a map +// \brief An abstract class template representing an entry in a map // ====================================================================== -#ifndef Fw_MapConstEntry_HPP -#define Fw_MapConstEntry_HPP +#ifndef Fw_MapEntry_HPP +#define Fw_MapEntry_HPP #include "Fw/FPrimeBasicTypes.hpp" namespace Fw { template -class MapConstEntry { +class MapEntry { private: // ---------------------------------------------------------------------- - // Private constructors + // Deleted elements // ---------------------------------------------------------------------- //! Copy constructor deleted in the base class //! Behavior depends on the implementation - MapConstEntry(const MapConstEntry&) = delete; + MapEntry(const MapEntry&) = delete; + + //! operator= deleted in the base class + //! Behavior depends on the implementation + //! We avoid virtual user-defined operators + MapEntry& operator=(const MapEntry&) = delete; protected: // ---------------------------------------------------------------------- @@ -28,20 +33,10 @@ class MapConstEntry { // ---------------------------------------------------------------------- //! Zero-argument constructor - MapConstEntry() {} + MapEntry() {} //! Destructor - virtual ~MapConstEntry() = default; - - private: - // ---------------------------------------------------------------------- - // Private member functions - // ---------------------------------------------------------------------- - - //! operator= deleted in the base class - //! Behavior depends on the implementation - //! We avoid virtual user-defined operators - MapConstEntry& operator=(const MapConstEntry&) = delete; + virtual ~MapEntry() = default; public: // ---------------------------------------------------------------------- diff --git a/Fw/DataStructures/SetOrMapImplEntry.hpp b/Fw/DataStructures/SetOrMapImplEntry.hpp index 6e7d658a6b2..9df7c9f6c0a 100644 --- a/Fw/DataStructures/SetOrMapImplEntry.hpp +++ b/Fw/DataStructures/SetOrMapImplEntry.hpp @@ -7,26 +7,26 @@ #ifndef Fw_SetOrMapImplEntry_HPP #define Fw_SetOrMapImplEntry_HPP -#include "Fw/DataStructures/MapConstEntry.hpp" +#include "Fw/DataStructures/MapEntry.hpp" #include "Fw/FPrimeBasicTypes.hpp" namespace Fw { template -class SetOrMapImplEntry final : public MapConstEntry { +class SetOrMapImplEntry final : public MapEntry { public: // ---------------------------------------------------------------------- // Public constructors and destructors // ---------------------------------------------------------------------- //! Zero-argument constructor - SetOrMapImplEntry() : MapConstEntry() {} + SetOrMapImplEntry() : MapEntry() {} //! Constructor providing members SetOrMapImplEntry(const KE& keyOrElement, //!< The key or element const VN& valueOrNil //!< The value or Nil ) - : MapConstEntry(), m_keyOrElement(keyOrElement), m_valueOrNil(valueOrNil) {} + : MapEntry(), m_keyOrElement(keyOrElement), m_valueOrNil(valueOrNil) {} //! Copy constructor SetOrMapImplEntry(const SetOrMapImplEntry& entry) { *this = entry; } @@ -67,7 +67,7 @@ class SetOrMapImplEntry final : public MapConstEntry { public: // ---------------------------------------------------------------------- - // MapConstEntry implementation + // MapEntry implementation // ---------------------------------------------------------------------- //! Get the key associated with this entry From 95dac0ba16fc849d2318f9f681c809b1855cc0de Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 09:19:06 -0700 Subject: [PATCH 378/458] Revise MapEntry --- Fw/DataStructures/MapEntry.hpp | 2 +- Fw/DataStructures/docs/MapConstIterator.md | 2 +- Fw/DataStructures/docs/MapEntry.md | 58 +++++----------------- 3 files changed, 14 insertions(+), 48 deletions(-) diff --git a/Fw/DataStructures/MapEntry.hpp b/Fw/DataStructures/MapEntry.hpp index 69b481fbceb..7fc7021e84b 100644 --- a/Fw/DataStructures/MapEntry.hpp +++ b/Fw/DataStructures/MapEntry.hpp @@ -33,7 +33,7 @@ class MapEntry { // ---------------------------------------------------------------------- //! Zero-argument constructor - MapEntry() {} + MapEntry() = default; //! Destructor virtual ~MapEntry() = default; diff --git a/Fw/DataStructures/docs/MapConstIterator.md b/Fw/DataStructures/docs/MapConstIterator.md index 4bb0b4fc13b..ef51499034c 100644 --- a/Fw/DataStructures/docs/MapConstIterator.md +++ b/Fw/DataStructures/docs/MapConstIterator.md @@ -82,7 +82,7 @@ const MapEntry& operator*() const ``` Return a const reference to the `MapEntry` object -pointed to by the itertor. +pointed to by the iterator. ### 4.7. operator-> diff --git a/Fw/DataStructures/docs/MapEntry.md b/Fw/DataStructures/docs/MapEntry.md index 25b95b6cca9..f5ce2d74ef0 100644 --- a/Fw/DataStructures/docs/MapEntry.md +++ b/Fw/DataStructures/docs/MapEntry.md @@ -2,7 +2,7 @@ `MapEntry` is an abstract class template defined in [`Fw/DataStructures`](sdd.md). -It represents an iterator for a map. +It represents an entry for a map. ## 1. Template Parameters @@ -13,66 +13,32 @@ It represents an iterator for a map. |`typename`|`K`|The type of a key in the map| |`typename`|`V`|The type of a value in the map| -## 2. Private Constructors and Destructors +## 2. Deleted elements -### 2.1. Copy Constructor - -```c++ -MapEntry(const MapEntry& map) -``` - -Defined as `= delete`. +Because this is an abstract base class, +the copy constructor and copy assignment operator are deleted. ## 3. Protected Constructors and Destructors -### 3.1. Zero-Argument Constructor - -```c++ -MapEntry() -``` - -Use default initialization of members. - -### 3.2. Destructor - -```c++ -virtual ~MapEntry() -``` - -Defined as `= default`. - -## 4. Private Member Functions - -### 4.1. operator= - -```c++ -MapEntry& operator=(const MapEntry&) -``` - +`MapEntry` provides a protected zero-argument constructor +and a protected virtual destructor. +It uses the default implementations. Defined as `= delete`. -## 5. Public Member Functions +## 4. Public Member Functions -### 5.1. getKey +### 4.1. getKey ```c++ virtual const K& getKey() const = 0 ``` -Return a reference to the key. +Return a const reference to the key stored in the entry. -### 5.2. getValue +### 4.2. getValue ```c++ virtual const V& getValue() const = 0 ``` -Return a reference to the value. - -### 5.3. getNextMapEntry - -```c++ -virtual const MapEntry* getNextMapEntry() = 0 -``` - -Return a pointer to the next map iterator, or `nullptr` if there is none. +Return a const reference to the value stored in the entry. From 77f7ccb703e9bdf6be5477659a7fbae6b08f76aa Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 09:20:29 -0700 Subject: [PATCH 379/458] Fix MapBase docs --- Fw/DataStructures/docs/MapBase.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index c1b0df84a7d..081ebb2a755 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -158,7 +158,7 @@ void f(MapBase& map) { // Check that iter is at the end ASSERT_EQ(iter, map.end()); } -`` +``` ### 5.5. find From 171a9e3081ba08cbe2ed6c360732dbfb7573c274 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 09:25:33 -0700 Subject: [PATCH 380/458] Revise MapConstIterator --- Fw/DataStructures/MapBase.hpp | 4 ++-- Fw/DataStructures/docs/MapBase.md | 4 ++-- Fw/DataStructures/docs/MapConstIterator.md | 12 ++++++------ Fw/DataStructures/docs/MapEntry.md | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Fw/DataStructures/MapBase.hpp b/Fw/DataStructures/MapBase.hpp index a0b51a26be0..b25be633c90 100644 --- a/Fw/DataStructures/MapBase.hpp +++ b/Fw/DataStructures/MapBase.hpp @@ -53,7 +53,7 @@ class MapBase { // Public member functions // ---------------------------------------------------------------------- - //! Get the begin iterator + //! Get the begin value of the iterator //! \return The iterator virtual ConstIterator begin() const = 0; @@ -74,7 +74,7 @@ class MapBase { } } - //! Get the end iterator + //! Get the end value of the iterator //! \return The iterator virtual ConstIterator end() const = 0; diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index 081ebb2a755..86c2629801c 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -61,7 +61,7 @@ Defined as `= default`. virtual ConstIterator begin() const = 0. ``` -Return the iterator for the implementation. +Return the begin value of the iterator for the implementation. _Example:_ ```c++ @@ -140,7 +140,7 @@ void f(MapBase& m1, MapBase& m2) { virtual ConstIterator end() const = 0 ``` -Return the iterator for the implementation. +Return the end value of the iterator for the implementation. _Example:_ ```c++ diff --git a/Fw/DataStructures/docs/MapConstIterator.md b/Fw/DataStructures/docs/MapConstIterator.md index ef51499034c..470d8e56304 100644 --- a/Fw/DataStructures/docs/MapConstIterator.md +++ b/Fw/DataStructures/docs/MapConstIterator.md @@ -1,10 +1,10 @@ # MapConstIterator -`MapConstIterator` is a class for performing const iteration over a map. +`MapConstIterator` is a class for performing immutable iteration over a map. ## 1. Template Parameters -`MapBase` has the following template parameters. +`MapConstIterator` has the following template parameters. |Kind|Name|Purpose| |----|----|-------| @@ -48,7 +48,7 @@ Compare two `MapConstIterator` instances for equality. 1. If the implementations differ, then return `false`. -1. Otherwise delegate the comparison to the common implementation. +1. Otherwise check whether the implementations have equal values. ### 4.3. operator != @@ -56,7 +56,7 @@ Compare two `MapConstIterator` instances for equality. bool operator!=(const MapConstIterator& it) ``` -Defined as the negation of `operator=`. +Return the negation of `operator=`. ### 4.4. operator++ @@ -81,7 +81,7 @@ Check whether the iterator is in range. const MapEntry& operator*() const ``` -Return a const reference to the `MapEntry` object +Return a `const` reference to the `MapEntry` object pointed to by the iterator. ### 4.7. operator-> @@ -90,5 +90,5 @@ pointed to by the iterator. const MapEntry* operator->() const ``` -Return a pointer to the const `MapEntry` object +Return a pointer to the `const MapEntry` object pointed to by the iterator. diff --git a/Fw/DataStructures/docs/MapEntry.md b/Fw/DataStructures/docs/MapEntry.md index f5ce2d74ef0..4945ce5c392 100644 --- a/Fw/DataStructures/docs/MapEntry.md +++ b/Fw/DataStructures/docs/MapEntry.md @@ -33,7 +33,7 @@ Defined as `= delete`. virtual const K& getKey() const = 0 ``` -Return a const reference to the key stored in the entry. +Return a `const` reference to the key stored in the entry. ### 4.2. getValue @@ -41,4 +41,4 @@ Return a const reference to the key stored in the entry. virtual const V& getValue() const = 0 ``` -Return a const reference to the value stored in the entry. +Return a `const` reference to the value stored in the entry. From ecceb79837c61ae818f99137ea8d46c4420c1d27 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 09:26:20 -0700 Subject: [PATCH 381/458] Revise MapEntry --- Fw/DataStructures/docs/MapEntry.md | 1 - 1 file changed, 1 deletion(-) diff --git a/Fw/DataStructures/docs/MapEntry.md b/Fw/DataStructures/docs/MapEntry.md index 4945ce5c392..b623b093603 100644 --- a/Fw/DataStructures/docs/MapEntry.md +++ b/Fw/DataStructures/docs/MapEntry.md @@ -23,7 +23,6 @@ the copy constructor and copy assignment operator are deleted. `MapEntry` provides a protected zero-argument constructor and a protected virtual destructor. It uses the default implementations. -Defined as `= delete`. ## 4. Public Member Functions From 53f591a7ec26457a758d8df2ac4607e34e4b58f2 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 09:30:38 -0700 Subject: [PATCH 382/458] Revise MapConstIterator docs --- Fw/DataStructures/docs/MapConstIterator.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/MapConstIterator.md b/Fw/DataStructures/docs/MapConstIterator.md index 470d8e56304..b1db65ce493 100644 --- a/Fw/DataStructures/docs/MapConstIterator.md +++ b/Fw/DataStructures/docs/MapConstIterator.md @@ -4,7 +4,7 @@ ## 1. Template Parameters -`MapConstIterator` has the following template parameters. +`MapConstIterator` has the following template parameters: |Kind|Name|Purpose| |----|----|-------| From 4bf2fe97fd52b8fb70efce99f3fc34f881fcb8da Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 09:36:40 -0700 Subject: [PATCH 383/458] Revise docs for ExternalArrayMap --- Fw/DataStructures/docs/ExternalArrayMap.md | 74 +++++++++++++--------- Fw/DataStructures/docs/MapBase.md | 2 +- 2 files changed, 45 insertions(+), 31 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index 15fa4684c77..33e8be5e775 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -178,6 +178,25 @@ ConstIterator begin() const Return `m_impl.begin()`. +_Example:_ +```c++ +using Map = ExternalArrayMap; +constexpr FwSizeType capacity = 10; +Map::ImplEntry entries[capacity]; +// Call the constructor providing backing storage +Map map(entries, capacity); +// Insert an entry in the map +const auto status = map.insert(0, 1); +ASSERT_EQ(status, Fw::Success::SUCCESS); +// Get a map const iterator object +auto it = map.begin(); +// Use the iterator to access the underlying map const entry +const key = it->getKey(); +const value = it->getValue(); +ASSERT_EQ(key, 0); +ASSERT_EQ(value, 1); +``` + ### 6.3. clear ```c++ @@ -206,6 +225,26 @@ ConstIterator end() const Return `m_impl.end()`. +_Example:_ +```c++ +using Map = ExternalArrayMap; +constexpr FwSizeType capacity = 10; +Map::ImplEntry entries[capacity]; +// Call the constructor providing backing storage +Map map(entries, capacity); +// Insert an entry in the map +auto status = map.insert(0, 1); +ASSERT_EQ(status, Fw::Success::SUCCESS); +// Get a map const iterator object +auto iter = map.begin(); +// Check that iter is not at the end +ASSERT_NE(iter, map.end()); +// Increment iter +it++; +// Check that iter is at the end +ASSERT_EQ(iter, map.end()); +``` + ### 6.5. find ```c++ @@ -247,32 +286,7 @@ Map map(entries, capacity); ASSERT_EQ(map.getCapacity(), capacity); ``` -### 6.7. getHeadMapEntry - -```c++ -const MapEntry* getHeadMapEntry const override -``` - -The type `MapEntry` is defined [here](ExternalArrayMap.md#Public-Types). - -Return `m_impl.getHeadEntry()`. - -_Example:_ -```c++ -using Map = ExternalArrayMap; -constexpr FwSizeType capacity = 10; -Map::ImplEntry entries[capacity]; -Map map(entries, capacity); -const auto* e = map.getHeadMapEntry(); -FW_ASSERT(e == nullptr); -map.insert(0, 1); -e = map.getHeadMapEntry(); -FW_ASSERT(e != nullptr); -ASSERT_EQ(e->getKey(), 0); -ASSERT_EQ(e->getValue(), 1); -``` - -### 6.8. getSize +### 6.7. getSize ```c++ FwSizeType getSize() const override @@ -294,7 +308,7 @@ size = map.getSize(); ASSERT_EQ(size, 1); ``` -### 6.9. insert +### 6.8. insert ```c++ Success insert(const K& key, const V& value) override @@ -316,7 +330,7 @@ size = map.getSize(); ASSERT_EQ(size, 1); ``` -### 6.10. remove +### 6.9. remove ```c++ Success remove(const K& key, V& value) override @@ -348,7 +362,7 @@ ASSERT_EQ(size, 0); ASSERT_EQ(value, 1); ``` -### 6.11. setStorage (Typed Data) +### 6.10. setStorage (Typed Data) ```c++ void setStorage(ImplEntry* entries, FwSizeType capacity) @@ -369,7 +383,7 @@ Map::ImplEntry entries[capacity]; map.setStorage(entries, capacity); ``` -### 6.12. setStorage (Untyped Data) +### 6.11. setStorage (Untyped Data) ```c++ void setStorage(ByteArray data, FwSizeType capacity) diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index 86c2629801c..0d600d89274 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -68,7 +68,7 @@ _Example:_ void f(MapBase& map) { map.clear(); // Insert an entry in the map - auto status = map.insert(0, 1); + const auto status = map.insert(0, 1); ASSERT_EQ(status, Fw::Success::SUCCESS); // Get a map const iterator object auto it = map.begin(); From cf32ecdad056354bafd303ef43e9635fd9165a85 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 09:48:16 -0700 Subject: [PATCH 384/458] Revise ArrayMap docs --- Fw/DataStructures/docs/ArrayMap.md | 117 ++++++++++++++++++++++++++--- 1 file changed, 108 insertions(+), 9 deletions(-) diff --git a/Fw/DataStructures/docs/ArrayMap.md b/Fw/DataStructures/docs/ArrayMap.md index 56d219e5108..d3b1d9d6600 100644 --- a/Fw/DataStructures/docs/ArrayMap.md +++ b/Fw/DataStructures/docs/ArrayMap.md @@ -41,8 +41,6 @@ It represents an array-based map with internal storage. |`m_extMap`|[`ExternalArrayMap`](ExternalArrayMap.md)|The external map implementation|C++ default initialization| |`m_entries`|`ImplEntries`|The array providing the backing memory for `m_extMap`|C++ default initialization| -The type `ImplEntry` is defined [here](ArrayMap.md#Public-Types). - ```mermaid classDiagram ArrayMap *-- ExternalArrayMap @@ -134,6 +132,22 @@ ConstIterator begin() const Return `m_extMap.begin()`. +_Example:_ +```c++ +using Map = ArrayMap; +Map map; +// Insert an entry in the map +const auto status = map.insert(0, 1); +ASSERT_EQ(status, Fw::Success::SUCCESS); +// Get a map const iterator object +auto it = map.begin(); +// Use the iterator to access the underlying map const entry +const key = it->getKey(); +const value = it->getValue(); +ASSERT_EQ(key, 0); +ASSERT_EQ(value, 1); +``` + ### 6.3. clear ```c++ @@ -142,6 +156,16 @@ void clear() override Call `m_extMap.clear()`. +_Example:_ +```c++ +using Map = ArrayMap; +Map map; +const auto status = map.insert(0, 3); +ASSERT_EQ(map.getSize(), 1); +map.clear(); +ASSERT_EQ(map.getSize(), 0); +``` + ### 6.4. end ```c++ @@ -150,6 +174,24 @@ ConstIterator end() const Return `m_extMap.end()`. +_Example:_ +```c++ +using Map = ArrayMap; +// Call the constructor providing backing storage +Map map; +// Insert an entry in the map +auto status = map.insert(0, 1); +ASSERT_EQ(status, Fw::Success::SUCCESS); +// Get a map const iterator object +auto iter = map.begin(); +// Check that iter is not at the end +ASSERT_NE(iter, map.end()); +// Increment iter +it++; +// Check that iter is at the end +ASSERT_EQ(iter, map.end()); +``` + ### 6.5. find ```c++ @@ -158,6 +200,20 @@ Success find(const K& key, V& value) override Return `m_extMap.find(key, value)`. +_Example:_ +```c++ +using Map = ArrayMap; +Map map; +U32 value = 0; +auto status = map.find(0, value); +ASSERT_EQ(status, Success::FAILURE); +status = map.insert(0, 1); +ASSERT_EQ(status, Success::SUCCESS); +status = map.find(0, value); +ASSERT_EQ(status, Success::SUCCESS); +ASSERT_EQ(value, 1); +``` + ### 6.6. getCapacity ```c++ @@ -166,16 +222,13 @@ FwSizeType getCapacity() const override Return `m_extMap.getCapacity()`. -### 6.7. getHeadMapEntry - +_Example:_ ```c++ -const MapEntry* getHeadMapEntry const override +using Map = ArrayMap; +Map map; +ASSERT_EQ(map.getCapacity(), capacity); ``` -The type `MapEntry` is defined [here](ArrayMap.md#Public-Types). - -Return `m_extMap.getHeadMapEntry()`. - ### 6.8. getSize ```c++ @@ -184,6 +237,18 @@ FwSizeType getSize() const override Return `m_extMap.getSize()`. +_Example:_ +```c++ +using Map = ArrayMap; +Map map; +auto size = map.getSize(); +ASSERT_EQ(size, 0); +const auto status = map.insert(0, 3); +ASSERT_EQ(status, Success::SUCCESS); +size = map.getSize(); +ASSERT_EQ(size, 1); +``` + ### 6.9. insert ```c++ @@ -192,6 +257,18 @@ Success insert(const K& key, const V& value) override Return `m_extMap.insert(key, value)`. +_Example:_ +```c++ +using Map = ArrayMap; +Map map; +auto size = map.getSize(); +ASSERT_EQ(size, 0); +const auto status = map.insert(0, 1); +ASSERT_EQ(status, Success::SUCCESS); +size = map.getSize(); +ASSERT_EQ(size, 1); +``` + ### 6.10. remove ```c++ @@ -199,3 +276,25 @@ Success remove(const K& key, V& value) override ``` Return `m_extMap.remove(key, value)`. + +_Example:_ +```c++ +using Map = ArrayMap; +Map map; +auto size = map.getSize(); +ASSERT_EQ(size, 0); +auto status = map.insert(0, 1); +ASSERT_EQ(status, Success::SUCCESS); +size = map.getSize(); +ASSERT_EQ(size, 1); +// Key does not exist +U32 value = 0; +status = map.remove(10, value); +ASSERT_EQ(status, Success::FAILURE); +ASSERT_EQ(size, 1); +// Key exists +status = map.remove(0, value); +ASSERT_EQ(status, Success::SUCCESS); +ASSERT_EQ(size, 0); +ASSERT_EQ(value, 1); +``` From f4da98d607c5c5e73192573ba8a49f1e86eaf3ef Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 09:59:14 -0700 Subject: [PATCH 385/458] Revise ArraySetOrMapImpl --- Fw/DataStructures/docs/ArraySetOrMapImpl.md | 135 ++---------------- .../docs/SetOrMapImplConstIterator.md | 6 + 2 files changed, 14 insertions(+), 127 deletions(-) create mode 100644 Fw/DataStructures/docs/SetOrMapImplConstIterator.md diff --git a/Fw/DataStructures/docs/ArraySetOrMapImpl.md b/Fw/DataStructures/docs/ArraySetOrMapImpl.md index 565357d98f4..5427e906131 100644 --- a/Fw/DataStructures/docs/ArraySetOrMapImpl.md +++ b/Fw/DataStructures/docs/ArraySetOrMapImpl.md @@ -32,115 +32,8 @@ storing the entries in the set or map. `ConstIterator` is a public inner class of `ArraySetOrMapImpl`. It provides non-modifying iteration over the elements of an `ArraySetOrMapImpl` instance. - -#### 2.2.1. Private Member Variables - -`ConstIterator` has the following private member variables. - -|Name|Type|Purpose|Default Value| -|----|----|-------|-------------| -|`m_impl`|[`const ArraySetOrMapImpl&`]|The implementation over which to iterate|None (must be set by the constructor)| -|`m_index`|`FwSizeType`|The current iteration index|0| - -#### 2.2.2. Public Constructors and Destructors - -##### 2.2.2.1. Constructor Providing the Implementation - -```c++ -ConstIterator(const ArraySetOrMapImpl& impl) -``` - -1. Set `m_impl = impl`. - -1. Call `reset()`. - -##### 2.2.2.2. Copy Constructor - -```c++ -ConstIterator(const ConstIterator& it) -``` - -Defined as `= delete`. - -##### 2.2.2.3. Destructor - -```c++ -~ConstIterator() -``` - -Defined as `= default`. - -#### 2.2.3. Public Member Functions - -##### 2.2.3.1. operator= - -```c++ -ConstIterator& operator=(const ConstIterator& it) -``` - -Defined as `= delete`. - -##### 2.2.3.2. operator== - -```c++ -bool operator==(const ConstIterator& it) -``` - -1. Set `result = false`. - -1. If `&this->m_impl == &it.m_impl` - - 1. If `this->m_index == it.m_index` then set `result = true`. - - 1. Otherwise `!this->isInRange()` and `!it.isInRange()` then set `result = true`. - -1. Return `result`. - -##### 2.2.3.3. operator++ - -```c++ -ConstIterator& operator++() -``` - -1. If `isInRange()` then increment `m_index`. - -1. Return `*this`. - -##### 2.2.3.4. getKeyOrElement - -```c++ -const KE& getKeyOrElement() const -``` - -1. Assert `isInRange()`. - -1. Return `m_impl.m_entries[m_index].getKeyOrElement()`. - -##### 2.2.3.5. getValueOrNil - -```c++ -const KE& getValueOrNil() const -``` - -1. Assert `m_index < m_impl.m_size`. - -1. Return `m_impl.m_entries[index].getValueOrNil()`. - -##### 2.2.3.6. isInRange - -```c++ -bool isInRange() const -``` - -Return `m_index < m_impl.m_size`. - -##### 2.2.3.7. reset - -```c++ -void reset() -``` - -Set `m_index = 0`. +It is a base class of [`SetOrMapImplConstIterator`](SetOrMapImplConstIterator.md). ## 3. Private Member Variables @@ -182,8 +75,8 @@ ArraySetOrMapImpl(ByteArray data, FwSizeType capacity) ``` `data` must be aligned according to -[`getByteArrayAlignment()`](#61-getbytearrayalignment) and must -contain at least [`getByteArraySize(size)`](#62-getbytearraysize) bytes. +[`getByteArrayAlignment()`](#getByteArrayAlignment) and must +contain at least [`getByteArraySize(size)`](#getByteArraySize) bytes. Call `setStorage(data, capacity)`. @@ -278,20 +171,6 @@ FwSizeType getCapacity() const Return `m_entries.getSize()`. -### 5.7. getHeadEntry - -```c++ -const Entry* getHeadEntry() const -``` - -1. Set `result = nullptr`. - -1. If `m_size > 0` - - 1. Set `result = &m_entries[0]`. - -1. Return `result`. - ### 5.8. getSize ```c++ @@ -380,8 +259,8 @@ void setStorage(ByteArray data, FwSizeType capacity) ``` `data` must be aligned according to -[`getByteArrayAlignment()`](#61-getbytearrayalignment) and must -contain at least [`getByteArraySize(size)`](#62-getbytearraysize) bytes. +[`getByteArrayAlignment()`](#getByteArrayAlignment) and must +contain at least [`getByteArraySize(size)`](#getByteArraySize) bytes. 1. Call `m_entries.setStorage(data, capacity)`. @@ -389,6 +268,7 @@ contain at least [`getByteArraySize(size)`](#62-getbytearraysize) bytes. ## 6. Public Static Functions + ### 6.1. getByteArrayAlignment ```c++ @@ -397,6 +277,7 @@ static constexpr U8 getByteArrayAlignment() Return `ExternalArray::getByteArrayAlignment()`. + ### 6.2. getByteArraySize ```c++ diff --git a/Fw/DataStructures/docs/SetOrMapImplConstIterator.md b/Fw/DataStructures/docs/SetOrMapImplConstIterator.md new file mode 100644 index 00000000000..1bb7b3a2758 --- /dev/null +++ b/Fw/DataStructures/docs/SetOrMapImplConstIterator.md @@ -0,0 +1,6 @@ +# SetOrMapImplConstIterator + +`SetOrMapImplConstIterator` is an abstract base class. +It specifies an interface for constant iterators over +set or map implementations. +The header file is defined [here](../SetOrMapImplConstIterator.hpp). From f8fb3cfde160cfff06d6200cc9f720707c3aff1c Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 10:00:53 -0700 Subject: [PATCH 386/458] Revise SetOrMapImplEntry --- Fw/DataStructures/docs/SetOrMapImplEntry.md | 44 +-------------------- 1 file changed, 2 insertions(+), 42 deletions(-) diff --git a/Fw/DataStructures/docs/SetOrMapImplEntry.md b/Fw/DataStructures/docs/SetOrMapImplEntry.md index 5def76c5fef..34807c31d37 100644 --- a/Fw/DataStructures/docs/SetOrMapImplEntry.md +++ b/Fw/DataStructures/docs/SetOrMapImplEntry.md @@ -2,7 +2,7 @@ `SetOrMapImplEntry` is a final class template defined in [`Fw/DataStructures`](sdd.md). -It represents an iterator for a set or a map. +It represents an iterator for a set or a map implementation. ## 1. Template Parameters @@ -20,12 +20,9 @@ templates: 1. [`MapEntry`](MapEntry.md). -1. [`SetEntry`](SetEntry.md). - ```mermaid classDiagram MapEntry <|-- SetOrMapImplEntry - SetEntry <|-- SetOrMapImplEntry ``` ## 3. Private Member Variables @@ -36,7 +33,6 @@ classDiagram |----|----|-------|-------------| |`m_keyOrElement`|`KE`|The map key or set element|C++ default initialization| |`m_valueOrNil`|`VN`|The value or [`Nil`](Nil.md)|C++ default initialization| -|`m_next`|`const SetOrMapImplEntry*`|Pointer to the next iterator or `nullptr` if none|`nullptr`| ## 4. Public Constructors and Destructors @@ -51,15 +47,13 @@ Use default initialization of members. ### 4.2. Constructor Providing Members ```c++ -SetOrMapImplEntry(const KE& keyOrElement, const VN& valueOrNil, const SetOrMapImplEntry* next = nullptr) +SetOrMapImplEntry(const KE& keyOrElement, const VN& valueOrNil) ``` 1. Set `m_keyOrElement = keyOrElement`. 2. Set `m_valueOrNil = valueOrNil`. -3. Set `m_next = next`. - ### 4.3. Copy Constructor ```c++ @@ -90,8 +84,6 @@ SetOrMapImplEntry& operator=(const SetOrMapImplEntry& iterator) 1. Set `m_valueOrNil = iterator.valueOrNil`. - 1. Set `m_next = iterator.next`. - ### 5.3. getElement ```c++ @@ -116,30 +108,6 @@ const VN& getValue() const override Return a reference to `m_valueOrNil`. -### 5.4. getNextEntry - -```c++ -SetOrMapImplEntry* getNextEntry() -``` - -Return `m_next`. - -### 5.4. getNextMapEntry - -```c++ -MapEntry* getNextMapEntry() override -``` - -Return `m_next`. - -### 5.5. getNextSetEntry - -```c++ -SetEntry* getNextSetEntry() override -``` - -Return `m_next`. - ### 5.6. setKeyOrElement ```c++ @@ -148,14 +116,6 @@ void setKeyOrElement(const KE& keyOrElement) const Set `m_keyOrElement = keyOrElement`. -### 5.8. setNextEntry - -```c++ -void setNextEntry(const SetOrMapImplEntry* next) -``` - -Set `m_next = next`. - ### 5.7. setValueOrNil ```c++ From ca478d90d1d878c0257d203406694ed9d192fffd Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 13:55:25 -0700 Subject: [PATCH 387/458] Revise MapEntry --- Fw/DataStructures/ArrayMap.hpp | 2 +- Fw/DataStructures/ArraySet.hpp | 2 +- Fw/DataStructures/ArraySetOrMapImpl.hpp | 4 +- Fw/DataStructures/ExternalArrayMap.hpp | 2 +- Fw/DataStructures/ExternalArraySet.hpp | 2 +- Fw/DataStructures/MapConstIterator.hpp | 1 - Fw/DataStructures/MapEntry.hpp | 79 +++++++++++---- .../SetOrMapImplConstIterator.hpp | 5 +- Fw/DataStructures/SetOrMapImplEntry.hpp | 95 ------------------- Fw/DataStructures/docs/ArrayMap.md | 2 +- Fw/DataStructures/docs/ArraySet.md | 2 +- Fw/DataStructures/docs/ArraySetOrMapImpl.md | 2 +- Fw/DataStructures/docs/ExternalArrayMap.md | 2 +- Fw/DataStructures/docs/ExternalArraySet.md | 2 +- Fw/DataStructures/docs/Nil.md | 2 +- Fw/DataStructures/docs/SetOrMapImplEntry.md | 24 ++--- Fw/DataStructures/test/ut/ArrayMapTest.cpp | 2 +- .../test/ut/ArraySetOrMapImplTester.hpp | 2 +- Fw/DataStructures/test/ut/ArraySetTest.cpp | 2 +- .../test/ut/ExternalArrayMapTest.cpp | 2 +- .../test/ut/ExternalArraySetTest.cpp | 2 +- .../ut/STest/ArraySetOrMapImplTestState.hpp | 2 +- 22 files changed, 90 insertions(+), 150 deletions(-) delete mode 100644 Fw/DataStructures/SetOrMapImplEntry.hpp diff --git a/Fw/DataStructures/ArrayMap.hpp b/Fw/DataStructures/ArrayMap.hpp index a6673c67a83..510c15fb163 100644 --- a/Fw/DataStructures/ArrayMap.hpp +++ b/Fw/DataStructures/ArrayMap.hpp @@ -26,7 +26,7 @@ class ArrayMap final : public MapBase { // ---------------------------------------------------------------------- //! The type of an implementation entry - using ImplEntry = SetOrMapImplEntry; + using ImplEntry = MapEntry; //! The type of a map entry using MapEntry = MapEntry; diff --git a/Fw/DataStructures/ArraySet.hpp b/Fw/DataStructures/ArraySet.hpp index db7aea8a23d..63fa69401f4 100644 --- a/Fw/DataStructures/ArraySet.hpp +++ b/Fw/DataStructures/ArraySet.hpp @@ -26,7 +26,7 @@ class ArraySet final : public SetBase { // ---------------------------------------------------------------------- //! The type of animplementation entry - using ImplEntry = SetOrMapImplEntry; + using ImplEntry = MapEntry; //! The type of the implementation entries using ImplEntries = ImplEntry[C]; diff --git a/Fw/DataStructures/ArraySetOrMapImpl.hpp b/Fw/DataStructures/ArraySetOrMapImpl.hpp index 3f9d66d0fb2..891001b5f1c 100644 --- a/Fw/DataStructures/ArraySetOrMapImpl.hpp +++ b/Fw/DataStructures/ArraySetOrMapImpl.hpp @@ -8,8 +8,8 @@ #define Fw_ArraySetOrMapImpl_HPP #include "Fw/DataStructures/ExternalArray.hpp" +#include "Fw/DataStructures/MapEntry.hpp" #include "Fw/DataStructures/SetOrMapImplConstIterator.hpp" -#include "Fw/DataStructures/SetOrMapImplEntry.hpp" #include "Fw/Types/Assert.hpp" #include "Fw/Types/SuccessEnumAc.hpp" @@ -30,7 +30,7 @@ class ArraySetOrMapImpl final { // ---------------------------------------------------------------------- //! The type of an entry in the set or map - using Entry = SetOrMapImplEntry; + using Entry = MapEntry; //! Const iterator class ConstIterator final : public SetOrMapImplConstIterator { diff --git a/Fw/DataStructures/ExternalArrayMap.hpp b/Fw/DataStructures/ExternalArrayMap.hpp index 43e2bd1b624..8a004ec6b23 100644 --- a/Fw/DataStructures/ExternalArrayMap.hpp +++ b/Fw/DataStructures/ExternalArrayMap.hpp @@ -28,7 +28,7 @@ class ExternalArrayMap final : public MapBase { // ---------------------------------------------------------------------- //! The type of a map implementation entry - using ImplEntry = SetOrMapImplEntry; + using ImplEntry = MapEntry; //! The type of a map entry using MapEntry = MapEntry; diff --git a/Fw/DataStructures/ExternalArraySet.hpp b/Fw/DataStructures/ExternalArraySet.hpp index f576d31e606..6aa8ffc9acd 100644 --- a/Fw/DataStructures/ExternalArraySet.hpp +++ b/Fw/DataStructures/ExternalArraySet.hpp @@ -29,7 +29,7 @@ class ExternalArraySet final : public SetBase { // ---------------------------------------------------------------------- //! The type of a set entry - using Entry = SetOrMapImplEntry; + using Entry = MapEntry; public: // ---------------------------------------------------------------------- diff --git a/Fw/DataStructures/MapConstIterator.hpp b/Fw/DataStructures/MapConstIterator.hpp index a7acc8eb52e..070737e7483 100644 --- a/Fw/DataStructures/MapConstIterator.hpp +++ b/Fw/DataStructures/MapConstIterator.hpp @@ -10,7 +10,6 @@ #include #include "Fw/DataStructures/ArraySetOrMapImpl.hpp" -#include "Fw/DataStructures/MapEntry.hpp" #include "Fw/FPrimeBasicTypes.hpp" namespace Fw { diff --git a/Fw/DataStructures/MapEntry.hpp b/Fw/DataStructures/MapEntry.hpp index 7fc7021e84b..9934152f49a 100644 --- a/Fw/DataStructures/MapEntry.hpp +++ b/Fw/DataStructures/MapEntry.hpp @@ -1,7 +1,7 @@ // ====================================================================== // \title MapEntry // \author bocchino -// \brief An abstract class template representing an entry in a map +// \brief A class template representing an entry for a set or map implementation // ====================================================================== #ifndef Fw_MapEntry_HPP @@ -11,45 +11,82 @@ namespace Fw { -template -class MapEntry { - private: +template +class MapEntry final { + public: // ---------------------------------------------------------------------- - // Deleted elements + // Public constructors and destructors // ---------------------------------------------------------------------- - //! Copy constructor deleted in the base class - //! Behavior depends on the implementation - MapEntry(const MapEntry&) = delete; + //! Zero-argument constructor + MapEntry() {} + + //! Constructor providing members + MapEntry(const KE& keyOrElement, //!< The key or element + const VN& valueOrNil //!< The value or Nil + ) + : m_keyOrElement(keyOrElement), m_valueOrNil(valueOrNil) {} + + //! Copy constructor + MapEntry(const MapEntry& entry) { *this = entry; } - //! operator= deleted in the base class - //! Behavior depends on the implementation - //! We avoid virtual user-defined operators - MapEntry& operator=(const MapEntry&) = delete; + //! Destructor + ~MapEntry() = default; - protected: + public: // ---------------------------------------------------------------------- - // Protected constructors and destructors + // Public member functions // ---------------------------------------------------------------------- - //! Zero-argument constructor - MapEntry() = default; + //! operator= + MapEntry& operator=(const MapEntry& entry) { + if (this != &entry) { + this->m_keyOrElement = entry.m_keyOrElement; + this->m_valueOrNil = entry.m_valueOrNil; + } + return *this; + } - //! Destructor - virtual ~MapEntry() = default; + //! Get the key or element associated with this entry + //! \return The key or element + const KE& getKeyOrElement() const { return this->m_keyOrElement; } + + //! Get the value or nil associated with this entry + //! \return The value or nil + const VN& getValueOrNil() const { return this->m_valueOrNil; } + + //! Set the key or element + void setKeyOrElement(const KE& keyOrElement //!< The key or element + ) { + this->m_keyOrElement = keyOrElement; + } + + //! Set the value or Nil + void setValueOrNil(const VN& valueOrNil) { this->m_valueOrNil = valueOrNil; } public: // ---------------------------------------------------------------------- - // Public member functions + // MapEntry implementation // ---------------------------------------------------------------------- //! Get the key associated with this entry //! \return The key - virtual const K& getKey() const = 0; + const KE& getKey() const { return this->m_keyOrElement; } //! Get the value associated with this entry //! \return The value - virtual const V& getValue() const = 0; + const VN& getValue() const { return this->m_valueOrNil; } + + private: + // ---------------------------------------------------------------------- + // Private member variables + // ---------------------------------------------------------------------- + + //! The map key or set element + KE m_keyOrElement = {}; + + //! The value or nil + VN m_valueOrNil = {}; }; } // namespace Fw diff --git a/Fw/DataStructures/SetOrMapImplConstIterator.hpp b/Fw/DataStructures/SetOrMapImplConstIterator.hpp index f3c59e0d503..0003baefe08 100644 --- a/Fw/DataStructures/SetOrMapImplConstIterator.hpp +++ b/Fw/DataStructures/SetOrMapImplConstIterator.hpp @@ -7,7 +7,7 @@ #ifndef Fw_SetOrMapImplConstIterator_HPP #define Fw_SetOrMapImplConstIterator_HPP -#include "Fw/DataStructures/SetOrMapImplEntry.hpp" +#include "Fw/DataStructures/MapEntry.hpp" #include "Fw/FPrimeBasicTypes.hpp" namespace Fw { @@ -62,8 +62,7 @@ class SetOrMapImplConstIterator { //! Get the set or map impl entry pointed to by this iterator //! \return The set or map impl entry - virtual const SetOrMapImplEntry& getEntry() const = 0; - + virtual const MapEntry& getEntry() const = 0; }; } // namespace Fw diff --git a/Fw/DataStructures/SetOrMapImplEntry.hpp b/Fw/DataStructures/SetOrMapImplEntry.hpp deleted file mode 100644 index 9df7c9f6c0a..00000000000 --- a/Fw/DataStructures/SetOrMapImplEntry.hpp +++ /dev/null @@ -1,95 +0,0 @@ -// ====================================================================== -// \title SetOrMapImplEntry -// \author bocchino -// \brief A class template representing an entry for a set or map implementation -// ====================================================================== - -#ifndef Fw_SetOrMapImplEntry_HPP -#define Fw_SetOrMapImplEntry_HPP - -#include "Fw/DataStructures/MapEntry.hpp" -#include "Fw/FPrimeBasicTypes.hpp" - -namespace Fw { - -template -class SetOrMapImplEntry final : public MapEntry { - public: - // ---------------------------------------------------------------------- - // Public constructors and destructors - // ---------------------------------------------------------------------- - - //! Zero-argument constructor - SetOrMapImplEntry() : MapEntry() {} - - //! Constructor providing members - SetOrMapImplEntry(const KE& keyOrElement, //!< The key or element - const VN& valueOrNil //!< The value or Nil - ) - : MapEntry(), m_keyOrElement(keyOrElement), m_valueOrNil(valueOrNil) {} - - //! Copy constructor - SetOrMapImplEntry(const SetOrMapImplEntry& entry) { *this = entry; } - - //! Destructor - ~SetOrMapImplEntry() override = default; - - public: - // ---------------------------------------------------------------------- - // Public member functions - // ---------------------------------------------------------------------- - - //! operator= - SetOrMapImplEntry& operator=(const SetOrMapImplEntry& entry) { - if (this != &entry) { - this->m_keyOrElement = entry.m_keyOrElement; - this->m_valueOrNil = entry.m_valueOrNil; - } - return *this; - } - - //! Get the key or element associated with this entry - //! \return The key or element - const KE& getKeyOrElement() const { return this->m_keyOrElement; } - - //! Get the value or nil associated with this entry - //! \return The value or nil - const VN& getValueOrNil() const { return this->m_valueOrNil; } - - //! Set the key or element - void setKeyOrElement(const KE& keyOrElement //!< The key or element - ) { - this->m_keyOrElement = keyOrElement; - } - - //! Set the value or Nil - void setValueOrNil(const VN& valueOrNil) { this->m_valueOrNil = valueOrNil; } - - public: - // ---------------------------------------------------------------------- - // MapEntry implementation - // ---------------------------------------------------------------------- - - //! Get the key associated with this entry - //! \return The key - const KE& getKey() const override { return this->m_keyOrElement; } - - //! Get the value associated with this entry - //! \return The value - const VN& getValue() const override { return this->m_valueOrNil; } - - private: - // ---------------------------------------------------------------------- - // Private member variables - // ---------------------------------------------------------------------- - - //! The map key or set element - KE m_keyOrElement = {}; - - //! The value or nil - VN m_valueOrNil = {}; -}; - -} // namespace Fw - -#endif diff --git a/Fw/DataStructures/docs/ArrayMap.md b/Fw/DataStructures/docs/ArrayMap.md index d3b1d9d6600..0641efab82d 100644 --- a/Fw/DataStructures/docs/ArrayMap.md +++ b/Fw/DataStructures/docs/ArrayMap.md @@ -28,7 +28,7 @@ It represents an array-based map with internal storage. |Name|Definition| |----|----------| -|`ImplEntry`|Alias of [`SetOrMapImplEntry`](SetOrMapImplEntry.md)| +|`ImplEntry`|Alias of [`MapEntry`](MapEntry.md)| |`MapEntry`|Alias of [`MapEntry`](MapEntry.md)| |`ImplEntries`|Alias of `ImplEntry[C]`| diff --git a/Fw/DataStructures/docs/ArraySet.md b/Fw/DataStructures/docs/ArraySet.md index 7a329bb631b..71b8f212dd1 100644 --- a/Fw/DataStructures/docs/ArraySet.md +++ b/Fw/DataStructures/docs/ArraySet.md @@ -27,7 +27,7 @@ It represents an array-based set with internal storage. |Name|Definition| |----|----------| -|`Entry`|Alias of [`SetOrMapImplEntry`](SetOrMapImplEntry.md)| +|`Entry`|Alias of [`MapEntry`](MapEntry.md)| |`SetEntry`|Alias of [`SetEntry`](SetEntry.md)| The type `Nil` is defined [here](Nil.md). diff --git a/Fw/DataStructures/docs/ArraySetOrMapImpl.md b/Fw/DataStructures/docs/ArraySetOrMapImpl.md index 5427e906131..dab0cd08dc5 100644 --- a/Fw/DataStructures/docs/ArraySetOrMapImpl.md +++ b/Fw/DataStructures/docs/ArraySetOrMapImpl.md @@ -25,7 +25,7 @@ storing the entries in the set or map. |Name|Definition| |----|----------| -|`Entry`|Alias for [`SetOrMapImplEntry`](SetOrMapImplEntry.md)| +|`Entry`|Alias for [`MapEntry`](MapEntry.md)| ### 2.2. ConstIterator diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index 33e8be5e775..7f80e5cd286 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -27,7 +27,7 @@ as the map implementation. |Name|Definition| |----|----------| -|`ImplEntry`|Alias of [`SetOrMapImplEntry`](SetOrMapImplEntry.md)| +|`ImplEntry`|Alias of [`MapEntry`](MapEntry.md)| |`MapEntry`|Alias of [`MapEntry`](MapEntry.md)| ## 4. Private Member Variables diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md index 88899f4d463..32c6eed288b 100644 --- a/Fw/DataStructures/docs/ExternalArraySet.md +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -26,7 +26,7 @@ as the set implementation. |Name|Definition| |----|----------| -|`ImplEntry`|Alias of [`SetOrMapImplEntry`](SetOrMapImplEntry.md)| +|`ImplEntry`|Alias of [`MapEntry`](MapEntry.md)| |`SetEntry`|Alias of [`SetEntry`](SetEntry.md)| The type `Nil` is defined [here](Nil.md). diff --git a/Fw/DataStructures/docs/Nil.md b/Fw/DataStructures/docs/Nil.md index 1600881b9ed..cd164e488d7 100644 --- a/Fw/DataStructures/docs/Nil.md +++ b/Fw/DataStructures/docs/Nil.md @@ -2,5 +2,5 @@ `Nil` is an empty type. It is a placeholder that is used as the value type -when a [`SetOrMapImplEntry`](SetOrMapImplEntry.md) +when a [`MapEntry`](MapEntry.md) is used as a set iterator. diff --git a/Fw/DataStructures/docs/SetOrMapImplEntry.md b/Fw/DataStructures/docs/SetOrMapImplEntry.md index 34807c31d37..10839bc2e2a 100644 --- a/Fw/DataStructures/docs/SetOrMapImplEntry.md +++ b/Fw/DataStructures/docs/SetOrMapImplEntry.md @@ -1,12 +1,12 @@ -# SetOrMapImplEntry +# MapEntry -`SetOrMapImplEntry` is a final class template +`MapEntry` is a final class template defined in [`Fw/DataStructures`](sdd.md). -It represents an iterator for a set or a map implementation. +It represents an entry for a set or a map implementation. ## 1. Template Parameters -`SetOrMapImplEntry` has the following template parameters. +`MapEntry` has the following template parameters. |Kind|Name|Purpose| |----|----|-------| @@ -15,19 +15,19 @@ It represents an iterator for a set or a map implementation. ## 2. Base Class -`SetOrMapImplEntry` is publicly derived from the following +`MapEntry` is publicly derived from the following templates: 1. [`MapEntry`](MapEntry.md). ```mermaid classDiagram - MapEntry <|-- SetOrMapImplEntry + MapEntry <|-- MapEntry ``` ## 3. Private Member Variables -`SetOrMapImplEntry` has the following private member variables. +`MapEntry` has the following private member variables. |Name|Type|Purpose|Default Value| |----|----|-------|-------------| @@ -39,7 +39,7 @@ classDiagram ### 4.1. Zero-Argument Constructor ```c++ -SetOrMapImplEntry() +MapEntry() ``` Use default initialization of members. @@ -47,7 +47,7 @@ Use default initialization of members. ### 4.2. Constructor Providing Members ```c++ -SetOrMapImplEntry(const KE& keyOrElement, const VN& valueOrNil) +MapEntry(const KE& keyOrElement, const VN& valueOrNil) ``` 1. Set `m_keyOrElement = keyOrElement`. @@ -57,7 +57,7 @@ SetOrMapImplEntry(const KE& keyOrElement, const VN& valueOrNil) ### 4.3. Copy Constructor ```c++ -SetOrMapImplEntry(const SetOrMapImplEntry& iterator) +MapEntry(const MapEntry& iterator) ``` Set `*this = iterator`. @@ -65,7 +65,7 @@ Set `*this = iterator`. ### 4.4. Destructor ```c++ -~SetOrMapImplEntry() override +~MapEntry() override ``` Defined as `= default`. @@ -75,7 +75,7 @@ Defined as `= default`. ### 5.1. operator= ```c++ -SetOrMapImplEntry& operator=(const SetOrMapImplEntry& iterator) +MapEntry& operator=(const MapEntry& iterator) ``` 1. If `this != &iterator` diff --git a/Fw/DataStructures/test/ut/ArrayMapTest.cpp b/Fw/DataStructures/test/ut/ArrayMapTest.cpp index 9ae8069954d..f595754d500 100644 --- a/Fw/DataStructures/test/ut/ArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ArrayMapTest.cpp @@ -30,7 +30,7 @@ class ArrayMapTester { namespace MapTest { using ConstIterator = MapConstIterator; -using Entry = SetOrMapImplEntry; +using Entry = MapEntry; using Map = ArrayMap; using MapTester = ArrayMapTester; using ImplTester = ArraySetOrMapImplTester; diff --git a/Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp b/Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp index fd5b4726e47..b36eb8b93ca 100644 --- a/Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp +++ b/Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp @@ -17,7 +17,7 @@ namespace Fw { template class ArraySetOrMapImplTester { public: - using Entry = SetOrMapImplEntry; + using Entry = MapEntry; ArraySetOrMapImplTester(const ArraySetOrMapImpl& impl) : m_impl(impl) {} diff --git a/Fw/DataStructures/test/ut/ArraySetTest.cpp b/Fw/DataStructures/test/ut/ArraySetTest.cpp index d902f0fce9e..3f35d5f9f7b 100644 --- a/Fw/DataStructures/test/ut/ArraySetTest.cpp +++ b/Fw/DataStructures/test/ut/ArraySetTest.cpp @@ -29,7 +29,7 @@ class ArraySetTester { namespace SetTest { -using Entry = SetOrMapImplEntry; +using Entry = MapEntry; using Set = ArraySet; using SetTester = ArraySetTester; using ImplTester = ArraySetOrMapImplTester; diff --git a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp index 0d2112e4629..c5fc56fbe61 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp @@ -25,7 +25,7 @@ class ExternalArrayMapTester { namespace MapTest { -using Entry = SetOrMapImplEntry; +using Entry = MapEntry; using Map = ExternalArrayMap; using MapTester = ExternalArrayMapTester; using ImplTester = ArraySetOrMapImplTester; diff --git a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp index d1c809c4117..4f983f60caf 100644 --- a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp @@ -27,7 +27,7 @@ class ExternalArraySetTester { namespace SetTest { -using Entry = SetOrMapImplEntry; +using Entry = MapEntry; using Set = ExternalArraySet; using SetTester = ExternalArraySetTester; using ImplTester = ArraySetOrMapImplTester; diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp index 10131e3f9f7..dd26e5b7df7 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp @@ -29,7 +29,7 @@ struct State { //! The Tester type using Tester = ArraySetOrMapImplTester; //! The entry type - using Entry = SetOrMapImplEntry; + using Entry = MapEntry; //! Constructor State(Impl& a_impl) : impl(a_impl), tester(a_impl) {} //! The array set or map under test From 01a65d41f12d9f52ef369162fa75e8da2ddcd9a7 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 14:02:10 -0700 Subject: [PATCH 388/458] Revise map and set interfaces --- Fw/DataStructures/ArrayMap.hpp | 13 +++++-------- Fw/DataStructures/ArraySet.hpp | 10 +++++----- Fw/DataStructures/ExternalArrayMap.hpp | 13 +++++-------- Fw/DataStructures/ExternalArraySet.hpp | 6 +++--- 4 files changed, 18 insertions(+), 24 deletions(-) diff --git a/Fw/DataStructures/ArrayMap.hpp b/Fw/DataStructures/ArrayMap.hpp index 510c15fb163..4b6f79dce07 100644 --- a/Fw/DataStructures/ArrayMap.hpp +++ b/Fw/DataStructures/ArrayMap.hpp @@ -25,14 +25,11 @@ class ArrayMap final : public MapBase { // Public types // ---------------------------------------------------------------------- - //! The type of an implementation entry - using ImplEntry = MapEntry; + //! The type of an entry in the map + using Entry = MapEntry; - //! The type of a map entry - using MapEntry = MapEntry; - - //! The type of the implementation entries - using ImplEntries = ImplEntry[C]; + //! The type of the entries + using Entries = Entry[C]; public: // ---------------------------------------------------------------------- @@ -111,7 +108,7 @@ class ArrayMap final : public MapBase { ExternalArrayMap m_extMap = {}; //! The array providing the backing memory for m_extMap - ImplEntries m_entries = {}; + Entries m_entries = {}; }; } // namespace Fw diff --git a/Fw/DataStructures/ArraySet.hpp b/Fw/DataStructures/ArraySet.hpp index 63fa69401f4..cd87603211d 100644 --- a/Fw/DataStructures/ArraySet.hpp +++ b/Fw/DataStructures/ArraySet.hpp @@ -25,11 +25,11 @@ class ArraySet final : public SetBase { // Public types // ---------------------------------------------------------------------- - //! The type of animplementation entry - using ImplEntry = MapEntry; + //! The type of an entry in the map that implements the set + using Entry = MapEntry; - //! The type of the implementation entries - using ImplEntries = ImplEntry[C]; + //! The type of the entries + using Entries = Entry[C]; public: // ---------------------------------------------------------------------- @@ -105,7 +105,7 @@ class ArraySet final : public SetBase { ExternalArraySet m_extSet = {}; //! The array providing the backing memory for m_extSet - ImplEntries m_entries = {}; + Entries m_entries = {}; }; } // namespace Fw diff --git a/Fw/DataStructures/ExternalArrayMap.hpp b/Fw/DataStructures/ExternalArrayMap.hpp index 8a004ec6b23..b3808d62998 100644 --- a/Fw/DataStructures/ExternalArrayMap.hpp +++ b/Fw/DataStructures/ExternalArrayMap.hpp @@ -27,11 +27,8 @@ class ExternalArrayMap final : public MapBase { // Public types // ---------------------------------------------------------------------- - //! The type of a map implementation entry - using ImplEntry = MapEntry; - //! The type of a map entry - using MapEntry = MapEntry; + using Entry = MapEntry; public: // ---------------------------------------------------------------------- @@ -42,8 +39,8 @@ class ExternalArrayMap final : public MapBase { ExternalArrayMap() = default; //! Constructor providing typed backing storage. - //! entries must point to at least capacity elements of type ImplEntry. - ExternalArrayMap(ImplEntry* entries, //!< The entries + //! entries must point to at least capacity elements of type Entry. + ExternalArrayMap(Entry* entries, //!< The entries FwSizeType capacity //!< The capacity ) : MapBase() { @@ -123,8 +120,8 @@ class ExternalArrayMap final : public MapBase { } //! Set the backing storage (typed data) - //! entries must point to at least capacity elements of type ImplEntry. - void setStorage(ImplEntry* entries, //!< The entries + //! entries must point to at least capacity elements of type Entry. + void setStorage(Entry* entries, //!< The entries FwSizeType capacity //!< The capacity ) { this->m_impl.setStorage(entries, capacity); diff --git a/Fw/DataStructures/ExternalArraySet.hpp b/Fw/DataStructures/ExternalArraySet.hpp index 6aa8ffc9acd..ef9e8d72702 100644 --- a/Fw/DataStructures/ExternalArraySet.hpp +++ b/Fw/DataStructures/ExternalArraySet.hpp @@ -40,7 +40,7 @@ class ExternalArraySet final : public SetBase { ExternalArraySet() = default; //! Constructor providing typed backing storage. - //! entries must point to at least capacity elements of type ImplEntry. + //! entries must point to at least capacity elements of type Entry. ExternalArraySet(Entry* entries, //!< The entries FwSizeType capacity //!< The capacity ) @@ -120,7 +120,7 @@ class ExternalArraySet final : public SetBase { } //! Set the backing storage (typed data) - //! entries must point to at least capacity elements of type ImplEntry. + //! entries must point to at least capacity elements of type Entry. void setStorage(Entry* entries, //!< The entries FwSizeType capacity //!< The capacity ) { @@ -130,7 +130,7 @@ class ExternalArraySet final : public SetBase { //! 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 + void setStorage(ByteArray data, //!< The data FwSizeType capacity //!< The capacity ) { this->m_impl.setStorage(data, capacity); From 3edb67b058d195ff493f6f9920f51f8d397b8de1 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 16:06:20 -0700 Subject: [PATCH 389/458] Revert changes to map interface --- Fw/DataStructures/ArrayMap.hpp | 13 +-- Fw/DataStructures/ArraySet.hpp | 10 +-- Fw/DataStructures/ArraySetOrMapImpl.hpp | 4 +- Fw/DataStructures/ExternalArrayMap.hpp | 13 +-- Fw/DataStructures/ExternalArraySet.hpp | 8 +- Fw/DataStructures/MapConstIterator.hpp | 1 + Fw/DataStructures/MapEntry.hpp | 79 +++++-------------- .../SetOrMapImplConstIterator.hpp | 5 +- Fw/DataStructures/docs/ArrayMap.md | 2 +- Fw/DataStructures/docs/ArraySet.md | 2 +- Fw/DataStructures/docs/ArraySetOrMapImpl.md | 2 +- Fw/DataStructures/docs/ExternalArrayMap.md | 2 +- Fw/DataStructures/docs/ExternalArraySet.md | 2 +- Fw/DataStructures/docs/Nil.md | 2 +- Fw/DataStructures/docs/SetOrMapImplEntry.md | 24 +++--- Fw/DataStructures/test/ut/ArrayMapTest.cpp | 2 +- .../test/ut/ArraySetOrMapImplTester.hpp | 2 +- Fw/DataStructures/test/ut/ArraySetTest.cpp | 2 +- .../test/ut/ExternalArrayMapTest.cpp | 2 +- .../test/ut/ExternalArraySetTest.cpp | 2 +- .../ut/STest/ArraySetOrMapImplTestState.hpp | 2 +- 21 files changed, 76 insertions(+), 105 deletions(-) diff --git a/Fw/DataStructures/ArrayMap.hpp b/Fw/DataStructures/ArrayMap.hpp index 4b6f79dce07..a6673c67a83 100644 --- a/Fw/DataStructures/ArrayMap.hpp +++ b/Fw/DataStructures/ArrayMap.hpp @@ -25,11 +25,14 @@ class ArrayMap final : public MapBase { // Public types // ---------------------------------------------------------------------- - //! The type of an entry in the map - using Entry = MapEntry; + //! The type of an implementation entry + using ImplEntry = SetOrMapImplEntry; - //! The type of the entries - using Entries = Entry[C]; + //! The type of a map entry + using MapEntry = MapEntry; + + //! The type of the implementation entries + using ImplEntries = ImplEntry[C]; public: // ---------------------------------------------------------------------- @@ -108,7 +111,7 @@ class ArrayMap final : public MapBase { ExternalArrayMap m_extMap = {}; //! The array providing the backing memory for m_extMap - Entries m_entries = {}; + ImplEntries m_entries = {}; }; } // namespace Fw diff --git a/Fw/DataStructures/ArraySet.hpp b/Fw/DataStructures/ArraySet.hpp index cd87603211d..db7aea8a23d 100644 --- a/Fw/DataStructures/ArraySet.hpp +++ b/Fw/DataStructures/ArraySet.hpp @@ -25,11 +25,11 @@ class ArraySet final : public SetBase { // Public types // ---------------------------------------------------------------------- - //! The type of an entry in the map that implements the set - using Entry = MapEntry; + //! The type of animplementation entry + using ImplEntry = SetOrMapImplEntry; - //! The type of the entries - using Entries = Entry[C]; + //! The type of the implementation entries + using ImplEntries = ImplEntry[C]; public: // ---------------------------------------------------------------------- @@ -105,7 +105,7 @@ class ArraySet final : public SetBase { ExternalArraySet m_extSet = {}; //! The array providing the backing memory for m_extSet - Entries m_entries = {}; + ImplEntries m_entries = {}; }; } // namespace Fw diff --git a/Fw/DataStructures/ArraySetOrMapImpl.hpp b/Fw/DataStructures/ArraySetOrMapImpl.hpp index 891001b5f1c..3f9d66d0fb2 100644 --- a/Fw/DataStructures/ArraySetOrMapImpl.hpp +++ b/Fw/DataStructures/ArraySetOrMapImpl.hpp @@ -8,8 +8,8 @@ #define Fw_ArraySetOrMapImpl_HPP #include "Fw/DataStructures/ExternalArray.hpp" -#include "Fw/DataStructures/MapEntry.hpp" #include "Fw/DataStructures/SetOrMapImplConstIterator.hpp" +#include "Fw/DataStructures/SetOrMapImplEntry.hpp" #include "Fw/Types/Assert.hpp" #include "Fw/Types/SuccessEnumAc.hpp" @@ -30,7 +30,7 @@ class ArraySetOrMapImpl final { // ---------------------------------------------------------------------- //! The type of an entry in the set or map - using Entry = MapEntry; + using Entry = SetOrMapImplEntry; //! Const iterator class ConstIterator final : public SetOrMapImplConstIterator { diff --git a/Fw/DataStructures/ExternalArrayMap.hpp b/Fw/DataStructures/ExternalArrayMap.hpp index b3808d62998..43e2bd1b624 100644 --- a/Fw/DataStructures/ExternalArrayMap.hpp +++ b/Fw/DataStructures/ExternalArrayMap.hpp @@ -27,8 +27,11 @@ class ExternalArrayMap final : public MapBase { // Public types // ---------------------------------------------------------------------- + //! The type of a map implementation entry + using ImplEntry = SetOrMapImplEntry; + //! The type of a map entry - using Entry = MapEntry; + using MapEntry = MapEntry; public: // ---------------------------------------------------------------------- @@ -39,8 +42,8 @@ class ExternalArrayMap final : public MapBase { ExternalArrayMap() = default; //! Constructor providing typed backing storage. - //! entries must point to at least capacity elements of type Entry. - ExternalArrayMap(Entry* entries, //!< The entries + //! entries must point to at least capacity elements of type ImplEntry. + ExternalArrayMap(ImplEntry* entries, //!< The entries FwSizeType capacity //!< The capacity ) : MapBase() { @@ -120,8 +123,8 @@ class ExternalArrayMap final : public MapBase { } //! Set the backing storage (typed data) - //! entries must point to at least capacity elements of type Entry. - void setStorage(Entry* entries, //!< The entries + //! entries must point to at least capacity elements of type ImplEntry. + void setStorage(ImplEntry* entries, //!< The entries FwSizeType capacity //!< The capacity ) { this->m_impl.setStorage(entries, capacity); diff --git a/Fw/DataStructures/ExternalArraySet.hpp b/Fw/DataStructures/ExternalArraySet.hpp index ef9e8d72702..f576d31e606 100644 --- a/Fw/DataStructures/ExternalArraySet.hpp +++ b/Fw/DataStructures/ExternalArraySet.hpp @@ -29,7 +29,7 @@ class ExternalArraySet final : public SetBase { // ---------------------------------------------------------------------- //! The type of a set entry - using Entry = MapEntry; + using Entry = SetOrMapImplEntry; public: // ---------------------------------------------------------------------- @@ -40,7 +40,7 @@ class ExternalArraySet final : public SetBase { ExternalArraySet() = default; //! Constructor providing typed backing storage. - //! entries must point to at least capacity elements of type Entry. + //! entries must point to at least capacity elements of type ImplEntry. ExternalArraySet(Entry* entries, //!< The entries FwSizeType capacity //!< The capacity ) @@ -120,7 +120,7 @@ class ExternalArraySet final : public SetBase { } //! Set the backing storage (typed data) - //! entries must point to at least capacity elements of type Entry. + //! entries must point to at least capacity elements of type ImplEntry. void setStorage(Entry* entries, //!< The entries FwSizeType capacity //!< The capacity ) { @@ -130,7 +130,7 @@ class ExternalArraySet final : public SetBase { //! 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 + void setStorage(ByteArray data, //!< THe data FwSizeType capacity //!< The capacity ) { this->m_impl.setStorage(data, capacity); diff --git a/Fw/DataStructures/MapConstIterator.hpp b/Fw/DataStructures/MapConstIterator.hpp index 070737e7483..a7acc8eb52e 100644 --- a/Fw/DataStructures/MapConstIterator.hpp +++ b/Fw/DataStructures/MapConstIterator.hpp @@ -10,6 +10,7 @@ #include #include "Fw/DataStructures/ArraySetOrMapImpl.hpp" +#include "Fw/DataStructures/MapEntry.hpp" #include "Fw/FPrimeBasicTypes.hpp" namespace Fw { diff --git a/Fw/DataStructures/MapEntry.hpp b/Fw/DataStructures/MapEntry.hpp index 9934152f49a..7fc7021e84b 100644 --- a/Fw/DataStructures/MapEntry.hpp +++ b/Fw/DataStructures/MapEntry.hpp @@ -1,7 +1,7 @@ // ====================================================================== // \title MapEntry // \author bocchino -// \brief A class template representing an entry for a set or map implementation +// \brief An abstract class template representing an entry in a map // ====================================================================== #ifndef Fw_MapEntry_HPP @@ -11,82 +11,45 @@ namespace Fw { -template -class MapEntry final { - public: +template +class MapEntry { + private: // ---------------------------------------------------------------------- - // Public constructors and destructors + // Deleted elements // ---------------------------------------------------------------------- - //! Zero-argument constructor - MapEntry() {} - - //! Constructor providing members - MapEntry(const KE& keyOrElement, //!< The key or element - const VN& valueOrNil //!< The value or Nil - ) - : m_keyOrElement(keyOrElement), m_valueOrNil(valueOrNil) {} - - //! Copy constructor - MapEntry(const MapEntry& entry) { *this = entry; } + //! Copy constructor deleted in the base class + //! Behavior depends on the implementation + MapEntry(const MapEntry&) = delete; - //! Destructor - ~MapEntry() = default; + //! operator= deleted in the base class + //! Behavior depends on the implementation + //! We avoid virtual user-defined operators + MapEntry& operator=(const MapEntry&) = delete; - public: + protected: // ---------------------------------------------------------------------- - // Public member functions + // Protected constructors and destructors // ---------------------------------------------------------------------- - //! operator= - MapEntry& operator=(const MapEntry& entry) { - if (this != &entry) { - this->m_keyOrElement = entry.m_keyOrElement; - this->m_valueOrNil = entry.m_valueOrNil; - } - return *this; - } - - //! Get the key or element associated with this entry - //! \return The key or element - const KE& getKeyOrElement() const { return this->m_keyOrElement; } - - //! Get the value or nil associated with this entry - //! \return The value or nil - const VN& getValueOrNil() const { return this->m_valueOrNil; } - - //! Set the key or element - void setKeyOrElement(const KE& keyOrElement //!< The key or element - ) { - this->m_keyOrElement = keyOrElement; - } + //! Zero-argument constructor + MapEntry() = default; - //! Set the value or Nil - void setValueOrNil(const VN& valueOrNil) { this->m_valueOrNil = valueOrNil; } + //! Destructor + virtual ~MapEntry() = default; public: // ---------------------------------------------------------------------- - // MapEntry implementation + // Public member functions // ---------------------------------------------------------------------- //! Get the key associated with this entry //! \return The key - const KE& getKey() const { return this->m_keyOrElement; } + virtual const K& getKey() const = 0; //! Get the value associated with this entry //! \return The value - const VN& getValue() const { return this->m_valueOrNil; } - - private: - // ---------------------------------------------------------------------- - // Private member variables - // ---------------------------------------------------------------------- - - //! The map key or set element - KE m_keyOrElement = {}; - - //! The value or nil - VN m_valueOrNil = {}; + virtual const V& getValue() const = 0; }; } // namespace Fw diff --git a/Fw/DataStructures/SetOrMapImplConstIterator.hpp b/Fw/DataStructures/SetOrMapImplConstIterator.hpp index 0003baefe08..f3c59e0d503 100644 --- a/Fw/DataStructures/SetOrMapImplConstIterator.hpp +++ b/Fw/DataStructures/SetOrMapImplConstIterator.hpp @@ -7,7 +7,7 @@ #ifndef Fw_SetOrMapImplConstIterator_HPP #define Fw_SetOrMapImplConstIterator_HPP -#include "Fw/DataStructures/MapEntry.hpp" +#include "Fw/DataStructures/SetOrMapImplEntry.hpp" #include "Fw/FPrimeBasicTypes.hpp" namespace Fw { @@ -62,7 +62,8 @@ class SetOrMapImplConstIterator { //! Get the set or map impl entry pointed to by this iterator //! \return The set or map impl entry - virtual const MapEntry& getEntry() const = 0; + virtual const SetOrMapImplEntry& getEntry() const = 0; + }; } // namespace Fw diff --git a/Fw/DataStructures/docs/ArrayMap.md b/Fw/DataStructures/docs/ArrayMap.md index 0641efab82d..d3b1d9d6600 100644 --- a/Fw/DataStructures/docs/ArrayMap.md +++ b/Fw/DataStructures/docs/ArrayMap.md @@ -28,7 +28,7 @@ It represents an array-based map with internal storage. |Name|Definition| |----|----------| -|`ImplEntry`|Alias of [`MapEntry`](MapEntry.md)| +|`ImplEntry`|Alias of [`SetOrMapImplEntry`](SetOrMapImplEntry.md)| |`MapEntry`|Alias of [`MapEntry`](MapEntry.md)| |`ImplEntries`|Alias of `ImplEntry[C]`| diff --git a/Fw/DataStructures/docs/ArraySet.md b/Fw/DataStructures/docs/ArraySet.md index 71b8f212dd1..7a329bb631b 100644 --- a/Fw/DataStructures/docs/ArraySet.md +++ b/Fw/DataStructures/docs/ArraySet.md @@ -27,7 +27,7 @@ It represents an array-based set with internal storage. |Name|Definition| |----|----------| -|`Entry`|Alias of [`MapEntry`](MapEntry.md)| +|`Entry`|Alias of [`SetOrMapImplEntry`](SetOrMapImplEntry.md)| |`SetEntry`|Alias of [`SetEntry`](SetEntry.md)| The type `Nil` is defined [here](Nil.md). diff --git a/Fw/DataStructures/docs/ArraySetOrMapImpl.md b/Fw/DataStructures/docs/ArraySetOrMapImpl.md index dab0cd08dc5..5427e906131 100644 --- a/Fw/DataStructures/docs/ArraySetOrMapImpl.md +++ b/Fw/DataStructures/docs/ArraySetOrMapImpl.md @@ -25,7 +25,7 @@ storing the entries in the set or map. |Name|Definition| |----|----------| -|`Entry`|Alias for [`MapEntry`](MapEntry.md)| +|`Entry`|Alias for [`SetOrMapImplEntry`](SetOrMapImplEntry.md)| ### 2.2. ConstIterator diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index 7f80e5cd286..33e8be5e775 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -27,7 +27,7 @@ as the map implementation. |Name|Definition| |----|----------| -|`ImplEntry`|Alias of [`MapEntry`](MapEntry.md)| +|`ImplEntry`|Alias of [`SetOrMapImplEntry`](SetOrMapImplEntry.md)| |`MapEntry`|Alias of [`MapEntry`](MapEntry.md)| ## 4. Private Member Variables diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md index 32c6eed288b..88899f4d463 100644 --- a/Fw/DataStructures/docs/ExternalArraySet.md +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -26,7 +26,7 @@ as the set implementation. |Name|Definition| |----|----------| -|`ImplEntry`|Alias of [`MapEntry`](MapEntry.md)| +|`ImplEntry`|Alias of [`SetOrMapImplEntry`](SetOrMapImplEntry.md)| |`SetEntry`|Alias of [`SetEntry`](SetEntry.md)| The type `Nil` is defined [here](Nil.md). diff --git a/Fw/DataStructures/docs/Nil.md b/Fw/DataStructures/docs/Nil.md index cd164e488d7..1600881b9ed 100644 --- a/Fw/DataStructures/docs/Nil.md +++ b/Fw/DataStructures/docs/Nil.md @@ -2,5 +2,5 @@ `Nil` is an empty type. It is a placeholder that is used as the value type -when a [`MapEntry`](MapEntry.md) +when a [`SetOrMapImplEntry`](SetOrMapImplEntry.md) is used as a set iterator. diff --git a/Fw/DataStructures/docs/SetOrMapImplEntry.md b/Fw/DataStructures/docs/SetOrMapImplEntry.md index 10839bc2e2a..34807c31d37 100644 --- a/Fw/DataStructures/docs/SetOrMapImplEntry.md +++ b/Fw/DataStructures/docs/SetOrMapImplEntry.md @@ -1,12 +1,12 @@ -# MapEntry +# SetOrMapImplEntry -`MapEntry` is a final class template +`SetOrMapImplEntry` is a final class template defined in [`Fw/DataStructures`](sdd.md). -It represents an entry for a set or a map implementation. +It represents an iterator for a set or a map implementation. ## 1. Template Parameters -`MapEntry` has the following template parameters. +`SetOrMapImplEntry` has the following template parameters. |Kind|Name|Purpose| |----|----|-------| @@ -15,19 +15,19 @@ It represents an entry for a set or a map implementation. ## 2. Base Class -`MapEntry` is publicly derived from the following +`SetOrMapImplEntry` is publicly derived from the following templates: 1. [`MapEntry`](MapEntry.md). ```mermaid classDiagram - MapEntry <|-- MapEntry + MapEntry <|-- SetOrMapImplEntry ``` ## 3. Private Member Variables -`MapEntry` has the following private member variables. +`SetOrMapImplEntry` has the following private member variables. |Name|Type|Purpose|Default Value| |----|----|-------|-------------| @@ -39,7 +39,7 @@ classDiagram ### 4.1. Zero-Argument Constructor ```c++ -MapEntry() +SetOrMapImplEntry() ``` Use default initialization of members. @@ -47,7 +47,7 @@ Use default initialization of members. ### 4.2. Constructor Providing Members ```c++ -MapEntry(const KE& keyOrElement, const VN& valueOrNil) +SetOrMapImplEntry(const KE& keyOrElement, const VN& valueOrNil) ``` 1. Set `m_keyOrElement = keyOrElement`. @@ -57,7 +57,7 @@ MapEntry(const KE& keyOrElement, const VN& valueOrNil) ### 4.3. Copy Constructor ```c++ -MapEntry(const MapEntry& iterator) +SetOrMapImplEntry(const SetOrMapImplEntry& iterator) ``` Set `*this = iterator`. @@ -65,7 +65,7 @@ Set `*this = iterator`. ### 4.4. Destructor ```c++ -~MapEntry() override +~SetOrMapImplEntry() override ``` Defined as `= default`. @@ -75,7 +75,7 @@ Defined as `= default`. ### 5.1. operator= ```c++ -MapEntry& operator=(const MapEntry& iterator) +SetOrMapImplEntry& operator=(const SetOrMapImplEntry& iterator) ``` 1. If `this != &iterator` diff --git a/Fw/DataStructures/test/ut/ArrayMapTest.cpp b/Fw/DataStructures/test/ut/ArrayMapTest.cpp index f595754d500..9ae8069954d 100644 --- a/Fw/DataStructures/test/ut/ArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ArrayMapTest.cpp @@ -30,7 +30,7 @@ class ArrayMapTester { namespace MapTest { using ConstIterator = MapConstIterator; -using Entry = MapEntry; +using Entry = SetOrMapImplEntry; using Map = ArrayMap; using MapTester = ArrayMapTester; using ImplTester = ArraySetOrMapImplTester; diff --git a/Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp b/Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp index b36eb8b93ca..fd5b4726e47 100644 --- a/Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp +++ b/Fw/DataStructures/test/ut/ArraySetOrMapImplTester.hpp @@ -17,7 +17,7 @@ namespace Fw { template class ArraySetOrMapImplTester { public: - using Entry = MapEntry; + using Entry = SetOrMapImplEntry; ArraySetOrMapImplTester(const ArraySetOrMapImpl& impl) : m_impl(impl) {} diff --git a/Fw/DataStructures/test/ut/ArraySetTest.cpp b/Fw/DataStructures/test/ut/ArraySetTest.cpp index 3f35d5f9f7b..d902f0fce9e 100644 --- a/Fw/DataStructures/test/ut/ArraySetTest.cpp +++ b/Fw/DataStructures/test/ut/ArraySetTest.cpp @@ -29,7 +29,7 @@ class ArraySetTester { namespace SetTest { -using Entry = MapEntry; +using Entry = SetOrMapImplEntry; using Set = ArraySet; using SetTester = ArraySetTester; using ImplTester = ArraySetOrMapImplTester; diff --git a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp index c5fc56fbe61..0d2112e4629 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayMapTest.cpp @@ -25,7 +25,7 @@ class ExternalArrayMapTester { namespace MapTest { -using Entry = MapEntry; +using Entry = SetOrMapImplEntry; using Map = ExternalArrayMap; using MapTester = ExternalArrayMapTester; using ImplTester = ArraySetOrMapImplTester; diff --git a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp index 4f983f60caf..d1c809c4117 100644 --- a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp @@ -27,7 +27,7 @@ class ExternalArraySetTester { namespace SetTest { -using Entry = MapEntry; +using Entry = SetOrMapImplEntry; using Set = ExternalArraySet; using SetTester = ExternalArraySetTester; using ImplTester = ArraySetOrMapImplTester; diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp index dd26e5b7df7..10131e3f9f7 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestState.hpp @@ -29,7 +29,7 @@ struct State { //! The Tester type using Tester = ArraySetOrMapImplTester; //! The entry type - using Entry = MapEntry; + using Entry = SetOrMapImplEntry; //! Constructor State(Impl& a_impl) : impl(a_impl), tester(a_impl) {} //! The array set or map under test From da8b02598c21ed11f58d7cdf04d18b2dd078c2e2 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 16:22:34 -0700 Subject: [PATCH 390/458] Rename MapEntry to MapEntryBase --- Fw/DataStructures/ArrayMap.hpp | 2 +- Fw/DataStructures/ExternalArrayMap.hpp | 2 +- Fw/DataStructures/MapConstIterator.hpp | 8 ++++---- .../{MapEntry.hpp => MapEntryBase.hpp} | 18 +++++++++--------- Fw/DataStructures/docs/ArrayMap.md | 2 +- Fw/DataStructures/docs/ExternalArrayMap.md | 2 +- Fw/DataStructures/docs/MapConstIterator.md | 10 +++++----- .../docs/{MapEntry.md => MapEntryBase.md} | 10 +++++----- Fw/DataStructures/docs/SetOrMapImplEntry.md | 4 ++-- 9 files changed, 29 insertions(+), 29 deletions(-) rename Fw/DataStructures/{MapEntry.hpp => MapEntryBase.hpp} (79%) rename Fw/DataStructures/docs/{MapEntry.md => MapEntryBase.md} (76%) diff --git a/Fw/DataStructures/ArrayMap.hpp b/Fw/DataStructures/ArrayMap.hpp index a6673c67a83..5d2e5523234 100644 --- a/Fw/DataStructures/ArrayMap.hpp +++ b/Fw/DataStructures/ArrayMap.hpp @@ -29,7 +29,7 @@ class ArrayMap final : public MapBase { using ImplEntry = SetOrMapImplEntry; //! The type of a map entry - using MapEntry = MapEntry; + using MapEntryBase = MapEntryBase; //! The type of the implementation entries using ImplEntries = ImplEntry[C]; diff --git a/Fw/DataStructures/ExternalArrayMap.hpp b/Fw/DataStructures/ExternalArrayMap.hpp index 43e2bd1b624..bf1c073cd5a 100644 --- a/Fw/DataStructures/ExternalArrayMap.hpp +++ b/Fw/DataStructures/ExternalArrayMap.hpp @@ -31,7 +31,7 @@ class ExternalArrayMap final : public MapBase { using ImplEntry = SetOrMapImplEntry; //! The type of a map entry - using MapEntry = MapEntry; + using MapEntryBase = MapEntryBase; public: // ---------------------------------------------------------------------- diff --git a/Fw/DataStructures/MapConstIterator.hpp b/Fw/DataStructures/MapConstIterator.hpp index a7acc8eb52e..bcccb29bc46 100644 --- a/Fw/DataStructures/MapConstIterator.hpp +++ b/Fw/DataStructures/MapConstIterator.hpp @@ -10,7 +10,7 @@ #include #include "Fw/DataStructures/ArraySetOrMapImpl.hpp" -#include "Fw/DataStructures/MapEntry.hpp" +#include "Fw/DataStructures/MapEntryBase.hpp" #include "Fw/FPrimeBasicTypes.hpp" namespace Fw { @@ -24,7 +24,7 @@ class MapConstIterator { //! The type of an array iterator using ArrayIterator = typename ArraySetOrMapImpl::ConstIterator; - using MapEntry = MapEntry; + using MapEntryBase = MapEntryBase; private: // ---------------------------------------------------------------------- @@ -123,10 +123,10 @@ class MapConstIterator { bool isInRange() const { return this->getImplIterator().isInRange(); } //! Dereference - const MapEntry& operator*() const { return this->getImplIterator().getEntry(); } + const MapEntryBase& operator*() const { return this->getImplIterator().getEntry(); } //! Pointer - const MapEntry* operator->() const { return &this->getImplIterator().getEntry(); } + const MapEntryBase* operator->() const { return &this->getImplIterator().getEntry(); } private: // ---------------------------------------------------------------------- diff --git a/Fw/DataStructures/MapEntry.hpp b/Fw/DataStructures/MapEntryBase.hpp similarity index 79% rename from Fw/DataStructures/MapEntry.hpp rename to Fw/DataStructures/MapEntryBase.hpp index 7fc7021e84b..c270b88e129 100644 --- a/Fw/DataStructures/MapEntry.hpp +++ b/Fw/DataStructures/MapEntryBase.hpp @@ -1,18 +1,18 @@ // ====================================================================== -// \title MapEntry +// \title MapEntryBase // \author bocchino -// \brief An abstract class template representing an entry in a map +// \brief An abstract base class representing an entry in a map // ====================================================================== -#ifndef Fw_MapEntry_HPP -#define Fw_MapEntry_HPP +#ifndef Fw_MapEntryBase_HPP +#define Fw_MapEntryBase_HPP #include "Fw/FPrimeBasicTypes.hpp" namespace Fw { template -class MapEntry { +class MapEntryBase { private: // ---------------------------------------------------------------------- // Deleted elements @@ -20,12 +20,12 @@ class MapEntry { //! Copy constructor deleted in the base class //! Behavior depends on the implementation - MapEntry(const MapEntry&) = delete; + MapEntryBase(const MapEntryBase&) = delete; //! operator= deleted in the base class //! Behavior depends on the implementation //! We avoid virtual user-defined operators - MapEntry& operator=(const MapEntry&) = delete; + MapEntryBase& operator=(const MapEntryBase&) = delete; protected: // ---------------------------------------------------------------------- @@ -33,10 +33,10 @@ class MapEntry { // ---------------------------------------------------------------------- //! Zero-argument constructor - MapEntry() = default; + MapEntryBase() = default; //! Destructor - virtual ~MapEntry() = default; + virtual ~MapEntryBase() = default; public: // ---------------------------------------------------------------------- diff --git a/Fw/DataStructures/docs/ArrayMap.md b/Fw/DataStructures/docs/ArrayMap.md index d3b1d9d6600..88290fd12fb 100644 --- a/Fw/DataStructures/docs/ArrayMap.md +++ b/Fw/DataStructures/docs/ArrayMap.md @@ -29,7 +29,7 @@ It represents an array-based map with internal storage. |Name|Definition| |----|----------| |`ImplEntry`|Alias of [`SetOrMapImplEntry`](SetOrMapImplEntry.md)| -|`MapEntry`|Alias of [`MapEntry`](MapEntry.md)| +|`MapEntryBase`|Alias of [`MapEntryBase`](MapEntryBase.md)| |`ImplEntries`|Alias of `ImplEntry[C]`| ## 4. Private Member Variables diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index 33e8be5e775..8bf4303d629 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -28,7 +28,7 @@ as the map implementation. |Name|Definition| |----|----------| |`ImplEntry`|Alias of [`SetOrMapImplEntry`](SetOrMapImplEntry.md)| -|`MapEntry`|Alias of [`MapEntry`](MapEntry.md)| +|`MapEntryBase`|Alias of [`MapEntryBase`](MapEntryBase.md)| ## 4. Private Member Variables diff --git a/Fw/DataStructures/docs/MapConstIterator.md b/Fw/DataStructures/docs/MapConstIterator.md index b1db65ce493..afe8670622f 100644 --- a/Fw/DataStructures/docs/MapConstIterator.md +++ b/Fw/DataStructures/docs/MapConstIterator.md @@ -17,7 +17,7 @@ |Name|Definition| |----|----------| -|`MapEntry`|Alias of [`MapEntry`](MapEntry.md)| +|`MapEntryBase`|Alias of [`MapEntryBase`](MapEntryBase.md)| ## 3. Constructors and Destructors @@ -78,17 +78,17 @@ Check whether the iterator is in range. ### 4.6. operator* ```c++ -const MapEntry& operator*() const +const MapEntryBase& operator*() const ``` -Return a `const` reference to the `MapEntry` object +Return a `const` reference to the `MapEntryBase` object pointed to by the iterator. ### 4.7. operator-> ```c++ -const MapEntry* operator->() const +const MapEntryBase* operator->() const ``` -Return a pointer to the `const MapEntry` object +Return a pointer to the `const MapEntryBase` object pointed to by the iterator. diff --git a/Fw/DataStructures/docs/MapEntry.md b/Fw/DataStructures/docs/MapEntryBase.md similarity index 76% rename from Fw/DataStructures/docs/MapEntry.md rename to Fw/DataStructures/docs/MapEntryBase.md index b623b093603..63b4d806e0f 100644 --- a/Fw/DataStructures/docs/MapEntry.md +++ b/Fw/DataStructures/docs/MapEntryBase.md @@ -1,12 +1,12 @@ -# MapEntry +# MapEntryBase -`MapEntry` is an abstract class template +`MapEntryBase` is an abstract class template defined in [`Fw/DataStructures`](sdd.md). -It represents an entry for a map. +It provides the user-facing interface for a map entry. ## 1. Template Parameters -`MapEntry` has the following template parameters. +`MapEntryBase` has the following template parameters. |Kind|Name|Purpose| |----|----|-------| @@ -20,7 +20,7 @@ the copy constructor and copy assignment operator are deleted. ## 3. Protected Constructors and Destructors -`MapEntry` provides a protected zero-argument constructor +`MapEntryBase` provides a protected zero-argument constructor and a protected virtual destructor. It uses the default implementations. diff --git a/Fw/DataStructures/docs/SetOrMapImplEntry.md b/Fw/DataStructures/docs/SetOrMapImplEntry.md index 34807c31d37..126c0e4cdc3 100644 --- a/Fw/DataStructures/docs/SetOrMapImplEntry.md +++ b/Fw/DataStructures/docs/SetOrMapImplEntry.md @@ -18,11 +18,11 @@ It represents an iterator for a set or a map implementation. `SetOrMapImplEntry` is publicly derived from the following templates: -1. [`MapEntry`](MapEntry.md). +1. [`MapEntryBase`](MapEntryBase.md). ```mermaid classDiagram - MapEntry <|-- SetOrMapImplEntry + MapEntryBase <|-- SetOrMapImplEntry ``` ## 3. Private Member Variables From 1538ecf7a94fa7a2f099c92fab44aeb10c71af23 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 16:28:54 -0700 Subject: [PATCH 391/458] Revise type aliases --- Fw/DataStructures/ExternalArrayMap.hpp | 13 +++----- Fw/DataStructures/MapConstIterator.hpp | 6 ++-- Fw/DataStructures/docs/ExternalArrayMap.md | 37 +++++++++++----------- Fw/DataStructures/docs/MapConstIterator.md | 10 +++--- 4 files changed, 31 insertions(+), 35 deletions(-) diff --git a/Fw/DataStructures/ExternalArrayMap.hpp b/Fw/DataStructures/ExternalArrayMap.hpp index bf1c073cd5a..26a79668f5d 100644 --- a/Fw/DataStructures/ExternalArrayMap.hpp +++ b/Fw/DataStructures/ExternalArrayMap.hpp @@ -27,11 +27,8 @@ class ExternalArrayMap final : public MapBase { // Public types // ---------------------------------------------------------------------- - //! The type of a map implementation entry - using ImplEntry = SetOrMapImplEntry; - //! The type of a map entry - using MapEntryBase = MapEntryBase; + using Entry = SetOrMapImplEntry; public: // ---------------------------------------------------------------------- @@ -42,8 +39,8 @@ class ExternalArrayMap final : public MapBase { ExternalArrayMap() = default; //! Constructor providing typed backing storage. - //! entries must point to at least capacity elements of type ImplEntry. - ExternalArrayMap(ImplEntry* entries, //!< The entries + //! entries must point to at least capacity elements of type Entry. + ExternalArrayMap(Entry* entries, //!< The entries FwSizeType capacity //!< The capacity ) : MapBase() { @@ -123,8 +120,8 @@ class ExternalArrayMap final : public MapBase { } //! Set the backing storage (typed data) - //! entries must point to at least capacity elements of type ImplEntry. - void setStorage(ImplEntry* entries, //!< The entries + //! entries must point to at least capacity elements of type Entry. + void setStorage(Entry* entries, //!< The entries FwSizeType capacity //!< The capacity ) { this->m_impl.setStorage(entries, capacity); diff --git a/Fw/DataStructures/MapConstIterator.hpp b/Fw/DataStructures/MapConstIterator.hpp index bcccb29bc46..e2842d2b4de 100644 --- a/Fw/DataStructures/MapConstIterator.hpp +++ b/Fw/DataStructures/MapConstIterator.hpp @@ -24,7 +24,7 @@ class MapConstIterator { //! The type of an array iterator using ArrayIterator = typename ArraySetOrMapImpl::ConstIterator; - using MapEntryBase = MapEntryBase; + using EntryBase = MapEntryBase; private: // ---------------------------------------------------------------------- @@ -123,10 +123,10 @@ class MapConstIterator { bool isInRange() const { return this->getImplIterator().isInRange(); } //! Dereference - const MapEntryBase& operator*() const { return this->getImplIterator().getEntry(); } + const EntryBase& operator*() const { return this->getImplIterator().getEntry(); } //! Pointer - const MapEntryBase* operator->() const { return &this->getImplIterator().getEntry(); } + const EntryBase* operator->() const { return &this->getImplIterator().getEntry(); } private: // ---------------------------------------------------------------------- diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index 8bf4303d629..d50db70e8ce 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -27,8 +27,7 @@ as the map implementation. |Name|Definition| |----|----------| -|`ImplEntry`|Alias of [`SetOrMapImplEntry`](SetOrMapImplEntry.md)| -|`MapEntryBase`|Alias of [`MapEntryBase`](MapEntryBase.md)| +|`Entry`|Alias of [`SetOrMapEntry`](SetOrMapEntry.md)| ## 4. Private Member Variables @@ -61,11 +60,11 @@ ExternalArrayMap map; ### 5.2. Constructor Providing Typed Backing Storage ```c++ -ExternalArrayMap(ImplEntry* entries, FwSizeType capacity) +ExternalArrayMap(Entry* entries, FwSizeType capacity) ``` `entries` must point to a primitive array of at least `capacity` -elements of type [`ImplEntry`](ExternalArrayMap.md#Public-Types). +elements of type [`Entry`](ExternalArrayMap.md#Public-Types). Call `setStorage(entries, capacity)`. @@ -73,7 +72,7 @@ _Example:_ ```c++ using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -Map::ImplEntry entries[capacity]; +Map::Entry entries[capacity]; Map map(entries, capacity); ``` @@ -111,7 +110,7 @@ _Example:_ ```c++ using Map = ExternalArrayMap; constexpr FwSizeType capacity = 3; -Map::ImplEntry entries[capacity]; +Map::Entry entries[capacity]; // Call the constructor providing backing storage Map m1(entries, capacity); // Insert an item @@ -150,7 +149,7 @@ _Example:_ ```c++ using Map = ExternalArrayMap; constexpr FwSizeType capacity = 3; -Map::ImplEntry entries[capacity]; +Map::Entry entries[capacity]; // Call the constructor providing backing storage Map m1(entries, capacity); // Insert an item @@ -182,7 +181,7 @@ _Example:_ ```c++ using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -Map::ImplEntry entries[capacity]; +Map::Entry entries[capacity]; // Call the constructor providing backing storage Map map(entries, capacity); // Insert an entry in the map @@ -209,7 +208,7 @@ _Example:_ ```c++ using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -Map::ImplEntry entries[capacity]; +Map::Entry entries[capacity]; Map map(entries, capacity); const auto status = map.insert(0, 3); ASSERT_EQ(map.getSize(), 1); @@ -229,7 +228,7 @@ _Example:_ ```c++ using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -Map::ImplEntry entries[capacity]; +Map::Entry entries[capacity]; // Call the constructor providing backing storage Map map(entries, capacity); // Insert an entry in the map @@ -257,7 +256,7 @@ _Example:_ ```c++ using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -Map::ImplEntry entries[capacity]; +Map::Entry entries[capacity]; Map map(entries, capacity); U32 value = 0; auto status = map.find(0, value); @@ -281,7 +280,7 @@ _Example:_ ```c++ using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -Map::ImplEntry entries[capacity]; +Map::Entry entries[capacity]; Map map(entries, capacity); ASSERT_EQ(map.getCapacity(), capacity); ``` @@ -298,7 +297,7 @@ _Example:_ ```c++ using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -Map::ImplEntry entries[capacity]; +Map::Entry entries[capacity]; Map map(entries, capacity); auto size = map.getSize(); ASSERT_EQ(size, 0); @@ -320,7 +319,7 @@ _Example:_ ```c++ using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -Map::ImplEntry entries[capacity]; +Map::Entry entries[capacity]; Map map(entries, capacity); auto size = map.getSize(); ASSERT_EQ(size, 0); @@ -342,7 +341,7 @@ _Example:_ ```c++ using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; -Map::ImplEntry entries[capacity]; +Map::Entry entries[capacity]; Map map(entries, capacity); auto size = map.getSize(); ASSERT_EQ(size, 0); @@ -365,12 +364,12 @@ ASSERT_EQ(value, 1); ### 6.10. setStorage (Typed Data) ```c++ -void setStorage(ImplEntry* entries, FwSizeType capacity) +void setStorage(Entry* entries, FwSizeType capacity) ``` `entries` must point to a primitive array of at least `capacity` -elements of type `ImplEntry`. -The type `ImplEntry` is defined [here](ExternalArrayMap.md#Public-Types). +elements of type `Entry`. +The type `Entry` is defined [here](ExternalArrayMap.md#Public-Types). Call `m_impl.setStorage(entries, capacity)`. @@ -379,7 +378,7 @@ _Example:_ using Map = ExternalArrayMap; constexpr FwSizeType capacity = 10; Map map; -Map::ImplEntry entries[capacity]; +Map::Entry entries[capacity]; map.setStorage(entries, capacity); ``` diff --git a/Fw/DataStructures/docs/MapConstIterator.md b/Fw/DataStructures/docs/MapConstIterator.md index afe8670622f..c8ab55dd459 100644 --- a/Fw/DataStructures/docs/MapConstIterator.md +++ b/Fw/DataStructures/docs/MapConstIterator.md @@ -17,7 +17,7 @@ |Name|Definition| |----|----------| -|`MapEntryBase`|Alias of [`MapEntryBase`](MapEntryBase.md)| +|`EntryBase`|Alias of [`MapEntryBase`](MapEntryBase.md)| ## 3. Constructors and Destructors @@ -78,17 +78,17 @@ Check whether the iterator is in range. ### 4.6. operator* ```c++ -const MapEntryBase& operator*() const +const EntryBase& operator*() const ``` -Return a `const` reference to the `MapEntryBase` object +Return a `const` reference to the `EntryBase` object pointed to by the iterator. ### 4.7. operator-> ```c++ -const MapEntryBase* operator->() const +const EntryBase* operator->() const ``` -Return a pointer to the `const MapEntryBase` object +Return a pointer to the `const EntryBase` object pointed to by the iterator. From 21b3a4f8cc4e3551ae0c720169f4836623dfde74 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 20:18:54 -0700 Subject: [PATCH 392/458] Reformat code --- Fw/DataStructures/SetOrMapImplConstIterator.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Fw/DataStructures/SetOrMapImplConstIterator.hpp b/Fw/DataStructures/SetOrMapImplConstIterator.hpp index f3c59e0d503..de4b19a32ca 100644 --- a/Fw/DataStructures/SetOrMapImplConstIterator.hpp +++ b/Fw/DataStructures/SetOrMapImplConstIterator.hpp @@ -63,7 +63,6 @@ class SetOrMapImplConstIterator { //! Get the set or map impl entry pointed to by this iterator //! \return The set or map impl entry virtual const SetOrMapImplEntry& getEntry() const = 0; - }; } // namespace Fw From b9754ab66dfce7d91ec70ad03d0c100cfe000767 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 20:39:57 -0700 Subject: [PATCH 393/458] Revise SetBase --- Fw/DataStructures/SetBase.hpp | 17 ++--- Fw/DataStructures/docs/MapBase.md | 6 +- Fw/DataStructures/docs/SetBase.md | 112 +++++++++++++++++------------- 3 files changed, 74 insertions(+), 61 deletions(-) diff --git a/Fw/DataStructures/SetBase.hpp b/Fw/DataStructures/SetBase.hpp index 7a54b7ccd1d..d7f24ac8f2a 100644 --- a/Fw/DataStructures/SetBase.hpp +++ b/Fw/DataStructures/SetBase.hpp @@ -17,13 +17,18 @@ template class SetBase { private: // ---------------------------------------------------------------------- - // Private constructors + // Deleted elements // ---------------------------------------------------------------------- //! Copy constructor deleted in the base class //! Behavior depends on the implementation SetBase(const SetBase&) = delete; + //! operator= deleted in the base class + //! Behavior depends on the implementation + //! We avoid virtual user-defined operators + SetBase& operator=(const SetBase&) = delete; + protected: // ---------------------------------------------------------------------- // Protected constructors and destructors @@ -35,16 +40,6 @@ class SetBase { //! Destructor virtual ~SetBase() = default; - private: - // ---------------------------------------------------------------------- - // Private member functions - // ---------------------------------------------------------------------- - - //! operator= deleted in the base class - //! Behavior depends on the implementation - //! We avoid virtual user-defined operators - SetBase& operator=(const SetBase&) = delete; - public: // ---------------------------------------------------------------------- // Public member functions diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index 0d600d89274..0a753e66f86 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -73,8 +73,8 @@ void f(MapBase& map) { // Get a map const iterator object auto it = map.begin(); // Use the iterator to access the underlying map const entry - const key = it->getKey(); - const value = it->getValue(); + const auto key = it->getKey(); + const auto value = it->getValue(); ASSERT_EQ(key, 0); ASSERT_EQ(value, 1); } @@ -112,7 +112,7 @@ void copyDataFrom(const MapBase& map) 1. For `i` in [0, `size`) - 1. Set `status = insert(it->getKey(), it->getValue())`. + 1. Let `status = insert(it->getKey(), it->getValue())`. 1. Assert `status == Success::SUCCESS`. diff --git a/Fw/DataStructures/docs/SetBase.md b/Fw/DataStructures/docs/SetBase.md index d36168bfa7c..b9e1e6bb5b2 100644 --- a/Fw/DataStructures/docs/SetBase.md +++ b/Fw/DataStructures/docs/SetBase.md @@ -21,15 +21,19 @@ It represents an abstract base class for a set. |----|----------| |`Entry`|Alias of [`SetEntry`](SetEntry.md)| -## 3. Private Constructors +## 3. Deleted Elements -### 3.1. Copy Constructor +The following elements are private and are defined `= delete`: -```c++ -SetBase(const SetBase& set) -``` +1. The copy constructor. + ```c++ + SetBase(const SetBase& map) + ``` -Defined as `= delete`. +1. The assignment operator. + ```c++ + SetBase& operator=(const SetBase&) + ``` ## 4. Protected Constructors and Destructors @@ -49,19 +53,31 @@ virtual ~SetBase() Defined as `= default`. -## 5. Private Member Functions +## 5. Public Member Functions -### 5.1. operator= +### 5.1. begin ```c++ -SetBase& operator=(const SetBase&) +virtual ConstIterator begin() const = 0. ``` -Defined as `= delete`. +_Example:_ +```c++ +void f(SetBase& set) { + set.clear(); + // Insert an element in the set + const auto status = set.insert(42); + ASSERT_EQ(status, Fw::Success::SUCCESS); + // Get a set const iterator object + auto it = set.begin(); + // Use the iterator to access the element + ASSERT_EQ(*it, 42); +} +``` -## 6. Public Member Functions +Return the begin value of the iterator for the implementation. -### 6.1. clear +### 5.2. clear ```c++ virtual void clear() = 0 @@ -77,7 +93,7 @@ void f(SetBase& set) { } ``` -### 6.2. copyDataFrom +### 5.3. copyDataFrom ```c++ void copyDataFrom(const SetBase& set) @@ -89,18 +105,15 @@ void copyDataFrom(const SetBase& set) 1. Let `size` be the minimum of `set.getSize()` and `getCapacity()`. - 1. Set `e = set.getHeadSetEntry()`. + 1. Set `it = map.begin()`. 1. For `i` in [0, `size`) - 1. Assert `e != nullptr`. - - 1. Set `status = insert(e->getElement())`. + 1. Let `status = insert(*it)`. 1. Assert `status == Success::SUCCESS`. - 1. Set `e = e->getNextSetEntry()` - + 1. Call `it++`. _Example:_ ```c++ @@ -117,7 +130,33 @@ void f(SetBase& s1, SetBase& s2) { } ``` -### 6.3. find +### 5.4. end + +```c++ +virtual ConstIterator end() const = 0 +``` + +Return the end value of the iterator for the implementation. + +_Example:_ +```c++ +void f(SetBase& set) { + set.clear(); + // Insert an element in the set + auto status = set.insert(42); + ASSERT_EQ(status, Fw::Success::SUCCESS); + // Get a set const iterator object + auto iter = set.begin(); + // Check that iter is not at the end + ASSERT_NE(iter, set.end()); + // Increment iter + it++; + // Check that iter is at the end + ASSERT_EQ(iter, set.end()); +} +``` + +### 5.5. find ```c++ virtual Success find(const T& element) = 0 @@ -142,7 +181,8 @@ void f(const SetBase& set) { } ``` -### 6.4. getCapacity + +### 5.6. getCapacity ```c++ virtual FwSizeType getCapacity() const = 0 @@ -159,29 +199,7 @@ void f(const SetBase& set) { } ``` -### 6.5. getHeadSetEntry - -```c++ -virtual const Entry* getHeadSetEntry const = 0 -``` - -Get a pointer to the head iterator for the set, or `nullptr` if there is none. - -_Example:_ -```c++ -void f(const SetBase& set) { - set.clear(); - const auto* e = set.getHeadSetEntry(); - ASSERT_EQ(e, nullptr); - set.insert(42); - e = set.getHeadSetEntry(); - ASSERT_NE(e, nullptr); - ASSERT_EQ(e->getElement(), 42); -} - -``` - -### 6.6. getSize +### 5.8. getSize ```c++ virtual FwSizeType getSize() const = 0 @@ -190,9 +208,9 @@ virtual FwSizeType getSize() const = 0 Return the current size. _Example:_ -See [**getCapacity**](SetBase.md#64-getcapacity). +See [**getCapacity**](#getCapacity). -### 6.7. insert +### 5.9. insert ```c++ virtual Success insert(const T& element) = 0 @@ -218,7 +236,7 @@ void f(SetBase& set) { } ``` -### 6.8. remove +### 5.10. remove ```c++ virtual Success remove(const T& element) = 0 From 8142f739210cec7d6bf42800e8524756ab1d52db Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 20:52:20 -0700 Subject: [PATCH 394/458] Revise map interface --- Fw/DataStructures/ArrayMap.hpp | 17 +++--- Fw/DataStructures/ExternalArrayMap.hpp | 7 ++- Fw/DataStructures/ExternalArraySet.hpp | 7 ++- Fw/DataStructures/docs/ArrayMap.md | 7 ++- Fw/DataStructures/docs/ExternalArrayMap.md | 5 +- Fw/DataStructures/docs/ExternalArraySet.md | 68 +++++++++++++++------- 6 files changed, 73 insertions(+), 38 deletions(-) diff --git a/Fw/DataStructures/ArrayMap.hpp b/Fw/DataStructures/ArrayMap.hpp index 5d2e5523234..b13a45e6ed8 100644 --- a/Fw/DataStructures/ArrayMap.hpp +++ b/Fw/DataStructures/ArrayMap.hpp @@ -25,15 +25,18 @@ class ArrayMap final : public MapBase { // Public types // ---------------------------------------------------------------------- + //! The type of a const iterator + using ConstIterator = MapConstIterator; + //! The type of an implementation entry - using ImplEntry = SetOrMapImplEntry; + using Entry = SetOrMapImplEntry; + + //! The type of the implementation entries + using Entries = Entry[C]; //! The type of a map entry using MapEntryBase = MapEntryBase; - //! The type of the implementation entries - using ImplEntries = ImplEntry[C]; - public: // ---------------------------------------------------------------------- // Public constructors and destructors @@ -61,14 +64,14 @@ class ArrayMap final : public MapBase { //! Get the begin iterator //! \return The iterator - MapConstIterator begin() const override { return this->m_extMap.begin(); } + ConstIterator begin() const override { return this->m_extMap.begin(); } //! Clear the map void clear() override { this->m_extMap.clear(); } //! Get the end iterator //! \return The iterator - MapConstIterator end() const override { return this->m_extMap.end(); } + ConstIterator end() const override { return this->m_extMap.end(); } //! Find a value associated with a key in the map //! \return SUCCESS if the item was found @@ -111,7 +114,7 @@ class ArrayMap final : public MapBase { ExternalArrayMap m_extMap = {}; //! The array providing the backing memory for m_extMap - ImplEntries m_entries = {}; + Entries m_entries = {}; }; } // namespace Fw diff --git a/Fw/DataStructures/ExternalArrayMap.hpp b/Fw/DataStructures/ExternalArrayMap.hpp index 26a79668f5d..006f8fc9cad 100644 --- a/Fw/DataStructures/ExternalArrayMap.hpp +++ b/Fw/DataStructures/ExternalArrayMap.hpp @@ -27,6 +27,9 @@ class ExternalArrayMap final : public MapBase { // Public types // ---------------------------------------------------------------------- + //! The type of a const iterator + using ConstIterator = MapConstIterator; + //! The type of a map entry using Entry = SetOrMapImplEntry; @@ -78,14 +81,14 @@ class ExternalArrayMap final : public MapBase { //! Get the begin iterator //! \return The iterator - MapConstIterator begin() const override { return MapConstIterator(this->m_impl.begin()); } + ConstIterator begin() const override { return MapConstIterator(this->m_impl.begin()); } //! Clear the map void clear() override { this->m_impl.clear(); } //! Get the end iterator //! \return The iterator - MapConstIterator end() const override { return MapConstIterator(this->m_impl.end()); } + ConstIterator end() const override { return MapConstIterator(this->m_impl.end()); } //! Find a value associated with a key in the map //! \return SUCCESS if the item was found diff --git a/Fw/DataStructures/ExternalArraySet.hpp b/Fw/DataStructures/ExternalArraySet.hpp index f576d31e606..69d137619be 100644 --- a/Fw/DataStructures/ExternalArraySet.hpp +++ b/Fw/DataStructures/ExternalArraySet.hpp @@ -28,6 +28,9 @@ class ExternalArraySet final : public SetBase { // Public types // ---------------------------------------------------------------------- + //! The type of a const iterator + using ConstIterator = SetConstIterator; + //! The type of a set entry using Entry = SetOrMapImplEntry; @@ -79,14 +82,14 @@ class ExternalArraySet final : public SetBase { //! Get the begin iterator //! \return The iterator - SetConstIterator begin() const override { return SetConstIterator(this->m_impl.begin()); } + ConstIterator begin() const override { return SetConstIterator(this->m_impl.begin()); } //! Clear the set void clear() override { this->m_impl.clear(); } //! Get the end iterator //! \return The iterator - SetConstIterator end() const override { return SetConstIterator(this->m_impl.end()); } + ConstIterator end() const override { return SetConstIterator(this->m_impl.end()); } //! Find a value associated with an element in the set //! \return SUCCESS if the item was found diff --git a/Fw/DataStructures/docs/ArrayMap.md b/Fw/DataStructures/docs/ArrayMap.md index 88290fd12fb..7fe194b0cde 100644 --- a/Fw/DataStructures/docs/ArrayMap.md +++ b/Fw/DataStructures/docs/ArrayMap.md @@ -28,9 +28,10 @@ It represents an array-based map with internal storage. |Name|Definition| |----|----------| -|`ImplEntry`|Alias of [`SetOrMapImplEntry`](SetOrMapImplEntry.md)| +|`ConstIterator`|Alias of [`MapConstIterator`](MapConstIterator.md)| +|`Entry`|Alias of [`SetOrMapImplEntry`](SetOrMapImplEntry.md)| +|`Entries`|Alias of `Entry[C]`| |`MapEntryBase`|Alias of [`MapEntryBase`](MapEntryBase.md)| -|`ImplEntries`|Alias of `ImplEntry[C]`| ## 4. Private Member Variables @@ -39,7 +40,7 @@ It represents an array-based map with internal storage. |Name|Type|Purpose|Default Value| |----|----|-------|-------------| |`m_extMap`|[`ExternalArrayMap`](ExternalArrayMap.md)|The external map implementation|C++ default initialization| -|`m_entries`|`ImplEntries`|The array providing the backing memory for `m_extMap`|C++ default initialization| +|`m_entries`|`Entries`|The array providing the backing memory for `m_extMap`|C++ default initialization| ```mermaid classDiagram diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index d50db70e8ce..fe635b310b4 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -27,6 +27,7 @@ as the map implementation. |Name|Definition| |----|----------| +|`ConstIterator`|Alias of [`MapConstIterator`](MapConstIterator.md)| |`Entry`|Alias of [`SetOrMapEntry`](SetOrMapEntry.md)| ## 4. Private Member Variables @@ -190,8 +191,8 @@ ASSERT_EQ(status, Fw::Success::SUCCESS); // Get a map const iterator object auto it = map.begin(); // Use the iterator to access the underlying map const entry -const key = it->getKey(); -const value = it->getValue(); +const auto key = it->getKey(); +const auto value = it->getValue(); ASSERT_EQ(key, 0); ASSERT_EQ(value, 1); ``` diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md index 88899f4d463..989e18c3447 100644 --- a/Fw/DataStructures/docs/ExternalArraySet.md +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -22,12 +22,12 @@ as the set implementation. ## 3. Public Types -`ExternalArrayMap` defines the following public types: +`ExternalArraySet` defines the following public types: |Name|Definition| |----|----------| -|`ImplEntry`|Alias of [`SetOrMapImplEntry`](SetOrMapImplEntry.md)| -|`SetEntry`|Alias of [`SetEntry`](SetEntry.md)| +|`ConstIterator`|Alias of [`MapConstIterator`](MapConstIterator.md)| +|`Entry`|Alias of [`SetOrMapImplEntry`](SetOrMapImplEntry.md)| The type `Nil` is defined [here](Nil.md). @@ -64,12 +64,12 @@ ExternalArraySet set; ### 5.2. Constructor Providing Typed Backing Storage ```c++ -ExternalArraySet(ImplEntry* entries, FwSizeType capacity) +ExternalArraySet(Entry* entries, FwSizeType capacity) ``` `entries` must point to a primitive array of at least `capacity` -elements of type `ImplEntry`. -The type `ImplEntry` is defined [here](ExternalArraySet.md#Public-Types). +elements of type `Entry`. +The type `Entry` is defined [here](ExternalArraySet.md#Public-Types). Call `setStorage(entries, capacity)`. @@ -77,7 +77,7 @@ _Example:_ ```c++ using Set = ExternalArraySet; constexpr FwSizeType capacity = 10; -Set::ImplEntry entries[capacity]; +Set::Entry entries[capacity]; Set set(entries, capacity); ``` @@ -115,7 +115,7 @@ _Example:_ ```c++ using Set = ExternalArraySet; constexpr FwSizeType capacity = 3; -Set::ImplEntry entries[capacity]; +Set::Entry entries[capacity]; // Call the constructor providing backing storage Set m1(entries, capacity); // Insert an item @@ -152,7 +152,7 @@ _Example:_ ```c++ using Set = ExternalArraySet; constexpr FwSizeType capacity = 3; -Set::ImplEntry entries[capacity]; +Set::Entry entries[capacity]; // Call the constructor providing backing storage Set m1(entries, capacity); // Insert an item @@ -166,6 +166,30 @@ m2 = m1; ASSERT_EQ(m2.getSize(), 1); ``` +### 6.2. begin + +```c++ +ConstIterator begin() const +``` + +Return `m_impl.begin()`. + +_Example:_ +```c++ +using Set = ExternalArraySet; +constexpr FwSizeType capacity = 10; +Set::Entry entries[capacity]; +// Call the constructor providing backing storage +Set set(entries, capacity); +// Insert an entry in the set +const auto status = set.insert(42); +ASSERT_EQ(status, Fw::Success::SUCCESS); +// Get a set const iterator object +auto it = set.begin(); +// Use the iterator to access the element +ASSERT_EQ(*it, 42); +``` + ### 6.2. clear ```c++ @@ -178,7 +202,7 @@ _Example:_ ```c++ using Set = ExternalArraySet; constexpr FwSizeType capacity = 10; -Set::ImplEntry entries[capacity]; +Set::Entry entries[capacity]; Set set(entries, capacity); const auto status = set.insert(42); ASSERT_EQ(set.getSize(), 1); @@ -200,7 +224,7 @@ _Example:_ ```c++ using Set = ExternalArraySet; constexpr FwSizeType capacity = 10; -Set::ImplEntry entries[capacity]; +Set::Entry entries[capacity]; Set set(entries, capacity); auto status = set.find(42); ASSERT_EQ(status, Success::FAILURE); @@ -222,7 +246,7 @@ _Example:_ ```c++ using Set = ExternalArraySet; constexpr FwSizeType capacity = 10; -Set::ImplEntry entries[capacity]; +Set::Entry entries[capacity]; Set set(entries, capacity); ASSERT_EQ(set.getCapacity(), capacity); ``` @@ -241,7 +265,7 @@ _Example:_ ```c++ using Set = ExternalArraySet; constexpr FwSizeType capacity = 10; -Set::ImplEntry entries[capacity]; +Set::Entry entries[capacity]; Set set(entries, capacity); const auto* e = set.getHeadSetEntry(); FW_ASSERT(e == nullptr); @@ -263,7 +287,7 @@ _Example:_ ```c++ using Set = ExternalArraySet; constexpr FwSizeType capacity = 10; -Set::ImplEntry entries[capacity]; +Set::Entry entries[capacity]; Set set(entries, capacity); auto size = set.getSize(); ASSERT_EQ(size, 0); @@ -285,7 +309,7 @@ _Example:_ ```c++ using Set = ExternalArraySet; constexpr FwSizeType capacity = 10; -Set::ImplEntry entries[capacity]; +Set::Entry entries[capacity]; Set set(entries, capacity); auto size = set.getSize(); ASSERT_EQ(size, 0); @@ -309,7 +333,7 @@ _Example:_ ```c++ using Set = ExternalArraySet; constexpr FwSizeType capacity = 10; -Set::ImplEntry entries[capacity]; +Set::Entry entries[capacity]; Set set(entries, capacity); auto size = set.getSize(); ASSERT_EQ(size, 0); @@ -330,12 +354,12 @@ ASSERT_EQ(size, 0); ### 6.9. setStorage (Typed Data) ```c++ -void setStorage(ImplEntry* entries, FwSizeType capacity) +void setStorage(Entry* entries, FwSizeType capacity) ``` `entries` must point to a primitive array of at least `capacity` -elements of type `ImplEntry`. -The type `ImplEntry` is defined [here](ExternalArraySet.md#Public-Types). +elements of type `Entry`. +The type `Entry` is defined [here](ExternalArraySet.md#Public-Types). Call `m_impl.setStorage(entries, capacity)`. @@ -344,7 +368,7 @@ _Example:_ using Set = ExternalArraySet; constexpr FwSizeType capacity = 10; Set set; -Set::ImplEntry entries[capacity]; +Set::Entry entries[capacity]; set.setStorage(entries, capacity); ``` @@ -381,7 +405,7 @@ set.setStorage(ByteArray(&bytes[0], sizeof bytes), capacity); static constexpr U8 getByteArrayAlignment() ``` -Return `ArraySetOrMapImpl::getByteArrayAlignment()`. +Return `ArraySetOrMapImpl::getByteArrayAlignment()`. ### 7.2. getByteArraySize @@ -390,4 +414,4 @@ Return `ArraySetOrMapImpl::getByteArrayAlignment()`. static constexpr FwSizeType getByteArraySize(FwSizeType capacity) ``` -Return `ArraySetOrMapImpl::getByteArraySize(capacity)`. +Return `ArraySetOrMapImpl::getByteArraySize(capacity)`. From 2c2f2a7f7d4b19707ffb0531ec9daf54e7e630d1 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 20:53:33 -0700 Subject: [PATCH 395/458] Revise set and map interface --- Fw/DataStructures/ExternalArrayMap.hpp | 4 ++-- Fw/DataStructures/ExternalArraySet.hpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Fw/DataStructures/ExternalArrayMap.hpp b/Fw/DataStructures/ExternalArrayMap.hpp index 006f8fc9cad..0362a8bac90 100644 --- a/Fw/DataStructures/ExternalArrayMap.hpp +++ b/Fw/DataStructures/ExternalArrayMap.hpp @@ -81,14 +81,14 @@ class ExternalArrayMap final : public MapBase { //! Get the begin iterator //! \return The iterator - ConstIterator begin() const override { return MapConstIterator(this->m_impl.begin()); } + ConstIterator begin() const override { return ConstIterator(this->m_impl.begin()); } //! Clear the map void clear() override { this->m_impl.clear(); } //! Get the end iterator //! \return The iterator - ConstIterator end() const override { return MapConstIterator(this->m_impl.end()); } + ConstIterator end() const override { return ConstIterator(this->m_impl.end()); } //! Find a value associated with a key in the map //! \return SUCCESS if the item was found diff --git a/Fw/DataStructures/ExternalArraySet.hpp b/Fw/DataStructures/ExternalArraySet.hpp index 69d137619be..0d8abb80f48 100644 --- a/Fw/DataStructures/ExternalArraySet.hpp +++ b/Fw/DataStructures/ExternalArraySet.hpp @@ -82,14 +82,14 @@ class ExternalArraySet final : public SetBase { //! Get the begin iterator //! \return The iterator - ConstIterator begin() const override { return SetConstIterator(this->m_impl.begin()); } + ConstIterator begin() const override { return ConstIterator(this->m_impl.begin()); } //! Clear the set void clear() override { this->m_impl.clear(); } //! Get the end iterator //! \return The iterator - ConstIterator end() const override { return SetConstIterator(this->m_impl.end()); } + ConstIterator end() const override { return ConstIterator(this->m_impl.end()); } //! Find a value associated with an element in the set //! \return SUCCESS if the item was found From 4d0a9038901eb22ffa784360b9b6fbbbb17572f9 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 20:57:14 -0700 Subject: [PATCH 396/458] Revise ExternalArraySet docs --- Fw/DataStructures/docs/ExternalArraySet.md | 68 ++++++++++++---------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md index 989e18c3447..5e41ce1b509 100644 --- a/Fw/DataStructures/docs/ExternalArraySet.md +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -190,7 +190,7 @@ auto it = set.begin(); ASSERT_EQ(*it, 42); ``` -### 6.2. clear +### 6.3. clear ```c++ void clear() override @@ -210,7 +210,35 @@ set.clear(); ASSERT_EQ(set.getSize(), 0); ``` -### 6.3. find +### 6.4. end + +```c++ +ConstIterator end() const +``` + +Return `m_impl.end()`. + +_Example:_ +```c++ +using Set = ExternalArraySet; +constexpr FwSizeType capacity = 10; +Set::Entry entries[capacity]; +// Call the constructor providing backing storage +Set set(entries, capacity); +// Insert an entry in the set +auto status = set.insert(42); +ASSERT_EQ(status, Fw::Success::SUCCESS); +// Get a set const iterator object +auto iter = set.begin(); +// Check that iter is not at the end +ASSERT_NE(iter, set.end()); +// Increment iter +it++; +// Check that iter is at the end +ASSERT_EQ(iter, set.end()); +``` + +### 6.5. find ```c++ Success find(const T& element) override @@ -234,7 +262,7 @@ status = set.find(42); ASSERT_EQ(status, Success::SUCCESS); ``` -### 6.4. getCapacity +### 6.6. getCapacity ```c++ FwSizeType getCapacity() const override @@ -251,31 +279,7 @@ Set set(entries, capacity); ASSERT_EQ(set.getCapacity(), capacity); ``` -### 6.5. getHeadSetEntry - -```c++ -const SetEntry* getHeadSetEntry const override -``` - -The type `SetEntry` is defined [here](ExternalArraySet.md#Public-Types). - -Return `m_impl.getHeadSetEntry()`. - -_Example:_ -```c++ -using Set = ExternalArraySet; -constexpr FwSizeType capacity = 10; -Set::Entry entries[capacity]; -Set set(entries, capacity); -const auto* e = set.getHeadSetEntry(); -FW_ASSERT(e == nullptr); -set.insert(42); -e = set.getHeadSetEntry(); -FW_ASSERT(e != nullptr); -ASSERT_EQ(e->getElement(), 42); -``` - -### 6.6. getSize +### 6.8. getSize ```c++ FwSizeType getSize() const override @@ -297,7 +301,7 @@ size = set.getSize(); ASSERT_EQ(size, 1); ``` -### 6.7. insert +### 6.9. insert ```c++ Success insert(const T& element) override @@ -319,7 +323,7 @@ size = set.getSize(); ASSERT_EQ(size, 1); ``` -### 6.8. remove +### 6.10. remove ```c++ Success remove(const T& element) override @@ -351,7 +355,7 @@ ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(size, 0); ``` -### 6.9. setStorage (Typed Data) +### 6.11. setStorage (Typed Data) ```c++ void setStorage(Entry* entries, FwSizeType capacity) @@ -372,7 +376,7 @@ Set::Entry entries[capacity]; set.setStorage(entries, capacity); ``` -### 6.10. setStorage (Untyped Data) +### 6.12. setStorage (Untyped Data) ```c++ void setStorage(ByteArray data, FwSizeType capacity) From 36c825f54475f65ca1a8b3a3bb39f251d69d3d9c Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 21:00:35 -0700 Subject: [PATCH 397/458] Revise ArraySet --- Fw/DataStructures/ArraySet.hpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Fw/DataStructures/ArraySet.hpp b/Fw/DataStructures/ArraySet.hpp index db7aea8a23d..c829819023e 100644 --- a/Fw/DataStructures/ArraySet.hpp +++ b/Fw/DataStructures/ArraySet.hpp @@ -25,11 +25,14 @@ class ArraySet final : public SetBase { // Public types // ---------------------------------------------------------------------- + //! The type of a const iterator + using ConstIterator = SetConstIterator; + //! The type of animplementation entry - using ImplEntry = SetOrMapImplEntry; + using Entry = SetOrMapImplEntry; //! The type of the implementation entries - using ImplEntries = ImplEntry[C]; + using Entries = Entry[C]; public: // ---------------------------------------------------------------------- @@ -58,14 +61,14 @@ class ArraySet final : public SetBase { //! Get the begin iterator //! \return The iterator - SetConstIterator begin() const override { return this->m_extSet.begin(); } + ConstIterator begin() const override { return this->m_extSet.begin(); } //! Clear the set void clear() override { this->m_extSet.clear(); } //! Get the end iterator //! \return The iterator - SetConstIterator end() const override { return this->m_extSet.end(); } + ConstIterator end() const override { return this->m_extSet.end(); } //! Find an element in the set //! \return SUCCESS if the element was found @@ -105,7 +108,7 @@ class ArraySet final : public SetBase { ExternalArraySet m_extSet = {}; //! The array providing the backing memory for m_extSet - ImplEntries m_entries = {}; + Entries m_entries = {}; }; } // namespace Fw From 8bd77ebc3bd0c1c6bbf250d2076e7f8c73b2bc1d Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 21:09:36 -0700 Subject: [PATCH 398/458] Revise ArraySet docs --- Fw/DataStructures/docs/ArrayMap.md | 2 +- Fw/DataStructures/docs/ArraySet.md | 144 +++++++++++++++++---- Fw/DataStructures/docs/SetConstIterator.md | 96 ++++++++++++++ 3 files changed, 216 insertions(+), 26 deletions(-) create mode 100644 Fw/DataStructures/docs/SetConstIterator.md diff --git a/Fw/DataStructures/docs/ArrayMap.md b/Fw/DataStructures/docs/ArrayMap.md index 7fe194b0cde..6c79d720e12 100644 --- a/Fw/DataStructures/docs/ArrayMap.md +++ b/Fw/DataStructures/docs/ArrayMap.md @@ -227,7 +227,7 @@ _Example:_ ```c++ using Map = ArrayMap; Map map; -ASSERT_EQ(map.getCapacity(), capacity); +ASSERT_EQ(map.getCapacity(), 10); ``` ### 6.8. getSize diff --git a/Fw/DataStructures/docs/ArraySet.md b/Fw/DataStructures/docs/ArraySet.md index 7a329bb631b..365453db603 100644 --- a/Fw/DataStructures/docs/ArraySet.md +++ b/Fw/DataStructures/docs/ArraySet.md @@ -27,6 +27,7 @@ It represents an array-based set with internal storage. |Name|Definition| |----|----------| +|`ConstIterator`|Alias of [`SetConstIterator`](SetConstIterator.md)| |`Entry`|Alias of [`SetOrMapImplEntry`](SetOrMapImplEntry.md)| |`SetEntry`|Alias of [`SetEntry`](SetEntry.md)| @@ -122,7 +123,28 @@ status = s2.find(element); ASSERT_EQ(status, Success::SUCCESS); ``` -### 6.2. clear +### 6.2. begin + +```c++ +ConstIterator begin() const +``` + +Return `m_extSet.begin()`. + +_Example:_ +```c++ +using Set = ArraySet; +Set set; +// Insert an element in the set +const auto status = map.insert(42); +ASSERT_EQ(status, Fw::Success::SUCCESS); +// Get a set const iterator object +auto it = set.begin(); +// Use the iterator to access the underlying map const entry +ASSERT_EQ(*it, 42); +``` + +### 6.3. clear ```c++ void clear() override @@ -130,7 +152,43 @@ void clear() override Call `m_extSet.clear()`. -### 6.3. find +_Example:_ +```c++ +using Set = ArraySet; +Set set; +const auto status = set.insert(42); +ASSERT_EQ(set.getSize(), 1); +set.clear(); +ASSERT_EQ(set.getSize(), 0); +``` + +### 6.4. end + +```c++ +ConstIterator end() const +``` + +Return `m_extSet.end()`. + +_Example:_ +```c++ +using Set = ArraySet; +// Call the constructor providing backing storage +Set set; +// Insert an element in the set +auto status = set.insert(42); +ASSERT_EQ(status, Fw::Success::SUCCESS); +// Get a set const iterator object +auto iter = set.begin(); +// Check that iter is not at the end +ASSERT_NE(iter, set.end()); +// Increment iter +it++; +// Check that iter is at the end +ASSERT_EQ(iter, set.end()); +``` + +### 6.5. find ```c++ Success find(const K& element, V& value) override @@ -138,7 +196,19 @@ Success find(const K& element, V& value) override Return `m_extSet.find(element, value)`. -### 6.4. getCapacity +_Example:_ +```c++ +using Set = ArraySet; +Set set; +auto status = set.find(42); +ASSERT_EQ(status, Success::FAILURE); +status = set.insert(42); +ASSERT_EQ(status, Success::SUCCESS); +status = set.find(42); +ASSERT_EQ(status, Success::SUCCESS); +``` + +### 6.6. getCapacity ```c++ FwSizeType getCapacity() const override @@ -146,17 +216,14 @@ FwSizeType getCapacity() const override Return `m_extSet.getCapacity()`. -### 6.5. getHeadSetEntry - +_Example:_ ```c++ -const SetEntry* getHeadSetEntry const override +using Set = ArraySet; +Set set; +ASSERT_EQ(set.getCapacity(), 10); ``` -The type `SetEntry` is defined [here](ArraySet.md#Public-Types). - -Return `m_extSet.getHeadSetEntry()`. - -### 6.6. getSize +### 6.7. getSize ```c++ FwSizeType getSize() const override @@ -164,7 +231,19 @@ FwSizeType getSize() const override Return `m_extSet.getSize()`. -### 6.7. insert +_Example:_ +```c++ +using Set = ArraySet; +Set set; +auto size = set.getSize(); +ASSERT_EQ(size, 0); +const auto status = set.insert(42); +ASSERT_EQ(status, Success::SUCCESS); +size = set.getSize(); +ASSERT_EQ(size, 1); +``` + +### 6.8. insert ```c++ Success insert(const T& element) override @@ -172,27 +251,42 @@ Success insert(const T& element) override Return `m_extSet.insert(element)`. -### 6.8. remove - +_Example:_ ```c++ -Success remove(const T& element) override +using Set = ArraySet; +Set set; +auto size = set.getSize(); +ASSERT_EQ(size, 0); +const auto status = set.insert(42); +ASSERT_EQ(status, Success::SUCCESS); +size = set.getSize(); +ASSERT_EQ(size, 1); ``` -Return `m_extSet.remove(element)`. - -## 7. Public Static Functions - -### 7.1. getStaticCapacity +### 6.9. remove ```c++ -static constexpr FwSizeType getStaticCapacity() +Success remove(const T& element) override ``` -Return the static capacity `C`. +Return `m_extSet.remove(element)`. _Example:_ ```c++ -using Set = ArraySet; -const auto capacity = Set::getStaticCapacity(); -ASSERT_EQ(capacity, 3); +using Set = ArraySet; +Set set; +auto size = set.getSize(); +ASSERT_EQ(size, 0); +auto status = set.insert(42); +ASSERT_EQ(status, Success::SUCCESS); +size = set.getSize(); +ASSERT_EQ(size, 1); +// Element does not exist +status = set.remove(0); +ASSERT_EQ(status, Success::FAILURE); +ASSERT_EQ(size, 1); +// Element exists +status = set.remove(42, value); +ASSERT_EQ(status, Success::SUCCESS); +ASSERT_EQ(size, 0); ``` diff --git a/Fw/DataStructures/docs/SetConstIterator.md b/Fw/DataStructures/docs/SetConstIterator.md new file mode 100644 index 00000000000..5d2d24007f8 --- /dev/null +++ b/Fw/DataStructures/docs/SetConstIterator.md @@ -0,0 +1,96 @@ +# SetConstIterator + +TODO + +`SetConstIterator` is a class for performing immutable iteration over a map. + +## 1. Template Parameters + +`SetConstIterator` has the following template parameters: + +|Kind|Name|Purpose| +|----|----|-------| +|`typename`|`K`|The type of a key in the map| +|`typename`|`V`|The type of a value in the map| + +## 2. Public Types + +`SetConstIterator` defines the following public types: + +|Name|Definition| +|----|----------| +|`EntryBase`|Alias of [`SetEntryBase`](SetEntryBase.md)| + +## 3. Constructors and Destructors + +`SetConstIterator` provides the following constructors and destructors: + +1. One constructor for each map implementation. + The map implementations use these constructors to provide iterators. + +1. A copy constructor. + +1. A destructor. + +## 4. Public Member Functions + +`SetConstIterator` provides the following member functions. + +### 4.1. operator= + +Defined as `= default`. + +### 4.2. operator== + +```c++ +bool operator==(const SetConstIterator& it) +``` + +Compare two `SetConstIterator` instances for equality. + +1. If the implementations differ, then return `false`. + +1. Otherwise check whether the implementations have equal values. + +### 4.3. operator != + +```c++ +bool operator!=(const SetConstIterator& it) +``` + +Return the negation of `operator=`. + +### 4.4. operator++ + +```c++ +SetConstIterator& operator++() +SetConstIterator& operator++(int) +``` + +Increment the iterator. + +### 4.5. isInRange() + +```c++ +bool isInRange() const +``` + +Check whether the iterator is in range. + +### 4.6. operator* + +```c++ +const EntryBase& operator*() const +``` + +Return a `const` reference to the `EntryBase` object +pointed to by the iterator. + +### 4.7. operator-> + +```c++ +const EntryBase* operator->() const +``` + +Return a pointer to the `const EntryBase` object +pointed to by the iterator. From e36bcd9ad6f154bdddd5ea873d5a5529bf2d403a Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 21:12:55 -0700 Subject: [PATCH 399/458] Revise SetConstIterator --- Fw/DataStructures/docs/SetConstIterator.md | 41 ++++++++-------------- 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/Fw/DataStructures/docs/SetConstIterator.md b/Fw/DataStructures/docs/SetConstIterator.md index 5d2d24007f8..bd81ae90795 100644 --- a/Fw/DataStructures/docs/SetConstIterator.md +++ b/Fw/DataStructures/docs/SetConstIterator.md @@ -1,8 +1,6 @@ # SetConstIterator -TODO - -`SetConstIterator` is a class for performing immutable iteration over a map. +`SetConstIterator` is a class for performing immutable iteration over a set. ## 1. Template Parameters @@ -10,37 +8,28 @@ TODO |Kind|Name|Purpose| |----|----|-------| -|`typename`|`K`|The type of a key in the map| -|`typename`|`V`|The type of a value in the map| - -## 2. Public Types - -`SetConstIterator` defines the following public types: - -|Name|Definition| -|----|----------| -|`EntryBase`|Alias of [`SetEntryBase`](SetEntryBase.md)| +|`typename`|`T`|The type of an element in the set| -## 3. Constructors and Destructors +## 2. Constructors and Destructors `SetConstIterator` provides the following constructors and destructors: -1. One constructor for each map implementation. - The map implementations use these constructors to provide iterators. +1. One constructor for each set implementation. + The set implementations use these constructors to provide iterators. 1. A copy constructor. 1. A destructor. -## 4. Public Member Functions +## 3. Public Member Functions `SetConstIterator` provides the following member functions. -### 4.1. operator= +### 3.1. operator= Defined as `= default`. -### 4.2. operator== +### 3.2. operator== ```c++ bool operator==(const SetConstIterator& it) @@ -52,7 +41,7 @@ Compare two `SetConstIterator` instances for equality. 1. Otherwise check whether the implementations have equal values. -### 4.3. operator != +### 3.3. operator != ```c++ bool operator!=(const SetConstIterator& it) @@ -60,7 +49,7 @@ bool operator!=(const SetConstIterator& it) Return the negation of `operator=`. -### 4.4. operator++ +### 3.4. operator++ ```c++ SetConstIterator& operator++() @@ -69,7 +58,7 @@ SetConstIterator& operator++(int) Increment the iterator. -### 4.5. isInRange() +### 3.5. isInRange() ```c++ bool isInRange() const @@ -77,20 +66,20 @@ bool isInRange() const Check whether the iterator is in range. -### 4.6. operator* +### 3.6. operator* ```c++ const EntryBase& operator*() const ``` -Return a `const` reference to the `EntryBase` object +Return a `const` reference to the `T` element pointed to by the iterator. -### 4.7. operator-> +### 3.7. operator-> ```c++ const EntryBase* operator->() const ``` -Return a pointer to the `const EntryBase` object +Return a pointer to the `const T` element pointed to by the iterator. From 3581819e41ea963bdbfbeaedca1e1e4e113b0689 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 21:16:03 -0700 Subject: [PATCH 400/458] Revise SetBase --- Fw/DataStructures/docs/SetBase.md | 37 ++++++++++++------------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/Fw/DataStructures/docs/SetBase.md b/Fw/DataStructures/docs/SetBase.md index b9e1e6bb5b2..8b02cc6f2b7 100644 --- a/Fw/DataStructures/docs/SetBase.md +++ b/Fw/DataStructures/docs/SetBase.md @@ -12,16 +12,7 @@ It represents an abstract base class for a set. |----|----|-------| |`typename`|`T`|The type of an element in the set| - -## 2. Public Types - -`SetBase` defines the following public types: - -|Name|Definition| -|----|----------| -|`Entry`|Alias of [`SetEntry`](SetEntry.md)| - -## 3. Deleted Elements +## 2. Deleted Elements The following elements are private and are defined `= delete`: @@ -35,9 +26,9 @@ The following elements are private and are defined `= delete`: SetBase& operator=(const SetBase&) ``` -## 4. Protected Constructors and Destructors +## 3. Protected Constructors and Destructors -### 4.1. Zero-Argument Constructor +### 3.1. Zero-Argument Constructor ```c++ SetBase() @@ -45,7 +36,7 @@ SetBase() Use default initialization of members. -### 4.2. Destructor +### 3.2. Destructor ```c++ virtual ~SetBase() @@ -53,9 +44,9 @@ virtual ~SetBase() Defined as `= default`. -## 5. Public Member Functions +## 4. Public Member Functions -### 5.1. begin +### 4.1. begin ```c++ virtual ConstIterator begin() const = 0. @@ -77,7 +68,7 @@ void f(SetBase& set) { Return the begin value of the iterator for the implementation. -### 5.2. clear +### 4.2. clear ```c++ virtual void clear() = 0 @@ -93,7 +84,7 @@ void f(SetBase& set) { } ``` -### 5.3. copyDataFrom +### 4.3. copyDataFrom ```c++ void copyDataFrom(const SetBase& set) @@ -130,7 +121,7 @@ void f(SetBase& s1, SetBase& s2) { } ``` -### 5.4. end +### 4.4. end ```c++ virtual ConstIterator end() const = 0 @@ -156,7 +147,7 @@ void f(SetBase& set) { } ``` -### 5.5. find +### 4.5. find ```c++ virtual Success find(const T& element) = 0 @@ -182,7 +173,7 @@ void f(const SetBase& set) { ``` -### 5.6. getCapacity +### 4.6. getCapacity ```c++ virtual FwSizeType getCapacity() const = 0 @@ -199,7 +190,7 @@ void f(const SetBase& set) { } ``` -### 5.8. getSize +### 4.7. getSize ```c++ virtual FwSizeType getSize() const = 0 @@ -210,7 +201,7 @@ Return the current size. _Example:_ See [**getCapacity**](#getCapacity). -### 5.9. insert +### 4.8. insert ```c++ virtual Success insert(const T& element) = 0 @@ -236,7 +227,7 @@ void f(SetBase& set) { } ``` -### 5.10. remove +### 4.9. remove ```c++ virtual Success remove(const T& element) = 0 From 1fbdbdffb28af04c753d707904d2e08c6d0c7ab0 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 21:16:43 -0700 Subject: [PATCH 401/458] Revise SetBase docs --- Fw/DataStructures/docs/SetBase.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/docs/SetBase.md b/Fw/DataStructures/docs/SetBase.md index 8b02cc6f2b7..f3f939c967d 100644 --- a/Fw/DataStructures/docs/SetBase.md +++ b/Fw/DataStructures/docs/SetBase.md @@ -52,6 +52,8 @@ Defined as `= default`. virtual ConstIterator begin() const = 0. ``` +Return the begin value of the iterator for the implementation. + _Example:_ ```c++ void f(SetBase& set) { @@ -66,8 +68,6 @@ void f(SetBase& set) { } ``` -Return the begin value of the iterator for the implementation. - ### 4.2. clear ```c++ From 3b512dae4fc124381348f186d25cf7ef67941b12 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 21:19:14 -0700 Subject: [PATCH 402/458] Revise SetBase --- Fw/DataStructures/SetBase.hpp | 12 +++++++++-- Fw/DataStructures/docs/SetBase.md | 34 +++++++++++++++++++------------ 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/Fw/DataStructures/SetBase.hpp b/Fw/DataStructures/SetBase.hpp index d7f24ac8f2a..ee5a78332b4 100644 --- a/Fw/DataStructures/SetBase.hpp +++ b/Fw/DataStructures/SetBase.hpp @@ -29,6 +29,14 @@ class SetBase { //! We avoid virtual user-defined operators SetBase& operator=(const SetBase&) = delete; + public: + // ---------------------------------------------------------------------- + // Public types + // ---------------------------------------------------------------------- + + //! The type of a set const iterator + using ConstIterator = SetConstIterator; + protected: // ---------------------------------------------------------------------- // Protected constructors and destructors @@ -47,14 +55,14 @@ class SetBase { //! Get the begin iterator //! \return The iterator - virtual SetConstIterator begin() const = 0; + virtual ConstIterator begin() const = 0; //! Clear the set virtual void clear() = 0; //! Get the end iterator //! \return The iterator - virtual SetConstIterator end() const = 0; + virtual ConstIterator end() const = 0; //! Copy data from another set void copyDataFrom(const SetBase& set) { diff --git a/Fw/DataStructures/docs/SetBase.md b/Fw/DataStructures/docs/SetBase.md index f3f939c967d..afdff913438 100644 --- a/Fw/DataStructures/docs/SetBase.md +++ b/Fw/DataStructures/docs/SetBase.md @@ -26,9 +26,17 @@ The following elements are private and are defined `= delete`: SetBase& operator=(const SetBase&) ``` -## 3. Protected Constructors and Destructors +## 3. Public Types -### 3.1. Zero-Argument Constructor +`SetBase` defines the following public types: + +|Name|Definition| +|----|----------| +|`ConstIterator`|Alias of [`SetConstIterator`](SetConstIterator.md)| + +## 4. Protected Constructors and Destructors + +### 4.1. Zero-Argument Constructor ```c++ SetBase() @@ -36,7 +44,7 @@ SetBase() Use default initialization of members. -### 3.2. Destructor +### 4.2. Destructor ```c++ virtual ~SetBase() @@ -44,9 +52,9 @@ virtual ~SetBase() Defined as `= default`. -## 4. Public Member Functions +## 5. Public Member Functions -### 4.1. begin +### 5.1. begin ```c++ virtual ConstIterator begin() const = 0. @@ -68,7 +76,7 @@ void f(SetBase& set) { } ``` -### 4.2. clear +### 5.2. clear ```c++ virtual void clear() = 0 @@ -84,7 +92,7 @@ void f(SetBase& set) { } ``` -### 4.3. copyDataFrom +### 5.3. copyDataFrom ```c++ void copyDataFrom(const SetBase& set) @@ -121,7 +129,7 @@ void f(SetBase& s1, SetBase& s2) { } ``` -### 4.4. end +### 5.4. end ```c++ virtual ConstIterator end() const = 0 @@ -147,7 +155,7 @@ void f(SetBase& set) { } ``` -### 4.5. find +### 5.5. find ```c++ virtual Success find(const T& element) = 0 @@ -173,7 +181,7 @@ void f(const SetBase& set) { ``` -### 4.6. getCapacity +### 5.6. getCapacity ```c++ virtual FwSizeType getCapacity() const = 0 @@ -190,7 +198,7 @@ void f(const SetBase& set) { } ``` -### 4.7. getSize +### 5.7. getSize ```c++ virtual FwSizeType getSize() const = 0 @@ -201,7 +209,7 @@ Return the current size. _Example:_ See [**getCapacity**](#getCapacity). -### 4.8. insert +### 5.8. insert ```c++ virtual Success insert(const T& element) = 0 @@ -227,7 +235,7 @@ void f(SetBase& set) { } ``` -### 4.9. remove +### 5.9. remove ```c++ virtual Success remove(const T& element) = 0 From 8b0517fea2eb5c37fcb92708258bd2ae9b63c0ad Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 21:21:33 -0700 Subject: [PATCH 403/458] Revise ArraySet --- Fw/DataStructures/docs/ArraySet.md | 1 - 1 file changed, 1 deletion(-) diff --git a/Fw/DataStructures/docs/ArraySet.md b/Fw/DataStructures/docs/ArraySet.md index 365453db603..9ad444526ab 100644 --- a/Fw/DataStructures/docs/ArraySet.md +++ b/Fw/DataStructures/docs/ArraySet.md @@ -29,7 +29,6 @@ It represents an array-based set with internal storage. |----|----------| |`ConstIterator`|Alias of [`SetConstIterator`](SetConstIterator.md)| |`Entry`|Alias of [`SetOrMapImplEntry`](SetOrMapImplEntry.md)| -|`SetEntry`|Alias of [`SetEntry`](SetEntry.md)| The type `Nil` is defined [here](Nil.md). From b1d44abc76b6986088bebf2fab7034a98806b5f6 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 21:22:48 -0700 Subject: [PATCH 404/458] Revise ArraySet docs --- Fw/DataStructures/docs/ArraySet.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Fw/DataStructures/docs/ArraySet.md b/Fw/DataStructures/docs/ArraySet.md index 9ad444526ab..b37b75f92d5 100644 --- a/Fw/DataStructures/docs/ArraySet.md +++ b/Fw/DataStructures/docs/ArraySet.md @@ -110,7 +110,7 @@ using Set = ArraySet; Set s1; // Insert an item U32 element = 42; -const auto status = s1.insert(element, value); +const auto status = s1.insert(element); ASSERT_EQ(status, Success::SUCCESS); // Call the default constructor Set s2; @@ -193,7 +193,7 @@ ASSERT_EQ(iter, set.end()); Success find(const K& element, V& value) override ``` -Return `m_extSet.find(element, value)`. +Return `m_extSet.find(element)`. _Example:_ ```c++ @@ -285,7 +285,7 @@ status = set.remove(0); ASSERT_EQ(status, Success::FAILURE); ASSERT_EQ(size, 1); // Element exists -status = set.remove(42, value); +status = set.remove(42); ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(size, 0); ``` From 90d156930625e14628eb7e3e766651bae26d51a7 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 21:23:04 -0700 Subject: [PATCH 405/458] Revise ExternalArraySet docs --- Fw/DataStructures/docs/ExternalArraySet.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md index 5e41ce1b509..8ca2a3fb159 100644 --- a/Fw/DataStructures/docs/ExternalArraySet.md +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -350,7 +350,7 @@ status = set.remove(0); ASSERT_EQ(status, Success::FAILURE); ASSERT_EQ(size, 1); // Element exists -status = set.remove(42, value); +status = set.remove(42); ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(size, 0); ``` From 2a68f61b507bd0ac3fbcc4b608434ebf42f4be2e Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 21:25:44 -0700 Subject: [PATCH 406/458] Add SetOrMapImplEntry --- Fw/DataStructures/SetOrMapImplEntry.hpp | 95 +++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 Fw/DataStructures/SetOrMapImplEntry.hpp diff --git a/Fw/DataStructures/SetOrMapImplEntry.hpp b/Fw/DataStructures/SetOrMapImplEntry.hpp new file mode 100644 index 00000000000..e11f89f1008 --- /dev/null +++ b/Fw/DataStructures/SetOrMapImplEntry.hpp @@ -0,0 +1,95 @@ +// ====================================================================== +// \title SetOrMapImplEntry +// \author bocchino +// \brief A class template representing an entry for a set or map implementation +// ====================================================================== + +#ifndef Fw_SetOrMapImplEntry_HPP +#define Fw_SetOrMapImplEntry_HPP + +#include "Fw/DataStructures/MapEntryBase.hpp" +#include "Fw/FPrimeBasicTypes.hpp" + +namespace Fw { + +template +class SetOrMapImplEntry final : public MapEntryBase { + public: + // ---------------------------------------------------------------------- + // Public constructors and destructors + // ---------------------------------------------------------------------- + + //! Zero-argument constructor + SetOrMapImplEntry() : MapEntryBase() {} + + //! Constructor providing members + SetOrMapImplEntry(const KE& keyOrElement, //!< The key or element + const VN& valueOrNil //!< The value or Nil + ) + : MapEntryBase(), m_keyOrElement(keyOrElement), m_valueOrNil(valueOrNil) {} + + //! Copy constructor + SetOrMapImplEntry(const SetOrMapImplEntry& entry) { *this = entry; } + + //! Destructor + ~SetOrMapImplEntry() override = default; + + public: + // ---------------------------------------------------------------------- + // Public member functions + // ---------------------------------------------------------------------- + + //! operator= + SetOrMapImplEntry& operator=(const SetOrMapImplEntry& entry) { + if (this != &entry) { + this->m_keyOrElement = entry.m_keyOrElement; + this->m_valueOrNil = entry.m_valueOrNil; + } + return *this; + } + + //! Get the key or element associated with this entry + //! \return The key or element + const KE& getKeyOrElement() const { return this->m_keyOrElement; } + + //! Get the value or nil associated with this entry + //! \return The value or nil + const VN& getValueOrNil() const { return this->m_valueOrNil; } + + //! Set the key or element + void setKeyOrElement(const KE& keyOrElement //!< The key or element + ) { + this->m_keyOrElement = keyOrElement; + } + + //! Set the value or Nil + void setValueOrNil(const VN& valueOrNil) { this->m_valueOrNil = valueOrNil; } + + public: + // ---------------------------------------------------------------------- + // MapEntryBase implementation + // ---------------------------------------------------------------------- + + //! Get the key associated with this entry + //! \return The key + const KE& getKey() const override { return this->m_keyOrElement; } + + //! Get the value associated with this entry + //! \return The value + const VN& getValue() const override { return this->m_valueOrNil; } + + private: + // ---------------------------------------------------------------------- + // Private member variables + // ---------------------------------------------------------------------- + + //! The map key or set element + KE m_keyOrElement = {}; + + //! The value or nil + VN m_valueOrNil = {}; +}; + +} // namespace Fw + +#endif From 74450b0a57f1cda02ef7caa14bb830623da20f04 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 14 Jul 2025 21:40:36 -0700 Subject: [PATCH 407/458] Revise ArraySetOrMapImpl --- Fw/DataStructures/ArraySetOrMapImpl.hpp | 9 ++++++--- Fw/DataStructures/docs/ArraySetOrMapImpl.md | 5 ++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Fw/DataStructures/ArraySetOrMapImpl.hpp b/Fw/DataStructures/ArraySetOrMapImpl.hpp index 3f9d66d0fb2..e82a1f748c5 100644 --- a/Fw/DataStructures/ArraySetOrMapImpl.hpp +++ b/Fw/DataStructures/ArraySetOrMapImpl.hpp @@ -100,8 +100,11 @@ class ArraySetOrMapImpl final { return this->m_index < this->m_impl->m_size; } - //! Set the index value - void setIndex(FwSizeType index) { this->m_index = index; } + //! 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 @@ -165,7 +168,7 @@ class ArraySetOrMapImpl final { //! Get the end iterator ConstIterator end() const { auto it = begin(); - it.setIndex(this->m_size); + it.setToEnd(); return it; } diff --git a/Fw/DataStructures/docs/ArraySetOrMapImpl.md b/Fw/DataStructures/docs/ArraySetOrMapImpl.md index 5427e906131..8f68850e1c4 100644 --- a/Fw/DataStructures/docs/ArraySetOrMapImpl.md +++ b/Fw/DataStructures/docs/ArraySetOrMapImpl.md @@ -118,7 +118,7 @@ ArraySetOrMapImpl& operator=(const ArraySetOrMapImpl& impl) ConstIterator begin() const ``` -1. Return `ConstIterator(*this)`. +Return `ConstIterator(*this)`. ### 5.3. clear @@ -136,11 +136,10 @@ ConstIterator end() const 1. Set `it = begin()`. -1. Set `it.m_index = m_size`. +1. Call `it.setToEnd()`. 1. Return `it`. - ### 5.5. find ```c++ From d120f0019331c33447b1478684b3b188f02ea9eb Mon Sep 17 00:00:00 2001 From: "Robert L. Bocchino Jr." Date: Mon, 21 Jul 2025 17:53:42 -0700 Subject: [PATCH 408/458] Revise Fw/DataStructures Fix compile errors on Linux --- Fw/DataStructures/ArrayMap.hpp | 3 -- Fw/DataStructures/CMakeLists.txt | 40 +++++++++---------- Fw/DataStructures/build_ut | 2 +- Fw/DataStructures/clear_gcda | 5 ++- .../test/ut/STest/StackTestRules.cpp | 2 +- .../test/ut/STest/StackTestRules.hpp | 2 +- .../test/ut/STest/StackTestState.hpp | 10 ++--- 7 files changed, 32 insertions(+), 32 deletions(-) diff --git a/Fw/DataStructures/ArrayMap.hpp b/Fw/DataStructures/ArrayMap.hpp index b13a45e6ed8..0f487e2be3c 100644 --- a/Fw/DataStructures/ArrayMap.hpp +++ b/Fw/DataStructures/ArrayMap.hpp @@ -34,9 +34,6 @@ class ArrayMap final : public MapBase { //! The type of the implementation entries using Entries = Entry[C]; - //! The type of a map entry - using MapEntryBase = MapEntryBase; - public: // ---------------------------------------------------------------------- // Public constructors and destructors diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index 2c408d1ba90..358cb5db775 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -5,26 +5,26 @@ set(SOURCE_FILES register_fprime_module() set(UT_SOURCE_FILES - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayMapTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestRules.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestScenarios.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/SetTestRules.cpp" - "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/SetTestScenarios.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayMapTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestRules.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestScenarios.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/SetTestRules.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/SetTestScenarios.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" diff --git a/Fw/DataStructures/build_ut b/Fw/DataStructures/build_ut index 55e45a4e109..eea7f1a874d 100755 --- a/Fw/DataStructures/build_ut +++ b/Fw/DataStructures/build_ut @@ -3,4 +3,4 @@ cd `dirname $0` ./clear_gcda fprime-util build --ut "$@" -cp ../../build-fprime-automatic-native-ut/bin/Darwin/Fw_DataStructures_ut_exe . +cp ../../build-fprime-automatic-native-ut/bin/`uname`/Fw_DataStructures_ut_exe . diff --git a/Fw/DataStructures/clear_gcda b/Fw/DataStructures/clear_gcda index 9be2282bfd7..54610a0c99d 100755 --- a/Fw/DataStructures/clear_gcda +++ b/Fw/DataStructures/clear_gcda @@ -1,4 +1,7 @@ #!/bin/sh -e cd `dirname $0` -find ../.. -name '*.gcda' | xargs rm +for file in `find ../.. -name '*.gcda'` +do + rm $file +done diff --git a/Fw/DataStructures/test/ut/STest/StackTestRules.cpp b/Fw/DataStructures/test/ut/STest/StackTestRules.cpp index dc93c8b761d..d8a59e4109a 100644 --- a/Fw/DataStructures/test/ut/STest/StackTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/StackTestRules.cpp @@ -26,7 +26,7 @@ PushFull pushFull; PushOK pushOK; -}; // namespace Rules +} // namespace Rules } // namespace StackTest diff --git a/Fw/DataStructures/test/ut/STest/StackTestRules.hpp b/Fw/DataStructures/test/ut/STest/StackTestRules.hpp index b77c572eb7c..64e1d925437 100644 --- a/Fw/DataStructures/test/ut/STest/StackTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/StackTestRules.hpp @@ -114,7 +114,7 @@ extern PushFull pushFull; extern PushOK pushOK; -}; // namespace Rules +} // namespace Rules } // namespace StackTest diff --git a/Fw/DataStructures/test/ut/STest/StackTestState.hpp b/Fw/DataStructures/test/ut/STest/StackTestState.hpp index 08e097c2406..7390c93bfd1 100644 --- a/Fw/DataStructures/test/ut/STest/StackTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/StackTestState.hpp @@ -21,18 +21,18 @@ struct State { using ItemType = U32; //! The stack capacity static constexpr FwSizeType capacity = 1024; - //! THe StackBase type - using StackBase = StackBase; + //! The StackBase type + using StackBaseType = StackBase; //! Constructor - State(StackBase& a_stack) : stack(a_stack) {} + State(StackBaseType& a_stack) : stack(a_stack) {} //! The stack under test - StackBase& stack; + StackBaseType& stack; //! The stack for modeling correct behavior std::vector modelStack; //! Get a random item static ItemType getRandomItem() { return STest::Pick::any(); } //! Test copy data from - static void testCopyDataFrom(StackBase& s1, FwSizeType size1, StackBase& s2) { + static void testCopyDataFrom(StackBaseType& s1, FwSizeType size1, StackBaseType& s2) { s1.clear(); for (FwSizeType i = 0; i < size1; i++) { const auto status = s1.push(static_cast(i)); From 2c22549ebbe589e232c0d5354ce6a57555350ccb Mon Sep 17 00:00:00 2001 From: "Robert L. Bocchino Jr." Date: Mon, 21 Jul 2025 18:00:00 -0700 Subject: [PATCH 409/458] Revise Fw/DataStructures Fix compile errors on Linux --- Fw/DataStructures/CMakeLists.txt | 18 +++++++++--------- .../test/ut/STest/FifoQueueTestRules.cpp | 2 +- .../test/ut/STest/FifoQueueTestRules.hpp | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index 358cb5db775..96d7ae14446 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -8,19 +8,19 @@ set(UT_SOURCE_FILES # "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayMapTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestRules.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestScenarios.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/SetTestRules.cpp" diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.cpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.cpp index d6214f23f41..ca8213a5090 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.cpp @@ -26,7 +26,7 @@ EnqueueOK enqueueOK; Peek peek; -}; // namespace Rules +} // namespace Rules } // namespace FifoQueueTest diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp index 2ac2ee29524..c9a9d4c3042 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp @@ -111,7 +111,7 @@ extern EnqueueOK enqueueOK; extern Peek peek; -}; // namespace Rules +} // namespace Rules } // namespace FifoQueueTest From 37977d7f840cc8df7d0010a4dc5b0ccd0b8d408a Mon Sep 17 00:00:00 2001 From: "Robert L. Bocchino Jr." Date: Mon, 21 Jul 2025 18:01:49 -0700 Subject: [PATCH 410/458] Revise Fw/DataStructures Fix compile errors on Linux --- Fw/DataStructures/CMakeLists.txt | 6 +++--- .../test/ut/STest/ArraySetOrMapImplTestRules.cpp | 2 +- .../test/ut/STest/ArraySetOrMapImplTestRules.hpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index 96d7ae14446..265a06aa35a 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -6,7 +6,7 @@ register_fprime_module() set(UT_SOURCE_FILES # "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayMapTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" @@ -17,8 +17,8 @@ set(UT_SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/FifoQueueTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestRules.cpp" diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp index cb56eea1ee7..088b68e62b3 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.cpp @@ -28,7 +28,7 @@ Remove remove; RemoveExisting removeExisting; -}; // namespace Rules +} // namespace Rules } // namespace ArraySetOrMapImplTest diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp index b0c999e0254..609bfb2612d 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp @@ -180,7 +180,7 @@ extern Remove remove; extern RemoveExisting removeExisting; -}; // namespace Rules +} // namespace Rules } // namespace ArraySetOrMapImplTest From 7ca284f8a270848a887a19f68da6aaaced3f2df8 Mon Sep 17 00:00:00 2001 From: "Robert L. Bocchino Jr." Date: Mon, 21 Jul 2025 18:10:45 -0700 Subject: [PATCH 411/458] Revise Fw/DataStructures Fix compile errors on Linux --- Fw/DataStructures/CMakeLists.txt | 8 ++++---- Fw/DataStructures/SetOrMapImplEntry.hpp | 2 +- Fw/DataStructures/test/ut/STest/MapTestRules.cpp | 2 +- Fw/DataStructures/test/ut/STest/MapTestRules.hpp | 2 +- Fw/DataStructures/test/ut/STest/MapTestState.hpp | 8 ++++---- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index 265a06aa35a..69181c1a2f0 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -5,13 +5,13 @@ set(SOURCE_FILES register_fprime_module() set(UT_SOURCE_FILES -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayMapTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayMapTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" @@ -21,8 +21,8 @@ set(UT_SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestRules.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestRules.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestScenarios.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/SetTestRules.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/SetTestScenarios.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" diff --git a/Fw/DataStructures/SetOrMapImplEntry.hpp b/Fw/DataStructures/SetOrMapImplEntry.hpp index e11f89f1008..4d23addfbcd 100644 --- a/Fw/DataStructures/SetOrMapImplEntry.hpp +++ b/Fw/DataStructures/SetOrMapImplEntry.hpp @@ -29,7 +29,7 @@ class SetOrMapImplEntry final : public MapEntryBase { : MapEntryBase(), m_keyOrElement(keyOrElement), m_valueOrNil(valueOrNil) {} //! Copy constructor - SetOrMapImplEntry(const SetOrMapImplEntry& entry) { *this = entry; } + SetOrMapImplEntry(const SetOrMapImplEntry& entry) : MapEntryBase() { *this = entry; } //! Destructor ~SetOrMapImplEntry() override = default; diff --git a/Fw/DataStructures/test/ut/STest/MapTestRules.cpp b/Fw/DataStructures/test/ut/STest/MapTestRules.cpp index 10a139b83a1..41179ffb8bf 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/MapTestRules.cpp @@ -28,7 +28,7 @@ Remove remove; RemoveExisting removeExisting; -}; // namespace Rules +} // namespace Rules } // namespace MapTest diff --git a/Fw/DataStructures/test/ut/STest/MapTestRules.hpp b/Fw/DataStructures/test/ut/STest/MapTestRules.hpp index 7a766b928d4..795491bc0af 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/MapTestRules.hpp @@ -175,7 +175,7 @@ extern Remove remove; extern RemoveExisting removeExisting; -}; // namespace Rules +} // namespace Rules } // namespace MapTest diff --git a/Fw/DataStructures/test/ut/STest/MapTestState.hpp b/Fw/DataStructures/test/ut/STest/MapTestState.hpp index e24efd01670..ee003f5c242 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/MapTestState.hpp @@ -24,11 +24,11 @@ struct State { //! The map capacity static constexpr FwSizeType capacity = 1024; //! THe MapBase type - using MapBase = MapBase; + using MapBaseType = MapBase; //! Constructor - State(MapBase& a_map) : map(a_map) {} + State(MapBaseType& a_map) : map(a_map) {} //! The map under test - MapBase& map; + MapBaseType& map; //! The map for modeling correct behavior std::map modelMap; //! Whether to use the stored key @@ -46,7 +46,7 @@ struct State { //! Check whether the model map contains the specified key bool modelMapContains(KeyType key) const { return modelMap.count(key) != 0; } //! Test copy data from - static void testCopyDataFrom(MapBase& m1, FwSizeType size1, MapBase& m2) { + static void testCopyDataFrom(MapBaseType& m1, FwSizeType size1, MapBaseType& m2) { m1.clear(); for (FwSizeType i = 0; i < size1; i++) { const auto status = m1.insert(static_cast(i), static_cast(i)); From 20bbbe328b567422747b02e54ec467ad4d42d0d3 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 21 Jul 2025 17:49:26 -0700 Subject: [PATCH 412/458] Fix comments --- Fw/DataStructures/ArraySetOrMapImpl.hpp | 2 +- Fw/DataStructures/ExternalArrayMap.hpp | 2 +- Fw/DataStructures/ExternalArraySet.hpp | 2 +- Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp | 2 +- Fw/DataStructures/test/ut/STest/MapTestState.hpp | 2 +- Fw/DataStructures/test/ut/STest/SetTestState.hpp | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Fw/DataStructures/ArraySetOrMapImpl.hpp b/Fw/DataStructures/ArraySetOrMapImpl.hpp index e82a1f748c5..920b2d1c400 100644 --- a/Fw/DataStructures/ArraySetOrMapImpl.hpp +++ b/Fw/DataStructures/ArraySetOrMapImpl.hpp @@ -251,7 +251,7 @@ class ArraySetOrMapImpl final { //! 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 + void setStorage(ByteArray data, //!< The data FwSizeType capacity //!< The capacity ) { this->m_entries.setStorage(data, capacity); diff --git a/Fw/DataStructures/ExternalArrayMap.hpp b/Fw/DataStructures/ExternalArrayMap.hpp index 0362a8bac90..6f99df95b4f 100644 --- a/Fw/DataStructures/ExternalArrayMap.hpp +++ b/Fw/DataStructures/ExternalArrayMap.hpp @@ -133,7 +133,7 @@ class ExternalArrayMap final : public MapBase { //! 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 + void setStorage(ByteArray data, //!< The data FwSizeType capacity //!< The capacity ) { this->m_impl.setStorage(data, capacity); diff --git a/Fw/DataStructures/ExternalArraySet.hpp b/Fw/DataStructures/ExternalArraySet.hpp index 0d8abb80f48..c36b67741db 100644 --- a/Fw/DataStructures/ExternalArraySet.hpp +++ b/Fw/DataStructures/ExternalArraySet.hpp @@ -133,7 +133,7 @@ class ExternalArraySet final : public SetBase { //! 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 + void setStorage(ByteArray data, //!< The data FwSizeType capacity //!< The capacity ) { this->m_impl.setStorage(data, capacity); diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp index 89731a17d66..87343a43e49 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp @@ -25,7 +25,7 @@ struct State { using Queue = FifoQueue; //! The ExternalQueue type using ExternalQueue = ExternalFifoQueue; - //! THe QueueBase type + //! The QueueBase type using QueueBase = FifoQueueBase; //! Constructor State(QueueBase& a_queue) : queue(a_queue) {} diff --git a/Fw/DataStructures/test/ut/STest/MapTestState.hpp b/Fw/DataStructures/test/ut/STest/MapTestState.hpp index ee003f5c242..9a5a153f0c3 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/MapTestState.hpp @@ -23,7 +23,7 @@ struct State { using ValueType = U32; //! The map capacity static constexpr FwSizeType capacity = 1024; - //! THe MapBase type + //! The MapBase type using MapBaseType = MapBase; //! Constructor State(MapBaseType& a_map) : map(a_map) {} diff --git a/Fw/DataStructures/test/ut/STest/SetTestState.hpp b/Fw/DataStructures/test/ut/STest/SetTestState.hpp index 630ea10b2c8..efa4ceaffaf 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/SetTestState.hpp @@ -23,7 +23,7 @@ struct State { using ElementType = U32; //! The set capacity static constexpr FwSizeType capacity = 1024; - //! THe SetBase type + //! The SetBase type using SetBase = SetBase; //! Constructor State(SetBase& a_set) : set(a_set) {} From efdb00abcbf25273370aefc2692f636df546140e Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 21 Jul 2025 17:50:42 -0700 Subject: [PATCH 413/458] Revise Fw/DataStructures Reformat code --- Fw/DataStructures/ArraySetOrMapImpl.hpp | 2 +- Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp | 4 ++-- Fw/DataStructures/test/ut/ArrayTest.cpp | 12 ++++++------ Fw/DataStructures/test/ut/STest/MapTestRules.hpp | 5 ++--- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/Fw/DataStructures/ArraySetOrMapImpl.hpp b/Fw/DataStructures/ArraySetOrMapImpl.hpp index 920b2d1c400..afa50456d40 100644 --- a/Fw/DataStructures/ArraySetOrMapImpl.hpp +++ b/Fw/DataStructures/ArraySetOrMapImpl.hpp @@ -101,7 +101,7 @@ class ArraySetOrMapImpl final { } //! Set the iterator to the end value - void setToEnd() { + void setToEnd() { FW_ASSERT(this->m_impl != nullptr); this->m_index = this->m_impl->m_size; } diff --git a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp index eabbcc347d4..a3adef9cda0 100644 --- a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp +++ b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp @@ -81,7 +81,7 @@ TEST(ArraySetOrMapImpl, CopyAssignmentOperator) { } TEST(ArraySetOrMapImplScenarios, Clear) { - State::Entry entries[State::capacity]; + State::Entry entries[State::capacity]; State::Impl impl(entries, State::capacity); State state(impl); Rules::insertNotFull.apply(state); @@ -161,5 +161,5 @@ TEST(ArraySetOrMapImplScenarios, Random) { Scenarios::random(Fw::String("ArraySetOrMapImplRandom"), state, 1000); } -} // namespace ArraySetOrMapTest +} // namespace ArraySetOrMapImplTest } // namespace Fw diff --git a/Fw/DataStructures/test/ut/ArrayTest.cpp b/Fw/DataStructures/test/ut/ArrayTest.cpp index f4f6de73d17..145d2ca5fe1 100644 --- a/Fw/DataStructures/test/ut/ArrayTest.cpp +++ b/Fw/DataStructures/test/ut/ArrayTest.cpp @@ -49,7 +49,7 @@ TEST(Array, CopyConstructor) { // Call the copy constructor Array a2(a1); for (FwSizeType i = 0; i < 3; i++) { - ASSERT_EQ(a2[i], 10); + ASSERT_EQ(a2[i], 10); } } @@ -66,13 +66,13 @@ TEST(Array, Subscript) { TEST(Array, CopyAssignmentOperator) { Array a1(1); - for (FwSizeType i = 0; i < 3; i ++) { - ASSERT_EQ(a1[i], 1); + for (FwSizeType i = 0; i < 3; i++) { + ASSERT_EQ(a1[i], 1); } Array a2(2); auto& a = (a1 = a2); - for (FwSizeType i = 0; i < 3; i ++) { - ASSERT_EQ(a1[i], 2); + for (FwSizeType i = 0; i < 3; i++) { + ASSERT_EQ(a1[i], 2); } ASSERT_EQ(&a, &a1); } @@ -89,7 +89,7 @@ TEST(Array, GetElements) { } TEST(Array, AsExternalArray) { - Array a = { 1, 2, 3 }; + Array a = {1, 2, 3}; ExternalArray ea = a.asExternalArray(); ASSERT_EQ(ea[0], 1); } diff --git a/Fw/DataStructures/test/ut/STest/MapTestRules.hpp b/Fw/DataStructures/test/ut/STest/MapTestRules.hpp index 795491bc0af..c9929653856 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/MapTestRules.hpp @@ -125,12 +125,11 @@ struct Remove : public Rule { ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(value, state.modelMap[key]); ASSERT_EQ(state.map.getSize(), size - 1); - } - else { + } else { ASSERT_EQ(status, Success::FAILURE); ASSERT_EQ(state.map.getSize(), size); } - (void) state.modelMap.erase(key); + (void)state.modelMap.erase(key); ASSERT_EQ(state.map.getSize(), state.modelMap.size()); } }; From 49fc53cd7929034fb1b2fdc6cb7faae8ba83a0e2 Mon Sep 17 00:00:00 2001 From: "Robert L. Bocchino Jr." Date: Mon, 21 Jul 2025 18:15:54 -0700 Subject: [PATCH 414/458] Revise Fw/DataStructures Fix compile errors on Linux --- Fw/DataStructures/CMakeLists.txt | 8 ++++---- Fw/DataStructures/test/ut/STest/SetTestRules.cpp | 2 +- Fw/DataStructures/test/ut/STest/SetTestRules.hpp | 2 +- Fw/DataStructures/test/ut/STest/SetTestState.hpp | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Fw/DataStructures/CMakeLists.txt b/Fw/DataStructures/CMakeLists.txt index 69181c1a2f0..2c408d1ba90 100644 --- a/Fw/DataStructures/CMakeLists.txt +++ b/Fw/DataStructures/CMakeLists.txt @@ -7,12 +7,12 @@ register_fprime_module() set(UT_SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayMapTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetOrMapImplTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArraySetTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ArrayTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/CircularIndexTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/DataStructuresTestMain.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayMapTest.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArraySetTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalArrayTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalFifoQueueTest.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalStackTest.cpp" @@ -23,8 +23,8 @@ set(UT_SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/FifoQueueTestScenarios.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestRules.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/MapTestScenarios.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/SetTestRules.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/SetTestScenarios.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/SetTestRules.cpp" + "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/SetTestScenarios.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestRules.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/STest/StackTestScenarios.cpp" "${CMAKE_CURRENT_LIST_DIR}/test/ut/StackTest.cpp" diff --git a/Fw/DataStructures/test/ut/STest/SetTestRules.cpp b/Fw/DataStructures/test/ut/STest/SetTestRules.cpp index 13429099ace..ff4ade40a73 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestRules.cpp +++ b/Fw/DataStructures/test/ut/STest/SetTestRules.cpp @@ -28,7 +28,7 @@ Remove remove; RemoveExisting removeExisting; -}; // namespace Rules +} // namespace Rules } // namespace SetTest diff --git a/Fw/DataStructures/test/ut/STest/SetTestRules.hpp b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp index c4e094deda6..7b551aee805 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp @@ -166,7 +166,7 @@ extern Remove remove; extern RemoveExisting removeExisting; -}; // namespace Rules +} // namespace Rules } // namespace SetTest diff --git a/Fw/DataStructures/test/ut/STest/SetTestState.hpp b/Fw/DataStructures/test/ut/STest/SetTestState.hpp index efa4ceaffaf..8ba0574794b 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/SetTestState.hpp @@ -24,11 +24,11 @@ struct State { //! The set capacity static constexpr FwSizeType capacity = 1024; //! The SetBase type - using SetBase = SetBase; + using SetBaseType = SetBase; //! Constructor - State(SetBase& a_set) : set(a_set) {} + State(SetBaseType& a_set) : set(a_set) {} //! The set under test - SetBase& set; + SetBaseType& set; //! The set for modeling correct behavior std::set modelSet; //! Whether to use the stored element @@ -42,7 +42,7 @@ struct State { //! Check whether the model set contains the specified element bool modelSetContains(ElementType e) const { return modelSet.count(e) != 0; } //! Test copy data from - static void testCopyDataFrom(SetBase& m1, FwSizeType size1, SetBase& m2) { + static void testCopyDataFrom(SetBaseType& m1, FwSizeType size1, SetBaseType& m2) { m1.clear(); for (FwSizeType i = 0; i < size1; i++) { const auto status = m1.insert(static_cast(i)); From 6994d957b59b543992b1985e9a6a3852f5b96f6c Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 21 Jul 2025 17:59:45 -0700 Subject: [PATCH 415/458] Revise ArrayMap docs --- Fw/DataStructures/docs/ArrayMap.md | 1 - 1 file changed, 1 deletion(-) diff --git a/Fw/DataStructures/docs/ArrayMap.md b/Fw/DataStructures/docs/ArrayMap.md index 6c79d720e12..8e66a0ea29f 100644 --- a/Fw/DataStructures/docs/ArrayMap.md +++ b/Fw/DataStructures/docs/ArrayMap.md @@ -31,7 +31,6 @@ It represents an array-based map with internal storage. |`ConstIterator`|Alias of [`MapConstIterator`](MapConstIterator.md)| |`Entry`|Alias of [`SetOrMapImplEntry`](SetOrMapImplEntry.md)| |`Entries`|Alias of `Entry[C]`| -|`MapEntryBase`|Alias of [`MapEntryBase`](MapEntryBase.md)| ## 4. Private Member Variables From 431fcab57bcaa6e0c37d43e2d93bb4bb67526f82 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 23 Jul 2025 15:18:29 -0700 Subject: [PATCH 416/458] Remove helper scripts --- Fw/DataStructures/build_ut | 6 ------ Fw/DataStructures/clear_gcda | 7 ------- Fw/DataStructures/run_ut | 5 ----- 3 files changed, 18 deletions(-) delete mode 100755 Fw/DataStructures/build_ut delete mode 100755 Fw/DataStructures/clear_gcda delete mode 100755 Fw/DataStructures/run_ut diff --git a/Fw/DataStructures/build_ut b/Fw/DataStructures/build_ut deleted file mode 100755 index eea7f1a874d..00000000000 --- a/Fw/DataStructures/build_ut +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -e - -cd `dirname $0` -./clear_gcda -fprime-util build --ut "$@" -cp ../../build-fprime-automatic-native-ut/bin/`uname`/Fw_DataStructures_ut_exe . diff --git a/Fw/DataStructures/clear_gcda b/Fw/DataStructures/clear_gcda deleted file mode 100755 index 54610a0c99d..00000000000 --- a/Fw/DataStructures/clear_gcda +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh -e - -cd `dirname $0` -for file in `find ../.. -name '*.gcda'` -do - rm $file -done diff --git a/Fw/DataStructures/run_ut b/Fw/DataStructures/run_ut deleted file mode 100755 index a108913eeee..00000000000 --- a/Fw/DataStructures/run_ut +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -e - -cd `dirname $0` -./build_ut "$@" -./Fw_DataStructures_ut_exe From 9ea19bbdf1290533b5eec98a7bf0d167a695bd3f Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 23 Jul 2025 15:35:25 -0700 Subject: [PATCH 417/458] Revise tests for Fw/DataStructures --- Fw/DataStructures/test/ut/ArrayMapTest.cpp | 1 - Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp | 7 +++++++ Fw/DataStructures/test/ut/STest/MapTestRules.hpp | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/test/ut/ArrayMapTest.cpp b/Fw/DataStructures/test/ut/ArrayMapTest.cpp index 9ae8069954d..6e505f43677 100644 --- a/Fw/DataStructures/test/ut/ArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ArrayMapTest.cpp @@ -29,7 +29,6 @@ class ArrayMapTester { namespace MapTest { -using ConstIterator = MapConstIterator; using Entry = SetOrMapImplEntry; using Map = ArrayMap; using MapTester = ArrayMapTester; diff --git a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp index a3adef9cda0..f0bf5c3a9ac 100644 --- a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp +++ b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp @@ -80,6 +80,13 @@ TEST(ArraySetOrMapImpl, CopyAssignmentOperator) { ASSERT_EQ(impl2.getSize(), 1); } +TEST(ArraySetOrMapImpl, IteratorComparison) { + // Test comparison in default case + State::Impl::ConstIterator it1; + State::Impl::ConstIterator it2; + ASSERT_TRUE(it1.compareEqual(it2)); +} + TEST(ArraySetOrMapImplScenarios, Clear) { State::Entry entries[State::capacity]; State::Impl impl(entries, State::capacity); diff --git a/Fw/DataStructures/test/ut/STest/MapTestRules.hpp b/Fw/DataStructures/test/ut/STest/MapTestRules.hpp index c9929653856..ade72081a09 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/MapTestRules.hpp @@ -146,7 +146,7 @@ struct RemoveExisting : public Rule { it++; } ASSERT_TRUE(it.isInRange()); - const auto key = it->getKey(); + const auto key = (*it).getKey(); const auto expectedValue = state.modelMap[key]; State::ValueType value = 0; const auto status = state.map.remove(key, value); From 1b532e08c5b5302e1e8fbf818e545654decedbcb Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 23 Jul 2025 15:55:37 -0700 Subject: [PATCH 418/458] Fix spelling --- Fw/DataStructures/ArraySet.hpp | 2 +- Fw/DataStructures/StackBase.hpp | 2 +- Fw/DataStructures/docs/ExternalArray.md | 4 ++-- Fw/DataStructures/docs/MapBase.md | 3 ++- Fw/DataStructures/test/ut/ExternalArrayTest.cpp | 6 +++--- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Fw/DataStructures/ArraySet.hpp b/Fw/DataStructures/ArraySet.hpp index c829819023e..e98078f48a0 100644 --- a/Fw/DataStructures/ArraySet.hpp +++ b/Fw/DataStructures/ArraySet.hpp @@ -28,7 +28,7 @@ class ArraySet final : public SetBase { //! The type of a const iterator using ConstIterator = SetConstIterator; - //! The type of animplementation entry + //! The type of an implementation entry using Entry = SetOrMapImplEntry; //! The type of the implementation entries diff --git a/Fw/DataStructures/StackBase.hpp b/Fw/DataStructures/StackBase.hpp index 70308f7bd48..d3a8f951cdf 100644 --- a/Fw/DataStructures/StackBase.hpp +++ b/Fw/DataStructures/StackBase.hpp @@ -76,7 +76,7 @@ class StackBase { } //! Push an item (add to the right) - //! \return SUCCESS if item pushd + //! \return SUCCESS if item pushed virtual Success push(const T& e //!< The item (output) ) = 0; diff --git a/Fw/DataStructures/docs/ExternalArray.md b/Fw/DataStructures/docs/ExternalArray.md index 67ae2f3d5c2..12b0187f414 100644 --- a/Fw/DataStructures/docs/ExternalArray.md +++ b/Fw/DataStructures/docs/ExternalArray.md @@ -73,7 +73,7 @@ _Example:_ ```c++ constexpr FwSizeType size = 3; constexpr U8 alignment = ExternalArray::byteArrayAlignment(); -constepxr FwSizeType byteArraySize = ExternalArray::getByteArraySize(size); +constexpr FwSizeType byteArraySize = ExternalArray::getByteArraySize(size); alignas(alignment) U8 bytes[byteArraySize]; ExternalArray a(ByteArray(&bytes[0], sizeof bytes), size); ``` @@ -262,7 +262,7 @@ _Example:_ ```c++ constexpr FwSizeType size = 3; constexpr U8 alignment = ExternalArray::byteArrayAlignment(); -constepxr FwSizeType byteArraySize = ExternalArray::getByteArraySize(size); +constexpr FwSizeType byteArraySize = ExternalArray::getByteArraySize(size); alignas(alignment) U8 bytes[byteArraySize]; ExternalArray a; a.setStorage(ByteArray(&bytes[0], sizeof bytes), size); diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index 0a753e66f86..b57a3daf097 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -186,6 +186,7 @@ void f(const MapBase& map) { } ``` + ### 5.6. getCapacity ```c++ @@ -212,7 +213,7 @@ virtual FwSizeType getSize() const = 0 Return the current size. _Example:_ -See [**getCapacity**](MapBase.md#64-getcapacity). +See [**getCapacity**](MapBase.md#getCapacity). ### 5.8. insert diff --git a/Fw/DataStructures/test/ut/ExternalArrayTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayTest.cpp index af732f36b70..26a4df20adb 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayTest.cpp @@ -112,7 +112,7 @@ TEST(ExternalArray, SetStorageTyped) { ASSERT_EQ(a.getSize(), size); } -TEST(ExternalArray, SetStorageUnypedOK) { +TEST(ExternalArray, SetStorageUntypedOK) { constexpr FwSizeType size = 10; constexpr U8 alignment = ExternalArray::getByteArrayAlignment(); constexpr FwSizeType byteArraySize = ExternalArray::getByteArraySize(size); @@ -123,7 +123,7 @@ TEST(ExternalArray, SetStorageUnypedOK) { ASSERT_EQ(a.getSize(), size); } -TEST(ExternalArray, SetStorageUnypedBadSize) { +TEST(ExternalArray, SetStorageUntypedBadSize) { constexpr FwSizeType size = 10; constexpr U8 alignment = ExternalArray::getByteArrayAlignment(); constexpr FwSizeType byteArraySize = ExternalArray::getByteArraySize(size); @@ -132,7 +132,7 @@ TEST(ExternalArray, SetStorageUnypedBadSize) { ASSERT_DEATH(a.setStorage(ByteArray(&bytes[0], sizeof bytes), size + 1), "Assert"); } -TEST(ExternalArray, SetStorageUnypedBadAlignment) { +TEST(ExternalArray, SetStorageUntypedBadAlignment) { constexpr FwSizeType size = 10; constexpr U8 alignment = ExternalArray::getByteArrayAlignment(); constexpr FwSizeType byteArraySize = ExternalArray::getByteArraySize(size); From 53c3e546df0cc64ce26ef13c67bffabbb63c74dd Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 23 Jul 2025 19:10:59 -0700 Subject: [PATCH 419/458] Fix Markdown link --- Fw/DataStructures/docs/ExternalArrayMap.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index fe635b310b4..16e2ba9b299 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -28,7 +28,7 @@ as the map implementation. |Name|Definition| |----|----------| |`ConstIterator`|Alias of [`MapConstIterator`](MapConstIterator.md)| -|`Entry`|Alias of [`SetOrMapEntry`](SetOrMapEntry.md)| +|`Entry`|Alias of [`SetOrMapImplEntry`](SetOrMapImplEntry.md)| ## 4. Private Member Variables From 1b9024823a8802eeeba3757dd9d1f269a831624d Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 23 Jul 2025 19:22:08 -0700 Subject: [PATCH 420/458] Fix uninitialized variable in test --- Fw/DataStructures/test/ut/STest/StackTestRules.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/test/ut/STest/StackTestRules.hpp b/Fw/DataStructures/test/ut/STest/StackTestRules.hpp index 64e1d925437..381fd6fb060 100644 --- a/Fw/DataStructures/test/ut/STest/StackTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/StackTestRules.hpp @@ -47,7 +47,7 @@ struct Peek : public Rule { void action(State& state) { const auto size = state.stack.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); - State::ItemType item; + State::ItemType item = 0; const auto status = state.stack.peek(item, index); ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(item, state.modelStack.at(size - 1 - index)); From 0c4e7065e95cef4da1ba0734e1df6d846931426c Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 23 Jul 2025 19:32:57 -0700 Subject: [PATCH 421/458] Fix uninitialized variable in test --- Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp index c9a9d4c3042..c3743cbfa94 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp @@ -90,7 +90,7 @@ struct Peek : public Rule { bool precondition(const State& state) { return state.queue.getSize() > 0; } void action(State& state) { const auto index = STest::Pick::startLength(0, static_cast(state.queue.getSize())); - State::ItemType item; + State::ItemType item = 0; const auto status = state.queue.peek(item, index); ASSERT_EQ(status, Success::SUCCESS); ASSERT_EQ(item, state.modelQueue.at(index)); From c94b25af11dce6cf8508816369a9cf3122b6b3e5 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 23 Jul 2025 19:39:14 -0700 Subject: [PATCH 422/458] Fix "spelling" Why is the spelling check enforcing arbitrary rules of style? --- Fw/DataStructures/SetBase.hpp | 2 +- Fw/DataStructures/docs/ArraySet.md | 4 ++-- Fw/DataStructures/docs/ExternalArrayMap.md | 2 +- Fw/DataStructures/docs/ExternalArraySet.md | 8 ++++---- Fw/DataStructures/docs/SetOrMapImplConstIterator.md | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Fw/DataStructures/SetBase.hpp b/Fw/DataStructures/SetBase.hpp index ee5a78332b4..870a913eb0b 100644 --- a/Fw/DataStructures/SetBase.hpp +++ b/Fw/DataStructures/SetBase.hpp @@ -78,7 +78,7 @@ class SetBase { } } - //! Find the an element in a set + //! Find an element in a set //! SUCCESS if the item was found virtual Success find(const T& element //!< The element ) const = 0; diff --git a/Fw/DataStructures/docs/ArraySet.md b/Fw/DataStructures/docs/ArraySet.md index b37b75f92d5..2539996e98a 100644 --- a/Fw/DataStructures/docs/ArraySet.md +++ b/Fw/DataStructures/docs/ArraySet.md @@ -30,7 +30,7 @@ It represents an array-based set with internal storage. |`ConstIterator`|Alias of [`SetConstIterator`](SetConstIterator.md)| |`Entry`|Alias of [`SetOrMapImplEntry`](SetOrMapImplEntry.md)| -The type `Nil` is defined [here](Nil.md). +The type `Nil` is defined [in this file](Nil.md). ## 4. Private Member Variables @@ -41,7 +41,7 @@ The type `Nil` is defined [here](Nil.md). |`m_extSet`|[`ExternalArraySet`](ExternalArraySet.md)|The external set implementation|C++ default initialization| |`m_entries`|`Entry[C]`|The array providing the backing memory for `m_extSet`|C++ default initialization| -The type `Entry` is defined [here](ArraySet.md#Public-Types). +The type `Entry` is defined [in this section](ArraySet.md#Public-Types). ```mermaid classDiagram diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index 16e2ba9b299..7d75184ed02 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -370,7 +370,7 @@ void setStorage(Entry* entries, FwSizeType capacity) `entries` must point to a primitive array of at least `capacity` elements of type `Entry`. -The type `Entry` is defined [here](ExternalArrayMap.md#Public-Types). +The type `Entry` is defined [in this section](ExternalArrayMap.md#Public-Types). Call `m_impl.setStorage(entries, capacity)`. diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md index 8ca2a3fb159..fc5ea4272d0 100644 --- a/Fw/DataStructures/docs/ExternalArraySet.md +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -29,7 +29,7 @@ as the set implementation. |`ConstIterator`|Alias of [`MapConstIterator`](MapConstIterator.md)| |`Entry`|Alias of [`SetOrMapImplEntry`](SetOrMapImplEntry.md)| -The type `Nil` is defined [here](Nil.md). +The type `Nil` is defined [in this file](Nil.md). ## 4. Private Member Variables @@ -39,7 +39,7 @@ The type `Nil` is defined [here](Nil.md). |----|----|-------|-------------| |`m_impl`|[`ArraySetOrMapImpl`](ArraySetOrMapImpl.md)|The set implementation|C++ default initialization| -The type `Nil` is defined [here](Nil.md). +The type `Nil` is defined [in this file](Nil.md). ```mermaid classDiagram @@ -69,7 +69,7 @@ ExternalArraySet(Entry* entries, FwSizeType capacity) `entries` must point to a primitive array of at least `capacity` elements of type `Entry`. -The type `Entry` is defined [here](ExternalArraySet.md#Public-Types). +The type `Entry` is defined [in this section](ExternalArraySet.md#Public-Types). Call `setStorage(entries, capacity)`. @@ -363,7 +363,7 @@ void setStorage(Entry* entries, FwSizeType capacity) `entries` must point to a primitive array of at least `capacity` elements of type `Entry`. -The type `Entry` is defined [here](ExternalArraySet.md#Public-Types). +The type `Entry` is defined [in this section](ExternalArraySet.md#Public-Types). Call `m_impl.setStorage(entries, capacity)`. diff --git a/Fw/DataStructures/docs/SetOrMapImplConstIterator.md b/Fw/DataStructures/docs/SetOrMapImplConstIterator.md index 1bb7b3a2758..1b2e207af57 100644 --- a/Fw/DataStructures/docs/SetOrMapImplConstIterator.md +++ b/Fw/DataStructures/docs/SetOrMapImplConstIterator.md @@ -3,4 +3,4 @@ `SetOrMapImplConstIterator` is an abstract base class. It specifies an interface for constant iterators over set or map implementations. -The header file is defined [here](../SetOrMapImplConstIterator.hpp). +Here is the [header file for the class](../SetOrMapImplConstIterator.hpp). From 7667203f1c746a0383a04f087795f10bb6c91478 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 23 Jul 2025 21:39:11 -0700 Subject: [PATCH 423/458] Fix comments --- Fw/DataStructures/MapConstIterator.hpp | 2 +- Fw/DataStructures/SetConstIterator.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/MapConstIterator.hpp b/Fw/DataStructures/MapConstIterator.hpp index e2842d2b4de..f9a1cc84b77 100644 --- a/Fw/DataStructures/MapConstIterator.hpp +++ b/Fw/DataStructures/MapConstIterator.hpp @@ -112,7 +112,7 @@ class MapConstIterator { return *this; } - //! Prefix increment + //! Postfix increment MapConstIterator operator++(int) { MapConstIterator tmp = *this; ++(*this); diff --git a/Fw/DataStructures/SetConstIterator.hpp b/Fw/DataStructures/SetConstIterator.hpp index cb08d849ed3..8af5ff73ef2 100644 --- a/Fw/DataStructures/SetConstIterator.hpp +++ b/Fw/DataStructures/SetConstIterator.hpp @@ -111,7 +111,7 @@ class SetConstIterator { return *this; } - //! Prefix increment + //! Postfix increment SetConstIterator operator++(int) { SetConstIterator tmp = *this; ++(*this); From 5d5a003d6db209af24b1d595bcbb6cd9740c9a5f Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Fri, 25 Jul 2025 10:11:22 -0700 Subject: [PATCH 424/458] Revise tests for ArraySetOrMapImpl --- Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp index f0bf5c3a9ac..83137dbb6cd 100644 --- a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp +++ b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp @@ -17,8 +17,6 @@ namespace Fw { namespace ArraySetOrMapImplTest { -State::Impl impl_; -State::Impl::ConstIterator it(impl_); TEST(ArraySetOrMapImpl, ZeroArgConstructor) { State::Impl impl; ASSERT_EQ(impl.getCapacity(), 0); @@ -80,6 +78,11 @@ TEST(ArraySetOrMapImpl, CopyAssignmentOperator) { ASSERT_EQ(impl2.getSize(), 1); } +TEST(ArraySetOrMapImpl, IteratorConstruction) { + State::Impl impl; + State::Impl::ConstIterator it(impl); +} + TEST(ArraySetOrMapImpl, IteratorComparison) { // Test comparison in default case State::Impl::ConstIterator it1; From c6df7a78843a6066d88062aee96a75187b082d3a Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Fri, 25 Jul 2025 10:37:19 -0700 Subject: [PATCH 425/458] Revise comment --- Fw/DataStructures/ArraySetOrMapImpl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/ArraySetOrMapImpl.hpp b/Fw/DataStructures/ArraySetOrMapImpl.hpp index afa50456d40..847f7215956 100644 --- a/Fw/DataStructures/ArraySetOrMapImpl.hpp +++ b/Fw/DataStructures/ArraySetOrMapImpl.hpp @@ -133,7 +133,7 @@ class ArraySetOrMapImpl final { //! 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, + ArraySetOrMapImpl(ByteArray data, //!< The data FwSizeType capacity //!< The capacity ) { this->setStorage(data, capacity); From d2168c823bea0042f3bd6892f32fc4abab570a76 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Fri, 25 Jul 2025 16:21:28 -0700 Subject: [PATCH 426/458] Revise ArraySetOrMap impl --- Fw/DataStructures/ArraySetOrMapImpl.hpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Fw/DataStructures/ArraySetOrMapImpl.hpp b/Fw/DataStructures/ArraySetOrMapImpl.hpp index 847f7215956..2c42f937737 100644 --- a/Fw/DataStructures/ArraySetOrMapImpl.hpp +++ b/Fw/DataStructures/ArraySetOrMapImpl.hpp @@ -42,14 +42,11 @@ class ArraySetOrMapImpl final { ConstIterator() {} //! Constructor providing the implementation - ConstIterator(const ArraySetOrMapImpl& impl) : SetOrMapImplConstIterator(), m_impl(&impl) { - this->m_index = 0; - } + ConstIterator(const ArraySetOrMapImpl& impl) : SetOrMapImplConstIterator(), m_impl(&impl) {} //! Copy constructor - ConstIterator(const ConstIterator& it) : SetOrMapImplConstIterator(), m_impl(it.m_impl) { - this->m_index = 0; - } + ConstIterator(const ConstIterator& it) + : SetOrMapImplConstIterator(), m_impl(it.m_impl), m_index(it.m_index) {} //! Destructor ~ConstIterator() override = default; From cac2fe239c3b36695b890119ec0c9cf3989c01bf Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 4 Aug 2025 15:40:03 -0700 Subject: [PATCH 427/458] Revise formatting --- .../test/ut/ArraySetOrMapImplTest.cpp | 8 ++++---- .../ut/STest/ArraySetOrMapImplTestScenarios.cpp | 14 +++----------- .../test/ut/STest/FifoQueueTestRules.hpp | 2 -- .../test/ut/STest/FifoQueueTestScenarios.cpp | 13 +++---------- .../test/ut/STest/FifoQueueTestState.hpp | 1 + Fw/DataStructures/test/ut/STest/MapTestRules.hpp | 2 -- .../test/ut/STest/MapTestScenarios.cpp | 14 +++----------- Fw/DataStructures/test/ut/STest/MapTestState.hpp | 1 + .../test/ut/STest/SetTestScenarios.cpp | 15 +++------------ .../test/ut/STest/StackTestRules.hpp | 2 -- .../test/ut/STest/StackTestScenarios.cpp | 13 +++---------- .../test/ut/STest/StackTestState.hpp | 1 + 12 files changed, 22 insertions(+), 64 deletions(-) diff --git a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp index 83137dbb6cd..e7f3daa5a63 100644 --- a/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp +++ b/Fw/DataStructures/test/ut/ArraySetOrMapImplTest.cpp @@ -84,10 +84,10 @@ TEST(ArraySetOrMapImpl, IteratorConstruction) { } TEST(ArraySetOrMapImpl, IteratorComparison) { - // Test comparison in default case - State::Impl::ConstIterator it1; - State::Impl::ConstIterator it2; - ASSERT_TRUE(it1.compareEqual(it2)); + // Test comparison in default case + State::Impl::ConstIterator it1; + State::Impl::ConstIterator it2; + ASSERT_TRUE(it1.compareEqual(it2)); } TEST(ArraySetOrMapImplScenarios, Clear) { diff --git a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp index 9d5a7e91d5e..e06ce310071 100644 --- a/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp +++ b/Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.cpp @@ -4,8 +4,8 @@ // \brief ArraySetOrMapImpl test scenarios // ====================================================================== -#include "Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp" #include "Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestScenarios.hpp" +#include "Fw/DataStructures/test/ut/STest/ArraySetOrMapImplTestRules.hpp" #include "STest/Scenario/BoundedScenario.hpp" #include "STest/Scenario/RandomScenario.hpp" @@ -16,16 +16,8 @@ namespace ArraySetOrMapImplTest { namespace Scenarios { void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { - Rule* rules[] = { - &Rules::clear, - &Rules::find, - &Rules::findExisting, - &Rules::insertExisting, - &Rules::insertFull, - &Rules::insertNotFull, - &Rules::remove, - &Rules::removeExisting - }; + Rule* rules[] = {&Rules::clear, &Rules::find, &Rules::findExisting, &Rules::insertExisting, + &Rules::insertFull, &Rules::insertNotFull, &Rules::remove, &Rules::removeExisting}; STest::RandomScenario scenario("RandomScenario", rules, sizeof(rules) / sizeof(STest::RandomScenario*)); STest::BoundedScenario boundedScenario(name.toChar(), scenario, maxNumSteps); diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp index c3743cbfa94..8e3da526348 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp @@ -7,8 +7,6 @@ #ifndef FifoQueueTestRules_HPP #define FifoQueueTestRules_HPP -#include - #include "Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp" #include "STest/STest/Pick/Pick.hpp" #include "STest/STest/Rule/Rule.hpp" diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.cpp index 535cac41128..b42cd4a3548 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.cpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.cpp @@ -4,8 +4,8 @@ // \brief FifoQueue test scenarios // ====================================================================== -#include "Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp" #include "Fw/DataStructures/test/ut/STest/FifoQueueTestScenarios.hpp" +#include "Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp" #include "STest/Scenario/BoundedScenario.hpp" #include "STest/Scenario/RandomScenario.hpp" @@ -52,15 +52,8 @@ void peek(State& state) { } void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { - Rule* rules[] = { - &Rules::at, - &Rules::clear, - &Rules::dequeueEmpty, - &Rules::dequeueOK, - &Rules::enqueueFull, - &Rules::enqueueOK, - &Rules::peek - }; + Rule* rules[] = {&Rules::at, &Rules::clear, &Rules::dequeueEmpty, &Rules::dequeueOK, + &Rules::enqueueFull, &Rules::enqueueOK, &Rules::peek}; STest::RandomScenario scenario("RandomScenario", rules, sizeof(rules) / sizeof(STest::RandomScenario*)); STest::BoundedScenario boundedScenario(name.toChar(), scenario, maxNumSteps); diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp index 87343a43e49..382a0d4ed9b 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestState.hpp @@ -7,6 +7,7 @@ #ifndef FifoQueueTestState_HPP #define FifoQueueTestState_HPP +#include #include #include "Fw/DataStructures/FifoQueue.hpp" diff --git a/Fw/DataStructures/test/ut/STest/MapTestRules.hpp b/Fw/DataStructures/test/ut/STest/MapTestRules.hpp index ade72081a09..9319a828bef 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/MapTestRules.hpp @@ -7,8 +7,6 @@ #ifndef MapTestRules_HPP #define MapTestRules_HPP -#include - #include "Fw/DataStructures/test/ut/STest/MapTestState.hpp" #include "STest/STest/Pick/Pick.hpp" #include "STest/STest/Rule/Rule.hpp" diff --git a/Fw/DataStructures/test/ut/STest/MapTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/MapTestScenarios.cpp index a32a288eaf0..75fdd7c3861 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestScenarios.cpp +++ b/Fw/DataStructures/test/ut/STest/MapTestScenarios.cpp @@ -4,8 +4,8 @@ // \brief Map test scenarios // ====================================================================== -#include "Fw/DataStructures/test/ut/STest/MapTestRules.hpp" #include "Fw/DataStructures/test/ut/STest/MapTestScenarios.hpp" +#include "Fw/DataStructures/test/ut/STest/MapTestRules.hpp" #include "STest/Scenario/BoundedScenario.hpp" #include "STest/Scenario/RandomScenario.hpp" @@ -66,16 +66,8 @@ void removeExisting(State& state) { } void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { - Rule* rules[] = { - &Rules::clear, - &Rules::find, - &Rules::findExisting, - &Rules::insertExisting, - &Rules::insertFull, - &Rules::insertNotFull, - &Rules::remove, - &Rules::removeExisting - }; + Rule* rules[] = {&Rules::clear, &Rules::find, &Rules::findExisting, &Rules::insertExisting, + &Rules::insertFull, &Rules::insertNotFull, &Rules::remove, &Rules::removeExisting}; STest::RandomScenario scenario("RandomScenario", rules, sizeof(rules) / sizeof(STest::RandomScenario*)); STest::BoundedScenario boundedScenario(name.toChar(), scenario, maxNumSteps); diff --git a/Fw/DataStructures/test/ut/STest/MapTestState.hpp b/Fw/DataStructures/test/ut/STest/MapTestState.hpp index 9a5a153f0c3..26c65919743 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/MapTestState.hpp @@ -7,6 +7,7 @@ #ifndef MapTestState_HPP #define MapTestState_HPP +#include #include #include "Fw/DataStructures/MapBase.hpp" diff --git a/Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp index 641edbcbf74..53f3d02aa3a 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp +++ b/Fw/DataStructures/test/ut/STest/SetTestScenarios.cpp @@ -4,8 +4,8 @@ // \brief Set test scenarios // ====================================================================== -#include "Fw/DataStructures/test/ut/STest/SetTestRules.hpp" #include "Fw/DataStructures/test/ut/STest/SetTestScenarios.hpp" +#include "Fw/DataStructures/test/ut/STest/SetTestRules.hpp" #include "STest/Scenario/BoundedScenario.hpp" #include "STest/Scenario/RandomScenario.hpp" @@ -15,7 +15,6 @@ namespace SetTest { namespace Scenarios { - void clear(State& state) { Rules::insertNotFull.apply(state); ASSERT_EQ(state.set.getSize(), 1); @@ -67,16 +66,8 @@ void removeExisting(State& state) { } void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { - Rule* rules[] = { - &Rules::clear, - &Rules::find, - &Rules::findExisting, - &Rules::insertExisting, - &Rules::insertFull, - &Rules::insertNotFull, - &Rules::remove, - &Rules::removeExisting - }; + Rule* rules[] = {&Rules::clear, &Rules::find, &Rules::findExisting, &Rules::insertExisting, + &Rules::insertFull, &Rules::insertNotFull, &Rules::remove, &Rules::removeExisting}; STest::RandomScenario scenario("RandomScenario", rules, sizeof(rules) / sizeof(STest::RandomScenario*)); STest::BoundedScenario boundedScenario(name.toChar(), scenario, maxNumSteps); diff --git a/Fw/DataStructures/test/ut/STest/StackTestRules.hpp b/Fw/DataStructures/test/ut/STest/StackTestRules.hpp index 381fd6fb060..2a6fea67bd7 100644 --- a/Fw/DataStructures/test/ut/STest/StackTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/StackTestRules.hpp @@ -7,8 +7,6 @@ #ifndef StackTestRules_HPP #define StackTestRules_HPP -#include - #include "Fw/DataStructures/test/ut/STest/StackTestState.hpp" #include "STest/STest/Pick/Pick.hpp" #include "STest/STest/Rule/Rule.hpp" diff --git a/Fw/DataStructures/test/ut/STest/StackTestScenarios.cpp b/Fw/DataStructures/test/ut/STest/StackTestScenarios.cpp index 54315d27afc..93e7de38dbc 100644 --- a/Fw/DataStructures/test/ut/STest/StackTestScenarios.cpp +++ b/Fw/DataStructures/test/ut/STest/StackTestScenarios.cpp @@ -4,8 +4,8 @@ // \brief Stack test scenarios // ====================================================================== -#include "Fw/DataStructures/test/ut/STest/StackTestRules.hpp" #include "Fw/DataStructures/test/ut/STest/StackTestScenarios.hpp" +#include "Fw/DataStructures/test/ut/STest/StackTestRules.hpp" #include "STest/Scenario/BoundedScenario.hpp" #include "STest/Scenario/RandomScenario.hpp" @@ -54,15 +54,8 @@ void pushOK(State& state) { } void random(const Fw::StringBase& name, State& state, U32 maxNumSteps) { - Rule* rules[] = { - &Rules::pushOK, - &Rules::pushFull, - &Rules::at, - &Rules::peek, - &Rules::popOK, - &Rules::popEmpty, - &Rules::clear - }; + Rule* rules[] = {&Rules::pushOK, &Rules::pushFull, &Rules::at, &Rules::peek, + &Rules::popOK, &Rules::popEmpty, &Rules::clear}; STest::RandomScenario scenario("RandomScenario", rules, sizeof(rules) / sizeof(STest::RandomScenario*)); STest::BoundedScenario boundedScenario(name.toChar(), scenario, maxNumSteps); diff --git a/Fw/DataStructures/test/ut/STest/StackTestState.hpp b/Fw/DataStructures/test/ut/STest/StackTestState.hpp index 7390c93bfd1..4c8b30b07b0 100644 --- a/Fw/DataStructures/test/ut/STest/StackTestState.hpp +++ b/Fw/DataStructures/test/ut/STest/StackTestState.hpp @@ -7,6 +7,7 @@ #ifndef StackTestState_HPP #define StackTestState_HPP +#include #include #include "Fw/DataStructures/StackBase.hpp" From a845f1d606d1f5a588adafe6bbbc8b06d39b8d6a Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 4 Aug 2025 17:35:36 -0700 Subject: [PATCH 428/458] Revise docs --- Fw/DataStructures/docs/MapConstIterator.md | 10 ++++++++++ Fw/DataStructures/docs/SetConstIterator.md | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/Fw/DataStructures/docs/MapConstIterator.md b/Fw/DataStructures/docs/MapConstIterator.md index c8ab55dd459..52e828cc83d 100644 --- a/Fw/DataStructures/docs/MapConstIterator.md +++ b/Fw/DataStructures/docs/MapConstIterator.md @@ -1,6 +1,7 @@ # MapConstIterator `MapConstIterator` is a class for performing immutable iteration over a map. +The iteration order is arbitrary. ## 1. Template Parameters @@ -74,6 +75,9 @@ bool isInRange() const ``` Check whether the iterator is in range. +It is a runtime error to attempt to access a map entry through an iterator +for which `isInRange` evaluates to `false`. +In this case an assertion failure will occur. ### 4.6. operator* @@ -83,6 +87,9 @@ const EntryBase& operator*() const Return a `const` reference to the `EntryBase` object pointed to by the iterator. +If the iterator is not in range for the map, an assertion failure will occur. +It is not recommended to use this operation +after updating the map that the iterator points to. ### 4.7. operator-> @@ -92,3 +99,6 @@ const EntryBase* operator->() const Return a pointer to the `const EntryBase` object pointed to by the iterator. +If the iterator is not in range for the map, an assertion failure will occur. +It is not recommended to use this operation +after updating the map that the iterator points to. diff --git a/Fw/DataStructures/docs/SetConstIterator.md b/Fw/DataStructures/docs/SetConstIterator.md index bd81ae90795..52e0b055a26 100644 --- a/Fw/DataStructures/docs/SetConstIterator.md +++ b/Fw/DataStructures/docs/SetConstIterator.md @@ -1,6 +1,7 @@ # SetConstIterator `SetConstIterator` is a class for performing immutable iteration over a set. +The iteration order is arbitrary. ## 1. Template Parameters @@ -65,6 +66,9 @@ bool isInRange() const ``` Check whether the iterator is in range. +It is a runtime error to attempt to access a set element through an iterator +for which `isInRange` evaluates to `false`. +In this case an assertion failure will occur. ### 3.6. operator* @@ -74,6 +78,9 @@ const EntryBase& operator*() const Return a `const` reference to the `T` element pointed to by the iterator. +If the iterator is not in range for the map, an assertion failure will occur. +It is not recommended to use this operation +after updating the set that the iterator points to. ### 3.7. operator-> @@ -83,3 +90,6 @@ const EntryBase* operator->() const Return a pointer to the `const T` element pointed to by the iterator. +If the iterator is not in range for the map, an assertion failure will occur. +It is not recommended to use this operation +after updating the set that the iterator points to. From d516eeef0933f85db5889759b2eeaa0bc5d9f354 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 4 Aug 2025 17:48:14 -0700 Subject: [PATCH 429/458] Revise docs for Fw/DataStructures --- Fw/DataStructures/docs/ArraySet.md | 2 +- Fw/DataStructures/docs/ExternalArrayMap.md | 4 ++-- Fw/DataStructures/docs/ExternalArraySet.md | 10 +++++----- Fw/DataStructures/docs/ExternalFifoQueue.md | 10 ++++++---- Fw/DataStructures/docs/ExternalStack.md | 10 ++++++---- Fw/DataStructures/docs/MapConstIterator.md | 2 +- Fw/DataStructures/docs/SetBase.md | 8 ++++---- Fw/DataStructures/docs/SetConstIterator.md | 2 +- 8 files changed, 26 insertions(+), 22 deletions(-) diff --git a/Fw/DataStructures/docs/ArraySet.md b/Fw/DataStructures/docs/ArraySet.md index 2539996e98a..43d11feec40 100644 --- a/Fw/DataStructures/docs/ArraySet.md +++ b/Fw/DataStructures/docs/ArraySet.md @@ -132,7 +132,7 @@ Return `m_extSet.begin()`. _Example:_ ```c++ -using Set = ArraySet; +using Set = ArraySet; Set set; // Insert an element in the set const auto status = map.insert(42); diff --git a/Fw/DataStructures/docs/ExternalArrayMap.md b/Fw/DataStructures/docs/ExternalArrayMap.md index 7d75184ed02..48cdb32431a 100644 --- a/Fw/DataStructures/docs/ExternalArrayMap.md +++ b/Fw/DataStructures/docs/ExternalArrayMap.md @@ -85,7 +85,7 @@ ExternalArrayMap(ByteArray data, FwSizeType capacity) `data` must be aligned according to [`getByteArrayAlignment()`](#getByteArrayAlignment) and must -contain at least [`getByteArraySize(size)`](#getByteArraySize) bytes. +contain at least [`getByteArraySize(capacity)`](#getByteArraySize) bytes. Call `setStorage(data, capacity)`. @@ -391,7 +391,7 @@ void setStorage(ByteArray data, FwSizeType capacity) `data` must be aligned according to [`getByteArrayAlignment()`](#getByteArrayAlignment) and must -contain at least [`getByteArraySize(size)`](#getByteArraySize) bytes. +contain at least [`getByteArraySize(capacity)`](#getByteArraySize) bytes. 1. Call `m_entries.setStorage(data, capacity)`. diff --git a/Fw/DataStructures/docs/ExternalArraySet.md b/Fw/DataStructures/docs/ExternalArraySet.md index fc5ea4272d0..f6747db8099 100644 --- a/Fw/DataStructures/docs/ExternalArraySet.md +++ b/Fw/DataStructures/docs/ExternalArraySet.md @@ -26,7 +26,7 @@ as the set implementation. |Name|Definition| |----|----------| -|`ConstIterator`|Alias of [`MapConstIterator`](MapConstIterator.md)| +|`ConstIterator`|Alias of [`MapConstIterator`](MapConstIterator.md)| |`Entry`|Alias of [`SetOrMapImplEntry`](SetOrMapImplEntry.md)| The type `Nil` is defined [in this file](Nil.md). @@ -89,7 +89,7 @@ ExternalArraySet(ByteArray data, FwSizeType capacity) `data` must be aligned according to [`getByteArrayAlignment()`](#getByteArrayAlignment) and must -contain at least [`getByteArraySize(size)`](#getByteArraySize) bytes. +contain at least [`getByteArraySize(capacity)`](#getByteArraySize) bytes. Call `setStorage(data, capacity)`. @@ -176,7 +176,7 @@ Return `m_impl.begin()`. _Example:_ ```c++ -using Set = ExternalArraySet; +using Set = ExternalArraySet; constexpr FwSizeType capacity = 10; Set::Entry entries[capacity]; // Call the constructor providing backing storage @@ -220,7 +220,7 @@ Return `m_impl.end()`. _Example:_ ```c++ -using Set = ExternalArraySet; +using Set = ExternalArraySet; constexpr FwSizeType capacity = 10; Set::Entry entries[capacity]; // Call the constructor providing backing storage @@ -384,7 +384,7 @@ void setStorage(ByteArray data, FwSizeType capacity) `data` must be aligned according to [`getByteArrayAlignment()`](#getByteArrayAlignment) and must -contain at least [`getByteArraySize(size)`](#getByteArraySize) bytes. +contain at least [`getByteArraySize(capacity)`](#getByteArraySize) bytes. 1. Call `m_entries.setStorage(data, capacity)`. diff --git a/Fw/DataStructures/docs/ExternalFifoQueue.md b/Fw/DataStructures/docs/ExternalFifoQueue.md index 2ff4c97de0d..86e377db616 100644 --- a/Fw/DataStructures/docs/ExternalFifoQueue.md +++ b/Fw/DataStructures/docs/ExternalFifoQueue.md @@ -79,8 +79,8 @@ ExternalFifoQueue(ByteArray data, FwSizeType capacity) ``` `data` must be aligned according to -[`getByteArrayAlignment()`](#61-getbytearrayalignment) and must -contain at least [`getByteArraySize(size)`](#62-getbytearraysize) bytes. +[`getByteArrayAlignment()`](#getByteArrayAlignment) and must +contain at least [`getByteArraySize(capacity)`](#getByteArraySize) bytes. 1. Call `setStorage(data, capacity)`. @@ -219,8 +219,8 @@ void setStorage(ByteArray data, FwSizeType capacity) ``` `data` must be aligned according to -[`getByteArrayAlignment()`](#61-getbytearrayalignment) and must -contain at least [`getByteArraySize(size)`](#62-getbytearraysize) bytes. +[`getByteArrayAlignment()`](#getByteArrayAlignment) and must +contain at least [`getByteArraySize(capacity)`](#getByteArraySize) bytes. 1. Call `m_items.setStorage(data, capacity)`. @@ -372,6 +372,7 @@ ASSERT_EQ(queue.getCapacity(), capacity); ## 6. Public Static Functions + ### 6.1. getByteArrayAlignment ```c++ @@ -380,6 +381,7 @@ static constexpr U8 getByteArrayAlignment() Return `ExternalArray::getByteArrayAlignment()`. + ### 6.2. getByteArraySize ```c++ diff --git a/Fw/DataStructures/docs/ExternalStack.md b/Fw/DataStructures/docs/ExternalStack.md index 8d3341c0af9..98533e29994 100644 --- a/Fw/DataStructures/docs/ExternalStack.md +++ b/Fw/DataStructures/docs/ExternalStack.md @@ -75,8 +75,8 @@ ExternalStack(ByteArray data, FwSizeType capacity) ``` `data` must be aligned according to -[`getByteArrayAlignment()`](#61-getbytearrayalignment) and must -contain at least [`getByteArraySize(size)`](#62-getbytearraysize) bytes. +[`getByteArrayAlignment()`](#getByteArrayAlignment) and must +contain at least [`getByteArraySize(capacity)`](#getByteArraySize) bytes. 1. Call `setStorage(data, capacity)`. @@ -201,8 +201,8 @@ void setStorage(ByteArray data, FwSizeType capacity) ``` `data` must be aligned according to -[`getByteArrayAlignment()`](#61-getbytearrayalignment) and must -contain at least [`getByteArraySize(size)`](#62-getbytearraysize) bytes. +[`getByteArrayAlignment()`](#getByteArrayAlignment) and must +contain at least [`getByteArraySize(capacity)`](#getByteArraySize) bytes. 1. Call `m_items.setStorage(data, capacity)`. @@ -336,6 +336,7 @@ ASSERT_EQ(stack.getSize(), 1); ## 6. Public Static Functions + ### 6.1. getByteArrayAlignment ```c++ @@ -344,6 +345,7 @@ static constexpr U8 getByteArrayAlignment() Return `ExternalArray::getByteArrayAlignment()`. + ### 6.2. getByteArraySize ```c++ diff --git a/Fw/DataStructures/docs/MapConstIterator.md b/Fw/DataStructures/docs/MapConstIterator.md index 52e828cc83d..a1536810301 100644 --- a/Fw/DataStructures/docs/MapConstIterator.md +++ b/Fw/DataStructures/docs/MapConstIterator.md @@ -1,7 +1,7 @@ # MapConstIterator `MapConstIterator` is a class for performing immutable iteration over a map. -The iteration order is arbitrary. +The iteration order is not specified. ## 1. Template Parameters diff --git a/Fw/DataStructures/docs/SetBase.md b/Fw/DataStructures/docs/SetBase.md index afdff913438..c1dc1428109 100644 --- a/Fw/DataStructures/docs/SetBase.md +++ b/Fw/DataStructures/docs/SetBase.md @@ -18,7 +18,7 @@ The following elements are private and are defined `= delete`: 1. The copy constructor. ```c++ - SetBase(const SetBase& map) + SetBase(const SetBase& map) ``` 1. The assignment operator. @@ -64,7 +64,7 @@ Return the begin value of the iterator for the implementation. _Example:_ ```c++ -void f(SetBase& set) { +void f(SetBase& set) { set.clear(); // Insert an element in the set const auto status = set.insert(42); @@ -139,7 +139,7 @@ Return the end value of the iterator for the implementation. _Example:_ ```c++ -void f(SetBase& set) { +void f(SetBase& set) { set.clear(); // Insert an element in the set auto status = set.insert(42); @@ -224,7 +224,7 @@ virtual Success insert(const T& element) = 0 _Example:_ ```c++ -void f(SetBase& set) { +void f(SetBase& set) { set.clear(); auto size = set.getSize(); ASSERT_EQ(size, 0); diff --git a/Fw/DataStructures/docs/SetConstIterator.md b/Fw/DataStructures/docs/SetConstIterator.md index 52e0b055a26..87f8f7ac9a9 100644 --- a/Fw/DataStructures/docs/SetConstIterator.md +++ b/Fw/DataStructures/docs/SetConstIterator.md @@ -1,7 +1,7 @@ # SetConstIterator `SetConstIterator` is a class for performing immutable iteration over a set. -The iteration order is arbitrary. +The iteration order is not specified. ## 1. Template Parameters From a03792a90e148d55c3be7e27af0064f21a6087b6 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 5 Aug 2025 08:36:32 -0700 Subject: [PATCH 430/458] Revise Array and ExternalArray Add static assertions --- Fw/DataStructures/Array.hpp | 5 +++++ Fw/DataStructures/ExternalArray.hpp | 7 +++++++ Fw/DataStructures/docs/Array.md | 5 ++++- Fw/DataStructures/docs/ExternalArray.md | 2 ++ 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Fw/DataStructures/Array.hpp b/Fw/DataStructures/Array.hpp index 1a178b80b65..2508e4257e2 100644 --- a/Fw/DataStructures/Array.hpp +++ b/Fw/DataStructures/Array.hpp @@ -17,6 +17,11 @@ namespace Fw { template class Array final { + // ---------------------------------------------------------------------- + // Static assertions + // ---------------------------------------------------------------------- + + static_assert(std::is_default_constructible::value, "T must be default constructible"); static_assert(S > 0, "array size must be greater than zero"); public: diff --git a/Fw/DataStructures/ExternalArray.hpp b/Fw/DataStructures/ExternalArray.hpp index e55a5d3816c..5d05946ac03 100644 --- a/Fw/DataStructures/ExternalArray.hpp +++ b/Fw/DataStructures/ExternalArray.hpp @@ -8,6 +8,7 @@ #define Fw_ExternalArray_HPP #include +#include #include "Fw/FPrimeBasicTypes.hpp" #include "Fw/Types/Assert.hpp" @@ -17,6 +18,12 @@ namespace Fw { template class ExternalArray final { + // ---------------------------------------------------------------------- + // Static assertions + // ---------------------------------------------------------------------- + + static_assert(std::is_assignable::value, "T must be assignable to T&"); + public: // ---------------------------------------------------------------------- // Public constructors and destructors diff --git a/Fw/DataStructures/docs/Array.md b/Fw/DataStructures/docs/Array.md index 9f0078c2cdf..0dc09805062 100644 --- a/Fw/DataStructures/docs/Array.md +++ b/Fw/DataStructures/docs/Array.md @@ -14,7 +14,10 @@ It maintains the backing memory _M_ as a member variable. |`typename`|`T`|The type of an array element| |`FwSizeType`|`S`|The array size in elements| -`Array` statically asserts that `S > 0`. +`Array` statically asserts the following: + +* `T` is default constructible. +* `S > 0`. ## 2. Types diff --git a/Fw/DataStructures/docs/ExternalArray.md b/Fw/DataStructures/docs/ExternalArray.md index 12b0187f414..9aab84d950d 100644 --- a/Fw/DataStructures/docs/ExternalArray.md +++ b/Fw/DataStructures/docs/ExternalArray.md @@ -14,6 +14,8 @@ It stores a pointer to the backing memory _M_. |----|----|-------| |`typename`|`T`|The type of an array element| +`Array` statically asserts that `T` is assignable to `T&`. + ## 2. Private Member Variables `ExternalArray` has the following private member variables. From f263b84ef2057859bc24527107886183fb18cbaf Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 5 Aug 2025 08:47:01 -0700 Subject: [PATCH 431/458] Revise FifoQueue and Stack Add static assertions --- Fw/DataStructures/FifoQueue.hpp | 7 +++++++ Fw/DataStructures/Stack.hpp | 7 +++++++ Fw/DataStructures/docs/FifoQueue.md | 5 ++++- Fw/DataStructures/docs/Stack.md | 5 ++++- 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/FifoQueue.hpp b/Fw/DataStructures/FifoQueue.hpp index e24aa858fbe..050c09d366e 100644 --- a/Fw/DataStructures/FifoQueue.hpp +++ b/Fw/DataStructures/FifoQueue.hpp @@ -14,6 +14,13 @@ namespace Fw { template class FifoQueue final : public FifoQueueBase { + // ---------------------------------------------------------------------- + // Static assertions + // ---------------------------------------------------------------------- + + static_assert(std::is_default_constructible::value, "T must be default constructible"); + static_assert(C > 0, "capacity must be greater than zero"); + // ---------------------------------------------------------------------- // Friend class for testing // ---------------------------------------------------------------------- diff --git a/Fw/DataStructures/Stack.hpp b/Fw/DataStructures/Stack.hpp index b971bf5b1de..8e55b53b32e 100644 --- a/Fw/DataStructures/Stack.hpp +++ b/Fw/DataStructures/Stack.hpp @@ -14,6 +14,13 @@ namespace Fw { template class Stack final : public StackBase { + // ---------------------------------------------------------------------- + // Static assertions + // ---------------------------------------------------------------------- + + static_assert(std::is_default_constructible::value, "T must be default constructible"); + static_assert(C > 0, "capacity must be greater than zero"); + // ---------------------------------------------------------------------- // Friend class for testing // ---------------------------------------------------------------------- diff --git a/Fw/DataStructures/docs/FifoQueue.md b/Fw/DataStructures/docs/FifoQueue.md index 4e945b95e08..a8878db8209 100644 --- a/Fw/DataStructures/docs/FifoQueue.md +++ b/Fw/DataStructures/docs/FifoQueue.md @@ -13,7 +13,10 @@ It represents a FIFO queue with internal storage. |`typename`|`T`|The type of a queue item| |`FwSizeType`|`C`|The queue capacity in items| -`FifoQueue` statically asserts that `C > 0`. +`FifoQueue` statically asserts the following: + +* `T` is default constructible. +* `C > 0`. ## 2. Base Class diff --git a/Fw/DataStructures/docs/Stack.md b/Fw/DataStructures/docs/Stack.md index a081cc117ed..735274870e7 100644 --- a/Fw/DataStructures/docs/Stack.md +++ b/Fw/DataStructures/docs/Stack.md @@ -13,7 +13,10 @@ It represents a stack with internal storage. |`typename`|`T`|The type of a stack item| |`FwSizeType`|`C`|The stack capacity in items| -`Stack` statically asserts that `C > 0`. +`Stack` statically asserts the following: + +* `T` is default constructible. +* `C > 0`. ## 2. Base Class From ba173c7c0bef7f511d6ec96e55a00110724cd941 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 5 Aug 2025 09:13:11 -0700 Subject: [PATCH 432/458] Revise ArraySet and ArrayMap Add static assertions --- Fw/DataStructures/ArrayMap.hpp | 6 ++++++ Fw/DataStructures/ArraySet.hpp | 6 ++++++ Fw/DataStructures/SetOrMapImplEntry.hpp | 9 +++++++++ Fw/DataStructures/docs/SetOrMapImplEntry.md | 7 +++++++ 4 files changed, 28 insertions(+) diff --git a/Fw/DataStructures/ArrayMap.hpp b/Fw/DataStructures/ArrayMap.hpp index 0f487e2be3c..e5f1c9addc3 100644 --- a/Fw/DataStructures/ArrayMap.hpp +++ b/Fw/DataStructures/ArrayMap.hpp @@ -13,6 +13,12 @@ namespace Fw { template class ArrayMap final : public MapBase { + // ---------------------------------------------------------------------- + // Static assertions + // ---------------------------------------------------------------------- + + static_assert(C > 0, "capacity must be greater than zero"); + // ---------------------------------------------------------------------- // Friend class for testing // ---------------------------------------------------------------------- diff --git a/Fw/DataStructures/ArraySet.hpp b/Fw/DataStructures/ArraySet.hpp index e98078f48a0..0a2afc7a491 100644 --- a/Fw/DataStructures/ArraySet.hpp +++ b/Fw/DataStructures/ArraySet.hpp @@ -13,6 +13,12 @@ namespace Fw { template class ArraySet final : public SetBase { + // ---------------------------------------------------------------------- + // Static assertions + // ---------------------------------------------------------------------- + + static_assert(C > 0, "capacity must be greater than zero"); + // ---------------------------------------------------------------------- // Friend class for testing // ---------------------------------------------------------------------- diff --git a/Fw/DataStructures/SetOrMapImplEntry.hpp b/Fw/DataStructures/SetOrMapImplEntry.hpp index 4d23addfbcd..12661481c07 100644 --- a/Fw/DataStructures/SetOrMapImplEntry.hpp +++ b/Fw/DataStructures/SetOrMapImplEntry.hpp @@ -14,6 +14,15 @@ namespace Fw { template class SetOrMapImplEntry final : public MapEntryBase { + // ---------------------------------------------------------------------- + // Static assertions + // ---------------------------------------------------------------------- + + static_assert(std::is_default_constructible::value, "key must be default constructible"); + static_assert(std::is_assignable::value, "key or element must be assignable"); + static_assert(std::is_default_constructible::value, "value must be default constructible"); + static_assert(std::is_assignable::value, "value must be assignable"); + public: // ---------------------------------------------------------------------- // Public constructors and destructors diff --git a/Fw/DataStructures/docs/SetOrMapImplEntry.md b/Fw/DataStructures/docs/SetOrMapImplEntry.md index 126c0e4cdc3..cbb1274230a 100644 --- a/Fw/DataStructures/docs/SetOrMapImplEntry.md +++ b/Fw/DataStructures/docs/SetOrMapImplEntry.md @@ -13,6 +13,13 @@ It represents an iterator for a set or a map implementation. |`typename`|`KE`|The type of a key in a map or the element of a set| |`typename`|`VN`|The type of a value in a map or [`Nil`](Nil.md) in a set| +`SetOrMapImplEntry` statically asserts the following: + +* `KE` is default constructible. +* `KE` is assignable to `KE&`. +* `VN` is default constructible. +* `VN` is assignable to `VN&`. + ## 2. Base Class `SetOrMapImplEntry` is publicly derived from the following From 40d5aba19247f78a13e4aab4beb6c1f6c0e81a6e Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 5 Aug 2025 15:45:58 -0700 Subject: [PATCH 433/458] Revise ArrayMap tests --- Fw/DataStructures/test/ut/ArrayMapTest.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/Fw/DataStructures/test/ut/ArrayMapTest.cpp b/Fw/DataStructures/test/ut/ArrayMapTest.cpp index 6e505f43677..e4514e3e1d2 100644 --- a/Fw/DataStructures/test/ut/ArrayMapTest.cpp +++ b/Fw/DataStructures/test/ut/ArrayMapTest.cpp @@ -92,7 +92,6 @@ TEST(ArrayMap, CopyDataFrom) { } } -#if 0 TEST(ArrayMapScenarios, Clear) { Map map; State state(map); @@ -104,7 +103,6 @@ TEST(ArrayMapScenarios, Find) { State state(map); Scenarios::find(state); } -#endif TEST(ArrayMapScenarios, FindExisting) { Map map; From aa9351ff6988df6b13e3e08b0cb7ed90078d6382 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 7 Aug 2025 08:56:53 -0700 Subject: [PATCH 434/458] Revise ExternalArraySet tests --- Fw/DataStructures/test/ut/ExternalArraySetTest.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp index d1c809c4117..e5e794d50ba 100644 --- a/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArraySetTest.cpp @@ -100,21 +100,21 @@ TEST(ExternalArraySet, CopyDataFrom) { constexpr FwSizeType smallSize = maxSize / 2; Entry entries1[maxSize]; Entry entries2[maxSize]; - Set m1(entries1, maxSize); + Set s1(entries1, maxSize); // size1 < capacity2 { - Set m2(entries2, maxSize); - State::testCopyDataFrom(m1, smallSize, m2); + Set s2(entries2, maxSize); + State::testCopyDataFrom(s1, smallSize, s2); } // size1 == size2 { - Set m2(entries2, maxSize); - State::testCopyDataFrom(m1, maxSize, m2); + Set s2(entries2, maxSize); + State::testCopyDataFrom(s1, maxSize, s2); } // size1 > size2 { - Set m2(entries2, smallSize); - State::testCopyDataFrom(m1, maxSize, m2); + Set s2(entries2, smallSize); + State::testCopyDataFrom(s1, maxSize, s2); } } From aee439bbc1665107b7eecf0b53ef384138d2e45c Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 7 Aug 2025 09:35:53 -0700 Subject: [PATCH 435/458] Refactor ArraySetTest --- Fw/DataStructures/test/ut/ArraySetTest.cpp | 36 +++++++++++----------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Fw/DataStructures/test/ut/ArraySetTest.cpp b/Fw/DataStructures/test/ut/ArraySetTest.cpp index d902f0fce9e..7e6b0f29f8d 100644 --- a/Fw/DataStructures/test/ut/ArraySetTest.cpp +++ b/Fw/DataStructures/test/ut/ArraySetTest.cpp @@ -41,50 +41,50 @@ TEST(ArraySet, ZeroArgConstructor) { } TEST(ArraySet, CopyConstructor) { - Set m1; + Set s1; // Insert an item const State::ElementType e = 42; - const auto status = m1.insert(e); + const auto status = s1.insert(e); ASSERT_EQ(status, Success::SUCCESS); // Call the copy constructor - Set m2(m1); - ASSERT_EQ(m2.getSize(), 1); + Set s2(s1); + ASSERT_EQ(s2.getSize(), 1); } TEST(ArraySet, CopyAssignmentOperator) { - Set m1; + Set s1; // Insert an item const State::ElementType e = 42; - auto status = m1.insert(e); + auto status = s1.insert(e); ASSERT_EQ(status, Success::SUCCESS); // Call the default constructor - Set m2; - ASSERT_EQ(m2.getSize(), 0); + Set s2; + ASSERT_EQ(s2.getSize(), 0); // Call the copy assignment operator - m2 = m1; - ASSERT_EQ(m2.getSize(), 1); - status = m2.find(e); + s2 = s1; + ASSERT_EQ(s2.getSize(), 1); + status = s2.find(e); ASSERT_EQ(status, Success::SUCCESS); } TEST(ArraySet, CopyDataFrom) { constexpr FwSizeType maxSize = State::capacity; constexpr FwSizeType smallSize = maxSize / 2; - Set m1; + Set s1; // size1 < capacity2 { - Set m2; - State::testCopyDataFrom(m1, smallSize, m2); + Set s2; + State::testCopyDataFrom(s1, smallSize, s2); } // size1 == capacity2 { - Set m2; - State::testCopyDataFrom(m1, maxSize, m2); + Set s2; + State::testCopyDataFrom(s1, maxSize, s2); } // size1 > capacity2 { - ArraySet m2; - State::testCopyDataFrom(m1, maxSize, m2); + ArraySet s2; + State::testCopyDataFrom(s1, maxSize, s2); } } From d038dac3bb1c315efebceb8f3e63c3acca415aef Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 12 Aug 2025 16:13:04 -0700 Subject: [PATCH 436/458] Revise array initialization --- Fw/DataStructures/ExternalArray.hpp | 6 ++++++ Fw/DataStructures/docs/ExternalArray.md | 2 ++ Fw/DataStructures/test/ut/ExternalArrayTest.cpp | 10 ++++++---- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Fw/DataStructures/ExternalArray.hpp b/Fw/DataStructures/ExternalArray.hpp index 5d05946ac03..adb54599af3 100644 --- a/Fw/DataStructures/ExternalArray.hpp +++ b/Fw/DataStructures/ExternalArray.hpp @@ -8,6 +8,7 @@ #define Fw_ExternalArray_HPP #include +#include #include #include "Fw/FPrimeBasicTypes.hpp" @@ -128,6 +129,11 @@ class ExternalArray final { FW_ASSERT(size * sizeof(T) <= data.size); // Initialize the array members this->m_elements = reinterpret_cast(data.bytes); + // Construct the array members in place + for (FwSizeType i = 0; i < size; i++) { + (void)new (&this->m_elements[i]) T(); + } + // Set the size this->m_size = size; } diff --git a/Fw/DataStructures/docs/ExternalArray.md b/Fw/DataStructures/docs/ExternalArray.md index 9aab84d950d..0147d3888c8 100644 --- a/Fw/DataStructures/docs/ExternalArray.md +++ b/Fw/DataStructures/docs/ExternalArray.md @@ -258,6 +258,8 @@ and must contain at least [`getByteArraySize(size)`](#52-getbytearraysize) bytes 1. Initialize `m_elements` with `data.bytes`. +1. Construct the objects pointed to by `m_elements` in place. + 1. Initialize `m_size` with `size`. _Example:_ diff --git a/Fw/DataStructures/test/ut/ExternalArrayTest.cpp b/Fw/DataStructures/test/ut/ExternalArrayTest.cpp index 26a4df20adb..b240e9c130c 100644 --- a/Fw/DataStructures/test/ut/ExternalArrayTest.cpp +++ b/Fw/DataStructures/test/ut/ExternalArrayTest.cpp @@ -6,6 +6,7 @@ #include +#include "Fw/Buffer/Buffer.hpp" #include "Fw/DataStructures/ExternalArray.hpp" namespace Fw { @@ -26,12 +27,13 @@ TEST(ExternalArray, StorageConstructorTyped) { TEST(ExternalArray, StorageConstructorUntyped) { constexpr FwSizeType size = 3; - constexpr U8 alignment = ExternalArray::getByteArrayAlignment(); - constexpr FwSizeType byteArraySize = ExternalArray::getByteArraySize(size); + constexpr U8 alignment = ExternalArray::getByteArrayAlignment(); + constexpr FwSizeType byteArraySize = ExternalArray::getByteArraySize(size); alignas(alignment) U8 bytes[byteArraySize]; - ExternalArray a(ByteArray(&bytes[0], sizeof bytes), size); - ASSERT_EQ(a.getElements(), reinterpret_cast(&bytes[0])); + ExternalArray a(ByteArray(&bytes[0], sizeof bytes), size); + ASSERT_EQ(a.getElements(), reinterpret_cast(&bytes[0])); ASSERT_EQ(a.getSize(), size); + a[0] = Fw::Buffer(); } TEST(ExternalArray, CopyConstructor) { From e17d0dc0c32a5a31e4dcb72af82eb59d920e2593 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Tue, 12 Aug 2025 16:45:27 -0700 Subject: [PATCH 437/458] Revise comments --- Fw/DataStructures/ExternalArray.hpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Fw/DataStructures/ExternalArray.hpp b/Fw/DataStructures/ExternalArray.hpp index adb54599af3..89febae1b59 100644 --- a/Fw/DataStructures/ExternalArray.hpp +++ b/Fw/DataStructures/ExternalArray.hpp @@ -130,8 +130,12 @@ class ExternalArray final { // Initialize the array members this->m_elements = reinterpret_cast(data.bytes); // Construct the array members in place + // This step ensures that each array element holds a valid object + // into which we can assign data for (FwSizeType i = 0; i < size; i++) { - (void)new (&this->m_elements[i]) T(); + // This code trips an alignment check in clang-tidy + // However the alignment has been checked by FW_ASSERT above + (void)new (&this->m_elements[i]) T(); // NOLINT } // Set the size this->m_size = size; From e2fce44261152fdc30f0d9f9fd3cd26fa25232b4 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 14 Aug 2025 13:14:26 -0700 Subject: [PATCH 438/458] Revise Array initialization --- Fw/DataStructures/Array.hpp | 32 ++++++++++++++++--------- Fw/DataStructures/test/ut/ArrayTest.cpp | 12 +++------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/Fw/DataStructures/Array.hpp b/Fw/DataStructures/Array.hpp index 2508e4257e2..cdca6e1265d 100644 --- a/Fw/DataStructures/Array.hpp +++ b/Fw/DataStructures/Array.hpp @@ -7,8 +7,6 @@ #ifndef Fw_Array_HPP #define Fw_Array_HPP -#include - #include "Fw/DataStructures/ExternalArray.hpp" #include "Fw/FPrimeBasicTypes.hpp" #include "Fw/Types/Assert.hpp" @@ -40,16 +38,14 @@ class Array final { //! Zero-argument constructor Array() {} - //! Initializer list constructor - Array(const std::initializer_list& il //!< The initializer list + //! Array constructor + //! Use a template to enforce exact array size + //! Otherwise C++ may implicitly convert a smaller array to an array of size S + template + Array(const T (&elements)[S1] //!< The array ) { - FW_ASSERT(il.size() == S, static_cast(il.size()), static_cast(S)); - FwSizeType i = 0; - for (const auto& e : il) { - FW_ASSERT(i < S); - this->m_elements[i] = e; - i++; - } + static_assert(S1 == S, "array size must match"); + *this = elements; } //! Single-element constructor @@ -103,6 +99,20 @@ class Array final { return *this; } + //! Array assignment operator + //! Use a template to enforce exact array size + //! Otherwise C++ may implicitly convert a smaller array to an array of size S + //! \return *this + template + Array& operator=(const T (&elements)[S1] //!< The elements + ) { + static_assert(S1 == S, "array size must match"); + for (FwSizeType i = 0; i < S; i++) { + this->m_elements[i] = elements[i]; + } + return *this; + } + //! Get a mutable reference to the elements //! \return A mutable reference to the elements Elements& getElements() { return this->m_elements; } diff --git a/Fw/DataStructures/test/ut/ArrayTest.cpp b/Fw/DataStructures/test/ut/ArrayTest.cpp index 145d2ca5fe1..e77a278a3a8 100644 --- a/Fw/DataStructures/test/ut/ArrayTest.cpp +++ b/Fw/DataStructures/test/ut/ArrayTest.cpp @@ -17,17 +17,11 @@ TEST(Array, ZeroArgConstructor) { } } -TEST(Array, InitializerListConstructor) { - // Explicit call to constructor +TEST(Array, ArrayConstructor) { Array a({1, 2, 3}); for (FwSizeType i = 0; i < 3; i++) { ASSERT_EQ(a[i], i + 1); } - // Implicit call to constructor via initialization - Array b = {1, 2, 3}; - for (FwSizeType i = 0; i < 3; i++) { - ASSERT_EQ(b[i], i + 1); - } } TEST(Array, SingleElementConstructor) { @@ -54,7 +48,7 @@ TEST(Array, CopyConstructor) { } TEST(Array, Subscript) { - Array a = {0, 1, 2}; + Array a({0, 1, 2}); // Constant access ASSERT_EQ(a[1], 1); // Mutable access @@ -89,7 +83,7 @@ TEST(Array, GetElements) { } TEST(Array, AsExternalArray) { - Array a = {1, 2, 3}; + Array a({1, 2, 3}); ExternalArray ea = a.asExternalArray(); ASSERT_EQ(ea[0], 1); } From dbeb457ca8964b9b873533aca84f6259b567b9ee Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 14 Aug 2025 13:23:32 -0700 Subject: [PATCH 439/458] Revise Array design and implementation --- Fw/DataStructures/Array.hpp | 6 +--- Fw/DataStructures/docs/Array.md | 57 ++++++++++++++++++++++++++------- 2 files changed, 46 insertions(+), 17 deletions(-) diff --git a/Fw/DataStructures/Array.hpp b/Fw/DataStructures/Array.hpp index cdca6e1265d..7cd08251752 100644 --- a/Fw/DataStructures/Array.hpp +++ b/Fw/DataStructures/Array.hpp @@ -100,13 +100,9 @@ class Array final { } //! Array assignment operator - //! Use a template to enforce exact array size - //! Otherwise C++ may implicitly convert a smaller array to an array of size S //! \return *this - template - Array& operator=(const T (&elements)[S1] //!< The elements + Array& operator=(const Elements& elements //!< The elements ) { - static_assert(S1 == S, "array size must match"); for (FwSizeType i = 0; i < S; i++) { this->m_elements[i] = elements[i]; } diff --git a/Fw/DataStructures/docs/Array.md b/Fw/DataStructures/docs/Array.md index 0dc09805062..6dcff7ef302 100644 --- a/Fw/DataStructures/docs/Array.md +++ b/Fw/DataStructures/docs/Array.md @@ -47,22 +47,30 @@ _Example:_ Array a; ``` -### 4.2. Initializer List Constructor +### 4.2. Array Constructor ```c++ -Array(const std::initializer_list& il) +template Array(const T (&elements)[S1]) ``` -1. Assert that `il.size() == S`. +1. Statically assert that `S1 == S`. -1. Initialize `m_elements` from `il`. +1. Set `*this = elements`. -_Examples:_ +_Example:_ ```c++ -// Explicit call to constructor Array a({ 1, 2, 3 }); -// Implicit call to constructor via initialization -Array b = { 1, 2, 3 }; +``` + +Note that the template and the static assertion ensure that this code +will not compile: +```c++ +Array a({ 1, 2 }); +``` +Without the template and static assertion, C++ would interpret +that code as if it were equivalent to this: +```c++ +Array a({ 1, 2, 0 }); ``` ### 4.3. Single-Element Constructor @@ -132,15 +140,17 @@ ASSERT_EQ(a[0], 1); ASSERT_DEATH(a[size], "Assert"); ``` -### 5.2. operator= +### 5.2. operator= (Copy Assignment) ```c++ Array& operator=(const Array& a) ``` -1. If `&a != this`, overwrite each element of `m_elements` with the +1. If `&a != this`, overwrite each element of `m_elements` with the corresponding element of `a`. +1. Return `*this`. + _Example:_ ```c++ Array a1(1); @@ -148,7 +158,30 @@ Array a2(2); a1 = a2; ``` -### 5.3. getElements +### 5.3. operator= (Raw Array) + +```c++ +Array& operator=(const Elements& elements) +``` + +1. Statically assert that `S1 == S`. + +1. Copy each element of `elements` into the corresponding element of + `m_elements`. + +1. Return `*this`. + +_Example:_ +```c++ +U32 elements[3] = {}; +Array a = elements; +``` + +Note that without the template and the static assertion, C++ may +allow a shorter array as the argument to the operation. +See the note on the array constructor above. + +### 5.4. getElements ```c++ Elements& getElements() @@ -170,7 +203,7 @@ const auto& elements2 = a.getElements(); ASSERT_EQ(elements2[0], 1); ``` -### 5.4. asExternalArray +### 5.5. asExternalArray ```c++ ExternalArray asExternalArray() From 254dabb3e39df9028234232c394d2f9ae57e75f8 Mon Sep 17 00:00:00 2001 From: "Robert L. Bocchino Jr." Date: Thu, 14 Aug 2025 15:56:17 -0700 Subject: [PATCH 440/458] Revert changes to Fw/DataStructures --- Fw/DataStructures/Array.hpp | 28 +++++------- Fw/DataStructures/docs/Array.md | 57 ++++++------------------- Fw/DataStructures/test/ut/ArrayTest.cpp | 12 ++++-- 3 files changed, 32 insertions(+), 65 deletions(-) diff --git a/Fw/DataStructures/Array.hpp b/Fw/DataStructures/Array.hpp index 7cd08251752..2508e4257e2 100644 --- a/Fw/DataStructures/Array.hpp +++ b/Fw/DataStructures/Array.hpp @@ -7,6 +7,8 @@ #ifndef Fw_Array_HPP #define Fw_Array_HPP +#include + #include "Fw/DataStructures/ExternalArray.hpp" #include "Fw/FPrimeBasicTypes.hpp" #include "Fw/Types/Assert.hpp" @@ -38,14 +40,16 @@ class Array final { //! Zero-argument constructor Array() {} - //! Array constructor - //! Use a template to enforce exact array size - //! Otherwise C++ may implicitly convert a smaller array to an array of size S - template - Array(const T (&elements)[S1] //!< The array + //! Initializer list constructor + Array(const std::initializer_list& il //!< The initializer list ) { - static_assert(S1 == S, "array size must match"); - *this = elements; + FW_ASSERT(il.size() == S, static_cast(il.size()), static_cast(S)); + FwSizeType i = 0; + for (const auto& e : il) { + FW_ASSERT(i < S); + this->m_elements[i] = e; + i++; + } } //! Single-element constructor @@ -99,16 +103,6 @@ class Array final { return *this; } - //! Array assignment operator - //! \return *this - Array& operator=(const Elements& elements //!< The elements - ) { - for (FwSizeType i = 0; i < S; i++) { - this->m_elements[i] = elements[i]; - } - return *this; - } - //! Get a mutable reference to the elements //! \return A mutable reference to the elements Elements& getElements() { return this->m_elements; } diff --git a/Fw/DataStructures/docs/Array.md b/Fw/DataStructures/docs/Array.md index 6dcff7ef302..0dc09805062 100644 --- a/Fw/DataStructures/docs/Array.md +++ b/Fw/DataStructures/docs/Array.md @@ -47,30 +47,22 @@ _Example:_ Array a; ``` -### 4.2. Array Constructor +### 4.2. Initializer List Constructor ```c++ -template Array(const T (&elements)[S1]) +Array(const std::initializer_list& il) ``` -1. Statically assert that `S1 == S`. +1. Assert that `il.size() == S`. -1. Set `*this = elements`. +1. Initialize `m_elements` from `il`. -_Example:_ +_Examples:_ ```c++ +// Explicit call to constructor Array a({ 1, 2, 3 }); -``` - -Note that the template and the static assertion ensure that this code -will not compile: -```c++ -Array a({ 1, 2 }); -``` -Without the template and static assertion, C++ would interpret -that code as if it were equivalent to this: -```c++ -Array a({ 1, 2, 0 }); +// Implicit call to constructor via initialization +Array b = { 1, 2, 3 }; ``` ### 4.3. Single-Element Constructor @@ -140,17 +132,15 @@ ASSERT_EQ(a[0], 1); ASSERT_DEATH(a[size], "Assert"); ``` -### 5.2. operator= (Copy Assignment) +### 5.2. operator= ```c++ Array& operator=(const Array& a) ``` -1. If `&a != this`, overwrite each element of `m_elements` with the +1. If `&a != this`, overwrite each element of `m_elements` with the corresponding element of `a`. -1. Return `*this`. - _Example:_ ```c++ Array a1(1); @@ -158,30 +148,7 @@ Array a2(2); a1 = a2; ``` -### 5.3. operator= (Raw Array) - -```c++ -Array& operator=(const Elements& elements) -``` - -1. Statically assert that `S1 == S`. - -1. Copy each element of `elements` into the corresponding element of - `m_elements`. - -1. Return `*this`. - -_Example:_ -```c++ -U32 elements[3] = {}; -Array a = elements; -``` - -Note that without the template and the static assertion, C++ may -allow a shorter array as the argument to the operation. -See the note on the array constructor above. - -### 5.4. getElements +### 5.3. getElements ```c++ Elements& getElements() @@ -203,7 +170,7 @@ const auto& elements2 = a.getElements(); ASSERT_EQ(elements2[0], 1); ``` -### 5.5. asExternalArray +### 5.4. asExternalArray ```c++ ExternalArray asExternalArray() diff --git a/Fw/DataStructures/test/ut/ArrayTest.cpp b/Fw/DataStructures/test/ut/ArrayTest.cpp index e77a278a3a8..145d2ca5fe1 100644 --- a/Fw/DataStructures/test/ut/ArrayTest.cpp +++ b/Fw/DataStructures/test/ut/ArrayTest.cpp @@ -17,11 +17,17 @@ TEST(Array, ZeroArgConstructor) { } } -TEST(Array, ArrayConstructor) { +TEST(Array, InitializerListConstructor) { + // Explicit call to constructor Array a({1, 2, 3}); for (FwSizeType i = 0; i < 3; i++) { ASSERT_EQ(a[i], i + 1); } + // Implicit call to constructor via initialization + Array b = {1, 2, 3}; + for (FwSizeType i = 0; i < 3; i++) { + ASSERT_EQ(b[i], i + 1); + } } TEST(Array, SingleElementConstructor) { @@ -48,7 +54,7 @@ TEST(Array, CopyConstructor) { } TEST(Array, Subscript) { - Array a({0, 1, 2}); + Array a = {0, 1, 2}; // Constant access ASSERT_EQ(a[1], 1); // Mutable access @@ -83,7 +89,7 @@ TEST(Array, GetElements) { } TEST(Array, AsExternalArray) { - Array a({1, 2, 3}); + Array a = {1, 2, 3}; ExternalArray ea = a.asExternalArray(); ASSERT_EQ(ea[0], 1); } From 0e187aaf543d0c5c2b9eb48d809211ed28ec038a Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 14 Aug 2025 16:16:48 -0700 Subject: [PATCH 441/458] Revise Array --- Fw/DataStructures/Array.hpp | 65 ++++++++++++++++++++----- Fw/DataStructures/test/ut/ArrayTest.cpp | 16 +++++- 2 files changed, 67 insertions(+), 14 deletions(-) diff --git a/Fw/DataStructures/Array.hpp b/Fw/DataStructures/Array.hpp index 2508e4257e2..7a93f2b7ade 100644 --- a/Fw/DataStructures/Array.hpp +++ b/Fw/DataStructures/Array.hpp @@ -43,29 +43,29 @@ class Array final { //! Initializer list constructor Array(const std::initializer_list& il //!< The initializer list ) { - FW_ASSERT(il.size() == S, static_cast(il.size()), static_cast(S)); - FwSizeType i = 0; - for (const auto& e : il) { - FW_ASSERT(i < S); - this->m_elements[i] = e; - i++; - } + *this = il; + } + + //! Raw array constructor + //! We use a template to force the array size to match S + //! Without the template, C++ may accept a smaller size + template + Array(const T (&elements)[S1] //!< The array + ) { + static_assert(S1 == S, "array size must match"); + *this = elements; } //! Single-element constructor explicit Array(const T& element //!< The element ) { - for (FwSizeType i = 0; i < S; i++) { - this->m_elements[i] = element; - } + *this = element; } //! Copy constructor Array(const Array& a //!< The array to copy ) { - for (FwSizeType i = 0; i < S; i++) { - this->m_elements[i] = a.m_elements[i]; - } + *this = a; } //! Destructor @@ -92,6 +92,45 @@ class Array final { return this->m_elements[i]; } + //! operator= (initializer list) + //! \return *this + Array& operator=(const std::initializer_list& il //!< The initializer list + ) { + // Since we are required to use C++11, this has to be a runtime check + // In C++14, it can be a static check + FW_ASSERT(il.size() == S, static_cast(il.size()), static_cast(S)); + FwSizeType i = 0; + for (const auto& e : il) { + FW_ASSERT(i < S); + this->m_elements[i] = e; + i++; + } + return *this; + } + + //! operator= (raw array) + //! We use a template to force the array size to match S + //! Without the template, C++ may accept a smaller size + //! \return *this + template + Array& operator=(const T (&elements)[S1]) { + static_assert(S1 == S, "array size must match"); + for (FwSizeType i = 0; i < S; i++) { + this->m_elements[i] = elements[i]; + } + return *this; + } + + //! operator= (single element) + //! \return *this + Array& operator=(const T& element //!< The element + ) { + for (FwSizeType i = 0; i < S; i++) { + this->m_elements[i] = element; + } + return *this; + } + //! Copy assignment operator //! \return *this Array& operator=(const Array& a) { diff --git a/Fw/DataStructures/test/ut/ArrayTest.cpp b/Fw/DataStructures/test/ut/ArrayTest.cpp index 145d2ca5fe1..898df715f34 100644 --- a/Fw/DataStructures/test/ut/ArrayTest.cpp +++ b/Fw/DataStructures/test/ut/ArrayTest.cpp @@ -23,13 +23,27 @@ TEST(Array, InitializerListConstructor) { for (FwSizeType i = 0; i < 3; i++) { ASSERT_EQ(a[i], i + 1); } - // Implicit call to constructor via initialization + // Explicit call to constructor in assignment Array b = {1, 2, 3}; for (FwSizeType i = 0; i < 3; i++) { ASSERT_EQ(b[i], i + 1); } } +TEST(Array, RawArrayConstructor) { + // Explicit call to constructor + U32 elements[3] = { 1, 2, 3 }; + Array a(elements); + for (FwSizeType i = 0; i < 3; i++) { + ASSERT_EQ(a[i], i + 1); + } + // Explicit call to constructor in assignment + Array b = elements; + for (FwSizeType i = 0; i < 3; i++) { + ASSERT_EQ(b[i], i + 1); + } +} + TEST(Array, SingleElementConstructor) { // Explicit call to constructor in variable declaration Array a(1); From 8533ce32ac108610936ff5874a16fc6536ae043d Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 14 Aug 2025 16:25:03 -0700 Subject: [PATCH 442/458] Revise Array --- Fw/DataStructures/Array.hpp | 14 +++----------- Fw/DataStructures/test/ut/ArrayTest.cpp | 4 ++-- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/Fw/DataStructures/Array.hpp b/Fw/DataStructures/Array.hpp index 7a93f2b7ade..27dffc26efc 100644 --- a/Fw/DataStructures/Array.hpp +++ b/Fw/DataStructures/Array.hpp @@ -59,7 +59,9 @@ class Array final { //! Single-element constructor explicit Array(const T& element //!< The element ) { - *this = element; + for (FwSizeType i = 0; i < S; i++) { + this->m_elements[i] = element; + } } //! Copy constructor @@ -121,16 +123,6 @@ class Array final { return *this; } - //! operator= (single element) - //! \return *this - Array& operator=(const T& element //!< The element - ) { - for (FwSizeType i = 0; i < S; i++) { - this->m_elements[i] = element; - } - return *this; - } - //! Copy assignment operator //! \return *this Array& operator=(const Array& a) { diff --git a/Fw/DataStructures/test/ut/ArrayTest.cpp b/Fw/DataStructures/test/ut/ArrayTest.cpp index 898df715f34..ff4ae55d7e0 100644 --- a/Fw/DataStructures/test/ut/ArrayTest.cpp +++ b/Fw/DataStructures/test/ut/ArrayTest.cpp @@ -23,7 +23,7 @@ TEST(Array, InitializerListConstructor) { for (FwSizeType i = 0; i < 3; i++) { ASSERT_EQ(a[i], i + 1); } - // Explicit call to constructor in assignment + // Implicit call to constructor in assignment Array b = {1, 2, 3}; for (FwSizeType i = 0; i < 3; i++) { ASSERT_EQ(b[i], i + 1); @@ -37,7 +37,7 @@ TEST(Array, RawArrayConstructor) { for (FwSizeType i = 0; i < 3; i++) { ASSERT_EQ(a[i], i + 1); } - // Explicit call to constructor in assignment + // Implicit call to constructor in assignment Array b = elements; for (FwSizeType i = 0; i < 3; i++) { ASSERT_EQ(b[i], i + 1); From b075ec41ea4d44b79ba0c8ae258f554f889ff5eb Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 14 Aug 2025 16:50:00 -0700 Subject: [PATCH 443/458] Revise Array --- Fw/DataStructures/Array.hpp | 19 +++------ Fw/DataStructures/docs/Array.md | 68 ++++++++++++++++++++++++++++----- 2 files changed, 65 insertions(+), 22 deletions(-) diff --git a/Fw/DataStructures/Array.hpp b/Fw/DataStructures/Array.hpp index 27dffc26efc..7cd6fea4331 100644 --- a/Fw/DataStructures/Array.hpp +++ b/Fw/DataStructures/Array.hpp @@ -47,12 +47,8 @@ class Array final { } //! Raw array constructor - //! We use a template to force the array size to match S - //! Without the template, C++ may accept a smaller size - template - Array(const T (&elements)[S1] //!< The array + Array(const Elements& elements //!< The array elements ) { - static_assert(S1 == S, "array size must match"); *this = elements; } @@ -94,7 +90,7 @@ class Array final { return this->m_elements[i]; } - //! operator= (initializer list) + //! operator= (Initializer List) //! \return *this Array& operator=(const std::initializer_list& il //!< The initializer list ) { @@ -110,20 +106,17 @@ class Array final { return *this; } - //! operator= (raw array) - //! We use a template to force the array size to match S - //! Without the template, C++ may accept a smaller size + //! operator= (Raw Array) //! \return *this - template - Array& operator=(const T (&elements)[S1]) { - static_assert(S1 == S, "array size must match"); + Array& operator=(const Elements& elements //!< The array elements + ) { for (FwSizeType i = 0; i < S; i++) { this->m_elements[i] = elements[i]; } return *this; } - //! Copy assignment operator + //! operator= (Copy Assignment) //! \return *this Array& operator=(const Array& a) { if (&a != this) { diff --git a/Fw/DataStructures/docs/Array.md b/Fw/DataStructures/docs/Array.md index 0dc09805062..5900565d3ba 100644 --- a/Fw/DataStructures/docs/Array.md +++ b/Fw/DataStructures/docs/Array.md @@ -59,13 +59,26 @@ Array(const std::initializer_list& il) _Examples:_ ```c++ -// Explicit call to constructor Array a({ 1, 2, 3 }); -// Implicit call to constructor via initialization -Array b = { 1, 2, 3 }; ``` -### 4.3. Single-Element Constructor +### 4.3. Raw Array Constructor + +```c++ +Array(const Elements& elements) +``` + +1. Statically assert that `S1 == S`. + +1. Set `*this = elements`. + +_Example:_ +```c++ +U32 elements[3] = { 1, 2, 3 }; +Array a(elements); +``` + +### 4.4. Single-Element Constructor ```c++ explicit Array(const T& element) @@ -81,7 +94,7 @@ Array a(1); a = Array(2); ``` -### 4.4. Copy Constructor +### 4.5. Copy Constructor ```c++ Array(const Array& a) @@ -98,7 +111,7 @@ Array a1(3); Array a2(a1); ``` -### 4.5. Destructor +### 4.6. Destructor ```c++ ~Array() @@ -132,7 +145,42 @@ ASSERT_EQ(a[0], 1); ASSERT_DEATH(a[size], "Assert"); ``` -### 5.2. operator= +### 5.2. operator= (Initializer List) + +```c++ +Array& operator=(const std::initializer_list& il) +``` + +1. Assert that `il.size() == S`. + +1. Copy each element of `il` into `m_elements`. + +1. Return `*this`. + +_Example:_ +```c++ +Array a; +a = { 1, 2, 3 }; +``` + +### 5.3. operator= (Raw Array) + +```c++ +Array& operator=(const Elements& elements) +``` + +1. Copy each element of `elements` into `m_elements`. + +1. Return `*this`. + +_Example:_ +```c++ +U32 elements[3] = { 1, 2, 3 }; +Array a; +a = elements; +``` + +### 5.4. operator= (Copy Assignment) ```c++ Array& operator=(const Array& a) @@ -141,6 +189,8 @@ Array& operator=(const Array& a) 1. If `&a != this`, overwrite each element of `m_elements` with the corresponding element of `a`. +1. Return `*this`. + _Example:_ ```c++ Array a1(1); @@ -148,7 +198,7 @@ Array a2(2); a1 = a2; ``` -### 5.3. getElements +### 5.5. getElements ```c++ Elements& getElements() @@ -170,7 +220,7 @@ const auto& elements2 = a.getElements(); ASSERT_EQ(elements2[0], 1); ``` -### 5.4. asExternalArray +### 5.6. asExternalArray ```c++ ExternalArray asExternalArray() From 3bc57ac8c0b460fabb70a9cf321d28c6eab490e6 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 14 Aug 2025 16:59:48 -0700 Subject: [PATCH 444/458] Fix formatting --- Fw/DataStructures/test/ut/ArrayTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/test/ut/ArrayTest.cpp b/Fw/DataStructures/test/ut/ArrayTest.cpp index ff4ae55d7e0..fad97f1bf4f 100644 --- a/Fw/DataStructures/test/ut/ArrayTest.cpp +++ b/Fw/DataStructures/test/ut/ArrayTest.cpp @@ -32,7 +32,7 @@ TEST(Array, InitializerListConstructor) { TEST(Array, RawArrayConstructor) { // Explicit call to constructor - U32 elements[3] = { 1, 2, 3 }; + U32 elements[3] = {1, 2, 3}; Array a(elements); for (FwSizeType i = 0; i < 3; i++) { ASSERT_EQ(a[i], i + 1); From b90aa974d4c4b31f728f8073b645de0f8a700c6a Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 14 Aug 2025 17:18:57 -0700 Subject: [PATCH 445/458] Add SizedContainer base class --- Fw/DataStructures/FifoQueueBase.hpp | 17 +---- Fw/DataStructures/SizedContainer.hpp | 70 +++++++++++++++++++ .../test/ut/STest/FifoQueueTestRules.hpp | 14 ++-- 3 files changed, 80 insertions(+), 21 deletions(-) create mode 100644 Fw/DataStructures/SizedContainer.hpp diff --git a/Fw/DataStructures/FifoQueueBase.hpp b/Fw/DataStructures/FifoQueueBase.hpp index 17a124dcd5a..8fc94743dd6 100644 --- a/Fw/DataStructures/FifoQueueBase.hpp +++ b/Fw/DataStructures/FifoQueueBase.hpp @@ -7,14 +7,14 @@ #ifndef Fw_FifoQueueBase_HPP #define Fw_FifoQueueBase_HPP -#include "Fw/FPrimeBasicTypes.hpp" +#include "Fw/DataStructures/SizedContainer.hpp" #include "Fw/Types/Assert.hpp" #include "Fw/Types/SuccessEnumAc.hpp" namespace Fw { template -class FifoQueueBase { +class FifoQueueBase : public SizedContainer { private: // ---------------------------------------------------------------------- // Private constructors @@ -30,7 +30,7 @@ class FifoQueueBase { // ---------------------------------------------------------------------- //! Zero-argument constructor - FifoQueueBase() {} + FifoQueueBase() : SizedContainer() {} //! Destructor virtual ~FifoQueueBase() = default; @@ -50,9 +50,6 @@ class FifoQueueBase { // Public member functions // ---------------------------------------------------------------------- - //! Clear the queue - virtual void clear() = 0; - //! Get an item at an index. //! Indices go from left to right in the queue. //! Fails an assertion if the index is out of range. @@ -97,14 +94,6 @@ class FifoQueueBase { //! \return SUCCESS if item dequeued virtual Success dequeue(T& e //!< The item (output) ) = 0; - - //! Get the size (number of items stored in the queue) - //! \return The size - virtual FwSizeType getSize() const = 0; - - //! Get the capacity (maximum number of items stored in the queue) - //! \return The capacity - virtual FwSizeType getCapacity() const = 0; }; } // namespace Fw diff --git a/Fw/DataStructures/SizedContainer.hpp b/Fw/DataStructures/SizedContainer.hpp new file mode 100644 index 00000000000..cb256641291 --- /dev/null +++ b/Fw/DataStructures/SizedContainer.hpp @@ -0,0 +1,70 @@ +// ====================================================================== +// \title SizedContainer +// \author bocchino +// \brief An abstract base class representing a sized container +// ====================================================================== + +#ifndef Fw_SizedContainer_HPP +#define Fw_SizedContainer_HPP + +#include "Fw/FPrimeBasicTypes.hpp" + +namespace Fw { + +class SizedContainer { + private: + // ---------------------------------------------------------------------- + // Private constructors + // ---------------------------------------------------------------------- + + //! Copy constructor deleted in the base class + //! Behavior depends on the implementation + SizedContainer(const SizedContainer&) = delete; + + protected: + // ---------------------------------------------------------------------- + // Protected constructors and destructors + // ---------------------------------------------------------------------- + + //! Zero-argument constructor + SizedContainer() {} + + //! Destructor + virtual ~SizedContainer() = default; + + private: + // ---------------------------------------------------------------------- + // Private member functions + // ---------------------------------------------------------------------- + + //! operator= deleted in the base class + //! Behavior depends on the implementation + //! We avoid virtual user-defined operators + SizedContainer& operator=(const SizedContainer&) = delete; + + public: + // ---------------------------------------------------------------------- + // Public member functions + // ---------------------------------------------------------------------- + + //! Clear the container + virtual void clear() = 0; + + //! Get the size (number of items stored in the container) + //! \return The size + virtual FwSizeType getSize() const = 0; + + //! Get the capacity (maximum number of items storable in the container) + //! \return The capacity + virtual FwSizeType getCapacity() const = 0; + + //! Check whether the container is empty + bool isEmpty() const { return this->getSize() == 0; } + + //! Check whether the container is full + bool isFull() const { return this->getSize() >= this->getCapacity(); } +}; + +} // namespace Fw + +#endif diff --git a/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp index 8e3da526348..507d75f2f61 100644 --- a/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/FifoQueueTestRules.hpp @@ -21,7 +21,7 @@ namespace Rules { struct At : public Rule { At() : Rule("At") {} - bool precondition(const State& state) { return state.queue.getSize() > 0; } + bool precondition(const State& state) { return !state.queue.isEmpty(); } void action(State& state) { const auto index = STest::Pick::startLength(0, static_cast(state.queue.getSize())); ASSERT_EQ(state.queue.at(index), state.modelQueue.at(index)); @@ -30,7 +30,7 @@ struct At : public Rule { struct Clear : public Rule { Clear() : Rule("Clear") {} - bool precondition(const State& state) { return state.queue.getSize() > 0; } + bool precondition(const State& state) { return !state.queue.isEmpty(); } void action(State& state) { state.queue.clear(); ASSERT_EQ(state.queue.getSize(), 0); @@ -40,7 +40,7 @@ struct Clear : public Rule { struct DequeueEmpty : public Rule { DequeueEmpty() : Rule("DequeueEmpty") {} - bool precondition(const State& state) { return static_cast(state.queue.getSize()) == 0; } + bool precondition(const State& state) { return state.queue.isEmpty(); } void action(State& state) { State::ItemType item = 0; const auto status = state.queue.dequeue(item); @@ -50,7 +50,7 @@ struct DequeueEmpty : public Rule { struct DequeueOK : public Rule { DequeueOK() : Rule("DequeueOK") {} - bool precondition(const State& state) { return static_cast(state.queue.getSize()) > 0; } + bool precondition(const State& state) { return !state.queue.isEmpty(); } void action(State& state) { State::ItemType item = 0; const auto status = state.queue.dequeue(item); @@ -64,7 +64,7 @@ struct DequeueOK : public Rule { struct EnqueueFull : public Rule { EnqueueFull() : Rule("EnqueueFull") {} - bool precondition(const State& state) { return static_cast(state.queue.getSize()) >= State::capacity; } + bool precondition(const State& state) { return state.queue.isFull(); } void action(State& state) { const auto item = State::getRandomItem(); const auto status = state.queue.enqueue(item); @@ -74,7 +74,7 @@ struct EnqueueFull : public Rule { struct EnqueueOK : public Rule { EnqueueOK() : Rule("EnqueueOK") {} - bool precondition(const State& state) { return static_cast(state.queue.getSize()) < State::capacity; } + bool precondition(const State& state) { return !state.queue.isFull(); } void action(State& state) { const auto item = State::getRandomItem(); const auto status = state.queue.enqueue(item); @@ -85,7 +85,7 @@ struct EnqueueOK : public Rule { struct Peek : public Rule { Peek() : Rule("Peek") {} - bool precondition(const State& state) { return state.queue.getSize() > 0; } + bool precondition(const State& state) { return !state.queue.isEmpty(); } void action(State& state) { const auto index = STest::Pick::startLength(0, static_cast(state.queue.getSize())); State::ItemType item = 0; From f210181562651cede276fdb2b72ed460185be9e4 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 14 Aug 2025 17:23:20 -0700 Subject: [PATCH 446/458] Revise StackBase Make it inherit from SizedContainer Revise stack tests --- Fw/DataStructures/StackBase.hpp | 17 +++-------------- .../test/ut/STest/StackTestRules.hpp | 14 +++++++------- 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/Fw/DataStructures/StackBase.hpp b/Fw/DataStructures/StackBase.hpp index d3a8f951cdf..435a0ebfc13 100644 --- a/Fw/DataStructures/StackBase.hpp +++ b/Fw/DataStructures/StackBase.hpp @@ -7,14 +7,14 @@ #ifndef Fw_StackBase_HPP #define Fw_StackBase_HPP -#include "Fw/FPrimeBasicTypes.hpp" +#include "Fw/DataStructures/SizedContainer.hpp" #include "Fw/Types/Assert.hpp" #include "Fw/Types/SuccessEnumAc.hpp" namespace Fw { template -class StackBase { +class StackBase : public SizedContainer { private: // ---------------------------------------------------------------------- // Private constructors @@ -30,7 +30,7 @@ class StackBase { // ---------------------------------------------------------------------- //! Zero-argument constructor - StackBase() {} + StackBase() : SizedContainer() {} //! Destructor virtual ~StackBase() = default; @@ -50,9 +50,6 @@ class StackBase { // Public member functions // ---------------------------------------------------------------------- - //! Clear the stack - virtual void clear() = 0; - //! Get an item at an index. //! Index 0 is the rightmost (latest) element in the stack. //! Increasing indices go from right to left. @@ -98,14 +95,6 @@ class StackBase { //! \return SUCCESS if item popped virtual Success pop(T& e //!< The item (output) ) = 0; - - //! Get the size (number of items stored in the stack) - //! \return The size - virtual FwSizeType getSize() const = 0; - - //! Get the capacity (maximum number of items stored in the stack) - //! \return The capacity - virtual FwSizeType getCapacity() const = 0; }; } // namespace Fw diff --git a/Fw/DataStructures/test/ut/STest/StackTestRules.hpp b/Fw/DataStructures/test/ut/STest/StackTestRules.hpp index 2a6fea67bd7..a3cb99bb9f6 100644 --- a/Fw/DataStructures/test/ut/STest/StackTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/StackTestRules.hpp @@ -21,7 +21,7 @@ namespace Rules { struct At : public Rule { At() : Rule("At") {} - bool precondition(const State& state) { return state.stack.getSize() > 0; } + bool precondition(const State& state) { return !state.stack.isEmpty(); } void action(State& state) { const auto size = state.stack.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); @@ -31,7 +31,7 @@ struct At : public Rule { struct Clear : public Rule { Clear() : Rule("Clear") {} - bool precondition(const State& state) { return state.stack.getSize() > 0; } + bool precondition(const State& state) { return !state.stack.isEmpty(); } void action(State& state) { state.stack.clear(); ASSERT_EQ(state.stack.getSize(), 0); @@ -41,7 +41,7 @@ struct Clear : public Rule { struct Peek : public Rule { Peek() : Rule("Peek") {} - bool precondition(const State& state) { return state.stack.getSize() > 0; } + bool precondition(const State& state) { return !state.stack.isEmpty(); } void action(State& state) { const auto size = state.stack.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); @@ -54,7 +54,7 @@ struct Peek : public Rule { struct PopEmpty : public Rule { PopEmpty() : Rule("PopEmpty") {} - bool precondition(const State& state) { return static_cast(state.stack.getSize()) == 0; } + bool precondition(const State& state) { return state.stack.isEmpty(); } void action(State& state) { U32 value = 0; const auto status = state.stack.pop(value); @@ -64,7 +64,7 @@ struct PopEmpty : public Rule { struct PopOK : public Rule { PopOK() : Rule("PopOK") {} - bool precondition(const State& state) { return static_cast(state.stack.getSize()) > 0; } + bool precondition(const State& state) { return !state.stack.isEmpty(); } void action(State& state) { const auto size = state.stack.getSize(); U32 value = 0; @@ -79,7 +79,7 @@ struct PopOK : public Rule { struct PushFull : public Rule { PushFull() : Rule("PushFull") {} - bool precondition(const State& state) { return static_cast(state.stack.getSize()) >= State::capacity; } + bool precondition(const State& state) { return state.stack.isFull(); } void action(State& state) { const auto item = State::getRandomItem(); const auto status = state.stack.push(item); @@ -89,7 +89,7 @@ struct PushFull : public Rule { struct PushOK : public Rule { PushOK() : Rule("PushOK") {} - bool precondition(const State& state) { return static_cast(state.stack.getSize()) < State::capacity; } + bool precondition(const State& state) { return !state.stack.isFull(); } void action(State& state) { const U32 value = STest::Pick::any(); const auto status = state.stack.push(value); From 64a1690946377ef70d8496088e27489d25417025 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 14 Aug 2025 17:31:21 -0700 Subject: [PATCH 447/458] Revise MapBase Make it inherit from SizedContainer Revise tests --- Fw/DataStructures/MapBase.hpp | 16 +++------------- Fw/DataStructures/test/ut/STest/MapTestRules.hpp | 12 ++++++------ 2 files changed, 9 insertions(+), 19 deletions(-) diff --git a/Fw/DataStructures/MapBase.hpp b/Fw/DataStructures/MapBase.hpp index b25be633c90..b2a0fbd0a54 100644 --- a/Fw/DataStructures/MapBase.hpp +++ b/Fw/DataStructures/MapBase.hpp @@ -8,13 +8,14 @@ #define Fw_MapBase_HPP #include "Fw/DataStructures/MapConstIterator.hpp" +#include "Fw/DataStructures/SizedContainer.hpp" #include "Fw/Types/Assert.hpp" #include "Fw/Types/SuccessEnumAc.hpp" namespace Fw { template -class MapBase { +class MapBase : public SizedContainer { private: // ---------------------------------------------------------------------- // Deleted elements @@ -43,7 +44,7 @@ class MapBase { // ---------------------------------------------------------------------- //! Zero-argument constructor - MapBase() {} + MapBase() : SizedContainer() {} //! Destructor virtual ~MapBase() = default; @@ -57,9 +58,6 @@ class MapBase { //! \return The iterator virtual ConstIterator begin() const = 0; - //! Clear the map - virtual void clear() = 0; - //! Copy data from another map void copyDataFrom(const MapBase& map) { if (&map != this) { @@ -84,14 +82,6 @@ class MapBase { V& value //!< The value (output) ) const = 0; - //! Get the capacity (maximum number of items stored in the map) - //! \return The capacity - virtual FwSizeType getCapacity() const = 0; - - //! Get the size (number of items stored in the map) - //! \return The size - virtual FwSizeType getSize() const = 0; - //! Insert a (key, value) pair in the map //! \return SUCCESS if there is room in the map virtual Success insert(const K& key, //!< The key diff --git a/Fw/DataStructures/test/ut/STest/MapTestRules.hpp b/Fw/DataStructures/test/ut/STest/MapTestRules.hpp index 9319a828bef..6d8f48330b0 100644 --- a/Fw/DataStructures/test/ut/STest/MapTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/MapTestRules.hpp @@ -21,7 +21,7 @@ namespace Rules { struct Clear : public Rule { Clear() : Rule("Clear") {} - bool precondition(const State& state) { return state.map.getSize() > 0; } + bool precondition(const State& state) { return !state.map.isEmpty(); } void action(State& state) { state.map.clear(); ASSERT_EQ(state.map.getSize(), 0); @@ -47,7 +47,7 @@ struct Find : public Rule { struct FindExisting : public Rule { FindExisting() : Rule("FindExisting") {} - bool precondition(const State& state) { return static_cast(state.map.getSize()) > 0; } + bool precondition(const State& state) { return !state.map.isEmpty(); } void action(State& state) { for (auto& entry : state.map) { const auto key = entry.getKey(); @@ -62,7 +62,7 @@ struct FindExisting : public Rule { struct InsertExisting : public Rule { InsertExisting() : Rule("InsertExisting") {} - bool precondition(const State& state) { return static_cast(state.map.getSize()) > 0; } + bool precondition(const State& state) { return !state.map.isEmpty(); } void action(State& state) { const auto size = state.map.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); @@ -83,7 +83,7 @@ struct InsertExisting : public Rule { struct InsertFull : public Rule { InsertFull() : Rule("InsertFull") {} - bool precondition(const State& state) { return static_cast(state.map.getSize()) >= State::capacity; } + bool precondition(const State& state) { return state.map.isFull(); } void action(State& state) { const auto key = state.getKey(); const auto value = state.getValue(); @@ -97,7 +97,7 @@ struct InsertFull : public Rule { struct InsertNotFull : public Rule { InsertNotFull() : Rule("InsertNotFull") {} - bool precondition(const State& state) { return static_cast(state.map.getSize()) < State::capacity; } + bool precondition(const State& state) { return !state.map.isFull(); } void action(State& state) { const auto key = state.getKey(); const auto value = state.getValue(); @@ -134,7 +134,7 @@ struct Remove : public Rule { struct RemoveExisting : public Rule { RemoveExisting() : Rule("RemoveExisting") {} - bool precondition(const State& state) { return static_cast(state.map.getSize()) > 0; } + bool precondition(const State& state) { return !state.map.isEmpty(); } void action(State& state) { const auto size = state.map.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); From 438a1d8d6a06eae9f17ae3d5a0a097dd99ac04a1 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 14 Aug 2025 17:35:57 -0700 Subject: [PATCH 448/458] Revise SetBase Make it inherit from SizedContainer Revise tests --- Fw/DataStructures/SetBase.hpp | 16 +++------------- Fw/DataStructures/test/ut/STest/SetTestRules.hpp | 12 ++++++------ 2 files changed, 9 insertions(+), 19 deletions(-) diff --git a/Fw/DataStructures/SetBase.hpp b/Fw/DataStructures/SetBase.hpp index 870a913eb0b..8097abbd8a3 100644 --- a/Fw/DataStructures/SetBase.hpp +++ b/Fw/DataStructures/SetBase.hpp @@ -8,13 +8,14 @@ #define Fw_SetBase_HPP #include "Fw/DataStructures/SetConstIterator.hpp" +#include "Fw/DataStructures/SizedContainer.hpp" #include "Fw/Types/Assert.hpp" #include "Fw/Types/SuccessEnumAc.hpp" namespace Fw { template -class SetBase { +class SetBase : public SizedContainer { private: // ---------------------------------------------------------------------- // Deleted elements @@ -43,7 +44,7 @@ class SetBase { // ---------------------------------------------------------------------- //! Zero-argument constructor - SetBase() {} + SetBase() : SizedContainer() {} //! Destructor virtual ~SetBase() = default; @@ -57,9 +58,6 @@ class SetBase { //! \return The iterator virtual ConstIterator begin() const = 0; - //! Clear the set - virtual void clear() = 0; - //! Get the end iterator //! \return The iterator virtual ConstIterator end() const = 0; @@ -83,14 +81,6 @@ class SetBase { virtual Success find(const T& element //!< The element ) const = 0; - //! Get the capacity (maximum number of items stored in the set) - //! \return The capacity - virtual FwSizeType getCapacity() const = 0; - - //! Get the size (number of items stored in the set) - //! \return The size - virtual FwSizeType getSize() const = 0; - //! Insert an element in the set //! \return SUCCESS if there is room in the set virtual Success insert(const T& element //!< The element diff --git a/Fw/DataStructures/test/ut/STest/SetTestRules.hpp b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp index 7b551aee805..dc2b5636556 100644 --- a/Fw/DataStructures/test/ut/STest/SetTestRules.hpp +++ b/Fw/DataStructures/test/ut/STest/SetTestRules.hpp @@ -21,7 +21,7 @@ namespace Rules { struct Clear : public Rule { Clear() : Rule("Clear") {} - bool precondition(const State& state) { return state.set.getSize() > 0; } + bool precondition(const State& state) { return !state.set.isEmpty(); } void action(State& state) { state.set.clear(); ASSERT_EQ(state.set.getSize(), 0); @@ -42,7 +42,7 @@ struct Find : public Rule { struct FindExisting : public Rule { FindExisting() : Rule("FindExisting") {} - bool precondition(const State& state) { return static_cast(state.set.getSize()) > 0; } + bool precondition(const State& state) { return !state.set.isEmpty(); } void action(State& state) { // Check that sizes match const auto size = state.set.getSize(); @@ -66,7 +66,7 @@ struct FindExisting : public Rule { struct InsertExisting : public Rule { InsertExisting() : Rule("InsertExisting") {} - bool precondition(const State& state) { return static_cast(state.set.getSize()) > 0; } + bool precondition(const State& state) { return !state.set.isEmpty(); } void action(State& state) { const auto size = state.set.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); @@ -84,7 +84,7 @@ struct InsertExisting : public Rule { struct InsertFull : public Rule { InsertFull() : Rule("InsertFull") {} - bool precondition(const State& state) { return static_cast(state.set.getSize()) >= State::capacity; } + bool precondition(const State& state) { return state.set.isFull(); } void action(State& state) { const auto e = state.getElement(); const auto size = state.set.getSize(); @@ -97,7 +97,7 @@ struct InsertFull : public Rule { struct InsertNotFull : public Rule { InsertNotFull() : Rule("InsertNotFull") {} - bool precondition(const State& state) { return static_cast(state.set.getSize()) < State::capacity; } + bool precondition(const State& state) { return !state.set.isFull(); } void action(State& state) { const auto e = state.getElement(); const auto size = state.set.getSize(); @@ -131,7 +131,7 @@ struct Remove : public Rule { struct RemoveExisting : public Rule { RemoveExisting() : Rule("RemoveExisting") {} - bool precondition(const State& state) { return static_cast(state.set.getSize()) > 0; } + bool precondition(const State& state) { return !state.set.isEmpty(); } void action(State& state) { const auto size = state.set.getSize(); const auto index = STest::Pick::startLength(0, static_cast(size)); From 6ae5ba01ae81e5563cfb345d186011e5e7026ad9 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 14 Aug 2025 17:44:25 -0700 Subject: [PATCH 449/458] Revise DataStructures design Add SizedContainer --- Fw/DataStructures/SizedContainer.hpp | 2 + Fw/DataStructures/docs/SizedContainer.md | 134 +++++++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 Fw/DataStructures/docs/SizedContainer.md diff --git a/Fw/DataStructures/SizedContainer.hpp b/Fw/DataStructures/SizedContainer.hpp index cb256641291..977e1fc5d1f 100644 --- a/Fw/DataStructures/SizedContainer.hpp +++ b/Fw/DataStructures/SizedContainer.hpp @@ -59,9 +59,11 @@ class SizedContainer { virtual FwSizeType getCapacity() const = 0; //! Check whether the container is empty + //! \return True if the container is empty bool isEmpty() const { return this->getSize() == 0; } //! Check whether the container is full + //! \return True if the container is full bool isFull() const { return this->getSize() >= this->getCapacity(); } }; diff --git a/Fw/DataStructures/docs/SizedContainer.md b/Fw/DataStructures/docs/SizedContainer.md new file mode 100644 index 00000000000..3edfe0f1c27 --- /dev/null +++ b/Fw/DataStructures/docs/SizedContainer.md @@ -0,0 +1,134 @@ +# SizedContainer + +`SizedContainer` is a class template +defined in [`Fw/DataStructures`](sdd.md). +It is an abstract base class representing as sized container. + +## 1. Private Constructors + +### 1.1. Copy Constructor + +```c++ +SizedContainer(const SizedContainer& c) +``` + +Defined as `= delete`. + +## 2. Protected Constructors and Destructors + +### 2.1. Zero-Argument Constructor + +```c++ +SizedContainer() +``` + +Use default initialization of members. + +### 2.2. Destructor + +```c++ +virtual ~SizedContainer() +``` + +Defined as `= default`. + +## 3. Private Member Functions + +### 3.1. operator= + +```c++ +SizedContainer& operator=(const SizedContainer&) +``` + +Defined as `= delete`. + +## 4. Public Member Functions + +### 4.1. clear + +```c++ +virtual void clear() = 0 +``` + +Clear the container. + +_Example:_ +```c++ +void f(SizedContainer& c) { + c.clear(); + ASSERT_EQ(c.getSize(), 0); +} +``` + +### 4.2. getCapacity + +```c++ +virtual FwSizeType getCapacity() const = 0 +``` + +Return the current capacity. + +_Example:_ +```c++ +void f(const SizedContainer& c) { + const auto size = c.getSize(); + const auto capacity = c.getCapacity(); + ASSERT_LE(size, capacity); +} +``` + +### 4.3. getSize + +```c++ +virtual FwSizeType getSize() const = 0 +``` + +Return the current size. + +_Example:_ +```c++ +void f(const SizedContainer& c) { + c.clear(); + auto size = c.getSize(); + ASSERT_EQ(size, 0); +} +``` + +### 4.4. isEmpty + +```c++ +bool isEmpty() const +``` + +Return `true` if the container is empty. + +_Example:_ +```c++ +void f(const SizedContainer& c) { + if (c.size() == 0) { + ASSERT_TRUE(c.isEmpty()); + } else { + ASSERT_FALSE(c.isEmpty()); + } +} +``` + +### 4.5. isFull + +```c++ +bool isFull() const +``` + +Return `true` if the container is full. + +_Example:_ +```c++ +void f(const SizedContainer& c) { + if (c.size() >= c.capacity()) { + ASSERT_TRUE(c.isFull()); + } else { + ASSERT_FALSE(c.isFull()); + } +} +``` + From a30569972890c4679d9d0b410aa65d561f3ae5d0 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 14 Aug 2025 17:49:01 -0700 Subject: [PATCH 450/458] Revise SDD for DataStructures --- Fw/DataStructures/docs/sdd.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Fw/DataStructures/docs/sdd.md b/Fw/DataStructures/docs/sdd.md index 2fc1b2d3dc8..86a7820faa2 100644 --- a/Fw/DataStructures/docs/sdd.md +++ b/Fw/DataStructures/docs/sdd.md @@ -58,10 +58,14 @@ operations in last-in-first-out (LIFO) order. ```mermaid classDiagram + SizedContainer <|-- StackBase StackBase <|-- ExternalStack StackBase <|-- Stack ``` +`StackBase` is a derived class of [`SizedContainer`](SizedContainer.md), +which represents a generic container with a capacity and a size. + ## 3. FIFO Queues A **FIFO queue** is a data structure that @@ -88,10 +92,14 @@ You can use this template to represent any circular index. ```mermaid classDiagram + SizedContainer <|-- FifoQueueBase FifoQueueBase <|-- ExternalFifoQueue FifoQueueBase <|-- FifoQueue ``` +`FifoQueueBase` is a derived class of [`SizedContainer`](SizedContainer.md), +which represents a generic container with a capacity and a size. + ## 4. Maps A **map** is a data structure that associates keys to values. @@ -113,12 +121,16 @@ It provides insert, remove, and find operations. ```mermaid classDiagram + SizedContainer <|-- MapBase MapBase <|-- ArrayMap MapBase <|-- ExternalArrayMap MapBase <|-- ExternalRedBlackTreeMap MapBase <|-- RedBlackTreeMap ``` +`MapBase` is a derived class of [`SizedContainer`](SizedContainer.md), +which represents a generic container with a capacity and a size. + ## 5. Sets A **set** is a data structure that contains elements. @@ -138,8 +150,13 @@ It provides insert, remove, and find operations. ```mermaid classDiagram + SizedContainer <|-- SetBase SetBase <|-- ArraySet SetBase <|-- ExternalArraySet SetBase <|-- ExternalRedBlackTreeSet SetBase <|-- RedBlackTreeSet ``` + +`SetBase` is a derived class of [`SizedContainer`](SizedContainer.md), +which represents a generic container with a capacity and a size. + From b8d1471dffcdd9c5aefcb491a8cb012f6a8a740b Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 14 Aug 2025 17:52:50 -0700 Subject: [PATCH 451/458] Revise DataStructures design --- Fw/DataStructures/docs/FifoQueueBase.md | 84 +++++-------------------- Fw/DataStructures/docs/StackBase.md | 84 +++++-------------------- 2 files changed, 34 insertions(+), 134 deletions(-) diff --git a/Fw/DataStructures/docs/FifoQueueBase.md b/Fw/DataStructures/docs/FifoQueueBase.md index 49ca34b0fa8..2a38b1f4e6e 100644 --- a/Fw/DataStructures/docs/FifoQueueBase.md +++ b/Fw/DataStructures/docs/FifoQueueBase.md @@ -12,9 +12,13 @@ It represents an abstract base class for a FIFO queue. |----|----|-------| |`typename`|`T`|The type of an item on the queue| -## 2. Private Constructors +## 2. Base Class -### 2.1. Copy Constructor +`Stackbase` is publicly derived from [`SizedContainer`](SizedContainer.md). + +## 3. Private Constructors + +### 3.1. Copy Constructor ```c++ FifoQueueBase(const FifoQueueBase& queue) @@ -22,9 +26,9 @@ FifoQueueBase(const FifoQueueBase& queue) Defined as `= delete`. -## 3. Protected Constructors and Destructors +## 4. Protected Constructors and Destructors -### 3.1. Zero-Argument Constructor +### 4.1. Zero-Argument Constructor ```c++ FifoQueueBase() @@ -32,7 +36,7 @@ FifoQueueBase() Use default initialization of members. -### 3.2. Destructor +### 4.2. Destructor ```c++ virtual ~FifoQueueBase() @@ -40,9 +44,9 @@ virtual ~FifoQueueBase() Defined as `= default`. -## 4. Private Member Functions +## 5. Private Member Functions -### 4.1. operator= +### 5.1. operator= ```c++ FifoQueueBase& operator=(const FifoQueueBase&) @@ -50,9 +54,9 @@ FifoQueueBase& operator=(const FifoQueueBase&) Defined as `= delete`. -## 5. Public Member Functions +## 6. Public Member Functions -### 5.1. at +### 6.1. at ```c++ virtual const T& at(FwSizeType index) const = 0 @@ -77,23 +81,7 @@ void f(FifoQueueBase& queue) { } ``` -### 5.2. clear - -```c++ -virtual void clear() = 0 -``` - -Clear the queue. - -_Example:_ -```c++ -void f(FifoQueueBase& queue) { - queue.clear(); - ASSERT_EQ(queue.getSize(), 0); -} -``` - -### 5.3. copyDataFrom +### 6.2. copyDataFrom ```c++ void copyDataFrom(const FifoQueueBase& queue) @@ -128,7 +116,7 @@ void f(FifoQueueBase& q1, FifoQueueBase& q2) { } ``` -### 5.4. dequeue +### 6.3. dequeue ```c++ virtual Success dequeue(T& e) = 0 @@ -159,7 +147,7 @@ void f(FifoQueueBase& queue) { } ``` -### 5.5. enqueue +### 6.4. enqueue ```c++ virtual Success enqueue(const T& e) = 0 @@ -184,45 +172,7 @@ void f(FifoQueueBase& queue) { } ``` -### 5.6. getCapacity - -```c++ -virtual FwSizeType getCapacity() const = 0 -``` - -Return the current capacity. - -_Example:_ -```c++ -void f(const FifoQueueBase& queue) { - const auto size = queue.getSize(); - const auto capacity = queue.getCapacity(); - ASSERT_LE(size, capacity); -} -``` - -### 5.7. getSize - -```c++ -virtual FwSizeType getSize() const = 0 -``` - -Return the current size. - -_Example:_ -```c++ -void f(const FifoQueueBase& queue) { - queue.clear(); - 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); -} -``` - -### 5.8. peek +### 6.5. peek ```c++ Success peek(T& e, FwSizeType index = 0) const diff --git a/Fw/DataStructures/docs/StackBase.md b/Fw/DataStructures/docs/StackBase.md index aec66bb55e2..6f8a811cf30 100644 --- a/Fw/DataStructures/docs/StackBase.md +++ b/Fw/DataStructures/docs/StackBase.md @@ -12,9 +12,13 @@ It represents an abstract base class for a stack. |----|----|-------| |`typename`|`T`|The type of an item on the stack| -## 2. Private Constructors +## 2. Base Class -### 2.1. Copy Constructor +`Stackbase` is publicly derived from [`SizedContainer`](SizedContainer.md). + +## 3. Private Constructors + +### 3.1. Copy Constructor ```c++ StackBase(const StackBase& stack) @@ -22,9 +26,9 @@ StackBase(const StackBase& stack) Defined as `= delete`. -## 3. Protected Constructors and Destructors +## 4. Protected Constructors and Destructors -### 3.1. Zero-Argument Constructor +### 4.1. Zero-Argument Constructor ```c++ StackBase() @@ -32,7 +36,7 @@ StackBase() Use default initialization of members. -### 3.2. Destructor +### 4.2. Destructor ```c++ virtual ~StackBase() @@ -40,9 +44,9 @@ virtual ~StackBase() Defined as `= default`. -## 4. Private Member Functions +## 5. Private Member Functions -### 4.1. operator= +### 5.1. operator= ```c++ StackBase& operator=(const StackBase&) @@ -50,9 +54,9 @@ StackBase& operator=(const StackBase&) Defined as `= delete`. -## 5. Public Member Functions +## 6. Public Member Functions -### 5.1. at +### 6.1. at ```c++ virtual const T& at(FwSizeType index) const = 0 @@ -77,23 +81,7 @@ void f(StackBase& stack) { } ``` -### 5.2. clear - -```c++ -virtual void clear() = 0 -``` - -Clear the stack. - -_Example:_ -```c++ -void f(StackBase& stack) { - stack.clear(); - ASSERT_EQ(stack.getSize(), 0); -} -``` - -### 5.3. copyDataFrom +### 6.2. copyDataFrom ```c++ void copyDataFrom(const StackBase& stack) @@ -128,45 +116,7 @@ void f(StackBase& q1, StackBase& q2) { } ``` -### 5.4. getCapacity - -```c++ -virtual FwSizeType getCapacity() const = 0 -``` - -Return the current capacity. - -_Example:_ -```c++ -void f(const StackBase& stack) { - const auto size = stack.getSize(); - const auto capacity = stack.getCapacity(); - ASSERT_LE(size, capacity); -} -``` - -### 5.5. getSize - -```c++ -virtual FwSizeType getSize() const = 0 -``` - -Return the current size. - -_Example:_ -```c++ -void f(const StackBase& stack) { - stack.clear(); - 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); -} -``` - -### 5.6. peek +### 6.3. peek ```c++ Success peek(T& e, FwSizeType index = 0) const @@ -205,7 +155,7 @@ void f(StackBase& stack) { } ``` -### 5.7. pop +### 6.4. pop ```c++ virtual Success pop(T& e) = 0 @@ -236,7 +186,7 @@ void f(StackBase& stack) { } ``` -### 5.8. push +### 6.5. push ```c++ virtual Success push(const T& e) = 0 From 00decef438ddcbbee9c0cc37dd4bbc54f2d08238 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 14 Aug 2025 17:55:39 -0700 Subject: [PATCH 452/458] Revise DataStructures design --- Fw/DataStructures/docs/MapBase.md | 73 +++++++---------------------- Fw/DataStructures/docs/SetBase.md | 73 +++++++---------------------- Fw/DataStructures/docs/StackBase.md | 2 +- 3 files changed, 33 insertions(+), 115 deletions(-) diff --git a/Fw/DataStructures/docs/MapBase.md b/Fw/DataStructures/docs/MapBase.md index b57a3daf097..a627399c90c 100644 --- a/Fw/DataStructures/docs/MapBase.md +++ b/Fw/DataStructures/docs/MapBase.md @@ -13,7 +13,11 @@ It represents an abstract base class for a map. |`typename`|`K`|The type of a key in the map| |`typename`|`V`|The type of a value in the map| -## 2. Deleted Elements +## 2. Base Class + +`MapBase` is publicly derived from [`SizedContainer`](SizedContainer.md). + +## 3. Deleted Elements The following elements are private and are defined `= delete`: @@ -27,7 +31,7 @@ The following elements are private and are defined `= delete`: MapBase& operator=(const MapBase&) ``` -## 3. Public Types +## 4. Public Types `MapBase` defines the following public types: @@ -35,9 +39,9 @@ The following elements are private and are defined `= delete`: |----|----------| |`ConstIterator`|Alias of [`MapConstIterator`](MapConstIterator.md)| -## 4. Protected Constructors and Destructors +## 5. Protected Constructors and Destructors -### 4.1. Zero-Argument Constructor +### 5.1. Zero-Argument Constructor ```c++ MapBase() @@ -45,7 +49,7 @@ MapBase() Use default initialization of members. -### 4.2. Destructor +### 5.2. Destructor ```c++ virtual ~MapBase() @@ -53,9 +57,9 @@ virtual ~MapBase() Defined as `= default`. -## 5. Public Member Functions +## 6. Public Member Functions -### 5.1. begin +### 6.1. begin ```c++ virtual ConstIterator begin() const = 0. @@ -80,23 +84,7 @@ void f(MapBase& map) { } ``` -### 5.2. clear - -```c++ -virtual void clear() = 0 -``` - -Clear the map. - -_Example:_ -```c++ -void f(MapBase& map) { - map.clear(); - ASSERT_EQ(map.getSize(), 0); -} -``` - -### 5.3. copyDataFrom +### 6.2. copyDataFrom ```c++ void copyDataFrom(const MapBase& map) @@ -134,7 +122,7 @@ void f(MapBase& m1, MapBase& m2) { } ``` -### 5.4. end +### 6.3. end ```c++ virtual ConstIterator end() const = 0 @@ -160,7 +148,7 @@ void f(MapBase& map) { } ``` -### 5.5. find +### 6.4. find ```c++ virtual Success find(const K& key, V& value) const = 0 @@ -186,36 +174,7 @@ void f(const MapBase& map) { } ``` - -### 5.6. getCapacity - -```c++ -virtual FwSizeType getCapacity() const = 0 -``` - -Return the current capacity. - -_Example:_ -```c++ -void f(const MapBase& map) { - const auto size = map.getSize(); - const auto capacity = map.getCapacity(); - ASSERT_LE(size, capacity); -} -``` - -### 5.7. getSize - -```c++ -virtual FwSizeType getSize() const = 0 -``` - -Return the current size. - -_Example:_ -See [**getCapacity**](MapBase.md#getCapacity). - -### 5.8. insert +### 6.5. insert ```c++ virtual Success insert(const K& key, const V& value) = 0 @@ -242,7 +201,7 @@ void f(MapBase& map) { } ``` -### 5.9. remove +### 6.6. remove ```c++ virtual Success remove(const K& key, V& value) = 0 diff --git a/Fw/DataStructures/docs/SetBase.md b/Fw/DataStructures/docs/SetBase.md index c1dc1428109..9d1aa38989a 100644 --- a/Fw/DataStructures/docs/SetBase.md +++ b/Fw/DataStructures/docs/SetBase.md @@ -12,7 +12,11 @@ It represents an abstract base class for a set. |----|----|-------| |`typename`|`T`|The type of an element in the set| -## 2. Deleted Elements +## 2. Base Class + +`SetBase` is publicly derived from [`SizedContainer`](SizedContainer.md). + +## 3. Deleted Elements The following elements are private and are defined `= delete`: @@ -26,7 +30,7 @@ The following elements are private and are defined `= delete`: SetBase& operator=(const SetBase&) ``` -## 3. Public Types +## 4. Public Types `SetBase` defines the following public types: @@ -34,9 +38,9 @@ The following elements are private and are defined `= delete`: |----|----------| |`ConstIterator`|Alias of [`SetConstIterator`](SetConstIterator.md)| -## 4. Protected Constructors and Destructors +## 5. Protected Constructors and Destructors -### 4.1. Zero-Argument Constructor +### 5.1. Zero-Argument Constructor ```c++ SetBase() @@ -44,7 +48,7 @@ SetBase() Use default initialization of members. -### 4.2. Destructor +### 5.2. Destructor ```c++ virtual ~SetBase() @@ -52,9 +56,9 @@ virtual ~SetBase() Defined as `= default`. -## 5. Public Member Functions +## 6. Public Member Functions -### 5.1. begin +### 6.1. begin ```c++ virtual ConstIterator begin() const = 0. @@ -76,23 +80,7 @@ void f(SetBase& set) { } ``` -### 5.2. clear - -```c++ -virtual void clear() = 0 -``` - -Call `m_setImpl.clear()`. - -_Example:_ -```c++ -void f(SetBase& set) { - set.clear(); - ASSERT_EQ(set.getSize(), 0); -} -``` - -### 5.3. copyDataFrom +### 6.2. copyDataFrom ```c++ void copyDataFrom(const SetBase& set) @@ -129,7 +117,7 @@ void f(SetBase& s1, SetBase& s2) { } ``` -### 5.4. end +### 6.3. end ```c++ virtual ConstIterator end() const = 0 @@ -155,7 +143,7 @@ void f(SetBase& set) { } ``` -### 5.5. find +### 6.4. find ```c++ virtual Success find(const T& element) = 0 @@ -180,36 +168,7 @@ void f(const SetBase& set) { } ``` - -### 5.6. getCapacity - -```c++ -virtual FwSizeType getCapacity() const = 0 -``` - -Return the current capacity. - -_Example:_ -```c++ -void f(const SetBase& set) { - const auto size = set.getSize(); - const auto capacity = set.getCapacity(); - ASSERT_LE(size, capacity); -} -``` - -### 5.7. getSize - -```c++ -virtual FwSizeType getSize() const = 0 -``` - -Return the current size. - -_Example:_ -See [**getCapacity**](#getCapacity). - -### 5.8. insert +### 6.5. insert ```c++ virtual Success insert(const T& element) = 0 @@ -235,7 +194,7 @@ void f(SetBase& set) { } ``` -### 5.9. remove +### 6.6. remove ```c++ virtual Success remove(const T& element) = 0 diff --git a/Fw/DataStructures/docs/StackBase.md b/Fw/DataStructures/docs/StackBase.md index 6f8a811cf30..8448c892486 100644 --- a/Fw/DataStructures/docs/StackBase.md +++ b/Fw/DataStructures/docs/StackBase.md @@ -14,7 +14,7 @@ It represents an abstract base class for a stack. ## 2. Base Class -`Stackbase` is publicly derived from [`SizedContainer`](SizedContainer.md). +`StackBase` is publicly derived from [`SizedContainer`](SizedContainer.md). ## 3. Private Constructors From 73c9f648279bf0a9bf8539bdc1059dfa1e5ec12f Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 14 Aug 2025 17:57:15 -0700 Subject: [PATCH 453/458] Revise DataStructures design --- Fw/DataStructures/docs/SizedContainer.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/docs/SizedContainer.md b/Fw/DataStructures/docs/SizedContainer.md index 3edfe0f1c27..0087b997d52 100644 --- a/Fw/DataStructures/docs/SizedContainer.md +++ b/Fw/DataStructures/docs/SizedContainer.md @@ -1,8 +1,8 @@ # SizedContainer -`SizedContainer` is a class template +`SizedContainer` is a class defined in [`Fw/DataStructures`](sdd.md). -It is an abstract base class representing as sized container. +It is an abstract class representing a sized container. ## 1. Private Constructors From 44ac8ccc40407a4617a2629e1c17cd50dfcdb6b1 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Fri, 15 Aug 2025 07:49:34 -0700 Subject: [PATCH 454/458] Revise DataStructures design --- Fw/DataStructures/docs/sdd.md | 1 - 1 file changed, 1 deletion(-) diff --git a/Fw/DataStructures/docs/sdd.md b/Fw/DataStructures/docs/sdd.md index 86a7820faa2..5973453b78a 100644 --- a/Fw/DataStructures/docs/sdd.md +++ b/Fw/DataStructures/docs/sdd.md @@ -159,4 +159,3 @@ classDiagram `SetBase` is a derived class of [`SizedContainer`](SizedContainer.md), which represents a generic container with a capacity and a size. - From 81ce350244deace21b3ee92f0db62731cdc3959f Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Fri, 15 Aug 2025 07:55:57 -0700 Subject: [PATCH 455/458] Fix spelling --- Fw/DataStructures/docs/FifoQueueBase.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/docs/FifoQueueBase.md b/Fw/DataStructures/docs/FifoQueueBase.md index 2a38b1f4e6e..4053f6b1811 100644 --- a/Fw/DataStructures/docs/FifoQueueBase.md +++ b/Fw/DataStructures/docs/FifoQueueBase.md @@ -14,7 +14,7 @@ It represents an abstract base class for a FIFO queue. ## 2. Base Class -`Stackbase` is publicly derived from [`SizedContainer`](SizedContainer.md). +`FifoQueueBase` is publicly derived from [`SizedContainer`](SizedContainer.md). ## 3. Private Constructors From 0c8a3725c6d0df77881c27ec40bb89b6076e2d91 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Mon, 18 Aug 2025 17:54:37 -0700 Subject: [PATCH 456/458] Revise zero-arg constructor for Array --- Fw/DataStructures/Array.hpp | 2 +- Fw/DataStructures/docs/Array.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Fw/DataStructures/Array.hpp b/Fw/DataStructures/Array.hpp index 7cd6fea4331..d66189f5660 100644 --- a/Fw/DataStructures/Array.hpp +++ b/Fw/DataStructures/Array.hpp @@ -38,7 +38,7 @@ class Array final { // ---------------------------------------------------------------------- //! Zero-argument constructor - Array() {} + Array() = default; //! Initializer list constructor Array(const std::initializer_list& il //!< The initializer list diff --git a/Fw/DataStructures/docs/Array.md b/Fw/DataStructures/docs/Array.md index 5900565d3ba..6d3120a6b87 100644 --- a/Fw/DataStructures/docs/Array.md +++ b/Fw/DataStructures/docs/Array.md @@ -40,7 +40,7 @@ It is an alias of `T[S]`. Array() ``` -Initialize each element of `m_elements` with the default value for `T`. +Defined as `= default`. _Example:_ ```c++ From 26b6f4f3b4450f3253959038638c7fba2fa30933 Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Wed, 20 Aug 2025 14:52:55 -0700 Subject: [PATCH 457/458] Revise Array interface Make it consistent with the arrays generated by FPP --- Fw/DataStructures/Array.hpp | 21 ++++++++++++++------- Fw/DataStructures/docs/Array.md | 26 +++++++++++++++++++++----- 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/Fw/DataStructures/Array.hpp b/Fw/DataStructures/Array.hpp index d66189f5660..bb5335f3b7a 100644 --- a/Fw/DataStructures/Array.hpp +++ b/Fw/DataStructures/Array.hpp @@ -46,7 +46,7 @@ class Array final { *this = il; } - //! Raw array constructor + //! Primitive array constructor Array(const Elements& elements //!< The array elements ) { *this = elements; @@ -55,9 +55,7 @@ class Array final { //! Single-element constructor explicit Array(const T& element //!< The element ) { - for (FwSizeType i = 0; i < S; i++) { - this->m_elements[i] = element; - } + *this = element; } //! Copy constructor @@ -90,7 +88,7 @@ class Array final { return this->m_elements[i]; } - //! operator= (Initializer List) + //! operator= (initializer list) //! \return *this Array& operator=(const std::initializer_list& il //!< The initializer list ) { @@ -106,7 +104,7 @@ class Array final { return *this; } - //! operator= (Raw Array) + //! operator= (primitive array) //! \return *this Array& operator=(const Elements& elements //!< The array elements ) { @@ -116,7 +114,16 @@ class Array final { return *this; } - //! operator= (Copy Assignment) + //! operator= (single element) + Array& operator=(const T& element //!< The element + ) { + for (FwSizeType i = 0; i < S; i++) { + this->m_elements[i] = element; + } + return *this; + } + + //! operator= (copy assignment) //! \return *this Array& operator=(const Array& a) { if (&a != this) { diff --git a/Fw/DataStructures/docs/Array.md b/Fw/DataStructures/docs/Array.md index 6d3120a6b87..361051ed1f8 100644 --- a/Fw/DataStructures/docs/Array.md +++ b/Fw/DataStructures/docs/Array.md @@ -62,7 +62,7 @@ _Examples:_ Array a({ 1, 2, 3 }); ``` -### 4.3. Raw Array Constructor +### 4.3. Primitive Array Constructor ```c++ Array(const Elements& elements) @@ -163,7 +163,7 @@ Array a; a = { 1, 2, 3 }; ``` -### 5.3. operator= (Raw Array) +### 5.3. operator= (Primitive Array) ```c++ Array& operator=(const Elements& elements) @@ -180,7 +180,23 @@ Array a; a = elements; ``` -### 5.4. operator= (Copy Assignment) +### 5.4. operator= (Single Element) + +```c++ +Array& operator=(const T& element) +``` + +1. Copy `element` into each element of `m_elements`. + +1. Return `*this`. + +_Example:_ +```c++ +Array a; +a = 5; +``` + +### 5.5. operator= (Copy Assignment) ```c++ Array& operator=(const Array& a) @@ -198,7 +214,7 @@ Array a2(2); a1 = a2; ``` -### 5.5. getElements +### 5.6. getElements ```c++ Elements& getElements() @@ -220,7 +236,7 @@ const auto& elements2 = a.getElements(); ASSERT_EQ(elements2[0], 1); ``` -### 5.6. asExternalArray +### 5.7. asExternalArray ```c++ ExternalArray asExternalArray() From 7ecc4be85239bac8a80567107e4bb2f8cca6c13c Mon Sep 17 00:00:00 2001 From: Rob Bocchino Date: Thu, 21 Aug 2025 10:55:34 -0700 Subject: [PATCH 458/458] Fix to assertion --- Fw/DataStructures/Array.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fw/DataStructures/Array.hpp b/Fw/DataStructures/Array.hpp index bb5335f3b7a..a1fc99a2150 100644 --- a/Fw/DataStructures/Array.hpp +++ b/Fw/DataStructures/Array.hpp @@ -97,7 +97,7 @@ class Array final { FW_ASSERT(il.size() == S, static_cast(il.size()), static_cast(S)); FwSizeType i = 0; for (const auto& e : il) { - FW_ASSERT(i < S); + FW_ASSERT(i < S, static_cast(i), static_cast(S)); this->m_elements[i] = e; i++; }