GCC Code Coverage Report


Directory: ./
File: Fw/DataStructures/CircularIndex.hpp
Date: 2026-09-23 22:11:34
Exec Total Coverage
Lines: 9 24 37.5%
Functions: 3 7 42.9%
Branches: 0 4 0.0%

Line Branch Exec Source
1 // ======================================================================
2 // \file CircularIndex.hpp
3 // \author bocchino
4 // \brief An index value that wraps around modulo an integer
5 // ======================================================================
6
7 #ifndef Fw_CircularIndex_HPP
8 #define Fw_CircularIndex_HPP
9
10 #include "Fw/FPrimeBasicTypes.hpp"
11 #include "Fw/Types/Assert.hpp"
12
13 namespace Fw {
14
15 class CircularIndex final {
16 public:
17 // ----------------------------------------------------------------------
18 // Public constructors and destructors
19 // ----------------------------------------------------------------------
20
21 //! Zero-argument constructor
22 2 CircularIndex() : m_value(0), m_modulus(1) {}
23
24 //! Constructor with specified members
25 explicit CircularIndex(FwSizeType modulus, //!< The modulus
26 FwSizeType value = 0 //!< The initial value
27 )
28 : m_modulus(modulus) {
29 FW_ASSERT(modulus > 0);
30 this->setValue(value);
31 }
32
33 //! Copy constructor
34 ✗ CircularIndex(const CircularIndex& ci) { *this = ci; }
35
36 //! Destructor
37 ~CircularIndex() = default;
38
39 public:
40 // ----------------------------------------------------------------------
41 // Public functions
42 // ----------------------------------------------------------------------
43
44 //! operator=
45 ✗ CircularIndex& operator=(const CircularIndex& ci) {
46 ✗ if (this != &ci) {
47 ✗ this->m_value = ci.m_value;
48 ✗ this->m_modulus = ci.m_modulus;
49 }
50 ✗ return *this;
51 }
52
53 //! Get the index value
54 //! \return The index value
55 ✗ FwSizeType getValue() const {
56 ✗ FW_ASSERT(this->m_value < this->m_modulus);
57 ✗ return this->m_value;
58 }
59
60 //! Set the index value
61 4 void setValue(FwSizeType value //!< The index value
62 ) {
63 4 FW_ASSERT(this->m_modulus > 0);
64 4 this->m_value = value % this->m_modulus;
65 4 }
66
67 //! Get the modulus
68 FwSizeType getModulus() const {
69 FW_ASSERT(this->m_value < this->m_modulus);
70 return this->m_modulus;
71 }
72
73 //! Set the modulus
74 2 void setModulus(FwSizeType modulus //!< The modulus value
75 ) {
76 2 this->m_modulus = modulus;
77 2 this->setValue(this->m_value);
78 2 }
79
80 //! Increment the index value
81 //! \return The new value
82 ✗ FwSizeType increment(FwSizeType amount = 1 //!< The amount by which to increment
83 ) {
84 ✗ FW_ASSERT(this->m_modulus > 0);
85 ✗ const FwSizeType offset = amount % m_modulus;
86 // The distance to the wrap point, in (0, m_modulus]. Adding the offset without this
87 // comparison could overflow FwSizeType before the modular reduction is applied.
88 ✗ const FwSizeType toWrap = this->m_modulus - this->m_value;
89 ✗ this->setValue((offset < toWrap) ? (this->m_value + offset) : (offset - toWrap));
90 ✗ return this->m_value;
91 }
92
93 //! Decrement the index value
94 //! \return The new value
95 FwSizeType decrement(FwSizeType amount = 1 //!< The amount by which to decrement
96 ) {
97 FW_ASSERT(this->m_modulus > 0);
98 const FwSizeType offset = amount % this->m_modulus;
99 // Subtracting first where possible avoids overflowing FwSizeType on m_value + m_modulus
100 this->setValue((offset <= this->m_value) ? (this->m_value - offset)
101 : (this->m_modulus - (offset - this->m_value)));
102 return this->m_value;
103 }
104
105 private:
106 // ----------------------------------------------------------------------
107 // Private member variables
108 // ----------------------------------------------------------------------
109
110 //! The index value
111 FwSizeType m_value;
112
113 //! The modulus
114 FwSizeType m_modulus;
115 };
116
117 } // namespace Fw
118
119 #endif
120