00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef PPL_Interval_Info_defs_hh
00024 #define PPL_Interval_Info_defs_hh 1
00025
00026 #include "Boundary.defs.hh"
00027 #include "Interval_Restriction.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);
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 }
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_empty_result, Policy::check_empty_result);
00106 const_bool_nodef(check_inexact, Policy::check_inexact);
00107 const_bool_nodef(store_special, false);
00108 const_bool_nodef(store_open, false);
00109 const_bool_nodef(cache_normalized, false);
00110 const_bool_nodef(cache_empty, false);
00111 const_bool_nodef(cache_singleton, false);
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 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, const Boundary_NS::Property& p) const {
00147 switch (p.type) {
00148 case Boundary_NS::Property::OPEN_:
00149 return open;
00150 default:
00151 return Boundary_NS::Property::unsupported_value;
00152 }
00153 }
00154
00155 void ascii_dump(std::ostream& s) const;
00156 bool ascii_load(std::istream& s);
00157
00158 private:
00159 bool open;
00160 };
00161
00162
00163 template <typename T, typename Policy>
00164 class Interval_Info_Bitset {
00165 public:
00166 const_bool_nodef(may_be_empty, Policy::may_be_empty);
00167 const_bool_nodef(may_contain_infinity, Policy::may_contain_infinity);
00168 const_bool_nodef(check_empty_result, Policy::check_empty_result);
00169 const_bool_nodef(check_inexact, Policy::check_inexact);
00170 const_bool_nodef(store_special, Policy::store_special);
00171 const_bool_nodef(store_open, Policy::store_open);
00172 const_bool_nodef(cache_normalized, Policy::cache_normalized);
00173 const_bool_nodef(cache_empty, Policy::cache_empty);
00174 const_bool_nodef(cache_singleton, Policy::cache_singleton);
00175 const_int_nodef(lower_special_bit, Policy::next_bit);
00176 const_int_nodef(lower_open_bit, lower_special_bit + store_special);
00177 const_int_nodef(lower_normalized_bit, lower_open_bit + store_open);
00178 const_int_nodef(upper_special_bit, lower_normalized_bit + cache_normalized);
00179 const_int_nodef(upper_open_bit, upper_special_bit + store_special);
00180 const_int_nodef(upper_normalized_bit, upper_open_bit + store_open);
00181 const_int_nodef(cardinality_is_bit, upper_normalized_bit + cache_normalized);
00182 const_int_nodef(cardinality_0_bit, cardinality_is_bit + (cache_empty || cache_singleton));
00183 const_int_nodef(cardinality_1_bit, cardinality_0_bit + cache_empty);
00184 const_int_nodef(next_bit, cardinality_1_bit + cache_singleton);
00185 Interval_Info_Bitset() {
00186
00187
00188 clear();
00189 }
00190
00191 void clear() {
00192 reset_bits(bitset);
00193 }
00194 void clear_boundary_properties(Boundary_Type t) {
00195 set_boundary_property(t, SPECIAL, false);
00196 set_boundary_property(t, OPEN, false);
00197 }
00198 void set_boundary_property(Boundary_Type t, const Boundary_NS::Property& p, bool value = true) {
00199 switch (p.type) {
00200 case Boundary_NS::Property::SPECIAL_:
00201 if (store_special) {
00202 if (t == LOWER)
00203 set_bit(bitset, lower_special_bit, value);
00204 else
00205 set_bit(bitset, upper_special_bit, value);
00206 }
00207 break;
00208 case Boundary_NS::Property::OPEN_:
00209 if (store_open) {
00210 if (t == LOWER)
00211 set_bit(bitset, lower_open_bit, value);
00212 else
00213 set_bit(bitset, upper_open_bit, value);
00214 }
00215 break;
00216 case Boundary_NS::Property::NORMALIZED_:
00217 if (cache_normalized) {
00218 if (t == LOWER)
00219 set_bit(bitset, lower_normalized_bit, value);
00220 else
00221 set_bit(bitset, upper_normalized_bit, value);
00222 }
00223 break;
00224 default:
00225 break;
00226 }
00227 }
00228 bool get_boundary_property(Boundary_Type t, const Boundary_NS::Property& p) const {
00229 switch (p.type) {
00230 case Boundary_NS::Property::SPECIAL_:
00231 if (!store_special)
00232 return false;
00233 if (t == LOWER)
00234 return get_bit(bitset, lower_special_bit);
00235 else
00236 return get_bit(bitset, upper_special_bit);
00237 case Boundary_NS::Property::OPEN_:
00238 if (!store_open)
00239 return false;
00240 else if (t == LOWER)
00241 return get_bit(bitset, lower_open_bit);
00242 else
00243 return get_bit(bitset, upper_open_bit);
00244 case Boundary_NS::Property::NORMALIZED_:
00245 if (!cache_normalized)
00246 return false;
00247 else if (t == LOWER)
00248 return get_bit(bitset, lower_normalized_bit);
00249 else
00250 return get_bit(bitset, upper_normalized_bit);
00251 default:
00252 return false;
00253 }
00254 }
00255 void set_interval_property(const Interval_NS::Property& p, bool value = true) {
00256 switch (p.type) {
00257 case Interval_NS::Property::CARDINALITY_0_:
00258 if (cache_empty)
00259 set_bit(bitset, cardinality_0_bit, value);
00260 break;
00261 case Interval_NS::Property::CARDINALITY_1_:
00262 if (cache_singleton)
00263 set_bit(bitset, cardinality_1_bit, value);
00264 break;
00265 case Interval_NS::Property::CARDINALITY_IS_:
00266 if (cache_empty || cache_singleton)
00267 set_bit(bitset, cardinality_is_bit, value);
00268 break;
00269 default:
00270 break;
00271 }
00272 }
00273 bool get_interval_property(Interval_NS::Property p) const {
00274 switch (p.type) {
00275 case Interval_NS::Property::CARDINALITY_0_:
00276 return cache_empty && get_bit(bitset, cardinality_0_bit);
00277 case Interval_NS::Property::CARDINALITY_1_:
00278 return cache_singleton && get_bit(bitset, cardinality_1_bit);
00279 case Interval_NS::Property::CARDINALITY_IS_:
00280 return (cache_empty || cache_singleton) && get_bit(bitset, cardinality_is_bit);
00281 default:
00282 return false;
00283 }
00284 }
00285
00287 void swap(Interval_Info_Bitset& y);
00288
00289 void ascii_dump(std::ostream& s) const;
00290 bool ascii_load(std::istream& s);
00291
00292 protected:
00293 T bitset;
00294 };
00295
00296 }
00297
00298 #include "Interval_Info.inlines.hh"
00299
00300 #endif // !defined(PPL_Interval_Info_defs_hh)