BitArray.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #ifndef __BITARRAY_H_21D62F9B61AF9F__
00041 #define __BITARRAY_H_21D62F9B61AF9F__
00042
00043 #include <stdint.h>
00044 #include <string.h>
00045 #include "mw/afp/shared/div_round_up.h"
00046 #include "object/Allocator.h"
00047 #include "mw/afp/Config.h"
00048
00049 namespace famouso {
00050 namespace mw {
00051 namespace afp {
00052 namespace defrag {
00053 namespace detail {
00054
00059 class Bit {
00060 uint8_t & byte;
00061 uint8_t mask;
00062 public:
00063
00069 Bit(uint8_t & byte, uint8_t mask) :
00070 byte(byte), mask(mask) {
00071 }
00072
00074 void set() {
00075 byte |= mask;
00076 }
00077
00079 void clear() {
00080 byte &= ~mask;
00081 }
00082
00084 bool get() const {
00085 return byte & mask;
00086 }
00087
00089 bool value() const {
00090 return get();
00091 }
00092
00094 Bit & operator=(bool value) {
00095 if (value)
00096 set();
00097 else
00098 clear();
00099 return *this;
00100 }
00101 };
00102
00103
00104
00105
00106
00107
00108
00109 template <size_t N, class Allocator = object::Allocator>
00110 class BitArray {
00111 enum { array_length = (N - 1) / 8 + 1 };
00112 uint8_t array[array_length];
00113 public:
00114
00121 BitArray(bool init_value = false) {
00122 memset(array, init_value ? 0xff : 0, array_length);
00123 }
00124
00131 Bit operator[](size_t bit_idx) {
00132 FAMOUSO_ASSERT(bit_idx < N);
00133 return Bit(array[bit_idx / 8], 1 << (bit_idx % 8));
00134 }
00135
00142 const Bit operator[](size_t bit_idx) const {
00143 return (*const_cast<BitArray *>(this))[bit_idx];
00144 }
00145
00147 size_t size() const {
00148 return N;
00149 }
00150
00155 bool resize(size_t count) {
00156 return false;
00157 }
00158 };
00159
00160
00161
00162
00163
00164 template <class Allocator>
00165 class BitArray<afp::dynamic, Allocator> {
00166 size_t bit_count;
00167 uint8_t * array;
00168 bool init_value;
00169 public:
00170
00180 BitArray(bool init_value = false) :
00181 bit_count(0), array(0), init_value(init_value) {
00182 }
00183
00190 Bit operator[](size_t bit_idx) {
00191 FAMOUSO_ASSERT(bit_idx < bit_count);
00192 return Bit(array[bit_idx / 8], 1 << (bit_idx % 8));
00193 }
00194
00201 const Bit operator[](size_t bit_idx) const {
00202 return (*const_cast<BitArray *>(this))[bit_idx];
00203 }
00204
00206 size_t size() const {
00207 return bit_count;
00208 }
00209
00215 bool resize(size_t new_bit_count) {
00216 size_t old_len = shared::div_round_up(bit_count, 8);
00217 size_t new_len = shared::div_round_up(new_bit_count, 8);
00218
00219 uint8_t * new_el = Allocator::alloc(new_len);
00220 if (!new_el)
00221 return false;
00222
00223 uint8_t init_byte = init_value ? 0xff : 0;
00224 if (array) {
00225 if (new_len > old_len) {
00226 memcpy(new_el, array, old_len);
00227 memset(new_el + old_len, init_byte, new_len - old_len);
00228 } else {
00229 memcpy(new_el, array, new_len);
00230 uint8_t last_byte_mask = new_bit_count % 8;
00231 if (last_byte_mask) {
00232 last_byte_mask = 0xff << (last_byte_mask);
00233 new_el[new_len-1] = (new_el[new_len-1] & ~last_byte_mask) | (init_byte & last_byte_mask);
00234 }
00235 }
00236 Allocator::free(array);
00237 } else {
00238 memset(new_el, init_byte, new_len);
00239 }
00240
00241 array = new_el;
00242 bit_count = new_bit_count;
00243
00244 return true;
00245 }
00246 };
00247
00248
00249 }
00250 }
00251 }
00252 }
00253 }
00254
00255
00256 #endif // __BITARRAY_H_21D62F9B61AF9F__
00257