Reputation: 7915
Is there any mentioning of having a specific bitstream
object either in a future release of C++ beyond C++20 or within the standard library? For example; we can have an std::bitset<n>
object where n
is a constant known integral value.
Pseudo Example:
#include <bitstream>
template<unsigned N>
class Foo {
public:
std::bitset<N> bits_;
};
Here we have a class template that will specify how many bits are in the std::bitset
object. Which is fine.
We also have stream
objects such as iostream
, fstream
, sstream
, etc. where we can feed values of various data types into these streams either reading or writing them to a string stream, a file stream, the I/O stream to the console or terminal, etc...
What I would like to know is there any proposal of having a stream object like the ones above but specific for an arbitrary sequence of bits similar to the nature of std::bitset
, where you could feed a set of bits into the stream. For example, it might look something like this:
#include <bitset>
#include <bitstream> // not an actual library - only suggestive
int main() {
std::bitset<8> byte{0xFE};
std::bitset<16> word{0xFEDC};
std::bitset<32> dword{0xFEDCBA98};
std::bitset<64> qword{0xFEDCBA9876543210};
std::bitstream bs;
bs << byte << word << dword << qword;
std::cout << bs;
return 0;
}
Here the expected output would be:
11111110111111101101110011111110110111001011101010011000111111101101110010111010100110000111011001010100001100100001000
Depending on the endian notation of the intended use...
The reversal would be applicable too. If we had an already populated bitstream
object like the one from the example above we could extract specific bit sequences from the bitstream
as follows:
#include <bitset>
#include <bitstream> // not an actual library - only suggestive
#include <iomanip> // manipulators for bitstreams not yet implemented...
int main() {
std::bitset<8> byte{0xFE};
std::bitset<16> word{0xFEDC};
std::bitset<32> dword{0xFEDCBA98};
std::bitset<64> qword{0xFEDCBA9876543210};
std::bitstream bs;
bs << byte << word << dword << qword;
std::bitset<3> odd3;
std::bitset<5> odd5;
std::bitset<7> odd7;
bs >> bs::msb >> odd3 >> odd7 >> odd5;
std::cout << odd3 << '\n' << odd7 << '\n' << odd5;
bs >> bs::lsb >> odd5 << odd3 << odd7;
std::cout << odd5 << '\n' << odd3 << '\n' << odd7;
// Or by using a constructor with a value for the bit size...
std::bitset<9> odd9( bs ); // odd9(bs::msb), odd9(bs::lsb)...
return 0;
}
And the expected results would pull the bits either from the MSB or the LSB directions by the amount of the size of the bitset
object respectively.
Just like iostream
and the other stream libraries by using the <iomanip>
library we can have formatting modifiers that would break this input or output into discrete bit-segments
of any specified length such as every 4 or 8 bits, or display it as hex, etc... All of the bit manipulation and calculations would still be the responsibility of std::bitset
.
Being able to push or retrieve arbitrary bitset
objects in and out of a bitstream
object that would be compatible with all of the other stream
like objects could be a very powerful and useful tool or feature.
Is there any mention of something like this or does there already exist something similar to this nature without having to convert back and forth between strings or other types, etc.?
EDIT -User- walnut
gave some great examples in his answer regarding this and that it can already be done using the existing iostream
objects and operators. You can read his answer and the comments within the discussion, however, I just wanted to illustrate my reasoning for a stream
object library that is written and designed to work explicitly and specifically with bitset
data types.
Imagine a function as such:
// Not written with perfect syntax or compilation in mind,
// only psuedo to illustrate a point.
template<typename... T>
std::ostream& concatinateBitSequences( T&& ... t ) { // assuming all t are bitset<n>
std::stringstream sstream;
sstream << t...;
return sstream;
}
and compare that too...
// Not written with perfect syntax or compilation in mind,
// only psuedo to illustrate a point.
template<typename... T>
std::bitstream& concatinateBitSequences( T&& ... t ) { // assuming all t are bitset<n>
std::bitstream bs;
bs << t...;
return bs;
}
The caller, the user will know that it is returning a bitstream
explicitly or specifically compared to an arbitrary stream
object! This was my main intention or goal... It is geared more towards readability and being more expressive in the code showing proper intentions. Also, it would be tightly coupled with bitset
objects meaning the bitstream
object would only accept data coming in from bitset
s or other bitstream
objects, but it can pass its data out to bitset
s, bitstream
s or other stream
objects.
Upvotes: 0
Views: 271
Reputation: 22152
This already works as you intend:
std::cout << byte << word << dword << qword;
and
std::cin >> odd5 >> odd3 >> odd7;
For intermediate storage one can simply use std::stringstream
which will also work as you describe.
There is however no endianess, because operations are bitwise, not bytewise.
Upvotes: 1