BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Lazy.h
Go to the documentation of this file.
00001 // Copyright (c) 2005,2006  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/Filtered_kernel/include/CGAL/Lazy.h $
00016 // $Id: Lazy.h 48759 2009-04-10 21:55:24Z spion $
00017 //
00018 //
00019 // Author(s)     : Andreas Fabri, Sylvain Pion
00020 
00021 #ifndef CGAL_LAZY_H
00022 #define CGAL_LAZY_H
00023 
00024 #include <CGAL/basic.h>
00025 #include <CGAL/Handle.h>
00026 #include <CGAL/Object.h>
00027 #include <CGAL/Kernel/Type_mapper.h>
00028 #include <CGAL/Profile_counter.h>
00029 #include <CGAL/Kernel/Return_base_tag.h>
00030 #include <CGAL/min_max_n.h>
00031 #include <CGAL/Origin.h>
00032 #include <vector>
00033 #include <CGAL/Default.h>
00034 
00035 #ifdef CGAL_HAS_THREADS
00036 #  include <boost/thread/tss.hpp>
00037 #endif
00038 
00039 CGAL_BEGIN_NAMESPACE
00040 
00041 template <typename AT, typename ET, typename EFT, typename E2A> class Lazy;
00042 
00043 template <typename ET_>
00044 class Lazy_exact_nt;
00045 
00046 template <typename AT, typename ET, typename EFT, typename E2A>
00047 inline
00048 const AT&
00049 approx(const Lazy<AT,ET, EFT, E2A>& l)
00050 {
00051   return l.approx();
00052 }
00053 
00054 // Where is this one (non-const) needed ?  Is it ?
00055 template <typename AT, typename ET, typename EFT, typename E2A>
00056 inline
00057 AT&
00058 approx(Lazy<AT,ET, EFT, E2A>& l)
00059 {
00060   return l.approx();
00061 }
00062 
00063 
00064 template <typename AT, typename ET, typename EFT, typename E2A>
00065 inline
00066 const ET&
00067 exact(const Lazy<AT,ET,EFT,E2A>& l)
00068 {
00069   return l.exact();
00070 }
00071 
00072 
00073 template <typename AT, typename ET, typename EFT, typename E2A>
00074 inline
00075 unsigned
00076 depth(const Lazy<AT,ET,EFT,E2A>& l)
00077 {
00078   return l.depth();
00079 }
00080 
00081 
00082 #define CGAL_LAZY_FORWARD(T) \
00083   inline const T & approx(const T& d) { return d; } \
00084   inline const T & exact (const T& d) { return d; } \
00085   inline unsigned  depth (const T&  ) { return 0; }
00086 
00087 
00088 CGAL_LAZY_FORWARD(double)
00089 CGAL_LAZY_FORWARD(float)
00090 CGAL_LAZY_FORWARD(int)
00091 CGAL_LAZY_FORWARD(unsigned)
00092 CGAL_LAZY_FORWARD(Return_base_tag)
00093 CGAL_LAZY_FORWARD(Null_vector)
00094 CGAL_LAZY_FORWARD(Origin)
00095 CGAL_LAZY_FORWARD(Orientation)
00096 
00097 
00098 
00099 
00100 #ifdef CGAL_LAZY_KERNEL_DEBUG
00101 template <class T>
00102 void
00103 print_at(std::ostream& os, const T& at)
00104 {
00105   os << at;
00106 }
00107 
00108 template <class T>
00109 void
00110 print_at(std::ostream& os, const std::vector<T>& at)
00111 {
00112   os << "std::vector";
00113 }
00114 
00115 template <>
00116 void
00117 print_at(std::ostream& os, const Object& o)
00118 {
00119   os << "Object";
00120 }
00121 
00122 template <class T1, class T2>
00123 void
00124 print_at(std::ostream& os, const std::pair<T1,T2> & at)
00125 {
00126   os << "[ " << at.first << " | " << at.second << " ]" << std::endl ;
00127 }
00128 
00129 
00130 template <typename AT, typename ET, typename EFT, typename E2A>
00131 inline
00132 void
00133 print_dag(const Lazy<AT,ET,EFT,E2A>& l, std::ostream& os, int level = 0)
00134 {
00135   l.print_dag(os, level);
00136 }
00137 
00138 inline
00139 void
00140 print_dag(double d, std::ostream& os, int level)
00141 {
00142   for(int i = 0; i < level; i++)
00143     os << "    ";
00144   os << d << std::endl;
00145 }
00146 
00147 inline
00148 void
00149 msg(std::ostream& os, int level, char* s)
00150 {
00151     for(int i = 0; i < level; i++)
00152       os << "    ";
00153     os << s << std::endl;
00154 }
00155 
00156 inline
00157 void
00158 print_dag(const Null_vector& nv, std::ostream& os, int level)
00159 {
00160   for(int i = 0; i < level; i++)
00161     os << "    ";
00162   os << "Null_vector" << std::endl;
00163 }
00164 
00165 inline
00166 void
00167 print_dag(const Origin& nv, std::ostream& os, int level)
00168 {
00169   for(int i = 0; i < level; i++)
00170     os << "    ";
00171   os << "Origin" << std::endl;
00172 }
00173 #endif
00174 
00175 
00176 struct Depth_base {
00177 #ifdef CGAL_PROFILE
00178   unsigned depth_;
00179   Depth_base() { set_depth(0); }
00180   unsigned depth() const { return depth_; }
00181   void set_depth(unsigned i)
00182   {
00183     depth_ = i;
00184     CGAL_HISTOGRAM_PROFILER(std::string("[Lazy_kernel DAG depths]"), i);
00185                             //(unsigned) ::log2(double(i)));
00186   }
00187 #else
00188   unsigned depth() const { return 0; }
00189   void set_depth(unsigned) {}
00190 #endif
00191 };
00192 
00193 
00194 // Abstract base class for lazy numbers and lazy objects
00195 template <typename AT_, typename ET, typename E2A>
00196 class Lazy_rep : public Rep, public Depth_base
00197 {
00198   Lazy_rep (const Lazy_rep&); // cannot be copied.
00199 
00200 public:
00201 
00202   typedef AT_ AT;
00203 
00204   AT at;
00205   mutable ET *et;
00206 
00207   Lazy_rep ()
00208     : at(), et(NULL) {}
00209 
00210   Lazy_rep (const AT& a)
00211       : at(a), et(NULL) {}
00212 
00213   Lazy_rep (const AT& a, const ET& e)
00214       : at(a), et(new ET(e)) {}
00215 
00216   const AT& approx() const
00217   {
00218       return at;
00219   }
00220 
00221   AT& approx()
00222   {
00223       return at;
00224   }
00225 
00226   const ET & exact() const
00227   {
00228     if (et==NULL)
00229       update_exact();
00230     return *et;
00231   }
00232 
00233   ET & exact()
00234   {
00235     if (et==NULL)
00236       update_exact();
00237     return *et;
00238   }
00239 
00240 #ifdef CGAL_LAZY_KERNEL_DEBUG
00241   void print_at_et(std::ostream& os, int level) const
00242   {
00243     for(int i = 0; i < level; i++){
00244       os << "    ";
00245     }
00246     os << "Approximation: ";
00247     print_at(os, at);
00248     os << std::endl;
00249     if(! is_lazy()){
00250       for(int i = 0; i < level; i++){
00251         os << "    ";
00252       }
00253       os << "Exact: ";
00254       print_at(os, *et);
00255       os << std::endl;
00256     }
00257   }
00258 
00259   virtual void print_dag(std::ostream& os, int level) const {}
00260 #endif
00261 
00262   bool is_lazy() const { return et == NULL; }
00263   virtual void update_exact() = 0;
00264   virtual ~Lazy_rep() { delete et; }
00265 };
00266 
00267 
00268 //____________________________________________________________
00269 // The rep for the leaf node
00270 // FIXME TODO : Factorize all the Lazy_rep_[0-8] !!!
00271 
00272 template <typename AT, typename ET, typename E2A>
00273 class Lazy_rep_0 : public Lazy_rep<AT, ET, E2A>
00274 {
00275 
00276   typedef Lazy_rep<AT, ET, E2A> Base;
00277 public:
00278 
00279   void
00280   update_exact()
00281   {
00282     this->et = new ET();
00283   }
00284 
00285   Lazy_rep_0()
00286     : Lazy_rep<AT,ET, E2A>() {}
00287 
00288   Lazy_rep_0(const AT& a, const ET& e)
00289     : Lazy_rep<AT,ET,E2A>(a, e) {}
00290 
00291   Lazy_rep_0(const AT& a, void*)
00292     : Lazy_rep<AT,ET,E2A>(a) {}
00293 
00294   Lazy_rep_0(const ET& e)
00295     : Lazy_rep<AT,ET,E2A>(E2A()(e), e) {}
00296 
00297   void
00298   print_dag(std::ostream& os, int level) const
00299   {
00300     this->print_at_et(os, level);
00301   }
00302 };
00303 
00304 
00305 //____________________________________________________________
00306 
00307 template <typename AC, typename EC, typename E2A, typename L1>
00308 class Lazy_rep_1
00309   : public Lazy_rep<typename AC::result_type, typename EC::result_type, E2A>
00310   , private EC
00311 {
00312   typedef typename AC::result_type AT;
00313   typedef typename EC::result_type ET;
00314   typedef Lazy_rep<AT, ET, E2A> Base;
00315 
00316   L1 l1_;
00317 
00318   const EC& ec() const { return *this; }
00319 
00320 public:
00321 
00322   void
00323   update_exact()
00324   {
00325     this->et = new ET(ec()(CGAL::exact(l1_)));
00326     this->at = E2A()(*(this->et));
00327     // Prune lazy tree
00328     l1_ = L1();
00329   }
00330 
00331   Lazy_rep_1(const AC& ac, const EC& ec, const L1& l1)
00332     : Lazy_rep<AT,ET, E2A>(ac(CGAL::approx(l1))), EC(ec), l1_(l1)
00333   {
00334     this->set_depth(CGAL::depth(l1_) + 1);
00335   }
00336 
00337 #ifdef CGAL_LAZY_KERNEL_DEBUG
00338   void
00339   print_dag(std::ostream& os, int level) const
00340   {
00341     this->print_at_et(os, level);
00342     if(this->is_lazy()){
00343       CGAL::msg(os, level, "DAG with one child node:");
00344       CGAL::print_dag(l1_, os, level+1);
00345     }
00346   }
00347 #endif
00348 };
00349 
00350 
00351 
00352 //____________________________________________________________
00353 
00354 template <typename AC, typename EC, typename E2A, typename L1, typename L2>
00355 class Lazy_rep_2
00356   : public Lazy_rep<typename AC::result_type, typename EC::result_type, E2A>
00357   , private EC
00358 {
00359   typedef typename AC::result_type AT;
00360   typedef typename EC::result_type ET;
00361   typedef Lazy_rep<AT, ET, E2A> Base;
00362 
00363   L1 l1_;
00364   L2 l2_;
00365 
00366   const EC& ec() const { return *this; }
00367 
00368 public:
00369 
00370   void
00371   update_exact()
00372   {
00373     this->et = new ET(ec()(CGAL::exact(l1_), CGAL::exact(l2_)));
00374     this->at = E2A()(*(this->et));
00375     // Prune lazy tree
00376     l1_ = L1();
00377     l2_ = L2();
00378   }
00379 
00380   Lazy_rep_2(const AC& ac, const EC& /*ec*/, const L1& l1, const L2& l2)
00381     : Lazy_rep<AT,ET,E2A>(ac(CGAL::approx(l1), CGAL::approx(l2))),
00382       l1_(l1), l2_(l2)
00383   {
00384     this->set_depth(max_n(CGAL::depth(l1_), CGAL::depth(l2_)) + 1);
00385   }
00386 
00387 #ifdef CGAL_LAZY_KERNEL_DEBUG
00388   void
00389   print_dag(std::ostream& os, int level) const
00390   {
00391     this->print_at_et(os, level);
00392     if(this->is_lazy()){
00393       CGAL::msg(os, level, "DAG with two child nodes:");
00394       CGAL::print_dag(l1_, os, level+1);
00395       CGAL::print_dag(l2_, os, level+1);
00396     }
00397   }
00398 #endif
00399 };
00400 
00401 
00402 //____________________________________________________________
00403 
00404 template <typename AC, typename EC, typename E2A,
00405           typename L1, typename L2, typename L3>
00406 class Lazy_rep_3
00407   : public Lazy_rep<typename AC::result_type, typename EC::result_type, E2A>
00408   , private EC
00409 {
00410   typedef typename AC::result_type AT;
00411   typedef typename EC::result_type ET;
00412   typedef Lazy_rep<AT, ET, E2A> Base;
00413 
00414   L1 l1_;
00415   L2 l2_;
00416   L3 l3_;
00417 
00418   const EC& ec() const { return *this; }
00419 
00420 public:
00421 
00422   void
00423   update_exact()
00424   {
00425     this->et = new ET(ec()(CGAL::exact(l1_), CGAL::exact(l2_),
00426                            CGAL::exact(l3_)));
00427     this->at = E2A()(*(this->et));
00428     // Prune lazy tree
00429     l1_ = L1();
00430     l2_ = L2();
00431     l3_ = L3();
00432   }
00433 
00434   Lazy_rep_3(const AC& ac, const EC& /*ec*/,
00435              const L1& l1, const L2& l2, const L3& l3)
00436     : Lazy_rep<AT,ET,E2A>(ac(CGAL::approx(l1), CGAL::approx(l2),
00437                              CGAL::approx(l3))),
00438       l1_(l1), l2_(l2), l3_(l3)
00439   {
00440     this->set_depth(max_n(CGAL::depth(l1_),
00441                           CGAL::depth(l2_),
00442                           CGAL::depth(l3_)) + 1);
00443   }
00444 
00445 #ifdef CGAL_LAZY_KERNEL_DEBUG
00446   void
00447   print_dag(std::ostream& os, int level) const
00448   {
00449     this->print_at_et(os, level);
00450     if(this->is_lazy()){
00451       CGAL::msg(os, level, "DAG with three child nodes:");
00452       CGAL::print_dag(l1_, os, level+1);
00453       CGAL::print_dag(l2_, os, level+1);
00454       CGAL::print_dag(l3_, os, level+1);
00455     }
00456   }
00457 #endif
00458 };
00459 
00460 
00461 //____________________________________________________________
00462 
00463 template <typename AC, typename EC, typename E2A,
00464           typename L1, typename L2, typename L3, typename L4>
00465 class Lazy_rep_4
00466   : public Lazy_rep<typename AC::result_type, typename EC::result_type, E2A>
00467   , private EC
00468 {
00469   typedef typename AC::result_type AT;
00470   typedef typename EC::result_type ET;
00471   typedef Lazy_rep<AT, ET, E2A> Base;
00472 
00473   L1 l1_;
00474   L2 l2_;
00475   L3 l3_;
00476   L4 l4_;
00477 
00478   const EC& ec() const { return *this; }
00479 
00480 public:
00481 
00482   void
00483   update_exact()
00484   {
00485     this->et = new ET(ec()(CGAL::exact(l1_), CGAL::exact(l2_),
00486                            CGAL::exact(l3_), CGAL::exact(l4_)));
00487     this->at = E2A()(*(this->et));
00488     // Prune lazy tree
00489     l1_ = L1();
00490     l2_ = L2();
00491     l3_ = L3();
00492     l4_ = L4();
00493   }
00494 
00495   Lazy_rep_4(const AC& ac, const EC& /*ec*/,
00496              const L1& l1, const L2& l2, const L3& l3, const L4& l4)
00497    : Lazy_rep<AT,ET,E2A>(ac(CGAL::approx(l1), CGAL::approx(l2),
00498                             CGAL::approx(l3), CGAL::approx(l4))),
00499      l1_(l1), l2_(l2), l3_(l3), l4_(l4)
00500   {
00501     this->set_depth(max_n(CGAL::depth(l1_),
00502                           CGAL::depth(l2_),
00503                           CGAL::depth(l3_),
00504                           CGAL::depth(l4_)) + 1);
00505   }
00506 
00507 #ifdef CGAL_LAZY_KERNEL_DEBUG
00508   void
00509   print_dag(std::ostream& os, int level) const
00510   {
00511     this->print_at_et(os, level);
00512 
00513     if(this->is_lazy()){
00514       CGAL::msg(os, level, "DAG with four child nodes:");
00515       CGAL::print_dag(l1_, os, level+1);
00516       CGAL::print_dag(l2_, os, level+1);
00517       CGAL::print_dag(l3_, os, level+1);
00518       CGAL::print_dag(l4_, os, level+1);
00519     }
00520   }
00521 #endif
00522 };
00523 
00524 //____________________________________________________________
00525 
00526 
00527 template <typename AC, typename EC, typename E2A,
00528           typename L1, typename L2, typename L3, typename L4, typename L5>
00529 class Lazy_rep_5
00530   : public Lazy_rep<typename AC::result_type, typename EC::result_type, E2A>
00531   , private EC
00532 {
00533   typedef typename AC::result_type AT;
00534   typedef typename EC::result_type ET;
00535   typedef Lazy_rep<AT, ET, E2A> Base;
00536 
00537   L1 l1_;
00538   L2 l2_;
00539   L3 l3_;
00540   L4 l4_;
00541   L5 l5_;
00542 
00543   const EC& ec() const { return *this; }
00544 
00545 public:
00546 
00547   void
00548   update_exact()
00549   {
00550     this->et = new ET(ec()(CGAL::exact(l1_), CGAL::exact(l2_),
00551                            CGAL::exact(l3_), CGAL::exact(l4_),
00552                            CGAL::exact(l5_)));
00553     this->at = E2A()(*(this->et));
00554     // Prune lazy tree
00555     l1_ = L1();
00556     l2_ = L2();
00557     l3_ = L3();
00558     l4_ = L4();
00559     l5_ = L5();
00560   }
00561 
00562  Lazy_rep_5(const AC& ac, const EC& /*ec*/,
00563             const L1& l1, const L2& l2, const L3& l3, const L4& l4,
00564             const L5& l5)
00565     : Lazy_rep<AT,ET,E2A>(ac(CGAL::approx(l1), CGAL::approx(l2),
00566                              CGAL::approx(l3), CGAL::approx(l4),
00567                              CGAL::approx(l5))),
00568       l1_(l1), l2_(l2), l3_(l3), l4_(l4), l5_(l5)
00569   {
00570     this->set_depth(max_n(CGAL::depth(l1_),
00571                           CGAL::depth(l2_),
00572                           CGAL::depth(l3_),
00573                           CGAL::depth(l4_),
00574                           CGAL::depth(l5_)) + 1);
00575   }
00576 
00577 #ifdef CGAL_LAZY_KERNEL_DEBUG
00578   void
00579   print_dag(std::ostream& os, int level) const
00580   {
00581     this->print_at_et(os, level);
00582 
00583     if(this->is_lazy()){
00584       CGAL::msg(os, level, "DAG with five child nodes:");
00585       CGAL::print_dag(l1_, os, level+1);
00586       CGAL::print_dag(l2_, os, level+1);
00587       CGAL::print_dag(l3_, os, level+1);
00588       CGAL::print_dag(l4_, os, level+1);
00589       CGAL::print_dag(l5_, os, level+1);
00590     }
00591   }
00592 #endif
00593 };
00594 
00595 template <typename AC, typename EC, typename E2A,
00596           typename L1, typename L2, typename L3, typename L4,
00597           typename L5, typename L6>
00598 class Lazy_rep_6
00599   : public Lazy_rep<typename AC::result_type, typename EC::result_type, E2A>
00600   , private EC
00601 {
00602   typedef typename AC::result_type AT;
00603   typedef typename EC::result_type ET;
00604   typedef Lazy_rep<AT, ET, E2A> Base;
00605 
00606   L1 l1_;
00607   L2 l2_;
00608   L3 l3_;
00609   L4 l4_;
00610   L5 l5_;
00611   L6 l6_;
00612 
00613   const EC& ec() const { return *this; }
00614 
00615 public:
00616 
00617   void
00618   update_exact()
00619   {
00620     this->et = new ET(ec()(CGAL::exact(l1_), CGAL::exact(l2_),
00621                            CGAL::exact(l3_), CGAL::exact(l4_),
00622                            CGAL::exact(l5_), CGAL::exact(l6_)));
00623     this->at = E2A()(*(this->et));
00624     // Prune lazy tree
00625     l1_ = L1();
00626     l2_ = L2();
00627     l3_ = L3();
00628     l4_ = L4();
00629     l5_ = L5();
00630     l6_ = L6();
00631   }
00632 
00633  Lazy_rep_6(const AC& ac, const EC& /*ec*/,
00634             const L1& l1, const L2& l2, const L3& l3, const L4& l4,
00635             const L5& l5, const L6& l6)
00636     : Lazy_rep<AT,ET,E2A>(ac(CGAL::approx(l1), CGAL::approx(l2),
00637                              CGAL::approx(l3), CGAL::approx(l4),
00638                              CGAL::approx(l5), CGAL::approx(l6))),
00639       l1_(l1), l2_(l2), l3_(l3), l4_(l4), l5_(l5), l6_(l6)
00640   {
00641     this->set_depth(max_n(CGAL::depth(l1_),
00642                           CGAL::depth(l2_),
00643                           CGAL::depth(l3_),
00644                           CGAL::depth(l4_),
00645                           CGAL::depth(l5_),
00646                           CGAL::depth(l6_)) + 1);
00647   }
00648 
00649 #ifdef CGAL_LAZY_KERNEL_DEBUG
00650   void
00651   print_dag(std::ostream& os, int level) const
00652   {
00653     this->print_at_et(os, level);
00654 
00655     if(this->is_lazy()){
00656       CGAL::msg(os, level, "DAG with 6 child nodes:");
00657       CGAL::print_dag(l1_, os, level+1);
00658       CGAL::print_dag(l2_, os, level+1);
00659       CGAL::print_dag(l3_, os, level+1);
00660       CGAL::print_dag(l4_, os, level+1);
00661       CGAL::print_dag(l5_, os, level+1);
00662       CGAL::print_dag(l6_, os, level+1);
00663     }
00664   }
00665 #endif
00666 };
00667 
00668 template <typename AC, typename EC, typename E2A,
00669           typename L1, typename L2, typename L3, typename L4,
00670           typename L5, typename L6, typename L7>
00671 class Lazy_rep_7
00672   : public Lazy_rep<typename AC::result_type, typename EC::result_type, E2A>
00673   , private EC
00674 {
00675   typedef typename AC::result_type AT;
00676   typedef typename EC::result_type ET;
00677   typedef Lazy_rep<AT, ET, E2A> Base;
00678 
00679   L1 l1_;
00680   L2 l2_;
00681   L3 l3_;
00682   L4 l4_;
00683   L5 l5_;
00684   L6 l6_;
00685   L7 l7_;
00686 
00687   const EC& ec() const { return *this; }
00688 
00689 public:
00690 
00691   void
00692   update_exact()
00693   {
00694     this->et = new ET(ec()(CGAL::exact(l1_), CGAL::exact(l2_),
00695                            CGAL::exact(l3_), CGAL::exact(l4_),
00696                            CGAL::exact(l5_), CGAL::exact(l6_),
00697                            CGAL::exact(l7_)));
00698     this->at = E2A()(*(this->et));
00699     // Prune lazy tree
00700     l1_ = L1();
00701     l2_ = L2();
00702     l3_ = L3();
00703     l4_ = L4();
00704     l5_ = L5();
00705     l6_ = L6();
00706     l7_ = L7();
00707   }
00708 
00709  Lazy_rep_7(const AC& ac, const EC& /*ec*/,
00710             const L1& l1, const L2& l2, const L3& l3, const L4& l4,
00711             const L5& l5, const L6& l6, const L7& l7)
00712     : Lazy_rep<AT,ET,E2A>(ac(CGAL::approx(l1), CGAL::approx(l2),
00713                              CGAL::approx(l3), CGAL::approx(l4),
00714                              CGAL::approx(l5), CGAL::approx(l6),
00715                              CGAL::approx(l7))),
00716       l1_(l1), l2_(l2), l3_(l3), l4_(l4), l5_(l5), l6_(l6), l7_(l7)
00717   {
00718     this->set_depth(max_n(CGAL::depth(l1_),
00719                           CGAL::depth(l2_),
00720                           CGAL::depth(l3_),
00721                           CGAL::depth(l4_),
00722                           CGAL::depth(l5_),
00723                           CGAL::depth(l6_),
00724                           CGAL::depth(l7_)) + 1);
00725   }
00726 
00727 #ifdef CGAL_LAZY_KERNEL_DEBUG
00728   void
00729   print_dag(std::ostream& os, int level) const
00730   {
00731     this->print_at_et(os, level);
00732 
00733     if(this->is_lazy()){
00734       CGAL::msg(os, level, "DAG with 7 child nodes:");
00735       CGAL::print_dag(l1_, os, level+1);
00736       CGAL::print_dag(l2_, os, level+1);
00737       CGAL::print_dag(l3_, os, level+1);
00738       CGAL::print_dag(l4_, os, level+1);
00739       CGAL::print_dag(l5_, os, level+1);
00740       CGAL::print_dag(l6_, os, level+1);
00741       CGAL::print_dag(l7_, os, level+1);
00742     }
00743   }
00744 #endif
00745 };
00746 
00747 template <typename AC, typename EC, typename E2A,
00748           typename L1, typename L2, typename L3, typename L4,
00749           typename L5, typename L6, typename L7, typename L8>
00750 class Lazy_rep_8
00751   : public Lazy_rep<typename AC::result_type, typename EC::result_type, E2A>
00752   , private EC
00753 {
00754   typedef typename AC::result_type AT;
00755   typedef typename EC::result_type ET;
00756   typedef Lazy_rep<AT, ET, E2A> Base;
00757 
00758   L1 l1_;
00759   L2 l2_;
00760   L3 l3_;
00761   L4 l4_;
00762   L5 l5_;
00763   L6 l6_;
00764   L7 l7_;
00765   L8 l8_;
00766 
00767   const EC& ec() const { return *this; }
00768 
00769 public:
00770 
00771   void
00772   update_exact()
00773   {
00774     this->et = new ET(ec()(CGAL::exact(l1_), CGAL::exact(l2_),
00775                            CGAL::exact(l3_), CGAL::exact(l4_),
00776                            CGAL::exact(l5_), CGAL::exact(l6_),
00777                            CGAL::exact(l7_), CGAL::exact(l8_)));
00778     this->at = E2A()(*(this->et));
00779     // Prune lazy tree
00780     l1_ = L1();
00781     l2_ = L2();
00782     l3_ = L3();
00783     l4_ = L4();
00784     l5_ = L5();
00785     l6_ = L6();
00786     l7_ = L7();
00787     l8_ = L8();
00788   }
00789 
00790  Lazy_rep_8(const AC& ac, const EC& /*ec*/,
00791             const L1& l1, const L2& l2, const L3& l3, const L4& l4,
00792             const L5& l5, const L6& l6, const L7& l7, const L8& l8)
00793     : Lazy_rep<AT,ET,E2A>(ac(CGAL::approx(l1), CGAL::approx(l2),
00794                              CGAL::approx(l3), CGAL::approx(l4),
00795                              CGAL::approx(l5), CGAL::approx(l6),
00796                              CGAL::approx(l7), CGAL::approx(l8))),
00797        l1_(l1), l2_(l2), l3_(l3), l4_(l4), l5_(l5), l6_(l6), l7_(l7), l8_(l8)
00798   {
00799     this->set_depth(max_n(CGAL::depth(l1_),
00800                           CGAL::depth(l2_),
00801                           CGAL::depth(l3_),
00802                           CGAL::depth(l4_),
00803                           CGAL::depth(l5_),
00804                           CGAL::depth(l6_),
00805                           CGAL::depth(l7_),
00806                           CGAL::depth(l8_)) + 1);
00807   }
00808 
00809 #ifdef CGAL_LAZY_KERNEL_DEBUG
00810   void
00811   print_dag(std::ostream& os, int level) const
00812   {
00813     this->print_at_et(os, level);
00814 
00815     if(this->is_lazy()){
00816       CGAL::msg(os, level, "DAG with 8 child nodes:");
00817       CGAL::print_dag(l1_, os, level+1);
00818       CGAL::print_dag(l2_, os, level+1);
00819       CGAL::print_dag(l3_, os, level+1);
00820       CGAL::print_dag(l4_, os, level+1);
00821       CGAL::print_dag(l5_, os, level+1);
00822       CGAL::print_dag(l6_, os, level+1);
00823       CGAL::print_dag(l7_, os, level+1);
00824       CGAL::print_dag(l8_, os, level+1);
00825     }
00826   }
00827 #endif
00828 };
00829 
00830 
00831 template < typename K1, typename K2 >
00832 struct Approx_converter
00833 {
00834   typedef K1         Source_kernel;
00835   typedef K2         Target_kernel;
00836   //typedef Converter  Number_type_converter;
00837 
00838   template < typename T >
00839   const typename T::AT&
00840   operator()(const T&t) const
00841   { return t.approx(); }
00842 
00843   const Null_vector&
00844   operator()(const Null_vector& n) const
00845   { return n; }
00846 };
00847 
00848 template < typename K1, typename K2 >
00849 struct Exact_converter
00850 {
00851   typedef K1         Source_kernel;
00852   typedef K2         Target_kernel;
00853   //typedef Converter  Number_type_converter;
00854 
00855   template < typename T >
00856   const typename T::ET&
00857   operator()(const T&t) const
00858   { return t.exact(); }
00859 
00860   const Null_vector&
00861   operator()(const Null_vector& n) const
00862   { return n; }
00863 };
00864 
00865 //____________________________________________________________
00866 
00867 
00868 
00869 template <typename AC, typename EC, typename E2A, typename L1>
00870 class Lazy_rep_with_vector_1
00871   : public Lazy_rep<std::vector<Object>, std::vector<Object>, E2A>
00872   , private EC
00873 {
00874   typedef std::vector<Object> AT;
00875   typedef std::vector<Object> ET;
00876   typedef Lazy_rep<AT, ET, E2A> Base;
00877 
00878   L1 l1_;
00879 
00880   const EC& ec() const { return *this; }
00881 
00882 public:
00883 
00884   void
00885   update_exact()
00886   {
00887 // TODO : This looks really unfinished...
00888     std::vector<Object> vec;
00889     this->et = new ET();
00890     //this->et->reserve(this->at.size());
00891     ec()(CGAL::exact(l1_), std::back_inserter(*(this->et)));
00892     if(this->et==NULL)
00893     E2A()(*(this->et));
00894     this->at = E2A()(*(this->et));
00895     // Prune lazy tree
00896     l1_ = L1();
00897   }
00898 
00899   Lazy_rep_with_vector_1(const AC& ac, const EC& /*ec*/, const L1& l1)
00900     : l1_(l1)
00901   {
00902     ac(CGAL::approx(l1), std::back_inserter(this->at));
00903   }
00904 
00905 #ifdef CGAL_LAZY_KERNEL_DEBUG
00906   void
00907   print_dag(std::ostream& os, int level) const
00908   {
00909     this->print_at_et(os, level);
00910     os << "A Lazy_rep_with_vector_1 of size " <<  this->at.size() << std::endl;
00911     if(this->is_lazy()){
00912       CGAL::msg(os, level, "DAG with one child node:");
00913       CGAL::print_dag(l1_, os, level+1);
00914 
00915     }
00916   }
00917 #endif
00918 };
00919 
00920 
00921 template <typename AC, typename EC, typename E2A, typename L1, typename L2>
00922 class Lazy_rep_with_vector_2
00923   : public Lazy_rep<std::vector<Object>, std::vector<Object>, E2A>
00924   , private EC
00925 {
00926   typedef std::vector<Object> AT;
00927   typedef std::vector<Object> ET;
00928   typedef Lazy_rep<AT, ET, E2A> Base;
00929 
00930   L1 l1_;
00931   L2 l2_;
00932 
00933   const EC& ec() const { return *this; }
00934 
00935 public:
00936 
00937   void
00938   update_exact()
00939   {
00940     this->et = new ET();
00941     this->et->reserve(this->at.size());
00942     ec()(CGAL::exact(l1_), CGAL::exact(l2_), std::back_inserter(*(this->et)));
00943     this->at = E2A()(*(this->et));
00944     // Prune lazy tree
00945     l1_ = L1();
00946     l2_ = L2();
00947   }
00948 
00949   Lazy_rep_with_vector_2(const AC& ac, const EC& /*ec*/, const L1& l1, const L2& l2)
00950     : l1_(l1), l2_(l2)
00951   {
00952     ac(CGAL::approx(l1), CGAL::approx(l2), std::back_inserter(this->at));
00953   }
00954 
00955 #ifdef CGAL_LAZY_KERNEL_DEBUG
00956   void
00957   print_dag(std::ostream& os, int level) const
00958   {
00959     this->print_at_et(os, level);
00960     os << "A Lazy_rep_with_vector_2 of size " <<  this->at.size() << std::endl;
00961     if(this->is_lazy()){
00962       CGAL::msg(os, level, "DAG with two child nodes:");
00963       CGAL::print_dag(l1_, os, level+1);
00964       CGAL::print_dag(l2_, os, level+1);
00965     }
00966   }
00967 #endif
00968 };
00969 
00970 
00971 template <typename AC, typename EC, typename E2A, typename L1, typename L2, typename R1>
00972 class Lazy_rep_2_1
00973   : public Lazy_rep<typename R1::AT, typename R1::ET, E2A>
00974   , private EC
00975 {
00976   typedef typename R1::AT AT;
00977   typedef typename R1::ET ET;
00978   typedef Lazy_rep<AT, ET, E2A> Base;
00979 
00980   L1 l1_;
00981   L2 l2_;
00982 
00983   const EC& ec() const { return *this; }
00984 
00985 public:
00986 
00987   void
00988   update_exact()
00989   {
00990     this->et = new ET();
00991     ec()(CGAL::exact(l1_), CGAL::exact(l2_), *(this->et));
00992     this->at = E2A()(*(this->et));
00993     // Prune lazy tree
00994     l1_ = L1();
00995     l2_ = L2();
00996   }
00997 
00998   Lazy_rep_2_1(const AC& ac, const EC& /*ec*/, const L1& l1, const L2& l2)
00999     : Lazy_rep<AT,ET,E2A>(), l1_(l1), l2_(l2)
01000   {
01001     ac(CGAL::approx(l1), CGAL::approx(l2), this->at);
01002   }
01003 
01004 #ifdef CGAL_LAZY_KERNEL_DEBUG
01005   void
01006   print_dag(std::ostream& os, int level) const
01007   {
01008     this->print_at_et(os, level);
01009     os << "A Lazy_rep_2_1" << std::endl;
01010     if(this->is_lazy()){
01011       CGAL::msg(os, level, "DAG with two child nodes:");
01012       CGAL::print_dag(l1_, os, level+1);
01013       CGAL::print_dag(l2_, os, level+1);
01014     }
01015   }
01016 #endif
01017 };
01018 
01019 
01020 //____________________________________________________________________________________
01021 // The following rep class stores two non-const reference parameters of type R1 and R2
01022 
01023 template <typename AC, typename EC, typename E2A, typename L1, typename L2, typename R1, typename R2>
01024 class Lazy_rep_2_2
01025   : public Lazy_rep<std::pair<typename R1::AT,typename R2::AT>, std::pair<typename R1::ET, typename R2::ET>, E2A>
01026   , private EC
01027 {
01028   typedef std::pair<typename R1::AT, typename R2::AT> AT;
01029   typedef std::pair<typename R1::ET, typename R2::ET> ET;
01030   typedef Lazy_rep<AT, ET, E2A> Base;
01031 
01032   L1 l1_;
01033   L2 l2_;
01034 
01035   const EC& ec() const { return *this; }
01036 
01037 public:
01038 
01039   void
01040   update_exact()
01041   {
01042     this->et = new ET();
01043     ec()(CGAL::exact(l1_), CGAL::exact(l2_), this->et->first, this->et->second );
01044     this->at = E2A()(*(this->et));
01045     // Prune lazy tree
01046     l1_ = L1();
01047     l2_ = L2();
01048   }
01049 
01050   Lazy_rep_2_2(const AC& ac, const EC& /*ec*/, const L1& l1, const L2& l2)
01051     : Lazy_rep<AT,ET,E2A>(), l1_(l1), l2_(l2)
01052   {
01053     ac(CGAL::approx(l1), CGAL::approx(l2), this->at.first, this->at.second);
01054   }
01055 
01056 #ifdef CGAL_LAZY_KERNEL_DEBUG
01057   void
01058   print_dag(std::ostream& os, int level) const
01059   {
01060     this->print_at_et(os, level);
01061     os << "A Lazy_rep_2_2"  << std::endl;
01062     if(this->is_lazy()){
01063       CGAL::msg(os, level, "DAG with two child nodes:");
01064       CGAL::print_dag(l1_, os, level+1);
01065       CGAL::print_dag(l2_, os, level+1);
01066     }
01067   }
01068 #endif
01069 };
01070 
01071 
01072 //____________________________________________________________
01073 // The handle class
01074 template <typename AT_, typename ET_, typename EFT, typename E2A>
01075 class Lazy : public Handle
01076 {
01077 public :
01078 
01079   typedef Lazy<AT_, ET_, EFT, E2A>  Self;
01080   typedef Lazy_rep<AT_, ET_, E2A>   Self_rep;
01081 
01082   typedef AT_ AT; // undocumented
01083   typedef ET_ ET; // undocumented
01084 
01085   typedef AT  Approximate_type;
01086   typedef ET  Exact_type;
01087 
01088 /*
01089   typedef Self Rep;
01090 
01091   const Rep& rep() const
01092   {
01093     return *this;
01094   }
01095 
01096   Rep& rep()
01097   {
01098     return *this;
01099   }
01100 */
01101 
01102   Lazy()
01103 #if 1 // ndef CGAL_HAS_THREADS
01104     : Handle(zero()) {}
01105 #else
01106   {
01107     PTR = new Lazy_rep_0<AT, ET, E2A>();
01108   }
01109 #endif
01110 
01111   Lazy(Self_rep *r)
01112   {
01113     PTR = r;
01114   }
01115 
01116   Lazy(const ET& e)
01117   {
01118     PTR = new Lazy_rep_0<AT,ET,E2A>(e);
01119   }
01120 
01121   const AT& approx() const
01122   { return ptr()->approx(); }
01123 
01124   const ET& exact() const
01125   { return ptr()->exact(); }
01126 
01127   AT& approx()
01128   { return ptr()->approx(); }
01129 
01130   ET& exact()
01131   { return ptr()->exact(); }
01132 
01133   unsigned depth() const
01134   {
01135     return ptr()->depth();
01136   }
01137 
01138   void print_dag(std::ostream& os, int level) const
01139   {
01140     ptr()->print_dag(os, level);
01141   }
01142 
01143 private:
01144 
01145   // We have a static variable for optimizing the default constructor,
01146   // which is in particular heavily used for pruning DAGs.
01147   static const Self & zero()
01148   {
01149 #ifdef CGAL_HAS_THREADS
01150     static boost::thread_specific_ptr<Self> z;
01151     if (z.get() == NULL) {
01152         z.reset(new Self(new Lazy_rep_0<AT, ET, E2A>()));
01153     }
01154     return * z.get();
01155 #else
01156     static const Self z = new Lazy_rep_0<AT, ET, E2A>();
01157     return z;
01158 #endif
01159   }
01160 
01161   Self_rep * ptr() const { return (Self_rep*) PTR; }
01162 };
01163 
01164 
01165 
01166 
01167 
01168 // The magic functor for Construct_bbox_[2,3], as there is no Lazy<Bbox>
01169 
01170 template <typename LK, typename AC, typename EC>
01171 struct Lazy_construction_bbox
01172 {
01173   static const bool Protection = true;
01174   typedef typename LK::Approximate_kernel AK;
01175   typedef typename LK::Exact_kernel EK;
01176   typedef typename AC::result_type result_type;
01177 
01178   AC ac;
01179   EC ec;
01180 
01181   template <typename L1>
01182   result_type operator()(const L1& l1) const
01183   {
01184     CGAL_BRANCH_PROFILER(std::string(" failures/calls to   : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
01185     // Protection is outside the try block as VC8 has the CGAL_CFG_FPU_ROUNDING_MODE_UNWINDING_VC_BUG
01186     Protect_FPU_rounding<Protection> P;
01187     try {
01188       return ac(CGAL::approx(l1));
01189     } catch (Uncertain_conversion_exception) {
01190       CGAL_BRANCH_PROFILER_BRANCH(tmp);
01191       Protect_FPU_rounding<!Protection> P2(CGAL_FE_TONEAREST);
01192       return ec(CGAL::exact(l1));
01193     }
01194   }
01195 };
01196 
01197 template <typename LK, typename AC, typename EC>
01198 struct Lazy_construction_nt {
01199 
01200   static const bool Protection = true;
01201 
01202   typedef typename LK::Approximate_kernel AK;
01203   typedef typename LK::Exact_kernel EK;
01204   typedef typename LK::E2A E2A;
01205   typedef typename AC::result_type AT;
01206   typedef typename EC::result_type ET;
01207   typedef Lazy_exact_nt<ET> result_type;
01208 
01209   AC ac;
01210   EC ec;
01211 
01212   template <typename L1>
01213   result_type operator()(const L1& l1) const
01214   {
01215     CGAL_BRANCH_PROFILER(std::string(" failures/calls to   : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
01216     Protect_FPU_rounding<Protection> P;
01217     try {
01218       return new Lazy_rep_1<AC, EC, To_interval<ET>, L1>(ac, ec, l1);
01219     } catch (Uncertain_conversion_exception) {
01220       CGAL_BRANCH_PROFILER_BRANCH(tmp);
01221       Protect_FPU_rounding<!Protection> P2(CGAL_FE_TONEAREST);
01222       return new Lazy_rep_0<AT,ET,To_interval<ET> >(ec(CGAL::exact(l1)));
01223     }
01224   }
01225 
01226   template <typename L1, typename L2>
01227   result_type operator()(const L1& l1, const L2& l2) const
01228   {
01229     CGAL_BRANCH_PROFILER(std::string(" failures/calls to   : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
01230     Protect_FPU_rounding<Protection> P;
01231     try {
01232       return new Lazy_rep_2<AC, EC, To_interval<ET>, L1,L2>(ac, ec, l1,l2);
01233     } catch (Uncertain_conversion_exception) {
01234       CGAL_BRANCH_PROFILER_BRANCH(tmp);
01235       Protect_FPU_rounding<!Protection> P2(CGAL_FE_TONEAREST);
01236       return new Lazy_rep_0<AT,ET,To_interval<ET> >(ec(CGAL::exact(l1), CGAL::exact(l2)));
01237     }
01238   }
01239 
01240   template <typename L1, typename L2, typename L3>
01241   result_type operator()(const L1& l1, const L2& l2, const L3& l3) const
01242   {
01243     CGAL_BRANCH_PROFILER(std::string(" failures/calls to   : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
01244     Protect_FPU_rounding<Protection> P;
01245     try {
01246       return new Lazy_rep_3<AC, EC, To_interval<ET>, L1,L2,L3>(ac, ec, l1,l2,l3);
01247     } catch (Uncertain_conversion_exception) {
01248       CGAL_BRANCH_PROFILER_BRANCH(tmp);
01249       Protect_FPU_rounding<!Protection> P2(CGAL_FE_TONEAREST);
01250       return new Lazy_rep_0<AT,ET,To_interval<ET> >(ec(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3)));
01251     }
01252   }
01253 
01254   template <typename L1, typename L2, typename L3, typename L4>
01255   result_type operator()(const L1& l1, const L2& l2, const L3& l3, const L4& l4) const
01256   {
01257     CGAL_BRANCH_PROFILER(std::string(" failures/calls to   : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
01258     Protect_FPU_rounding<Protection> P;
01259     try {
01260       return new Lazy_rep_4<AC, EC, To_interval<ET>, L1,L2,L3,L4>(ac, ec, l1,l2,l3,l4);
01261     } catch (Uncertain_conversion_exception) {
01262       CGAL_BRANCH_PROFILER_BRANCH(tmp);
01263       Protect_FPU_rounding<!Protection> P2(CGAL_FE_TONEAREST);
01264       return new Lazy_rep_0<AT,ET,To_interval<ET> >(ec(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3), CGAL::exact(l4)));
01265     }
01266   }
01267 
01268   template <typename L1, typename L2, typename L3, typename L4, typename L5>
01269   result_type operator()(const L1& l1, const L2& l2, const L3& l3, const L4& l4, const L5& l5) const
01270   {
01271     CGAL_BRANCH_PROFILER(std::string(" failures/calls to   : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
01272     Protect_FPU_rounding<Protection> P;
01273     try {
01274       return new Lazy_rep_5<AC, EC, To_interval<ET>, L1,L2,L3,L4,L5>(ac, ec, l1,l2,l3,l4,l5);
01275     } catch (Uncertain_conversion_exception) {
01276       CGAL_BRANCH_PROFILER_BRANCH(tmp);
01277       Protect_FPU_rounding<!Protection> P2(CGAL_FE_TONEAREST);
01278       return new Lazy_rep_0<AT,ET,To_interval<ET> >(ec(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3), CGAL::exact(l4), CGAL::exact(l5)));
01279     }
01280   }
01281 };
01282 
01283 
01284 template <typename LK>
01285 Object
01286 make_lazy(const Object& eto)
01287 {
01288   typedef typename LK::Approximate_kernel AK;
01289   typedef typename LK::Exact_kernel EK;
01290   typedef typename LK::E2A E2A;
01291 
01292   if (eto.is_empty())
01293     return Object();
01294 
01295 #define CGAL_Kernel_obj(X) \
01296   if (const typename EK::X* ptr = object_cast<typename EK::X>(&eto)) \
01297     return make_object(typename LK::X(new Lazy_rep_0<typename AK::X, typename EK::X, E2A>(*ptr)));
01298 
01299 #include <CGAL/Kernel/interface_macros.h>
01300 
01301   std::cerr << "object_cast inside Lazy_construction_rep::operator() failed. It needs more else if's (#2)" << std::endl;
01302   std::cerr << "dynamic type of the Object : " << eto.type().name() << std::endl;
01303 
01304   return Object();
01305 }
01306 
01307 
01308 // This functor selects the i'th element in a vector of Object's
01309 // and casts it to what is in the Object
01310 
01311 template <typename T2>
01312 struct Ith {
01313   typedef T2 result_type;
01314 
01315   // We keep a Sign member object
01316   // for future utilisation, in case
01317   // we have pairs of 2 T2 objects e.g.
01318   // for a numeric_point vector returned
01319   // from a construction of a possible
01320   // lazy algebraic kernel
01321 
01322   int i;
01323   Sign sgn;
01324 
01325   Ith(int i_)
01326     : i(i_)
01327   {sgn=NEGATIVE;}
01328 
01329   Ith(int i_, bool b_)
01330     : i(i_)
01331   { sgn= (b_) ? POSITIVE : ZERO;}
01332 
01333   const T2&
01334   operator()(const std::vector<Object>& v) const
01335   {
01336     if(sgn==NEGATIVE)
01337     return *object_cast<T2>(&v[i]);
01338 
01339     typedef std::pair<T2,unsigned int >         Pair_type_1;
01340     typedef std::pair<T2,std::pair<bool,bool> > Pair_type_2;
01341 
01342     if(const Pair_type_1 *p1 = object_cast<Pair_type_1>(&v[i]))
01343         return p1->first;
01344     else if(const Pair_type_2 *p2 = object_cast<Pair_type_2>(&v[i]))
01345         return p2->first;
01346 
01347     CGAL_error_msg( " Unexpected encapsulated type ");
01348   }
01349 };
01350 
01351 
01352 template <typename LK, typename AC, typename EC>
01353 struct Lazy_cartesian_const_iterator_2
01354 {
01355   typedef typename LK::Approximate_kernel AK;
01356   typedef typename LK::Exact_kernel EK;
01357   typedef typename LK::Cartesian_const_iterator_2 result_type;
01358 
01359   AC ac;
01360   EC ec;
01361 
01362 public:
01363 
01364   template < typename L1>
01365   result_type
01366   operator()(const L1& l1) const
01367   {
01368     return result_type(&l1);
01369   }
01370 
01371   template < typename L1>
01372   result_type
01373   operator()(const L1& l1, int i) const
01374   {
01375     return result_type(&l1,i);
01376   }
01377 
01378 };
01379 
01380 
01381 template <typename LK, typename AC, typename EC>
01382 struct Lazy_cartesian_const_iterator_3
01383 {
01384   typedef typename LK::Approximate_kernel AK;
01385   typedef typename LK::Exact_kernel EK;
01386   typedef typename LK::Cartesian_const_iterator_3 result_type;
01387 
01388   AC ac;
01389   EC ec;
01390 
01391 public:
01392 
01393   template < typename L1>
01394   result_type
01395   operator()(const L1& l1) const
01396   {
01397     return result_type(&l1);
01398   }
01399 
01400   template < typename L1>
01401   result_type
01402   operator()(const L1& l1, int i) const
01403   {
01404     return result_type(&l1,i);
01405   }
01406 
01407 };
01408 
01409 
01410 // This is the magic functor for functors that write their result in a  reference argument
01411 // In a first version we assume that the references are of type Lazy<Something>,
01412 // and that the result type is void
01413 
01414 template <typename LK, typename AK, typename EK, typename AC, typename EC, typename EFT, typename E2A>
01415 struct Lazy_functor_2_1
01416 {
01417   static const bool Protection = true;
01418   typedef void result_type;
01419 
01420   AC ac;
01421   EC ec;
01422 
01423 public:
01424 
01425   template <typename L1, typename L2, typename R1>
01426   void
01427   operator()(const L1& l1, const L2& l2, R1& r1) const
01428   {
01429     CGAL_BRANCH_PROFILER(std::string(" failures/calls to   : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
01430     Protect_FPU_rounding<Protection> P;
01431     try {
01432       // we suppose that R1 is a Lazy<Something>
01433       r1 = R1(new Lazy_rep_2_1<AC, EC, E2A, L1, L2, R1>(ac, ec, l1, l2));
01434     } catch (Uncertain_conversion_exception) {
01435       CGAL_BRANCH_PROFILER_BRANCH(tmp);
01436       Protect_FPU_rounding<!Protection> P2(CGAL_FE_TONEAREST);
01437       typename R1::ET et;
01438       ec(CGAL::exact(l1), CGAL::exact(l2), et);
01439       r1 = R1(new Lazy_rep_0<typename R1::AT,typename R1::ET,E2A>(et));
01440     }
01441   }
01442 };
01443 
01444 
01445 template <typename T>
01446 struct First
01447 {
01448    typedef typename T::first_type result_type;
01449 
01450    const typename T::first_type&
01451    operator()(const T& p) const
01452    {
01453      return p.first;
01454    }
01455  };
01456 
01457 template <typename T>
01458 struct Second
01459 {
01460   typedef typename T::second_type result_type;
01461 
01462   const typename T::second_type&
01463   operator()(const T& p) const
01464   {
01465     return p.second;
01466   }
01467 };
01468 
01469 // This is the magic functor for functors that write their result in a reference argument
01470 // In a first version we assume that the references are of type Lazy<Something>,
01471 // and that the result type is void
01472 
01473 //template <typename LK, typename AK, typename EK, typename AC, typename EC, typename EFT, typename E2A>
01474 template <typename LK, typename AC, typename EC>
01475 struct Lazy_functor_2_2
01476 {
01477   static const bool Protection = true;
01478 
01479   typedef void result_type;
01480   typedef typename LK::Approximate_kernel AK;
01481   typedef typename LK::Exact_kernel EK;
01482   typedef typename EK::FT EFT;
01483   typedef typename LK::E2A E2A;
01484 
01485   AC ac;
01486   EC ec;
01487 
01488 public:
01489 
01490   template <typename L1, typename L2, typename R1, typename R2>
01491   void
01492   operator()(const L1& l1, const L2& l2, R1& r1, R2& r2) const
01493   {
01494     CGAL_BRANCH_PROFILER(std::string(" failures/calls to   : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
01495     Protect_FPU_rounding<Protection> P;
01496     try {
01497       typedef Lazy<std::pair<typename R1::AT, typename R2::AT>, std::pair<typename R1::ET, typename R2::ET>, EFT, E2A> Lazy_pair;
01498       Lazy_pair lv(new Lazy_rep_2_2<AC, EC, E2A, L1, L2, R1, R2>(ac, ec, l1, l2));
01499       // lv->approx() is a std::pair<R1::AT, R2::AT>;
01500       r1 = R1(new Lazy_rep_1<First<std::pair<typename R1::AT, typename R2::AT> >, First<std::pair<typename R1::ET, typename R2::ET> >, E2A, Lazy_pair>(First<std::pair<typename R1::AT, typename R2::AT> >(), First<std::pair<typename R1::ET, typename R2::ET> >(), lv));
01501       r2 = R2(new Lazy_rep_1<Second<std::pair<typename R1::AT, typename R2::AT> >, Second<std::pair<typename R1::ET, typename R2::ET> >, E2A, Lazy_pair>(Second<std::pair<typename R1::AT, typename R2::AT> >(), Second<std::pair<typename R1::ET, typename R2::ET> >(), lv));
01502     } catch (Uncertain_conversion_exception) {
01503       CGAL_BRANCH_PROFILER_BRANCH(tmp);
01504       Protect_FPU_rounding<!Protection> P2(CGAL_FE_TONEAREST);
01505       typename R1::ET et1, et2;
01506       ec(CGAL::exact(l1), CGAL::exact(l2), et1, et2);
01507       r1 = R1(new Lazy_rep_0<typename R1::AT,typename R1::ET,E2A>(et1));
01508       r2 = R2(new Lazy_rep_0<typename R2::AT,typename R2::ET,E2A>(et2));
01509     }
01510   }
01511 };
01512 
01513 
01514 // This is the magic functor for functors that write their result as Objects into an output iterator
01515 
01516 template <typename LK, typename AC, typename EC>
01517 struct Lazy_intersect_with_iterators
01518 {
01519   static const bool Protection = true;
01520   typedef typename LK::Approximate_kernel AK;
01521   typedef typename LK::Exact_kernel EK;
01522   typedef typename EK::FT EFT;
01523   typedef typename LK::E2A E2A;
01524   typedef void result_type;
01525   typedef Lazy<Object, Object, EFT, E2A> Lazy_object;
01526   typedef Lazy<std::vector<Object>, std::vector<Object>, EFT, E2A> Lazy_vector;
01527 
01528   AC ac;
01529   EC ec;
01530 
01531 public:
01532 
01533   // In the example we intersect two Lazy<Segment>s
01534   // and write into a back_inserter(list<Object([Lazy<Point>,Lazy<Segment>]) >)
01535   template <typename L1, typename L2, typename OutputIterator>
01536   OutputIterator
01537   operator()(const L1& l1, const L2& l2, OutputIterator it) const
01538   {
01539     CGAL_BRANCH_PROFILER(std::string(" failures/calls to   : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
01540     Protect_FPU_rounding<Protection> P;
01541     try {
01542       Lazy_vector lv(new Lazy_rep_with_vector_2<AC, EC, E2A, L1, L2>(ac, ec, l1, l2));
01543       // lv.approx() is a std::vector<Object([AK::Point_2,AK::Segment_2])>
01544       // that is, when we get here we have constructed all approximate results
01545       for (unsigned int i = 0; i < lv.approx().size(); i++) {
01546 // FIXME : I'm not sure how this work...
01547 #define CGAL_Kernel_obj(X) if (object_cast<typename AK::X>(& (lv.approx()[i]))) { \
01548           *it++ = make_object(typename LK::X(new Lazy_rep_1<Ith<typename AK::X>, \
01549                                                                       Ith<typename EK::X>, E2A, Lazy_vector> \
01550                                                  (Ith<typename AK::X>(i), Ith<typename EK::X>(i), lv))); \
01551           continue; \
01552         }
01553 
01554 #include <CGAL/Kernel/interface_macros.h>
01555 
01556         std::cerr << "we need  more casts" << std::endl;
01557       }
01558 
01559     } catch (Uncertain_conversion_exception) {
01560       CGAL_BRANCH_PROFILER_BRANCH(tmp);
01561       // TODO: Instead of using a vector, write an iterator adapter
01562       Protect_FPU_rounding<!Protection> P2(CGAL_FE_TONEAREST);
01563       std::vector<Object> exact_objects;
01564       ec(CGAL::exact(l1), CGAL::exact(l2), std::back_inserter(exact_objects));
01565       for (std::vector<Object>::const_iterator oit = exact_objects.begin();
01566            oit != exact_objects.end();
01567            ++oit){
01568         *it++ = make_lazy<LK>(*oit);
01569       }
01570     }
01571     return it;
01572   }
01573 };
01574 
01575 
01576 template <typename T>
01577 struct Object_cast
01578 {
01579   typedef T result_type;
01580 
01581   const T&
01582   operator()(const Object& o) const
01583   {
01584     return *object_cast<T>(&o);
01585   }
01586 };
01587 
01588 // The following functor returns an Object with a Lazy<Something> inside
01589 // As the nested kernels return Objects of AK::Something and EK::Something
01590 // we have to unwrap them from the Object, and wrap them in a Lazy<Something>
01591 //
01592 // TODO: write operators for other than two arguments. For the current kernel we only need two for Intersect_2
01593 
01594 template <typename LK, typename AC, typename EC>
01595 struct Lazy_construction_object
01596 {
01597   static const bool Protection = true;
01598 
01599   typedef typename LK::Approximate_kernel AK;
01600   typedef typename LK::Exact_kernel EK;
01601   typedef typename EK::FT EFT;
01602   typedef typename LK::E2A E2A;
01603   typedef typename AC::result_type AT;
01604   typedef typename EC::result_type ET;
01605   typedef Object result_type;
01606 
01607   typedef Lazy<Object, Object, EFT, E2A> Lazy_object;
01608 
01609   AC ac;
01610   EC ec;
01611 
01612 public:
01613 
01614   template <typename L1>
01615   result_type
01616   operator()(const L1& l1) const
01617   {
01618     CGAL_BRANCH_PROFILER(std::string(" failures/calls to   : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
01619     Protect_FPU_rounding<Protection> P;
01620     try {
01621       Lazy_object lo(new Lazy_rep_1<AC, EC, E2A, L1>(ac, ec, l1));
01622 
01623       if(lo.approx().is_empty())
01624         return Object();
01625 
01626 #define CGAL_Kernel_obj(X) \
01627       if (object_cast<typename AK::X>(& (lo.approx()))) { \
01628         typedef Lazy_rep_1<Object_cast<typename AK::X>, Object_cast<typename EK::X>, E2A, Lazy_object> Lcr; \
01629         Lcr * lcr = new Lcr(Object_cast<typename AK::X>(), Object_cast<typename EK::X>(), lo); \
01630         return make_object(typename LK::X(lcr)); \
01631       }
01632 
01633 #include <CGAL/Kernel/interface_macros.h>
01634 
01635       std::cerr << "object_cast inside Lazy_construction_rep::operator() failed. It needs more else if's (#1)" << std::endl;
01636       std::cerr << "dynamic type of the Object : " << lo.approx().type().name() << std::endl;
01637 
01638     } catch (Uncertain_conversion_exception) {
01639       CGAL_BRANCH_PROFILER_BRANCH(tmp);
01640       Protect_FPU_rounding<!Protection> P2(CGAL_FE_TONEAREST);
01641       ET eto = ec(CGAL::exact(l1));
01642       return make_lazy<LK>(eto);
01643     }
01644     return Object();
01645   }
01646 
01647   template <typename L1, typename L2>
01648   result_type
01649   operator()(const L1& l1, const L2& l2) const
01650   {
01651     CGAL_BRANCH_PROFILER(std::string(" failures/calls to   : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
01652     Protect_FPU_rounding<Protection> P;
01653     try {
01654       Lazy_object lo(new Lazy_rep_2<AC, EC, E2A, L1, L2>(ac, ec, l1, l2));
01655 
01656       if(lo.approx().is_empty())
01657         return Object();
01658 
01659 #define CGAL_Kernel_obj(X) \
01660       if (object_cast<typename AK::X>(& (lo.approx()))) { \
01661         typedef Lazy_rep_1<Object_cast<typename AK::X>, Object_cast<typename EK::X>, E2A, Lazy_object> Lcr; \
01662         Lcr * lcr = new Lcr(Object_cast<typename AK::X>(), Object_cast<typename EK::X>(), lo); \
01663         return make_object(typename LK::X(lcr)); \
01664       }
01665 
01666 #include <CGAL/Kernel/interface_macros.h>
01667 
01668       std::cerr << "object_cast inside Lazy_construction_rep::operator() failed. It needs more else if's (#1)" << std::endl;
01669       std::cerr << "dynamic type of the Object : " << lo.approx().type().name() << std::endl;
01670 
01671     } catch (Uncertain_conversion_exception) {
01672       CGAL_BRANCH_PROFILER_BRANCH(tmp);
01673       Protect_FPU_rounding<!Protection> P2(CGAL_FE_TONEAREST);
01674       ET eto = ec(CGAL::exact(l1), CGAL::exact(l2));
01675       return make_lazy<LK>(eto);
01676     }
01677     return Object();
01678   }
01679 
01680 };
01681 
01682 
01683 
01684 //____________________________________________________________
01685 // The magic functor that has Lazy<Something> as result type
01686 
01687 template <typename LK, typename AC, typename EC, typename E2A_ = Default>
01688 struct Lazy_construction
01689 {
01690   static const bool Protection = true;
01691 
01692   typedef typename LK::Approximate_kernel AK;
01693   typedef typename LK::Exact_kernel EK;
01694   typedef typename EK::FT EFT;
01695   typedef typename Default::Get<E2A_, typename LK::E2A>::type E2A;
01696   typedef typename AC::result_type AT;
01697   typedef typename EC::result_type ET;
01698   typedef Lazy<AT, ET, EFT, E2A> Handle;
01699   typedef typename Type_mapper<AT,AK,LK>::type result_type;
01700 
01701   AC ac;
01702   EC ec;
01703 
01704 public:
01705 
01706   result_type
01707   operator()() const
01708   {
01709     return Handle(new Lazy_rep_0<AT,ET,E2A>());
01710   }
01711 
01712   template <typename L1>
01713   result_type
01714   operator()(const L1& l1) const
01715   {
01716     CGAL_BRANCH_PROFILER(std::string(" failures/calls to   : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
01717     Protect_FPU_rounding<Protection> P;
01718     try {
01719       return  Handle(new Lazy_rep_1<AC, EC, E2A, L1>(ac, ec, l1));
01720     } catch (Uncertain_conversion_exception) {
01721       CGAL_BRANCH_PROFILER_BRANCH(tmp);
01722       Protect_FPU_rounding<!Protection> P2(CGAL_FE_TONEAREST);
01723       return Handle(new Lazy_rep_0<AT,ET,E2A>(ec(CGAL::exact(l1))));
01724     }
01725   }
01726 
01727   template <typename L1, typename L2>
01728   result_type
01729   operator()(const L1& l1, const L2& l2) const
01730   {
01731     CGAL_BRANCH_PROFILER(std::string(" failures/calls to   : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
01732     Protect_FPU_rounding<Protection> P;
01733     try {
01734       return Handle(new Lazy_rep_2<AC, EC, E2A, L1, L2>(ac, ec, l1, l2));
01735     } catch (Uncertain_conversion_exception) {
01736       CGAL_BRANCH_PROFILER_BRANCH(tmp);
01737       Protect_FPU_rounding<!Protection> P2(CGAL_FE_TONEAREST);
01738       return Handle(new Lazy_rep_0<AT,ET,E2A>(ec(CGAL::exact(l1), CGAL::exact(l2))));
01739     }
01740   }
01741 
01742   template <typename L1, typename L2, typename L3>
01743   result_type
01744   operator()(const L1& l1, const L2& l2, const L3& l3) const
01745   {
01746     CGAL_BRANCH_PROFILER(std::string(" failures/calls to   : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
01747       Protect_FPU_rounding<Protection> P;
01748     try {
01749       return Handle(new Lazy_rep_3<AC, EC, E2A, L1, L2, L3>(ac, ec, l1, l2, l3));
01750     } catch (Uncertain_conversion_exception) {
01751       CGAL_BRANCH_PROFILER_BRANCH(tmp);
01752       Protect_FPU_rounding<!Protection> P2(CGAL_FE_TONEAREST);
01753       return Handle(new Lazy_rep_0<AT,ET,E2A>(ec(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3))));
01754     }
01755   }
01756 
01757   template <typename L1, typename L2, typename L3, typename L4>
01758   result_type
01759   operator()(const L1& l1, const L2& l2, const L3& l3, const L4& l4) const
01760   {
01761     CGAL_BRANCH_PROFILER(std::string(" failures/calls to   : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
01762     Protect_FPU_rounding<Protection> P;
01763     try {
01764       return Handle(new Lazy_rep_4<AC, EC, E2A, L1, L2, L3, L4>(ac, ec, l1, l2, l3, l4));
01765     } catch (Uncertain_conversion_exception) {
01766       CGAL_BRANCH_PROFILER_BRANCH(tmp);
01767       Protect_FPU_rounding<!Protection> P2(CGAL_FE_TONEAREST);
01768       return Handle(new Lazy_rep_0<AT,ET,E2A>(ec(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3), CGAL::exact(l4))));
01769     }
01770   }
01771 
01772   template <typename L1, typename L2, typename L3, typename L4, typename L5>
01773   result_type
01774   operator()(const L1& l1, const L2& l2, const L3& l3, const L4& l4, const L5& l5) const
01775   {
01776     CGAL_BRANCH_PROFILER(std::string(" failures/calls to   : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
01777     Protect_FPU_rounding<Protection> P;
01778     try {
01779       return Handle(new Lazy_rep_5<AC, EC, E2A, L1, L2, L3, L4, L5>(ac, ec, l1, l2, l3, l4, l5));
01780     } catch (Uncertain_conversion_exception) {
01781       CGAL_BRANCH_PROFILER_BRANCH(tmp);
01782       Protect_FPU_rounding<!Protection> P2(CGAL_FE_TONEAREST);
01783       return Handle(new Lazy_rep_0<AT,ET,E2A>(ec(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3), CGAL::exact(l4), CGAL::exact(l5))));
01784     }
01785   }
01786 
01787   template <typename L1, typename L2, typename L3, typename L4, typename L5, typename L6>
01788   result_type
01789   operator()(const L1& l1, const L2& l2, const L3& l3, const L4& l4, const L5& l5, const L6& l6) const
01790   {
01791     CGAL_BRANCH_PROFILER(std::string(" failures/calls to   : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
01792     Protect_FPU_rounding<Protection> P;
01793     try {
01794       return Handle(new Lazy_rep_6<AC, EC, E2A, L1, L2, L3, L4, L5, L6>(ac, ec, l1, l2, l3, l4, l5, l6));
01795     } catch (Uncertain_conversion_exception) {
01796       CGAL_BRANCH_PROFILER_BRANCH(tmp);
01797       Protect_FPU_rounding<!Protection> P2(CGAL_FE_TONEAREST);
01798       return Handle(new Lazy_rep_0<AT,ET,E2A>(ec(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3), CGAL::exact(l4), CGAL::exact(l5), CGAL::exact(l6))));
01799     }
01800   }
01801 
01802   template <typename L1, typename L2, typename L3, typename L4, typename L5, typename L6, typename L7>
01803   result_type
01804   operator()(const L1& l1, const L2& l2, const L3& l3, const L4& l4, const L5& l5, const L6& l6, const L7& l7) const
01805   {
01806     CGAL_BRANCH_PROFILER(std::string(" failures/calls to   : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
01807     Protect_FPU_rounding<Protection> P;
01808     try {
01809       return Handle(new Lazy_rep_7<AC, EC, E2A, L1, L2, L3, L4, L5, L6, L7>(ac, ec, l1, l2, l3, l4, l5, l6, l7));
01810     } catch (Uncertain_conversion_exception) {
01811       CGAL_BRANCH_PROFILER_BRANCH(tmp);
01812       Protect_FPU_rounding<!Protection> P2(CGAL_FE_TONEAREST);
01813       return Handle(new Lazy_rep_0<AT,ET,E2A>(ec(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3), CGAL::exact(l4), CGAL::exact(l5), CGAL::exact(l6), CGAL::exact(l7))));
01814     }
01815   }
01816 
01817   template <typename L1, typename L2, typename L3, typename L4, typename L5, typename L6, typename L7, typename L8>
01818   result_type
01819   operator()(const L1& l1, const L2& l2, const L3& l3, const L4& l4, const L5& l5, const L6& l6, const L7& l7, const L8& l8) const
01820   {
01821     CGAL_BRANCH_PROFILER(std::string(" failures/calls to   : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
01822     Protect_FPU_rounding<Protection> P;
01823     try {
01824       return Handle(new Lazy_rep_8<AC, EC, E2A, L1, L2, L3, L4, L5, L6, L7, L8>(ac, ec, l1, l2, l3, l4, l5, l6, l7, l8));
01825     } catch (Uncertain_conversion_exception) {
01826       CGAL_BRANCH_PROFILER_BRANCH(tmp);
01827       Protect_FPU_rounding<!Protection> P2(CGAL_FE_TONEAREST);
01828       return Handle(new Lazy_rep_0<AT,ET,E2A>(ec(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3), CGAL::exact(l4), CGAL::exact(l5), CGAL::exact(l6), CGAL::exact(l7), CGAL::exact(l8))));
01829     }
01830   }
01831 
01832 };
01833 
01834 CGAL_END_NAMESPACE
01835 
01836 #endif // CGAL_LAZY_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines