Aleph-w  1.5a.2
Biblioteca general de algoritmos y estructuras de datos
 Todo Clases Archivos Funciones Variables 'typedefs' Enumeraciones Amigas Grupos Páginas
bitArray.H
1 
2 # ifndef BITARRAY_H
3 # define BITARRAY_H
4 
5 # include <iostream>
6 # include <fstream>
7 # include <aleph.H>
8 # include <tpl_dynArray.H>
9 
10 namespace Aleph {
11 
12 class Byte
13 {
14  unsigned int b0 : 1;
15  unsigned int b1 : 1;
16  unsigned int b2 : 1;
17  unsigned int b3 : 1;
18  unsigned int b4 : 1;
19  unsigned int b5 : 1;
20  unsigned int b6 : 1;
21  unsigned int b7 : 1;
22 
23 public:
24 
25  unsigned int read_bit(const unsigned int i) const
26  {
27  I(i < 8);
28 
29  switch (i)
30  {
31  case 0 : return b0;
32  case 1 : return b1;
33  case 2 : return b2;
34  case 3 : return b3;
35  case 4 : return b4;
36  case 5 : return b5;
37  case 6 : return b6;
38  case 7 : return b7;
39  default: throw std::out_of_range ("bit index greater than 7");
40  }
41  }
42 
43  void write_bit(const unsigned int i, const unsigned int value)
44  {
45  I(i < 8);
46  I(value <= 1);
47 
48  switch (i)
49  {
50  case 0 : b0 = value; break;
51  case 1 : b1 = value; break;
52  case 2 : b2 = value; break;
53  case 3 : b3 = value; break;
54  case 4 : b4 = value; break;
55  case 5 : b5 = value; break;
56  case 6 : b6 = value; break;
57  case 7 : b7 = value; break;
58  default: throw std::out_of_range ("bit index greater than 7");
59  }
60  }
61 
62  Byte() : b0(0), b1(0), b2(0), b3(0), b4(0), b5(0), b6(0), b7(0) {}
63 
64  int get_int() const
65  {
66  const unsigned char * const ptr = (unsigned char*) this;
67  return *ptr;
68  }
69 
70  void set_int(int i)
71  {
72  unsigned char * ptr = (unsigned char*) this;
73  *ptr = i;
74  }
75 };
76 
96 class BitArray
97 {
98  size_t current_size;
99  DynArray<Byte> array_of_bytes;
100 
101  size_t get_num_bytes() const
102  {
103  size_t div = current_size/8;
104 
105  return (current_size % 8) != 0 ? div + 1 : div;
106  }
107 
108  class BitProxy
109  {
110  const size_t index;
111  const size_t bit_index;
112  const size_t byte_index;
113  BitArray * array;
114  Byte * byte_ptr;
115 
116  public:
117 
118  BitProxy(BitArray & a, const size_t i) :
119  index(i), bit_index(i % 8), byte_index(i/8), array(&a)
120  {
121  if (array->array_of_bytes.exist(byte_index))
122  byte_ptr = &array->array_of_bytes.access(byte_index);
123  else
124  byte_ptr = NULL;
125  }
126 
127  operator int () const
128  {
129  if (index >= array->current_size)
130  throw std::out_of_range("Index out of range");
131 
132  return byte_ptr != NULL ? byte_ptr->read_bit(bit_index) : 0;
133  }
134 
135  BitProxy & operator = (const size_t value)
136  {
137  I(value <= 1);
138 
139  if (byte_ptr == NULL)
140  byte_ptr = &array->array_of_bytes.touch(byte_index);
141 
142  if (index >= array->current_size)
143  array->current_size = index;
144 
145  byte_ptr->write_bit(bit_index, value);
146 
147  return *this;
148  }
149 
150  BitProxy & operator = (const BitProxy & proxy)
151  {
152  if (byte_ptr == NULL)
153  byte_ptr = &array->array_of_bytes.touch(byte_index);
154 
155  if (index >= array->current_size)
156  array->current_size = index;
157 
158  byte_ptr->write_bit(bit_index, proxy.byte_ptr->read_bit(proxy.bit_index));
159 
160  return *this;
161  }
162  };
163 
164 public:
165 
172  BitArray(const size_t dim = 0) throw(std::exception, std::bad_alloc)
173  : current_size(dim), array_of_bytes(get_num_bytes())
174  {
175  array_of_bytes.set_default_initial_value(Byte());
176  }
177 
188  void reserve(size_t dim)
189  {
190  current_size = dim;
191 
192  int num_bytes = dim/8;
193  if (dim % 8)
194  ++num_bytes;
195 
196  array_of_bytes.reserve(num_bytes);
197  }
198 
200  size_t size() const { return current_size; }
201 
203  void set_size(const size_t sz)
204  {
205  size_t array_size = sz / 8;
206  if (array_size % 8)
207  ++array_size;
208  array_of_bytes.cut(array_size);
209  current_size = sz;
210  }
211 
212  BitProxy operator [] (const size_t i) const
213  {
214  return BitProxy(const_cast<BitArray&>(*this), i);
215  }
216 
217  BitProxy operator [] (const size_t i) { return BitProxy(*this, i); }
218 
225  int read_bit(const size_t i) const
226  {
227  if (i >= current_size)
228  throw std::out_of_range("index out of range");
229 
230  const int bit_index = i % 8;
231  const Byte byte = array_of_bytes[i/8];
232  return byte.read_bit(bit_index);
233  }
234 
242  void write_bit(const size_t i, const unsigned int value)
243  {
244  array_of_bytes.touch(i/8).write_bit(i%8, value);
245  if (i >= current_size)
246  current_size = i + 1;
247  }
248 
257  int read(const size_t i) const
258  {
259  if (i >= current_size)
260  throw std::out_of_range("index out of range");
261 
262  const int bit_index = i % 8;
263  return array_of_bytes.access(i/8).read_bit(bit_index);
264  }
265 
273  void write(const size_t i, const unsigned int value)
274  {
275  array_of_bytes.access(i/8).write_bit(i%8, value);
276  if (i >= current_size)
277  current_size = i + 1;
278  }
279 
281  void push(const unsigned int value)
282  {
283  write_bit(current_size, value);
284  }
285 
287  void pop()
288  {
289  current_size--;
290  array_of_bytes.cut(get_num_bytes());
291  }
292 
294  void empty()
295  {
296  current_size = 0;
297  array_of_bytes.cut();
298  }
299 
308  BitArray(const BitArray & array) throw(std::exception, std::bad_alloc)
309  : current_size(array.current_size), array_of_bytes (array.array_of_bytes)
310  {
311  // empty
312  }
313 
314  void swap(BitArray & array)
315  {
316  std::swap(current_size, array.current_size);
317  array_of_bytes.swap(array.array_of_bytes);
318  }
319 
320  BitArray(BitArray && array)
321  : BitArray()
322  {
323  swap(array);
324  }
325 
326  BitArray & operator = (BitArray && array)
327  {
328  current_size = 0;
329  array_of_bytes.cut();
330  swap(array);
331  return *this;
332  }
333 
336  {
337  DynList<char> ret_val;
338  for (size_t i = 0; i < current_size; ++i)
339  ret_val.append((char) read_bit(i));
340  return ret_val;
341  }
342 
354  BitArray & operator = (const BitArray & array)
355  throw(std::exception, std::bad_alloc)
356  {
357  if (this == &array)
358  return *this;
359 
360  current_size = array.current_size;
361  array_of_bytes = array.array_of_bytes;
362 
363  return *this;
364  }
365 
378  void save(ofstream & output)
379  {
380  const size_t & num_bytes = array_of_bytes.size();
381 
382  output << num_bytes << " " << current_size << endl;
383 
384  for (size_t i = 0; i < num_bytes; i++)
385  if (array_of_bytes.exist(i))
386  {
387  int byte = array_of_bytes.access(i).get_int();
388  output << byte << " ";
389  }
390  else
391  output << "0 ";
392 
393  output << endl;
394  }
395 
406  void load(ifstream & input)
407  {
408  array_of_bytes.cut();
409 
410  size_t num_bytes = 0;
411  input >> num_bytes >> current_size;
412  for (size_t i = 0; i < num_bytes; i++)
413  {
414  int c;
415  input >> c;
416  array_of_bytes.touch(i).set_int(c);;
417  }
418  }
419 
422  BitArray(ifstream & input)
423  {
424  load(input);
425  }
426 
442  void save_in_array_of_chars(const string & name, ofstream & output)
443  {
444  const size_t & num_bytes = array_of_bytes.size();
445 
446  output << "// " << current_size << " bits declaration" << endl
447  << "const unsigned char " << name << " [" << num_bytes << "] = {"
448  << endl << " ";
449  for (size_t i = 0; i < num_bytes; i++)
450  {
451  if (array_of_bytes.exist(i))
452  {
453  int byte = array_of_bytes.access(i).get_int();
454  output << byte;
455  }
456  else
457  output << "0";
458 
459  if (i != num_bytes - 1)
460  output << ", ";
461 
462  if ((i+1) % 15 == 0)
463  output << endl << " ";
464  }
465  output << endl << "};" << endl << endl;
466  }
467 
479  void load_from_array_of_chars(const unsigned char str[],
480  const size_t num_bits)
481  {
482  array_of_bytes.cut();
483 
484  size_t num_bytes = num_bits/8;
485 
486  if (num_bits % 8 != 0)
487  num_bytes++;
488 
489  for (size_t i = 0; i < num_bytes; i++)
490  array_of_bytes.touch(i).set_int(str[i]);
491 
492  current_size = num_bits;
493  }
494 
502  void left_shift(const size_t n = 1)
503  {
504  const size_t real_n = std::min <size_t>(n, current_size);
505 
506  for (size_t i = 0; i < current_size - real_n; ++i)
507  write_bit(i, read_bit(i + real_n));
508 
509  for (size_t i = current_size - real_n; i < current_size; ++i)
510  write_bit(i, 0);
511  }
512 
520  void right_shift(const size_t n = 1)
521  {
522  const size_t real_n = std::min <size_t>(n, current_size);
523 
524  for (size_t i = current_size; i > real_n; --i)
525  write_bit(i - 1, read_bit(i - real_n - 1));
526 
527  for (size_t i = real_n; i > 0; --i)
528  write_bit(i - 1, 0);
529  }
530 
538  void dyn_left_shift(const size_t n = 1)
539  {
540  for (size_t i = 0; i < n; ++i)
541  push(0);
542  }
543 
551  void dyn_right_shift(const size_t n = 1)
552  {
553  if (n >= current_size)
554  {
555  set_size(1);
556  array_of_bytes.set_default_initial_value(Byte());
557  return;
558  }
559 
560  BitArray array(current_size - n);
561 
562  for (size_t i = 0; i < current_size - n; ++i)
563  array.write_bit(i, read_bit(i));
564 
565  *this = array;
566  }
567 
575  void circular_left_shift(const size_t n = 1)
576  {
577  const size_t real_n = n % current_size;
578 
579  if (real_n == 0)
580  return;
581 
582  BitArray array(real_n);
583 
584  for (size_t i = 0; i < real_n; ++i)
585  array.write_bit(i, read_bit(i));
586 
587  for (size_t i = 0; i < current_size - real_n; ++i)
588  write_bit(i, read_bit(i + real_n));
589 
590  for (size_t i = 0; i < real_n; ++i)
591  write_bit(current_size - real_n + i, array.read_bit(i));
592  }
593 
601  void circular_right_shift(const size_t n = 1)
602  {
603  const size_t real_n = n % current_size;
604 
605  if (real_n == 0)
606  return;
607 
608  BitArray array(real_n);
609 
610  for (size_t i = current_size - real_n; i < current_size; ++i)
611  array.write_bit(i - (current_size - real_n), read_bit(i));
612 
613  for (size_t i = current_size - 1; i >= real_n; --i)
614  write_bit(i, read_bit(i - real_n));
615 
616  for (size_t i = 0; i < real_n; ++i)
617  write_bit(i, array.read_bit(i));
618  }
619 
620  template <typename T>
621  void set_num(T n) // Paso copia porque es modificado adentro
622  {
623  empty();
624  const size_t num_bits = sizeof(T) * 8;
625  reserve(num_bits);
626  for (int i = 0; i < num_bits; ++i)
627  {
628  write_bit(current_size - i - 1, n & 1);
629  n >>= 1;
630  }
631  }
632 
633  void set_num(const char & c)
634  {
635  set_num<char>(c);
636  }
637 
638  void set_num(const short & c)
639  {
640  set_num<short>(c);
641  }
642 
643  void set_num(const int & c)
644  {
645  set_num<int>(c);
646  }
647 
648  void set_num(const long & c)
649  {
650  set_num<long>(c);
651  }
652 
653  long get_num()
654  {
655  long ret_val = 0;
656  for (int i = 0; i < current_size; ++i)
657  ret_val += read_bit(current_size - i - 1) << i;
658  return ret_val;
659  }
660 
661  void set_bit_str(const std::string & str)
662  {
663  empty();
664  const size_t & str_size = str.size();
665 
666  reserve(str_size);
667 
668  for (size_t i = 0; i < str_size; ++i)
669  {
670  char c = str[i];
671  I(c == '1' or c == '0');
672  write_bit(i, (c == '0' ? 0 : 1));
673  }
674  }
675 
676  std::string get_bit_str() const
677  {
678  std::string ret_val;
679  for (size_t i = 0; i < current_size; ++i)
680  ret_val.append(read_bit(i) == 0 ? "0" : "1");
681 
682  return ret_val;
683  }
684 
685  friend ostream & operator << (ostream & out, const BitArray & array)
686  {
687  for (size_t i = 0; i < array.current_size; ++i)
688  out << array.read_bit(i);
689  return out;
690  }
691 
694  BitArray(const unsigned char str[], const size_t num_bits)
695  {
696  load_from_array_of_chars(str, num_bits);
697  }
698 };
699 
700 } // end namespace Aleph
701 # endif /* BITARRAY_H */
702 
void write_bit(const size_t i, const unsigned int value)
Definition: bitArray.H:242
void reserve(const size_t l, const size_t r)
Definition: tpl_dynArray.H:960
BitArray(const BitArray &array)
Definition: bitArray.H:308
void save(ofstream &output)
Definition: bitArray.H:378
BitArray(ifstream &input)
Definition: bitArray.H:422
void cut(const size_t new_dim=0)
Definition: tpl_dynArray.H:1040
void reserve(size_t dim)
Definition: bitArray.H:188
size_t size() const
Retorna dimensión actual (más lejano índice escrito)
Definition: tpl_dynArray.H:523
Definition: bitArray.H:96
BitArray(const size_t dim=0)
Definition: bitArray.H:172
void dyn_left_shift(const size_t n=1)
Definition: bitArray.H:538
T & touch(const size_t i)
Definition: tpl_dynArray.H:915
void load(ifstream &input)
Definition: bitArray.H:406
void set_default_initial_value(const T &value)
Definition: tpl_dynArray.H:541
size_t size() const
Retorna la dimensión del arreglo de bits.
Definition: bitArray.H:200
void save_in_array_of_chars(const string &name, ofstream &output)
Definition: bitArray.H:442
bool exist(const size_t i) const
Definition: tpl_dynArray.H:854
void circular_right_shift(const size_t n=1)
Definition: bitArray.H:601
DynList< char > bits_list()
Lo convierte a una lista.
Definition: bitArray.H:335
BitArray(const unsigned char str[], const size_t num_bits)
Definition: bitArray.H:694
void dyn_right_shift(const size_t n=1)
Definition: bitArray.H:551
void push(const unsigned int value)
Inserta al final del arreglo el valor value.
Definition: bitArray.H:281
void left_shift(const size_t n=1)
Definition: bitArray.H:502
int read_bit(const size_t i) const
Definition: bitArray.H:225
void load_from_array_of_chars(const unsigned char str[], const size_t num_bits)
Definition: bitArray.H:479
void right_shift(const size_t n=1)
Definition: bitArray.H:520
void write(const size_t i, const unsigned int value)
Definition: bitArray.H:273
void pop()
Elimina el último bit del arreglo.
Definition: bitArray.H:287
int read(const size_t i) const
Definition: bitArray.H:257
void set_size(const size_t sz)
Reajusta la dimensión del arreglo.
Definition: bitArray.H:203
void empty()
Elimina todos los bits insertados.
Definition: bitArray.H:294
void circular_left_shift(const size_t n=1)
Definition: bitArray.H:575
Definition: ahDry.H:13
T & access(const size_t i)
Definition: tpl_dynArray.H:793
T & append(const T &item)
Inserta un item como último elemento.
Definition: htlist.H:685
void swap(DynArray< T > &array)
Definition: tpl_dynArray.H:725
Definition: bitArray.H:12

Leandro Rabindranath León