BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Uncertain.h
Go to the documentation of this file.
00001 // Copyright (c) 2005-2008  INRIA Sophia-Antipolis (France).
00002 // All rights reserved.
00003 //
00004 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public License as
00006 // published by the Free Software Foundation; version 2.1 of the License.
00007 // See the file LICENSE.LGPL distributed with CGAL.
00008 //
00009 // Licensees holding a valid commercial license may use this file in
00010 // accordance with the commercial license agreement provided with the software.
00011 //
00012 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00013 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00014 //
00015 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/STL_Extension/include/CGAL/Uncertain.h $
00016 // $Id: Uncertain.h 48839 2009-04-21 18:00:27Z spion $
00017 //
00018 // Author(s)     : Sylvain Pion
00019 
00020 #ifndef CGAL_UNCERTAIN_H
00021 #define CGAL_UNCERTAIN_H
00022 
00023 #include <CGAL/config.h>
00024 #include <CGAL/assertions.h>
00025 #include <CGAL/enum.h>
00026 #include <CGAL/Profile_counter.h>
00027 #include <stdexcept>
00028 #include <typeinfo>
00029 
00030 CGAL_BEGIN_NAMESPACE
00031 
00032 namespace CGALi {
00033 
00034   // Accessory traits class to provide min and max value of a type.
00035   // Specialized for bool and CGAL's enums.
00036   template < typename T >
00037   struct Minmax_traits;
00038 
00039   template <>
00040   struct Minmax_traits <bool>
00041   {
00042     static const bool min = false;
00043     static const bool max = true;
00044   };
00045 
00046   template <>
00047   struct Minmax_traits <Sign>
00048   {
00049     static const Sign min = NEGATIVE;
00050     static const Sign max = POSITIVE;
00051   };
00052 
00053   template <>
00054   struct Minmax_traits <Bounded_side>
00055   {
00056     static const Bounded_side min = ON_UNBOUNDED_SIDE;
00057     static const Bounded_side max = ON_BOUNDED_SIDE;
00058   };
00059 
00060   template <>
00061   struct Minmax_traits <Angle>
00062   {
00063     static const Angle min = OBTUSE;
00064     static const Angle max = ACUTE;
00065   };
00066 
00067 } // namespace CGALi
00068 
00069 
00070 // Exception type for the automatic conversion.
00071 class Uncertain_conversion_exception
00072   : std::range_error
00073 {
00074 public:
00075   Uncertain_conversion_exception(const std::string &s)
00076     : std::range_error(s) {}
00077 
00078   ~Uncertain_conversion_exception() throw() {}
00079 };
00080 
00081 
00082 // Encodes a range [inf,sup] of values of type T.
00083 // T can be enums or bool.
00084 
00085 template < typename T >
00086 class Uncertain
00087 {
00088   T _i, _s;
00089 
00090 public:
00091 
00092   typedef T  value_type;
00093 
00094   typedef CGAL::Uncertain_conversion_exception  Uncertain_conversion_exception;
00095 
00096   Uncertain()
00097     : _i(), _s() {}
00098 
00099   Uncertain(T t)
00100     : _i(t), _s(t) {}
00101 
00102   Uncertain(T i, T s)
00103     : _i(i), _s(s) { CGAL_precondition(i <= s); }
00104 
00105   Uncertain& operator=(T t)
00106   {
00107     _i = _s = t;
00108     return *this;
00109   }
00110 
00111   T inf() const { return _i; }
00112   T sup() const { return _s; }
00113 
00114   bool is_same(Uncertain u) const { return _i == u._i && _s == u._s; }
00115 
00116   bool is_certain() const { return _i == _s; }
00117 
00118   T make_certain() const
00119   {
00120     if (is_certain())
00121       return _i;
00122     CGAL_PROFILER(std::string("Uncertain_conversion_exception thrown for CGAL::Uncertain< ")
00123                   + typeid(T).name() + " >");
00124     throw Uncertain_conversion_exception(
00125                   "Undecidable conversion of CGAL::Uncertain<T>");
00126   }
00127 
00128 #ifndef CGAL_NO_UNCERTAIN_CONVERSION_OPERATOR
00129   // NB : the general conversion to bool might be too risky.
00130   //      boost::tribool uses a more restricted conversion (see below).
00131   operator T() const
00132   {
00133     return make_certain();
00134   }
00135 #else
00136 private:
00137   struct dummy {
00138     void nonnull() {};
00139   };
00140 
00141   typedef void (dummy::*safe_bool)();
00142 
00143 public:
00144   operator safe_bool() const
00145   {
00146     return make_certain() ? &dummy::nonnull : 0;
00147   }
00148 #endif
00149 
00150   static Uncertain indeterminate();
00151 };
00152 
00153 
00154 // Access functions
00155 // ----------------
00156 
00157 template < typename T >
00158 inline
00159 T inf(Uncertain<T> i)
00160 {
00161   return i.inf();
00162 }
00163 
00164 template < typename T >
00165 inline
00166 T sup(Uncertain<T> i)
00167 {
00168   return i.sup();
00169 }
00170 
00171 
00172 // Basic functions
00173 // ---------------
00174 
00175 #if 1
00176 // Commenting them out allows the test-suite to spot those predicates that do not
00177 // propagate Uncertain-ty correctly.  But they should probably be enabled
00178 // for now, for backward-compatibility.
00179 template < typename T >
00180 inline
00181 bool is_certain(T)
00182 {
00183   return true;
00184 }
00185 
00186 template < typename T >
00187 inline
00188 T get_certain(T t)
00189 {
00190   return t;
00191 }
00192 #endif
00193 
00194 template < typename T >
00195 inline
00196 bool is_certain(Uncertain<T> a)
00197 {
00198   return a.is_certain();
00199 }
00200 
00201 template < typename T >
00202 inline
00203 T get_certain(Uncertain<T> a)
00204 {
00205   CGAL_assertion(is_certain(a));
00206   return a.inf();
00207 }
00208 
00209 template < typename T >
00210 inline
00211 Uncertain<T>
00212 Uncertain<T>::indeterminate()
00213 {
00214   return Uncertain<T>(CGALi::Minmax_traits<T>::min, CGALi::Minmax_traits<T>::max);
00215 }
00216 
00217 namespace CGALi {
00218 
00219         // helper class
00220         template < typename T >
00221         struct Indeterminate_helper {
00222                 typedef T result_type;
00223                 result_type operator()() const
00224                 { return T(); }
00225         };
00226 
00227         template < typename T >
00228         struct Indeterminate_helper< Uncertain<T> > {
00229                 typedef Uncertain<T> result_type;
00230                 result_type operator()() const
00231                 { return Uncertain<T>::indeterminate(); }
00232         };
00233 
00234 } // namespace CGALi
00235 
00236 template < typename T >
00237 inline
00238 typename CGALi::Indeterminate_helper<T>::result_type
00239 indeterminate()
00240 {
00241   return CGALi::Indeterminate_helper<T>()();
00242 }
00243 
00244 template < typename T >
00245 inline
00246 bool is_indeterminate(T)
00247 {
00248   return false;
00249 }
00250 
00251 template < typename T >
00252 inline
00253 bool is_indeterminate(Uncertain<T> a)
00254 {
00255   return ! a.is_certain();
00256 }
00257 
00258 
00259 // certainly/possibly
00260 // ------------------
00261 
00262 inline bool certainly(bool b) { return b; }
00263 inline bool possibly(bool b) { return b; }
00264 
00265 inline bool certainly_not(bool b) { return !b; }
00266 inline bool possibly_not(bool b) { return !b; }
00267 
00268 inline
00269 bool certainly(Uncertain<bool> c)
00270 {
00271   return is_certain(c) && get_certain(c);
00272 }
00273 
00274 inline
00275 bool possibly(Uncertain<bool> c)
00276 {
00277   return !is_certain(c) || get_certain(c);
00278 }
00279 
00280 inline
00281 bool certainly_not(Uncertain<bool> c)
00282 {
00283   return is_certain(c) && !get_certain(c);
00284 }
00285 
00286 inline
00287 bool possibly_not(Uncertain<bool> c)
00288 {
00289   return !is_certain(c) || !get_certain(c);
00290 }
00291 
00292 
00293 // Boolean operations for Uncertain<bool>
00294 // --------------------------------------
00295 
00296 inline
00297 Uncertain<bool> operator!(Uncertain<bool> a)
00298 {
00299   return Uncertain<bool>(!a.sup(), !a.inf());
00300 }
00301 
00302 inline
00303 Uncertain<bool> operator|(Uncertain<bool> a, Uncertain<bool> b)
00304 {
00305   return Uncertain<bool>(a.inf() | b.inf(), a.sup() | b.sup());
00306 }
00307 
00308 inline
00309 Uncertain<bool> operator|(bool a, Uncertain<bool> b)
00310 {
00311   return Uncertain<bool>(a | b.inf(), a | b.sup());
00312 }
00313 
00314 inline
00315 Uncertain<bool> operator|(Uncertain<bool> a, bool b)
00316 {
00317   return Uncertain<bool>(a.inf() | b, a.sup() | b);
00318 }
00319 
00320 inline
00321 Uncertain<bool> operator&(Uncertain<bool> a, Uncertain<bool> b)
00322 {
00323   return Uncertain<bool>(a.inf() & b.inf(), a.sup() & b.sup());
00324 }
00325 
00326 inline
00327 Uncertain<bool> operator&(bool a, Uncertain<bool> b)
00328 {
00329   return Uncertain<bool>(a & b.inf(), a & b.sup());
00330 }
00331 
00332 inline
00333 Uncertain<bool> operator&(Uncertain<bool> a, bool b)
00334 {
00335   return Uncertain<bool>(a.inf() & b, a.sup() & b);
00336 }
00337 
00338 // operator&& and operator|| are not provided because, unless their bool counterpart,
00339 // they lack the "short-circuiting" property.
00340 // We provide macros CGAL_AND and CGAL_OR, which attempt to emulate their behavior.
00341 // Key things : do not evaluate expressions twice, and evaluate the right hand side
00342 // expression only when needed.
00343 // TODO : C++0x lambdas should be able to help here.
00344 #ifdef CGAL_CFG_NO_STATEMENT_EXPRESSIONS
00345 #  define CGAL_AND(X, Y)  ((X) && (Y))
00346 #  define CGAL_OR(X, Y)   ((X) || (Y))
00347 #else
00348 #  define CGAL_AND(X, Y) \
00349        ({ CGAL::Uncertain<bool> CGAL_TMP = (X); \
00350           CGAL::certainly_not(CGAL_TMP) ? CGAL::make_uncertain(false) \
00351                                         : CGAL_TMP & CGAL::make_uncertain((Y)); })
00352 #  define CGAL_OR(X, Y) \
00353        ({ CGAL::Uncertain<bool> CGAL_TMP = (X); \
00354           CGAL::certainly(CGAL_TMP) ? CGAL::make_uncertain(true) \
00355                                     : CGAL_TMP | CGAL::make_uncertain((Y)); })
00356 #endif
00357 
00358 #define CGAL_AND_3(X, Y, Z)  CGAL_AND(X, CGAL_AND(Y, Z))
00359 #define CGAL_OR_3(X, Y, Z)   CGAL_OR(X, CGAL_OR(Y, Z))
00360 
00361 
00362 // Equality operators
00363 
00364 template < typename T >
00365 inline
00366 Uncertain<bool> operator==(Uncertain<T> a, Uncertain<T> b)
00367 {
00368   if (a.sup() < b.inf() || b.sup() < a.inf())
00369     return false;
00370   if (is_certain(a) && is_certain(b)) // test above implies get_certain(a) == get_certain(b)
00371     return true;
00372   return Uncertain<bool>::indeterminate();
00373 }
00374 
00375 template < typename T >
00376 inline
00377 Uncertain<bool> operator==(Uncertain<T> a, T b)
00378 {
00379   if (a.sup() < b || b < a.inf())
00380     return false;
00381   if (is_certain(a))
00382     return true;
00383   return Uncertain<bool>::indeterminate();
00384 }
00385 
00386 template < typename T >
00387 inline
00388 Uncertain<bool> operator==(T a, Uncertain<T> b)
00389 {
00390   return b == a;
00391 }
00392 
00393 template < typename T >
00394 inline
00395 Uncertain<bool> operator!=(Uncertain<T> a, Uncertain<T> b)
00396 {
00397   return ! (a == b);
00398 }
00399 
00400 template < typename T >
00401 inline
00402 Uncertain<bool> operator!=(Uncertain<T> a, T b)
00403 {
00404   return ! (a == b);
00405 }
00406 
00407 template < typename T >
00408 inline
00409 Uncertain<bool> operator!=(T a, Uncertain<T> b)
00410 {
00411   return ! (a == b);
00412 }
00413 
00414 
00415 // Comparison operators (useful for enums only, I guess (?) ).
00416 
00417 template < typename T >
00418 inline
00419 Uncertain<bool> operator<(Uncertain<T> a, Uncertain<T> b)
00420 {
00421   if (a.sup() < b.inf())
00422     return true;
00423   if (a.inf() >= b.sup())
00424     return false;
00425   return Uncertain<bool>::indeterminate();
00426 }
00427 
00428 template < typename T >
00429 inline
00430 Uncertain<bool> operator<(Uncertain<T> a, T b)
00431 {
00432   if (a.sup() < b)
00433     return true;
00434   if (a.inf() >= b)
00435     return false;
00436   return Uncertain<bool>::indeterminate();
00437 }
00438 
00439 template < typename T >
00440 inline
00441 Uncertain<bool> operator<(T a, Uncertain<T> b)
00442 {
00443   if (a < b.inf())
00444     return true;
00445   if (a >= b.sup())
00446     return false;
00447   return Uncertain<bool>::indeterminate();
00448 }
00449 
00450 template < typename T >
00451 inline
00452 Uncertain<bool> operator>(Uncertain<T> a, Uncertain<T> b)
00453 {
00454   return b < a;
00455 }
00456 
00457 template < typename T >
00458 inline
00459 Uncertain<bool> operator>(Uncertain<T> a, T b)
00460 {
00461   return b < a;
00462 }
00463 
00464 template < typename T >
00465 inline
00466 Uncertain<bool> operator>(T a, Uncertain<T> b)
00467 {
00468   return b < a;
00469 }
00470 
00471 template < typename T >
00472 inline
00473 Uncertain<bool> operator<=(Uncertain<T> a, Uncertain<T> b)
00474 {
00475   return !(b < a);
00476 }
00477 
00478 template < typename T >
00479 inline
00480 Uncertain<bool> operator<=(Uncertain<T> a, T b)
00481 {
00482   return !(b < a);
00483 }
00484 
00485 template < typename T >
00486 inline
00487 Uncertain<bool> operator<=(T a, Uncertain<T> b)
00488 {
00489   return !(b < a);
00490 }
00491 
00492 template < typename T >
00493 inline
00494 Uncertain<bool> operator>=(Uncertain<T> a, Uncertain<T> b)
00495 {
00496   return !(a < b);
00497 }
00498 
00499 template < typename T >
00500 inline
00501 Uncertain<bool> operator>=(Uncertain<T> a, T b)
00502 {
00503   return !(a < b);
00504 }
00505 
00506 template < typename T >
00507 inline
00508 Uncertain<bool> operator>=(T a, Uncertain<T> b)
00509 {
00510   return !(a < b);
00511 }
00512 
00513 
00514 // Maker function (a la std::make_pair).
00515 
00516 template < typename T >
00517 inline
00518 Uncertain<T> make_uncertain(T t)
00519 {
00520   return Uncertain<T>(t);
00521 }
00522 
00523 template < typename T >
00524 inline
00525 Uncertain<T> make_uncertain(Uncertain<T> t)
00526 {
00527   return t;
00528 }
00529 
00530 
00531 // make_certain() : Forcing a cast to certain (possibly throwing).
00532 // This is meant to be used only in cases where we cannot easily propagate the
00533 // uncertainty, such as when used in a switch statement (code may later be
00534 // revisited to do things in a better way).
00535 
00536 template < typename T >
00537 inline
00538 T make_certain(T t)
00539 {
00540   return t;
00541 }
00542 
00543 template < typename T >
00544 inline
00545 T make_certain(Uncertain<T> t)
00546 {
00547   return t.make_certain();
00548 }
00549 
00550 
00551 // opposite
00552 template < typename T > // should be constrained only for enums.
00553 inline
00554 Uncertain<T> operator-(Uncertain<T> u)
00555 {
00556   return Uncertain<T>(-u.sup(), -u.inf());
00557 }
00558 
00559 // "sign" multiplication.
00560 // Should be constrained only for "sign" enums, useless for bool.
00561 template < typename T >
00562 Uncertain<T> operator*(Uncertain<T> a, Uncertain<T> b)
00563 {
00564   if (a.inf() >= 0)                                   // e>=0
00565   {
00566     // b>=0     [a.inf()*b.inf(); a.sup()*b.sup()]
00567     // b<=0     [a.sup()*b.inf(); a.inf()*b.sup()]
00568     // b~=0     [a.sup()*b.inf(); a.sup()*b.sup()]
00569     T aa = a.inf(), bb = a.sup();
00570     if (b.inf() < 0)
00571     {
00572         aa = bb;
00573         if (b.sup() < 0)
00574             bb = a.inf();
00575     }
00576     return Uncertain<T>(aa * b.inf(), bb * b.sup());
00577   }
00578   else if (a.sup()<=0)                                // e<=0
00579   {
00580     // b>=0     [a.inf()*b.sup(); a.sup()*b.inf()]
00581     // b<=0     [a.sup()*b.sup(); a.inf()*b.inf()]
00582     // b~=0     [a.inf()*b.sup(); a.inf()*b.inf()]
00583     T aa = a.sup(), bb = a.inf();
00584     if (b.inf() < 0)
00585     {
00586         aa=bb;
00587         if (b.sup() < 0)
00588             bb=a.sup();
00589     }
00590     return Uncertain<T>(bb * b.sup(), aa * b.inf());
00591   }
00592   else                                          // 0 \in [inf();sup()]
00593   {
00594     if (b.inf()>=0)                           // d>=0
00595       return Uncertain<T>(a.inf() * b.sup(), a.sup() * b.sup());
00596     if (b.sup()<=0)                           // d<=0
00597       return Uncertain<T>(a.sup() * b.inf(), a.inf() * b.inf());
00598                                                 // 0 \in d
00599     T tmp1 = a.inf() * b.sup();
00600     T tmp2 = a.sup() * b.inf();
00601     T tmp3 = a.inf() * b.inf();
00602     T tmp4 = a.sup() * b.sup();
00603     return Uncertain<T>((std::min)(tmp1, tmp2), (std::max)(tmp3, tmp4));
00604   }
00605 }
00606 
00607 template < typename T >
00608 inline
00609 Uncertain<T> operator*(T a, Uncertain<T> b)
00610 {
00611         return Uncertain<T>(a) * b;
00612 }
00613 
00614 template < typename T >
00615 inline
00616 Uncertain<T> operator*(Uncertain<T> a, T b)
00617 {
00618         return a * Uncertain<T>(b);
00619 }
00620 
00621 // enum_cast overload
00622 
00623 #ifdef CGAL_CFG_MATCHING_BUG_5
00624 
00625 template < typename T, typename U >
00626 inline
00627 Uncertain<T> enum_cast_bug(Uncertain<U> u, const T*)
00628 {
00629   return Uncertain<T>(static_cast<const T>(u.inf()),
00630                       static_cast<const T>(u.sup()));
00631 }
00632 
00633 #else
00634 
00635 template < typename T, typename U >
00636 inline
00637 Uncertain<T> enum_cast(Uncertain<U> u)
00638 {
00639   return Uncertain<T>(static_cast<T>(u.inf()), static_cast<T>(u.sup()));
00640 }
00641 
00642 #endif
00643 
00644 CGAL_END_NAMESPACE
00645 
00646 #endif // CGAL_UNCERTAIN_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines