Boost C++ 库

……世界上最受推崇、设计最专业的 C++ 库项目之一。 Herb SutterAndrei Alexandrescu, C++ Coding Standards

dynamic_bitset<Block, Allocator> - Boost C++ 函数库

dynamic_bitset<Block, Allocator>

目录

描述
提要
定义
示例
基本原理
头文件
模板参数
概念建模
类型要求
公共基类
嵌套类型名称
公开数据成员
构造函数
析构函数
成员函数
非成员函数
异常保证
与先前版本的变化
另请参阅
致谢

描述

dynamic_bitset类表示一个位集合。它通过一个operator[]提供了可以应用于内置整数的所有位运算符,例如operator&andoperator<<。集合中的位数在运行时通过构造函数的参数指定。dynamic_bitset.

dynamic_bitset类与 std::bitset 类几乎相同。区别在于dynamic_bitset的大小(即位数)是在构造dynamic_bitset对象时于运行时指定的,而std::bitset的大小是在编译时通过一个整型模板参数指定的。

dynamic_bitset旨在解决的主要问题是表示一个有限集的子集。每个位表示有限集中的一个元素是否在该子集中。因此,dynamic_bitset的位运算(如operator&andoperator|)对应于集合运算(如交集和并集)。

提要

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;

    dynamic_bitset();

    explicit dynamic_bitset(const Allocator& alloc);

    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);

    dynamic_bitset(dynamic_bitset&& b);

    void swap(dynamic_bitset& b);

    dynamic_bitset& operator=(const dynamic_bitset& b);

    dynamic_bitset& operator=(dynamic_bitset&& b);

    allocator_type get_allocator() const;

    void resize(size_type num_bits, bool value = false);
    void clear();
    void pop_back();
    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, size_type len, bool val);
    dynamic_bitset& set(size_type n, bool val = true);
    dynamic_bitset& set();
    dynamic_bitset& reset(size_type n, size_type len);
    dynamic_bitset& reset(size_type n);
    dynamic_bitset& reset();
    dynamic_bitset& flip(size_type n, size_type len);
    dynamic_bitset& flip(size_type n);
    dynamic_bitset& flip();
    reference at(size_type n);
    bool at(size_type n) const;
    bool test(size_type n) const;
    bool test_set(size_type n, bool val = true);
    bool all() const;
    bool any() const;
    bool none() const;
    dynamic_bitset operator~() const;
    size_type count() const noexcept;

    reference operator[](size_type pos);
    bool operator[](size_type pos) const;

    unsigned long to_ulong() const;

    size_type size() const noexcept;
    size_type num_blocks() const noexcept;
    size_type max_size() const noexcept;
    bool empty() const noexcept;
    size_type capacity() const noexcept;
    void reserve(size_type num_bits);
    void shrink_to_fit();

    bool is_subset_of(const dynamic_bitset& a) const;
    bool is_proper_subset_of(const dynamic_bitset& a) const;
    bool intersects(const dynamic_bitset& a) const;

    size_type find_first() const;
    size_type find_first(size_type pos) 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)。一个位集xcontainsx.size()个位,每个位都被赋予一个在范围[0,x.size())内的唯一位置。位置 0 的位称为最低有效位(least significant bit),而位置size() - 1的位是最高有效位(most significant bit)。当将dynamic_bitset的实例与 unsigned long 相互转换时n,位集中位置i的位与(n >> i) & 1.

示例

示例 1 (设置和读取一些位)

示例 2 (从整数创建一些位集)

示例 3 (执行输入/输出和一些位运算)。

基本原理

dynamic_bitset不是一个 容器(Container),并且不提供迭代器,原因如下:

  • 一个带有代理reference类型的容器无法满足 C++ 标准中规定的容器要求(除非诉诸于奇怪的迭代器语义)。std::vector<bool>有一个代理reference类型,不满足容器要求,因此导致了许多问题。一个常见的问题是当人们尝试将std::vector<bool>的迭代器用于标准算法,例如std::search来填充。该std::search。其要求迭代器必须是前向迭代器(Forward Iterator),但std::vector<bool>::iterator由于代理引用的存在而不满足此要求。根据实现的不同,这种误用可能会也可能不会导致编译错误,甚至可能导致运行时错误。有关此问题的进一步讨论,请参阅 Scott Meyers 的 Effective STL。因此,dynamic_bitset通过不伪装成容器来尝试避免这些问题。

有些人更喜欢使用“toggle”而不是“flip”。选择“flip”这个名称是因为这是 std::bitset 中使用的名称。事实上,dynamic_bitset的大多数函数名都是因此而选择的。

dynamic_bitset在违反前置条件时不会抛出异常(如在std::bitset中所做的那样)。取而代之的是使用断言。有关解释,请参阅错误和异常处理指南。

头文件

dynamic_bitset定义在头文件 boost/dynamic_bitset.hpp 中。此外,在头文件 boost/dynamic_bitset_fwd.hpp 中有dynamic_bitset的前向声明。

模板参数

Parameter 描述 Default
Block 用于存储位的整数类型。 unsigned long
Allocator 所有内部内存管理使用的分配器类型。 std::allocator<Block>

建模的概念

可赋值(Assignable)可默认构造(Default Constructible)可相等比较(Equality Comparable)可小于比较(LessThan Comparable)

类型要求

Block是一个无符号整数类型。Allocator满足标准对分配器的要求。

公共基类

无。

嵌套类型名称


dynamic_bitset::reference

一个代理类,用作单个位的引用。它包含一个赋值运算符、一个到bool的转换、一个operator~和一个成员函数flip。它仅作为dynamic_bitsetoperator[]的辅助类存在。下表描述了对reference类型的有效操作。假设b是的一个实例dynamic_bitset, i, jsize_type类型,且在范围[0,b.size())内。另外,请注意当我们写b[i]时,我们指的是一个从reference初始化的b[i]类型的对象。变量xbool.

表达式 语义
x = b[i] bx.
(bool)b[i] 返回b.
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的值并返回b[i].
b[i] |= b[j] b的第 i 位与b的值并返回b[i].
b[i] &= b[j] b的第 i 位与b的值并返回b[i].
b[i] ^= b[j] b的第 i 位与b的值并返回b[i].
b[i] -= b[j] 如果b的第 j 位已设置,则清除b的第 i 位。返回b[i].
x = ~b[i] bx.
(bool)~b[i] 返回b.
b[i].flip() 翻转b的值并返回b[i].

dynamic_bitset::const_reference
类型bool.
dynamic_bitset::size_type
用于表示位集大小的无符号整数类型。
dynamic_bitset::block_type
Block.
dynamic_bitset::allocator_type;
Allocator.

公开数据成员

dynamic_bitset::bits_per_block
类型Block用于表示值的位数,不包括任何填充位。数值上等于std::numeric_limits<Block>::digits.
dynamic_bitset::npos
的最大值。size_type.

构造函数


dynamic_bitset()
效果:构造一个大小为零的位集。此位集的分配器是一个默认构造的Allocator.
后置条件 this->size() == 0.
抛出:除非Allocator的默认构造函数抛出异常。
可默认构造 的要求。)
dynamic_bitset(const Allocator& alloc)
效果:构造一个大小为零的位集。一个分配器对象的副本将在后续的位集操作(例如resize)中用于分配内存。
后置条件 this->size() == 0.
抛出:无。
dynamic_bitset(size_type num_bits,
               unsigned long value = 0,
               const Allocator& alloc = Allocator())
效果:从一个整数构造位集。前M个位被初始化为value中对应的位,所有其他位(如果有的话)被初始化为零(其中M = min(num_bits, std::numeric_limits<unsigned long>::digits))。一个分配器对象的副本将在后续的位集操作(例如resize对象的副本将用于分配内存。请注意,例如,以下代码

dynamic_bitset b<>( 16, 7 );

将匹配从迭代器范围构造的构造函数(而不是这一个),但底层实现仍会“做正确的事”,即从值 7 构造一个 16 位的位集。
后置条件
  • this->size() == num_bits
  • 对于所有i个在范围[0,M), (*this)[i] == (value >> i) & 1.
  • 对于所有i个在范围[M,num_bits), (*this)[i] == false.
抛出:如果内存耗尽,则抛出分配错误(std::bad_allocifAllocator=std::allocator).

dynamic_bitset(const dynamic_bitset& x)
效果:构造一个位集,它是位集x的副本。此位集的分配器是x.
后置条件:对于所有i个在范围[0,x.size()), (*this)[i] == x[i].
抛出:如果内存耗尽,则抛出分配错误(std::bad_allocifAllocator=std::allocator).
可赋值 的要求。)
dynamic_bitset(dynamic_bitset&& x)
效果:构造一个与位集x相同的位集,同时使用来自x的资源。此位集的分配器是从x.
后置条件:对于所有i个在范围[0,x.size()), (*this)[i] == x[i].
抛出:如果内存耗尽,则抛出分配错误(std::bad_allocifAllocator=std::allocator).
template <typename BlockInputIterator>
explicit
dynamic_bitset(BlockInputIterator first, BlockInputIterator last,
               const Allocator& alloc = Allocator());
效果
  • 如果使用一个BlockInputIterator类型调用此构造函数,而该类型实际上是一个整型,则库的行为就像调用了从unsigned long构造的构造函数一样,参数依次为static_cast<size_type>(first), last 和 alloc

    示例
    // 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);
    

    注意
    在撰写本文时(2008年10月),这与库问题438的提议解决方案保持一致。这是一个C++03 的变更,目前在C++0x的工作草案中。通俗地说,相对于C++03的关键变化是去掉了对第二个参数的static_cast,以及在何时模板化构造函数应具有与(大小,值)构造函数相同效果方面给予了更多 leeway:在InputIterator中,仅当该类型是整型时;在提议的解决方案中,当它是整型或实现可能检测到不可能是输入迭代器的任何其他类型时。为了C++03的目的dynamic_bitset,我们仅限于这两项变更中的第一项。

  • 否则,如果模板参数不是整型),则在requires子句的条件下,基于一个块范围构造一个位集。令*first为块号 0,*++first为块号 1,依此类推。块号b用于初始化 dynamic_bitset 在位置范围[b*bits_per_block, (b+1)*bits_per_block)内的位。对于每个值为b的块号bval,位(bval >> i) & 1对应于位集中位置为(b * bits_per_block + i)的位(其中i遍历范围[0, bits_per_block)).

要求 BlockInputIterator必须是整型或输入迭代器的模型,其value_typeBlock.
抛出:如果内存耗尽,则抛出分配错误(std::bad_allocifAllocator=std::allocator).

template<typename Char, typename Traits, typename Alloc>
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())
前置条件 pos <= s.size()且用于初始化位的字符必须是01.
效果:从一个由 0 和 1 组成的字符串构造位集。前M个位被初始化为s,其中M = min(s.size() - pos, n)中对应的字符。注意,字符串s最高的字符位置,而不是最低的,对应于最低有效位。也就是说,字符位置pos + M - 1 - i对应于位i。因此,例如,dynamic_bitset(string("1101"))与此相同dynamic_bitset(13ul).
抛出:如果内存耗尽,则抛出分配错误(std::bad_allocifAllocator=std::allocator).

析构函数


~dynamic_bitset()
效果:释放与此位集关联的内存并销毁位集对象本身。
抛出:无。

成员函数


void swap(dynamic_bitset& b);
效果:此位集与位集b的内容进行交换。
后置条件:此位集等于原来的bb,而
抛出:无。
dynamic_bitset& operator=(const dynamic_bitset& x)
效果:此位集成为位集x.
后置条件:对于所有i个在范围[0,x.size()), (*this)[i] == x[i].
返回 *this.
抛出:无。
可赋值 的要求。)
dynamic_bitset& operator=(dynamic_bitset&& x)
效果:此位集变得与位集x相同的位集,同时使用来自x.
后置条件:对于所有i个在范围[0,x.size()), (*this)[i] == x[i].
返回 *this.
抛出:如果内存耗尽,则抛出分配错误(std::bad_allocifAllocator=std::allocator).
allocator_type get_allocator() const;
返回:用于构造*this.
void resize(size_type num_bits, bool value = false);
效果:将位集的位数更改为num_bits。如果num_bits > size(),则范围[0,size())内的位保持不变,而[size(),num_bits)中的位全部设置为value。如果num_bits < size(),则范围[0,num_bits)保持不变(其余位被丢弃)。
后置条件 this->size() == num_bits.
抛出:如果内存耗尽,则抛出分配错误(std::bad_allocifAllocator=std::allocator).

void clear()
效果:位集的大小变为零。
抛出:无。
void pop_back();
前置条件 !this->empty().
效果:将位集的大小减一。
抛出:无。
void push_back(bool value);
效果:将位集的大小加一,并将新的最高有效位的值设置为value.
抛出:如果内存耗尽,则抛出分配错误(std::bad_allocifAllocator=std::allocator).

void append(Block value);
效果:value中的位追加到位集中(追加到最高有效位端)。这将位集的大小增加bits_per_block。令s为位集的旧大小,则对于i个在范围[0,bits_per_block),位集中位置(s + i)被设置为((value >> i) & 1).
抛出:如果内存耗尽,则抛出分配错误(std::bad_allocifAllocator=std::allocator).

template <typename BlockInputIterator>
void append(BlockInputIterator first, BlockInputIterator last);
效果:此函数提供与以下代码相同的结果,但通常更高效。
for (; first != last; ++first)
  append(*first);
要求:BlockInputIterator类型必须是输入迭代器的模型,并且value_type必须与Block.
抛出:如果内存耗尽,则抛出分配错误(std::bad_allocifAllocator=std::allocator).

dynamic_bitset& operator&=(const dynamic_bitset& rhs)
要求 this->size() == rhs.size().
效果:将此位集中的所有位与rhs中的位进行按位与(AND)运算。这等同于
for (size_type i = 0; i != this->size(); ++i)
  (*this)[i] = (*this)[i] & rhs[i];
返回 *this.
抛出:无。
dynamic_bitset& operator|=(const dynamic_bitset& rhs)
要求 this->size() == rhs.size().
效果:将此位集中的所有位与rhs中的位进行按位与(AND)运算。这等同于
for (size_type i = 0; i != this->size(); ++i)
  (*this)[i] = (*this)[i] | rhs[i];
返回 *this.
抛出:无。
dynamic_bitset& operator^=(const dynamic_bitset& rhs)
要求 this->size() == rhs.size().
效果:将此位集中的所有位与rhs中的位进行按位与(AND)运算。这等同于
for (size_type i = 0; i != this->size(); ++i)
  (*this)[i] = (*this)[i] ^ rhs[i];
返回 *this.
抛出:无。
dynamic_bitset& operator-=(const dynamic_bitset& rhs)
要求 this->size() == rhs.size().
效果:计算此位集与rhs位集的差集。这等同于
for (size_type i = 0; i != this->size(); ++i)
  (*this)[i] = (*this)[i] && !rhs[i];
返回 *this.
抛出:无。
dynamic_bitset& operator<<=(size_type n)
效果:将此位集中的位向左移动n位。对于位集中的每个位,位置 pos 上的位取位置pos - n上位的先前值,如果不存在这样的位,则为零。
返回 *this.
抛出:无。
dynamic_bitset& operator>>=(size_type n)
效果:将此位集中的位向右移动n位。对于位集中的每个位,位置pos上的位取位pos + n上位的先前值,如果不存在这样的位,则为零。
返回 *this.
抛出:无。
dynamic_bitset operator<<(size_type n) const
返回:一个*this向左移动n位的副本。对于返回的位集中的每个位,位置 pos 上的位取此位集中位置pos - n处位的值,如果不存在这样的位,则为零。
抛出:如果内存耗尽,则抛出分配错误(std::bad_allocifAllocator=std::allocator).
dynamic_bitset operator>>(size_type n) const
返回:一个*this向右移动n位的副本。对于返回的位集中的每个位,位置 pos 上的位取此位集中位置pos + n处位的值,如果不存在这样的位,则为零。
抛出:如果内存耗尽,则抛出分配错误(std::bad_allocifAllocator=std::allocator).
dynamic_bitset& set()
效果:将此位集中的每个位设置为 1。
返回 *this
抛出:无。
dynamic_bitset& flip()
效果:翻转此位集中每个位的值。
返回 *this
抛出:无。
dynamic_bitset operator~() const
返回:一个*this所有位都被翻转的副本。
抛出:如果内存耗尽,则抛出分配错误(std::bad_allocifAllocator=std::allocator).
dynamic_bitset& reset()
效果:清除此位集中的每个位。
返回 *this
抛出:无。
dynamic_bitset& set(size_type n, size_type len, bool val);
前置条件 n + len < this->size().
效果:如果nn + len - 1,则设置从valtrue到(含)的所有位,如果valfalse.
返回 *this
dynamic_bitset& set(size_type n, bool val = true)
前置条件 n < this->size().
效果:设置位nifvaltrue,并清除位nifvalfalse.
返回 *this
dynamic_bitset& reset(size_type n, size_type len);
前置条件 n + len < this->size().
效果:清除从nn + len - 1到(含)的所有位。
返回 *this
dynamic_bitset& reset(size_type n)
前置条件 n < this->size().
效果:清除位n.
返回 *this
dynamic_bitset& flip(size_type n, size_type len)
前置条件 n + len < this->size().
效果:翻转从nn + len - 1到(含)的所有位。
返回 *this
dynamic_bitset& flip(size_type n)
前置条件 n < this->size().
效果:翻转位n.
返回 *this
size_type size() const
返回:此位集中的位数。
抛出:无。
size_type num_blocks() const
返回:此位集中的块数。
抛出:无。
size_type max_size() const;
返回:一个与dynamic_bitset类型相同的*this对象的最大大小。请注意,如果任何dynamic_bitset操作导致size()超过max_size(),则行为是未定义的

[当库问题197关闭时,此函数的语义可能会略有变化]

bool empty() const;
返回 trueifthis->size() == 0, false,否则返回none(),其语义不同。
size_type capacity() const;
返回:*this可以容纳而无需重新分配的总元素数。
抛出:无。
void reserve(size_type num_bits);
效果:一个指令,通知位集计划的大小变化,以便它可以相应地管理存储分配。在 reserve() 之后,如果发生重新分配,capacity() 大于或等于 reserve() 的参数;否则等于 capacity() 的先前值。当且仅当当前容量小于 reserve() 的参数时,才会发生重新分配。
注意:它不会改变位集的 size()。
后置条件 this->capacity() >= num_bits.
抛出:如果内存耗尽,则抛出分配错误(std::bad_allocifAllocator=std::allocator).
void shrink_to_fit();
效果:shrink_to_fit() 是一个通过移除未使用的容量来减少内存使用的请求。
注意:它不会改变位集的 size()。
抛出:如果内存耗尽,则抛出分配错误(std::bad_allocifAllocator=std::allocator).
size_type count() const
返回:此位集中被设置为 1 的位数。
抛出:无。
bool all() const
返回 true如果此位集中的所有位都被设置或size() == 0,否则返回false.
抛出:无。
bool any() const
返回 true如果此位集中有任何位被设置,否则返回false.
抛出:无。
bool none() const
返回 true如果没有任何位被设置,否则返回false.
抛出:无。
reference at(size_type n)
前置条件 n < this->size().
返回:operator[](n).
抛出 std::out_of_range如果该n不在位集的范围内。
bool at(size_type n) const
前置条件 n < this->size().
返回:operator[](n).
抛出 std::out_of_range如果该n不在位集的范围内。
bool test(size_type n) const
前置条件 n < this->size().
返回 true如果位n被设置,false如果位n为 0。
bool test_set(size_type n, bool val = true)
前置条件 n < this->size().
效果:设置位nifvaltrue,并清除位nifvalfalse.
返回 true如果位n的先前状态是设置的,false如果位n为 0。
reference operator[](size_type n)
前置条件 n < this->size().
返回:一个reference到位的n。请注意reference是一个代理类,具有赋值运算符和到bool的转换,这允许您使用operator[]进行赋值。也就是说,您可以同时写x = b[n]andb[n] = x。然而,在许多其他方面,该代理与真正的引用类型bool&.
bool operator[](size_type n) const
前置条件 n < this->size().
返回:test(n).
unsigned long to_ulong() const
返回:*this.
抛出 std::overflow_error中的位对应的数值,如果该值太大无法在unsigned long中表示,即如果*this在位置>= std::numeric_limits<unsigned long>::digits.
bool is_subset_of(const dynamic_bitset& a) const
要求 this->size() == a.size()
返回:如果此位集是位集a的子集,则返回 true。也就是说,如果此位集中设置的每个位,在位集a中对应的位也被设置,则返回 true。否则此函数返回 false。
抛出:无。
bool is_proper_subset_of(const dynamic_bitset& a) const
要求 this->size() == a.size()
返回:如果此位集是位集a的子集,则返回 true。也就是说,如果此位集中设置的每个位,在位集a的真子集,则返回 true。也就是说,如果此位集中设置的每个位,在位集this->count() < a.count()中对应的位也被设置,并且
抛出:无。
bool intersects(const dynamic_bitset& a) const
要求 this->size() == a.size()
返回:如果此位集与a相交,则返回 true。也就是说,如果此位集中有一个位被设置,使得位集a中对应的位也被设置,则返回 true。否则此函数返回 false。
抛出:无。
size_type find_first() const;
返回:使得位i被设置的最小索引i,或者如果nposif*this中没有置位的位,则返回
size_type find_first(size_type pos) const;
返回:使得位i,如果不存在这样的索引,则返回offset被设置的最小索引i,或者如果npos且对于所有
size_type find_next(size_type pos) const;
返回:使得位i大于pos被设置的最小索引i,或者如果npos且对于所有
bool operator==(const dynamic_bitset& rhs) const
返回 trueifthis->size() == rhs.size()[0,rhs.size())i个在范围,都有, (*this)[i] == rhs[i]。否则返回false.
抛出:无。
可相等比较 的要求。)
bool operator!=(const dynamic_bitset& rhs) const
返回 !((*this) == rhs)
抛出:无。
可相等比较 的要求。)
bool operator<(const dynamic_bitset& rhs) const
返回 true如果此位集在字典序上小于rhs,则返回false,否则返回
抛出:无。
可小于比较 的要求。)
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()
返回:一个新的位集,它是位集aandb.
抛出:如果内存耗尽,则抛出分配错误(std::bad_allocifAllocator=std::allocator).
dynamic_bitset operator|(const dynamic_bitset& a, const dynamic_bitset& b)
要求 a.size() == b.size()
返回:一个新的位集,它是位集aandb.
抛出:如果内存耗尽,则抛出分配错误(std::bad_allocifAllocator=std::allocator).
dynamic_bitset operator^(const dynamic_bitset& a, const dynamic_bitset& b)
要求 a.size() == b.size()
返回:一个新的位集,它是位集aandb.
抛出:如果内存耗尽,则抛出分配错误(std::bad_allocifAllocator=std::allocator).
dynamic_bitset operator-(const dynamic_bitset& a, const dynamic_bitset& b)
要求 a.size() == b.size()
返回:一个新的位集,它是位集aandb.
抛出:如果内存耗尽,则抛出分配错误(std::bad_allocifAllocator=std::allocator).
template <typename CharT, typename Alloc>
void to_string(const dynamic_bitset<Block, Allocator>& b,
               std::basic_string<Char,Traits,Alloc>& s)
效果:b的表示复制到字符串s中。如果对应的位被设置,则字符串中的字符为'1',如果未设置,则为'0'。字符串中的字符位置i对应于位位置b.size() - 1 - i.
抛出:如果内存耗尽,字符串将抛出分配错误。
基本原理:此函数不是一个不带参数并返回字符串的成员函数,原因有几个。首先,这个版本可能稍微更高效,因为字符串没有被复制(由于是按值传递)。其次,作为成员函数,为了允许在basic_string的模板参数方面具有灵活性,该成员函数将需要显式模板参数。很少有 C++ 程序员熟悉显式模板参数,并且一些 C++ 编译器不能正确处理它们。
template <typename Block, typename Alloc, typename BlockOutputIterator>
void to_block_range(const dynamic_bitset<Block, Alloc>& b, BlockOutputIterator result)
效果:将位集的位一次一个块地写入迭代器result。写入的第一个块表示位集中位置范围[0,bits_per_block)内的位,写入的第二个块表示范围[bits_pre_block,2*bits_per_block)内的位,依此类推。对于每个写入的块bval,位(bval >> i) & 1对应于位集中位置为(b * bits_per_block + i)在位集中。
要求:类型BlockOutputIterator必须是输出迭代器的模型,并且其value_type必须与Block。此外,输出范围的大小必须大于或等于b.num_blocks().
template <typename BlockIterator, typename Block, typename Alloc>
void from_block_range(BlockIterator first,
    BlockIterator last, const dynamic_bitset<Block, Alloc>& b)
效果:从迭代器范围读取块到此位集中。
要求:类型BlockIterator必须是输入迭代器的模型,并且其value_type必须与Block。迭代器范围的大小必须小于或等于b.num_blocks().
template <typename Char, typename Traits, typename Block, typename Alloc>
basic_ostream<Char, Traits>&
operator<<(basic_ostream<Char, Traits>& os, const dynamic_bitset<Block, Alloc>& b)
效果:将 b 的文本表示插入到流os中(最高位在前)。通俗地说,输出与执行
std::basic_string<Char, Traits> s;
boost::to_string(x, s):
os << s;
相同,但流插入器会考虑注入到os中的区域设置,而boost::to_string()无法做到这一点。以下是一个更精确的规范,以“如同”规则给出:首先,对于位集b中的每个有效位置 i,我们令character_of(b[i)]) = b[i]? os.widen('1') : os.widen('0');再令s为一个std::basic_string<Char, Traits>对象,其长度为b.size(),且对于每个iin[0, b.size()), s[i] 是 character_of(b[i])。那么,输出、对os的影响以及异常行为与输出对象sos相同(相同的宽度、相同的异常掩码、相同的填充、相同的 setstate() 逻辑)。
返回: os
抛出 std::ios_base::failure如果在写入流时出现问题。
template <typename Char, typename Traits, typename Block, typename Alloc>
std::basic_istream<Char,Traits>&
operator>>(std::basic_istream<Char,Traits>& is, dynamic_bitset<Block, Alloc>& b)
效果:从输入流中提取一个dynamic_bitset

定义

Tris 的 traits_type。那么
  1. 一个从c中提取的(非 eof)字符是一个位集数字,当且仅当 Tr::eq(c, is.widen('0')) 或 Tr::eq(c, is.widen('1')) 返回 true。
  2. 如果 c 是一个位集数字,其对应的位值为 0(如果 Tr::eq(c, is.widen('0')) 为 true),否则为 1。
该函数首先构造一个sentryboost::extentsk对象,如同k通过typename std::basic_istream<Char, Traits>::sentry k(is)。如果bool(k)为 true,它会调用b.clear(),然后尝试从中提取字符。对于每个作为位集数字的字符 c,其对应的位值被追加到b的最低有效位端(追加可能会抛出异常)。如果is.width()大于零且小于b.max_size(),则追加的位的最大数量为n。除非提取器因异常而退出,否则将一直提取字符(并追加相应的位),直到发生以下任一情况:is.width()关联的值类型;否则n = b.max_size()位被存储到此位集中;
  • n输入序列上发生文件结束或错误;
  • 下一个可用的输入字符不是位集数字。
  • 如果没有异常导致函数退出,则会调用

is.width(0),无论实际提取了多少字符。哨兵对象 k 被销毁。如果函数没有提取任何字符[???],它会调用 is.setstate(std::ios::failbit),这可能会抛出

)。一个std::ios_base::failure.
------
抛出:如果内存耗尽,则抛出分配错误(std::bad_allocifAllocator=std::allocator如果在从流中读取时出现问题。std::ios_base::failure函数提供至少基本的异常保证。

异常保证

所有dynamic_bitsetBoost 1.56.0 中的变更

与先前版本的变化

支持 C++11 移动构造函数。

  • 修复了 MSVC 2013 上的警告。
  • 支持 C++11 最小分配器。
  • 添加 noexcept 规范。
  • Boost 1.37.0 中的变更

从块范围构造的构造函数实现了“做正确的事”的行为,类似于标准序列。

  • 与 Boost 1.31.0 的变化

流提取器具有完全不同的语义:对于动态结构来说,它现在在提取期间根据需要扩展位集,这是很自然的。新的行为模仿了

  • 提取器的行为,但存在一些用户应该注意的差异;因此,请检查文档。(一个差异涉及 stream.width() > bitset.max_size() > 0 的情况。在这种情况下,basic_string的提取器从不尝试提取超过dynamic_bitset个字符,而max_size()的提取器会继续,并且在符合规范的实现上,最终会抛出basic_string异常。注意:这是标准强制要求的——尤其参见库问题83——但并非所有实现都符合)length_error流提取器现在也是“异常感知”的,即在流上设置异常掩码时它能正确工作。

    添加了几个成员函数(

  • find_next()empty(), find_first() , intersects(), get_allocator(), )。 , max_size()
  • 构造的构造函数有一个新的参数,之前完全被遗忘了。basic_string技术细节和次要变更
已被重新实现,以便 dynamic_bitset 的引用行为更像标准容器元素的引用。特别是,现在保证它们不会因为应用于其对应
  • references 的标准库 swap() 函数而失效。dynamic_bitset一般性改进
对成员和非成员函数以及嵌套类
  • 进行了多项优化。reference.

另请参阅

std::bitset, std::vector,

致谢

我们要感谢 Boost 社区花时间审查并接受这个库。由于 Boost 成员提出的所有建议,这个库比以往任何时候都更好。我们特别感谢 Matt Marcus 承担了审查经理的任务。此外,特别感谢 James Kanze 在国际化问题上提供的宝贵帮助。

版权所有 © 2001 Jeremy Siek, Indiana University (jsiek@osl.iu.edu)
Chuck Allison, C/C++ Users Journal 高级编辑 (cda@freshsources.com)
版权所有 © 2003-2004, 2008 Gennaro Prota (name.surname yahoo.com)
版权所有 © 2014 Ahmed Charles (acharles@outlook.com)
版权所有 © 2014 Glen Fernandes (glenjofe@gmail.com)
版权所有 © 2014 Riccardo Marcangelo (ricky.65@outlook.com)

根据 Boost 软件许可证 1.0 版分发。(参见附带文件 LICENSE_1_0.txt 或在 https://boost.ac.cn/LICENSE_1_0.txt 获取副本)