#ifndef __BITARRAY__  //数组不支持多线程同时访问,没有对引用计数以及分配的资源做任何锁处理
#define __BITARRAY__ 1 //越界访问修改为抛出异常 #ifdef __BIT_DEBUG__  //__BIT_DEBUG__是调试用的宏定义
#include <cstdio>
#endif #ifdef __cplusplus > 201103L
#include <cstdint>
#else
#include <stdint.h>
#define nullptr NULL
#define noexcept throw()
#endif #define __BIT_ERRMSG_LEN__ 512 #include <cstring>
#include <stdexcept> class BitArray
{
private:
enum __e_bit_size {bit = }; class __Ref_Array  //引用计数类
{
public:
__Ref_Array(int64_t __size)
:m_ref_count(), m_size(__size)
{
#ifdef __BIT_DEBUG__
fprintf(stderr, "__Ref_Array ctor @addr: %p with size:%ld\n", this, __size);
#endif
init();
} ~__Ref_Array()
{
#ifdef __BIT_DEBUG__
fprintf(stderr, "__Ref_Array dtor @addr: %p with size:%ld\n", this, __size);
#endif
delete[] m_array;
} __Ref_Array(const __Ref_Array& o)
:m_ref_count(),
m_size(o.m_size),
m_array_size(o.m_array_size),
m_used(o.m_used)
{
#ifdef __BIT_DEBUG__
fprintf(stderr, "__Ref_Array copytor @addr: %p with @addr: %p && size:%ld\n", this, &o, __size);
#endif
m_array = new int8_t[m_array_size];
memcpy(m_array, o.m_array, m_array_size);
} inline bool
get(int64_t __pos) const
{return *(m_array + slot_bit(__pos)) & mask(__pos);} inline void
set(int64_t __pos)
{
*(m_array + slot_bit(__pos)) |= mask(__pos);
m_used ++;
} inline void
clear(int64_t __pos)
{
*(m_array + slot_bit(__pos)) &= ~mask(__pos);
m_used --;
} inline void
reset()
{
std::memset(m_array, , m_array_size);
m_used = ;
} inline int64_t
length() const
{return m_size;} inline int64_t
size() const
{return m_size;} inline int64_t
used() const
{return m_used;} inline int64_t
refCount() const
{return m_ref_count;} inline bool
sizeRange(int64_t __pos) const
{return __pos >= && __pos < m_size;} inline int64_t
sharedPlus()
{return ++ m_ref_count;} inline int64_t
sharedSub()
{return -- m_ref_count;} inline bool
isShared() const
{return m_ref_count > ;} private:
inline void
init()
{
m_array_size = nslot(m_size);
m_array = new int8_t[m_array_size];
reset();
} inline int64_t
slot_bit(int64_t __n) const
{return __n / bit;} inline int64_t
nslot(int64_t __size) const
{return slot_bit(__size + bit - );} inline int8_t
mask(int64_t __pos) const
{return int8_t() << (__pos % bit);} private:
int8_t m_array;    //位数组存储
int64_t m_ref_count; //引用计数
int64_t m_size;    //引用计数大小
int64_t m_array_size;  //分配的int8_t数组大小
int64_t m_used;      //已经使用的bit位数
}; private:
class BitProxy  //代理类 为了区分 x = ba[?]; 和 ba[?];
{
BitProxy(BitArray& ba, int64_t pos)
:m_array(ba), m_pos(pos)
{} BitProxy& operator = (const BitProxy& rh)
{
if(rh)
m_array.set(m_pos);
else{
m_array.clear(m_pos);
} return *this;
} BitProxy& operator = (bool status)
{
if(status)
m_array.set(m_pos);
else{
m_array.clear(m_pos);
} return *this;
} operator bool() const
{
return m_array.get(m_pos);
} private:
BitArray& m_array;
int64_t m_pos;
}; public: BitArray() noexcept //无参数构造函数
:m_ref(nullptr)
{
#ifdef __BIT_DEBUG__
fprintf(stderr, "BitArray ctor @addr: %p with nullptr ...\n", this);
#endif
} BitArray(int64_t size) noexcept //构造函数
:m_ref(size > new __Ref_Array(size) : nullptr)
{
#ifdef __BIT_DEBUG__
fprintf(stderr, "BitArray ctor @addr: %p with size: %d ...\n", this, size);
#endif
} ~BitArray()  //析构函数
{release()} BitArray(const BitArray& o) noexcept  //copy构造函数
m_ref(o.m_ref)
{
#ifdef __BIT_DEBUG__
fprintf(stderr, "BitArray copy tor @addr: %p with other BitArray @addr: %p ...\n", this, &o);
#endif
} #ifdef __cplusplus >= 201103L
BitArray(BitArray&& o) noexcept  //move构造函数
m_ref(o.m_ref)
{
#ifdef __BIT_DEBUG__
fprintf(stderr, "BitArray move tor @addr: %p <--- other BitArray @addr: %p ...\n", this, &o);
#endif
o.m_ref = nullptr;
}
#endif BitArray& operator=(const BitArray& o)  //赋值运算符
{
if(m_ref != o.m_ref)
{
release();
m_ref = o.m_ref;
#ifdef __BIT_DEBUG__
fprintf(stderr, "BitArray assign @addr: %p with other BitArray @addr: %p ...\n", this, &o);
#endif
if(m_ref)
m_ref->sharedPlus();
}
} const BitProxy
operator[] (int64_t pos) const  //下标运算符
{return BitProxy(const_cast<BitArray&>(*this), pos);} BitProxy
operator[] (int64_t pos)  //下标运算符
{return BitProxy(*this, pos);} public:
inline bool
get(int64_t pos) const throw(std::out_of_range)
{
if(!m_ref || !m_ref->sizeRange(pos))
{
char errmsg[__BIT_ERRMSG_LEN__] = {}; snprintf(errmsg, sizeof(errmsg), "out of range in get -> pos : %d | size : %d\n", pos, size()); throw std::out_of_range(errmsg);
}
else
return m_ref->get(pos);
} inline bool
set(int64_t pos) const throw(std::out_of_range)
{
if(!m_ref || !m_ref->sizeRange(pos))
{
char errmsg[__BIT_ERRMSG_LEN__] = {}; snprintf(errmsg, sizeof(errmsg), "out of range in set -> pos : %d | size : %d\n", pos, size()); throw std::out_of_range(errmsg);
}
else if(m_ref->get(pos))
{
return true;
}
else
{
if(m_ref->isShared())
{
__Ref_Array* last_ref = m_ref; m_ref = new __Ref_Array(*last_ref); last_ref->sharedSub();
} return m_ref->get(pos);
}
} inline bool
clear(int64_t pos) const throw(std::out_of_range)
{
if(!m_ref || !m_ref->sizeRange(pos))
{
char errmsg[__BIT_ERRMSG_LEN__] = {}; snprintf(errmsg, sizeof(errmsg), "out of range in clear -> pos : %d | size : %d\n", pos, size()); throw std::out_of_range(errmsg);
}
else if(!m_ref->get(pos))
{
return true;
}
else
{
if(m_ref->isShared())
{
__Ref_Array* last_ref = m_ref; m_ref = new __Ref_Array(*last_ref); last_ref->sharedSub();
} return m_ref->clear(pos);
}
} inline void
reset()
{if(m_ref) m_ref->reset();} inline int64_t
size()
{return m_ref ? m_ref->size() : ;} inline int64_t
length()
{return m_ref ? m_ref->length() : ;} inline int64_t
count()
{return m_ref ? m_ref->count() : ;}
private:
inline void
release()  //引用计数释放
{
#ifdef __BIT_DEBUG__
fprintf(stderr, "BitArray released @addr: %p current reference : %d ...\n", this, m_ref->refCount());
#endif
if(m_ref && (m_ref->sharedSub() == ))
{
delete m_ref;
m_ref = null;
}
} __Ref_Array* m_ref;
}; #endif

C++ BitArray 引用计数实现的更多相关文章

  1. Objective-C内存管理之引用计数

    初学者在学习Objective-c的时候,很容易在内存管理这一部分陷入混乱状态,很大一部分原因是没有弄清楚引用计数的原理,搞不明白对象的引用数量,这样就当然无法彻底释放对象的内存了,苹果官方文档在内存 ...

  2. swift学习笔记5——其它部分(自动引用计数、错误处理、泛型...)

    之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...

  3. C++ 引用计数技术及智能指针的简单实现

    一直以来都对智能指针一知半解,看C++Primer中也讲的不够清晰明白(大概是我功力不够吧).最近花了点时间认真看了智能指针,特地来写这篇文章. 1.智能指针是什么 简单来说,智能指针是一个类,它对普 ...

  4. 【Python】引用计数

    一.概述 要保持追踪内存中的对象,Python使用了引用计数这一简单的技术. 二.引用计数的增减 2.1 增加引用计数 当对象被创建并(将其引用)赋值给变量时,该对象的引用计数被设置为1. 对象的引用 ...

  5. iOS开发--引用计数与ARC

    以下是关于内存管理的学习笔记:引用计数与ARC. iOS5以前自动引用计数(ARC)是在MacOS X 10.7与iOS 5中引入一项新技术,用于代替之前的手工引用计数MRC(Manual Refer ...

  6. Objective-C内存管理之-引用计数

    本文会继续深入学习OC内存管理,内容主要参考iOS高级编程,Objective-C基础教程,疯狂iOS讲义,是我学习内存管理的笔记 内存管理 1 内存管理的基本概念 1.1 Objective-C中的 ...

  7. 第3月第2天 find symbolicatecrash 生产者-消费者 ice 引用计数

    1.linux find export find /Applications/Xcode.app/ -name symbolicatecrash -type f export DEVELOPER_DI ...

  8. swif-自动引用计数

    import UIKit /* class Person { let name: String //强引用 init(name: String) { self.name = name print(&q ...

  9. OC中的自动引用计数

    目录: 1,自动引用计数的定义 2,强引用和弱引用 3,类比手动引用 4,循环引用 5,CoreFoundation 内容: 自动引用计数的定义: (Automatic Reference Count ...

随机推荐

  1. 练习使用css3实现3d按钮

    网上有很多漂亮的用css3实现的3d按钮,如'这个'.‘糖果色按钮’, 今天练习了一下,喏,下面这样,兼容性不好. 小黑子小虎子 3d效果和发光效果都是利用box-shadow,也经常利用伪元素:af ...

  2. css应用四

    1.Float属性详解 float属性定义元素在哪个方向浮动. Left 左浮动: Right 右浮动: None 默认,不浮动: Inherit 继承父元素float属性. 示例一: <div ...

  3. 转载:spring ,struct2 在 web.xml中的配置

    转载网址:http://blog.sina.com.cn/s/blog_4c6e822d0102dv63.html <!-- Struts2 need begin-->  <filt ...

  4. .net转php laraval框架学习系列(二)项目实战---Models

    上一篇已经介绍开发环境的搭建,如果有问题可以在文章后留言. 这篇将从项目实战开发,一步一步了解laravel框架. 在开发mvc项目时,models都是第一步. 下面就从建模开始. 实体关系图 由于不 ...

  5. android studio gradle自动签名构建实现

    我为自己代言: 一.在android studio中生成签名文件. 1.在android studio 选中项目,在菜单栏中选择Build. 2.点击Generate Signed APK选项卡. 3 ...

  6. fiddler使用之坑

    今天一上午都在搞fiddler,之前可以抓到浏览器的请求,今天突然不行了,弄得我花一上午时间去设置浏览器代理的事情,遇到各种各样的问题,现将解决办法记录如下: 1.原来fiddler安装在E盘中,安装 ...

  7. mysql日志文件相关的配置【1】

    1.log_output=[file | table | none ] 这个参数指定general_log &slow_query_log 的输出目标.可以是table | file | no ...

  8. Android中写入读取XML

    获取XML文件的基本思路是,通过getResources().getXml()获的XML原始文件,得到XmlResourceParser对象,通过该对象来判断是文档的开头还是结尾,是某个标签的开始还是 ...

  9. cf C. Purification

    http://codeforces.com/contest/330/problem/C 这道题分三种情况.有一行全是E,有一列全是E,还有一种为无解的情况. #include <cstdio&g ...

  10. Linux企业级项目实践之网络爬虫(13)——处理user-agent

    User Agent即用户代理,是Http协议中的一部分,属于头域的组成部分,User Agent也简称UA.它是一个特殊字符串头,是一种向访问网站提供你所使用的浏览器类型及版本.操作系统及版本.浏览 ...