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 #ifndef _CHOMP_STRUCT_BITSETS_H_
00036 #define _CHOMP_STRUCT_BITSETS_H_
00037
00038 #include "chomp/system/config.h"
00039
00040 #include <iostream>
00041 #include <cstdlib>
00042
00043 namespace chomp {
00044 namespace homology {
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 class BitSets
00059 {
00060 static const int_t longBits = sizeof (long) * 8;
00061 static const int_t longBitMask = longBits - 1;
00062 static const int_t longBitShift = (sizeof (long) == 8) ? 6 : 5;
00063
00064 public:
00065
00066
00067
00068
00069 BitSets (int_t _nsets, int_t _nelem);
00070
00071
00072 BitSets (const BitSets &s);
00073
00074
00075 BitSets &operator = (const BitSets &s);
00076
00077
00078 ~BitSets ();
00079
00080
00081 void add (int_t n, int_t e);
00082
00083
00084 void remove (int_t n, int_t e);
00085
00086
00087 bool check (int_t n, int_t e) const;
00088
00089
00090 void addset (int_t n, int_t m);
00091
00092
00093
00094 int_t get (int_t n, int_t start = 0) const;
00095
00096 private:
00097
00098 int_t nsets;
00099
00100
00101 int_t nelem;
00102
00103
00104 int_t nunits;
00105
00106
00107 unsigned long *bits;
00108
00109
00110 int_t arraySize ();
00111
00112 };
00113
00114
00115
00116 inline int_t BitSets::arraySize ()
00117 {
00118 long size = static_cast<long> (nsets) * static_cast<long> (nunits);
00119 if (static_cast<long> (static_cast<int_t> (size)) != size)
00120 throw "Too large BitSets requested.";
00121 return static_cast<int_t> (size);
00122 }
00123
00124 inline BitSets::BitSets (int_t _nsets, int_t _nelem):
00125 nsets (_nsets), nelem (_nelem),
00126 nunits ((_nelem + (sizeof (unsigned long) << 3) - 1) /
00127 (sizeof (unsigned long) << 3)), bits (0)
00128 {
00129 int_t size = arraySize ();
00130 bits = new unsigned long [size];
00131 for (int_t i = 0; i < size; ++ i)
00132 bits [i] = 0;
00133 return;
00134 }
00135
00136 inline BitSets::BitSets (const BitSets &s):
00137 nsets (s. nsets), nelem (s. nelem), nunits (s. nunits), bits (0)
00138 {
00139 int_t size = arraySize ();
00140 bits = new unsigned long [size];
00141 for (int_t i = 0; i < size; ++ i)
00142 bits [i] = s. bits [i];
00143 return;
00144 }
00145
00146 inline BitSets &BitSets::operator = (const BitSets &s)
00147 {
00148 if (this == &s)
00149 return *this;
00150 delete [] bits;
00151 nsets = s. nsets;
00152 nelem = s. nelem;
00153 nunits = s. nunits;
00154 int_t size = arraySize ();
00155 bits = new unsigned long [size];
00156 for (int_t i = 0; i < size; ++ i)
00157 bits [i] = s. bits [i];
00158 return *this;
00159 }
00160
00161 inline BitSets::~BitSets ()
00162 {
00163 delete [] bits;
00164 return;
00165 }
00166
00167 inline void BitSets::add (int_t n, int_t e)
00168 {
00169
00170 unsigned long *buf = bits + n * nunits;
00171 buf [e >> longBitShift] |= (1ul << (e & longBitMask));
00172 return;
00173 }
00174
00175 inline void BitSets::remove (int_t n, int_t e)
00176 {
00177 unsigned long *buf = bits + n * nunits;
00178 buf [e >> longBitShift] &= ~(1ul << (e & longBitMask));
00179 return;
00180 }
00181
00182 inline bool BitSets::check (int_t n, int_t e) const
00183 {
00184 unsigned long *buf = bits + n * nunits;
00185 return !!(buf [e >> longBitShift] & (1ul << (e & longBitMask)));
00186 }
00187
00188 inline void BitSets::addset (int_t n, int_t m)
00189 {
00190 unsigned long *nbuf = bits + n * nunits;
00191 unsigned long *mbuf = bits + m * nunits;
00192 for (int_t i = 0; i < nunits; ++ i)
00193 *(nbuf ++) |= *(mbuf ++);
00194 return;
00195 }
00196
00197 inline int_t BitSets::get (int_t n, int_t start) const
00198 {
00199 if (start >= nelem)
00200 return -1;
00201 unsigned long *buf = bits + n * nunits;
00202 int_t offset = start >> longBitShift;
00203 int bit = start & longBitMask;
00204 if (buf [offset] & (~0ul << bit))
00205 {
00206 for (; bit < longBits; ++ bit)
00207 {
00208 if (buf [offset] & (1ul << bit))
00209 return (offset << longBitShift) + bit;
00210 }
00211 throw "Wrong bit number in BitSets.";
00212 }
00213 for (++ offset; offset < nunits; ++ offset)
00214 {
00215 if (!buf [offset])
00216 continue;
00217 for (int bit = 0; bit < longBits; ++ bit)
00218 {
00219 if (buf [offset] & (1ul << bit))
00220 return (offset << longBitShift) + bit;
00221 }
00222 throw "False bit in BitSets.";
00223 }
00224 return -1;
00225 }
00226
00227
00228 }
00229 }
00230
00231 #endif // _CHOMP_STRUCT_BITSETS_H_
00232
00233
00234