w3hello.com logo
Home PHP C# C++ Android Java Javascript Python IOS SQL HTML videos Categories
How do you efficiently support "sub-bitstrings" in a bitset like class in C++11?
template<size_t bits>
std::bitset<bits> subset(std::bitset<bits> set, int min, int
max)
{
    const int ignore_hi = bits-max;
    std::bitset<bits> range = (~std::bitset<bits>() <<
ignore_hi) >> ignore_hi;
    set &= range;
    return set >> min;
}

Tested at: http://coliru.stacked-crooked.com/a/531831e9c4c029f8. I think it can be optimized slightly, I think a shift can be elided, but I'm too lazy to analyze it, and hopefully the optimizer can figure it out itself.

Usually, if you want a range of bits, the correct answer is to use a bitfield instead of a bitset. However, since you seem to have a thousand bits, use a class instead.

struct flags {
   int height : 3; //3 bits
   int is_square : 1; //1 bit (as if bool)
   int width : 3; //3 bits
}; //keep in mind that a 1 bit int has possible values of `0` and `-1`.

if you want the wierdo truncation, this is untested. These operations could be done more efficiently as a single operation, but they might also be convenient separate. I wouldn't bother optimizing unless profiling shows it's necessary.

template<class dst_bits, src_bits>
std::bitset<maxbit-minbit> convert_bitset(std::bitset<src_bits>
src) {
    std::bitset<maxbit-minbit> result;
    for(int i=0; i<maxbit-minbit; i+=64)
         result |=
std::bitset<maxbit-minbit>((src>>i).to_ulllong())<<i;
    return result;
}

template<size_t src_bits, minbit, maxbit>
std::bitset<maxbit-minbit> subset(std::bitset<src_bits> set)
{
    const int ignore_hi = src_bits-maxbit;
    std::bitset<bits> range = (~std::bitset<bits>() <<
ignore_hi) >> ignore_hi;
    set &= range;
    return convert_bitset<maxbit-minbit>(set >> minbit);
}

If you want truncation with runtime sized min/max, it seems like you should re-evaluate the design. Not that it's wrong, but it should be confirmed to be right before proceeding. If you still insist on proceeding, here's a proxy that should be able to convert from one size to another implicitly, merely alter the first subset function to return proxy_bitset<bits> instead of std::bitset<bits>.

template<size_t src_bits>
struct proxy_bitset {
    proxy_bitset(std::bitset<src_bits> src) :src(src) {}
    template<size_t dst_bits>
    operator std::bitset<dst_bits>() const {return
convert_bitset<dst_bits>(src);}
private:
    std::bitset<src_bits> src;
};




© Copyright 2018 w3hello.com Publishing Limited. All rights reserved.