BWAPI
|
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