BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Lazy_exact_nt.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines