Working with Bit Flags Using STL
2011-08-15 12:39 Daniel Zheng 阅读(280) 评论(0) 编辑 收藏 举报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;
}