PPL  0.12.1
Interval_Info.defs.hh
Go to the documentation of this file.
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)