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