LCOV - code coverage report
Current view: top level - src/Helpers - BitArray.hpp (source / functions) Hit Total Coverage
Test: 19d2efc7037c2e176feca44750a12594c76f466f Lines: 24 25 96.0 %
Date: 2019-11-24 14:50:27 Functions: 10 10 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14-5-g4ff2ed6