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