Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
bitArray.H
Go to the documentation of this file.
1/*
2 Aleph_w
3
4 Data structures & Algorithms
5 version 2.0.0b
6 https://github.com/lrleon/Aleph-w
7
8 This file is part of Aleph-w library
9
10 Copyright (c) 2002-2026 Leandro Rabindranath Leon
11
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files (the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29*/
30
31
97# ifndef BITARRAY_H
98# define BITARRAY_H
99
100# include <bit>
101# include <cstdint>
102# include <iostream>
103# include <fstream>
104# include <algorithm>
105# include <type_traits>
106# include <aleph.H>
107# include <tpl_dynArray.H>
108# include <ah-errors.H>
109# include <ahDry.H>
110# include <ah-dry-mixin.H>
111
112namespace Aleph
113{
114 class Byte
115 {
116 std::uint8_t value = 0;
117
118 public:
119 [[nodiscard]] unsigned int read_bit(const unsigned int i) const noexcept
120 {
121 assert(i < 8);
122 return (value >> i) & 0x1;
123 }
124
125 void write_bit(const unsigned int i, const unsigned int val) noexcept
126 {
127 assert(i < 8);
128 assert(val <= 1);
129 const std::uint8_t mask = static_cast<std::uint8_t>(1) << i;
130 const auto bit = static_cast<std::uint8_t>(val & 0x1u);
131 this->value = (this->value & ~mask) | (bit << i);
132 }
133
135
137 {
138 return static_cast<int>(value);
139 }
140
141 void set_int(int i) noexcept
142 {
143 value = static_cast<std::uint8_t>(i);
144 }
145
146 Byte &operator|=(const Byte & rhs) noexcept
147 {
148 value |= rhs.value;
149 return *this;
150 }
151
152 Byte &operator&=(const Byte & rhs) noexcept
153 {
154 value &= rhs.value;
155 return *this;
156 }
157
159 {
160 return std::popcount(value);
161 }
162
164 {
165 return 8 - count_ones();
166 }
167 };
168
188 class BitArray : public FunctionalMixin<BitArray, unsigned int>
189 {
192
194 {
195 if (current_size == 0)
196 return;
197
198 const size_t used_bits_in_last_byte = current_size % 8;
199 if (used_bits_in_last_byte == 0)
200 return;
201
202 const size_t last_byte_index = current_size / 8;
204 if (last_byte == nullptr)
205 return;
206
207 const int mask = (1u << used_bits_in_last_byte) - 1u;
208 last_byte->set_int(last_byte->get_int() & mask);
209 }
210
211 void ensure_num_bytes(const size_t num_bytes)
212 {
213 if (num_bytes == 0)
214 {
215 array_of_bytes.cut();
216 return;
217 }
218
219 if (array_of_bytes.size() < num_bytes)
220 array_of_bytes.touch(num_bytes - 1);
221 }
222
224 {
225 const size_t div = current_size / 8;
226
227 return (current_size % 8) != 0 ? div + 1 : div;
228 }
229
231 {
232 const size_t index;
233 const size_t bit_index;
234 const size_t byte_index;
237
238 public:
239 BitProxy(BitArray & a, const size_t i) noexcept
240 : index(i), bit_index(i % 8), byte_index(i / 8), array(&a)
241 {
242 if (array->array_of_bytes.exist(byte_index))
244 else
245 byte_ptr = nullptr;
246 }
247
248 operator int() const
249 {
250 ah_out_of_range_error_if(index >= array->current_size) << "Index out of range";
251
252 return byte_ptr != nullptr ? byte_ptr->read_bit(bit_index) : 0;
253 }
254
255 BitProxy &operator=(const size_t value)
256 {
257 assert(value <= 1);
258
259 if (byte_ptr == nullptr)
261
262 const bool grew = index >= array->current_size;
263 if (grew)
264 array->current_size = index + 1;
265
267
268 if (grew)
270
271 return *this;
272 }
273
275 {
276 if (byte_ptr == nullptr)
278
279 const bool grew = index >= array->current_size;
280 if (grew)
281 array->current_size = index + 1;
282
283 const int rhs_value = proxy;
285
286 if (grew)
288
289 return *this;
290 }
291 };
292
293 public:
295 using Item_Type = unsigned int;
296
303 BitArray(const size_t dim = 0)
305 {
306 array_of_bytes.set_default_initial_value(Byte());
307 }
308
310 BitArray(const size_t dim, const unsigned int value)
311 : BitArray(dim)
312 {
313 assert(value <= 1);
314 for (size_t i = 0; i < dim; ++i)
315 write_bit(i, value);
316 }
317
328 void reserve(const size_t dim)
329 {
330 set_size(dim);
331 }
332
334 [[nodiscard]] constexpr size_t size() const noexcept { return current_size; }
335
337 void set_size(const size_t sz)
338 {
339 const size_t old_size = current_size;
340 const size_t array_size = (sz + 7) / 8;
341
342 array_of_bytes.adjust(array_size); // allocate for fast read()/write()
343 current_size = sz;
344
345 if (sz > old_size && old_size != 0)
346 if (const size_t rem = old_size % 8; rem != 0)
347 {
348 const size_t clear_end = std::min(sz, old_size + (8 - rem));
349 for (size_t i = old_size; i < clear_end; ++i)
350 write_bit(i, 0);
351 }
352
354 }
355
356 int operator[](const size_t i) const { return read_bit(i); }
357
358 BitProxy operator[](const size_t i) noexcept { return BitProxy(*this, i); }
359
360 int read_bit_ne(const size_t i) const noexcept
361 {
362 const unsigned int bit_index = static_cast<unsigned int>(i % 8);
363 if (const auto ptr = array_of_bytes.test(i / 8))
364 {
365 const Byte & byte = *ptr;
366 return byte.read_bit(bit_index);
367 }
368 return 0;
369 }
370
377 int read_bit(const size_t i) const
378 {
379 ah_out_of_range_error_if(i >= current_size) << "index out of range";
380 return read_bit_ne(i);
381 }
382
383 int operator()(const size_t i) const { return read_bit(i); }
384
392 void write_bit(const size_t i, const unsigned int value)
393 {
394 ah_out_of_range_error_if(value > 1) << "BitArray::write_bit: value must be 0 or 1";
395 array_of_bytes.touch(i / 8).write_bit(i % 8, value);
396 if (i >= current_size)
397 {
398 current_size = i + 1;
400 }
401 }
402
411 int read(const size_t i) const
412 {
413 ah_out_of_range_error_if(i >= current_size) << "index out of range";
414
415 const int bit_index = i % 8;
416 return array_of_bytes.access(i / 8).read_bit(bit_index);
417 }
418
426 void write(const size_t i, const unsigned int value)
427 {
428 ah_out_of_range_error_if(value > 1) << "BitArray::write: value must be 0 or 1";
429
430 array_of_bytes.access(i / 8).write_bit(i % 8, value);
431 if (i >= current_size)
432 {
433 current_size = i + 1;
435 }
436 }
437
438 int fast_read(const size_t i) const noexcept
439 {
440 return array_of_bytes.access(i / 8).read_bit(i % 8);
441 }
442
443 void fast_write(const size_t i, const unsigned int value)
444 {
445 ah_out_of_range_error_if(value > 1) << "BitArray::fast_write: value must be 0 or 1";
446 array_of_bytes.access(i / 8).write_bit(i % 8, value);
447 }
448
450 void push(const unsigned int value)
451 {
452 write_bit(current_size, value);
453 }
454
456 void pop()
457 {
458 ah_underflow_error_if(current_size == 0) << "BitArray::pop on empty array";
459 current_size--;
462 }
463
466 {
467 current_size = 0;
468 array_of_bytes.cut();
469 }
470
479 BitArray(const BitArray & array)
481 {
482 // empty
483 }
484
485 void swap(BitArray & array) noexcept
486 {
487 std::swap(current_size, array.current_size);
488 array_of_bytes.swap(array.array_of_bytes);
489 }
490
492 : BitArray()
493 {
494 swap(array);
495 }
496
497 BitArray &operator=(BitArray && array) noexcept
498 {
499 current_size = 0;
500 array_of_bytes.cut();
501 swap(array);
502 return *this;
503 }
504
507 {
509 for (size_t i = 0; i < current_size; ++i)
510 ret_val.append(static_cast<char>(read_bit(i)));
511 return ret_val;
512 }
513
526 {
527 if (this == &array)
528 return *this;
529
532
533 return *this;
534 }
535
548 void save(std::ostream & output) const
549 {
550 const size_t num_bytes = get_num_bytes();
551
552 // Header
553 output << num_bytes << " " << current_size << '\n';
554 ah_runtime_error_if(not output) << "BitArray::save: write failed (header)";
555
556 // Payload
557 for (size_t i = 0; i < num_bytes; ++i)
558 {
559 int byte = 0;
560 if (const Byte *p = array_of_bytes.test(i); p != nullptr)
561 byte = p->get_int();
562
563 // defend export invariant last masked byte
564 if (num_bytes != 0 && i + 1 == num_bytes)
565 if (const size_t used = current_size % 8; used != 0)
566 {
567 const int mask = (1u << used) - 1u;
568 byte &= mask;
569 }
570
571 output << byte << " ";
573 << "BitArray::save: write payload failed (byte " << i << ")";
574 }
575
576 output << '\n';
577 ah_runtime_error_if(not output) << "BitArray::save: write failed (newline)";
578 }
579
590 void load(std::istream & input)
591 {
592 // Read header first (without touching the current state until validated)
593 size_t num_bytes = 0;
594 size_t num_bits = 0;
595
596 ah_runtime_error_if(not (input >> num_bytes >> num_bits)) << "BitArray::load: read failed (header)";
597
598 const size_t expected = (num_bits + 7) / 8;
599 ah_runtime_error_if(num_bytes != expected)
600 << "BitArray::load: inconsistent header (num_bytes vs num_bits)";
601
602 // Heavy Load: build temporary and then swap
604 tmp.current_size = num_bits;
605 tmp.array_of_bytes.cut();
606 tmp.ensure_num_bytes(num_bytes);
607
608 for (size_t i = 0; i < num_bytes; ++i)
609 {
610 long v = 0;
611 ah_runtime_error_if(not (input >> v)) << "BitArray::load: read failed (payload)";
612 ah_runtime_error_if(v < 0 or v > 255) << "BitArray::load: byte value out of range";
613
614 tmp.array_of_bytes.touch(i).set_int(static_cast<int>(v));
615 }
616
617 tmp.clear_unused_bits_in_last_byte();
618 swap(tmp);
619 }
620
623 BitArray(std::ifstream & input)
624 {
625 load(input);
626 }
627
643 void save_in_array_of_chars(const std::string & name, std::ostream & output) const
644 {
645 const size_t num_bytes = get_num_bytes();
646
647 output << "// " << current_size << " bits declaration" << '\n'
648 << "const unsigned char " << name << " [" << num_bytes << "] = {"
649 << '\n' << " ";
650
651 for (size_t i = 0; i < num_bytes; i++)
652 {
653 int byte = 0;
654 if (const Byte *p = array_of_bytes.test(i); p != nullptr)
655 byte = p->get_int();
656
657 if (num_bytes != 0 && i + 1 == num_bytes)
658 if (const size_t used = current_size % 8; used != 0)
659 {
660 const int mask = (1u << used) - 1u;
661 byte &= mask;
662 }
663
664 output << byte;
665
666 if (i != num_bytes - 1)
667 output << ", ";
668
669 if ((i + 1) % 15 == 0)
670 output << '\n' << " ";
671 }
672
673 output << '\n' << "};" << '\n' << '\n';
674 }
675
687 void load_from_array_of_chars(const unsigned char str[],
688 const size_t num_bits)
689 {
690 array_of_bytes.cut();
691
692 size_t num_bytes = num_bits / 8;
693
694 if (num_bits % 8 != 0)
695 num_bytes++;
696
697 for (size_t i = 0; i < num_bytes; i++)
698 array_of_bytes.touch(i).set_int(str[i]);
699
700 current_size = num_bits;
702 }
703
711 void left_shift(const size_t n = 1)
712 {
713 const size_t real_n = std::min<size_t>(n, current_size);
714
715 for (size_t i = 0; i < current_size - real_n; ++i)
716 write_bit(i, read_bit(i + real_n));
717
718 for (size_t i = current_size - real_n; i < current_size; ++i)
719 write_bit(i, 0);
720 }
721
729 void right_shift(const size_t n = 1)
730 {
731 const size_t real_n = std::min<size_t>(n, current_size);
732
733 for (size_t i = current_size; i > real_n; --i)
734 write_bit(i - 1, read_bit(i - real_n - 1));
735
736 for (size_t i = real_n; i > 0; --i)
737 write_bit(i - 1, 0);
738 }
739
747 void dyn_left_shift(const size_t n = 1)
748 {
749 for (size_t i = 0; i < n; ++i)
750 push(0);
751 }
752
760 void dyn_right_shift(const size_t n = 1)
761 {
762 if (current_size == 0)
763 return;
764
765 if (n >= current_size)
766 {
767 set_size(1);
768 write_bit(0, 0);
770 return;
771 }
772
773 BitArray array(current_size - n);
774
775 for (size_t i = 0; i < current_size - n; ++i)
776 array.write_bit(i, read_bit(i));
777
778 *this = array;
779 }
780
788 void circular_left_shift(const size_t n = 1)
789 {
790 if (current_size < 2)
791 return;
792
793 const size_t real_n = n % current_size;
794
795 if (real_n == 0)
796 return;
797
798 BitArray array(real_n);
799
800 for (size_t i = 0; i < real_n; ++i)
801 array.write_bit(i, read_bit(i));
802
803 for (size_t i = 0; i < current_size - real_n; ++i)
804 write_bit(i, read_bit(i + real_n));
805
806 for (size_t i = 0; i < real_n; ++i)
807 write_bit(current_size - real_n + i, array.read_bit(i));
808 }
809
817 void circular_right_shift(const size_t n = 1)
818 {
819 if (current_size < 2)
820 return;
821
822 const size_t real_n = n % current_size;
823
824 if (real_n == 0)
825 return;
826
827 BitArray array(real_n);
828
829 for (size_t i = current_size - real_n; i < current_size; ++i)
830 array.write_bit(i - (current_size - real_n), read_bit(i));
831
832 for (size_t i = current_size; i-- > real_n;)
833 write_bit(i, read_bit(i - real_n));
834
835 for (size_t i = 0; i < real_n; ++i)
836 write_bit(i, array.read_bit(i));
837 }
838
839 template <typename T>
840 void set_num(T n) // Copy step because it is modified inside
841 {
842 using U = std::make_unsigned_t<T>;
843 U u = static_cast<U>(n);
844 empty();
845 const size_t num_bits = sizeof(T) * 8;
846 reserve(num_bits);
847 for (size_t i = 0; i < num_bits; ++i)
848 {
849 write_bit(current_size - i - 1, u & 1u);
850 u >>= 1;
851 }
852 }
853
854 void set_num(const char & c)
855 {
856 set_num<char>(c);
857 }
858
859 void set_num(const short & c)
860 {
862 }
863
864 void set_num(const int & c)
865 {
866 set_num<int>(c);
867 }
868
869 void set_num(const long & c)
870 {
871 set_num<long>(c);
872 }
873
874 unsigned long get_unum() const noexcept
875 {
876 using UL = unsigned long;
877 constexpr size_t max_bits = sizeof(UL) * 8;
878 const size_t n = std::min(current_size, max_bits);
879
880 UL ret_val = 0;
881 for (size_t i = 0; i < n; ++i)
882 ret_val |= static_cast<UL>(read_bit_ne(current_size - i - 1)) << i;
883 return ret_val;
884 }
885
887 {
888 return static_cast<long>(get_unum());
889 }
890
891 void set_bit_str(const std::string & str)
892 {
893 empty();
894 const size_t & str_size = str.size();
895
897
898 for (size_t i = 0; i < str_size; ++i)
899 {
900 char c = str[i];
901 assert(c == '1' or c == '0');
902 write_bit(i, (c == '0' ? 0 : 1));
903 }
904 }
905
906 std::string get_bit_str() const
907 {
908 std::string ret_val;
909 for (size_t i = 0; i < current_size; ++i)
910 ret_val.append(read_bit(i) == 0 ? "0" : "1");
911
912 return ret_val;
913 }
914
915 std::string to_string() const
916 {
917 return get_bit_str();
918 }
919
920 friend std::ostream &operator<<(std::ostream & out, const BitArray & array)
921 {
922 for (size_t i = 0; i < array.current_size; ++i)
923 out << array.read_bit(i);
924 return out;
925 }
926
929 BitArray(const unsigned char str[], const size_t num_bits)
930 {
931 load_from_array_of_chars(str, num_bits);
932 }
933
935 {
936 if (rhs.size() > current_size)
937 {
940 }
941
942 const size_t rhs_num_bytes = (rhs.size() + 7) / 8;
943 const size_t rhs_used_bits_in_last_byte = rhs.size() % 8;
944 for (size_t i = 0; i < rhs_num_bytes; ++i)
945 {
946 const Byte *rhs_byte = rhs.array_of_bytes.test(i);
947 if (rhs_byte == nullptr)
948 continue;
949
951 if (rhs_used_bits_in_last_byte != 0 && i + 1 == rhs_num_bytes)
952 {
953 const int mask = (1u << rhs_used_bits_in_last_byte) - 1u;
954 masked.set_int(masked.get_int() & mask);
955 }
956
957 if (masked.get_int() == 0)
958 continue;
959
960 array_of_bytes.touch(i) |= masked;
961 }
962
964 return *this;
965 }
966
968 {
969 if (const size_t new_size = std::min(size(), rhs.size()); new_size != current_size)
970 {
973 }
974
975 const size_t num_bytes = get_num_bytes();
976 for (size_t i = 0; i < num_bytes; ++i)
977 {
978 Byte *lhs_byte = array_of_bytes.test(i);
979 if (lhs_byte == nullptr)
980 continue;
981
982 if (const Byte *rhs_byte = rhs.array_of_bytes.test(i); rhs_byte == nullptr)
983 lhs_byte->set_int(0);
984 else
985 *lhs_byte &= *rhs_byte;
986 }
987
989 return *this;
990 }
991
992 friend BitArray operator|(const BitArray & op1, const BitArray & op2)
993 {
994 BitArray ret = op1;
995 ret |= op2;
996 return ret;
997 }
998
999 friend BitArray operator&(const BitArray & op1, const BitArray & op2)
1000 {
1001 BitArray ret = op1;
1002 ret &= op2;
1003 return ret;
1004 }
1005
1006 bool operator==(const BitArray & rhs) const
1007 {
1008 if (size() != rhs.size())
1009 return false;
1010
1011 for (size_t i = 0; i < size(); ++i)
1012 if (read_bit(i) != rhs.read_bit(i))
1013 return false;
1014
1015 return true;
1016 }
1017
1018 private:
1019 template <class Operation>
1021 {
1022 for (size_t i = 0; i < current_size; ++i)
1023 if (not operation(read_bit(i)))
1024 return false;
1025 return true;
1026 }
1027
1028 public:
1030 {
1032 long curr_idx = 0;
1033
1034 public:
1035 Iterator() = default;
1036
1038 : array_ptr(const_cast<BitArray *>(&array)), curr_idx(0)
1039 {
1040 // empty
1041 }
1042
1044 {
1045 return array_ptr != nullptr and curr_idx >= 0 and
1046 static_cast<size_t>(curr_idx) < array_ptr->size();
1047 }
1048
1050 {
1051 return has_curr() ? array_ptr->read_bit_ne(static_cast<size_t>(curr_idx)) : 0;
1052 }
1053
1054 [[nodiscard]] unsigned int get_curr() const
1055 {
1057 << "Iterator is at the end of the list";
1058 return array_ptr->read_bit(static_cast<size_t>(curr_idx));
1059 }
1060
1061 [[nodiscard]] long get_pos() const noexcept { return curr_idx; }
1062
1064
1065 void next()
1066 {
1067 ah_overflow_error_if(array_ptr == nullptr) << "Iterator is not bound to any BitArray";
1068 ah_overflow_error_if(curr_idx == static_cast<long>(array_ptr->size()))
1069 << "not current item in iterator";
1070 next_ne();
1071 }
1072
1074
1075 void prev()
1076 {
1077 ah_underflow_error_if(array_ptr == nullptr) << "Iterator is not bound to any BitArray";
1078 ah_underflow_error_if(curr_idx == -1) << "not current item in iterator";
1079 prev_ne();
1080 }
1081
1083 {
1084 if (array_ptr == nullptr or array_ptr->size() == 0)
1085 curr_idx = -1;
1086 else
1087 curr_idx = static_cast<long>(array_ptr->size()) - 1;
1088 }
1089
1091 {
1092 if (array_ptr == nullptr)
1093 {
1094 curr_idx = 0;
1095 return;
1096 }
1097 curr_idx = static_cast<long>(array_ptr->size());
1098 }
1099
1101
1103 };
1104
1105 auto get_it() const noexcept { return Iterator(*this); }
1106
1107 template <class Operation>
1109 {
1110 return const_cast<BitArray &>(*this).__traverse(operation);
1111 }
1112
1113 template <class Operation>
1115 {
1116 return __traverse(operation);
1117 }
1118
1119 template <class Operation>
1121 {
1123 }
1124
1125 template <class Operation>
1127 {
1129 }
1130
1131 // Functional methods provided by FunctionalMixin<BitArray, unsigned int>
1132
1133 Generic_Items(unsigned int);
1134
1136
1138 {
1139 return foldl<int>(0, [](int acc, int x) { return acc + x; });
1140 }
1141
1143 {
1144 return foldl<int>(0, [](int acc, int x) { return acc + (x == 0); });
1145 }
1146 };
1147} // end namespace Aleph
1148# endif /* BITARRAY_H */
CRTP Mixins for container functionality (DRY principle).
Exception handling system with formatted messages for Aleph-w.
#define ah_out_of_range_error_if(C)
Throws std::out_of_range if condition holds.
Definition ah-errors.H:579
#define ah_underflow_error_if(C)
Throws std::underflow_error if condition holds.
Definition ah-errors.H:368
#define ah_overflow_error_if(C)
Throws std::overflow_error if condition holds.
Definition ah-errors.H:463
#define ah_runtime_error_if(C)
Throws std::runtime_error if condition holds.
Definition ah-errors.H:266
DRY (Don't Repeat Yourself) utilities and macros.
#define Generic_Items(Type)
Generates an items() method returning all container elements.
Definition ahDry.H:139
#define STL_ALEPH_ITERATOR(Set_Name)
Definition ahIterator.H:208
Core header for the Aleph-w library.
const size_t byte_index
Definition bitArray.H:234
BitProxy(BitArray &a, const size_t i) noexcept
Definition bitArray.H:239
BitProxy & operator=(const BitProxy &proxy)
Definition bitArray.H:274
BitProxy & operator=(const size_t value)
Definition bitArray.H:255
void reset_first() noexcept
Definition bitArray.H:1100
unsigned int get_curr_ne() const noexcept
Definition bitArray.H:1049
void prev_ne() noexcept
Definition bitArray.H:1073
Iterator(const BitArray &array) noexcept
Definition bitArray.H:1037
unsigned int get_curr() const
Definition bitArray.H:1054
void reset() noexcept
Definition bitArray.H:1102
bool has_curr() const noexcept
Definition bitArray.H:1043
long get_pos() const noexcept
Definition bitArray.H:1061
void end() noexcept
Definition bitArray.H:1090
void next_ne() noexcept
Definition bitArray.H:1063
void reset_last() noexcept
Definition bitArray.H:1082
Contiguous array of bits.
Definition bitArray.H:189
bool traverse(Operation &operation) const
Definition bitArray.H:1108
void fast_write(const size_t i, const unsigned int value)
Definition bitArray.H:443
int read_bit(const size_t i) const
Read bit i.
Definition bitArray.H:377
bool traverse(Operation &&operation=Operation()) const
Definition bitArray.H:1120
void set_num(const short &c)
Definition bitArray.H:859
std::string get_bit_str() const
Definition bitArray.H:906
BitArray & operator=(BitArray &&array) noexcept
Definition bitArray.H:497
BitArray & operator&=(const BitArray &rhs)
Definition bitArray.H:967
void circular_left_shift(const size_t n=1)
Shifts the bits n positions to the left circularly.
Definition bitArray.H:788
BitArray(const unsigned char str[], const size_t num_bits)
Constructs a new array of bits from an array of characters previously generated with load_from_array_...
Definition bitArray.H:929
BitProxy operator[](const size_t i) noexcept
Definition bitArray.H:358
void set_num(const char &c)
Definition bitArray.H:854
void load_from_array_of_chars(const unsigned char str[], const size_t num_bits)
Reads an array of bits saved in a character array.
Definition bitArray.H:687
bool __traverse(Operation &operation)
Definition bitArray.H:1020
bool operator==(const BitArray &rhs) const
Definition bitArray.H:1006
long get_num() const noexcept
Definition bitArray.H:886
void set_bit_str(const std::string &str)
Definition bitArray.H:891
int fast_read(const size_t i) const noexcept
Definition bitArray.H:438
void write(const size_t i, const unsigned int value)
Writes bit i with value without memory check.
Definition bitArray.H:426
auto get_it() const noexcept
Definition bitArray.H:1105
void left_shift(const size_t n=1)
Shifts the bits n positions to the left.
Definition bitArray.H:711
BitArray(const BitArray &array)
Copy constructor.
Definition bitArray.H:479
void circular_right_shift(const size_t n=1)
Shifts the bits n positions to the right circularly.
Definition bitArray.H:817
void pop()
Removes the last bit of the array.
Definition bitArray.H:456
size_t current_size
Definition bitArray.H:190
void set_num(const long &c)
Definition bitArray.H:869
void write_bit(const size_t i, const unsigned int value)
Write bit i with the value.
Definition bitArray.H:392
BitArray(const size_t dim, const unsigned int value)
Build a BitArray of size dim with all bits set to value.
Definition bitArray.H:310
void reserve(const size_t dim)
Reserve memory in advance for the bit array dim dimension.
Definition bitArray.H:328
void dyn_left_shift(const size_t n=1)
Shifts bits n positions to the left dynamically.
Definition bitArray.H:747
BitArray & operator|=(const BitArray &rhs)
Definition bitArray.H:934
BitArray(const size_t dim=0)
Bit array constructor.
Definition bitArray.H:303
void right_shift(const size_t n=1)
Shifts the bits n positions to the right.
Definition bitArray.H:729
void load(std::istream &input)
Loads an array of bits from a file.
Definition bitArray.H:590
DynList< char > bits_list() const
Converts it to a list.
Definition bitArray.H:506
void empty() noexcept
Delete all inserted bits.
Definition bitArray.H:465
BitArray(BitArray &&array) noexcept
Definition bitArray.H:491
int count_ones() const noexcept
Definition bitArray.H:1137
size_t get_num_bytes() const noexcept
Definition bitArray.H:223
void save_in_array_of_chars(const std::string &name, std::ostream &output) const
Saves a static string declaration to a text file.
Definition bitArray.H:643
int read(const size_t i) const
Quick read of bit i.
Definition bitArray.H:411
friend BitArray operator&(const BitArray &op1, const BitArray &op2)
Definition bitArray.H:999
friend std::ostream & operator<<(std::ostream &out, const BitArray &array)
Definition bitArray.H:920
void set_num(T n)
Definition bitArray.H:840
void ensure_num_bytes(const size_t num_bytes)
Definition bitArray.H:211
BitArray(std::ifstream &input)
Build a new array of bits from a file constructed using the save() method.
Definition bitArray.H:623
void push(const unsigned int value)
Inserts the value at the end of the array.
Definition bitArray.H:450
constexpr size_t size() const noexcept
Returns the dimension of the bit array.
Definition bitArray.H:334
void swap(BitArray &array) noexcept
Definition bitArray.H:485
BitArray & operator=(const BitArray &array)
Bit array allocation.
Definition bitArray.H:525
void dyn_right_shift(const size_t n=1)
Shifts bits n positions to the right dynamically.
Definition bitArray.H:760
void set_num(const int &c)
Definition bitArray.H:864
friend BitArray operator|(const BitArray &op1, const BitArray &op2)
Definition bitArray.H:992
int operator()(const size_t i) const
Definition bitArray.H:383
bool traverse(Operation &operation)
Definition bitArray.H:1114
bool traverse(Operation &&operation=Operation())
Definition bitArray.H:1126
void save(std::ostream &output) const
Saves the bit sequence in a text file.
Definition bitArray.H:548
int count_zeros() const noexcept
Definition bitArray.H:1142
int read_bit_ne(const size_t i) const noexcept
Definition bitArray.H:360
void clear_unused_bits_in_last_byte() noexcept
Definition bitArray.H:193
unsigned int Item_Type
Type returned by Iterator::get_curr() - individual bits as unsigned int.
Definition bitArray.H:295
unsigned long get_unum() const noexcept
Definition bitArray.H:874
std::string to_string() const
Definition bitArray.H:915
DynArray< Byte > array_of_bytes
Definition bitArray.H:191
int operator[](const size_t i) const
Definition bitArray.H:356
void set_size(const size_t sz)
Resets the dimension of the array.
Definition bitArray.H:337
void write_bit(const unsigned int i, const unsigned int val) noexcept
Definition bitArray.H:125
int get_int() const noexcept
Definition bitArray.H:136
std::uint8_t value
Definition bitArray.H:116
Byte & operator|=(const Byte &rhs) noexcept
Definition bitArray.H:146
int count_ones() const noexcept
Definition bitArray.H:158
void set_int(int i) noexcept
Definition bitArray.H:141
Byte() noexcept=default
unsigned int read_bit(const unsigned int i) const noexcept
Definition bitArray.H:119
Byte & operator&=(const Byte &rhs) noexcept
Definition bitArray.H:152
int count_zeros() const noexcept
Definition bitArray.H:163
Dynamic singly linked list with functional programming support.
Definition htlist.H:1423
T & append(const T &item)
Append a new item by copy.
Definition htlist.H:1562
CRTP Mixin providing functional programming operations.
Container< __Type > maps(Operation &operation) const
Transform elements using a mapping function.
__gmp_expr< typename __gmp_resolve_expr< T, V >::value_type, __gmp_binary_expr< __gmp_expr< T, U >, __gmp_expr< V, W >, __gmp_dim_function > > dim(const __gmp_expr< T, U > &expr1, const __gmp_expr< V, W > &expr2)
Definition gmpfrxx.h:4052
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
std::decay_t< typename HeadC::Item_Type > T
Definition ah-zip.H:107
DynList< T > maps(const C &c, Op op)
Classic map operation.
Lazy and scalable dynamic array implementation.
ofstream output
Definition writeHeap.C:213