00001 #ifndef BIT_STRING_HH
00002 #define BIT_STRING_HH
00003
00010 #ifndef DOXYGEN_PROCESSING
00011 #include <iostream>
00012 #include <cstdlib>
00013 #include <cstring>
00014 #include "common/deb.hh"
00015 #include "common/types.hh"
00016
00017 namespace divine {
00018 using std::cerr; using std::endl;
00019 #endif //DOXYGEN_PROCESSING
00020
00021 static const ulong_int_t bit_values[32] =
00022 {1, 2, 4, 8, 16, 32, 64, 128, 256, 1<<9, 1<<10, 1<<11, 1<<12, 1<<13, 1<<14,
00023 1<<15, 1<<16, 1<<17, 1<<18, 1<<19, 1<<20, 1<<21, 1<<22, 1<<23, 1<<24,
00024 1<<25, 1<<26, 1<<27, 1<<28, 1<<29, 1<<30, 1<<31};
00025
00026
00028 class bit_string_t
00029 {
00030 private:
00031 typedef ulong_int_t BIT32_TYPE_t;
00032 typedef BIT32_TYPE_t* P_BIT32_TYPE_t;
00033 typedef void* P_VOID;
00034 P_BIT32_TYPE_t mem;
00035 size_int_t allocated;
00036 size_int_t bits;
00037 static const size_int_t BIT32_SIZE = sizeof(BIT32_TYPE_t);
00038
00039 public:
00041 bit_string_t(const bit_string_t & bit_str2)
00042 {
00043 mem = 0;
00044 alloc_mem(bit_str2.bits);
00045 memcpy(mem,bit_str2.mem,allocated*BIT32_SIZE);
00046 }
00048 bit_string_t & operator=(const bit_string_t & bit_str2)
00049 {
00050 if (mem) free(mem);
00051 mem = 0;
00052 alloc_mem(bit_str2.bits);
00053 memcpy(mem,bit_str2.mem,allocated*BIT32_SIZE);
00054 return (*this);
00055 }
00057 bit_string_t() { mem = 0; allocated=0; bits=0; }
00059
00063 bit_string_t(const size_int_t bit_count)
00064 { mem = 0; alloc_mem(bit_count); }
00066
00071 void alloc_mem(const size_int_t bit_count)
00072 {
00073 if (mem) free(mem);
00074 bits = bit_count;
00075 allocated = bit_count>>5;
00076 if (allocated<<5 != bit_count) ++allocated;
00077 DEB(cerr << "Allocating "<< allocated <<" 4bytes"<<endl);
00078 mem = P_BIT32_TYPE_t(calloc(allocated,BIT32_SIZE));
00079 }
00081 byte_t * get_mem()
00082 { return (reinterpret_cast<byte_t *>(mem)); }
00083
00085 size_int_t get_mem_size() { return (allocated*BIT32_SIZE); }
00087
00088 void clear()
00089 { memset(mem,0,allocated*BIT32_SIZE); }
00091 ~bit_string_t() { free(P_VOID(mem)); }
00093 void enable_bit(const size_int_t i)
00094 { mem[i>>5] |= bit_values[i%32]; }
00096 void disable_bit(const size_int_t i)
00097 { mem[i>>5] &= ~ bit_values[i%32]; }
00099 void set_bit(const size_int_t i, const bool value)
00100 { mem[i>>5] = value ? (mem[i>>5]| bit_values[i%32]) :
00101 (mem[i>>5]&~bit_values[i%32]); }
00103 void invert_bit(const size_int_t i)
00104 { mem[i>>5] ^= bit_values[i%32]; }
00106 bool get_bit(const size_int_t i) const
00107 {
00108 BIT32_TYPE_t and_val = bit_values[i%32];
00109 return (mem[i>>5] & and_val);
00110 }
00112
00116 size_int_t get_allocated_4bytes_count() const
00117 { return allocated; }
00118
00120 size_int_t get_bit_count() const
00121 { return bits; }
00122
00125 void DBG_print(std::ostream & outs = cerr) const
00126 {
00127 DEB(cerr << "First 4Byte value:" << (*mem) << endl;)
00128 DEB(cerr << "Print of bit_string_t: ";)
00129 for (size_int_t i = 0; i!=bits; ++i)
00130 if (get_bit(i)) outs << '1'; else outs << '0';
00131 outs << endl;
00132 }
00133
00135 void add(const bit_string_t & from)
00136 {
00137 for (size_int_t i = 0; i!= allocated; ++i)
00138 mem[i] = mem[i] | from.mem[i];
00139 }
00140
00142 friend bool operator&(const bit_string_t & bs1, const bit_string_t & bs2)
00143 {
00144 for (size_int_t i = 0; i!= bs1.allocated; ++i)
00145 if (bs1.mem[i] & bs2.mem[i]) return false;
00146 return true;
00147 }
00148
00150 friend bool operator|(const bit_string_t & bs1, const bit_string_t & bs2)
00151 {
00152 for (size_int_t i = 0; i!= bs1.allocated; ++i)
00153 if (bs1.mem[i] | bs2.mem[i]) return false;
00154 return true;
00155 }
00156
00158 friend bool operator^(const bit_string_t & bs1, const bit_string_t & bs2)
00159 {
00160 for (size_int_t i = 0; i!= bs1.allocated; ++i)
00161 if (bs1.mem[i] ^ bs2.mem[i]) return false;
00162 return true;
00163 }
00164 };
00165
00166 };
00167
00168 #include "common/undeb.hh"
00169
00170 #endif