Gab*_*ber 5 c++ bit-manipulation
我需要一个bool数组的最小大小实现.数组的大小在编译时是已知的.
我检查std::bitset和boost::array,但他们都招致的开销是小数组显著.例如,如果数组大小为8,则容器应仅使用1个字节的内存(假设通用CPU架构).
这是存在还是我需要自己动手?
编辑:这是我最后的实施基于Tom Knapen的帖子.我为构造函数添加了一个默认值,并在越界索引的情况下添加了throw.非常感谢汤姆和其他所有人.
#include <stdexcept>
#include <climits>
/// Minimum size container for bool-arrays
/**
* TODO: may want to add to_uint32_t accessor and the like
* for sufficently small arrays
*/
template<int SIZE>
class bitarray
{
public:
bitarray(bool initial_value = false);
bool get(int index) const;
void set(int index, bool value);
private:
static const int ARRAY_SIZE = (SIZE + CHAR_BIT - 1) / 8;
unsigned char mBits[ARRAY_SIZE];
};
// ----------------------------------------------------
// Definitions
// ----------------------------------------------------
template<int SIZE>
inline bitarray<SIZE>::bitarray(bool initial_value)
{
for(int i = 0; i < ARRAY_SIZE; ++i)
mBits[i] = initial_value ? -1 : 0;
}
template<int SIZE>
inline bool bitarray<SIZE>::get(int index) const
{
if (index >= SIZE)
throw std::out_of_range("index out of range");
return (mBits[index / CHAR_BIT] & (1 << (index % CHAR_BIT)));
}
template<int SIZE>
inline void bitarray<SIZE>::set(int index, bool value)
{
if (index >= SIZE)
throw std::out_of_range("index out of range");
if (value)
mBits[index / CHAR_BIT] |= (1 << (index % CHAR_BIT));
else
mBits[index / CHAR_BIT] &= ~(1 << (index % CHAR_BIT));
}
Run Code Online (Sandbox Code Playgroud)
这是一个简单的例子。请注意,它只做它需要做的事情,所以你将无法像std::bitset.
#include <climits>
#include <iostream>
#include <cassert>
template<int S> struct boolset {
static int const SIZE = ((S / CHAR_BIT) + (0 != (S % CHAR_BIT)));
unsigned char m_bits[SIZE];
public:
boolset() : m_bits() { for(int i = 0; i < SIZE; ++i) m_bits[i] = 0; }
bool get(int i) const {
assert(i < S);
return (m_bits[i / CHAR_BIT] & (1 << (i % CHAR_BIT)));
}
void set(int i, bool v) {
assert(i < S);
if(v) { m_bits[i / CHAR_BIT] |= (1 << (i % CHAR_BIT)); }
else { m_bits[i / CHAR_BIT] &= ~(1 << (i % CHAR_BIT)); }
}
void print(std::ostream & s) const {
for(int i = 0; i < S; ++i) {
s << get(i);
}
}
};
int main(int argc, char ** argv) {
std::cout << sizeof(boolset<1>) << std::endl;
std::cout << sizeof(boolset<8>) << std::endl;
std::cout << sizeof(boolset<9>) << std::endl;
std::cout << sizeof(boolset<16>) << std::endl;
std::cout << sizeof(boolset<17>) << std::endl;
std::cout << sizeof(boolset<32>) << std::endl;
std::cout << sizeof(boolset<33>) << std::endl;
std::cout << sizeof(boolset<64>) << std::endl;
std::cout << sizeof(boolset<129>) << std::endl;
std::cout << std::endl;
boolset<31> bs;
bs.set(0, true);
bs.set(28, true);
bs.set(2, true);
std::cout << bs.get(28) << std::endl;
bs.print(std::cout); std::cout << std::endl;
bs.set(2, false);
bs.print(std::cout); std::cout << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
在ideone上输出。
| 归档时间: |
|
| 查看次数: |
1290 次 |
| 最近记录: |