Bits can be very efficient way of storing settings and flags. STL supplies classes that help organize and manipulate bitwise information.
The bitset Class
std::bitset is an STL class designed for handling information in bits and bit flags. The std::bitset is not classified as an STL container because it cannot resize itself and does not exhibit other characteristics of containers, such as access via iterators. This is a utility class that is optimized for working with a sequence of bits whose length is known at comiple-time.
Instantiating the std::bitset
This template class requires the inclusion of the header <bitset> and needs some template parameter that supplies the number of bits the instance of the class has to manage.
#include <bitset>
#include <iostream>
#include <string>
int main ()
{
using namespace std;
// instantiate a bitset object for holding 4 bits
// all initialized to '0000'
bitset <4> fourBits;
cout << "The initial contents of fourBits: " << fourBits << endl;
// instantiate a bitset object for holding 5 bits
// initialize it to a bit sequence supplied by a string
bitset <5> fiveBits (string ("10101"));
cout << "The initial contents of fiveBits: " << fiveBits << endl;
// instantiate a bitset object for 8 bits
// given an unsigned long init value
bitset <8> eightbits (255);
cout << "The initial contents of eightBits: " << eightbits << endl;
return 0;
}
Using std::bitset and Its Members
The bitset class supplies member functions that help perform insertions into the bitset, set or reset contents, read them or write them into a stream. It also supplies operators that help display the contents of a bitset, and perform perform bitwise logical operations among others.
#include <bitset>
#include <string>
#include <iostream>
int main ()
{
using namespace std;
// A bitset to hold 8-bits
bitset <8> eightBits;
cout << "Enter a 8-bit sequence: ";
// Store user-supplied sequence into the bitset
cin >> eightBits;
cout << endl;
// Supply info on number of 1s and 0s in it:
cout << "The number of 1s in the input sequence: ";
cout << eightBits.count () << endl;
cout << "The number of 0s in the input sequence: ";
cout << eightBits.size () - eightBits.count () << endl;
// create a copy
bitset <8> flipInput (eightBits);
// flip the bits
flipInput.flip ();
cout << "The flipped version of the input sequence is: "
<< flipInput << endl << endl;
// another 8-bit sequence to perform bitwise-ops against the first
bitset <8> eightMoreBits;
cout << "Enter another 8-bit sequence: ";
cin >> eightMoreBits;
cout << endl;
cout << "Result of AND, OR and XOR between the two sequences:" << endl;
cout << eightBits << " & " << eightMoreBits << " = "
<< (eightBits & eightMoreBits) // bitwise AND
<< endl;
cout << eightBits << " | " << eightMoreBits << " = "
<< (eightBits | eightMoreBits) // bitwise OR
<< endl;
cout << eightBits << " ^ " << eightMoreBits << " = "
<< (eightBits ^ eightMoreBits) // bitwise XOR
<< endl;
return 0;
}
The vector<bool>
The vector<bool> is a partial specialization of the std::vector and is intended for storing boolean data. This class is able to dynamically size itself and hence the programmer does not need to know the number of boolean-flags to be stored at compile-time.
Instantiating a vector<bool>
#include <vector>
int main ()
{
using namespace std;
// Instantiate an object using the default constructor
vector <bool> vecBool1;
// A vector of 10 elements with value true (default: false)
vector <bool> vecBool2 (10, true);
// Instantiate one object as a copy of another
vector <bool> vecBool2Copy (vecBool2);
return 0;
}
Using the vector<bool>
The vector<bool> features the function flip() that toggles the state of the boolean values in the sequence. Otherwise, this class is quite similar to the std::vector in the sense that you can, for example, even push_back flags into the sequence.
#include <vector>
#include <iostream>
int main ()
{
using namespace std;
// Instantiate a vector<bool> to hold 3 elements
vector <bool> vecBool (3);
// Assign 3 elements using the array operator []
vecBool [0] = true;
vecBool [1] = true;
vecBool [2] = false;
// Insert a 4th element using push_back:
// this will cause the vector to resize the buffer
vecBool.push_back (true);
cout << "The contents of the vector are: " << endl << "{";
for (size_t nIndex = 0; nIndex < vecBool.size (); ++ nIndex)
cout << vecBool [nIndex] << ' ';
cout << "}" << endl << endl;
vecBool.flip ();
cout << "The flipped contents of the vector are: " << endl << "{";
for (size_t nIndex = 0; nIndex < vecBool.size (); ++ nIndex)
cout << vecBool [nIndex] << ' ';
cout << "}";
return 0;
}