danilabagroff
danilabagroff

Reputation: 656

Extracting bits from std::stringstream to std::bitset

According to some documentation I found for std::bitset:

They can also be directly inserted and extracted from streams in binary format (see applicable operators).

Applicable operators:

is,os basic_istream or basic_ostream object from which a bitset object is respectively extracted or inserted. The format in which bitsets are inserted/extracted is a sequence of (suitably widened) '0' and '1' characters.

template<class charT, class traits, size_t N>
   basic_istream<charT, traits>&
     operator>> (basic_istream<charT,traits>& is, bitset<N>& rhs);
 template<class charT, class traits, size_t N>
   basic_ostream<charT, traits>&
     operator<< (basic_ostream<charT,traits>& os, const bitset<N>& rhs);

This essentially means that we are allowed to do something like:

std::stringstream _stream(std::ios::binary);
{...}
std::bitset<16> a1;
std::bitset<8> a2;
_stream >> std::bin >> a1;
_stream >> std::bin >> a2;

It seems to me that I just don't have std::bin in the Standard Library, everything else should be ok.

I'm wondering if there is any way to implement this modifier?

Upvotes: 4

Views: 1281

Answers (1)

πάντα ῥεῖ
πάντα ῥεῖ

Reputation: 1

There's no such thing like a std::bin stream manipulator, but If you want to write the std::bitset contents bit wise, you might try the following:

template<std::size_t num_bits>
void writeBits(ostream& os, const std::bitset<num_bits>& thebits)
{
    for(std::size_t bit_pos = 0; bit_pos < num_bits;)
    {
        unsigned char currentByte = 0;
        for(int currentBit = 0; 
            currentBit < sizeof(unsigned char) && 
            bit_pos < num_bits; 
            ++currentBit, ++bit_pos)
        {
            currentByte |= thebits[bit_pos] ? (0x80 >> currentBit) : 0;
        }
        os << currentByte;
    }
}

See the full sample on ideone.

The other way round would only work if you know the size of std::bitset<> portions to read in advance:

template<std::size_t num_bits>
void readBits(istream& is, std::bitset<num_bits>& thebits)
{
    thebits.reset();
    std::size_t total_bytes = num_bits / sizeof(unsigned char) + 1;
    std::size_t bit_pos = 0;
    for(std::size_t i = 0; 
        is && 
        i < total_bytes && 
        bit_pos < num_bits;
        ++i)
    {
        unsigned char currentByte = 0;
        if(is >> currentByte)
        {
            for(int currentBit = 0; 
                currentBit < sizeof(unsigned char) &&
                bit_pos < num_bits;
                ++currentBit, ++bit_pos)
            {
                thebits[bit_pos] = (currentByte &  (0x80 >> currentBit)) > 0;
            }
        }
    }
}

See the full sample on ideone.

Upvotes: 1

Related Questions