00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef PPL_Bit_Row_inlines_hh
00025 #define PPL_Bit_Row_inlines_hh 1
00026
00027 #include "globals.defs.hh"
00028 #include "assert.hh"
00029
00030
00031 #if defined(PPL_HAVE_STRINGS_H)
00032 # include <strings.h>
00033 #elif defined(PPL_HAVE_STRING_H)
00034 # include <string.h>
00035 #endif
00036
00037 #define PPL_BITS_PER_GMP_LIMB (PPL_SIZEOF_MP_LIMB_T*CHAR_BIT)
00038
00039 namespace Parma_Polyhedra_Library {
00040
00041 inline
00042 Bit_Row::Bit_Row() {
00043 mpz_init(vec);
00044 }
00045
00046 inline
00047 Bit_Row::Bit_Row(const Bit_Row& y) {
00048 mpz_init_set(vec, y.vec);
00049 }
00050
00051 inline
00052 Bit_Row::Bit_Row(const Bit_Row& y, const Bit_Row& z) {
00053 const mp_size_t y_size = y.vec->_mp_size;
00054 PPL_ASSERT(y_size >= 0);
00055 const mp_size_t z_size = z.vec->_mp_size;
00056 PPL_ASSERT(z_size >= 0);
00057 if (y_size < z_size) {
00058 PPL_ASSERT(static_cast<unsigned long>(z_size)
00059 <= ULONG_MAX / PPL_BITS_PER_GMP_LIMB);
00060 mpz_init2(vec, z_size * PPL_BITS_PER_GMP_LIMB);
00061 union_helper(y, z);
00062 }
00063 else {
00064 PPL_ASSERT(static_cast<unsigned long>(y_size)
00065 <= ULONG_MAX / PPL_BITS_PER_GMP_LIMB);
00066 mpz_init2(vec, y_size * PPL_BITS_PER_GMP_LIMB);
00067 union_helper(z, y);
00068 }
00069 }
00070
00071 inline
00072 Bit_Row::~Bit_Row() {
00073 mpz_clear(vec);
00074 }
00075
00076 inline Bit_Row&
00077 Bit_Row::operator=(const Bit_Row& y) {
00078 mpz_set(vec, y.vec);
00079 return *this;
00080 }
00081
00082 inline void
00083 Bit_Row::set(const unsigned long k) {
00084 mpz_setbit(vec, k);
00085 }
00086
00087 inline void
00088 Bit_Row::clear(const unsigned long k) {
00089 mpz_clrbit(vec, k);
00090 }
00091
00092 inline void
00093 Bit_Row::clear_from(const unsigned long k) {
00094 mpz_tdiv_r_2exp(vec, vec, k);
00095 }
00096
00097 inline unsigned long
00098 Bit_Row::count_ones() const {
00099 mp_size_t x_size = vec->_mp_size;
00100 PPL_ASSERT(x_size >= 0);
00101 return x_size == 0 ? 0 : mpn_popcount(vec->_mp_d, x_size);
00102 }
00103
00104 inline bool
00105 Bit_Row::empty() const {
00106 return mpz_sgn(vec) == 0;
00107 }
00108
00109 inline void
00110 Bit_Row::swap(Bit_Row& y) {
00111 mpz_swap(vec, y.vec);
00112 }
00113
00114 inline void
00115 Bit_Row::clear() {
00116 mpz_set_ui(vec, 0UL);
00117 }
00118
00119 inline memory_size_type
00120 Bit_Row::external_memory_in_bytes() const {
00121 return vec[0]._mp_alloc * PPL_SIZEOF_MP_LIMB_T;
00122 }
00123
00124 inline memory_size_type
00125 Bit_Row::total_memory_in_bytes() const {
00126 return sizeof(*this) + external_memory_in_bytes();
00127 }
00128
00130 inline void
00131 set_union(const Bit_Row& x, const Bit_Row& y, Bit_Row& z) {
00132 const mp_size_t x_size = x.vec->_mp_size;
00133 PPL_ASSERT(x_size >= 0);
00134 const mp_size_t y_size = y.vec->_mp_size;
00135 PPL_ASSERT(y_size >= 0);
00136 if (x_size < y_size) {
00137 PPL_ASSERT(static_cast<unsigned long>(y_size)
00138 <= ULONG_MAX / PPL_BITS_PER_GMP_LIMB);
00139 mpz_realloc2(z.vec, y_size * PPL_BITS_PER_GMP_LIMB);
00140 z.union_helper(x, y);
00141 }
00142 else {
00143 PPL_ASSERT(static_cast<unsigned long>(x_size)
00144 <= ULONG_MAX / PPL_BITS_PER_GMP_LIMB);
00145 mpz_realloc2(z.vec, x_size * PPL_BITS_PER_GMP_LIMB);
00146 z.union_helper(y, x);
00147 }
00148 }
00149
00151 inline void
00152 set_intersection(const Bit_Row& x, const Bit_Row& y, Bit_Row& z) {
00153 mpz_and(z.vec, x.vec, y.vec);
00154 }
00155
00157 inline void
00158 set_difference(const Bit_Row& x, const Bit_Row& y, Bit_Row& z) {
00159 PPL_DIRTY_TEMP0(mpz_class, complement_y);
00160 mpz_com(complement_y.get_mpz_t(), y.vec);
00161 mpz_and(z.vec, x.vec, complement_y.get_mpz_t());
00162 }
00163
00164 namespace Implementation {
00165
00166 #if defined(__GNUC__)
00167
00171 inline unsigned int
00172 first_one(unsigned int u) {
00173 PPL_ASSERT(u != 0);
00174 return __builtin_ctz(u);
00175 }
00176
00181 inline unsigned int
00182 first_one(unsigned long ul) {
00183 PPL_ASSERT(ul != 0);
00184 return __builtin_ctzl(ul);
00185 }
00186
00191 inline unsigned int
00192 first_one(unsigned long long ull) {
00193 PPL_ASSERT(ull != 0);
00194 return __builtin_ctzll(ull);
00195 }
00196
00197 #elif PPL_HAVE_DECL_FFS && PPL_SIZEOF_MP_LIMB_T == PPL_SIZEOF_INT
00198
00202 inline unsigned int
00203 first_one(mp_limb_t w) {
00204 return ffs(w)-1;
00205 }
00206
00207 #else
00208
00212 inline unsigned int
00213 first_one(mp_limb_t w) {
00214 unsigned int r = 0;
00215 w = w & -w;
00216 #if PPL_SIZEOF_MP_LIMB_T == 8
00217 if ((w & 0xffffffff) == 0) {
00218 w >>= 32;
00219 r += 32;
00220 }
00221 #elif PPL_SIZEOF_MP_LIMB_T != 4
00222 #error "size of mp_limb_t not supported by first_one(mp_limb_t w)."
00223 #endif
00224 if ((w & 0xffff) == 0) {
00225 w >>= 16;
00226 r += 16;
00227 }
00228 if ((w & 0xff) == 0) {
00229 w >>= 8;
00230 r += 8;
00231 }
00232 if (w & 0xf0)
00233 r += 4;
00234 if (w & 0xcc)
00235 r += 2;
00236 if (w & 0xaa)
00237 r += 1;
00238 return r;
00239 }
00240 #endif // !defined(__GNUC__)
00241
00242
00243 #if defined(__GNUC__)
00244
00248 inline unsigned int
00249 last_one(unsigned int u) {
00250 PPL_ASSERT(u != 0);
00251 return sizeof(unsigned int)*CHAR_BIT - 1 - __builtin_clz(u);
00252 }
00253
00258 inline unsigned int
00259 last_one(unsigned long ul) {
00260 PPL_ASSERT(ul != 0);
00261 return sizeof(unsigned long)*CHAR_BIT - 1 - __builtin_clzl(ul);
00262 }
00263
00268 inline unsigned int
00269 last_one(unsigned long long ull) {
00270 PPL_ASSERT(ull != 0);
00271 return sizeof(unsigned long long)*CHAR_BIT - 1 - __builtin_clzll(ull);
00272 }
00273
00274 #else // !defined(__GNUC__)
00275
00279 inline unsigned int
00280 last_one(mp_limb_t w) {
00281 PPL_ASSERT(w != 0);
00282 unsigned int r = 0;
00283 #if PPL_SIZEOF_MP_LIMB_T == 8
00284 if (w &
00285 #if PPL_SIZEOF_LONG == 8
00286 0xffffffff00000000
00287 #else
00288 0xffffffff00000000LL
00289 #endif
00290 ) {
00291 w >>= 32;
00292 r += 32;
00293 }
00294 #elif PPL_SIZEOF_MP_LIMB_T != 4
00295 #error "size of mp_limb_t not supported by last_one(mp_limb_t w)."
00296 #endif
00297 if (w & 0xffff0000) {
00298 w >>= 16;
00299 r += 16;
00300 }
00301 if (w & 0xff00) {
00302 w >>= 8;
00303 r += 8;
00304 }
00305 if (w & 0xf0) {
00306 w >>= 4;
00307 r += 4;
00308 }
00309 if (w & 0xc) {
00310 w >>= 2;
00311 r += 2;
00312 }
00313 if (w & 0x2)
00314 r += 1;
00315 return r;
00316 }
00317
00318 #endif // !defined(__GNUC__)
00319
00320 }
00321
00322 }
00323
00324
00325 namespace std {
00326
00328 inline void
00329 swap(Parma_Polyhedra_Library::Bit_Row& x,
00330 Parma_Polyhedra_Library::Bit_Row& y) {
00331 x.swap(y);
00332 }
00333
00335 inline void
00336 iter_swap(std::vector<Parma_Polyhedra_Library::Bit_Row>::iterator x,
00337 std::vector<Parma_Polyhedra_Library::Bit_Row>::iterator y) {
00338 swap(*x, *y);
00339 }
00340
00341 }
00342
00343 #endif // !defined(PPL_Bit_Row_inlines_hh)