STL源码分析--bitset

简介: STL源码分析--bitset
  • 1 相关头文件


  • 2 bitset


  • 2.1 数据结构


  • 2.2 重要接口




1 相关头文件


bitset


2 bitset


bitset中STL中用于表示位图的容器,它支持读写特定bit、从整数或字符串生成bitset对象。bitset大小通过模板参数指定,一旦编译器确定便无法变更,这一点与vector<bool>有差异。



2.1 数据结构


bitset_Base_bitset的派生类。_Base_bitset中包含一个长度_Nw,类型unsigned long的数组,其中_Nw通过模板参数指定。在64位系统中,unsigned long长度为8 Byte。


注意,这里_Nb不一定是8 * sizeof(unsigned)的整数倍,所以需要宏__BITSET_WORDS对其进行向上取整操作。


template<size_t _Nb>
class bitset : private _Base_bitset<__BITSET_WORDS(_Nb)>
{
private:
  typedef _Base_bitset<__BITSET_WORDS(_Nb)> _Base;
  typedef unsigned long _WordT;
  ...
}
template<size_t _Nw>
struct _Base_bitset {
  typedef unsigned long _WordT;
  _WordT _M_w[_Nw];                // 0 is the least significant word.
  ...
}




2.2 重要接口


  • 从整数构造bitset



首先对数组清零,然后将__val值赋给数组的首个元素。最后使用_M_do_sanitize判断_Nb是不是sizeof(unsigned long)的整数倍,否则将right padding bits全部置为1。



bitset(unsigned long __val) : _Base_bitset<__BITSET_WORDS(_Nb)>(__val) 
    { _M_do_sanitize(); }
  _Base_bitset(unsigned long __val) {
    _M_do_reset();
    _M_w[0] = __val;
  }
  void _M_do_sanitize() {
    _Sanitize<_Nb%__BITS_PER_WORD>::_M_do_sanitize(this->_M_hiword());
  }
template <size_t _Extrabits> struct _Sanitize {
  static void _M_do_sanitize(unsigned long& __val)
    { __val &= ~((~static_cast<unsigned long>(0)) << _Extrabits); }
};
__STL_TEMPLATE_NULL struct _Sanitize<0> {
  static void _M_do_sanitize(unsigned long) {}
};



  • 从字符串构造bitset



由字符'0', '1'组成的字符串构造bitset。注意: 字符串从左到右,对应的bit在bitset中从右到左。因为字符串中, 左边为高位,bitset中右边为高位。

explicit bitset(const basic_string<char>& __s,
                  size_t __pos = 0,
                  size_t __n = basic_string<char>::npos) 
    : _Base() 
  {
    if (__pos > __s.size()) 
      __STL_THROW(out_of_range("bitset"));
    _M_copy_from_string(__s, __pos, __n);
  }


  • to_ulong: 将bitset转化为ulong类型


  • to_string: 将bitset转化为'0' '1'组成的字符串


  • <<=: 逻辑左移,移出部分补零。注意:在实现上,数组_M_w中低位对应bitset中低位,因此,对bitset的左移操作其实就是对数组的右移操作,右移同理。如果移动位数是8 * sizeof(unsigned long)的整数倍,则直接移动数组中元素即可。


const size_t __sub_offset = __BITS_PER_WORD - __offset;
      for (size_t __n = _Nw - 1; __n > __wshift; --__n)
        _M_w[__n] = (_M_w[__n - __wshift] << __offset) | 
                    (_M_w[__n - __wshift - 1] >> __sub_offset);
      _M_w[__wshift] = _M_w[0] << __offset;
    }



  • >>=: 逻辑右移


const size_t __sub_offset = __BITS_PER_WORD - __offset;
      for (size_t __n = 0; __n < __limit; ++__n)
        _M_w[__n] = (_M_w[__n + __wshift] >> __offset) |
                    (_M_w[__n + __wshift + 1] << __sub_offset);
      _M_w[__limit] = _M_w[_Nw-1] >> __offset;



  • |=: 按位或


  • &=: 按位与


  • ^+: 按位异或


  • set: 置位


  • reset: 清零


  • flip: 翻转


  • ~: 全部翻转


  • count: count为了快速计算bitset中1的个数,使用了查找表的技巧。查找表中key为byte值,value为该byte值中1的个数。count方法遍历数组中每个字节,通过查找表计算每个字节中1的个数,并累加之。


  • size: 返回bitset大小


  • test:  判断bitset中某位是否为1


  • any:  判断bitset中是否有至少一个1


  • none: 同any相反


  • all: 判断bitset中是否全为1


留下问题给读者思考:为何bitset中的数组类型是unsigned long而非unsigned char?

相关文章
|
Unix Linux 开发工具
git中有关old mode 100644、new mode 10075的问题解决小结
在 Git 中处理文件权限变更时,理解 `old mode 100644` 和 `new mode 100755` 的含义是解决问题的关键。通过确认变更的合理性、修改不必要的权限变更,以及配置 Git 忽略权限变更,可以有效管理文件权限,确保版本库的稳定性和一致性。
1236 3
|
NoSQL
技术分享:如何使用GDB调试不带调试信息的可执行程序
【8月更文挑战第27天】在软件开发和调试过程中,我们有时会遇到需要调试没有调试信息的可执行程序的情况。这可能是由于程序在编译时没有加入调试信息,或者调试信息被剥离了。然而,即使面对这样的挑战,GDB(GNU Debugger)仍然提供了一些方法和技术来帮助我们进行调试。以下将详细介绍如何使用GDB调试不带调试信息的可执行程序。
450 0
|
存储 设计模式 分布式计算
分布式系统架构(一)——Master-Workers 架构
分布式系统架构(一)——Master-Workers 架构
714 0
分布式系统架构(一)——Master-Workers 架构
|
消息中间件 Java C++
开源项目推荐:多进程和多线程的高性能消息队列(无锁队列),lock-free queue
开源项目推荐:多进程和多线程的高性能消息队列(无锁队列),lock-free queue
1782 0
|
1天前
|
存储 机器学习/深度学习 人工智能
打破硬件壁垒!煎饺App:强悍AI语音工具,为何是豆包AI手机平替?
直接上干货!3000 字以上长文,细节拉满,把核心功能、使用技巧和实测结论全给大家摆明白,读完你就知道这款 “安卓机通用 AI 语音工具"——煎饺App它为何能打破硬件壁垒?它接下来,咱们就深度拆解煎饺 App—— 先给大家扒清楚它的使用逻辑,附上“操作演示”和“🚀快速上手不踩坑 : 4 条核心操作干货(必看)”,跟着走零基础也能快速上手;后续再用真实实测数据,正面硬刚煎饺 App的语音助手口令效果——创建京东「牛奶自动下单神器」口令 ,从修改口令、识别准确率到场景实用性,逐一测试不掺水,最后,再和豆包 AI 手机语音助手的普通版——豆包App对比测试下,简单地谈谈煎饺App的能力边界在哪?
|
3天前
|
云安全 监控 安全
|
8天前
|
机器学习/深度学习 人工智能 自然语言处理
Z-Image:冲击体验上限的下一代图像生成模型
通义实验室推出全新文生图模型Z-Image,以6B参数实现“快、稳、轻、准”突破。Turbo版本仅需8步亚秒级生成,支持16GB显存设备,中英双语理解与文字渲染尤为出色,真实感和美学表现媲美国际顶尖模型,被誉为“最值得关注的开源生图模型之一”。
1063 5
|
10天前
|
机器学习/深度学习 人工智能 数据可视化
1秒生图!6B参数如何“以小博大”生成超真实图像?
Z-Image是6B参数开源图像生成模型,仅需16GB显存即可生成媲美百亿级模型的超真实图像,支持中英双语文本渲染与智能编辑,登顶Hugging Face趋势榜,首日下载破50万。
710 42
|
14天前
|
人工智能 Java API
Java 正式进入 Agentic AI 时代:Spring AI Alibaba 1.1 发布背后的技术演进
Spring AI Alibaba 1.1 正式发布,提供极简方式构建企业级AI智能体。基于ReactAgent核心,支持多智能体协作、上下文工程与生产级管控,助力开发者快速打造可靠、可扩展的智能应用。
1144 41

热门文章

最新文章