42 #include "top_exception.h" 44 #include "bj_stream.h" 46 typedef long bit_rw_idx;
49 #define INVALID_IDX -1 53 #define FILL_FULL_CAP -100 57 #define START_CAP 16 // avoid mem problems (due to mem alloc, re-alloc failures) 60 #ifndef k_num_bits_byte 61 #define k_num_bits_byte 8 64 #define BITS_CK(prm) DBG_CK(prm) 71 #define div8(b) ((b)>>3) 72 #define mod8(b) ((b)&7) 74 #define get_bit(a, b) ((((t_1byte*)a)[div8(b)] >> mod8(b)) & 1) 75 #define set_bit(a, b) (((t_1byte*)a)[div8(b)] |= (1 << mod8(b))) 76 #define reset_bit(a, b) (((t_1byte*)a)[div8(b)] &= ~(1 << mod8(b))) 77 #define toggle_bit(a, b) (((t_1byte*)a)[div8(b)] ^= (1 << mod8(b))) 79 #define to_bytes(num_bits) (div8(num_bits) + (mod8(num_bits) > 0)) 80 #define to_bits(num_bytes) (num_bytes * k_num_bits_byte) 90 class bit_rw_exception :
public top_exception {
92 bit_rw_exception(
long the_id = 0) : top_exception(the_id)
111 bit_ref& operator = (
bool val);
116 rot_lft_idx(bit_rw_idx pos, bit_rw_idx row_sz,
long num_rot);
119 rot_rgt_idx(bit_rw_idx pos, bit_rw_idx row_sz,
long num_rot);
121 bj_ostream& operator << (bj_ostream& os, bit_row& rr);
122 bit_row& operator << (bit_row& rr,
const bool elem);
123 bit_row& operator >> (bit_row& rr,
bool& elem);
124 bit_row& operator << (bit_row& rr1, bit_row& rr2);
128 bit_row& operator = (bit_row& other){
129 throw bit_rw_exception(brx_bad_eq_op);
132 bit_row(bit_row& other){
133 throw bit_rw_exception(brx_bad_creat);
152 void init_with_copy_of(t_1byte* dat_bytes,
long dat_num_bytes){
156 bit_rw_idx nw_sz = to_bits(dat_num_bytes);
158 bj_memcpy(data, dat_bytes, cap);
162 const t_1byte* get_c_array(){
163 return (t_1byte*)data;
166 long get_c_array_sz(){
167 return (
long)(to_bytes(sz));
170 bit_rw_idx get_cap(){
174 bit_rw_idx get_bytes_cap(){
178 bool is_valid_idx(bit_rw_idx idx){
179 return ((idx >= 0) && (idx < size()));
182 bit_rw_idx last_idx(){
187 void grow(bit_rw_idx bits_cap){
188 bit_rw_idx min_cap = to_bytes(bits_cap);
189 if(min_cap <= cap){
return; }
190 bit_rw_idx nxt_cap = cap;
193 nxt_cap = to_bytes(START_CAP);
197 nxt_cap = nxt_cap * 2;
198 }
while(nxt_cap < min_cap);
200 BITS_CK(nxt_cap > 1);
201 set_cap(to_bits(nxt_cap));
205 void set_cap(bit_rw_idx bits_cap){
206 bit_rw_idx min_cap = to_bytes(bits_cap);
207 if(min_cap <= cap){
return; }
208 bit_rw_idx old_cap = cap;
209 BITS_CK(old_cap >= 0);
211 t_1byte* n_dat = tpl_realloc(data, old_cap, cap);
216 void set_size(bit_rw_idx bits_sz){
222 void clear(
bool reset_them =
false,
bool dealloc =
false, bit_rw_idx from = 0){
231 for(bit_rw_idx ii = from; ii < sz; ii++){
244 bit_rw_idx size()
const {
248 bit_rw_idx num_bytes()
const {
253 return (sz == get_cap());
260 bool pos(bit_rw_idx idx){
261 return get_bit(data, idx);
264 void set(bit_rw_idx idx){
268 void reset(bit_rw_idx idx){
269 reset_bit(data, idx);
272 void set_val(bit_rw_idx idx,
bool val =
false){
276 reset_bit(data, idx);
281 void push(
const bool elem){
317 void swap(bit_rw_idx idx1, bit_rw_idx idx2){
318 bool tmp1 = pos(idx1);
319 set_val(idx1, pos(idx2));
324 bool swap_pop(bit_rw_idx idx){
325 bool tmp1 = pos(idx);
327 set_val(idx, pos(sz));
333 void swapop(bit_rw_idx idx){
335 set_val(idx, pos(sz));
339 void fill(
const bool elem, bit_rw_idx num_fill = INVALID_IDX,
340 bool only_new =
false)
342 if(num_fill == INVALID_IDX){
345 if(num_fill == FILL_FULL_CAP){
346 num_fill = get_cap();
351 for(ii = 0; ((ii < sz) && (ii < num_fill)); ii++){
355 for(ii = sz; ii < num_fill; ii++){
360 void fill_new(bit_rw_idx num_fill = INVALID_IDX){
362 if(num_fill == INVALID_IDX){
365 if(num_fill == FILL_FULL_CAP){
366 num_fill = get_cap();
369 for(bit_rw_idx ii = 0; ii < num_fill; ii++){
374 bit_ref operator [] (bit_rw_idx idx) {
383 void copy_to(bit_row& r_cpy, bit_rw_idx first_ii = 0, bit_rw_idx last_ii = -1){
384 r_cpy.clear(
true,
false);
385 if((last_ii < 0) || (last_ii > sz)){
388 if((first_ii < 0) || (first_ii > last_ii)){
391 r_cpy.set_cap(last_ii - first_ii);
392 for (bit_rw_idx ii = first_ii; ii < last_ii; ii++){
398 void append_to(bit_row& orig){
399 orig.set_cap(orig.sz + sz);
400 for (bit_rw_idx ii = 0; ii < sz; ii++){
407 void rotate_left(bit_row& dest,
long num_bits){
408 dest.set_size(size());
409 BITS_CK(size() == dest.size());
410 long d_sz = dest.size();
411 for(bit_rw_idx aa = 0; aa < size(); aa++){
412 bit_rw_idx d_idx = rot_lft_idx(aa, d_sz, num_bits);
413 dest[d_idx] = pos(aa);
417 void rotate_right(bit_row& dest,
long num_bits){
418 dest.set_size(size());
419 BITS_CK(size() == dest.size());
420 long d_sz = dest.size();
421 for(bit_rw_idx aa = 0; aa < size(); aa++){
422 bit_rw_idx d_idx = rot_rgt_idx(aa, d_sz, num_bits);
423 dest[d_idx] = pos(aa);
429 bj_ostream& print_bit_row(
431 bool with_lims =
true,
433 char* sep = as_pt_char(
" "),
434 bit_rw_idx low = INVALID_IDX,
435 bit_rw_idx hi = INVALID_IDX,
436 bit_rw_idx grp_sz = -1,
437 char* grp_sep = as_pt_char(
"\n")
440 bool equal_to(bit_row& rw2, bit_rw_idx first_ii = 0, bit_rw_idx last_ii = -1){
441 if((last_ii < 0) || (last_ii > sz)){
444 if((first_ii < 0) || (first_ii > last_ii)){
448 for (bit_rw_idx ii = first_ii; ii < last_ii; ii++){
449 if(pos(ii) != rw2.pos(ii)){
456 void swap_with(bit_row& dest){
457 bit_rw_idx tmp_cap = cap;
458 bit_rw_idx tmp_sz = sz;
459 t_1byte* tmp_data = data;
467 dest.data = tmp_data;
470 void mem_copy_to(bit_row& r_cpy){
472 bj_memcpy(r_cpy.data, data, r_cpy.cap);
479 bit_row::print_bit_row(
490 bit_rw_idx num_elem = 1;
491 if(with_lims){ os <<
"["; }
492 for(bit_rw_idx ii = 0; ii < sz; ii++){
493 if(ii == low){ os <<
">"; }
495 if(ii == hi){ os <<
"<"; }
497 if((grp_sz > 1) && ((num_elem % grp_sz) == 0)){
502 if(with_lims){ os <<
"] "; }
508 bit_ref& bit_ref::operator = (
bool val){
509 BITS_CK(brow != NULL_PT);
510 brow->set_val(idx, val);
515 bit_ref::operator bool(){
516 BITS_CK(brow != NULL_PT);
517 return brow->pos(idx);
522 rot_lft_idx(bit_rw_idx pos, bit_rw_idx row_sz,
long num_rot){
524 long r_rot = (num_rot % row_sz);
525 bit_rw_idx n_idx = (pos - r_rot);
527 n_idx = row_sz + n_idx;
530 BITS_CK(n_idx < row_sz);
536 rot_rgt_idx(bit_rw_idx pos, bit_rw_idx row_sz,
long num_rot){
538 long r_rot = (num_rot % row_sz);
539 bit_rw_idx n_idx = (pos + r_rot);
541 n_idx = n_idx % row_sz;
544 BITS_CK(n_idx < row_sz);
549 bj_ostream& operator << (bj_ostream& os, bit_row& rr){
550 rr.print_bit_row(os,
true, as_pt_char(
" "));
555 bit_row& operator << (bit_row& rr,
const bool elem){
561 bit_row& operator >> (bit_row& rr,
bool& elem){
567 bit_row& operator << (bit_row& rr1, bit_row& rr2){
578 class s_bit_row :
public bit_row {
581 void grow(bit_rw_idx bits_cap){ MARK_USED(bits_cap); }
583 void set_cap(bit_rw_idx bits_cap){ MARK_USED(bits_cap); }
585 void set_size(bit_rw_idx bits_sz){ MARK_USED(bits_sz); }
587 void push(
const bool elem){ MARK_USED(elem); }
593 bool pop(){
return false; }
595 bool swap_pop(bit_rw_idx idx){ MARK_USED(idx);
return false; }
597 void swapop(bit_rw_idx idx){ MARK_USED(idx); }
601 void clear(
bool reset_them =
false,
bool dealloc =
false, bit_rw_idx from = 0){
602 MARK_USED(reset_them);
610 s_bit_row(t_1byte* dat = NULL_PT,
long dat_num_bytes = 0){
611 init_data(dat, dat_num_bytes);
614 s_bit_row(
double* dat){
615 init_data((t_1byte*)dat,
sizeof(
double));
618 s_bit_row(
long* dat){
619 init_data((t_1byte*)dat,
sizeof(
long));
622 s_bit_row(
char* dat){
623 init_data((t_1byte*)dat,
sizeof(
char));
626 s_bit_row(s_bit_row& bt_r,
long from_byte,
629 long max_byte = bt_r.get_bytes_cap();
630 if(from_byte > max_byte){
631 from_byte = max_byte;
633 if((from_byte + num_bytes) > max_byte){
634 num_bytes = (max_byte - from_byte);
636 t_1byte* dat = bt_r.data + from_byte;
637 init_data(dat, num_bytes);
644 void init_data(t_1byte* dat,
long dat_num_bytes){
645 sz = to_bits(dat_num_bytes);