WEBVTT

00:00.150 --> 00:00.750
Hello again!

00:01.080 --> 00:03.560
In this video, we are going to look at bitsets.

00:04.920 --> 00:12.240
C has operators which manipulate integers at the bit level, so things like bit-wise AND, or the

00:12.240 --> 00:13.500
left shift operator.

00:14.400 --> 00:16.590
These were inherited by C++.

00:16.980 --> 00:24.060
And like most of the things that C++ inherited from C, these are low level, and not easy to use safely.

00:25.050 --> 00:30.360
In C++11, we have a bitset class in the standard library. In the <bitset>

00:30.360 --> 00:31.080
header.

00:31.680 --> 00:37.020
This is an abstraction which represents groups of bits. So we can work with them, and manipulate them,

00:37.110 --> 00:42.030
much more easily, and safely, than we can using the old C legacy.

00:43.540 --> 00:45.430
bitset is a template class.

00:45.730 --> 00:51.210
So we need to give the number of bits as the type parameter, when we create a bitset objects.

00:52.200 --> 01:00.040
I have used 8, but you could use 7 or 9 or 13, or any number within reason, really. We can initialize

01:00.040 --> 01:07.810
a bitset from a string; from an integer, including a hex literal; and from C++14, we can also use

01:07.870 --> 01:12.670
binary literals, with an optional separator, so we can see where the bytes are.

01:15.850 --> 01:20.020
We can print out a bitset object directly, just by sending it to the stream.

01:20.530 --> 01:25.810
So that is the overloaded left shift operator for input and output, not the one for bit shifting.

01:26.410 --> 01:28.570
And that will display all the bits in the object.

01:30.190 --> 01:34.090
If we want to access the underlying data, we can call a member function.

01:34.090 --> 01:37.540
We can get this as an integer, or as a string.

01:39.770 --> 01:46.250
There is a size() member function, which gives the number of bits in the object. And we can use subscript notation

01:46.250 --> 01:47.870
for accessing individual bits.

01:48.350 --> 01:52.700
So that is just like accessing array elements by using indexes.

01:54.940 --> 01:58.300
The index zero will give the Least Significant Bit.

01:58.300 --> 02:03.430
So that is the one at the right. The one on the left is called the Most Significant

02:03.430 --> 02:04.210
Bit, by the way.

02:04.690 --> 02:09.220
So, index zero will display the value of that bit.

02:10.690 --> 02:16.120
If we want extra safety, we can also have bounds checking, by using the test() member function.

02:16.780 --> 02:20.740
This will return the bit whose index corresponds to its argument.

02:21.460 --> 02:25.090
If the argument is out of range, then we get an exception thrown.

02:30.140 --> 02:31.670
So let's try that out.

02:31.670 --> 02:34.040
We create some bitset objects.

02:34.940 --> 02:37.970
Then we display their values in various ways.

02:39.320 --> 02:44.780
We display the number of bits in this object, and then we iterate through them and print them out.

02:45.770 --> 02:47.720
And then finally we try it with bounds

02:47.720 --> 02:54.110
checking. Eight is not a valid subscript, so this should throw an exception, which we catch.

02:54.620 --> 02:58.160
So we should see a message printed out, when we run this program.

03:00.380 --> 03:01.190
So there we are.

03:01.670 --> 03:03.710
That is the value of these bitsets.

03:04.430 --> 03:11.660
We have 8 bits in the object. And they are in reverse order, because we started with index zero, and

03:11.660 --> 03:12.950
finished with index seven.

03:13.880 --> 03:15.350
Eight is not a valid index.

03:15.590 --> 03:17.000
So we get the exception thrown.

03:20.320 --> 03:23.510
We can also perform all the usual operations that we do with ints.

03:24.250 --> 03:32.920
So we can invert all the bits, we can do AND, OR and EXOR, and also left shift and right shift.

03:33.340 --> 03:36.250
And those will cause but shifting, and not input-output.

03:36.670 --> 03:39.040
We need to use brackets here, because of the operator

03:39.040 --> 03:39.940
precedence rules.

03:42.090 --> 03:42.810
So there we are.

03:42.810 --> 03:48.480
We have inverted the bits in b1, and then we have performed all these other operations.

03:51.360 --> 03:58.140
There are member functions which will modify bitsets. These can either modify all the bits, or just

03:58.140 --> 04:03.270
one bit. If we call set() with no arguments, that will set all the bits to true.

04:03.900 --> 04:07.690
If we provide a index, then it will set the bit with that

04:07.710 --> 04:08.790
index to true.

04:09.030 --> 04:13.890
And there is also a version where we can pass false as the second argument, if we want to set it to

04:13.890 --> 04:14.310
false.

04:15.480 --> 04:18.450
reset() with no arguments will make all the bits false.

04:18.990 --> 04:20.850
Or we can do that for just one bit.

04:21.660 --> 04:23.220
We can also invert all the bits.

04:23.220 --> 04:25.530
So all the bits which have value true,

04:25.530 --> 04:27.930
will now have value false, and vice versa.

04:28.470 --> 04:31.350
And we can do that for all the bits, or just one

04:31.350 --> 04:32.160
argument bits.

04:34.730 --> 04:38.090
So in this function, we are going to use this pattern of bits.

04:38.600 --> 04:42.350
We will make a copy of it each time, so we do not get confused about what we have changed.

04:43.730 --> 04:47.300
So we call the same member functions as we did on the slide.

04:47.300 --> 04:51.260
So we call set() with no arguments, with one argument, and so on.

04:52.010 --> 04:54.800
Then reset() and then flip().

04:57.880 --> 05:00.060
So we have set all the bits to true there.

05:00.070 --> 05:03.760
We have set them to false there, and then we have inverted the bits there.

05:07.820 --> 05:11.750
There are also some member functions we can use for checking the entire bitset.

05:12.080 --> 05:15.200
If all the bits are true, then all() will return true.

05:16.010 --> 05:20.450
If at least one bit in the object is true, then any() will return true.

05:21.290 --> 05:24.680
And if all the bits are false, then none() will return true.

05:25.400 --> 05:30.350
And there is also a count() member function, which will return the number of bits which are true.

05:32.470 --> 05:34.210
So we have a similar program

05:34.210 --> 05:41.470
again. We have these bits. We have another bit set object in which all the bits are true, and one

05:41.470 --> 05:42.800
in which they are all false.

05:43.480 --> 05:47.290
And then we just call these member functions for those three objects.

05:52.430 --> 05:54.410
So, are all the bits set?

05:54.830 --> 05:59.090
So that will be false for this object, true for this one, and false for this one.

05:59.900 --> 06:00.770
Are any bits set?

06:00.830 --> 06:01.790
That is true for this one,

06:01.790 --> 06:04.310
and this one, but false for that one. And so on.

06:05.000 --> 06:08.600
And we have five bits set here, eight here, and zero here.

06:09.560 --> 06:11.000
Okay, so that is it for this video.

06:11.390 --> 06:12.200
I will see you next time.

06:12.200 --> 06:14.330
But until then, keep coding!
