Hello again!
In this video, we are going to look at bitsets.
C has operators which manipulate integers at the bit level, so things like bit-wise AND, or the
left shift operator.
These were inherited by C++.
And like most of the things that C++ inherited from C, these are low level, and not easy to use safely.
In C++11, we have a bitset class in the standard library. In the
header.
This is an abstraction which represents groups of bits. So we can work with them, and manipulate them,
much more easily, and safely, than we can using the old C legacy.
bitset is a template class.
So we need to give the number of bits as the type parameter, when we create a bitset objects.
I have used 8, but you could use 7 or 9 or 13, or any number within reason, really. We can initialize
a bitset from a string; from an integer, including a hex literal; and from C++14, we can also use
binary literals, with an optional separator, so we can see where the bytes are.
We can print out a bitset object directly, just by sending it to the stream.
So that is the overloaded left shift operator for input and output, not the one for bit shifting.
And that will display all the bits in the object.
If we want to access the underlying data, we can call a member function.
We can get this as an integer, or as a string.
There is a size() member function, which gives the number of bits in the object. And we can use subscript notation
for accessing individual bits.
So that is just like accessing array elements by using indexes.
The index zero will give the Least Significant Bit.
So that is the one at the right. The one on the left is called the Most Significant
Bit, by the way.
So, index zero will display the value of that bit.
If we want extra safety, we can also have bounds checking, by using the test() member function.
This will return the bit whose index corresponds to its argument.
If the argument is out of range, then we get an exception thrown.
So let's try that out.
We create some bitset objects.
Then we display their values in various ways.
We display the number of bits in this object, and then we iterate through them and print them out.
And then finally we try it with bounds
checking. Eight is not a valid subscript, so this should throw an exception, which we catch.
So we should see a message printed out, when we run this program.
So there we are.
That is the value of these bitsets.
We have 8 bits in the object. And they are in reverse order, because we started with index zero, and
finished with index seven.
Eight is not a valid index.
So we get the exception thrown.
We can also perform all the usual operations that we do with ints.
So we can invert all the bits, we can do AND, OR and EXOR, and also left shift and right shift.
And those will cause but shifting, and not input-output.
We need to use brackets here, because of the operator
precedence rules.
So there we are.
We have inverted the bits in b1, and then we have performed all these other operations.
There are member functions which will modify bitsets. These can either modify all the bits, or just
one bit. If we call set() with no arguments, that will set all the bits to true.
If we provide a index, then it will set the bit with that
index to true.
And there is also a version where we can pass false as the second argument, if we want to set it to
false.
reset() with no arguments will make all the bits false.
Or we can do that for just one bit.
We can also invert all the bits.
So all the bits which have value true,
will now have value false, and vice versa.
And we can do that for all the bits, or just one
argument bits.
So in this function, we are going to use this pattern of bits.
We will make a copy of it each time, so we do not get confused about what we have changed.
So we call the same member functions as we did on the slide.
So we call set() with no arguments, with one argument, and so on.
Then reset() and then flip().
So we have set all the bits to true there.
We have set them to false there, and then we have inverted the bits there.
There are also some member functions we can use for checking the entire bitset.
If all the bits are true, then all() will return true.
If at least one bit in the object is true, then any() will return true.
And if all the bits are false, then none() will return true.
And there is also a count() member function, which will return the number of bits which are true.
So we have a similar program
again. We have these bits. We have another bit set object in which all the bits are true, and one
in which they are all false.
And then we just call these member functions for those three objects.
So, are all the bits set?
So that will be false for this object, true for this one, and false for this one.
Are any bits set?
That is true for this one,
and this one, but false for that one. And so on.
And we have five bits set here, eight here, and zero here.
Okay, so that is it for this video.
I will see you next time.
But until then, keep coding!