BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Segment_Delaunay_graph_2/edge_list.h
Go to the documentation of this file.
00001 // Copyright (c) 2003,2004,2005  INRIA Sophia-Antipolis (France) and
00002 // Notre Dame University (U.S.A.).  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/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_2/edge_list.h $
00015 // $Id: edge_list.h 28567 2006-02-16 14:30:13Z lsaboret $
00016 // 
00017 //
00018 // Author(s)     : Menelaos Karavelas <mkaravel@cse.nd.edu>
00019 
00020 #ifndef CGAL_SEGMENT_DELAUNAY_GRAPH_2_EDGE_LIST_H
00021 #define CGAL_SEGMENT_DELAUNAY_GRAPH_2_EDGE_LIST_H
00022 
00023 
00024 #include <CGAL/Unique_hash_map.h>
00025 #include <CGAL/Edge_hash_function.h>
00026 #include <CGAL/circulator_bases.h>
00027 
00028 CGAL_BEGIN_NAMESPACE
00029 
00030 
00031 namespace CGALi {
00032 
00033   template<class Edge_t>
00034   class Edge_list_item
00035   {
00036   public:
00037     typedef Edge_t                      Edge;
00038 
00039   private:
00040     typedef typename Edge::first_type   Face_handle;
00041 
00042   private:
00043     Edge prev_;
00044     Edge next_;
00045 
00046   public:
00047     // remove the following method and make SENTINEL_EDGE a static const
00048     // member of the class.
00049     static const Edge& sentinel_edge() {
00050       static Edge SENTINEL_EDGE = Edge(Face_handle(), sentinel_index());
00051       return SENTINEL_EDGE;
00052     }
00053 
00054   private:
00055     static int sentinel_index() { return -1; }
00056 
00057   public:
00058     Edge_list_item()
00059       : prev_(sentinel_edge()), next_(sentinel_edge()) {}
00060     Edge_list_item(const Edge& prev, const Edge& next)
00061       : prev_(prev), next_(next) {}
00062 
00063 
00064     bool is_in_list() const
00065     {
00066       return ( next_.second != sentinel_index() ||
00067                prev_.second != sentinel_index() );
00068     }
00069 
00070     void set_next(const Edge& next)
00071     {
00072       next_ = next;
00073     }
00074 
00075     void set_previous(const Edge& prev)
00076     {
00077       prev_ = prev;
00078     }
00079 
00080     const Edge& next()     const { return next_; }
00081     const Edge& previous() const { return prev_; }
00082 
00083     void reset() {
00084       Edge SENTINEL_EDGE = sentinel_edge();
00085       next_ = prev_ = SENTINEL_EDGE;
00086     }
00087   };
00088 
00089 
00090   
00091   template<class E_t, class ListItem, class USE_STL_MAP_Tag>
00092   struct Edge_list_which_map;
00093 
00094   // use STL's map
00095   template<class E_t, class ListItem>
00096   struct Edge_list_which_map<E_t,ListItem,Tag_true>
00097   {
00098     typedef E_t                       Edge;
00099     typedef ListItem                  List_item;
00100     typedef std::map<Edge,List_item>  Edge_map;
00101   };
00102 
00103   // use CGAL's Unique_hash_map
00104   template<class E_t, class ListItem>
00105   struct Edge_list_which_map<E_t,ListItem,Tag_false>
00106   {
00107     typedef E_t                         Edge;
00108     typedef ListItem                    List_item;
00109     typedef CGAL::Edge_hash_function    Hash_function;
00110 
00111     typedef Unique_hash_map<Edge,List_item,Hash_function>  Edge_map;
00112   };
00113 
00114 
00115   template<class Edge_list_t>
00116   class Edge_list_circulator
00117     : public CGAL::Bidirectional_circulator_base<typename Edge_list_t::Edge>
00118   {
00119   private:
00120     typedef Edge_list_t                                 List;
00121     typedef typename List::Edge                         Edge;
00122     typedef Edge_list_item<Edge>                        List_item;
00123     typedef CGAL::Bidirectional_circulator_base<Edge>   Base;
00124 
00125     typedef Edge_list_circulator<List>                  Self;
00126 
00127   public:
00128     Edge_list_circulator()
00129       : l_(NULL), c_(List_item::sentinel_edge()) {}
00130 
00131     Edge_list_circulator(const List* l, const Edge& c)
00132       : l_(l), c_(/*const_cast<Edge&>(*/c/*)*/) {}
00133 
00134     Edge_list_circulator(const Edge_list_circulator& other)
00135       : l_(other.l_), c_(other.c_) {}
00136 
00137     Edge_list_circulator& operator=(const Edge_list_circulator& other) {
00138       l_ = other.l_;
00139       c_ = other.c_;
00140       return *this;
00141     }
00142 
00143     Self& operator++() {
00144       CGAL_precondition( l_ != NULL );
00145       //      c_ = const_cast<Edge&>(l_->next(c_));
00146       c_ = l_->next(c_);
00147       return *this;
00148     }
00149 
00150     Self& operator--() {
00151       CGAL_precondition( l_ != NULL );
00152       //      c_ = const_cast<Edge&>(l_->previous(c_));
00153       c_ = l_->previous(c_);
00154       return *this;
00155     }
00156 
00157     Self operator++(int) {
00158       Self tmp(*this);
00159       ++tmp;
00160       return tmp;
00161     }
00162 
00163     Self operator--(int) {
00164       Self tmp(*this);
00165       --tmp;
00166       return tmp;
00167     }
00168 
00169     typename Base::pointer   operator->() { return &c_; }
00170     typename Base::reference operator*() { return c_; }
00171 
00172     bool operator==(const Self& other) const {
00173       return l_ == other.l_ && c_ == other.c_;
00174     }
00175 
00176     bool operator!=(const Self& other) const {
00177       return l_ != other.l_ || c_ != other.c_;
00178     }
00179 
00180   protected:
00181     const List* l_;
00182     //    Edge& c_;
00183     Edge c_;
00184   };
00185 
00186 
00187 } // namespace CGALi
00188 
00189 
00190 
00191 template<class Edge_t, class USE_STL_MAP_Tag = Tag_true>
00192 class Edge_list
00193 {
00194 public:
00195   // TYPES
00196   //======
00197   typedef std::size_t       size_type;
00198   typedef Edge_t            Edge;
00199   typedef USE_STL_MAP_Tag   Use_stl_map_tag;
00200 
00201 private:
00202   typedef CGALi::Edge_list_item<Edge>  List_item;
00203 
00204   typedef
00205   CGALi::Edge_list_which_map<Edge,List_item,Use_stl_map_tag>
00206   Which_map;
00207 
00208   typedef typename Which_map::Edge_map  Edge_map;
00209 
00210   typedef Edge_list<Edge,Use_stl_map_tag>  Self;
00211 
00212 public:
00213   typedef CGALi::Edge_list_circulator<Self>  circulator;
00214 
00215 private:
00216   // PRIVATE DATA MEMBERS
00217   //=====================
00218   Edge_map             emap;
00219   Edge                 front_;
00220   size_type            size_;
00221 
00222 private:
00223   // PRIVATE METHODS
00224   //================
00225   void increase_size() {
00226     size_++;
00227   }
00228 
00229   void decrease_size() {
00230     size_--;
00231   }
00232 
00233   void insert_before_nocheck(const Edge& e, const Edge& new_e) {
00234     List_item& li_e = emap[e];
00235 
00236     const Edge& prev_e = li_e.previous();
00237     List_item& li_prev_e = emap[prev_e];
00238 
00239     emap[new_e] = List_item(prev_e, e);
00240     li_e.set_previous(new_e);
00241     li_prev_e.set_next(new_e);
00242     increase_size();
00243   }
00244 
00245   // check whether the edge is in the list;
00246   // the map used is STL's map 
00247   bool is_in_list_with_tag(const Edge& e, const Tag_true&) const
00248   {
00249     if ( emap.find(e) == emap.end() ) { return false; }
00250     return emap.find(e)->second.is_in_list();    
00251   }
00252 
00253   // check whether the edge is in the list;
00254   // the map used is CGAL's Unique_hash_map 
00255   bool is_in_list_with_tag(const Edge& e, const Tag_false&) const
00256   {
00257     if ( !emap.is_defined(e) ) { return false; }
00258     return emap[e].is_in_list();
00259   }
00260 
00261   // return the next edge in the list;
00262   // the map used is STL's map 
00263   const Edge& next_with_tag(const Edge& e, const Tag_true&) const
00264   {
00265     return emap.find(e)->second.next();
00266   }
00267 
00268   // return the next edge in the list;
00269   // the map used is CGAL's Unique_hash_map 
00270   const Edge& next_with_tag(const Edge& e, const Tag_false&) const
00271   {
00272     return emap[e].next();
00273   }
00274 
00275   // return the previous edge in the list;
00276   // the map used is STL's map 
00277   const Edge& previous_with_tag(const Edge& e, const Tag_true&) const
00278   {
00279     return emap.find(e)->second.previous();
00280   }
00281 
00282   // return the previous edge in the list;
00283   // the map used is CGAL's Unique_hash_map 
00284   const Edge& previous_with_tag(const Edge& e, const Tag_false&) const
00285   {
00286     return emap[e].previous();
00287   }
00288 
00289 public:
00290   // CONSTRUCTOR
00291   //============
00292 #ifdef _MSC_VER
00293   Edge_list(const Edge& e = Edge(typename Edge::first_type(),-1) )
00294     : emap(), front_(e), size_(0) {}
00295 #else
00296   Edge_list(const Edge& e = List_item::sentinel_edge() )
00297     : emap(), front_(e), size_(0) {}
00298 #endif
00299 
00300   // PREDICATES
00301   //===========
00302   bool is_valid() const { return true; }
00303 
00304   bool is_in_list(const Edge& e) const {
00305     static Use_stl_map_tag  map_tag;
00306     return is_in_list_with_tag(e, map_tag);
00307   }
00308 
00309 
00310   // ACCESS METHODS
00311   //===============
00312   size_type size() const {
00313     return size_;
00314   }
00315 
00316   const Edge& next(const Edge& e) const {
00317     CGAL_precondition( is_in_list(e) );
00318     static Use_stl_map_tag  map_tag;
00319     return next_with_tag(e, map_tag);
00320   }
00321 
00322   const Edge& previous(const Edge& e) const {
00323     CGAL_precondition( is_in_list(e) );
00324     static Use_stl_map_tag  map_tag;
00325     return previous_with_tag(e, map_tag);
00326   }
00327 
00328   const Edge& front() const {
00329     CGAL_precondition( size() > 0 );
00330     return front_;
00331   }
00332 
00333   const Edge& back() const {
00334     CGAL_precondition( size() > 0 );
00335     return previous(front_);
00336   }
00337 
00338 
00339   // INSERTION
00340   //==========
00341   void push_front(const Edge& e) {
00342     push_back(e);
00343     front_ = e;
00344   }
00345 
00346   void push_back(const Edge& e) {
00347     CGAL_precondition( !is_in_list(e) );
00348 
00349     if ( size() == 0 ) {
00350       emap[e] = List_item(e,e);
00351       front_ = e;
00352       increase_size();
00353       return;
00354     }
00355 
00356     insert_before_nocheck(front_, e);
00357   }
00358 
00359   void insert_after(const Edge& e, const Edge& new_e) {
00360     CGAL_precondition( is_in_list(e) );
00361     CGAL_precondition( !is_in_list(new_e) );
00362 
00363     List_item& li_e = emap[e];
00364 
00365     const Edge& next_e = li_e.next();
00366     List_item& li_next_e = emap[next_e];
00367 
00368     emap[new_e] = List_item(e, next_e);
00369     li_e.set_next(new_e);
00370     li_next_e.set_previous(new_e);
00371     increase_size();
00372   }
00373 
00374   void insert_before(const Edge& e, const Edge& new_e) {
00375     CGAL_precondition( is_in_list(e) );
00376     CGAL_precondition( !is_in_list(new_e) );
00377     insert_before_nocheck(e, new_e);
00378   }
00379 
00380 
00381   // REPLACEMENT
00382   //============
00383   void replace(const Edge& e, const Edge& new_e) {
00384     CGAL_precondition( is_in_list(e) );
00385     CGAL_precondition( !is_in_list(new_e) );
00386 
00387     List_item& li_e = emap[e];
00388 
00389     if ( size() == 1 ) {
00390       emap[new_e] = List_item(new_e, new_e);
00391       front_ = new_e;
00392       li_e.reset();
00393     }
00394 
00395     const Edge& next_e = li_e.next();
00396     const Edge& prev_e = li_e.previous();
00397 
00398     emap[prev_e].set_next(new_e);
00399     emap[next_e].set_previous(new_e);
00400 
00401     emap[new_e] = List_item(prev_e, next_e);
00402 
00403     li_e.reset();
00404 
00405     if ( e == front_ ) {
00406       front_ = new_e;
00407     }
00408   }
00409 
00410 
00411   // REMOVAL
00412   //========
00413 
00414   void remove(const Edge& e) {
00415     CGAL_precondition( is_in_list(e) );
00416 
00417     if ( size() == 1 ) {
00418       front_ = List_item::sentinel_edge();
00419       emap[e].reset();
00420       decrease_size();
00421       return;
00422     }
00423 
00424     List_item& li_e = emap[e];
00425     const Edge& next_e = li_e.next();
00426     const Edge& prev_e = li_e.previous();
00427 
00428     emap[prev_e].set_next(next_e);
00429     emap[next_e].set_previous(prev_e);
00430 
00431     if ( e == front_ ) {
00432       //      front_ = next_e;
00433       front_ = next_e;
00434     }
00435 
00436     li_e.reset();
00437 
00438     decrease_size();
00439   }
00440 
00441 #if 0
00442   // ACCESS TO CIRCULATOR
00443   //=====================
00444   inline circulator start() const {
00445     return start(front());
00446   }
00447 
00448   inline circulator start(const Edge& start) const {
00449     CGAL_precondition( is_in_list(start) );
00450     return circulator(this, start);
00451   }
00452 #endif
00453 
00454   // MISCELLANEOUS
00455   //==============
00456   void clear() {
00457     emap.clear();
00458   }
00459 };
00460 
00461 CGAL_END_NAMESPACE
00462 
00463 
00464 #endif // CGAL_SEGMENT_DELAUNAY_GRAPH_2_EDGE_LIST_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines