BitBool Class ( boolean array ), upto 16000 elements on UNO.

This is a small class designed to lower SRAM usage for bool arrays. Values can be inspected or assigned using standard array sub-script operators ( '[]' ), the code below is the library, and underneath that is a sample sketch of generic array usage, it contains a #define called USE_STANDARD_BOOL which if uncommented will use a standard bool array, otherwise a BitBool array is used. The internal data is accessible allowing manipulation of bits and bytes.

Some usages may be: large sets of bool flags, LED patterns/shift data.

This is only a basic implementation, if anybody has a need for some form of shifting / conversion /any other mod, please post your ideas.

BitBool.h

#ifndef HEADER_BITBOOL
  #define HEADER_BITBOOL
  #include "Arduino.h"
 
  template< size_t _Count, bool _Reverse = false >
    class BitBool{
      protected:
        struct BitRef{
         
          BitRef( uint8_t &u_DataRef, const uint8_t u_Idx ) : u_Data( u_DataRef ), u_Index( _Reverse ? ( 0x80 >> u_Idx ) : ( 0x1 << u_Idx ) ) { return; }
 
          operator const bool() const { return this->u_Data & this->u_Index; }
           
          const bool operator =( const BitRef &b_Copy ) const { return *this = ( const bool ) b_Copy; }
 
          const bool operator =( const bool &b_Copy ) const
            {
              if( b_Copy )  this->u_Data |= this->u_Index;
              else          this->u_Data &= ~this->u_Index;
              return b_Copy;
            }      
             
          uint8_t &u_Data;
          uint8_t const u_Index;
        };  
      public:
        enum{ bitCount = _Count, byteCount = ( bitCount / 0x8 ) + ( ( bitCount % 0x8 ) ? 0x1 : 0x0 ) };
 
        BitRef operator []( const uint16_t i_Index ) { return BitRef( this->data[ i_Index >> 0x3 ], i_Index & 0x7 ); }  
        uint8_t data[ byteCount ];
  };
#endif

Sketch

//#define USE_STANDARD_BOOL
#define MAX_ITEMS 100

#include <BitBool.h> //use "BitBool.h" if file is local, or remove include and copy class directly in.

#ifdef USE_STANDARD_BOOL
  bool b_Array[ MAX_ITEMS ] = { true, true, true };
#else
  BitBool< MAX_ITEMS > b_Array = { B00000111 };
#endif

void setup() { Serial.begin(9600); }

void loop()
  {
    bool b_TempCopy = b_Array[ MAX_ITEMS - 1 ];
    
    //Roll items up.
    for( int i_Index = MAX_ITEMS - 1 ; i_Index ; --i_Index )
      b_Array[ i_Index ] = b_Array[ i_Index - 1 ];
    b_Array[ 0 ] = b_TempCopy;
    
    //Show contents.
    Serial.print('[');
    for( int i_Index = 0 ; i_Index < MAX_ITEMS ; ++i_Index ) 
      Serial.print( b_Array[ i_Index ] ? '#' : '-' );
    Serial.print("]\r\n");
  }

Cheers

BitRef( uint8_t &u_DataRef, const uint8_t u_Idx ) : u_Data( u_DataRef ), u_Index( 0x1 << u_Idx ) { return; }

byte b_Data[ ( _Count / 0x8 ) + ( ( _Count % 0x8 ) ? 0x1 : 0x0 ) ];

Different data-types?

For what it's worth, I prefer something that looks more like rounding...

byte b_Data[ ( (_Count + 0x7) / 0x8 ) ];

...
#else
  BitBool< MAX_ITEMS > b_Array; = { B00000111 };
#endif
...

Topic_128407:8: error: braces around initializer for non-aggregate type 'BitBool<100u>'

...which compiler version are you using?

I agree that the names should match, I have extracted this from a larger library I plan to release once the Due is here, so artifacts have crept in. Also I assume you do already know 'byte' is simply an alias for uint8_t.

And as far as sizing the types, its done in compile time, and I don't believe your method is any more intuitive. I have my own style of writing expressions, I think it is more of a personal preference thing.

I'll edit the code in a sec, another artifact... done.

b_Data cannot be private.
Original code is fixed now.

Oh and I'm using the Arduino IDE, nothing special ( not relevant now as it was my code error ), thanks for the find.

16000 elements ??

Have you tried your class in PROGMEM? You could have a really big bitarray - although readonly, e.g. 25KB ==> 200.000 fixed booleans.

What to do with it?

  • for games a fixed bit array (2 dimensional) could hold a playing field e.g. think minesweeper
  • a spelling checker (Bentley in Programming pearls), that used a hash function that mapped strings on a bool array. Every bit indicated right or wrong.

Hmmm, I'm not sure, I'll have to do some investigation on making it compatible, but as it stands I don't think it would work, needs a way to retrieve the data.

You have given me some more ideas anyway. I also have a class for dealing with PROGMEM types which may be better for this type of thing.

I tried this, quite fun:


#include <BitBool.h>

auto Led = toBitRef(PORTB, 5);//ledpin

void setup() {
pinMode(13, OUTPUT);
}

void loop() {
Led = !Led;
delay(300);
}