LCOV - code coverage report
Current view: top level - src/AH/Containers - BitArray.hpp (source / functions) Hit Total Coverage
Test: 3a807a259ebe0769dd942f7f612dca5273937539 Lines: 21 21 100.0 %
Date: 2024-03-24 17:16:54 Functions: 9 18 50.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.15