2 #include <
string.h>
3 #include <exception>
4 #include <stdexcept>
5 6 BitArray::BitArray()
7 {
8 m_owns =
true;
9 m_bitsLength =
0;
10 if(c_initBitsCapacity ==
0){
11 m_data = nullptr;
12 m_bitsCapacity =
0;
13 }
else{
14 size_t t_bytesLength = BitsToBytes(c_initBitsCapacity);
15 m_data =
new uchar[t_bytesLength];
16 memset(m_data,
0,t_bytesLength);
17 if(!m_data){
18 // 内存分配失败逻辑 19 throw std::bad_alloc();
// ("can't allow memory!"); 20 }
21 m_bitsCapacity =
8*t_bytesLength;
22 }
23 }
24 25 BitArray::BitArray(BitArray&& bits)
26 {
27 m_data = bits.m_data;
28 m_owns =
true;
29 m_bitsCapacity = bits.m_bitsCapacity;
30 m_bitsLength = bits.m_bitsLength;
31 bits.m_owns =
false;
32 bits.m_data = nullptr;
33 }
34 35 BitArray::BitArray(
const BitArray& bits)
36 {
37 *
this = bits;
38 }
39 40 BitArray& BitArray::
operator =(
const BitArray& bits)
41 {
42 m_data = bits.m_data;
43 m_owns =
true;
44 m_bitsCapacity = bits.m_bitsCapacity;
45 m_bitsLength = bits.m_bitsLength;
46 uchar* t_data =
new uchar[BitsToBytes(m_bitsCapacity)];
47 memcpy(t_data,m_data,BitsToBytes(m_bitsCapacity));
48 m_data = t_data;
49 return *
this;
50 }
51 52 BitArray& BitArray::
operator =(BitArray&& bits)
53 {
54 m_data = bits.m_data;
55 m_owns =
true;
56 m_bitsCapacity = bits.m_bitsCapacity;
57 m_bitsLength = bits.m_bitsLength;
58 bits.m_owns =
false;
59 bits.m_data = nullptr;
60 return *
this;
61 }
62 63 BitArray::BitArray(size_t bitsLength,size_t bitsCapacity)
64 {
65 /* * 66 整体思路:如果 bitsCapacity==0 ,那么默认容量将以 bitsLength乘以默认系数扩增 67 * */ 68 // 69 m_bitsLength = bitsLength;
70 m_owns =
true;
71 size_t t_fact_bitsCapacity = bitsCapacity;
72 if( t_fact_bitsCapacity < bitsLength){
73 t_fact_bitsCapacity = size_t(c_increaseCapacity*bitsLength);
74 }
75 size_t t_fact_bytesCapacity = BitsToBytes(t_fact_bitsCapacity);
76 m_bitsCapacity =
8*t_fact_bytesCapacity;
77 m_data =
new uchar[t_fact_bytesCapacity];
78 if(!m_data){
79 // 内存分配失败逻辑 80 throw std::bad_alloc();
// ("can't allow memory!"); 81 }
82 memset(m_data,
0,t_fact_bytesCapacity);
83 }
84 85 BitArray::~BitArray()
86 {
87 if(m_owns && m_data != nullptr )
88 delete[] m_data;
89 }
90 91 bool BitArray::
operator==(BitArray &bits)
92 {
93 if(m_bitsLength != bits.m_bitsLength)
94 return false;
95 for(
int i=
0;i<m_bitsLength;i++){
96 if(
get(i) != bits.
get(i) ){
97 return false;
98 }
99 }
100 return true;
101 }
102 103 BitArray::BitArray(unsigned
char* data,
int bitsLength,
bool isClear,
bool isOwns)
104 {
105 m_data = data;
106 m_bitsLength = bitsLength;
107 m_bitsCapacity =
8*BitsToBytes(m_bitsLength);
108 m_owns = isOwns;
109 size_t t_bytesLength = BitsToBytes(m_bitsLength);
110 if(isClear)
111 memset(m_data,
0,t_bytesLength);
112 }
113 114 void BitArray::setData(unsigned
char* data,
int bitsLength,
bool isClear,
bool isOwns){
115 if(m_owns && m_data != nullptr )
116 delete[] m_data;
117 m_data = data;
118 m_bitsLength = bitsLength;
119 m_bitsCapacity =
8*BitsToBytes(m_bitsLength);
120 m_owns = isOwns;
121 size_t t_bytesLength = BitsToBytes(m_bitsLength);
122 if(isClear)
123 memset(m_data,
0,t_bytesLength);
124 }
125 126 bool BitArray::
set(
int position,
bool bit,
bool isAllowOutOfRange,
bool isAllowOutOfSize,
bool isAllowToInfinite)
127 {
128 /* * 129 整体思路:将position分为六个区间,(-INF,-m_len),[-m_len,0), 130 [0,m_len),[m_len,m_cap),[m_cap,c_max*m_cap),[c_max*m_cap,INF) 131 一定越界的范围:(-INF,-m_len) 132 越界与否取决于isAllowToInfinite:[c_max*m_cap,INF) 133 越界与否取决于isAllowedOutOfRange:[m_cap,c_max*m_cap) 及 isAllowToInfinite 134 越界与否取决于isAllowOutOfSize:[m_len,m_cap) 及 isAllowToInfinite 135 合法访问范围:[-m_len,0),[0,m_len), 136 * */ 137 // position比 -(int)m_bitsLength 还小,或者需要扩张的倍数超出c_maxAllowedOutOfBound,此时一定越界 138 if( position<-(
int)m_bitsLength || (position>=size_t(c_maxAllowedOutOfBound*m_bitsCapacity)&&!isAllowToInfinite) ){
139 throw std::out_of_range(
" Out of range , This position is too larger! ");
140 }
141 // 注意 isAllowToInfinite , 如果这个值为 true,那么其他的条件开关将被忽略 142 // 如果不允许进行自动扩张,而访问位置超出 m_bitsCapacity 143 if(!isAllowOutOfRange&&position>=m_bitsCapacity&&!isAllowToInfinite){
144 throw std::out_of_range(
" Out of range , You are not allowed to automatically expanded memory! ");
145 }
146 if(!isAllowOutOfSize&&position>=m_bitsLength&&!isAllowToInfinite){
147 throw std::out_of_range(
" Out of range , You are not allowed to amplification size automatically! ");
148 }
149 // 以负数进行访问,修正position的实际位置,使得 [-m_len,0) -> [0,m_len) 150 if( position <
0){
151 position += m_bitsLength;
152 }
153 if( position < m_bitsLength){
154 // 访问位置没有超出目前的长度 155 return writeBit(m_data,position,bit);
156 }
else if( position >= m_bitsLength && position < m_bitsCapacity){
157 // 访问的位置已经超出了目前的长度,但是并没有超出实际的容量 158 m_bitsLength = position+
1;
159 return writeBit(m_data,position,bit);
160 }
else{
161 size_t t_new_bitsLength = position+
1;
162 size_t t_new_bytesCapacity = BitsToBytes(c_increaseCapacity*t_new_bitsLength);
163 size_t t_new_bitsCapacity =
8*t_new_bytesCapacity;
164 uchar* t_data =
new uchar[t_new_bytesCapacity];
165 if(!t_data){
166 // 内存分配失败逻辑 167 throw std::bad_alloc();
// ("can't allow memory!"); 168 }
169 memset(t_data,
0,t_new_bytesCapacity);
170 memcpy(t_data,m_data,BitsToBytes(m_bitsCapacity));
171 if( m_owns ){
172 delete[] m_data;
173 }
174 m_data = t_data;
175 m_bitsCapacity = t_new_bitsCapacity;
176 m_bitsLength = t_new_bitsLength;
177 m_owns =
true;
178 return writeBit(m_data,position,bit);
179 }
180 }
181 182 bool BitArray::
get(
int position)
183 {
184 if(position >= m_bitsLength || position < -(
int)m_bitsLength ){
185 // 访问越界,抛出异常 186 throw std::out_of_range(
" The location of the access is illegal! ");
187 }
188 if( position <
0 && position >= -(
int)m_bitsLength ){
189 // 以负数进行访问,修正position的实际位置 190 position += m_bitsLength;
191 }
192 return readBit(m_data,position);
193 }
194 195 size_t BitArray::setBitSize(size_t newBitsLength)
196 {
197 size_t origin_bitsLength = m_bitsLength;
198 if( newBitsLength <= m_bitsCapacity){
199 m_bitsLength = newBitsLength;
200 }
else{
201 // 既然需要将大小扩充至newBitsLength,那么在newBitsLength-1 处赋false即可完成该功能 202 set(newBitsLength-
1,
false,
true,
true,
true);
203 }
204 return origin_bitsLength;
205 }
206 207 size_t BitArray::setBitCapacity(size_t newBitsCapacity)
208 {
209 /* * 210 整体思路:无论新的容量是多少,显然当与原来大小不一样时是需要进行扩容的 211 但是如果新容量比原来的长度还小,那么长度必须进行修改 212 * */ 213 // 原来的容量必定为8的倍数 214 size_t origin_bytesCapacity = BitsToBytes(m_bitsCapacity);
215 size_t new_bytesCapacity = BitsToBytes(newBitsCapacity);
216 if( origin_bytesCapacity != new_bytesCapacity){
217 uchar* t_data =
new uchar[new_bytesCapacity];
218 if(!t_data){
219 // 内存分配失败逻辑 220 throw std::bad_alloc();
// ("can't allow memory!"); 221 }
222 memset(t_data,
0,new_bytesCapacity);
223 if( origin_bytesCapacity < new_bytesCapacity){
224 // 如果新容量比原来的容量大,那么全部复制 225 memcpy(t_data,m_data,origin_bytesCapacity);
226 }
else{
227 // 如果新容量比原来的容量小,那么仅复制一部分 228 memcpy(t_data,m_data,new_bytesCapacity);
229 }
230 if( m_owns ){
231 delete[] m_data;
232 }
233 m_data = t_data;
234 m_bitsCapacity = BytesToBits(new_bytesCapacity);
235 if( m_bitsLength > m_bitsCapacity){
236 m_bitsLength = m_bitsCapacity;
237 }
238 m_owns =
true;
239 }
240 return BytesToBits(origin_bytesCapacity);
241 }
242 243 bool BitArray::setOwns(
bool owns)
244 {
245 bool r = m_owns;
246 m_owns = owns;
247 return r;
248 }
249 250 /* 251 在map的position位置写入bit 252 */ 253 bool writeBit(unsigned
char *map,
int position,
bool bit)
254 {
255 // sub表示在szMap中的下标,pos表示在该位置中相应的比特位 256 int sub = (position) /
8;
257 int pos =
7 - (position) %
8;
258 if( bit ){
259 map[sub] |=
1<<pos;
// 打开位开关 260 }
else{
261 map[sub] &= ~(
1<<pos);
// 关闭位开关 262 }
263 return true;
264 }
265 266 /* 267 读取map的position位置的bit数据 268 */ 269 bool readBit(unsigned
char *map,
int position)
270 {
271 // sub 代表 szMap中对应的下标,范围是[0,bitmapLength) ;pos为相应的bit位置,范围是[0,8) 272 int sub = (position)/
8;
273 int pos =
7 - (position)%
8;
274 return bool( (map[sub]>>pos)&
1 );
275 }
276 277 Bit::Bit(BitArray *bits,
int position){
278 m_bits = bits;
279 m_position = position;
280 }
281 282 Bit& Bit::
operator =(
bool bit){
283 m_bits->
set(m_position,bit,
true);
284 return *
this;
285 }
286 287 Bit::
operator bool(){
288 return m_bits->
get(m_position);
289 }