BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Arr_dcel_base.h
Go to the documentation of this file.
00001 // Copyright (c) 2006  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_dcel_base.h $
00015 // $Id: Arr_dcel_base.h 46826 2008-11-12 08:37:24Z lrineau $
00016 // 
00017 //
00018 // Author(s)     : Ron Wein <wein@post.tau.ac.il>
00019 //                 (based on old version by: Iddo Hanniel and Oren Nechushtan)
00020 
00021 #ifndef CGAL_ARR_DCEL_BASE_H
00022 #define CGAL_ARR_DCEL_BASE_H
00023 
00029 #include <CGAL/basic.h>
00030 #include <CGAL/Arr_enums.h>
00031 #include <list>
00032 #include <map>
00033 #include <CGAL/N_step_adaptor_derived.h>
00034 #include <CGAL/In_place_list.h>
00035 #include <CGAL/function_objects.h>
00036 #include <CGAL/Iterator_project.h>
00037 #include <CGAL/Arrangement_2/Arrangement_2_iterators.h>
00038 
00039 CGAL_BEGIN_NAMESPACE
00040 
00041 inline void* _clean_pointer (const void* p)
00042 {
00043   const size_t  mask = ~1;
00044   const size_t  val = (reinterpret_cast<size_t>(p) & mask);
00045 
00046   return (reinterpret_cast<void*> (val));
00047 }
00048 
00049 inline void* _set_lsb (const void* p)
00050 {
00051   const size_t  mask = 1;
00052   const size_t  val = (reinterpret_cast<size_t>(p) | mask);
00053 
00054   return (reinterpret_cast<void*> (val));
00055 }
00056 
00057 inline bool _is_lsb_set (const void* p)
00058 {
00059   const size_t  mask = 1;
00060   const size_t  val = reinterpret_cast<size_t>(p);
00061 
00062   return ((val & mask) != 0); 
00063 }
00064 
00068 template <class Point_> class Arr_vertex_base 
00069 {
00070 public:
00071 
00072   typedef Point_       Point;
00073 
00077   template<typename PNT>
00078   struct rebind
00079   {
00080     typedef Arr_vertex_base<PNT>             other;
00081   };
00082 
00083 protected:
00084 
00085   void       *p_inc;  // An incident halfedge pointing at the vertex,
00086                       // or the isolated vertex information (in case it is
00087                       // isolated). The LSB of the pointer indicates whether
00088                       // the vertex is isolated.
00089   Point      *p_pt;   // The point associated with the vertex.
00090   char        pss[2]; // The x and y parameter spaces (condensed in two bytes).
00091 
00092 public:
00093 
00095   Arr_vertex_base() :
00096     p_inc (NULL),
00097     p_pt (NULL)
00098   {
00099     pss[0] = pss[1] = static_cast<char> (CGAL::ARR_INTERIOR);
00100   }
00101   
00103   virtual ~Arr_vertex_base() {}
00104 
00106   bool has_null_point () const
00107   {
00108     return (p_pt == NULL);
00109   }
00110 
00112   const Point& point() const 
00113   {
00114     CGAL_assertion (p_pt != NULL);
00115     return (*p_pt);
00116   }
00117 
00119   Point& point() 
00120   { 
00121     CGAL_assertion (p_pt != NULL);
00122     return (*p_pt);
00123   }
00124 
00126   void set_point (Point *p) 
00127   {
00128     p_pt = p;
00129   }
00130 
00132   Arr_parameter_space parameter_space_in_x () const
00133   {
00134     return (Arr_parameter_space (pss[0]));
00135   }
00136 
00138   Arr_parameter_space parameter_space_in_y () const
00139   {
00140     return (Arr_parameter_space (pss[1]));
00141   }
00142 
00144   void set_boundary (Arr_parameter_space ps_x, Arr_parameter_space ps_y)
00145   {
00146     pss[0] = static_cast<char> (ps_x);
00147     pss[1] = static_cast<char> (ps_y);
00148     return;
00149   }
00150 
00152   virtual void assign (const Arr_vertex_base<Point>& v)
00153   {
00154     p_pt = v.p_pt;
00155     pss[0] = v.pss[0];
00156     pss[1] = v.pss[1];
00157   }
00158 };
00159 
00163 template <class X_monotone_curve_> class Arr_halfedge_base 
00164 {
00165 public:
00166 
00167   typedef X_monotone_curve_  X_monotone_curve;
00168 
00172   template<typename XCV>
00173   struct rebind
00174   {
00175     typedef Arr_halfedge_base<XCV>           other;
00176   };
00177 
00178 protected:
00179 
00180   void       *p_opp;   // The opposite halfedge.
00181   void       *p_prev;  // The previous halfedge in the component boundary.
00182   void       *p_next;  // The next halfedge in the component boundary.
00183 
00184   void       *p_v;     // The incident vertex (the target of the halfedge).
00185                        // The LSB of this pointer is used to store the
00186                        // direction of the halfedge.
00187   void       *p_comp;  // The component this halfedge belongs to: the incident
00188                        // face for outer CCBs and the inner CCB information for
00189                        // inner CCBs. The LSB of the pointer indicates whether
00190                        // the halfedge lies on the boundary of an inner CCB.
00191   
00192   X_monotone_curve *p_cv; // The associated x-monotone curve.
00193 
00194 public:
00195 
00197   Arr_halfedge_base() :
00198     p_opp (NULL),
00199     p_prev (NULL),
00200     p_next (NULL),
00201     p_v (NULL),
00202     p_comp (NULL),
00203     p_cv (NULL)
00204   {}
00205 
00207   virtual ~Arr_halfedge_base()
00208   {}
00209 
00211   bool has_null_curve () const
00212   {
00213     return (p_cv == NULL);
00214   }
00215 
00217   const X_monotone_curve& curve() const 
00218   {
00219     CGAL_precondition (p_cv != NULL);
00220     return (*p_cv);
00221   }
00222 
00224   X_monotone_curve& curve () 
00225   {
00226     CGAL_precondition (p_cv != NULL);
00227     return (*p_cv);
00228   }
00229 
00231   void set_curve (X_monotone_curve* c)
00232   { 
00233     p_cv = c;
00234 
00235     // Set the curve for the opposite halfedge as well.
00236     Arr_halfedge_base<X_monotone_curve>* opp =
00237       reinterpret_cast<Arr_halfedge_base<X_monotone_curve>* > (p_opp);
00238 
00239     opp->p_cv = c;
00240   }
00241 
00243   virtual void assign (const Arr_halfedge_base<X_monotone_curve>& he)
00244   {
00245     p_cv = he.p_cv;
00246   }
00247 };
00248 
00252 class Arr_face_base
00253 {
00254 public:
00255 
00256   typedef std::list<void*>                      Outer_ccbs_container;
00257   typedef Outer_ccbs_container::iterator        Outer_ccb_iterator;
00258   typedef Outer_ccbs_container::const_iterator  Outer_ccb_const_iterator;
00259 
00260   typedef std::list<void*>                      Inner_ccbs_container;
00261   typedef Inner_ccbs_container::iterator        Inner_ccb_iterator;
00262   typedef Inner_ccbs_container::const_iterator  Inner_ccb_const_iterator;
00263 
00264   typedef std::list<void*>                      Isolated_vertices_container;
00265   typedef Isolated_vertices_container::iterator Isolated_vertex_iterator;
00266   typedef Isolated_vertices_container::const_iterator
00267                                                 Isolated_vertex_const_iterator;
00268 
00269 protected:
00270 
00271   enum
00272   {
00273     IS_UNBOUNDED = 1,
00274     IS_FICTITIOUS = 2
00275   };
00276 
00277   int                          flags;      // Face flags.
00278   Outer_ccbs_container         outer_ccbs; // The outer CCBs of the faces.
00279   Inner_ccbs_container         inner_ccbs; // The holes inside the face.
00280   Isolated_vertices_container  iso_verts;  // The isolated vertices inside
00281                                            // the face.
00282 
00283 public:
00284 
00286   Arr_face_base() :
00287     flags (0)
00288   {}
00289 
00291   virtual ~Arr_face_base()
00292   {}
00293 
00295   bool is_unbounded () const
00296   {
00297     return ((flags & IS_UNBOUNDED) != 0);
00298   }
00299 
00301   void set_unbounded (bool unbounded)
00302   {
00303     flags = (unbounded) ? (flags | IS_UNBOUNDED) : (flags & ~IS_UNBOUNDED);
00304   }
00305 
00307   bool is_fictitious () const
00308   {
00309     return ((flags & IS_FICTITIOUS) != 0);
00310   }
00311 
00313   void set_fictitious (bool fictitious)
00314   {
00315     flags = (fictitious) ? (flags | IS_FICTITIOUS) : (flags & ~IS_FICTITIOUS);
00316   }
00317 
00319   virtual void assign (const Arr_face_base& f)
00320   {
00321     flags = f.flags;
00322   }
00323 };
00324 
00325 // Forward declarations:
00326 template <class V, class H, class F> class Arr_vertex;
00327 template <class V, class H, class F> class Arr_halfedge;
00328 template <class V, class H, class F> class Arr_face;
00329 template <class V, class H, class F> class Arr_outer_ccb;
00330 template <class V, class H, class F> class Arr_inner_ccb;
00331 template <class V, class H, class F> class Arr_isolated_vertex;
00332 
00336 template <class V, class H, class F>
00337 class Arr_vertex : public V,
00338                    public In_place_list_base<Arr_vertex<V,H,F> >
00339 {
00340 public:
00341 
00342   typedef V                           Base;
00343   typedef Arr_vertex<V,H,F>           Vertex;
00344   typedef Arr_halfedge<V,H,F>         Halfedge;
00345   typedef Arr_isolated_vertex<V,H,F>  Isolated_vertex;
00346 
00348   Arr_vertex() 
00349   {}
00350 
00352   bool is_isolated () const
00353   {
00354     // Note that we use the LSB of the p_inc pointer as a Boolean flag.
00355     return (_is_lsb_set (this->p_inc));
00356   }
00357 
00359   const Halfedge* halfedge () const
00360   {
00361     CGAL_precondition (! is_isolated());
00362     return (reinterpret_cast<const Halfedge*>(this->p_inc));
00363   }
00364 
00366   Halfedge* halfedge ()
00367   {
00368     CGAL_precondition (! is_isolated());
00369     return (reinterpret_cast<Halfedge*>(this->p_inc));
00370   }
00371 
00373   void set_halfedge (Halfedge* he)
00374   { 
00375     // Set the halfedge pointer and reset the LSB.
00376     this->p_inc = he;
00377   }
00378 
00380   const Isolated_vertex* isolated_vertex () const
00381   {
00382     CGAL_precondition (is_isolated());
00383     return (reinterpret_cast<const Isolated_vertex*>(_clean_pointer 
00384                                                      (this->p_inc)));
00385   }
00386 
00388   Isolated_vertex* isolated_vertex ()
00389   {
00390     CGAL_precondition (is_isolated());
00391     return (reinterpret_cast<Isolated_vertex*>(_clean_pointer (this->p_inc)));
00392   }
00393 
00395   void set_isolated_vertex (Isolated_vertex* iv)
00396   {
00397     // Set the isolated vertex-information pointer and set its LSB.
00398     this->p_inc = _set_lsb (iv);
00399   }
00400 };
00401 
00405 template <class V, class H, class F>
00406 class Arr_halfedge : public H,
00407                      public In_place_list_base<Arr_halfedge<V,H,F> >
00408 {
00409 public:
00410 
00411   typedef H                     Base;
00412   typedef Arr_vertex<V,H,F>     Vertex;
00413   typedef Arr_halfedge<V,H,F>   Halfedge;
00414   typedef Arr_face<V,H,F>       Face;
00415   typedef Arr_outer_ccb<V,H,F>  Outer_ccb;
00416   typedef Arr_inner_ccb<V,H,F>  Inner_ccb;
00417 
00419   Arr_halfedge()
00420   {}
00421 
00423   const Halfedge* opposite () const
00424   { 
00425     return (reinterpret_cast<const Halfedge*>(this->p_opp));
00426   }
00427   
00429   Halfedge* opposite ()
00430   { 
00431     return (reinterpret_cast<Halfedge*>(this->p_opp));
00432   }
00433 
00435   void set_opposite (Halfedge* he) 
00436   { 
00437     this->p_opp = he;
00438   }
00439 
00441   Arr_halfedge_direction direction () const
00442   {
00443     // Note that we use the LSB of the p_v pointer as a Boolean flag.
00444     if (_is_lsb_set (this->p_v))
00445       return (ARR_LEFT_TO_RIGHT);
00446     else
00447       return (ARR_RIGHT_TO_LEFT);
00448   }
00449 
00451   void set_direction (Arr_halfedge_direction dir)
00452   {
00453     Halfedge*   opp = reinterpret_cast<Halfedge*> (this->p_opp);
00454 
00455     if (dir == ARR_LEFT_TO_RIGHT)
00456     {
00457       this->p_v = _set_lsb (this->p_v);
00458       opp->p_v = _clean_pointer (opp->p_v);
00459     }
00460     else
00461     {
00462       this->p_v = _clean_pointer (this->p_v);
00463       opp->p_v = _set_lsb (opp->p_v);
00464     }
00465   }
00466 
00468   const Halfedge* prev () const
00469   {
00470     return (reinterpret_cast<const Halfedge*>(this->p_prev));
00471   }
00472 
00474   Halfedge* prev ()
00475   {
00476     return (reinterpret_cast<Halfedge*>(this->p_prev));
00477   }
00478 
00480   void set_prev (Halfedge* he)
00481   {
00482     this->p_prev = he;
00483     he->p_next = this;
00484   }
00485 
00487   const Halfedge* next () const
00488   {
00489     return (reinterpret_cast<const Halfedge*>(this->p_next));
00490   }
00491 
00493   Halfedge* next ()
00494   {
00495     return (reinterpret_cast<Halfedge*>(this->p_next));
00496   }
00497 
00499   void set_next (Halfedge* he)
00500   {
00501     this->p_next = he;
00502     he->p_prev = this;
00503   }
00504 
00506   const Vertex* vertex () const 
00507   { 
00508     return (reinterpret_cast<const Vertex*>(_clean_pointer (this->p_v)));
00509   }
00510 
00512   Vertex* vertex ()
00513   { 
00514     return (reinterpret_cast<Vertex*>(_clean_pointer (this->p_v)));
00515   }
00516 
00518   void set_vertex (Vertex* v)
00519   {
00520     // Set the vertex pointer, preserving the content of the LSB.
00521     if (_is_lsb_set (this->p_v))
00522       this->p_v = _set_lsb (v);
00523     else
00524       this->p_v = v;
00525   }
00526 
00528   bool is_on_inner_ccb () const
00529   {
00530     return (_is_lsb_set (this->p_comp));
00531   }
00532 
00537   const Outer_ccb* outer_ccb () const
00538   {
00539     CGAL_precondition (! is_on_inner_ccb());
00540     return (reinterpret_cast<const Outer_ccb*>(this->p_comp));
00541   }
00542 
00547   Outer_ccb* outer_ccb ()
00548   {
00549     CGAL_precondition (! is_on_inner_ccb());
00550     return (reinterpret_cast<Outer_ccb*>(this->p_comp));
00551   }
00552 
00554   void set_outer_ccb (Outer_ccb *oc)
00555   { 
00556     // Set the component pointer and reset its LSB.
00557     this->p_comp = oc;
00558   }
00559 
00564   const Inner_ccb* inner_ccb () const 
00565   {     
00566     CGAL_precondition (is_on_inner_ccb());
00567     return (reinterpret_cast<const Inner_ccb*>(_clean_pointer (this->p_comp)));
00568   }
00569 
00574   Inner_ccb* inner_ccb () 
00575   {
00576     CGAL_precondition (is_on_inner_ccb());
00577     return (reinterpret_cast<Inner_ccb*> (_clean_pointer (this->p_comp)));
00578   }
00579 
00581   void set_inner_ccb (Inner_ccb *ic)
00582   { 
00583     // Set the component pointer and set its LSB.
00584     this->p_comp = _set_lsb (ic);
00585   }
00586 };
00587 
00591 template <class V, class H, class F>
00592 class Arr_face : public F,
00593                  public In_place_list_base<Arr_face<V,H,F> >
00594 {
00595 public:
00596 
00597   typedef F                            Base;
00598   typedef Arr_vertex<V,H,F>            Vertex;
00599   typedef Arr_halfedge<V,H,F>          Halfedge;
00600   typedef Arr_face<V,H,F>              Face;
00601   typedef Arr_outer_ccb<V,H,F>         Outer_ccb;
00602   typedef Arr_inner_ccb<V,H,F>         Inner_ccb;
00603   typedef Arr_isolated_vertex<V,H,F>   Isolated_vertex;
00604 
00605 private:
00606 
00607   typedef Cast_function_object<void*,
00608                                Halfedge*>        _Ccb_to_halfedge_cast;
00609   typedef Cast_function_object<const void*,
00610                                const Halfedge*>  _Const_ccb_to_halfedge_cast;
00611 
00612 
00613 public:
00614 
00616   Arr_face()
00617   {}
00618 
00619   // Definition of the outer CCB iterators:
00620   typedef Iterator_project<typename F::Outer_ccb_iterator, 
00621                            _Ccb_to_halfedge_cast>   Outer_ccb_iterator;
00622 
00623   typedef Iterator_project<typename F::Outer_ccb_const_iterator,
00624                            _Const_ccb_to_halfedge_cast> 
00625                                                     Outer_ccb_const_iterator;
00626 
00628   size_t number_of_outer_ccbs () const
00629   {
00630     return (this->outer_ccbs.size());
00631   }
00632 
00634   Outer_ccb_iterator outer_ccbs_begin()
00635   {
00636     return (this->outer_ccbs.begin());
00637   }
00638 
00640   Outer_ccb_iterator outer_ccbs_end()
00641   {
00642     return (this->outer_ccbs.end());
00643   }
00644 
00646   Outer_ccb_const_iterator outer_ccbs_begin() const
00647   {
00648     return (this->outer_ccbs.begin());
00649   }
00650 
00652   Outer_ccb_const_iterator outer_ccbs_end() const
00653   {
00654     return (this->outer_ccbs.end());
00655   }
00656 
00658   void add_outer_ccb (Outer_ccb *oc, Halfedge *h)
00659   {
00660     oc->set_iterator (this->outer_ccbs.insert (this->outer_ccbs.end(), h));
00661     return;
00662   }
00663 
00665   void erase_outer_ccb (Outer_ccb *oc)
00666   {
00667     this->outer_ccbs.erase (oc->iterator().current_iterator());
00668   }
00669 
00670   // Definition of the inner CCB iterators:
00671   typedef Iterator_project<typename F::Inner_ccb_iterator, 
00672                            _Ccb_to_halfedge_cast>   Inner_ccb_iterator;
00673 
00674   typedef Iterator_project<typename F::Inner_ccb_const_iterator,
00675                            _Const_ccb_to_halfedge_cast> 
00676                                                     Inner_ccb_const_iterator;
00677 
00679   size_t number_of_inner_ccbs () const
00680   {
00681     return (this->inner_ccbs.size());
00682   }
00683 
00685   Inner_ccb_iterator inner_ccbs_begin()
00686   {
00687     return (this->inner_ccbs.begin());
00688   }
00689 
00691   Inner_ccb_iterator inner_ccbs_end()
00692   {
00693     return (this->inner_ccbs.end());
00694   }
00695 
00697   Inner_ccb_const_iterator inner_ccbs_begin() const
00698   {
00699     return (this->inner_ccbs.begin());
00700   }
00701 
00703   Inner_ccb_const_iterator inner_ccbs_end() const
00704   {
00705     return (this->inner_ccbs.end());
00706   }
00707 
00709   void add_inner_ccb (Inner_ccb *ic, Halfedge *h)
00710   {
00711     ic->set_iterator (this->inner_ccbs.insert (this->inner_ccbs.end(), h));
00712     return;
00713   }
00714 
00716   void erase_inner_ccb (Inner_ccb *ic)
00717   {
00718     this->inner_ccbs.erase (ic->iterator().current_iterator());
00719   }
00720 
00721   // Definition of the isloated vertices iterators:
00722   typedef I_Dereference_iterator<
00723     typename F::Isolated_vertex_iterator,
00724     Vertex,
00725     typename F::Isolated_vertex_iterator::difference_type,
00726     typename F::Isolated_vertex_iterator::iterator_category>
00727                                               Isolated_vertex_iterator;
00728   
00729   typedef I_Dereference_const_iterator<
00730     typename F::Isolated_vertex_const_iterator,
00731     typename F::Isolated_vertex_iterator,
00732     Vertex,
00733     typename F::Isolated_vertex_iterator::difference_type,
00734     typename F::Isolated_vertex_iterator::iterator_category>
00735                                               Isolated_vertex_const_iterator;
00736 
00738   size_t number_of_isolated_vertices() const
00739   {
00740     return (this->iso_verts.size());
00741   }
00742 
00744   Isolated_vertex_iterator isolated_vertices_begin()
00745   {
00746     return (this->iso_verts.begin());
00747   }
00748 
00750   Isolated_vertex_iterator isolated_vertices_end()
00751   {
00752     return (this->iso_verts.end());
00753   }
00754 
00756   Isolated_vertex_const_iterator isolated_vertices_begin() const
00757   {
00758     return (this->iso_verts.begin());
00759   }
00760 
00763   Isolated_vertex_const_iterator isolated_vertices_end() const
00764   {
00765     return (this->iso_verts.end());
00766   }
00767 
00769   void add_isolated_vertex (Isolated_vertex *iv, Vertex* v)
00770   {
00771     iv->set_iterator (this->iso_verts.insert (this->iso_verts.end(), v));
00772     return;
00773   }
00774 
00776   void erase_isolated_vertex (Isolated_vertex *iv)
00777   {
00778     this->iso_verts.erase (iv->iterator().current_iterator());
00779     return;
00780   }
00781 
00782 };
00783 
00787 template <class V, class H, class F>
00788 class Arr_outer_ccb : public In_place_list_base<Arr_outer_ccb<V,H,F> >
00789 {
00790 public:
00791 
00792   typedef Arr_outer_ccb<V,H,F>               Self;
00793   typedef Arr_halfedge<V,H,F>                Halfedge;
00794   typedef Arr_face<V,H,F>                    Face;
00795   typedef typename Face::Outer_ccb_iterator  Outer_ccb_iterator;
00796 
00797 private:
00798 
00799   Face               *p_f;    // The face the contains the CCB in its interior.
00800   Outer_ccb_iterator  iter;   // The outer CCB identifier.
00801   bool iter_is_not_singular;
00802 
00803 public:
00804 
00806   Arr_outer_ccb () :
00807     p_f (NULL), iter_is_not_singular(false)
00808   {}
00809 
00811   Arr_outer_ccb (const Arr_outer_ccb& other )
00812     : p_f (other.p_f), iter_is_not_singular(other.iter_is_not_singular)
00813   {
00814     if(other.iter_is_not_singular) {
00815       iter = other.iter;
00816     }
00817   }
00818 
00820   const Halfedge* halfedge () const
00821   {
00822     return (*iter);
00823   }
00824 
00826   Halfedge* halfedge ()
00827   {
00828     return (*iter);
00829   }
00830 
00832   void set_halfedge (Halfedge *he)
00833   {
00834     *iter = he;
00835     return;
00836   }
00837 
00839   const Face* face () const
00840   {
00841     return (p_f);
00842   }
00843 
00845   Face* face ()
00846   {
00847     return (p_f);
00848   }
00849 
00851   void set_face (Face* f)
00852   {
00853     p_f = f;
00854     return;
00855   }
00856 
00858   Outer_ccb_iterator iterator () const
00859   {
00860     CGAL_assertion(iter_is_not_singular);
00861     return (iter);
00862   }
00863 
00865   Outer_ccb_iterator iterator ()
00866   {
00867     CGAL_assertion(iter_is_not_singular);
00868     return (iter);
00869   }
00870 
00872   void set_iterator (Outer_ccb_iterator it)
00873   {
00874     iter = it;
00875     iter_is_not_singular = true;
00876     return;
00877   }
00878 };
00879 
00883 template <class V, class H, class F>
00884 class Arr_inner_ccb : public In_place_list_base<Arr_inner_ccb<V,H,F> >
00885 {
00886 public:
00887 
00888   typedef Arr_inner_ccb<V,H,F>               Self;
00889   typedef Arr_halfedge<V,H,F>                Halfedge;
00890   typedef Arr_face<V,H,F>                    Face;
00891   typedef typename Face::Inner_ccb_iterator  Inner_ccb_iterator;
00892 
00893 private:
00894 
00895   Face               *p_f;    // The face the contains the CCB in its interior.
00896   Inner_ccb_iterator  iter;   // The inner CCB identifier.
00897   bool iter_is_not_singular;
00898 
00899 public:
00900 
00902   Arr_inner_ccb () :
00903     p_f (NULL), iter_is_not_singular(false)
00904   {}
00905 
00907   Arr_inner_ccb (const Arr_inner_ccb& other )
00908     : p_f (other.p_f), iter_is_not_singular(other.iter_is_not_singular)
00909   {
00910     if(other.iter_is_not_singular) {
00911       iter = other.iter;
00912     }
00913   }
00914 
00916   const Halfedge* halfedge () const
00917   {
00918     return (*iter);
00919   }
00920 
00922   Halfedge* halfedge ()
00923   {
00924     return (*iter);
00925   }
00926 
00928   void set_halfedge (Halfedge *he)
00929   {
00930     *iter = he;
00931     return;
00932   }
00933 
00935   const Face* face () const
00936   {
00937     return (p_f);
00938   }
00939 
00941   Face* face ()
00942   {
00943     return (p_f);
00944   }
00945 
00947   void set_face (Face* f)
00948   {
00949     p_f = f;
00950     return;
00951   }
00952 
00954   Inner_ccb_iterator iterator () const
00955   {
00956     CGAL_assertion(iter_is_not_singular);
00957     return (iter);
00958   }
00959 
00961   Inner_ccb_iterator iterator ()
00962   {
00963     CGAL_assertion(iter_is_not_singular);
00964     return (iter);
00965   }
00966 
00968   void set_iterator (Inner_ccb_iterator it)
00969   {
00970     iter = it;
00971     iter_is_not_singular = true;
00972     return;
00973   }
00974 };
00975 
00979 template <class V, class H, class F>
00980 class Arr_isolated_vertex : 
00981 public In_place_list_base<Arr_isolated_vertex<V,H,F> >
00982 {
00983 public:
00984 
00985   typedef Arr_isolated_vertex<V,H,F>                Self;
00986   typedef Arr_face<V,H,F>                           Face;
00987   typedef typename Face::Isolated_vertex_iterator   Isolated_vertex_iterator;
00988 
00989 private:
00990 
00991   Face                        *p_f;   // The face containing the hole.
00992   Isolated_vertex_iterator   iv_it; // The isolated vertex identifier.
00993   bool iter_is_not_singular;
00994 
00995 public:
00996 
00998   Arr_isolated_vertex ():
00999     p_f (NULL), iter_is_not_singular(false)
01000   {}
01001 
01003   Arr_isolated_vertex (const Arr_isolated_vertex& other )
01004     : p_f (other.p_f), iter_is_not_singular(other.iter_is_not_singular)
01005   {
01006     if(other.iter_is_not_singular) {
01007       iv_it = other.iv_it;
01008     }
01009   }
01010 
01012   const Face* face () const
01013   {
01014     return (p_f);
01015   }
01016 
01018   Face* face ()
01019   {
01020     return (p_f);
01021   }
01022 
01024   void set_face (Face* f)
01025   {
01026     p_f = f;
01027     return;
01028   }
01029 
01031   Isolated_vertex_iterator iterator () const
01032   {
01033     CGAL_assertion(iter_is_not_singular);
01034     return (iv_it);
01035   }
01036 
01038   Isolated_vertex_iterator iterator ()
01039   {
01040     CGAL_assertion(iter_is_not_singular);
01041     return (iv_it);
01042   }
01043 
01045   void set_iterator (Isolated_vertex_iterator iv)
01046   {
01047     iv_it = iv;
01048     iter_is_not_singular = true;
01049     return;
01050   }
01051 };
01052 
01056 template <class V, class H, class F,
01057           class Allocator = CGAL_ALLOCATOR(int) >
01058 class Arr_dcel_base
01059 {
01060 public:
01061 
01062   // Define the vertex, halfedge and face types.
01063   typedef Arr_dcel_base<V,H,F>        Self;
01064   typedef Arr_vertex<V,H,F>           Vertex;
01065   typedef Arr_halfedge<V,H,F>         Halfedge;
01066   typedef Arr_face<V,H,F>             Face;
01067   typedef Arr_outer_ccb<V,H,F>        Outer_ccb;
01068   typedef Arr_inner_ccb<V,H,F>        Inner_ccb;
01069   typedef Arr_isolated_vertex<V,H,F>  Isolated_vertex;
01070 
01071 protected:
01072 
01073   // The vetices, halfedges and faces are stored in three in-place lists.
01074   typedef In_place_list<Vertex, false>           Vertex_list;
01075   typedef In_place_list<Halfedge, false>         Halfedge_list;
01076   typedef In_place_list<Face, false>             Face_list;
01077   typedef In_place_list<Outer_ccb, false>        Outer_ccb_list;
01078   typedef In_place_list<Inner_ccb, false>        Inner_ccb_list;
01079   typedef In_place_list<Isolated_vertex, false>  Iso_vert_list;
01080 
01081   // Vertex allocator.
01082   typedef typename Allocator::template rebind<Vertex>    Vertex_alloc_rebind;
01083   typedef typename Vertex_alloc_rebind::other            Vertex_allocator;
01084 
01085   // Halfedge allocator.
01086   typedef typename Allocator::template rebind<Halfedge>  Halfedge_alloc_rebind;
01087   typedef typename Halfedge_alloc_rebind::other          Halfedge_allocator;
01088 
01089   // Face allocator.
01090   typedef typename Allocator::template rebind<Face>      Face_alloc_rebind;
01091   typedef typename Face_alloc_rebind::other              Face_allocator;
01092   
01093   // Outer CCB allocator.
01094   typedef typename Allocator::template rebind<Outer_ccb> Out_ccb_alloc_rebind;
01095   typedef typename Out_ccb_alloc_rebind::other           Outer_ccb_allocator;
01096 
01097   // Inner CCB allocator.
01098   typedef typename Allocator::template rebind<Inner_ccb> In_ccb_alloc_rebind;
01099   typedef typename In_ccb_alloc_rebind::other            Inner_ccb_allocator;
01100 
01101   // Isolated vertex allocator.
01102   typedef typename Allocator::template rebind<Isolated_vertex>
01103                                                          Iso_vert_alloc_rebind;
01104   typedef typename Iso_vert_alloc_rebind::other          Iso_vert_allocator;
01105 
01106 public:
01107 
01108   typedef typename Halfedge_list::size_type              Size;
01109   typedef typename Halfedge_list::size_type              size_type;
01110   typedef typename Halfedge_list::difference_type        difference_type;
01111   typedef typename Halfedge_list::difference_type        Difference;
01112   typedef std::bidirectional_iterator_tag                iterator_category;
01113 
01114 protected:
01115 
01116   Vertex_list         vertices;             // The vertices container.
01117   Halfedge_list       halfedges;            // The halfedges container.
01118   Face_list           faces;                // The faces container.
01119   Outer_ccb_list      out_ccbs;             // The outer CCBs.
01120   Inner_ccb_list      in_ccbs;              // The inner CCBs.
01121   Iso_vert_list       iso_verts;            // The isolated vertices.
01122 
01123   Vertex_allocator    vertex_alloc;         // An allocator for vertices.
01124   Halfedge_allocator  halfedge_alloc;       // An allocator for halfedges.
01125   Face_allocator      face_alloc;           // An allocator for faces.
01126   Outer_ccb_allocator out_ccb_alloc;        // An allocator for outer CCBs.
01127   Inner_ccb_allocator in_ccb_alloc;         // An allocator for inner CCBs.
01128   Iso_vert_allocator  iso_vert_alloc;       // Allocator for isolated vertices.
01129 
01130 public:
01131 
01132   // Definitions of iterators.
01133   typedef typename Vertex_list::iterator              Vertex_iterator;
01134   typedef typename Halfedge_list::iterator            Halfedge_iterator;
01135   typedef typename Face_list::iterator                Face_iterator;
01136   typedef CGAL::N_step_adaptor_derived<Halfedge_iterator, 2>
01137                                                       Edge_iterator;
01138   
01139   // Definitions of const iterators.
01140   typedef typename Vertex_list::const_iterator        Vertex_const_iterator;
01141   typedef typename Halfedge_list::const_iterator      Halfedge_const_iterator;
01142   typedef typename Face_list::const_iterator          Face_const_iterator;
01143   typedef CGAL::N_step_adaptor_derived<Halfedge_const_iterator, 2>
01144                                                       Edge_const_iterator;
01145 
01146 private:
01147 
01148   // Copy constructor - not supported.
01149   Arr_dcel_base (const Self&) ;
01150 
01151   // Assignment operator - not supported.
01152   Self& operator= (const Self&);
01153 
01154 public:
01155 
01157 
01158 
01159   Arr_dcel_base ()
01160   {}
01161   
01163   ~Arr_dcel_base ()
01164   {
01165     delete_all();
01166   }
01168 
01170 
01171 
01172   Size size_of_vertices () const
01173   { 
01174     return (vertices.size());
01175   }
01176 
01178   Size size_of_halfedges () const
01179   {
01180     return (halfedges.size());
01181   }
01182 
01184   Size size_of_faces() const
01185   {
01186     return (faces.size());
01187   }
01188 
01190   Size size_of_outer_ccbs() const
01191   {
01192     return (out_ccbs.size());
01193   }
01194 
01196   Size size_of_inner_ccbs() const
01197   {
01198     return (in_ccbs.size());
01199   }
01200 
01202   Size size_of_isolated_vertices () const
01203   {
01204     return (iso_verts.size());
01205   }
01207 
01209 
01210   Vertex_iterator   vertices_begin()  { return vertices.begin(); }
01211   Vertex_iterator   vertices_end()    { return vertices.end(); }
01212   Halfedge_iterator halfedges_begin() { return halfedges.begin();}
01213   Halfedge_iterator halfedges_end()   { return halfedges.end(); }
01214   Face_iterator     faces_begin()     { return faces.begin(); }
01215   Face_iterator     faces_end()       { return faces.end(); }
01216   Edge_iterator     edges_begin()     { return halfedges.begin(); }  
01217   Edge_iterator     edges_end()       { return halfedges.end(); }  
01219 
01221 
01222   Vertex_const_iterator   vertices_begin() const { return vertices.begin(); }
01223   Vertex_const_iterator   vertices_end() const { return vertices.end(); }
01224   Halfedge_const_iterator halfedges_begin() const { return halfedges.begin(); }
01225   Halfedge_const_iterator halfedges_end() const { return halfedges.end(); }
01226   Face_const_iterator     faces_begin() const { return faces.begin(); }
01227   Face_const_iterator     faces_end() const { return faces.end(); }
01228   Edge_const_iterator     edges_begin() const { return halfedges.begin(); }  
01229   Edge_const_iterator     edges_end() const { return halfedges.end(); }  
01231 
01232   // \name Creation of new DCEL features.
01234 
01235   Vertex* new_vertex()
01236   {
01237     Vertex     *v = vertex_alloc.allocate (1);
01238 
01239     vertex_alloc.construct (v, Vertex());
01240     vertices.push_back (*v);
01241     return v;
01242   }
01243   
01245   Halfedge* new_edge() 
01246   {
01247     // Create two new halfedges.
01248     Halfedge   *h1 = _new_halfedge ();
01249     Halfedge   *h2 = _new_halfedge ();
01250 
01251     // Pair them together.
01252     h1->set_opposite (h2);
01253     h2->set_opposite (h1);
01254 
01255     return (h1);
01256   }
01257 
01259   Face* new_face()
01260   {
01261     Face       *f = face_alloc.allocate (1);
01262     
01263     face_alloc.construct (f, Face());
01264     faces.push_back (*f);
01265     return (f);
01266   }
01267 
01269   Outer_ccb* new_outer_ccb ()
01270   {
01271     Outer_ccb  *oc = out_ccb_alloc.allocate (1);
01272     out_ccb_alloc.construct (oc, Outer_ccb());
01273     out_ccbs.push_back (*oc);
01274     return (oc);
01275   }
01276 
01278   Inner_ccb* new_inner_ccb ()
01279   {
01280     Inner_ccb  *ic = in_ccb_alloc.allocate (1);
01281     
01282     in_ccb_alloc.construct (ic, Inner_ccb());
01283     in_ccbs.push_back (*ic);
01284     return (ic);
01285   }
01286 
01288   Isolated_vertex* new_isolated_vertex ()
01289   {
01290     Isolated_vertex  *iv = iso_vert_alloc.allocate (1);
01291     
01292     iso_vert_alloc.construct (iv, Isolated_vertex());
01293     iso_verts.push_back (*iv);
01294     return (iv);
01295   }
01297 
01299 
01300 
01301   void delete_vertex (Vertex *v)
01302   {
01303     vertices.erase (v);
01304     vertex_alloc.destroy (v);
01305     vertex_alloc.deallocate (v,1);
01306   }
01307   
01309   void delete_edge (Halfedge *h) 
01310   {
01311     Halfedge   *h_opp = h->opposite();
01312 
01313     _delete_halfedge (h);
01314     _delete_halfedge (h_opp);
01315   }
01316 
01318   void delete_face(Face *f)
01319   {
01320     faces.erase (f);
01321     face_alloc.destroy (f);
01322     face_alloc.deallocate (f, 1);
01323   }
01324 
01326   void delete_outer_ccb (Outer_ccb *oc)
01327   {
01328     out_ccbs.erase (oc);
01329     out_ccb_alloc.destroy (oc);
01330     out_ccb_alloc.deallocate (oc, 1);
01331   }
01332 
01334   void delete_inner_ccb (Inner_ccb *ic)
01335   {
01336     in_ccbs.erase (ic);
01337     in_ccb_alloc.destroy (ic);
01338     in_ccb_alloc.deallocate (ic, 1);
01339   }
01340 
01342   void delete_isolated_vertex (Isolated_vertex *iv)
01343   {
01344     iso_verts.erase (iv);
01345     iso_vert_alloc.destroy (iv);
01346     iso_vert_alloc.deallocate (iv, 1);
01347   }
01348   
01350   void delete_all() 
01351   {
01352     // Free all vertices.
01353     Vertex_iterator    vit = vertices.begin(), v_curr;
01354 
01355     while (vit != vertices.end())
01356     {
01357       v_curr = vit;
01358       ++vit;
01359       delete_vertex (&(*v_curr));
01360     }
01361 
01362     // Free all halfedges.
01363     Halfedge_iterator  hit = halfedges.begin(), h_curr;
01364 
01365     while (hit != halfedges.end())
01366     {
01367       h_curr = hit;
01368       ++hit;
01369       _delete_halfedge (&(*h_curr));
01370     }
01371 
01372     // Free all faces.
01373     Face_iterator      fit = faces.begin(), f_curr;
01374 
01375     while (fit != faces.end())
01376     {
01377       f_curr = fit;
01378       ++fit;
01379       delete_face (&(*f_curr));
01380     }
01381 
01382     // Free all outer CCBs.
01383     typename Outer_ccb_list::iterator   ocit = out_ccbs.begin(), oc_curr;
01384 
01385     while (ocit != out_ccbs.end())
01386     {
01387       oc_curr = ocit;
01388       ++ocit;
01389       delete_outer_ccb (&(*oc_curr));
01390     }
01391 
01392     // Free all inner CCBs.
01393     typename Inner_ccb_list::iterator   icit = in_ccbs.begin(), ic_curr;
01394 
01395     while (icit != in_ccbs.end())
01396     {
01397       ic_curr = icit;
01398       ++icit;
01399       delete_inner_ccb (&(*ic_curr));
01400     }
01401 
01402     // Free all isolated vertices.
01403     typename Iso_vert_list::iterator   ivit = iso_verts.begin(), iv_curr;
01404 
01405     while (ivit != iso_verts.end())
01406     {
01407       iv_curr = ivit;
01408       ++ivit;
01409       delete_isolated_vertex (&(*iv_curr));
01410     }
01411   }
01413 
01417   void assign (const Self& dcel)
01418   {
01419     // Clear the current contents of the DCEL.
01420     delete_all();
01421 
01422     // Create duplicated of the DCEL features and map the features of the
01423     // given DCEL to their corresponding duplicates.
01424     typedef std::map<const Vertex*, Vertex*>                    Vertex_map;
01425     typedef std::map<const Halfedge*, Halfedge*>                Halfedge_map;
01426     typedef std::map<const Face*, Face*>                        Face_map;
01427     typedef std::map<const Outer_ccb*, Outer_ccb*>              Outer_ccb_map;
01428     typedef std::map<const Inner_ccb*, Inner_ccb*>              Inner_ccb_map;
01429     typedef std::map<const Isolated_vertex*, Isolated_vertex*>  Iso_vert_map;
01430 
01431     Vertex_map                v_map;
01432     Vertex_const_iterator     vit;
01433     Vertex                   *dup_v;
01434 
01435     for (vit = dcel.vertices_begin(); vit != dcel.vertices_end(); ++vit)
01436     {
01437       dup_v = new_vertex();
01438       dup_v->assign (*vit);
01439       v_map.insert (typename Vertex_map::value_type (&(*vit), dup_v));
01440     }
01441 
01442     Halfedge_map              he_map;
01443     Halfedge_const_iterator   hit;
01444     Halfedge                 *dup_h;
01445 
01446     for (hit = dcel.halfedges_begin(); hit != dcel.halfedges_end(); ++hit)
01447     {
01448       dup_h = _new_halfedge();
01449       dup_h->assign (*hit);
01450       he_map.insert (typename Halfedge_map::value_type(&(*hit), dup_h));
01451     }
01452 
01453     Face_map                  f_map;
01454     Face_const_iterator       fit;
01455     Face                     *dup_f;
01456 
01457     for (fit = dcel.faces_begin(); fit != dcel.faces_end(); ++fit)
01458     {
01459       dup_f = new_face();
01460       dup_f->assign (*fit);
01461       f_map.insert (typename Face_map::value_type(&(*fit), dup_f));
01462     }
01463 
01464     Outer_ccb_map                            oc_map;
01465     typename Outer_ccb_list::const_iterator  ocit;
01466     Outer_ccb                               *dup_oc;
01467 
01468     for (ocit = dcel.out_ccbs.begin(); ocit != dcel.out_ccbs.end(); ++ocit)
01469     {
01470       dup_oc = new_outer_ccb();
01471       oc_map.insert (typename Outer_ccb_map::value_type(&(*ocit), dup_oc));
01472     }
01473 
01474     Inner_ccb_map                            ic_map;
01475     typename Inner_ccb_list::const_iterator  icit;
01476     Inner_ccb                               *dup_ic;
01477 
01478     for (icit = dcel.in_ccbs.begin(); icit != dcel.in_ccbs.end(); ++icit)
01479     {
01480       dup_ic = new_inner_ccb();
01481       ic_map.insert (typename Inner_ccb_map::value_type(&(*icit), dup_ic));
01482     }
01483 
01484     Iso_vert_map                            iv_map;
01485     typename Iso_vert_list::const_iterator  ivit;
01486     Isolated_vertex                        *dup_iv;
01487 
01488     for (ivit = dcel.iso_verts.begin(); ivit != dcel.iso_verts.end(); ++ivit)
01489     {
01490       dup_iv = new_isolated_vertex();
01491       iv_map.insert (typename Iso_vert_map::value_type(&(*ivit), dup_iv));
01492     }
01493 
01494     // Update the vertex records.
01495     const Vertex             *v;
01496     const Halfedge           *h;
01497     const Face               *f;
01498     const Outer_ccb          *oc;
01499     const Inner_ccb          *ic;
01500     const Isolated_vertex    *iv;
01501     
01502     for (vit = dcel.vertices_begin(); vit != dcel.vertices_end(); ++vit)
01503     {
01504       v = &(*vit);
01505       dup_v = (v_map.find (v))->second;
01506 
01507       if (v->is_isolated())
01508       {
01509         // Isolated vertex - set its information.
01510         iv = v->isolated_vertex();
01511         dup_iv = (iv_map.find (iv))->second;
01512 
01513         dup_v->set_isolated_vertex (dup_iv);
01514       }
01515       else
01516       {
01517         // Regular vertex - set its incident halfedge.
01518         h = v->halfedge();
01519         dup_h = (he_map.find (h))->second;
01520 
01521         dup_v->set_halfedge (dup_h);
01522       }
01523     }
01524 
01525     // Update the halfedge records.
01526     const Halfedge           *opp, *prev, *next;
01527     Halfedge                 *dup_opp, *dup_prev, *dup_next;
01528 
01529     for (hit = dcel.halfedges_begin(); hit != dcel.halfedges_end(); ++hit)
01530     {
01531       h = &(*hit);
01532       v = h->vertex();
01533       opp = h->opposite();
01534       prev = h->prev();
01535       next = h->next();
01536 
01537       dup_h = (he_map.find (h))->second;
01538       dup_v = (v_map.find (v))->second;
01539       dup_opp = (he_map.find (opp))->second;
01540       dup_prev = (he_map.find (prev))->second;
01541       dup_next = (he_map.find (next))->second;
01542 
01543       dup_h->set_vertex (dup_v);
01544       dup_h->set_opposite (dup_opp);
01545       dup_h->set_prev (dup_prev);
01546       dup_h->set_next (dup_next);
01547       dup_h->set_direction (h->direction());
01548 
01549       if (h->is_on_inner_ccb())
01550       {
01551         // The halfedge lies on an inner CCB - set its inner CCB record.
01552         ic = h->inner_ccb();
01553         dup_ic = (ic_map.find (ic))->second;
01554         dup_h->set_inner_ccb (dup_ic);
01555       }
01556       else
01557       {
01558         // The halfedge lies on an outer CCB - set its outer CCB record.
01559         oc = h->outer_ccb();
01560         dup_oc = (oc_map.find (oc))->second;
01561         dup_h->set_outer_ccb (dup_oc);
01562       }
01563     }
01564 
01565     // Update the face records, along with the CCB records and isolated vertex
01566     // records.
01567     typename Face::Outer_ccb_const_iterator        out_ccb_it;
01568     typename Face::Inner_ccb_const_iterator        in_ccb_it;
01569     typename Face::Isolated_vertex_const_iterator  iso_vert_it;
01570     const Halfedge                      *hccb;
01571     const Vertex                        *iso_vert;
01572     Halfedge                            *dup_hccb;
01573     Vertex                              *dup_iso_vert;
01574 
01575     for (fit = dcel.faces_begin(); fit != dcel.faces_end(); ++fit)
01576     {
01577       f = &(*fit);
01578       dup_f = (f_map.find (f))->second;
01579       dup_f->set_unbounded (f->is_unbounded());
01580       dup_f->set_fictitious (f->is_fictitious());
01581 
01582       // Assign the outer CCBs of the face.
01583       for (out_ccb_it = f->outer_ccbs_begin();
01584            out_ccb_it != f->outer_ccbs_end(); ++out_ccb_it)
01585       {
01586         hccb = *out_ccb_it;
01587 
01588         dup_hccb = (he_map.find (hccb))->second;
01589         dup_oc = dup_hccb->outer_ccb();
01590 
01591         dup_oc->set_face (dup_f);
01592         dup_f->add_outer_ccb (dup_oc, dup_hccb);
01593       }
01594 
01595       // Assign the inner CCBs of the face.
01596       for (in_ccb_it = f->inner_ccbs_begin();
01597            in_ccb_it != f->inner_ccbs_end(); ++in_ccb_it)
01598       {
01599         hccb = *in_ccb_it;
01600 
01601         dup_hccb = (he_map.find (hccb))->second;
01602         dup_ic = dup_hccb->inner_ccb();
01603 
01604         dup_ic->set_face (dup_f);
01605         dup_f->add_inner_ccb (dup_ic, dup_hccb);
01606       }
01607 
01608       // Assign the isolated vertices.
01609       for (iso_vert_it = f->isolated_vertices_begin();
01610            iso_vert_it != f->isolated_vertices_end(); ++iso_vert_it)
01611       {
01612         iso_vert = &(*iso_vert_it);
01613 
01614         dup_iso_vert = (v_map.find (iso_vert))->second;
01615         dup_iv = dup_iso_vert->isolated_vertex();
01616 
01617         dup_iv->set_face (dup_f);
01618         dup_f->add_isolated_vertex (dup_iv, dup_iso_vert);
01619       }
01620     }
01621 
01622     return;
01623   }
01624 
01625 protected:
01626 
01628   Halfedge * _new_halfedge ()
01629   {
01630     Halfedge   *h = halfedge_alloc.allocate (1);
01631 
01632     halfedge_alloc.construct (h, Halfedge());
01633     halfedges.push_back (*h);
01634     return (h);
01635   }
01636 
01638   void _delete_halfedge (Halfedge* h)
01639   {
01640     halfedges.erase (h);
01641     halfedge_alloc.destroy (h);
01642     halfedge_alloc.deallocate (h, 1);
01643   }
01644 };
01645 
01646 CGAL_END_NAMESPACE
01647 
01648 #endif 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines