|
PPL
0.12.1
|
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)