LCOV - code coverage report
Current view: top level - src/AH/Containers - BitArray.hpp (source / functions) Hit Total Coverage
Test: ffed98f648fe78e7aa7bdd228474317d40dadbec Lines: 21 21 100.0 %
Date: 2022-05-28 15:22:59 Functions: 9 18 50.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* ✔ */
       2             : 
       3             : #pragma once
       4             : 
       5             : #include <AH/Settings/Warnings.hpp>
       6             : 
       7             : AH_DIAGNOSTIC_WERROR() // Enable errors on warnings
       8             : 
       9             : #include <AH/Error/Error.hpp>
      10             : #include <AH/Settings/NamespaceSettings.hpp>
      11             : #include <stdint.h>
      12             : 
      13             : BEGIN_AH_NAMESPACE
      14             : 
      15             : /// @addtogroup AH_Containers
      16             : /// @{
      17             : 
      18             : /**
      19             :  * @brief   A class for arrays of bits.
      20             :  * 
      21             :  * @tparam  N
      22             :  *          The number of bits.
      23             :  */
      24             : template <uint16_t N>
      25             : class BitArray {
      26             :   public:
      27             :     /**
      28             :      * @brief   Get the value of the given bit.
      29             :      * 
      30             :      * @param   bitIndex
      31             :      *          The (zero-based) index of the bit to read.
      32             :      */
      33          65 :     bool get(uint16_t bitIndex) const {
      34          65 :         return buffer[getBufferIndex(bitIndex)] & getBufferMask(bitIndex);
      35             :     }
      36             : 
      37             :     /**
      38             :      * @brief   Set the value of the given bit to 1.
      39             :      * 
      40             :      * @param   bitIndex
      41             :      *          The (zero-based) index of the bit to set.
      42             :      */
      43           3 :     void set(uint16_t bitIndex) {
      44           3 :         buffer[getBufferIndex(bitIndex)] |= getBufferMask(bitIndex);
      45           3 :     }
      46             : 
      47             :     /**
      48             :      * @brief   Clear the value of the given bit to 0.
      49             :      * 
      50             :      * @param   bitIndex
      51             :      *          The (zero-based) index of the bit to clear.
      52             :      */
      53           2 :     void clear(uint16_t bitIndex) {
      54           2 :         buffer[getBufferIndex(bitIndex)] &= ~getBufferMask(bitIndex);
      55           2 :     }
      56             : 
      57             :     /**
      58             :      * @brief   Set the value of the given bit to the given state.
      59             :      * 
      60             :      * @param   bitIndex
      61             :      *          The (zero-based) index of the bit to set.
      62             :      * @param   state
      63             :      *          The value to set the bit to.
      64             :      */
      65           2 :     void set(uint16_t bitIndex, bool state) {
      66           2 :         state ? set(bitIndex) : clear(bitIndex);
      67           2 :     }
      68             : 
      69             :     /**
      70             :      * @brief   Check the given byte index, and return it if it is within the
      71             :      *          bounds of the array, otherwise, throw an error, and return
      72             :      *          the last valid index.
      73             :      * 
      74             :      * @param   byteIndex 
      75             :      *          The index to check.
      76             :      */
      77          70 :     uint16_t safeIndex(uint16_t byteIndex) const {
      78          70 :         if (byteIndex >= getBufferLength()) {
      79           1 :             ERROR(F("Error: index out of bounds (")
      80             :                       << byteIndex << F(", length is ") << getBufferLength()
      81             :                       << ')',
      82             :                   0xFFFF);
      83             :             return getBufferLength() - 1; // LCOV_EXCL_LINE
      84             :         }
      85          69 :         return byteIndex;
      86             :     }
      87             : 
      88             :     /**
      89             :      * @brief   Get the byte at the given index.
      90             :      * 
      91             :      * This function can be used to quickly access all of the bits, to send 
      92             :      * them out to a shift register, for example.
      93             :      * 
      94             :      * @note    No bounds checking is performed.
      95             :      * 
      96             :      * @param   byteIndex
      97             :      *          The index of the byte within the array. 
      98             :      */
      99             :     const uint8_t &getByte(uint16_t byteIndex) const {
     100             :         return buffer[byteIndex];
     101             :         // return buffer[safeIndex(byteIndex)];
     102             :     }
     103             :     /// @copydoc AH::BitArray::getByte(uint16_t) const
     104             :     uint8_t &getByte(uint16_t byteIndex) {
     105             :         return buffer[byteIndex];
     106             :         // return buffer[safeIndex(byteIndex)];
     107             :     }
     108             : 
     109             :     /**
     110             :      * @brief   Set the byte at the given index.
     111             :      * 
     112             :      * This function can be used to quickly write all of the bits, when reading
     113             :      * them in from an I/O expander, for example.
     114             :      * 
     115             :      * @note    No bounds checking is performed.
     116             :      * 
     117             :      * @param   byteIndex
     118             :      *          The index of the byte within the array. 
     119             :      * @param   value
     120             :      *          The byte to write.
     121             :      */
     122             :     void setByte(uint16_t byteIndex, uint8_t value) {
     123             :         buffer[byteIndex] = value;
     124             :     }
     125             : 
     126             :     /**
     127             :      * @brief   Get the buffer length in bytes.
     128             :      */
     129          71 :     uint16_t getBufferLength() const { return bufferLength; }
     130             : 
     131             :   private:
     132          70 :     uint16_t getBufferIndex(uint16_t bitIndex) const {
     133          70 :         return safeIndex(bitIndex / 8);
     134             :     }
     135          69 :     uint8_t getBufferBit(uint16_t bitIndex) const { return bitIndex % 8; }
     136          69 :     uint8_t getBufferMask(uint16_t bitIndex) const {
     137          69 :         return 1 << getBufferBit(bitIndex);
     138             :     }
     139             : 
     140             :     constexpr static uint16_t bufferLength = (uint16_t)((N + 7) / 8);
     141             :     uint8_t buffer[bufferLength] = {};
     142             : };
     143             : 
     144             : /// @}
     145             : 
     146             : END_AH_NAMESPACE
     147             : 
     148             : AH_DIAGNOSTIC_POP()

Generated by: LCOV version 1.15