#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. android手机获取手机号

    最近做到一个项目,需要获取手机号.项目中使用的手机卡为电信卡,那么就以此为例吧. 网上不符合需求的方法 Google了一下,网上的做法如下: //获取手机号码 TelephonyManager tm  ...

  2. Python学习笔记总结(三)类

    一.类简单介绍 1.介绍 类是Python面向对象程序设计(OOP)的主要工具,类建立使用class语句,通过class定义的对象. 类和模块的差异,类是语句,模块是文件. 类和实例 实例:代表程序领 ...

  3. const int *p,int *const p区别(转)

    1)先从const int i说起.使用const修饰的i我们称之为符号常量.即,i不能在其他地方被重新赋值了.注意:const int i与int const i是等价的,相同的,即const与in ...

  4. Scala学习笔记--文件IO

    补充: http://blog.csdn.net/lyrebing/article/details/20369445 http://developer.51cto.com/art/200907/134 ...

  5. Qt C++中的关键字explicit——防止隐式转换(也就是Java里的装箱),必须写清楚

    最近在复习QT,准备做项目了,QT Creator 默认生成的代码 explicit Dialog(QWidget *parent = 0)中,有这么一个关键字explicit,用来修饰构造函数.以前 ...

  6. 自定义高级QFileDialog文件过滤器

    QFileDialog提供了一个函数---setproxyModel..就是用这个来玩了.就是override filterAcceptsRow的虚函数,里面定制自己的过滤需求.返回bool   下面 ...

  7. sqlplus与sqlplusw (转)

    一.sqlplus与sqlplusw两者统称SQLPlus,是Oracle的一个命令行执行工具.   二.SQLPlus的有两种运行方式: 1.在命令行窗口运行.sqlplus 2.在窗口中运行.sq ...

  8. pthread_mutex_init & 互斥锁pthread_mutex_t的使用

    pthread_mutex_init l         头文件: #include <pthread.h> l         函数原型: int pthread_mutex_init( ...

  9. java 面试基础典型题及答案

    1.switch能否作用在byte.int.long.String? 答案:switch能作用在byte.int.enum常量, 补充:jdk7可以作用在String上 2.short s = 1; ...

  10. Hibernate中Session的几个方法的简单说明

    Hibernate对普通JDBC的操作进行了轻量级的封装,使得开发人员可以利用Session对象以面向对象的思想来实现对关系数据库的操作. 一般通过Configuration对象读取相应的配置文件来创 ...