// Copyright (c) 2014 GeometryFactory (France). All rights reserved. // // This file is part of CGAL (www.cgal.org) // // $URL: https://github.com/CGAL/cgal/blob/v5.1/BGL/include/CGAL/boost/graph/iterator.h $ // $Id: iterator.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Andreas Fabri #ifndef CGAL_BGL_ITERATORS_H #define CGAL_BGL_ITERATORS_H #include #include #include #include #include #include #include namespace CGAL { /// \cond SKIP_IN_MANUAL namespace internal { template struct Edge { const G* g; Edge() : g(nullptr) {} Edge(const G& g) : g(&g) {} typedef typename boost::graph_traits::edge_descriptor result_type; typedef typename boost::graph_traits::halfedge_descriptor argument_type; result_type operator()(argument_type h) const { return edge(h, *g); } }; template struct Opposite_edge { const G* g; Opposite_edge() : g(nullptr) {} Opposite_edge(const G& g) : g(&g) {} typedef typename boost::graph_traits::edge_descriptor result_type; typedef typename boost::graph_traits::halfedge_descriptor argument_type; result_type operator()(argument_type h) const { return edge(opposite(h,*g), *g); } }; template struct Opposite_halfedge { const G* g; Opposite_halfedge() : g(nullptr) {} Opposite_halfedge(const G& g) : g(&g) {} typedef typename boost::graph_traits::halfedge_descriptor result_type; typedef typename boost::graph_traits::halfedge_descriptor argument_type; result_type operator()(argument_type h) const { return opposite(h,*g); } }; template struct Target { const G* g; Target() : g(nullptr) {} Target(const G& g) : g(&g) {} typedef typename boost::graph_traits::vertex_descriptor result_type; typedef typename boost::graph_traits::halfedge_descriptor argument_type; result_type operator()(argument_type h) const { return target(h,*g); } }; template struct Source { const G* g; Source() : g(nullptr) {} Source(const G& g) : g(&g) {} typedef typename boost::graph_traits::vertex_descriptor result_type; typedef typename boost::graph_traits::halfedge_descriptor argument_type; result_type operator()(argument_type h) const { return source(h,*g); } }; template struct Face { const G* g; Face() : g(nullptr) {} Face(const G& g) : g(&g) {} typedef typename boost::graph_traits::face_descriptor result_type; typedef typename boost::graph_traits::halfedge_descriptor argument_type; result_type operator()(argument_type h) const { return face(h,*g); } }; template struct Opposite_face { const G* g; Opposite_face() : g(nullptr) {} Opposite_face(const G& g) : g(&g) {} typedef typename boost::graph_traits::face_descriptor result_type; typedef typename boost::graph_traits::halfedge_descriptor argument_type; result_type operator()(argument_type h) const { return face(opposite(h,*g),*g); } }; } // namespace internal /// \endcond /** * \ingroup PkgBGLIterators * A bidirectional iterator with value type `boost::graph_traits::%halfedge_descriptor` over all halfedges having the same vertex as source. * Let `h` be a halfedge of graph `g`. For a `Halfedge_around_source_iterator` `havi` with `h = *havi;` * the following holds: Either `++havi` is the past the end iterator, or `next(opposite(h,g),g) == *++havi`. * \tparam Graph must be a model of the concept `HalfedgeGraph` * \cgalModels `BidirectionalIterator` */ template class Halfedge_around_source_iterator { typedef Halfedge_around_source_iterator Self; public: #ifndef DOXYGEN_RUNNING typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::halfedge_descriptor vertex_descriptor; typedef std::bidirectional_iterator_tag iterator_category; typedef halfedge_descriptor value_type; typedef value_type* pointer; typedef const value_type& reference; typedef std::ptrdiff_t difference_type; private: halfedge_descriptor anchor, pos; const Graph* g; int winding; #endif public: Halfedge_around_source_iterator() : anchor(), pos(), g(0) {} Halfedge_around_source_iterator(halfedge_descriptor hd, const Graph& g, int n=0) : anchor(hd), pos(hd), g(&g), winding((hd==halfedge_descriptor())?1:n) {} #ifndef DOXYGEN_RUNNING // design patter: "safe bool" // will be replaced by explicit operator bool with C++11 typedef void (Halfedge_around_source_iterator::*bool_type)() const; void this_type_does_not_support_comparisons() const {} operator bool_type() const { return (! (this->base() == nullptr)) ? &Halfedge_around_source_iterator::this_type_does_not_support_comparisons : 0; } bool operator==( const Self& i) const { CGAL_assertion( anchor == anchor); return ( g == i.g) && ( pos == i.pos) && ( winding == i.winding); } bool operator!=( const Self& i) const { return !(*this == i); } bool operator== (void* ) const { return g == nullptr; } reference operator*() const { return pos; } pointer operator->() const { return &pos; } Self& operator++() { pos = next(opposite(pos,*g),*g); if ( pos == anchor) ++winding; return *this; } Self operator++(int) { Self tmp = *this; ++*this; return tmp; } Self& operator--() { if ( pos == anchor) --winding; pos = opposite(prev(pos,*g),*g); return *this; } Self operator--(int) { Self tmp = *this; --*this; return tmp; } #endif }; /** * \ingroup PkgBGLIterators * A bidirectional iterator with value type `boost::graph_traits::%halfedge_descriptor` over all halfedges having the same vertex as target. * Let `h` be a halfedge of graph `g`. For a `Halfedge_around_target_iterator` `havi` with `h = *havi;` * the following holds: Either `++havi` is the past the end iterator, or `opposite(next(h,g),g) == *++havi`. * \tparam Graph must be a model of the concept `HalfedgeGraph` * \cgalModels `BidirectionalIterator` */ template class Halfedge_around_target_iterator { typedef Halfedge_around_target_iterator Self; public: #ifndef DOXYGEN_RUNNING typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::halfedge_descriptor vertex_descriptor; typedef std::bidirectional_iterator_tag iterator_category; typedef halfedge_descriptor value_type; typedef value_type* pointer; typedef const value_type& reference; typedef std::ptrdiff_t difference_type; private: halfedge_descriptor anchor, pos; const Graph* g; int winding; #endif public: Halfedge_around_target_iterator() : anchor(), pos(), g(0) {} Halfedge_around_target_iterator(halfedge_descriptor hd, const Graph& g, int n=0) : anchor(hd), pos(hd), g(&g), winding((hd==halfedge_descriptor())?1:n) {} #ifndef DOXYGEN_RUNNING // design patter: "safe bool" // will be replaced by explicit operator bool with C++11 typedef void (Halfedge_around_target_iterator::*bool_type)() const; void this_type_does_not_support_comparisons() const {} operator bool_type() const { return (! (this->base() == nullptr)) ? &Halfedge_around_target_iterator::this_type_does_not_support_comparisons : 0; } bool operator==( const Self& i) const { CGAL_assertion( anchor == anchor); return ( g == i.g) && ( pos == i.pos) && ( winding == i.winding); } bool operator!=( const Self& i) const { return !(*this == i); } bool operator== (void* ) const { return g == nullptr; } reference operator*() const { return pos; } pointer operator->() const { return &pos; } Self& operator++() { pos = opposite(next(pos,*g),*g); if ( pos == anchor) ++winding; return *this; } Self operator++(int) { Self tmp = *this; ++*this; return tmp; } Self& operator--() { if ( pos == anchor) --winding; pos = prev(opposite(pos,*g),*g); return *this; } Self operator--(int) { Self tmp = *this; --*this; return tmp; } #endif }; /** * \ingroup PkgBGLIterators * A bidirectional iterator with value type `boost::graph_traits::%halfedge_descriptor` over all halfedges incident to the same face or border. * Let `h` be a halfedge of graph `g`. For a `Halfedge_around_face_iterator` `hafi` with `h = *hafi` * the following holds: Either `++hafi` is the past the end iterator, or `next(h,g) == *++hafi`. * \tparam Graph must be a model of the concept `HalfedgeGraph` * \cgalModels `BidirectionalIterator` */ template class Halfedge_around_face_iterator { #ifndef DOXYGEN_RUNNING typedef Halfedge_around_face_iterator Self; public: typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef std::bidirectional_iterator_tag iterator_category; typedef halfedge_descriptor value_type; typedef value_type* pointer; typedef value_type& reference; typedef std::ptrdiff_t difference_type; #endif Halfedge_around_face_iterator() : pos(), g(0) {} Halfedge_around_face_iterator(halfedge_descriptor hd, const Graph& g, int n=0) : anchor(hd), pos(hd), g(&g), winding((hd == halfedge_descriptor())?1:n) {} #ifndef DOXYGEN_RUNNING reference operator * ( ) { return pos; } const value_type& operator * ( ) const { return pos; } pointer operator -> ( ) { return &pos; } const value_type* operator -> ( ) const { return &pos; } // design patter: "safe bool" // will be replaced by explicit operator bool with C++11 typedef void (Halfedge_around_face_iterator::*bool_type)() const; void this_type_does_not_support_comparisons() const {} operator bool_type() const { return (! (this->base() == nullptr)) ? &Halfedge_around_face_iterator::this_type_does_not_support_comparisons : 0; } bool operator==( const Self& i) const { CGAL_assertion( anchor == anchor); return ( g == i.g) && ( pos == i.pos) && ( winding == i.winding); } bool operator!=( const Self& i) const { return !(*this == i); } Self& operator++() { CGAL_assertion(g != nullptr); pos = next(pos,*g); if ( pos == anchor) ++winding; return *this; } Self operator++(int) { CGAL_assertion(g != nullptr); Self tmp = *this; ++*this; return tmp; } Self& operator--() { CGAL_assertion(g != nullptr); if ( pos == anchor) --winding; pos = prev(pos,*g); return *this; } Self operator--(int) { CGAL_assertion(g != nullptr); Self tmp = *this; --*this; return tmp; } #endif private: halfedge_descriptor anchor, pos; const Graph* g; int winding; }; template class Halfedge_around_target_circulator; /** * \ingroup PkgBGLIterators * A bidirectional circulator with value type `boost::graph_traits::%halfedge_descriptor` over all halfedges having the same vertex as source. * Let `h` be a halfedge of graph `g`. For a `Halfedge_around_source_circulator` `havc` with `h = *havc;` * the following holds: `next(opposite(h,g),g) == *++havc`. * \tparam Graph must be a model of the concept `HalfedgeGraph` * \cgalModels `BidirectionalCirculator` */ template class Halfedge_around_source_circulator #ifndef DOXYGEN_RUNNING : public boost::iterator_adaptor< Halfedge_around_source_circulator // Derived , Halfedge_around_target_circulator // Base , typename boost::graph_traits::halfedge_descriptor // Value , Bidirectional_circulator_tag // CategoryOrTraversal , typename boost::graph_traits::halfedge_descriptor // Reference > #endif { private: internal::Opposite_halfedge opp; #ifndef DOXYGEN_RUNNING typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; #endif public: #ifndef DOXYGEN_RUNNING typedef std::size_t size_type; #endif Halfedge_around_source_circulator() {} Halfedge_around_source_circulator(halfedge_descriptor hd, const Graph& g) : Halfedge_around_source_circulator::iterator_adaptor_(Halfedge_around_target_circulator(opposite(hd,g),g)), opp(g) {} Halfedge_around_source_circulator(vertex_descriptor vd, const Graph& g) : Halfedge_around_source_circulator::iterator_adaptor_(Halfedge_around_target_circulator(halfedge(vd,g),g)), opp(g) {} // design patter: "safe bool" // will be replaced by explicit operator bool with C++11 typedef void (Halfedge_around_source_circulator::*bool_type)() const; void this_type_does_not_support_comparisons() const {} operator bool_type() const { return (! (this->base_reference() == nullptr)) ? &Halfedge_around_source_circulator::this_type_does_not_support_comparisons : 0; } bool operator== (void*) const { return this->base_reference() == nullptr; } private: friend class boost::iterator_core_access; typename boost::graph_traits::halfedge_descriptor dereference() const { return opp(*this->base_reference()); } }; /** * \ingroup PkgBGLIterators * A bidirectional circulator with value type `boost::graph_traits::%face_descriptor` over all faces incident to the same vertex. * It circulates over the same halfedges as the `Halfedge_around_target_circulator`. * * \tparam Graph must be a model of the concept `HalfedgeGraph` * \cgalModels `BidirectionalCirculator` */ template class Face_around_target_circulator #ifndef DOXYGEN_RUNNING : public boost::iterator_adaptor< Face_around_target_circulator // Derived , Halfedge_around_target_circulator // Base , typename boost::graph_traits::face_descriptor // Value , Bidirectional_circulator_tag // CategoryOrTraversal , typename boost::graph_traits::face_descriptor // Reference > #endif { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; internal::Face fct; public: Face_around_target_circulator() {} Face_around_target_circulator(halfedge_descriptor hd, const Graph& g) : Face_around_target_circulator::iterator_adaptor_(Halfedge_around_target_circulator(hd,g)), fct(g) {} #ifndef DOXYGEN_RUNNING typedef std::size_t size_type; // design patter: "safe bool" // will be replaced by explicit operator bool with C++11 typedef void (Face_around_target_circulator::*bool_type)() const; void this_type_does_not_support_comparisons() const {} operator bool_type() const { return (! (this->base_reference() == nullptr)) ? &Face_around_target_circulator::this_type_does_not_support_comparisons : 0; } bool operator== (void*) const { return this->base_reference() == nullptr; } private: friend class boost::iterator_core_access; typename boost::graph_traits::face_descriptor dereference() const { return fct(*this->base_reference()); } #endif }; /** * \ingroup PkgBGLIterators * A bidirectional circulator with value type `boost::graph_traits::%halfedge_descriptor` over all halfedges having the same vertex as target. * Let `h` be a halfedge of graph `g`. For a `Halfedge_around_target_circulator` `havc` with `h = *havc;` * the following holds: `opposite(next(h,g),g) == *++havc`. * \tparam Graph must be a model of the concept `HalfedgeGraph` * \cgalModels `BidirectionalCirculator` */ template class Halfedge_around_target_circulator { typedef Halfedge_around_target_circulator Self; public: #ifndef DOXYGEN_RUNNING typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; typedef Bidirectional_circulator_tag iterator_category; typedef halfedge_descriptor value_type; typedef value_type* pointer; typedef value_type& reference; typedef std::ptrdiff_t difference_type; typedef std::size_t size_type; #endif Halfedge_around_target_circulator() : g(0) {} Halfedge_around_target_circulator(halfedge_descriptor pos, const Graph& g) : pos(pos), g(&g) {} Halfedge_around_target_circulator(vertex_descriptor vd, const Graph& g) : pos(halfedge(vd,g)), g(&g) {} #ifndef DOXYGEN_RUNNING reference operator * ( ) { return pos; } const value_type& operator * ( ) const { return pos; } pointer operator -> ( ) { return &pos; } const value_type* operator -> ( ) const { return &pos; } bool operator == ( const Self& other) const { return g == other.g && pos == other.pos; } bool operator != ( const Self& other) const { return g != other.g || pos != other.pos; } // design patter: "safe bool" // will be replaced by explicit operator bool with C++11 typedef void (Halfedge_around_target_circulator::*bool_type)() const; void this_type_does_not_support_comparisons() const {} operator bool_type() const { return (! (g == nullptr)) ? &Halfedge_around_target_circulator::this_type_does_not_support_comparisons : 0; } bool operator== (void* ) const { return g == nullptr; } Self& operator++() { CGAL_assertion(g != nullptr); pos = opposite(next(pos,*g),*g); return *this; } Self operator++(int) { CGAL_assertion(g != nullptr); Self tmp = *this; ++*this; return tmp; } Self& operator--() { CGAL_assertion(g != nullptr); pos = prev(opposite(pos,*g),*g); return *this; } Self operator--(int) { CGAL_assertion(g != nullptr); Self tmp = *this; --*this; return tmp; } #endif private: halfedge_descriptor pos; const Graph* g; }; /** * \ingroup PkgBGLIterators * A bidirectional circulator with value type `boost::graph_traits::%halfedge_descriptor` over all halfedges incident to the same face or border. * Let `h` be a halfedge of graph `g`. For a `Halfedge_around_face_circulator` `hafc` with `h = *hafc` * the following holds: `next(h,g) == *++hafc`. * \tparam Graph must be a model of the concept `HalfedgeGraph` * \cgalModels `BidirectionalCirculator` */ template class Halfedge_around_face_circulator { typedef Halfedge_around_face_circulator Self; public: #ifndef DOXYGEN_RUNNING typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef Bidirectional_circulator_tag iterator_category; typedef halfedge_descriptor value_type; typedef value_type* pointer; typedef value_type& reference; typedef std::ptrdiff_t difference_type; typedef std::size_t size_type; #endif Halfedge_around_face_circulator() : pos(), g(0) {} Halfedge_around_face_circulator(halfedge_descriptor pos, const Graph& g) : pos(pos), g(&g) {} #ifndef DOXYGEN_RUNNING reference operator * ( ) { return pos; } const value_type& operator * ( ) const { return pos; } pointer operator -> ( ) { return &pos; } const value_type* operator -> ( ) const { return &pos; } bool operator == ( const Self& other) const { return g == other.g && pos == other.pos; } bool operator != ( const Self& other) const { return g != other.g || pos != other.pos; } // design patter: "safe bool" // will be replaced by explicit operator bool with C++11 typedef void (Halfedge_around_face_circulator::*bool_type)() const; void this_type_does_not_support_comparisons() const {} operator bool_type() const { return (! (g == nullptr)) ? &Halfedge_around_face_circulator::this_type_does_not_support_comparisons : 0; } bool operator== (void* ) const { return g == nullptr; } Self& operator++() { CGAL_assertion(g != nullptr); pos = next(pos,*g); return *this; } Self operator++(int) { CGAL_assertion(g != nullptr); Self tmp = *this; ++*this; return tmp; } Self& operator--() { CGAL_assertion(g != nullptr); pos = prev(pos,*g); return *this; } Self operator--(int) { CGAL_assertion(g != nullptr); Self tmp = *this; --*this; return tmp; } #endif private: halfedge_descriptor pos; const Graph* g; }; /** * \ingroup PkgBGLIterators * returns an iterator range over all halfedges with vertex `source(h,g)` as source. */ template Iterator_range > halfedges_around_source(typename boost::graph_traits::halfedge_descriptor h, const Graph& g) { typedef Halfedge_around_source_iterator I; return make_range(I(h,g), I(h,g,1)); } /** * \ingroup PkgBGLIterators * returns an iterator range over all halfedges with vertex `v` as source. */ template Iterator_range > halfedges_around_source(typename boost::graph_traits::vertex_descriptor v, const Graph& g) { return halfedges_around_source(opposite(halfedge(v,g),g),g); } /** * \ingroup PkgBGLIterators * returns an iterator range over all halfedges with vertex `target(h,g)` as target. */ template Iterator_range > halfedges_around_target(typename boost::graph_traits::halfedge_descriptor h, const Graph& g) { typedef Halfedge_around_target_iterator I; return make_range(I(h,g), I(h,g,1)); } /** * \ingroup PkgBGLIterators * returns an iterator range over all halfedges with vertex `v` as target. */ template Iterator_range > halfedges_around_target(typename boost::graph_traits::vertex_descriptor v, const Graph& g) { return halfedges_around_target(halfedge(v,g),g); } /** * \ingroup PkgBGLIterators * returns an iterator range over all halfedges incident to the same face or border as `h`. */ template Iterator_range > halfedges_around_face(typename boost::graph_traits::halfedge_descriptor h, const Graph& g) { typedef Halfedge_around_face_iterator I; return make_range(I(h,g), I(h,g,1)); } /** * \ingroup PkgBGLIterators * A bidirectional iterator with value type `boost::graph_traits::%face_descriptor`. * It iterates over the same halfedges as the `Halfedge_around_face_iterator`, * and provides the face descriptor associated to the opposite halfedge. The face descriptor * may be the null face, and it may be several times the same face descriptor. * * \tparam Graph must be a model of the concept `HalfedgeGraph` * \cgalModels `BidirectionalCirculator` */ template class Face_around_face_iterator #ifndef DOXYGEN_RUNNING : public boost::iterator_adaptor< Face_around_face_iterator // Derived , Halfedge_around_face_iterator // Base , typename boost::graph_traits::face_descriptor // Value , std::bidirectional_iterator_tag // CategoryOrTraversal , typename boost::graph_traits::face_descriptor // Reference > #endif { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; internal::Opposite_face fct; public: Face_around_face_iterator() {} Face_around_face_iterator(halfedge_descriptor h, const Graph& g, int n = 0) : Face_around_face_iterator::iterator_adaptor_(Halfedge_around_face_iterator(h,g,(h==halfedge_descriptor())?1:n)), fct(g) {} private: friend class boost::iterator_core_access; typename boost::graph_traits::face_descriptor dereference() const { return fct(*this->base_reference()); } }; /** * \ingroup PkgBGLIterators * A bidirectional circulator with value type `boost::graph_traits::%face_descriptor`. * It circulates over the same halfedges as the `Halfedge_around_face_circulator`, * and provides the face descriptor associated to the opposite halfedge. The face descriptor * may be the null face, and it may be several times the same face descriptor. * * \tparam Graph must be a model of the concept `HalfedgeGraph` * \cgalModels `BidirectionalCirculator` */ template class Face_around_face_circulator {}; /** * \ingroup PkgBGLIterators * A bidirectional iterator with value type `boost::graph_traits::%face_descriptor`. * It iterates over the same halfedges as the `Halfedge_around_face_iterator`, * and provides the face descriptor associated to the opposite halfedge. The face descriptor * may be the null face, and it may be several times the same face descriptor. * * \tparam Graph must be a model of the concept `HalfedgeGraph` * \cgalModels `BidirectionalIterator` */ template class Face_around_target_iterator #ifndef DOXYGEN_RUNNING : public boost::iterator_adaptor< Face_around_target_iterator // Derived , Halfedge_around_target_iterator // Base , typename boost::graph_traits::face_descriptor // Value , std::bidirectional_iterator_tag // CategoryOrTraversal , typename boost::graph_traits::face_descriptor // Reference > #endif { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; internal::Face fct; public: Face_around_target_iterator() {} Face_around_target_iterator(halfedge_descriptor h, const Graph& g, int n = 0) : Face_around_target_iterator::iterator_adaptor_(Halfedge_around_target_iterator(h,g,(h==halfedge_descriptor())?1:n)), fct(g) {} private: friend class boost::iterator_core_access; typename boost::graph_traits::face_descriptor dereference() const { return fct(*this->base_reference()); } }; /** * \ingroup PkgBGLIterators * returns an iterator range over all faces around vertex `target(h,g)`. */ template Iterator_range > faces_around_target(typename boost::graph_traits::halfedge_descriptor h, const Graph& g) { typedef Face_around_target_iterator I; return make_range(I(h,g), I(h,g,1)); } /** * \ingroup PkgBGLIterators * returns an iterator range over all edge-adjacent faces to the same face `face(h,g)`. */ template Iterator_range > faces_around_face(typename boost::graph_traits::halfedge_descriptor h, const Graph& g) { typedef Face_around_face_iterator I; return make_range(I(h,g), I(h,g,1)); } template class Vertex_around_face_circulator #ifndef DOXYGEN_RUNNING : public boost::iterator_adaptor< Vertex_around_face_circulator // Derived , Halfedge_around_face_circulator // Base , typename boost::graph_traits::vertex_descriptor // Value , Bidirectional_circulator_tag // CategoryOrTraversal , typename boost::graph_traits::vertex_descriptor // Reference > #endif { internal::Target fct; typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; public: #ifndef DOXYGEN_RUNNING typedef std::size_t size_type; #endif Vertex_around_face_circulator() {} Vertex_around_face_circulator(halfedge_descriptor h, const Graph& g) : Vertex_around_face_circulator::iterator_adaptor_(Halfedge_around_face_circulator(h,g)), fct(g) {} #ifndef DOXYGEN_RUNNING // design patter: "safe bool" // will be replaced by explicit operator bool with C++11 typedef void (Vertex_around_face_circulator::*bool_type)() const; void this_type_does_not_support_comparisons() const {} operator bool_type() const { return (! (this->base_reference() == nullptr)) ? &Vertex_around_face_circulator::this_type_does_not_support_comparisons : 0; } bool operator== (void*) const { return this->base_reference()== nullptr; } private: friend class boost::iterator_core_access; typename boost::graph_traits::vertex_descriptor dereference() const { return fct(*this->base_reference()); } #endif }; /** * \ingroup PkgBGLIterators * A bidirectional iterator with value type `boost::graph_traits::%vertex_descriptor` * over all vertices incident to the same face or border. * \tparam Graph must be a model of the concept `HalfedgeGraph` * \cgalModels `BidirectionalIterator` */ template class Vertex_around_face_iterator #ifndef DOXYGEN_RUNNING : public boost::iterator_adaptor< Vertex_around_face_iterator // Derived , Halfedge_around_face_iterator // Base , typename boost::graph_traits::vertex_descriptor // Value , std::bidirectional_iterator_tag // CategoryOrTraversal , typename boost::graph_traits::vertex_descriptor // Reference > #endif { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; internal::Target fct; public: Vertex_around_face_iterator() {} Vertex_around_face_iterator(halfedge_descriptor h, const Graph& g, int n = 0) : Vertex_around_face_iterator::iterator_adaptor_(Halfedge_around_face_iterator(h,g,(h==halfedge_descriptor())?1:n)), fct(g) {} #ifndef DOXYGEN_RUNNING // design patter: "safe bool" // will be replaced by explicit operator bool with C++11 typedef void (Vertex_around_face_iterator::*bool_type)() const; void this_type_does_not_support_comparisons() const {} operator bool_type() const { return (! (this->base_reference() == nullptr)) ? &Vertex_around_face_iterator::this_type_does_not_support_comparisons : 0; } bool operator== (void*) const { return this->base_reference()== nullptr; } private: friend class boost::iterator_core_access; typename boost::graph_traits::vertex_descriptor dereference() const { return fct(*this->base_reference()); } #endif }; template class Opposite_edge_around_face_iterator #ifndef DOXYGEN_RUNNING : public boost::iterator_adaptor< Opposite_edge_around_face_iterator // Derived , Halfedge_around_face_iterator // Base , typename boost::graph_traits::edge_descriptor // Value , std::bidirectional_iterator_tag // CategoryOrTraversal , typename boost::graph_traits::edge_descriptor // Reference > #endif { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; internal::Opposite_edge fct; public: Opposite_edge_around_face_iterator() {} Opposite_edge_around_face_iterator(halfedge_descriptor h, const Graph& g, int n = 0) : Opposite_edge_around_face_iterator::iterator_adaptor_(Halfedge_around_face_iterator(h,g,(h==halfedge_descriptor())?1:n)), fct(g) {} private: friend class boost::iterator_core_access; typename boost::graph_traits::edge_descriptor dereference() const { return fct(*this->base_reference()); } }; template Iterator_range > opposite_edges_around_face(typename boost::graph_traits::halfedge_descriptor h, const Graph& g) { typedef Opposite_edge_around_face_iterator I; return make_range(I(h,g), I(h,g,1)); } template class Edge_around_face_iterator #ifndef DOXYGEN_RUNNING : public boost::iterator_adaptor< Edge_around_face_iterator // Derived , Halfedge_around_face_iterator // Base , typename boost::graph_traits::edge_descriptor // Value , std::bidirectional_iterator_tag // CategoryOrTraversal , typename boost::graph_traits::edge_descriptor // Reference > #endif { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; internal::Edge fct; public: Edge_around_face_iterator() {} Edge_around_face_iterator(halfedge_descriptor h, const Graph& g, int n = 0) : Edge_around_face_iterator::iterator_adaptor_(Halfedge_around_face_iterator(h,g,(h==halfedge_descriptor())?1:n)), fct(g) {} private: friend class boost::iterator_core_access; typename boost::graph_traits::edge_descriptor dereference() const { return fct(*this->base_reference()); } }; template Iterator_range > edges_around_face(typename boost::graph_traits::halfedge_descriptor h, const Graph& g) { typedef Edge_around_face_iterator I; return make_range(I(h,g), I(h,g,1)); } /** * \ingroup PkgBGLIterators * A bidirectional circulator with value type `boost::graph_traits::%vertex_descriptor` over all vertices adjacent to the same vertex. * It circulates over the same halfedges as the `Halfedge_around_target_circulator`. * * \tparam Graph must be a model of the concept `HalfedgeGraph` * \cgalModels `BidirectionalCirculator` */ template class Vertex_around_target_circulator #ifndef DOXYGEN_RUNNING : public boost::iterator_adaptor< Vertex_around_target_circulator // Derived , Halfedge_around_target_circulator // Base , typename boost::graph_traits::vertex_descriptor // Value , Bidirectional_circulator_tag // CategoryOrTraversal , typename boost::graph_traits::vertex_descriptor // Reference > #endif { internal::Source fct; public: #ifndef DOXYGEN_RUNNING typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef std::size_t size_type; #endif Vertex_around_target_circulator() {} Vertex_around_target_circulator(halfedge_descriptor h, const Graph& g) : Vertex_around_target_circulator::iterator_adaptor_(Halfedge_around_target_circulator(h,g)), fct(g) {} #ifndef DOXYGEN_RUNNING // design patter: "safe bool" // will be replaced by explicit operator bool with C++11 typedef void (Vertex_around_target_circulator::*bool_type)() const; void this_type_does_not_support_comparisons() const {} operator bool_type() const { return (! (this->base_reference() == nullptr)) ? &Vertex_around_target_circulator::this_type_does_not_support_comparisons : 0; } bool operator== (void*) const { return this->base_reference()== nullptr; } private: friend class boost::iterator_core_access; typename boost::graph_traits::vertex_descriptor dereference() const { return fct(*this->base_reference()); } #endif }; /** * \ingroup PkgBGLIterators * A bidirectional iterator with value type `boost::graph_traits::%vertex_descriptor` over all vertices adjacent to the same vertex. * It iterates over the same halfedges as the `Halfedge_around_target_iterator`. * * \tparam Graph must be a model of the concept `HalfedgeGraph` * \cgalModels `BidirectionalIterator` */ template class Vertex_around_target_iterator #ifndef DOXYGEN_RUNNING : public boost::iterator_adaptor< Vertex_around_target_iterator // Derived , Halfedge_around_target_iterator // Base , typename boost::graph_traits::vertex_descriptor // Value , std::bidirectional_iterator_tag // CategoryOrTraversal , typename boost::graph_traits::vertex_descriptor // Reference > #endif { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; internal::Source fct; public: Vertex_around_target_iterator() {} Vertex_around_target_iterator(halfedge_descriptor h, const Graph& g, int n = 0) : Vertex_around_target_iterator::iterator_adaptor_(Halfedge_around_target_iterator(h,g,(h==halfedge_descriptor())?1:n)), fct(g) {} #ifndef DOXYGEN_RUNNING // design patter: "safe bool" // will be replaced by explicit operator bool with C++11 typedef void (Vertex_around_target_iterator::*bool_type)() const; void this_type_does_not_support_comparisons() const {} operator bool_type() const { return (! (this->base_reference() == nullptr)) ? &Vertex_around_target_iterator::this_type_does_not_support_comparisons : 0; } private: friend class boost::iterator_core_access; typename boost::graph_traits::vertex_descriptor dereference() const { return fct(*this->base_reference()); } #endif }; template Iterator_range > adjacent_vertices(typename boost::graph_traits::halfedge_descriptor h, const Graph& g) { typedef Vertex_around_target_iterator I; return make_range(I(h,g), I(h,g,1)); } template Iterator_range > adjacent_vertices(typename boost::graph_traits::vertex_descriptor v, const Graph& g) { typedef Vertex_around_target_iterator I; return make_range(I(halfedge(v,g),g), I(halfedge(v,g),g,1)); } /** * \ingroup PkgBGLIterators * returns an iterator range over all vertices adjacent to the vertex `target(h,g)`. */ template Iterator_range > vertices_around_target(typename boost::graph_traits::halfedge_descriptor h, const Graph& g) { typedef Vertex_around_target_iterator I; return make_range(I(h,g), I(h,g,1)); } template Iterator_range > vertices_around_target(typename boost::graph_traits::vertex_descriptor v, const Graph& g) { typedef Vertex_around_target_iterator I; return make_range(I(halfedge(v,g),g), I(halfedge(v,g),g,1)); } /** * \ingroup PkgBGLIterators * returns an iterator range over all vertices adjacent to the face `face(h,g)`. */ template Iterator_range > vertices_around_face(typename boost::graph_traits::halfedge_descriptor h, const Graph& g) { typedef Vertex_around_face_iterator I; return make_range(I(h,g), I(h,g,1)); } template class Out_edge_iterator : public boost::iterator_adaptor< Out_edge_iterator // Derived , Halfedge_around_target_iterator // Base , typename boost::graph_traits::edge_descriptor // Value , std::bidirectional_iterator_tag // CategoryOrTraversal , typename boost::graph_traits::edge_descriptor // Reference > { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; private: internal::Opposite_edge opp; public: Out_edge_iterator() {} Out_edge_iterator(halfedge_descriptor h, const Graph& g, int n = 0) : Out_edge_iterator::iterator_adaptor_(Halfedge_around_target_iterator(h,g,(h==halfedge_descriptor())?1:n)), opp(g) {} // design patter: "safe bool" // will be replaced by explicit operator bool with C++11 typedef void (Out_edge_iterator::*bool_type)() const; void this_type_does_not_support_comparisons() const {} operator bool_type() const { return (! (this->base_reference() == nullptr)) ? &Out_edge_iterator::this_type_does_not_support_comparisons : 0; } private: friend class boost::iterator_core_access; typename boost::graph_traits::edge_descriptor dereference() const { return opp(*this->base_reference()); } }; template class In_edge_iterator : public boost::iterator_adaptor< In_edge_iterator // Derived , Halfedge_around_target_iterator // Base , typename boost::graph_traits::edge_descriptor // Value , std::bidirectional_iterator_tag // CategoryOrTraversal , typename boost::graph_traits::edge_descriptor // Reference > { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; private: internal::Edge fct; public: In_edge_iterator() {} In_edge_iterator(halfedge_descriptor h, const Graph& g, int n = 0) : In_edge_iterator::iterator_adaptor_(Halfedge_around_target_iterator(h,g,(h==halfedge_descriptor())?1:n)), fct(g) {} // design patter: "safe bool" // will be replaced by explicit operator bool with C++11 typedef void (In_edge_iterator::*bool_type)() const; void this_type_does_not_support_comparisons() const {} operator bool_type() const { return (! (this->base_reference() == nullptr)) ? &In_edge_iterator::this_type_does_not_support_comparisons : 0; } private: friend class boost::iterator_core_access; typename boost::graph_traits::edge_descriptor dereference() const { return fct(*this->base_reference()); } }; } // CGAL #endif /* CGAL_BGL_ITERATORS_H */