|
PPL
0.12.1
|
00001 /* Interval_Info class declaration and implementation. 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_Interval_Info_defs_hh 00025 #define PPL_Interval_Info_defs_hh 1 00026 00027 #include "Boundary.defs.hh" 00028 00029 #include <iostream> 00030 00031 namespace Parma_Polyhedra_Library { 00032 00033 namespace Interval_NS { 00034 00035 struct Property { 00036 enum Type { 00037 CARDINALITY_0_, 00038 CARDINALITY_1_, 00039 CARDINALITY_IS_ 00040 }; 00041 typedef bool Value; 00042 static const Value default_value = true; 00043 static const Value unsupported_value = false; 00044 Property(Type t) 00045 : type(t) { 00046 } 00047 Type type; 00048 }; 00049 00050 const Property CARDINALITY_0(Property::CARDINALITY_0_); 00051 const Property CARDINALITY_1(Property::CARDINALITY_1_); 00052 const Property CARDINALITY_IS(Property::CARDINALITY_IS_); 00053 00054 template <typename T> 00055 inline void 00056 reset_bits(T& bits) { 00057 bits = 0; 00058 } 00059 00060 template <typename T> 00061 inline void 00062 reset_bit(T& bits, unsigned int bit) { 00063 bits &= ~(static_cast<T>(1) << bit); 00064 } 00065 00066 template <typename T> 00067 inline void 00068 set_bit(T& bits, unsigned int bit, bool value) { 00069 if (value) 00070 bits |= static_cast<T>(1) << bit; 00071 else 00072 reset_bit(bits, bit); 00073 } 00074 00075 template <typename T> 00076 inline bool 00077 get_bit(const T& bits, unsigned int bit) { 00078 return (bits & (static_cast<T>(1) << bit)) != 0; 00079 } 00080 00081 template <typename T> 00082 inline void 00083 set_bits(T& bits, unsigned int start, unsigned int len, T value) { 00084 bits &= ~(((static_cast<T>(1) << len) - 1) << start); 00085 bits |= value << start; 00086 } 00087 00088 template <typename T> 00089 inline T 00090 get_bits(T& bits, unsigned int start, unsigned int len) { 00091 return (bits >> start) & ((static_cast<T>(1) << len) - 1); 00092 } 00093 00094 } // namespace Interval_NS 00095 00096 using namespace Interval_NS; 00097 using namespace Boundary_NS; 00098 00099 00100 template <typename Policy> 00101 class Interval_Info_Null { 00102 public: 00103 const_bool_nodef(may_be_empty, Policy::may_be_empty); 00104 const_bool_nodef(may_contain_infinity, Policy::may_contain_infinity); 00105 const_bool_nodef(check_inexact, Policy::check_inexact); 00106 const_bool_nodef(store_special, false); 00107 const_bool_nodef(store_open, false); 00108 const_bool_nodef(cache_empty, false); 00109 const_bool_nodef(cache_singleton, false); 00110 Interval_Info_Null() { 00111 } 00112 void clear() { 00113 } 00114 void clear_boundary_properties(Boundary_Type) { 00115 } 00116 00117 template <typename Property> 00118 void set_boundary_property(Boundary_Type, const Property&, typename Property::Value = Property::default_value) { 00119 } 00120 template <typename Property> 00121 typename Property::Value get_boundary_property(Boundary_Type, const Property&) const { 00122 return Property::unsupported_value; 00123 } 00124 template <typename Property> 00125 void set_interval_property(const Property&, typename Property::Value = Property::default_value) { 00126 } 00127 template <typename Property> 00128 typename Property::Value get_interval_property(const Property&) const { 00129 return Property::unsupported_value; 00130 } 00131 00133 void m_swap(Interval_Info_Null& y); 00134 00135 void ascii_dump(std::ostream& s) const; 00136 bool ascii_load(std::istream& s); 00137 }; 00138 00139 template <typename Policy> 00140 class Interval_Info_Null_Open : public Interval_Info_Null<Policy> { 00141 public: 00142 const_bool_nodef(store_open, true); 00143 Interval_Info_Null_Open(bool o) 00144 : open(o) { 00145 } 00146 bool get_boundary_property(Boundary_Type, 00147 const Boundary_NS::Property& p) const { 00148 if (p.type == Boundary_NS::Property::OPEN_) 00149 return open; 00150 else 00151 return Boundary_NS::Property::unsupported_value; 00152 } 00153 00154 void ascii_dump(std::ostream& s) const; 00155 bool ascii_load(std::istream& s); 00156 00157 private: 00158 bool open; 00159 }; 00160 00161 00162 template <typename T, typename Policy> 00163 class Interval_Info_Bitset { 00164 public: 00165 const_bool_nodef(may_be_empty, Policy::may_be_empty); 00166 const_bool_nodef(may_contain_infinity, Policy::may_contain_infinity); 00167 const_bool_nodef(check_inexact, Policy::check_inexact); 00168 const_bool_nodef(store_special, Policy::store_special); 00169 const_bool_nodef(store_open, Policy::store_open); 00170 const_bool_nodef(cache_empty, Policy::cache_empty); 00171 const_bool_nodef(cache_singleton, Policy::cache_singleton); 00172 const_int_nodef(lower_special_bit, Policy::next_bit); 00173 const_int_nodef(lower_open_bit, lower_special_bit + (store_special ? 1 : 0)); 00174 const_int_nodef(upper_special_bit, lower_open_bit + (store_open ? 1 : 0)); 00175 const_int_nodef(upper_open_bit, upper_special_bit + (store_special ? 1 : 0)); 00176 const_int_nodef(cardinality_is_bit, upper_open_bit + (store_open ? 1 : 0)); 00177 const_int_nodef(cardinality_0_bit, cardinality_is_bit 00178 + ((cache_empty || cache_singleton) ? 1 : 0)); 00179 const_int_nodef(cardinality_1_bit, cardinality_0_bit + (cache_empty ? 1 : 0)); 00180 const_int_nodef(next_bit, cardinality_1_bit + (cache_singleton ? 1 : 0)); 00181 00182 Interval_Info_Bitset() { 00183 // FIXME: would we have speed benefits with uninitialized info? 00184 // (Dirty_Temp) 00185 clear(); 00186 } 00187 00188 void clear() { 00189 reset_bits(bitset); 00190 } 00191 void clear_boundary_properties(Boundary_Type t) { 00192 set_boundary_property(t, SPECIAL, false); 00193 set_boundary_property(t, OPEN, false); 00194 } 00195 void set_boundary_property(Boundary_Type t, 00196 const Boundary_NS::Property& p, 00197 bool value = true) { 00198 switch (p.type) { 00199 case Boundary_NS::Property::SPECIAL_: 00200 if (store_special) { 00201 if (t == LOWER) 00202 set_bit(bitset, lower_special_bit, value); 00203 else 00204 set_bit(bitset, upper_special_bit, value); 00205 } 00206 break; 00207 case Boundary_NS::Property::OPEN_: 00208 if (store_open) { 00209 if (t == LOWER) 00210 set_bit(bitset, lower_open_bit, value); 00211 else 00212 set_bit(bitset, upper_open_bit, value); 00213 } 00214 break; 00215 default: 00216 break; 00217 } 00218 } 00219 bool get_boundary_property(Boundary_Type t, const Boundary_NS::Property& p) const { 00220 switch (p.type) { 00221 case Boundary_NS::Property::SPECIAL_: 00222 if (!store_special) 00223 return false; 00224 if (t == LOWER) 00225 return get_bit(bitset, lower_special_bit); 00226 else 00227 return get_bit(bitset, upper_special_bit); 00228 case Boundary_NS::Property::OPEN_: 00229 if (!store_open) 00230 return false; 00231 else if (t == LOWER) 00232 return get_bit(bitset, lower_open_bit); 00233 else 00234 return get_bit(bitset, upper_open_bit); 00235 default: 00236 return false; 00237 } 00238 } 00239 void set_interval_property(const Interval_NS::Property& p, bool value = true) { 00240 switch (p.type) { 00241 case Interval_NS::Property::CARDINALITY_0_: 00242 if (cache_empty) 00243 set_bit(bitset, cardinality_0_bit, value); 00244 break; 00245 case Interval_NS::Property::CARDINALITY_1_: 00246 if (cache_singleton) 00247 set_bit(bitset, cardinality_1_bit, value); 00248 break; 00249 case Interval_NS::Property::CARDINALITY_IS_: 00250 if (cache_empty || cache_singleton) 00251 set_bit(bitset, cardinality_is_bit, value); 00252 break; 00253 default: 00254 break; 00255 } 00256 } 00257 bool get_interval_property(Interval_NS::Property p) const { 00258 switch (p.type) { 00259 case Interval_NS::Property::CARDINALITY_0_: 00260 return cache_empty && get_bit(bitset, cardinality_0_bit); 00261 case Interval_NS::Property::CARDINALITY_1_: 00262 return cache_singleton && get_bit(bitset, cardinality_1_bit); 00263 case Interval_NS::Property::CARDINALITY_IS_: 00264 return (cache_empty || cache_singleton) 00265 && get_bit(bitset, cardinality_is_bit); 00266 default: 00267 return false; 00268 } 00269 } 00270 00272 void m_swap(Interval_Info_Bitset& y); 00273 00274 void ascii_dump(std::ostream& s) const; 00275 bool ascii_load(std::istream& s); 00276 00277 protected: 00278 T bitset; 00279 }; 00280 00281 } 00282 00283 #include "Interval_Info.inlines.hh" 00284 00285 #endif // !defined(PPL_Interval_Info_defs_hh)