BWAPI
|
00001 // Copyright (c) 1997 Tel-Aviv University (Israel). 00002 // All rights reserved. 00003 // 00004 // This file is part of CGAL (www.cgal.org); you may redistribute it under 00005 // the terms of the Q Public License version 1.0. 00006 // See the file LICENSE.QPL distributed with CGAL. 00007 // 00008 // Licensees holding a valid commercial license may use this file in 00009 // accordance with the commercial license agreement provided with the software. 00010 // 00011 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00012 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00013 // 00014 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Td_dag.h $ 00015 // $Id: Td_dag.h 41714 2008-01-20 20:24:20Z spion $ 00016 // 00017 // 00018 // Author(s) : Iddo Hanniel <hanniel@math.tau.ac.il> 00019 // Oren Nechushtan <theoren@math.tau.ac.il> 00020 00021 /* Directed acyclic binary graph template class */ 00022 00023 #ifndef CGAL_TD_DAG_H 00024 #define CGAL_TD_DAG_H 00025 00026 #include <CGAL/basic.h> 00027 #include <CGAL/number_utils.h> 00028 #include <CGAL/kernel_assertions.h> 00029 #include <CGAL/Handle.h> 00030 00031 #include <cstdlib> 00032 #include <iostream> 00033 #include <list> 00034 #include <functional> 00035 00036 CGAL_BEGIN_NAMESPACE 00037 00038 template<class T> 00039 class Td_dag_base : public Handle 00040 { 00041 public: //iddo (for CC-7.2) maybe protected? 00042 typedef T * pointer; 00043 typedef T & reference; 00044 typedef const T & const_reference; 00045 00046 protected: 00047 void init() { PTR = 0; } 00048 00049 public: 00050 Td_dag_base() {init();} 00051 Td_dag_base(const Td_dag_base<T> & x) : Handle(x) {} 00052 Td_dag_base & operator=(const Td_dag_base<T> & x) 00053 {Handle::operator=(x); return *this; } 00054 bool operator!() const { return PTR == 0; } 00055 }; 00056 00057 template<class T> 00058 class Td_dag : public Td_dag_base<T> 00059 { 00060 public: 00061 typedef T* pointer; 00062 typedef T& reference; 00063 typedef const T& const_reference; 00064 typedef Td_dag_base<T> Td_dag_handle; 00065 typedef Td_dag<T> Self; 00066 typedef std::list<pointer> list_pointer; 00067 00068 #ifndef CGAL_CFG_USING_BASE_MEMBER_BUG_2 00069 public: 00070 using Td_dag_handle::PTR; 00071 using Td_dag_handle::operator!; 00072 #endif 00073 00074 protected: 00075 class node : public Rep 00076 { 00077 friend class Td_dag<T>; 00078 public: 00079 node(const T& e,unsigned long _depth=0) : 00080 data(e),leftPtr(),rightPtr(),depth_(_depth){} 00081 node(const T& e, const Td_dag_handle& left, 00082 const Td_dag_handle& right,unsigned long _depth=0) : 00083 data(e),leftPtr(left),rightPtr(right),depth_(_depth){} 00084 // node(const T& e) : data(e),leftPtr(),rightPtr(){} 00085 // node(const T& e, const Td_dag_handle& left, 00086 // const Td_dag_handle& right) : data(e),leftPtr(left),rightPtr(right) {} 00087 ~node(){} 00088 bool is_inner_node() const {return !!leftPtr && !!rightPtr;} 00089 bool visited() const {return visited_;} 00090 protected: 00091 T data; // information stored in node 00092 Td_dag_handle leftPtr,rightPtr; 00093 mutable unsigned long depth_; 00094 mutable bool visited_; 00095 }; 00096 00097 public: 00098 /* -------constructors destructors -----*/ 00099 Td_dag(){} 00100 Td_dag(const Td_dag_handle& dag):Td_dag_handle(dag){} 00101 Td_dag(const Self& dag):Td_dag_handle(dag){} 00102 Td_dag(const T& rootValue){PTR = new node(rootValue);} 00103 Td_dag(const T& rootValue, const Self& left, const Self& right) 00104 {PTR = new node(rootValue, left, right); rebalance_depth();} 00105 ~Td_dag(){} 00106 00107 /* --------information retrieval -------*/ 00108 const Self& left() const 00109 { 00110 CGAL_precondition(!operator!()); 00111 return *(const Self*)&ptr()->leftPtr; 00112 00113 } 00114 const Self& right() const 00115 { 00116 CGAL_precondition(!operator!()); 00117 return *(const Self*)&ptr()->rightPtr; 00118 } 00119 reference get_data() const 00120 { 00121 CGAL_precondition(!operator!()); 00122 return ptr()->data; 00123 } 00124 reference operator*() const 00125 { 00126 return get_data(); 00127 } 00128 pointer data_ptr() const 00129 { 00130 CGAL_precondition(!operator!()); 00131 return &operator*(); 00132 } 00133 pointer operator->() const 00134 { 00135 return data_ptr(); 00136 } 00137 bool is_inner_node() const 00138 {return !operator!() && ptr()->is_inner_node();} 00139 unsigned long size() const 00140 { 00141 visit_none(); 00142 return recursive_size(); 00143 } 00144 unsigned long depth() const 00145 { 00146 visit_none(); 00147 return recursive_depth(); 00148 } 00149 bool operator==(const Self& b) const 00150 { 00151 return PTR==b.PTR; 00152 } 00153 bool operator!=(const Self& b) const 00154 { 00155 return !operator==(b); 00156 } 00157 /* dynamic management ---------*/ 00158 00159 /* description: 00160 Shallow copy */ 00161 Self& operator=(const Self& b) 00162 { 00163 Handle::operator=(b); 00164 return *this; 00165 } 00166 /* 00167 Self& deep_copy(const Self& b) 00168 { 00169 if (this != &b) 00170 { 00171 clear(); 00172 operator=(b); 00173 } 00174 return *this; 00175 } 00176 void clear() 00177 { 00178 if (!operator!()) 00179 { 00180 left().clear(); 00181 right().clear(); 00182 operator=(Self()); 00183 } 00184 } 00185 void detach_left() 00186 { 00187 if (!operator!()) 00188 { 00189 // create dummy Td_dag 00190 T tmp; 00191 Self dummy(tmp); 00192 // detach left son,redirect to dummy 00193 set_left(dummy); 00194 // set left son pointer to 0 00195 ptr()->leftPtr.PTR=0; 00196 // delete dummy Td_dag 00197 delete dummy.ptr(); 00198 } 00199 } 00200 void detach_right() 00201 { 00202 if (!operator!()) 00203 { 00204 // create dummy Td_dag 00205 T tmp; 00206 Self dummy(tmp); 00207 // detach right son,redirect to dummy 00208 set_right(dummy); 00209 // set right son pointer to 0 00210 ptr()->rightPtr.PTR=0; 00211 // delete dummy Td_dag 00212 delete dummy.ptr(); 00213 } 00214 } 00215 void detach() 00216 { 00217 detach_left(); 00218 detach_right(); 00219 } 00220 */ 00221 void set_data(const T& data) 00222 { 00223 if (!operator!()) ptr()->data=data; 00224 else operator=(Self(data)); 00225 } 00226 void set_depth(unsigned long _depth) const 00227 { 00228 ptr()->depth_=_depth; 00229 } 00230 void set_left(const Self& left) 00231 { 00232 CGAL_precondition(!operator!()); 00233 ptr()->leftPtr=left; 00234 if (left.depth()<depth()+1) left.ptr()->depth_=depth()+1; 00235 left.rebalance_depth(); 00236 // does nothing if right is a leaf 00237 } 00238 void set_right(const Self& right) 00239 { 00240 CGAL_precondition(!operator!()); 00241 ptr()->rightPtr=right; 00242 if (right.depth()<depth()+1) right.ptr()->depth_=depth()+1; 00243 right.rebalance_depth(); 00244 // does nothing if right is a leaf 00245 } 00246 void replace(const T& data,const Self& left,const Self& right) 00247 { 00248 set_data(data); 00249 set_left(left); 00250 set_right(right); 00251 } 00252 00253 // Td_dag implementation not thread safe! 00254 void visit_none() const 00255 { 00256 if (!operator!()) 00257 { 00258 ptr()->visited_=false; 00259 left().visit_none(); 00260 right().visit_none(); 00261 } 00262 } 00263 void visit_one() const 00264 { 00265 if (!operator!()) 00266 ptr()->visited_=true; 00267 } 00268 /* -----output ---------------*/ 00269 #ifdef CGAL_PRE_IN_POST_ORDER 00270 void preorder() const 00271 { 00272 if (!operator!()) 00273 { 00274 std::cout << operator*() << '\t'; 00275 left().preorder(); 00276 right().preorder(); 00277 } 00278 } 00279 void inorder() const 00280 { 00281 if (!operator!()) 00282 { 00283 left().inorder(); 00284 std::cout << operator*() << '\t'; 00285 right().inorder(); 00286 } 00287 } 00288 void postorder() const 00289 { 00290 if (!operator!()) 00291 { 00292 left().postorder(); 00293 right().postorder(); 00294 std::cout << operator*() << '\t'; 00295 } 00296 } 00297 #endif 00298 00299 template <class Container,class Predicate> 00300 Container& filter(Container& c,const Predicate& pr) const 00301 { 00302 visit_none(); 00303 return recursive_filter(c,pr); 00304 } 00305 #if 0 00306 template <class Container,class Predicate> 00307 Container& hash_filter(Container& c,const Predicate& pr) const 00308 { 00309 visit_none(); 00310 return recursive_hash_filter(c,pr); 00311 } 00312 #endif 00313 protected: 00314 void rebalance_depth() const 00315 { 00316 if (is_inner_node()) 00317 { 00318 unsigned long depth_=depth(); 00319 if (left().depth()<depth_+1) 00320 { 00321 left().set_depth(depth_+1); 00322 left().rebalance_depth(); 00323 } 00324 if (right().depth()<depth_+1) 00325 { 00326 right().set_depth(depth_+1); 00327 right().rebalance_depth(); 00328 } 00329 } 00330 } 00331 00332 unsigned long recursive_size() const 00333 { 00334 if (!operator!() && !ptr()->visited()) 00335 return 1+left().recursive_size()+right().recursive_size(); 00336 else 00337 return 0; 00338 } 00339 unsigned long recursive_depth() const 00340 { 00341 if (!operator!() && !ptr()->visited()) 00342 return 1+ (std::max)(left().recursive_depth(),right().recursive_depth()); 00343 else 00344 return 0; 00345 } 00346 template <class Container,class Predicate> 00347 Container& recursive_filter(Container& c,const Predicate& pr) const 00348 { 00349 if (!operator!() && !ptr()->visited()) 00350 { 00351 if (pr(operator*())) 00352 c.insert(c.end(),operator*()); 00353 visit_one(); 00354 left().recursive_filter(c,pr); 00355 right().recursive_filter(c,pr); 00356 } 00357 return c; 00358 } 00359 #if 0 00360 template <class Container, class Predicate> 00361 Container& recursive_hash_filter(Container& c, const Predicate& ptr) const 00362 /* Generate a copy of the Dag filtered according to the predicate */ 00363 { 00364 if (!operator!() && !ptr()->visited()) 00365 { 00366 if (pr(operator*())) 00367 c.insert(pair<&operator*(), new X_trapezoid(operator*())); 00368 // The hash links between the old trapezoid to the new one. 00369 visit_one(); 00370 left().recursive_hash_filter(c,pr); 00371 right().recursive_hash_filter(c,pr); 00372 } 00373 return c; 00374 } 00375 #endif 00376 private: 00377 node* ptr() const {return (node*)PTR;} 00378 }; 00379 00380 template<class T,class Traits> 00381 std::ostream& write(std::ostream& out, 00382 const Td_dag<T>& t, 00383 const Traits& traits) 00384 { 00385 static int depth; 00386 int i; 00387 if (!!t) { 00388 out << "\n"; 00389 for(i=0;i<depth;i++)out << ">"; 00390 out << "Data="; 00391 write(out,*t,traits); 00392 { 00393 depth++; 00394 out << "\n"; 00395 for(i=0;i<depth;i++)out << ">"; 00396 out << "left="; 00397 write(out,t.left(),traits); 00398 out << "\n"; 00399 for(i=0;i<depth;i++)out << ">"; 00400 out << "right="; 00401 write(out,t.right(),traits); 00402 depth--; 00403 } 00404 } 00405 else 00406 { 00407 out << "Empty"; 00408 } 00409 return out ; 00410 } 00411 00412 template<class T> std::ostream& operator<<(std::ostream& out, 00413 const Td_dag<T>& t) 00414 { 00415 static int depth; 00416 int i; 00417 if (!!t) { 00418 out << "\n"; 00419 for(i=0;i<depth;i++)out << ">"; 00420 out << "Data=" << *t; 00421 { 00422 depth++; 00423 out << "\n"; 00424 for(i=0;i<depth;i++)out << ">"; 00425 out << "left=" << t.left(); 00426 out << "\n"; 00427 for(i=0;i<depth;i++)out << ">"; 00428 out << "right=" <<t.right(); 00429 depth--; 00430 } 00431 } 00432 else 00433 { 00434 out << "Empty"; 00435 } 00436 return out ; 00437 } 00438 00439 CGAL_END_NAMESPACE 00440 00441 #endif 00442 00443 /* 00444 tech notes: 00445 The code is Handle designed. 00446 left(),right() are designed to cope with Handle(Handle& x) 00447 precondition x.PTR!=0 00448 operator=() performs shallow copy 00449 operator*() returns data type 00450 output is done as a binary tree. 00451 */