/**
 * The STL classes bitset and vector<bool> make no guarantees about compactness 
 * or speed.  Here are a simple set of templated functions which operate on an 
 * unsigned char (8 bits) that provide these guarantees.  
 * 
 * Hint: Combine the templated functions with an enum to document the layout of 
 *       your bit collection.
 *
 * This code was placed in the public domain by its author, Niek Sanders, on 
 * January 25, 2005.
 *
 */

// Note, iostream is only required for dumpBits()
#include <iostream>


/**
 * Turn on the designated bit position.
 */
template< int bitPos >
inline void bitOn( unsigned char& bits ) {

    // Build mask based on bit position
    static const char bitMask = 0x01 << bitPos;

    // Apply mask to turn on designated bit
    bits = bits | bitMask;

}


/**
 * Turn off the designated bit position.
 */
template< int bitPos >
inline void bitOff( unsigned char& bits ) {

    // Place a 1 in bit position to turn off
    static const char disableBit = 0x01 << bitPos;

    // Make mask of all ones except for flip bit
    static const char bitMask = 0xFF ^ disableBit;

    // Apply mask to turn off designated bit
    bits = bits & bitMask;

}


/**
 * Flip the designated bit position.
 */
template< int bitPos >
inline void bitFlip( unsigned char& bits ) {

    // Place 1 in bit pos we want to flip
    static const char flipBit = 0x01 << bitPos;

    // Apply mask to flip designated bit
    bits = bits ^ flipBit;

}


/**
 * Extract the designated bit position.
 */
template< int bitPos >
inline bool getBit( unsigned char& bits ) {

    // Build mask based on bit position
    static const char bitMask = 0x01 << bitPos;

    // Apply mask to turn on designated bit
    return ( bits & bitMask ) ? true : false;

}


/**
 * Dump a bit collection for debugging purposes.
 */
void dumpBits( unsigned char& bits ) {

    // deep copy!
    unsigned char myBits = bits;

    // mask out everything except first bit (10000000b)
    unsigned char bitMask = 0x80;

    for ( int i = 0; i < 8; i++ ) {
        int tmp = ( myBits & bitMask ) ? 1 : 0;
        std::cout << tmp;
        if ( (i+1) < 8 ) {
            std::cout << "-";
        }
        myBits <<= 1; 
    }
    std::cout << std::endl;

}


/**
 * A sample program.
 */
int main( int argc, char* argv[] ) {

    // Use an enum to document your bit collection.
    enum BitPos { LoveChicken = 0, LoveLiver = 1 };

    // The bit collection.  Make sure it's unsigned!
    unsigned char myBits = 0;
    
    // Lets play a bit (pun intended).
    dumpBits( myBits );
    bitFlip< LoveChicken >( myBits );
    bitOn< LoveLiver >( myBits );
    dumpBits( myBits );
    bitOff< LoveLiver >( myBits );
    dumpBits( myBits );

}
