dynamic_bitset 類表示一組二進制位。它通過 operator[] 提供對單獨二進制位的值的訪問,並提供了可以應用於內建整數類型的全部位操作符,比如 operator& 和 operator<<。組內的二進制位數目在運行期通過 dynamic_bitset 的構造函數的一個參數指定。
dynamic_bitset 類和 std::bitset 類幾乎相同。區別在於 dynamic_bitset 的大小(二進制位的數目)是在運行期 dynamic_bitset 對象的構造過程中指定的,而 std::bitset 的大小是在編譯期由一個整型模板參數指定。
dynamic_bitset 的設計要解決的主要問題是表示一個有限集合的子集。每一個二進制位表示有限集合中的一個元素是否在子集中。這樣一來,dynamic_bitset 的位操作,比如 operator& 和 operator|,就對應於相應的集合操作,比如交集和並集。
namespace boost {
template <typename Block, typename Allocator>
class dynamic_bitset
{
public:
typedef Block block_type;
typedef Allocator allocator_type;
typedef implementation-defined size_type;
static const int bits_per_block = implementation-defined;
static const size_type npos = implementation-defined;
class reference
{
void operator&(); // not defined
public:
// An automatically generated copy constructor.
reference& operator=(bool value);
reference& operator=(const reference& rhs);
reference& operator|=(bool value);
reference& operator&=(bool value);
reference& operator^=(bool value);
reference& operator-=(bool value);
bool operator~() const;
operator bool() const;
reference& flip();
};
typedef bool const_reference;
explicit dynamic_bitset(const Allocator& alloc = Allocator());
explicit dynamic_bitset(size_type num_bits, unsigned long value = 0,
const Allocator& alloc = Allocator());
template <typename CharT, typename Traits, typename Alloc>
explicit dynamic_bitset(const std::basic_string<CharT, Traits, Alloc>& s,
typename std::basic_string<CharT, Traits, Alloc>::size_type pos = 0,
typename std::basic_string<CharT, Traits, Alloc>::size_type n = std::basic_string<CharT, Traits, Alloc>::npos,
const Allocator& alloc = Allocator());
template <typename BlockInputIterator>
dynamic_bitset(BlockInputIterator first, BlockInputIterator last,
const Allocator& alloc = Allocator());
dynamic_bitset(const dynamic_bitset& b);
void swap(dynamic_bitset& b);
dynamic_bitset& operator=(const dynamic_bitset& b);
allocator_type get_allocator() const;
void resize(size_type num_bits, bool value = false);
void clear();
void push_back(bool bit);
void append(Block block);
template <typename BlockInputIterator>
void append(BlockInputIterator first, BlockInputIterator last);
dynamic_bitset& operator&=(const dynamic_bitset& b);
dynamic_bitset& operator|=(const dynamic_bitset& b);
dynamic_bitset& operator^=(const dynamic_bitset& b);
dynamic_bitset& operator-=(const dynamic_bitset& b);
dynamic_bitset& operator<<=(size_type n);
dynamic_bitset& operator>>=(size_type n);
dynamic_bitset operator<<(size_type n) const;
dynamic_bitset operator>>(size_type n) const;
dynamic_bitset& set(size_type n, bool val = true);
dynamic_bitset& set();
dynamic_bitset& reset(size_type n);
dynamic_bitset& reset();
dynamic_bitset& flip(size_type n);
dynamic_bitset& flip();
bool test(size_type n) const;
bool any() const;
bool none() const;
dynamic_bitset operator~() const;
size_type count() const;
reference operator[](size_type pos);
bool operator[](size_type pos) const;
unsigned long to_ulong() const;
size_type size() const;
size_type num_blocks() const;
size_type max_size() const;
bool empty() const;
bool is_subset_of(const dynamic_bitset& a) const;
bool is_proper_subset_of(const dynamic_bitset& a) const;
size_type find_first() const;
size_type find_next(size_type pos) const;
};
template <typename B, typename A>
bool operator==(const dynamic_bitset<B, A>& a, const dynamic_bitset<B, A>& b);
template <typename Block, typename Allocator>
bool operator!=(const dynamic_bitset<Block, Allocator>& a, const dynamic_bitset<Block, Allocator>& b);
template <typename B, typename A>
bool operator<(const dynamic_bitset<B, A>& a, const dynamic_bitset<B, A>& b);
template <typename Block, typename Allocator>
bool operator<=(const dynamic_bitset<Block, Allocator>& a, const dynamic_bitset<Block, Allocator>& b);
template <typename Block, typename Allocator>
bool operator>(const dynamic_bitset<Block, Allocator>& a, const dynamic_bitset<Block, Allocator>& b);
template <typename Block, typename Allocator>
bool operator>=(const dynamic_bitset<Block, Allocator>& a, const dynamic_bitset<Block, Allocator>& b);
template <typename Block, typename Allocator>
dynamic_bitset<Block, Allocator>
operator&(const dynamic_bitset<Block, Allocator>& b1, const dynamic_bitset<Block, Allocator>& b2);
template <typename Block, typename Allocator>
dynamic_bitset<Block, Allocator>
operator|(const dynamic_bitset<Block, Allocator>& b1, const dynamic_bitset<Block, Allocator>& b2);
template <typename Block, typename Allocator>
dynamic_bitset<Block, Allocator>
operator^(const dynamic_bitset<Block, Allocator>& b1, const dynamic_bitset<Block, Allocator>& b2);
template <typename Block, typename Allocator>
dynamic_bitset<Block, Allocator>
operator-(const dynamic_bitset<Block, Allocator>& b1, const dynamic_bitset<Block, Allocator>& b2);
template <typename Block, typename Allocator, typename CharT, typename Alloc>
void to_string(const dynamic_bitset<Block, Allocator>& b,
std::basic_string<CharT, Alloc>& s);
template <typename Block, typename Allocator, typename BlockOutputIterator>
void to_block_range(const dynamic_bitset<Block, Allocator>& b,
BlockOutputIterator result);
template <typename CharT, typename Traits, typename Block, typename Allocator>
std::basic_ostream<CharT, Traits>&
operator<<(std::basic_ostream<CharT, Traits>& os, const dynamic_bitset<Block, Allocator>& b);
template <typename CharT, typename Traits, typename Block, typename Allocator>
std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is, dynamic_bitset<Block, Allocator>& b);
} // namespace boost
每一個二進制位代表布爾值 true 或者 false(1 或者 0)。set 一個二進制位就是將它賦值為 1。clear 或者 reset 一個二進制位就是將它賦值為 0。flip 一個二進制位就是如果它的值為 0 就變為 1,如果為 1 就變為 0。每一個二進制位有一個非負的 position。一個 bitset x 包含 x.size() 個二進制位,每一個二進制位被分配在區間 [0,x.size()) 中一個唯一的 position。position 0 的那個二進制位被稱為 least significant bit,而 position size() - 1 的是 most significant bit。當將一個 dynamic_bitset 實例變換為 unsigned long n,或從 unsigned long n 變換為一個 dynamic_bitset 實例時,bitset 中 position i 的二進制位的值與 (n >> i) & 1 相同。
Example 1 (設置並讀出一些二進制位)
Example 2 (從整數創建 bitsets)
Example 3 (執行輸入/輸出和一些位操作)。
有些人更喜歡用名字 "toggle" 而不是 "flip"。選擇名字 "flip" 是因為它是 std::bitset 中使用的名字。實際上,dynamic_bitset 中大多數函數名字的選擇都是因為這個原因。
當一個前提條件被違反的時候,dynamic_bitset 不拋出異常(就像 std::bitset 所做的)。代之以使用 assert。關於這一點的解釋參見 Error and Exception Handling 的指導方針。
類 dynamic_bitset 被定義在頭文件 boost/dynamic_bitset.hpp 中。而且,頭文件 boost/dynamic_bitset_fwd.hpp 中有一個 dynamic_bitset 的前向聲明。
| 參數 | 說明 | 缺省 |
|---|---|---|
| Block | 存儲在二進制位中的整數類型。 | unsigned long |
| Allocator | 用於所有內部內存管理的分配器類型。 | std::allocator<Block> |
dynamic_bitset::reference
一個行為類似引向一個單獨二進制位的引用的代理類。它包含一個賦值操作符,一個到 bool 的轉換,一個 operator~,和一個成員函數 flip。它僅僅作為 dynamic_bitset 的 operator[] 的一個輔助類而存在。下表描述了對 reference 類型的合法的操作。假設 b 是一個 dynamic_bitset 的實例,i, j 是 size_type 而且在區間 [0,b.size()) 中。還有,注意,當我們寫 b[i] 時,我們的意思是一個由 b[i] 初始化的類型 reference 的對象。變量 x 是一個 bool。
| 表達式 | 語義 |
|---|---|
| x = b[i] | 將 b 的第 i 個二進制位賦給 x。 |
| (bool)b[i] | 返回 b 的第 i 個二進制位。 |
| b[i] = x | 將 b 的第 i 個二進制位設置為 x,並返回 b[i]。 |
| b[i] |= x | 將 b 的第 i 個二進制位和 x 的值做或操作,並返回 b[i]。 |
| b[i] &= x | 將 b 的第 i 個二進制位和 x 的值做與操作,並返回 b[i]。 |
| b[i] ^= x | 將 b 的第 i 個二進制位和 x 的值做異或操作,並返回 b[i]。 |
| b[i] -= x | 如果 x==true,清空 b 的第 i 個二進制位。返回 b[i]。 |
| b[i] = b[j] | 將 b 的第 i 個二進制位設置為 b 的第 j 個二進制位的值,並返回 b[i]。 |
| b[i] |= b[j] | 將 b 的第 i 個二進制位和 b 的第 j 個二進制位做或操作,並返回 b[i]。 |
| b[i] &= b[j] | 將 b 的第 i 個二進制位和 b 的第 j 個二進制位做與操作,並返回 b[i]。 |
| b[i] ^= b[j] | 將 b 的第 i 個二進制位和 b 的第 j 個二進制位做異或操作,並返回 b[i]。 |
| b[i] -= b[j] | 如果 b 的第 j 個二進制位被設置,清空 b 的第 i 個二進制位。並返回 b[i]。 |
| x = ~b[i] | 將 b 的第 i 個二進制位的反賦給 x。 |
| (bool)~b[i] | 返回 b 的第 i 個二進制位的反。 |
| b[i].flip() | 對 b 的第 i 個二進制位取反,並返回 b[i]。 |
dynamic_bitset::const_reference類型 bool。
dynamic_bitset::size_type無符號整數類型,代表 bit set 的大小。
dynamic_bitset::block_type與 Block 類型相同。
dynamic_bitset::allocator_type;與 Allocator 類型相同。
dynamic_bitset::bits_per_block用來表示值的類型 Block 的,排除任何冗余二進制位後的二進制位的數目。在數字上等於 std::numeric_limits<Block>::digits。
dynamic_bitset::npossize_type 的最大值。[gps]
dynamic_bitset(const Allocator& alloc = Allocator())作用:構造一個大小為 0 的 bitset。alloc 對象的一個拷貝將被用於隨後的 bitset 操作(比如 resize)中分配內存。
dynamic_bitset(size_type num_bits,作用:從一個整數構造一個 bitset。前 M 個二進制位被初始化為 val 中的相應的二進制位,其他(如果有的話)全部被初始化為 0(這裡的 M = min(num_bits, std::numeric_limits<unsigned long>::digits))。alloc 對象的一個拷貝將被用於隨後的 bitset 操作(比如 resize)中分配內存。例如,如下:
unsigned long value = 0,
const Allocator& alloc = Allocator())
dynamic_bitset(const dynamic_bitset& x)作用:構造一個是 bitset x 的拷貝的 bitset。this bitset 的分配器是 x 中的分配器的一個拷貝。
template <typename BlockInputIterator>作用:基於一個 blocks 的區間構造一個 bitset。讓 *first 為 block number 0,*++first 為 block number 1,等等。block number b 被用於初始化 dynamic_bitset 的位置區間 [b*bits_per_block, (b+1)*bits_per_block) 中的二進制位。對於每一個值為 bval 的 block number b,二進制位 (bval >> i) & 1 相當於在 bitset 中位置 (b * bits_per_block + i) 上的二進制位(這裡的 i 在區間 [0, bits_per_block) 中)。
explicit
dynamic_bitset(BlockInputIterator first, BlockInputIterator last,
const Allocator& alloc = Allocator());
dynamic_bitset(BlockInputIterator first, BlockInputIterator last,作用:
const Allocator& alloc = Allocator());
// b is constructed as if by calling the constructor
//
// dynamic_bitset(size_type num_bits,
// unsigned long value = 0,
// const Allocator& alloc = Allocator())
//
// with arguments
//
// static_cast<dynamic_bitset<unsigned short>::size_type>(8),
// 7,
// Allocator()
//
dynamic_bitset<unsigned short> b(8, 7);
template<typename Char, typename Traits, typename Alloc>前提條件:pos <= s.size() 而且用於初始化二進制位的字符必須是 0 或者 1。
explicit
dynamic_bitset(const std::basic_string<Char,Traits,Alloc>& s,
typename std::basic_string<CharT, Traits, Alloc>::size_type pos = 0,
typename std::basic_string<CharT, Traits, Alloc>::size_type n = std::basic_string<Char,Traits,Alloc>::npos,
const Allocator& alloc = Allocator())
~dynamic_bitset()作用:釋放與 this bitset 有關的內存並銷毀這個 bitset 對像自身。
void swap(dynamic_bitset& b);作用:this bitset 的內容與 bitset b 的內容被互相交換。
dynamic_bitset& operator=(const dynamic_bitset& x)作用:this bitset 成為 bitset x 的一個拷貝。
allocator_type get_allocator() const;返回:用於構造 *this 的分配器對象的一個拷貝。
void resize(size_type num_bits, bool value = false);作用:將此 bitset 的二進制位數目變為 num_bits。如果 num_bits > size(),那麼區間 [0,size()) 中的二進制位保持不變,[size(),num_bits) 中的二進制位全部被設置為 value。如果 num_bits < size(),那麼區間 [0,num_bits) 中的二進制位保持不變(而剩餘的二進制位被拋棄)。
void clear()作用:bitset 的大小變為 0。
void push_back(bool value);作用:將 bitset 的大小增加 1,並設置新的 most-significant bit 的值為 value。
void append(Block value);作用:將 value 中的二進制位附加到 bitset 中(加在最後)。這將 bitset 的大小增大 bits_per_block。如果 s 是 bitset 的原大小,那麼對於區間 [0,bits_per_block) 中的 i,位置 (s + i) 上的二進制位被設置為 ((value >> i) & 1)。
template <typename BlockInputIterator>作用:這個函數提供和下面的代碼相同的最終結果,但是一般更有效率。[gps]
void append(BlockInputIterator first, BlockInputIterator last);
for (; first != last; ++first)要求:BlockInputIterator 類型必須是一個 Input Iterator 的原型,而它的 value_type 必須和 Block 是同一個類型。
append(*first);
dynamic_bitset& operator&=(const dynamic_bitset& rhs)要求:this->size() == rhs.size()。
for (size_type i = 0; i != this->size(); ++i)返回:*this。
(*this)[i] = (*this)[i] & rhs[i];
dynamic_bitset& operator|=(const dynamic_bitset& rhs)要求:this->size() == rhs.size()。
for (size_type i = 0; i != this->size(); ++i)返回:*this。
(*this)[i] = (*this)[i] | rhs[i];
dynamic_bitset& operator^=(const dynamic_bitset& rhs)要求:this->size() == rhs.size().
for (size_type i = 0; i != this->size(); ++i)返回:*this。
(*this)[i] = (*this)[i] ^ rhs[i];
dynamic_bitset& operator-=(const dynamic_bitset& rhs)要求:this->size() == rhs.size()。
for (size_type i = 0; i != this->size(); ++i)返回:*this。
(*this)[i] = (*this)[i] && !rhs[i];
dynamic_bitset& operator<<=(size_type n)作用:將 this bitset 中的二進制位向左移動 n 個二進制位。對於 bitset 中的每一個二進制位,位置 pos 上的二進制位持有位置 pos - n 上的二進制位原來的值,或者如果沒有這樣的二進制位存在,則為 0。
dynamic_bitset& operator>>=(size_type n)作用:將 this bitset 中的二進制位向右移動 n 個二進制位。對於 bitset 中的每一個二進制位,位置 pos 上的二進制位持有位置 pos + n 上的二進制位原來的值,或者如果沒有這樣的二進制位存在,則為 0。
dynamic_bitset operator<<(size_type n) const返回:*this 的一個拷貝並向左移動 n 個二進制位。對於返回的 bitset 中的每一個二進制位,位置 pos 上的二進制位持有 this bitset 的位置 pos - n 上的二進制位的值,或者如果這樣的二進制位不存在,則為 0。注意,表達式 b << n 等價於構造一個 b 的臨時拷貝,然後使用 operator<<=。
dynamic_bitset operator>>(size_type n) const返回:*this 的一個拷貝並向右移動 n 個二進制位。對於返回的 bitset 中的每一個二進制位,位置 pos 上的二進制位持有 this bitset 的位置 pos + n 上的二進制位的值,或者如果這樣的二進制位不存在,則為 0。注意,表達式 b >> n 等價於構造一個 b 的臨時拷貝,然後使用 operator>>=。
dynamic_bitset& set()作用:設置 this bitset 中的每一個二進制位為 1。
dynamic_bitset& flip()作用:翻轉 this bitset 中的每一個二進制位的值。
dynamic_bitset operator~() const返回:*this 的一個拷貝,並翻轉它的所有二進制位。
dynamic_bitset& reset()作用:清空 this bitset 中的每一個二進制位。
dynamic_bitset& set(size_type n, bool val = true)前提條件:n < this->size()。
dynamic_bitset& reset(size_type n)前提條件:n < this->size()。
dynamic_bitset& flip(size_type n)前提條件:n < this->size()。
size_type size() const返回:this bitset 中的二進制位的數目。
size_type num_blocks() const返回:this bitset 中的 blocks 的數目。
size_type max_size() const;返回:擁有和 *this 相同類型的一個 dynamic_bitset 對象的最大大小。注意,如果有任何 dynamic_bitset 操作導致 size() 超過了 max_size(),則行為是未定義的。
bool empty() const;返回:如果 this->size() == 0,則為 true,否則,為 false。注意:不要和 none() 混淆,那具有不同的語義。
size_type count() const返回:this bitset 中被設置的二進制位的數目。
bool any() const返回:如果 this bitset 中有任何二進制位被設置,則為 true,否則,為 false。
bool none() const返回:如果沒有二進制位被設置,則為 true,否則,為 false。
bool test(size_type n) const前提條件:n < this->size()。
reference operator[](size_type n)前提條件:n < this->size()。
bool operator[](size_type n) const前提條件:n < this->size()。
unsigned long to_ulong() const返回:*this 中的二進制位的相應的數字值。
bool is_subset_of(const dynamic_bitset& a) const要求:this->size() == a.size()
bool is_proper_subset_of(const dynamic_bitset& a) const要求:this->size() == a.size()
size_type find_first() const;返回:被設置的二進制位的最小的索引 i,或者如果 *this 中沒有被設置的二進制位,則為 npos。
size_type find_next(size_type pos) const;返回:比 pos 大的被設置的二進制位的最小的索引 i,或者如果這樣的索引不存在,則為 npos。
bool operator==(const dynamic_bitset& rhs) const返回:如果 this->size() == rhs.size(),而且對於所有的在區間 [0,rhs.size()) 中的 i,都有 (*this)[i] == rhs[i],則為 true。否則,返回 false。
bool operator!=(const dynamic_bitset& rhs) const返回:!((*this) == rhs)
bool operator<(const dynamic_bitset& rhs) const返回:如果按照字典順序 this bitset 比 rhs 小,則為 true,否則,返回 false。(關於字典順序的定義,參見 lexicographical_compare(字典式比較)的描述)。
bool operator>(const dynamic_bitset& rhs) const返回:!((*this) < rhs || (*this) == rhs)
bool operator<=(const dynamic_bitset& rhs) const返回:(*this) < rhs || (*this) == rhs
bool operator>=(const dynamic_bitset& rhs) const返回:(*this) > rhs || (*this) == rhs
dynamic_bitset operator&(const dynamic_bitset& a, const dynamic_bitset& b)要求:a.size() == b.size()
dynamic_bitset operator|(const dynamic_bitset& a, const dynamic_bitset& b)要求:a.size() == b.size()
dynamic_bitset operator^(const dynamic_bitset& a, const dynamic_bitset& b)要求:a.size() == b.size()
dynamic_bitset operator-(const dynamic_bitset& a, const dynamic_bitset& b)要求:a.size() == b.size()
template <typename CharT, typename Alloc>作用:拷貝 b 的一個表示到 string s 中。如果一個二進制位被設置,則 string 中相應的字符為 '1',如果沒有設置,則為 '0'。string 的字符位置 i 對應於二進制位位置 b.size() - 1 – i。
void to_string(const dynamic_bitset<Block, Allocator>& b,
std::basic_string<Char,Traits,Alloc>& s)
template <typename Block, typename Alloc, typename BlockOutputIterator>作用:將 bitset 中的二進制位一次一個 block 地寫入迭代器 result 中。第一個 block 寫入代表 bitset 中位置區間 [0,bits_per_block) 內的二進制位,第二個 block 寫入區間 [bits_pre_block,2*bits_per_block) 內的二進制位,並依此類推。對於每一個寫入的 block bval,二進制位 (bval >> i) & 1 對應於 bitset 中位置 (b * bits_per_block + i) 上的二進制位。
void to_block_range(const dynamic_bitset<Block, Alloc>& b, BlockOutputIterator result)
template <typename BlockIterator, typename Block, typename Alloc>作用:從迭代器區間讀 blocks 到 bitset 中。
void from_block_range(BlockIterator first,
BlockIterator last, const dynamic_bitset<Block, Alloc>& b)
template <typename Char, typename Traits, typename Block, typename Alloc>作用:向流 os 中插入 b 的一個字面表示(高位在前)。粗略地說,輸出和以下操作相同
basic_ostream<Char, Traits>&
operator<<(basic_ostream<Char, Traits>& os, const dynamic_bitset<Block, Alloc>& b)
std::basic_string<Char, Traits> s;只不過 stream inserter(流插入器)會考慮將地區信息注入 os,而 boost::to_string() 不會這樣做。更加精確的規範,按照 "as if" 規則給出:首先,對於 bitset b 中每一個合法的位置 i,讓我們放入:character_of(b[i)]) = b[i]? os.widen('1') : os.widen('0'); 再讓 s 成為一個 std::basic_string<Char, Traits> 對象,長度為 b.size(),並且,對於每一個 [0, b.size()) 中的 i,s[i] 是 character_of(b[i])。那麼,輸出,對 os 的影響和異常行為和輸出對像 s 到 os 中相同(相同的寬度,相同的異常掩碼,相同的填充,相同的 setstate() 邏輯)。
boost::to_string(x, s):
os << s;
template <typename Char, typename Traits, typename Block, typename Alloc>作用:從一個輸入流中提取一個 dynamic_bitset。
std::basic_istream<Char,Traits>&
operator>>(std::basic_istream<Char,Traits>& is, dynamic_bitset<Block, Alloc>& b)
我們衷心感謝 Boost 社群投入時間來審查和接受這個庫。由於來自 Boost 成員的建議,這個庫變得比以前更好。我們特別要感謝 Matt Marcus 承擔了審查管理者的任務。而且,專門的感謝送給 James Kanze,他對國際化的幫助無法估量。
| Copyright c 2001 | Jeremy Siek,
Indiana University (jsiek@osl.iu.edu) Chuck Allison, Senior Editor, C/C++ Users Journal (cda@freshsources.com) |
| Copyright c 2003-2004 | Gennaro Prota |