C ++ BitArray reference counting implementation, bitarray counting
1 # ifndef _ BITARRAY _ 2 # define _ BITARRAY _ 1 3 4 # include <cstdio> 5 # include <cstring> 6 7 # if _ cplusplus> = 201103L 8 # include <cstdint> 9 # else 10 # include <stdint. h> 11 # endif 12 13 # if _ cplusplus <201103L 14 # define _ nullptr NULL 15 # else 16 # define _ nullptr 17 # endif 18 19 class BitArray 20 {21 private: 22/* Reference count */23 class _ Ref_Array 24 {25 private: 26 typedef int8_t _ bit _ Type; 27 typedef int32_t _ size_type; 28 typedef int32_t _ length_type; 29 30 enum _ enum_bit 31 {32 _ ref_byte = 8, 33}; 34 35 public: 36/* 37 * constructor 38 * construct an empty space array 39 */40 _ Ref_Array (_ size_type _ size) no1_t 41 :__ M_size (_ size ), _ M_refcount (1) 42 {init_array ();} 43 44/* 45 * copy constructor 46 * directly copy all content, set Reference count to 1 47 */48 _ Ref_Array (const _ Ref_Array & other) no1_t 49 :__ M_used (other. _ M_used ), _ M_size (other. _ M_size), 50 _ M_length (other. _ M_length), _ M_refcount (1) 51 {52 alloc (); 53 memcpy (_ M_array, other. _ M_array, _ M_length); 54} 55 56/* 57 * destructor 58 * destructor 59 */60 ~ _ Ref_Array () 61 {if (_ M_refcount = 0 &&! _ M_array) delete [] _ M_array;} 62 63 public: 64 65/* 66 * test the status of one digit 67 */68 inline bool 69 test (_ size_type _ pos) const 70 {return * (_ M_array + slot (_ pos) & mask (_ pos );} 71 72/* 73 * set the status of one digit 74 */75 inline bool 76 set (_ size_type _ pos) 77 {78 (* (_ M_array + slot (_ pos) | = mask (_ pos); 79 80 _ M_used ++; 81 82 return true; 83} 84 85/* 86 * clear one-digit status 87 */88 inline bool 89 clear (_ size_t Ype _ pos) 90 {91 (* (_ M_array + slot (_ pos) & = ~ Mask (_ pos); 92 93 _ M_used --; 94 95 return true; 96} 97 98/* 99 * clear all status settings 100 */101 inline void102 reset () 103 {104 memset (_ M_array, 0, _ M_length ); 105 _ M_used = 0; 106} 107 108/* 109 * test whether the specified pos is valid 110 */111 inline bool112 range (_ size_type _ pos) const113 {return _ pos> = 0 & _ pos <_ M_size ;} 114 115/* 116 * Get the number of digits of the array 117 */118 inline _ size_type119 size () const120 {return _ M_size;} 121 122 /* 123 * Get the byte length of the array 124 */125 inline _ size_type126 length () const127 {return _ M_length ;} 128 129/* 130 * Get the number of used bits 131 */132 inline _ size_type1_used () const134 {return _ M_used ;} 135 136/* 137 * Get object reference count 138 */139 inline _ size_type140 refcount () const141 {return _ M_refcount;} 142 143 public: 144 _ size_type145 operator ++ () 146 {return ++ _ M_refcount;} 147 148 _ size_type149 operator -- () 150 {return -- _ M_refcount;} 151 152 _ size_type153 operator ++ (int) 154 {return _ M_refcount ++;} 155 156 _ size_type157 operator -- (int) 158 {return _ M_refcount --;} 159 private: 160 161/* 162 * allocated memory 163 */164 inline void165 alloc () 166 {__ M_array = new _ bit_type [_ M_length];} 167 168 169/* 170 * initialize array 171 * memory allocation, clear Data 172 */173 inline void174 init_array () 175 {176 _ M_length = nslots (_ M_size); 177 alloc (); 178 reset (); 179} 180 181/* 182 * get a mask of 183 */184 inline _ bit_type185 mask (_ size_type _ pos) const186 {return _ bit_type (1) <(_ pos % _ ref_byte );} 187 188 189/* 190 * calculate the length of the array 191 */192 inline _ size_type193 nslots (_ size_type _ size) const194 {return (_ size + _ ref_byte-1)/_ ref_byte ;} 195 196/* 197 * calculate the pos location 198 */199 inline _ size_type200 slot (_ size_type _ pos) const201 {return _ pos/_ ref_byte ;} 202 203 private: 204 205 _ bit_type * _ M_array; // array space 206 _ size_type _ M_used; // used count 207 _ size_type _ M_size; // The number of BITs is 208 _ length_type _ M_length; // The Byte size of the array is 209 _ size_type _ M_refcount; // The reference count is 210}; 211 212 public: 213 BitArray (int32_t size) no1_t214 :__ M_ref (size = 0 )? _ Nullptr: new _ Ref_Array (size) 215 {} 216 217 BitArray () no1_t218 :__ M_ref (_ nullptr) 219 {} 220 221 BitArray (const BitArray & other) no1_t222 :__ M_ref (other. _ M_ref) 223 {(* _ M_ref) ++;} 224 225 # if _ cplusplus> = 201103L226 BitArray (BitArray & other) no1_t227 :__ M_ref (other. _ M_ref) 228 {other. _ M_ref = _ nullptr;} 229 # endif230 231 BitArray & 232 operator = (const BitArray & other) 233 {234 if (_ M_ref! = Other. _ M_ref) 235 {236 release (); 237 _ M_ref = other. _ M_ref; 238 (* _ M_ref) ++; 239} 240 241 return * this; 242} 243 public: 244 inline int32_t245 size () const246 {return _ M_ref? _ M_ref-> size (): 0;} 247 248 inline int32_t249 length () const250 {return _ M_ref? _ M_ref-> length (): 0;} 251 252 inline int32_t253 used () const254 {return _ M_ref? _ M_ref-> used (): 0;} 255 256 public: 257 inline bool258 test (int32_t pos) const259 {return _ M_ref & _ M_ref-> range (pos )? _ M_ref-> test (pos): false;} 260 261 inline bool262 set (int32_t pos) 263 {264 if (! _ M_ref |! _ M_ref-> range (pos) 265 {266 return false; 267} 268 else if (_ M_ref-> test (pos) 269 {270 return true; 271} 272 else273 {274 if (_ M_ref-> refcount ()> 1) 275 {276 // when the reference count of the array is greater than 1, you need to copy it and set 277 _ Ref_Array * _ last_ref = _ M_ref; 278 279 _ M_ref = new _ Ref_Array (* _ last_ref); 280 281 (* _ last_ref )--; 282} 283 284 return _ M_ref-> set (pos); 285} 286} 287 288 inline bool289 clear (int32_t pos) 290 {291 if (! _ M_ref |! _ M_ref-> range (pos) 292 {293 return false; 294} 295 else if (! _ M_ref-> test (pos) 296 {297 return true; 298} 299 else300 {301 if (_ M_ref-> refcount ()> 1) 302 {303 _ Ref_Array * _ last_ref = _ M_ref; 304 305 _ M_ref = new _ Ref_Array (* _ last_ref); 306 307 (* _ last_ref) --; 308} 309 310 return _ M_ref-> clear (pos); 311} 312} 313 314 inline void315 reset () 316 {if (_ M_ref) _ M_ref-> reset ();} 317 318 private: 319 inline void321 release () 320 {if (-- (* _ M_ref) = 0) delete _ M_ref;} 323 324 _ Ref_Array * _ M_ref; 325}; 326 327 328 # endif