|
BWAPI
|
00001 // Copyright (c) 1999-2007 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/Number_types/include/CGAL/Lazy_exact_nt.h $ 00016 // $Id: Lazy_exact_nt.h 49008 2009-04-29 13:57:45Z hemmer $ 00017 // 00018 // 00019 // Author(s) : Sylvain Pion 00020 00021 #ifndef CGAL_LAZY_EXACT_NT_H 00022 #define CGAL_LAZY_EXACT_NT_H 00023 00024 #define CGAL_int(T) typename First_if_different<int, T>::Type 00025 #define CGAL_double(T) typename First_if_different<double, T>::Type 00026 #define CGAL_To_interval(T) To_interval<T> 00027 00028 00029 #include <CGAL/number_type_basic.h> 00030 00031 #include <boost/iterator/transform_iterator.hpp> // for Root_of functor 00032 #include <boost/static_assert.hpp> 00033 #include <boost/operators.hpp> 00034 00035 #include <CGAL/Interval_nt.h> 00036 #include <CGAL/Handle.h> 00037 #include <CGAL/NT_converter.h> 00038 00039 #include <CGAL/Profile_counter.h> 00040 #include <CGAL/Lazy.h> 00041 00042 // #include <CGAL/Root_of_traits.h> // TODO 00043 00044 /* 00045 * This file contains the definition of the number type Lazy_exact_nt<ET>, 00046 * where ET is an exact number type (must provide the exact operations needed). 00047 * 00048 * Lazy_exact_nt<ET> provides a DAG-based lazy evaluation, like LEDA's real, 00049 * Core's Expr, LEA's lazy rationals... 00050 * 00051 * The values are first approximated using Interval_base. 00052 * The exactness is provided when needed by ET. 00053 * 00054 * Lazy_exact_nt<ET> is just a handle to the abstract base class 00055 * Lazy_exact_nt_rep which has pure virtual methods .approx() and .exact(). 00056 * From this class derives one class per operation, with one constructor. 00057 * 00058 * The DAG is managed by : 00059 * - Handle and Rep. 00060 * - virtual functions to denote the various operators (instead of an enum). 00061 * 00062 * Other packages with vaguely similar design : APU, MetaCGAL, LOOK. 00063 */ 00064 00065 /* 00066 * TODO : 00067 * - Generalize it for constructions at the kernel level. 00068 * - Add mixed operations with ET too ? 00069 * - Interval refinement functionnality ? 00070 * - Separate the handle and the representation(s) in 2 files (?) 00071 * maybe not a good idea, better if everything related to one operation is 00072 * close together. 00073 * - Add a CT template parameter ? 00074 * - Add a string constant to provide an expression string (a la MetaCGAL) ? 00075 * // virtual ostream operator<<() const = 0; // or string, like Core ? 00076 * - Have a template-expression (?) thing that evaluates a temporary element, 00077 * and allocates stuff in memory only when really needs to convert to the 00078 * NT. (cf gmp++, and maybe other things, Blitz++, Synaps...) 00079 */ 00080 00081 /* 00082 * Interface of the rep classes: 00083 * - .approx() returns Interval_nt<> (assumes rounding=nearest). 00084 * [ only called from the handle, and declared in the base ] 00085 * - .exact() returns ET, if not already done, computes recursively 00086 * 00087 * - .rafine_approx() ?? 00088 */ 00089 00090 CGAL_BEGIN_NAMESPACE 00091 00092 template <class NT> class Lazy_exact_nt; 00093 00094 00095 // Abstract base representation class for lazy numbers 00096 template <typename ET> 00097 struct Lazy_exact_nt_rep : public Lazy_exact_nt<ET>::Self_rep 00098 { 00099 typedef typename Lazy_exact_nt<ET>::Self_rep Base; 00100 00101 Lazy_exact_nt_rep (const Interval_nt<false> & i) 00102 : Base(i) {} 00103 00104 #ifdef CGAL_LAZY_KERNEL_DEBUG 00105 void 00106 print_dag(std::ostream& os, int level) const 00107 { 00108 this->print_at_et(os, level); 00109 } 00110 #endif 00111 }; 00112 00113 // int constant 00114 template <typename ET> 00115 struct Lazy_exact_Int_Cst : public Lazy_exact_nt_rep<ET> 00116 { 00117 Lazy_exact_Int_Cst (int i) 00118 : Lazy_exact_nt_rep<ET>(double(i)) {} 00119 00120 void update_exact() { this->et = new ET((int)this->approx().inf()); } 00121 }; 00122 00123 // double constant 00124 template <typename ET> 00125 struct Lazy_exact_Cst : public Lazy_exact_nt_rep<ET> 00126 { 00127 Lazy_exact_Cst (double d) 00128 : Lazy_exact_nt_rep<ET>(d) {} 00129 00130 void update_exact() { this->et = new ET(this->approx().inf()); } 00131 }; 00132 00133 // Exact constant 00134 template <typename ET> 00135 struct Lazy_exact_Ex_Cst : public Lazy_exact_nt_rep<ET> 00136 { 00137 Lazy_exact_Ex_Cst (const ET & e) 00138 : Lazy_exact_nt_rep<ET>(CGAL_NTS to_interval(e)) 00139 { 00140 this->et = new ET(e); 00141 } 00142 00143 void update_exact() { CGAL_error(); } 00144 }; 00145 00146 // Construction from a Lazy_exact_nt<ET1> (which keeps the lazyness). 00147 template <typename ET, typename ET1> 00148 class Lazy_lazy_exact_Cst : public Lazy_exact_nt_rep<ET> 00149 { 00150 Lazy_exact_nt<ET1> l; 00151 00152 public: 00153 00154 Lazy_lazy_exact_Cst (const Lazy_exact_nt<ET1> &x) 00155 : Lazy_exact_nt_rep<ET>(x.approx()), l(x) 00156 { 00157 this->set_depth(l.depth() + 1); 00158 } 00159 00160 void update_exact() 00161 { 00162 this->et = new ET(l.exact()); 00163 this->approx() = l.approx(); 00164 prune_dag(); 00165 } 00166 00167 void prune_dag() { l = Lazy_exact_nt<ET1>(); } 00168 }; 00169 00170 00171 // Unary operations: abs, sqrt, square. 00172 // Binary operations: +, -, *, /, min, max. 00173 00174 // Base unary operation 00175 template <typename ET> 00176 struct Lazy_exact_unary : public Lazy_exact_nt_rep<ET> 00177 { 00178 Lazy_exact_nt<ET> op1; 00179 00180 Lazy_exact_unary (const Interval_nt<false> &i, const Lazy_exact_nt<ET> &a) 00181 : Lazy_exact_nt_rep<ET>(i), op1(a) 00182 { 00183 this->set_depth(op1.depth() + 1); 00184 } 00185 00186 void prune_dag() { op1 = Lazy_exact_nt<ET>(); } 00187 00188 #ifdef CGAL_LAZY_KERNEL_DEBUG 00189 void 00190 print_dag(std::ostream& os, int level) const 00191 { 00192 this->print_at_et(os, level); 00193 if(this->is_lazy()){ 00194 msg(os, level, "Unary number operator:"); 00195 print_dag(op1, os, level+1); 00196 } 00197 } 00198 #endif 00199 }; 00200 00201 // Base binary operation 00202 template <typename ET, typename ET1 = ET, typename ET2 = ET> 00203 struct Lazy_exact_binary : public Lazy_exact_nt_rep<ET> 00204 { 00205 Lazy_exact_nt<ET1> op1; 00206 Lazy_exact_nt<ET2> op2; 00207 00208 Lazy_exact_binary (const Interval_nt<false> &i, 00209 const Lazy_exact_nt<ET1> &a, const Lazy_exact_nt<ET2> &b) 00210 : Lazy_exact_nt_rep<ET>(i), op1(a), op2(b) 00211 { 00212 this->set_depth((std::max)(op1.depth(), op2.depth()) + 1); 00213 } 00214 00215 void prune_dag() 00216 { 00217 op1 = Lazy_exact_nt<ET1>(); 00218 op2 = Lazy_exact_nt<ET2>(); 00219 } 00220 00221 #ifdef CGAL_LAZY_KERNEL_DEBUG 00222 void 00223 print_dag(std::ostream& os, int level) const 00224 { 00225 this->print_at_et(os, level); 00226 if(this->is_lazy()){ 00227 msg(os, level, "Binary number operator:"); 00228 print_dag(op1, os, level+1); 00229 print_dag(op2, os, level+1); 00230 } 00231 } 00232 #endif 00233 }; 00234 00235 // Here we could use a template class for all operations (STL provides 00236 // function objects plus, minus, multiplies, divides...). But it would require 00237 // a template template parameter, and GCC 2.95 seems to crash easily with them. 00238 00239 // Macro for unary operations 00240 #define CGAL_LAZY_UNARY_OP(OP, NAME) \ 00241 template <typename ET> \ 00242 struct NAME : public Lazy_exact_unary<ET> \ 00243 { \ 00244 typedef typename Lazy_exact_unary<ET>::AT::Protector P; \ 00245 NAME (const Lazy_exact_nt<ET> &a) \ 00246 : Lazy_exact_unary<ET>((P(), OP(a.approx())), a) {} \ 00247 \ 00248 void update_exact() \ 00249 { \ 00250 this->et = new ET(OP(this->op1.exact())); \ 00251 if (!this->approx().is_point()) \ 00252 this->approx() = CGAL_NTS to_interval(*(this->et)); \ 00253 this->prune_dag(); \ 00254 } \ 00255 }; 00256 00257 CGAL_LAZY_UNARY_OP(opposite, Lazy_exact_Opp) 00258 CGAL_LAZY_UNARY_OP(CGAL_NTS abs, Lazy_exact_Abs) 00259 CGAL_LAZY_UNARY_OP(CGAL_NTS square, Lazy_exact_Square) 00260 CGAL_LAZY_UNARY_OP(CGAL_NTS sqrt, Lazy_exact_Sqrt) 00261 00262 // A macro for +, -, * and / 00263 #define CGAL_LAZY_BINARY_OP(OP, NAME) \ 00264 template <typename ET, typename ET1 = ET, typename ET2 = ET> \ 00265 struct NAME : public Lazy_exact_binary<ET, ET1, ET2> \ 00266 { \ 00267 typedef typename Lazy_exact_binary<ET,ET1,ET2>::AT::Protector P; \ 00268 NAME (const Lazy_exact_nt<ET1> &a, const Lazy_exact_nt<ET2> &b) \ 00269 : Lazy_exact_binary<ET, ET1, ET2>((P(), a.approx() OP b.approx()), a, b) {} \ 00270 \ 00271 void update_exact() \ 00272 { \ 00273 this->et = new ET(this->op1.exact() OP this->op2.exact()); \ 00274 if (!this->approx().is_point()) \ 00275 this->approx() = CGAL_NTS to_interval(*(this->et)); \ 00276 this->prune_dag(); \ 00277 } \ 00278 }; 00279 00280 CGAL_LAZY_BINARY_OP(+, Lazy_exact_Add) 00281 CGAL_LAZY_BINARY_OP(-, Lazy_exact_Sub) 00282 CGAL_LAZY_BINARY_OP(*, Lazy_exact_Mul) 00283 CGAL_LAZY_BINARY_OP(/, Lazy_exact_Div) 00284 00285 // Minimum 00286 template <typename ET> 00287 struct Lazy_exact_Min : public Lazy_exact_binary<ET> 00288 { 00289 Lazy_exact_Min (const Lazy_exact_nt<ET> &a, const Lazy_exact_nt<ET> &b) 00290 : Lazy_exact_binary<ET>((min)(a.approx(), b.approx()), a, b) {} 00291 00292 void update_exact() 00293 { 00294 this->et = new ET((min)(this->op1.exact(), this->op2.exact())); 00295 if (!this->approx().is_point()) this->approx() = CGAL_NTS to_interval(*(this->et)); 00296 this->prune_dag(); 00297 } 00298 }; 00299 00300 // Maximum 00301 template <typename ET> 00302 struct Lazy_exact_Max : public Lazy_exact_binary<ET> 00303 { 00304 Lazy_exact_Max (const Lazy_exact_nt<ET> &a, const Lazy_exact_nt<ET> &b) 00305 : Lazy_exact_binary<ET>((max)(a.approx(), b.approx()), a, b) {} 00306 00307 void update_exact() 00308 { 00309 this->et = new ET((max)(this->op1.exact(), this->op2.exact())); 00310 if (!this->approx().is_point()) this->approx() = CGAL_NTS to_interval(*(this->et)); 00311 this->prune_dag(); 00312 } 00313 }; 00314 00315 00316 // The real number type, handle class 00317 template <typename ET_> 00318 class Lazy_exact_nt 00319 : public Lazy<Interval_nt<false>, ET_, Lazy_exact_nt<ET_>, To_interval<ET_> > 00320 , boost::ordered_euclidian_ring_operators2< Lazy_exact_nt<ET_>, int > 00321 , boost::ordered_euclidian_ring_operators2< Lazy_exact_nt<ET_>, double > 00322 { 00323 public: 00324 00325 typedef Lazy_exact_nt<ET_> Self; 00326 typedef Lazy<Interval_nt<false>, ET_, Self, To_interval<ET_> > Base; 00327 typedef typename Base::Self_rep Self_rep; 00328 00329 typedef typename Base::ET ET; // undocumented 00330 typedef typename Base::AT AT; // undocumented 00331 00332 typedef typename Base::Exact_type Exact_type; 00333 typedef typename Base::Approximate_type Approximate_type; 00334 00335 public : 00336 00337 Lazy_exact_nt () {} 00338 00339 Lazy_exact_nt (Self_rep *r) 00340 : Base(r) {} 00341 00342 Lazy_exact_nt (const CGAL_int(ET) & i) 00343 : Base(new Lazy_exact_Int_Cst<ET>(i)) {} 00344 00345 Lazy_exact_nt (unsigned i) 00346 : Base(new Lazy_exact_Cst<ET>(i)){} 00347 00348 Lazy_exact_nt (const CGAL_double(ET) & d) 00349 : Base(new Lazy_exact_Cst<ET>(d)){} 00350 00351 Lazy_exact_nt (const ET & e) 00352 : Base(new Lazy_exact_Ex_Cst<ET>(e)){} 00353 00354 template <class ET1> 00355 Lazy_exact_nt (const Lazy_exact_nt<ET1> &x) 00356 : Base(new Lazy_lazy_exact_Cst<ET, ET1>(x)){} 00357 00358 Self operator+ () const 00359 { return *this; } 00360 00361 Self operator- () const 00362 { return new Lazy_exact_Opp<ET>(*this); } 00363 00364 Self & operator+=(const Self& b) 00365 { return *this = new Lazy_exact_Add<ET>(*this, b); } 00366 00367 Self & operator-=(const Self& b) 00368 { return *this = new Lazy_exact_Sub<ET>(*this, b); } 00369 00370 Self & operator*=(const Self& b) 00371 { return *this = new Lazy_exact_Mul<ET>(*this, b); } 00372 00373 Self & operator/=(const Self& b) 00374 { 00375 CGAL_precondition(b != 0); 00376 return *this = new Lazy_exact_Div<ET>(*this, b); 00377 } 00378 00379 // Mixed operators. (could be optimized ?) 00380 Self & operator+=(CGAL_int(ET) b) 00381 { return *this = new Lazy_exact_Add<ET>(*this, b); } 00382 00383 Self & operator-=(CGAL_int(ET) b) 00384 { return *this = new Lazy_exact_Sub<ET>(*this, b); } 00385 00386 Self & operator*=(CGAL_int(ET) b) 00387 { return *this = new Lazy_exact_Mul<ET>(*this, b); } 00388 00389 Self & operator/=(CGAL_int(ET) b) 00390 { 00391 CGAL_precondition(b != 0); 00392 return *this = new Lazy_exact_Div<ET>(*this, b); 00393 } 00394 00395 Self & operator+=(CGAL_double(ET) b) 00396 { return *this = new Lazy_exact_Add<ET>(*this, b); } 00397 00398 Self & operator-=(CGAL_double(ET) b) 00399 { return *this = new Lazy_exact_Sub<ET>(*this, b); } 00400 00401 Self & operator*=(CGAL_double(ET) b) 00402 { return *this = new Lazy_exact_Mul<ET>(*this, b); } 00403 00404 Self & operator/=(CGAL_double(ET) b) 00405 { 00406 CGAL_precondition(b != 0); 00407 return *this = new Lazy_exact_Div<ET>(*this, b); 00408 } 00409 00410 // % kills filtering 00411 Self & operator%=(const Self& b) 00412 { 00413 CGAL_precondition(b != 0); 00414 ET res = this->exact(); 00415 res %= b.exact(); 00416 return *this = Lazy_exact_nt<ET>(res); 00417 } 00418 00419 Self & operator%=(int b) 00420 { 00421 CGAL_precondition(b != 0); 00422 ET res = this->exact(); 00423 res %= b; 00424 return *this = Lazy_exact_nt<ET>(res); 00425 } 00426 00427 Interval_nt<true> interval() const 00428 { 00429 const Interval_nt<false>& i = this->approx(); 00430 return Interval_nt<true>(i.inf(), i.sup()); 00431 } 00432 00433 Interval_nt_advanced approx_adv() const 00434 { return this->ptr()->approx(); } 00435 00436 static const double & get_relative_precision_of_to_double() 00437 { 00438 return relative_precision_of_to_double; 00439 } 00440 00441 static void set_relative_precision_of_to_double(const double & d) 00442 { 00443 CGAL_assertion((0 < d) & (d < 1)); 00444 relative_precision_of_to_double = d; 00445 } 00446 00447 bool identical(const Self& b) const 00448 { 00449 return ::CGAL::identical( 00450 static_cast<const Handle &>(*this), 00451 static_cast<const Handle &>(b)); 00452 } 00453 00454 template < typename T > 00455 bool identical(const T&) const 00456 { return false; } 00457 00458 private: 00459 static double relative_precision_of_to_double; 00460 }; 00461 00462 00463 template <typename ET> 00464 double Lazy_exact_nt<ET>::relative_precision_of_to_double = 0.00001; 00465 00466 00467 template <typename ET1, typename ET2> 00468 bool 00469 operator<(const Lazy_exact_nt<ET1>& a, const Lazy_exact_nt<ET2>& b) 00470 { 00471 CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); 00472 if (a.identical(b)) 00473 return false; 00474 Uncertain<bool> res = a.approx() < b.approx(); 00475 if (is_certain(res)) 00476 return get_certain(res); 00477 CGAL_BRANCH_PROFILER_BRANCH(tmp); 00478 return a.exact() < b.exact(); 00479 } 00480 00481 template <typename ET1, typename ET2> 00482 bool 00483 operator==(const Lazy_exact_nt<ET1>& a, const Lazy_exact_nt<ET2>& b) 00484 { 00485 CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); 00486 if (a.identical(b)) 00487 return true; 00488 Uncertain<bool> res = a.approx() == b.approx(); 00489 if (is_certain(res)) 00490 return get_certain(res); 00491 CGAL_BRANCH_PROFILER_BRANCH(tmp); 00492 return a.exact() == b.exact(); 00493 } 00494 00495 template <typename ET1, typename ET2> 00496 inline 00497 bool 00498 operator>(const Lazy_exact_nt<ET1>& a, const Lazy_exact_nt<ET2>& b) 00499 { return b < a; } 00500 00501 template <typename ET1, typename ET2> 00502 inline 00503 bool 00504 operator>=(const Lazy_exact_nt<ET1>& a, const Lazy_exact_nt<ET2>& b) 00505 { return ! (a < b); } 00506 00507 template <typename ET1, typename ET2> 00508 inline 00509 bool 00510 operator<=(const Lazy_exact_nt<ET1>& a, const Lazy_exact_nt<ET2>& b) 00511 { return b >= a; } 00512 00513 template <typename ET1, typename ET2> 00514 inline 00515 bool 00516 operator!=(const Lazy_exact_nt<ET1>& a, const Lazy_exact_nt<ET2>& b) 00517 { return ! (a == b); } 00518 00519 00520 template <typename ET> 00521 inline 00522 Lazy_exact_nt<ET> 00523 operator%(const Lazy_exact_nt<ET>& a, const Lazy_exact_nt<ET>& b) 00524 { 00525 CGAL_PROFILER(std::string("calls to : ") + std::string(CGAL_PRETTY_FUNCTION)); 00526 CGAL_precondition(b != 0); 00527 return Lazy_exact_nt<ET>(a) %= b; 00528 } 00529 00530 00531 00532 // Mixed operators with int. 00533 template <typename ET> 00534 bool 00535 operator<(const Lazy_exact_nt<ET>& a, int b) 00536 { 00537 CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); 00538 Uncertain<bool> res = a.approx() < b; 00539 if (is_certain(res)) 00540 return res; 00541 CGAL_BRANCH_PROFILER_BRANCH(tmp); 00542 return a.exact() < b; 00543 } 00544 00545 template <typename ET> 00546 bool 00547 operator>(const Lazy_exact_nt<ET>& a, int b) 00548 { 00549 CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); 00550 Uncertain<bool> res = b < a.approx(); 00551 if (is_certain(res)) 00552 return get_certain(res); 00553 CGAL_BRANCH_PROFILER_BRANCH(tmp); 00554 return b < a.exact(); 00555 } 00556 00557 template <typename ET> 00558 bool 00559 operator==(const Lazy_exact_nt<ET>& a, int b) 00560 { 00561 CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); 00562 Uncertain<bool> res = b == a.approx(); 00563 if (is_certain(res)) 00564 return get_certain(res); 00565 CGAL_BRANCH_PROFILER_BRANCH(tmp); 00566 return b == a.exact(); 00567 } 00568 00569 00570 // Mixed operators with double. 00571 template <typename ET> 00572 bool 00573 operator<(const Lazy_exact_nt<ET>& a, double b) 00574 { 00575 CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); 00576 Uncertain<bool> res = a.approx() < b; 00577 if (is_certain(res)) 00578 return res; 00579 CGAL_BRANCH_PROFILER_BRANCH(tmp); 00580 return a.exact() < b; 00581 } 00582 00583 template <typename ET> 00584 bool 00585 operator>(const Lazy_exact_nt<ET>& a, double b) 00586 { 00587 CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); 00588 Uncertain<bool> res = b < a.approx(); 00589 if (is_certain(res)) 00590 return res; 00591 CGAL_BRANCH_PROFILER_BRANCH(tmp); 00592 return b < a.exact(); 00593 } 00594 00595 template <typename ET> 00596 bool 00597 operator==(const Lazy_exact_nt<ET>& a, double b) 00598 { 00599 CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); 00600 Uncertain<bool> res = b == a.approx(); 00601 if (is_certain(res)) 00602 return res; 00603 CGAL_BRANCH_PROFILER_BRANCH(tmp); 00604 return b == a.exact(); 00605 } 00606 00607 00608 00609 template <typename ET1, typename ET2> 00610 Lazy_exact_nt< typename Coercion_traits<ET1, ET2>::Type > 00611 operator+(const Lazy_exact_nt<ET1>& a, const Lazy_exact_nt<ET2>& b) 00612 { 00613 CGAL_PROFILER(std::string("calls to : ") + std::string(CGAL_PRETTY_FUNCTION)); 00614 return new Lazy_exact_Add<typename Coercion_traits<ET1, ET2>::Type, 00615 ET1, ET2>(a, b); 00616 } 00617 00618 template <typename ET1, typename ET2> 00619 Lazy_exact_nt< typename Coercion_traits<ET1, ET2>::Type > 00620 operator-(const Lazy_exact_nt<ET1>& a, const Lazy_exact_nt<ET2>& b) 00621 { 00622 CGAL_PROFILER(std::string("calls to : ") + std::string(CGAL_PRETTY_FUNCTION)); 00623 return new Lazy_exact_Sub<typename Coercion_traits<ET1, ET2>::Type, 00624 ET1, ET2>(a, b); 00625 } 00626 00627 template <typename ET1, typename ET2> 00628 Lazy_exact_nt< typename Coercion_traits<ET1, ET2>::Type > 00629 operator*(const Lazy_exact_nt<ET1>& a, const Lazy_exact_nt<ET2>& b) 00630 { 00631 CGAL_PROFILER(std::string("calls to : ") + std::string(CGAL_PRETTY_FUNCTION)); 00632 return new Lazy_exact_Mul<typename Coercion_traits<ET1, ET2>::Type, 00633 ET1, ET2>(a, b); 00634 } 00635 00636 template <typename ET1, typename ET2> 00637 Lazy_exact_nt< typename Coercion_traits<ET1, ET2>::Type > 00638 operator/(const Lazy_exact_nt<ET1>& a, const Lazy_exact_nt<ET2>& b) 00639 { 00640 CGAL_PROFILER(std::string("calls to : ") + std::string(CGAL_PRETTY_FUNCTION)); 00641 CGAL_precondition(b != 0); 00642 return new Lazy_exact_Div<typename Coercion_traits<ET1, ET2>::Type, 00643 ET1, ET2>(a, b); 00644 } 00645 00646 // 00647 // Algebraic structure traits 00648 // 00649 00650 namespace INTERN_LAZY_EXACT_NT { 00651 00652 template< class NT, class Functor > 00653 struct Simplify_selector { 00654 struct Simplify : public std::unary_function<NT&, void> { 00655 void operator()( NT& ) const { 00656 // TODO: In the old implementation the Simplify-functor was the default 00657 // (which does nothing). But this cannot be the correct way!? 00658 } 00659 }; 00660 }; 00661 00662 template< class NT > 00663 struct Simplify_selector< NT, Null_functor > { 00664 typedef Null_functor Simplify; 00665 }; 00666 00667 template< class NT, class Functor > 00668 struct Unit_part_selector { 00669 struct Unit_part : public std::unary_function<NT, NT > { 00670 NT operator()( const NT& x ) const { 00671 return NT( CGAL_NTS unit_part( x.exact() ) ); 00672 } 00673 }; 00674 }; 00675 00676 template< class NT > 00677 struct Unit_part_selector< NT, Null_functor > { 00678 typedef Null_functor Unit_part; 00679 }; 00680 00681 template< class NT, class Functor > 00682 struct Is_zero_selector { 00683 struct Is_zero : public std::unary_function<NT, bool > { 00684 bool operator()( const NT& x ) const { 00685 return CGAL_NTS is_zero( x.exact() ); 00686 } 00687 }; 00688 }; 00689 00690 template< class NT > 00691 struct Is_zero_selector< NT, Null_functor > { 00692 typedef Null_functor Is_zero; 00693 }; 00694 00695 template< class NT, class Functor > 00696 struct Is_one_selector { 00697 struct Is_one : public std::unary_function<NT, bool > { 00698 bool operator()( const NT& x ) const { 00699 return CGAL_NTS is_one( x.exact() ); 00700 } 00701 }; 00702 }; 00703 00704 template< class NT > 00705 struct Is_one_selector< NT, Null_functor > { 00706 typedef Null_functor Is_one; 00707 }; 00708 00709 template< class NT, class Functor > 00710 struct Square_selector { 00711 struct Square : public std::unary_function<NT, NT > { 00712 NT operator()( const NT& x ) const { 00713 CGAL_PROFILER(std::string("calls to : ") + std::string(CGAL_PRETTY_FUNCTION)); 00714 return new Lazy_exact_Square<typename NT::ET>(x); 00715 } 00716 }; 00717 }; 00718 00719 template< class NT > 00720 struct Square_selector< NT, Null_functor > { 00721 typedef Null_functor Square; 00722 }; 00723 00724 template< class NT, class Functor > 00725 struct Integral_division_selector { 00726 struct Integral_division : public std::binary_function<NT, NT, NT > { 00727 NT operator()( const NT& x, const NT& y ) const { 00728 return NT( CGAL_NTS integral_division( x.exact(), y.exact() ) ); 00729 } 00730 00731 CGAL_IMPLICIT_INTEROPERABLE_BINARY_OPERATOR( NT ) 00732 }; 00733 }; 00734 00735 template< class NT > 00736 struct Integral_division_selector< NT, Null_functor > { 00737 typedef Null_functor Integral_division; 00738 }; 00739 00740 template< class NT, class Functor > 00741 struct Is_square_selector { 00742 struct Is_square : public std::binary_function<NT, NT&, bool > { 00743 bool operator()( const NT& x, NT& y ) const { 00744 typename NT::ET y_et; 00745 bool result = CGAL_NTS is_square( x.exact(), y_et ); 00746 y = NT(y_et); 00747 return result; 00748 } 00749 bool operator()( const NT& x) const { 00750 typename NT::ET y_et; 00751 return CGAL_NTS is_square( x.exact(), y_et ); 00752 } 00753 }; 00754 }; 00755 00756 template< class NT > 00757 struct Is_square_selector< NT, Null_functor > { 00758 typedef Null_functor Is_square; 00759 }; 00760 00761 00762 template <class NT, class AlgebraicStructureTag> 00763 struct Sqrt_selector{ 00764 struct Sqrt : public std::unary_function<NT, NT > { 00765 NT operator ()(const NT& x) const { 00766 CGAL_PROFILER(std::string("calls to : ") + std::string(CGAL_PRETTY_FUNCTION)); 00767 CGAL_precondition(x >= 0); 00768 return new Lazy_exact_Sqrt<typename NT::ET>(x); 00769 } 00770 }; 00771 }; 00772 template <class NT> 00773 struct Sqrt_selector<NT,Null_functor> { 00774 typedef Null_functor Sqrt; 00775 }; 00776 00777 template< class NT, class Functor > 00778 struct Kth_root_selector { 00779 struct Kth_root : public std::binary_function<int, NT, NT > { 00780 NT operator()( int k, const NT& x ) const { 00781 return NT( CGAL_NTS kth_root( k, x.exact() ) ); 00782 } 00783 }; 00784 }; 00785 00786 template< class NT > 00787 struct Kth_root_selector< NT, Null_functor > { 00788 typedef Null_functor Kth_root; 00789 }; 00790 00791 template< class NT, class Functor > 00792 struct Root_of_selector { 00793 private: 00794 struct Cast{ 00795 typedef typename NT::ET result_type; 00796 result_type operator()(const NT& lazy_exact) const { 00797 return lazy_exact.exact(); 00798 } 00799 }; 00800 00801 public: 00802 struct Root_of { 00803 // typedef typename Functor::Boundary Boundary; 00804 typedef NT result_type; 00805 template< class Input_iterator > 00806 NT operator()( int k, Input_iterator begin, Input_iterator end ) const { 00807 Cast cast; 00808 return NT( typename Algebraic_structure_traits<typename NT::ET>:: 00809 Root_of()( k, 00810 ::boost::make_transform_iterator( begin, cast ), 00811 ::boost::make_transform_iterator( end, cast ) ) ); 00812 } 00813 00814 }; 00815 }; 00816 00817 template< class NT > 00818 struct Root_of_selector< NT, Null_functor > { 00819 typedef Null_functor Root_of; 00820 }; 00821 00822 template< class NT, class Functor > 00823 struct Gcd_selector { 00824 struct Gcd : public std::binary_function<NT, NT, NT > { 00825 NT operator()( const NT& x, const NT& y ) const { 00826 CGAL_PROFILER(std::string("calls to : ") + std::string(CGAL_PRETTY_FUNCTION)); 00827 return NT( CGAL_NTS gcd( x.exact(), y.exact() ) ); 00828 } 00829 00830 CGAL_IMPLICIT_INTEROPERABLE_BINARY_OPERATOR( NT ) 00831 }; 00832 }; 00833 00834 template< class NT > 00835 struct Gcd_selector< NT, Null_functor > { 00836 typedef Null_functor Gcd; 00837 }; 00838 00839 template< class NT, class Functor > 00840 struct Div_selector { 00841 struct Div : public std::binary_function<NT, NT, NT > { 00842 NT operator()( const NT& x, const NT& y ) const { 00843 return NT( CGAL_NTS div( x.exact(), y.exact() ) ); 00844 } 00845 00846 CGAL_IMPLICIT_INTEROPERABLE_BINARY_OPERATOR( NT ) 00847 00848 }; 00849 }; 00850 00851 template< class NT > 00852 struct Div_selector< NT, Null_functor > { 00853 typedef Null_functor Div; 00854 }; 00855 00856 template< class NT, class Functor > 00857 struct Mod_selector { 00858 struct Mod : public std::binary_function<NT, NT, NT > { 00859 NT operator()( const NT& x, const NT& y ) const { 00860 return NT( CGAL_NTS mod( x.exact(), y.exact() ) ); 00861 } 00862 00863 CGAL_IMPLICIT_INTEROPERABLE_BINARY_OPERATOR( NT ) 00864 00865 }; 00866 }; 00867 00868 template< class NT > 00869 struct Mod_selector< NT, Null_functor > { 00870 typedef Null_functor Mod; 00871 }; 00872 00873 template< class NT, class Functor > 00874 struct Div_mod_selector { 00875 struct Div_mod { 00876 typedef void result_type; 00877 typedef NT first_argument_type; 00878 typedef NT second_argument_type; 00879 typedef NT& third_argument_type; 00880 typedef NT& fourth_argument_type; 00881 00882 void operator()( const NT& x, const NT& y, NT& q, NT& r ) const { 00883 typename NT::ET q_et; 00884 typename NT::ET r_et; 00885 CGAL_NTS div_mod( x.exact(), y.exact(), q_et, r_et ); 00886 q = NT( q_et ); 00887 r = NT( r_et ); 00888 } 00889 00890 template< class NT1, class NT2 > 00891 void operator()( const NT1& x, const NT2& y, 00892 NT& q, 00893 NT& r ) const { 00894 BOOST_STATIC_ASSERT((::boost::is_same< 00895 typename Coercion_traits< NT1, NT2 >::Type, NT 00896 >::value)); 00897 00898 typename Coercion_traits< NT1, NT2 >::Cast cast; 00899 operator()( cast(x), cast(y), q, r ); 00900 } 00901 }; 00902 }; 00903 00904 template< class NT > 00905 struct Div_mod_selector< NT, Null_functor >{ 00906 typedef Null_functor Div_mod; 00907 }; 00908 } // namespace INTERN_LAZY_EXACT_NT 00909 00910 template <class ET> 00911 class Algebraic_structure_traits< Lazy_exact_nt<ET> > 00912 :public Algebraic_structure_traits_base 00913 < Lazy_exact_nt<ET>, 00914 typename Algebraic_structure_traits<ET>::Algebraic_category > 00915 { 00916 private: 00917 typedef Algebraic_structure_traits<ET> AST_ET; 00918 typedef typename AST_ET::Algebraic_category ET_as_tag; 00919 public: 00920 typedef typename AST_ET::Is_exact Is_exact; 00921 typedef typename AST_ET::Is_numerical_sensitive Is_numerical_sensitive; 00922 00923 typedef typename INTERN_LAZY_EXACT_NT::Simplify_selector 00924 <Lazy_exact_nt<ET>, typename AST_ET::Simplify > ::Simplify Simplify; 00925 00926 typedef typename INTERN_LAZY_EXACT_NT::Unit_part_selector 00927 <Lazy_exact_nt<ET>, typename AST_ET::Unit_part > ::Unit_part Unit_part; 00928 00929 typedef typename INTERN_LAZY_EXACT_NT::Is_zero_selector 00930 <Lazy_exact_nt<ET>, typename AST_ET::Is_zero > ::Is_zero Is_zero; 00931 00932 typedef typename INTERN_LAZY_EXACT_NT::Is_one_selector 00933 <Lazy_exact_nt<ET>, typename AST_ET::Is_one > ::Is_one Is_one; 00934 00935 typedef typename INTERN_LAZY_EXACT_NT::Square_selector 00936 <Lazy_exact_nt<ET>, typename AST_ET::Square > ::Square Square; 00937 00938 typedef typename INTERN_LAZY_EXACT_NT::Integral_division_selector 00939 <Lazy_exact_nt<ET>, typename AST_ET::Integral_division> ::Integral_division Integral_division; 00940 00941 typedef typename INTERN_LAZY_EXACT_NT::Is_square_selector 00942 <Lazy_exact_nt<ET>, typename AST_ET::Is_square > ::Is_square Is_square; 00943 00944 typedef typename INTERN_LAZY_EXACT_NT::Sqrt_selector 00945 <Lazy_exact_nt<ET>, typename AST_ET::Sqrt> ::Sqrt Sqrt; 00946 00947 typedef typename INTERN_LAZY_EXACT_NT::Kth_root_selector 00948 <Lazy_exact_nt<ET>, typename AST_ET::Kth_root > ::Kth_root Kth_root; 00949 00950 typedef typename INTERN_LAZY_EXACT_NT::Root_of_selector 00951 <Lazy_exact_nt<ET>, typename AST_ET::Root_of > ::Root_of Root_of; 00952 00953 typedef typename INTERN_LAZY_EXACT_NT::Gcd_selector 00954 <Lazy_exact_nt<ET>, typename AST_ET::Gcd > ::Gcd Gcd; 00955 00956 typedef typename INTERN_LAZY_EXACT_NT::Div_selector 00957 <Lazy_exact_nt<ET>, typename AST_ET::Div > ::Div Div; 00958 00959 typedef typename INTERN_LAZY_EXACT_NT::Mod_selector 00960 <Lazy_exact_nt<ET>, typename AST_ET::Mod > ::Mod Mod; 00961 00962 typedef typename INTERN_LAZY_EXACT_NT::Div_mod_selector 00963 <Lazy_exact_nt<ET>, typename AST_ET::Div_mod > ::Div_mod Div_mod; 00964 }; 00965 00966 00967 00968 // 00969 // Real embeddalbe traits 00970 // 00971 00972 template < typename ET > class Real_embeddable_traits< Lazy_exact_nt<ET> > 00973 : public INTERN_RET::Real_embeddable_traits_base< Lazy_exact_nt<ET> , CGAL::Tag_true > { 00974 00975 // Every type ET of Lazy_exact_nt<ET> has to be real embeddable. 00976 BOOST_STATIC_ASSERT((::boost::is_same< typename Real_embeddable_traits< ET > 00977 ::Is_real_embeddable, Tag_true >::value)); 00978 00979 public: 00980 typedef Lazy_exact_nt<ET> Type; 00981 00982 class Abs 00983 : public std::unary_function< Type, Type > { 00984 public: 00985 Type operator()( const Type& a ) const { 00986 CGAL_PROFILER(std::string("calls to : ") + std::string(CGAL_PRETTY_FUNCTION)); 00987 return new Lazy_exact_Abs<ET>(a); 00988 } 00989 }; 00990 00991 class Sgn 00992 : public std::unary_function< Type, ::CGAL::Sign > { 00993 public: 00994 ::CGAL::Sign operator()( const Type& a ) const { 00995 CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); 00996 Uncertain< ::CGAL::Sign> res = CGAL_NTS sign(a.approx()); 00997 if (is_certain(res)) 00998 return get_certain(res); 00999 CGAL_BRANCH_PROFILER_BRANCH(tmp); 01000 return CGAL_NTS sign(a.exact()); 01001 } 01002 }; 01003 01004 class Compare 01005 : public std::binary_function< Type, Type, 01006 Comparison_result > { 01007 public: 01008 Comparison_result operator()( const Type& a, 01009 const Type& b ) const { 01010 CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); 01011 if (a.identical(b)) 01012 return EQUAL; 01013 Uncertain<Comparison_result> res = CGAL_NTS compare(a.approx(), b.approx()); 01014 if (is_certain(res)) 01015 return get_certain(res); 01016 CGAL_BRANCH_PROFILER_BRANCH(tmp); 01017 return CGAL_NTS compare(a.exact(), b.exact()); 01018 } 01019 01020 CGAL_IMPLICIT_INTEROPERABLE_BINARY_OPERATOR_WITH_RT( Type, 01021 Comparison_result ) 01022 01023 }; 01024 01025 class To_double 01026 : public std::unary_function< Type, double > { 01027 public: 01028 double operator()( const Type& a ) const { 01029 CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); 01030 01031 const Interval_nt<false>& app = a.approx(); 01032 double r; 01033 if (fit_in_double(app, r)) 01034 return r; 01035 01036 // If it's precise enough, then OK. 01037 if (has_smaller_relative_precision(app, 01038 Lazy_exact_nt<ET>::get_relative_precision_of_to_double())) 01039 return CGAL_NTS to_double(app); 01040 01041 CGAL_BRANCH_PROFILER_BRANCH(tmp); 01042 01043 // Otherwise we trigger exact computation first, 01044 // which will refine the approximation. 01045 a.exact(); 01046 return CGAL_NTS to_double(a.approx()); 01047 } 01048 }; 01049 01050 class To_interval 01051 : public std::unary_function< Type, std::pair< double, double > > { 01052 public: 01053 std::pair<double, double> operator()( const Type& a ) const { 01054 CGAL_PROFILER(std::string("calls to : ") + std::string(CGAL_PRETTY_FUNCTION)); 01055 return a.approx().pair(); 01056 } 01057 }; 01058 01059 class Is_finite 01060 : public std::unary_function< Type, bool > { 01061 public: 01062 bool operator()( const Type& x ) const { 01063 return CGAL_NTS is_finite(x.approx()) || CGAL_NTS is_finite(x.exact()); 01064 } 01065 }; 01066 01067 }; 01068 01069 template <class ET1, class ET2, class F> 01070 class Lazy_exact_nt_coercion_traits_base { 01071 public: 01072 typedef Tag_false Are_explicit_interoperable; 01073 typedef Tag_false Are_implicit_interoperable; 01074 //typedef Null_type Type 01075 typedef Null_functor Cast; 01076 }; 01077 01078 template <class ET1, class ET2> 01079 class Lazy_exact_nt_coercion_traits_base < Lazy_exact_nt<ET1>, Lazy_exact_nt<ET2>, Tag_true > 01080 { 01081 typedef Coercion_traits<ET1,ET2> CT; 01082 typedef Lazy_exact_nt<ET1> A; 01083 typedef Lazy_exact_nt<ET2> B; 01084 public: 01085 typedef Lazy_exact_nt<typename CT::Type> Type; 01086 typedef typename CT::Are_implicit_interoperable Are_explicit_interoperable; 01087 typedef typename CT::Are_implicit_interoperable Are_implicit_interoperable; 01088 01089 class Cast{ 01090 private: 01091 template <class T> 01092 Type cast(const T& x) const{ return Type(x); } 01093 Type cast(const Type& x) const{ return x; } 01094 public: 01095 typedef Type result_type; 01096 Type operator()(const A& x) const { return cast(x);} 01097 Type operator()(const B& x) const { return cast(x);} 01098 }; 01099 }; 01100 01101 01102 CGAL_DEFINE_COERCION_TRAITS_FOR_SELF_TEM(Lazy_exact_nt<ET>, class ET) 01103 01104 template<class ET1, class ET2 > 01105 struct Coercion_traits< Lazy_exact_nt<ET1>, Lazy_exact_nt<ET2> > 01106 :public Lazy_exact_nt_coercion_traits_base 01107 <Lazy_exact_nt<ET1>, Lazy_exact_nt<ET2>, 01108 typename Coercion_traits<ET1,ET2>::Are_implicit_interoperable>{}; 01109 01110 01111 #define CGAL_COERCION_TRAITS_LAZY_EXACT(NTX) \ 01112 template<class ET> \ 01113 struct Coercion_traits< NTX, Lazy_exact_nt<ET> >{ \ 01114 private: \ 01115 typedef Coercion_traits<NTX,ET> CT; \ 01116 typedef Lazy_exact_nt<ET> NT; \ 01117 public: \ 01118 typedef typename CT::Are_explicit_interoperable \ 01119 Are_explicit_interoperable; \ 01120 typedef typename CT::Are_implicit_interoperable \ 01121 Are_implicit_interoperable; \ 01122 private: \ 01123 static const bool interoperable \ 01124 =boost::is_same< Are_implicit_interoperable, Tag_false>::value; \ 01125 public: \ 01126 typedef typename boost::mpl::if_c <interoperable,Null_tag,NT> \ 01127 ::type Type; \ 01128 typedef typename boost::mpl::if_c <interoperable, Null_functor, \ 01129 INTERN_CT::Cast_from_to<NTX,NT> >::type Cast; \ 01130 }; \ 01131 \ 01132 template<class ET> \ 01133 struct Coercion_traits< Lazy_exact_nt<ET>, NTX > \ 01134 :public Coercion_traits<NTX, Lazy_exact_nt<ET> >{}; \ 01135 01136 01137 CGAL_COERCION_TRAITS_LAZY_EXACT(int); 01138 CGAL_COERCION_TRAITS_LAZY_EXACT(short); 01139 CGAL_COERCION_TRAITS_LAZY_EXACT(double); 01140 CGAL_COERCION_TRAITS_LAZY_EXACT(float); 01141 #undef CGAL_COERCION_TRAITS_LAZY_EXACT 01142 01143 namespace INTERN_LAZY_EXACT_NT { 01144 01145 template < typename NT, typename TAG > class Fraction_traits_base; 01146 01147 template < class ET > 01148 class Fraction_traits_base <Lazy_exact_nt<ET> , CGAL::Tag_false> 01149 : public Fraction_traits<ET> { 01150 public: 01151 typedef Lazy_exact_nt<ET> Type; 01152 }; 01153 01154 template < class ET > 01155 class Fraction_traits_base <Lazy_exact_nt<ET> , CGAL::Tag_true>{ 01156 typedef Fraction_traits<ET> ETT; 01157 typedef typename ETT::Numerator_type ET_numerator; 01158 typedef typename ETT::Denominator_type ET_denominator; 01159 public: 01160 typedef Lazy_exact_nt<ET> Type; 01161 typedef Tag_true Is_fraction; 01162 typedef Lazy_exact_nt<ET_numerator> Numerator_type; 01163 typedef Lazy_exact_nt<ET_denominator> Denominator_type; 01164 01165 struct Common_factor : std::binary_function<Denominator_type,Denominator_type,Denominator_type>{ 01166 Denominator_type operator()(const Denominator_type& a, const Denominator_type& b) const { 01167 typename ETT::Common_factor common_factor; 01168 return Denominator_type(common_factor(a.exact(),b.exact())); 01169 } 01170 }; 01171 struct Compose : std::binary_function<Type,Numerator_type,Denominator_type>{ 01172 Type operator()(const Numerator_type& n, const Denominator_type& d) const { 01173 typename ETT::Compose compose; 01174 return Type(compose(n.exact(),d.exact())); 01175 } 01176 }; 01177 struct Decompose { 01178 typedef void result_type; 01179 typedef Type first_argument_type; 01180 typedef Numerator_type second_argument_type; 01181 typedef Denominator_type third_argument_type; 01182 void operator()(const Type& f, Numerator_type& n, Denominator_type& d) const { 01183 typename ETT::Decompose decompose; 01184 ET_numerator nn; 01185 ET_denominator dd; 01186 decompose(f.exact(),nn,dd); 01187 n = Numerator_type(nn); 01188 d = Denominator_type(dd); 01189 } 01190 }; 01191 }; 01192 } // namespace INTERN_LAZY_EXACT_NT 01193 01194 01195 template < class ET > 01196 class Fraction_traits< Lazy_exact_nt< ET > > 01197 :public INTERN_LAZY_EXACT_NT::Fraction_traits_base<Lazy_exact_nt<ET>, 01198 typename Fraction_traits<ET>::Is_fraction> 01199 {}; 01200 01201 template < class ET > 01202 struct Min <Lazy_exact_nt<ET> > 01203 : public std::binary_function<Lazy_exact_nt<ET>,Lazy_exact_nt<ET>,Lazy_exact_nt<ET> > { 01204 01205 Lazy_exact_nt<ET> operator()( const Lazy_exact_nt<ET>& x, const Lazy_exact_nt<ET>& y) const 01206 { 01207 CGAL_PROFILER(std::string("calls to : ") + std::string(CGAL_PRETTY_FUNCTION)); 01208 return new Lazy_exact_Min<ET>(x, y); 01209 } 01210 }; 01211 01212 template < class ET > 01213 struct Max <Lazy_exact_nt<ET> > 01214 : public std::binary_function<Lazy_exact_nt<ET>,Lazy_exact_nt<ET>,Lazy_exact_nt<ET> > { 01215 01216 Lazy_exact_nt<ET> operator()( const Lazy_exact_nt<ET>& x, const Lazy_exact_nt<ET>& y) const 01217 { 01218 CGAL_PROFILER(std::string("calls to : ") + std::string(CGAL_PRETTY_FUNCTION)); 01219 return new Lazy_exact_Max<ET>(x, y); 01220 } 01221 }; 01222 01223 template<typename ET> inline 01224 Lazy_exact_nt<ET> min BOOST_PREVENT_MACRO_SUBSTITUTION( 01225 const Lazy_exact_nt<ET> & x, 01226 const Lazy_exact_nt<ET> & y){ 01227 return CGAL::Min<Lazy_exact_nt<ET> > ()(x,y); 01228 } 01229 template<typename ET> inline 01230 Lazy_exact_nt<ET> max BOOST_PREVENT_MACRO_SUBSTITUTION( 01231 const Lazy_exact_nt<ET> & x, 01232 const Lazy_exact_nt<ET> & y){ 01233 return CGAL::Max<Lazy_exact_nt<ET> > ()(x,y); 01234 } 01235 01236 template <typename ET> 01237 std::ostream & 01238 operator<< (std::ostream & os, const Lazy_exact_nt<ET> & a) 01239 { return os << CGAL_NTS to_double(a); } 01240 01241 template <typename ET> 01242 std::istream & 01243 operator>> (std::istream & is, Lazy_exact_nt<ET> & a) 01244 { 01245 ET e; 01246 is >> e; 01247 if (is) 01248 a = e; 01249 return is; 01250 } 01251 01252 template< class ET > 01253 class Is_valid< Lazy_exact_nt<ET> > 01254 : public std::unary_function< Lazy_exact_nt<ET>, bool > { 01255 public : 01256 bool operator()( const Lazy_exact_nt<ET>& x ) const { 01257 return is_valid(x.approx()); 01258 } 01259 }; 01260 01261 template < typename ET > 01262 struct NT_converter < Lazy_exact_nt<ET>, ET > 01263 { 01264 const ET& operator()(const Lazy_exact_nt<ET> &a) const 01265 { return a.exact(); } 01266 }; 01267 01268 // Returns true if the value is representable by a double and to_double() 01269 // would return it. False means "don't know" (the exact number type is not 01270 // queried). 01271 template < typename ET > 01272 inline bool 01273 fit_in_double(const Lazy_exact_nt<ET>& l, double& r) 01274 { return fit_in_double(l.approx(), r); } 01275 01276 01277 // We create a type of new node in Lazy_exact_nt's DAG 01278 // for the make_root_of_2() operation. 01279 01280 template <typename ET > 01281 struct Lazy_exact_ro2 01282 : public Lazy_exact_nt_rep< typename Root_of_traits<ET>::RootOf_2 > 01283 { 01284 typedef typename Root_of_traits<ET>::RootOf_2 RO2; 01285 typedef Lazy_exact_nt_rep<RO2> Base; 01286 typedef typename Base::AT::Protector P; 01287 01288 01289 mutable Lazy_exact_nt<ET> op1, op2, op3; 01290 bool smaller; 01291 bool old_rep;//if the rep=true then representation with polynomial coeff, else alpha, beta, gamma 01292 01293 01294 Lazy_exact_ro2 (const Lazy_exact_nt<ET> &a, 01295 const Lazy_exact_nt<ET> &b, 01296 const Lazy_exact_nt<ET> &c, bool s) 01297 : Base((P(), make_root_of_2(a.approx(), b.approx(), c.approx(), s))), 01298 op1(a), op2(b), op3(c), smaller(s), old_rep(true) {} 01299 01300 Lazy_exact_ro2 (const Lazy_exact_nt<ET> &a, 01301 const Lazy_exact_nt<ET> &b, 01302 const Lazy_exact_nt<ET> &c) 01303 : Base((P(), make_root_of_2(a.approx(), b.approx(), c.approx()))), 01304 op1(a), op2(b), op3(c), smaller(true), old_rep(false) {} 01305 01306 void update_exact() 01307 { 01308 if (old_rep) 01309 this->et = new RO2(make_root_of_2(op1.exact(), op2.exact(), 01310 op3.exact(), smaller)); 01311 else 01312 this->et = new RO2(make_root_of_2(op1.exact(), op2.exact(), 01313 op3.exact())); 01314 if (!this->approx().is_point()) 01315 this->at = to_interval(*(this->et)); 01316 this->prune_dag(); 01317 01318 } 01319 01320 void prune_dag() const 01321 { 01322 op1 = op2 = op3 = Lazy_exact_nt<ET>(); 01323 } 01324 }; 01325 01326 template <typename NT > 01327 struct Root_of_traits< Lazy_exact_nt < NT > > 01328 { 01329 private: 01330 typedef Root_of_traits<NT> T; 01331 public: 01332 typedef Root_of_traits< Lazy_exact_nt < NT > > Base; 01333 typedef Lazy_exact_nt< typename T::RootOf_1 > RootOf_1; 01334 typedef Lazy_exact_nt< typename T::RootOf_2 > RootOf_2; 01335 typedef RootOf_2 Root_of_2; 01336 typedef RootOf_1 Root_of_1; 01337 struct Make_root_of_2{ 01338 typedef RootOf_2 result_type; 01339 Root_of_2 01340 operator()(const Lazy_exact_nt<NT>& a, const Lazy_exact_nt<NT>& b, const Lazy_exact_nt<NT>& c) const{ 01341 return new Lazy_exact_ro2<NT>(a, b, c); 01342 }; 01343 RootOf_2 01344 operator()(const Lazy_exact_nt<NT>& a, const Lazy_exact_nt<NT>& b, const Lazy_exact_nt<NT>& c, bool smaller) const{ 01345 return new Lazy_exact_ro2<NT>(a, b, c, smaller); 01346 }; 01347 }; 01348 01349 }; 01350 01351 01352 //these two functions for test suite requirement 01353 template < typename RT > 01354 typename CGAL::Root_of_traits<CGAL::Lazy_exact_nt<RT> >::RootOf_2 make_sqrt(const CGAL::Lazy_exact_nt< RT> & r) 01355 { 01356 typedef Lazy_exact_nt< RT> TT; 01357 CGAL_assertion(r >= 0); 01358 if(CGAL_NTS is_zero(r)) return make_root_of_2((TT) 1,(TT) 0,(TT) 0); 01359 return make_root_of_2((TT) 1,(TT) 0,-r,false); 01360 } 01361 01362 template < typename RT > 01363 void 01364 print(std::ostream &os, const CGAL::Lazy_exact_nt< Root_of_2<RT> > &r) 01365 { 01366 print(os,r.exact()); 01367 } 01368 01369 namespace INTERN_LAZY_EXACT_NT { 01370 template< typename ET , typename Tag> 01371 class Modular_traits_base{ 01372 public: 01373 typedef Lazy_exact_nt<ET> NT; 01374 typedef ::CGAL::Tag_false Is_modularizable; 01375 typedef ::CGAL::Null_functor Residue_type; 01376 typedef ::CGAL::Null_functor Modular_image; 01377 typedef ::CGAL::Null_functor Modular_image_representative; 01378 }; 01379 01380 template< typename ET > 01381 class Modular_traits_base<ET, Tag_true>{ 01382 typedef Modular_traits<ET> MT_ET; 01383 public: 01384 typedef Lazy_exact_nt<ET> NT; 01385 typedef CGAL::Tag_true Is_modularizable; 01386 typedef typename MT_ET::Residue_type Residue_type; 01387 01388 struct Modular_image{ 01389 Residue_type operator()(const NT& a){ 01390 typename MT_ET::Modular_image modular_image; 01391 return modular_image(a.exact()); 01392 } 01393 }; 01394 struct Modular_image_representative{ 01395 NT operator()(const Residue_type& x){ 01396 typename MT_ET::Modular_image_representative modular_image_representative; 01397 return NT(modular_image_representative(x)); 01398 } 01399 }; 01400 }; 01401 } // namespace INTERN_LAZY_EXACT_NT 01402 01403 template < typename ET > 01404 class Modular_traits<Lazy_exact_nt<ET> > 01405 :public INTERN_LAZY_EXACT_NT::Modular_traits_base 01406 <ET,typename Modular_traits<ET>::Is_modularizable>{}; 01407 01408 01409 #undef CGAL_double 01410 #undef CGAL_int 01411 #undef CGAL_To_interval 01412 01413 CGAL_END_NAMESPACE 01414 01415 #endif // CGAL_LAZY_EXACT_NT_H
1.7.6.1