PPL  0.12.1
Bit_Row.inlines.hh
Go to the documentation of this file.
00001 /* Bit_Row class implementation: inline functions.
00002    Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it>
00003    Copyright (C) 2010-2012 BUGSENG srl (http://bugseng.com)
00004 
00005 This file is part of the Parma Polyhedra Library (PPL).
00006 
00007 The PPL is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 3 of the License, or (at your
00010 option) any later version.
00011 
00012 The PPL is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with this program; if not, write to the Free Software Foundation,
00019 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA.
00020 
00021 For the most up-to-date information see the Parma Polyhedra Library
00022 site: http://bugseng.com/products/ppl/ . */
00023 
00024 #ifndef PPL_Bit_Row_inlines_hh
00025 #define PPL_Bit_Row_inlines_hh 1
00026 
00027 #include "compiler.hh"
00028 #include "globals.defs.hh"
00029 #include "assert.hh"
00030 
00031 // For the declaration of ffs(3).
00032 #if defined(PPL_HAVE_STRINGS_H)
00033 # include <strings.h>
00034 #elif defined(PPL_HAVE_STRING_H)
00035 # include <string.h>
00036 #endif
00037 
00038 #define PPL_BITS_PER_GMP_LIMB sizeof_to_bits(PPL_SIZEOF_MP_LIMB_T)
00039 
00040 namespace Parma_Polyhedra_Library {
00041 
00042 inline
00043 Bit_Row::Bit_Row() {
00044   mpz_init(vec);
00045 }
00046 
00047 inline
00048 Bit_Row::Bit_Row(const Bit_Row& y) {
00049   mpz_init_set(vec, y.vec);
00050 }
00051 
00052 inline
00053 Bit_Row::Bit_Row(const Bit_Row& y, const Bit_Row& z) {
00054   const mp_size_t y_size = y.vec->_mp_size;
00055   PPL_ASSERT(y_size >= 0);
00056   const mp_size_t z_size = z.vec->_mp_size;
00057   PPL_ASSERT(z_size >= 0);
00058   if (y_size < z_size) {
00059     PPL_ASSERT(static_cast<unsigned long>(z_size)
00060                <= C_Integer<unsigned long>::max / PPL_BITS_PER_GMP_LIMB);
00061     mpz_init2(vec, static_cast<unsigned long>(z_size) * PPL_BITS_PER_GMP_LIMB);
00062     union_helper(y, z);
00063   }
00064   else {
00065     PPL_ASSERT(static_cast<unsigned long>(y_size)
00066                <= C_Integer<unsigned long>::max / PPL_BITS_PER_GMP_LIMB);
00067     mpz_init2(vec, static_cast<unsigned long>(y_size) * PPL_BITS_PER_GMP_LIMB);
00068     union_helper(z, y);
00069   }
00070 }
00071 
00072 inline
00073 Bit_Row::~Bit_Row() {
00074   mpz_clear(vec);
00075 }
00076 
00077 inline Bit_Row&
00078 Bit_Row::operator=(const Bit_Row& y) {
00079   mpz_set(vec, y.vec);
00080   return *this;
00081 }
00082 
00083 inline void
00084 Bit_Row::set(const unsigned long k) {
00085   mpz_setbit(vec, k);
00086 }
00087 
00088 inline void
00089 Bit_Row::clear(const unsigned long k) {
00090   mpz_clrbit(vec, k);
00091 }
00092 
00093 inline void
00094 Bit_Row::clear_from(const unsigned long k) {
00095   mpz_tdiv_r_2exp(vec, vec, k);
00096 }
00097 
00098 inline unsigned long
00099 Bit_Row::count_ones() const {
00100   mp_size_t x_size = vec->_mp_size;
00101   PPL_ASSERT(x_size >= 0);
00102   return (x_size == 0) ? 0 : mpn_popcount(vec->_mp_d, x_size);
00103 }
00104 
00105 inline bool
00106 Bit_Row::empty() const {
00107   return mpz_sgn(vec) == 0;
00108 }
00109 
00110 inline void
00111 Bit_Row::m_swap(Bit_Row& y) {
00112   mpz_swap(vec, y.vec);
00113 }
00114 
00115 inline void
00116 Bit_Row::clear() {
00117   mpz_set_ui(vec, 0UL);
00118 }
00119 
00120 inline memory_size_type
00121 Bit_Row::external_memory_in_bytes() const {
00122   return static_cast<memory_size_type>(vec[0]._mp_alloc) * PPL_SIZEOF_MP_LIMB_T;
00123 }
00124 
00125 inline memory_size_type
00126 Bit_Row::total_memory_in_bytes() const {
00127   return sizeof(*this) + external_memory_in_bytes();
00128 }
00129 
00130 inline void
00131 Bit_Row::union_assign(const Bit_Row& x, const Bit_Row& y) {
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                <= C_Integer<unsigned long>::max / PPL_BITS_PER_GMP_LIMB);
00139     mpz_realloc2(vec, static_cast<unsigned long>(y_size) * PPL_BITS_PER_GMP_LIMB);
00140     union_helper(x, y);
00141   }
00142   else {
00143     PPL_ASSERT(static_cast<unsigned long>(x_size)
00144                <= C_Integer<unsigned long>::max / PPL_BITS_PER_GMP_LIMB);
00145     mpz_realloc2(vec, static_cast<unsigned long>(x_size) * PPL_BITS_PER_GMP_LIMB);
00146     union_helper(y, x);
00147   }
00148 }
00149 
00150 inline void
00151 Bit_Row::intersection_assign(const Bit_Row& x, const Bit_Row& y) {
00152   mpz_and(vec, x.vec, y.vec);
00153 }
00154 
00155 inline void
00156 Bit_Row::difference_assign(const Bit_Row& x, const Bit_Row& y) {
00157   PPL_DIRTY_TEMP(mpz_class, complement_y);
00158   mpz_com(complement_y.get_mpz_t(), y.vec);
00159   mpz_and(vec, x.vec, complement_y.get_mpz_t());
00160 }
00161 
00162 namespace Implementation {
00163 
00167 inline unsigned int
00168 first_one(unsigned int u) {
00169   return ctz(u);
00170 }
00171 
00176 inline unsigned int
00177 first_one(unsigned long ul) {
00178   return ctz(ul);
00179 }
00180 
00185 inline unsigned int
00186 first_one(unsigned long long ull) {
00187   return ctz(ull);
00188 }
00189 
00193 inline unsigned int
00194 last_one(unsigned int u) {
00195   return static_cast<unsigned int>(sizeof_to_bits(sizeof(u)))
00196     - 1U - clz(u);
00197 }
00198 
00203 inline unsigned int
00204 last_one(unsigned long ul) {
00205   return static_cast<unsigned int>(sizeof_to_bits(sizeof(ul)))
00206     - 1U - clz(ul);
00207 }
00208 
00213 inline unsigned int
00214 last_one(unsigned long long ull) {
00215   return static_cast<unsigned int>(sizeof_to_bits(sizeof(ull)))
00216     - 1U - clz(ull);
00217 }
00218 
00219 } // namespace Implementation
00220 
00222 inline void
00223 swap(Bit_Row& x, Bit_Row& y) {
00224   x.m_swap(y);
00225 }
00226 
00228 inline void
00229 iter_swap(std::vector<Bit_Row>::iterator x,
00230           std::vector<Bit_Row>::iterator y) {
00231   swap(*x, *y);
00232 }
00233 
00234 } // namespace Parma_Polyhedra_Library
00235 
00236 #endif // !defined(PPL_Bit_Row_inlines_hh)