⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 face_iterators.hpp

📁 Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
💻 HPP
字号:
//=======================================================================// Copyright (c) Aaron Windsor 2007//// Distributed under the Boost Software License, Version 1.0. (See// accompanying file LICENSE_1_0.txt or copy at// http://www.boost.org/LICENSE_1_0.txt)//=======================================================================#ifndef __FACE_ITERATORS_HPP__#define __FACE_ITERATORS_HPP__#include <boost/iterator/iterator_facade.hpp>#include <boost/mpl/bool.hpp>#include <boost/graph/graph_traits.hpp>namespace boost {  //tags for defining traversal properties  //VisitorType  struct lead_visitor {};  struct follow_visitor {};  //TraversalType  struct single_side {};  struct both_sides {};  //TraversalSubType  struct first_side {}; //for single_side  struct second_side {}; //for single_side  struct alternating {}; //for both_sides  //Time  struct current_iteration {};  struct previous_iteration {};  // Why TraversalType AND TraversalSubType? TraversalSubType is a function   // template parameter passed in to the constructor of the face iterator,   // whereas TraversalType is a class template parameter. This lets us decide   // at runtime whether to move along the first or second side of a bicomp (by   // assigning a face_iterator that has been constructed with TraversalSubType   // = first_side or second_side to a face_iterator variable) without any of   // the virtual function overhead that comes with implementing this   // functionality as a more structured form of type erasure. It also allows   // a single face_iterator to be the end iterator of two iterators traversing   // both sides of a bicomp.  //ValueType is either graph_traits<Graph>::vertex_descriptor   //or graph_traits<Graph>::edge_descriptor    //forward declaration (defining defaults)  template <typename Graph,            typename FaceHandlesMap,            typename ValueType,            typename BicompSideToTraverse = single_side,            typename VisitorType = lead_visitor,            typename Time = current_iteration            >  class face_iterator;    template <typename Graph, bool StoreEdge>  struct edge_storage  {};  template <typename Graph>  struct edge_storage <Graph, true>  {    typename graph_traits<Graph>::edge_descriptor value;  };  //specialization for TraversalType = traverse_vertices  template <typename Graph,            typename FaceHandlesMap,            typename ValueType,            typename TraversalType,            typename VisitorType,            typename Time            >  class face_iterator      : public boost::iterator_facade < face_iterator<Graph,                                                      FaceHandlesMap,                                                      ValueType,                                                      TraversalType,                                                      VisitorType,                                                      Time                                                      >,                                        ValueType,                                        boost::forward_traversal_tag,                                        ValueType                                       >  {  public:    typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;    typedef typename graph_traits<Graph>::edge_descriptor edge_t;    typedef face_iterator       <Graph,FaceHandlesMap,ValueType,TraversalType,VisitorType,Time> self;    typedef typename FaceHandlesMap::value_type face_handle_t;    face_iterator() :       m_lead(graph_traits<Graph>::null_vertex()),      m_follow(graph_traits<Graph>::null_vertex())    {}    template <typename TraversalSubType>    face_iterator(face_handle_t anchor_handle,                   FaceHandlesMap face_handles,                   TraversalSubType traversal_type):      m_follow(anchor_handle.get_anchor()),       m_face_handles(face_handles)    {      set_lead_dispatch(anchor_handle, traversal_type);    }    template <typename TraversalSubType>    face_iterator(vertex_t anchor,                   FaceHandlesMap face_handles,                   TraversalSubType traversal_type):      m_follow(anchor),       m_face_handles(face_handles)    {      set_lead_dispatch(m_face_handles[anchor], traversal_type);    }  private:        friend class boost::iterator_core_access;        inline vertex_t get_first_vertex(face_handle_t anchor_handle,                                      current_iteration                                     )    {      return anchor_handle.first_vertex();    }    inline vertex_t get_second_vertex(face_handle_t anchor_handle,                                       current_iteration                                      )    {      return anchor_handle.second_vertex();    }    inline vertex_t get_first_vertex(face_handle_t anchor_handle,                                      previous_iteration                                     )    {      return anchor_handle.old_first_vertex();    }    inline vertex_t get_second_vertex(face_handle_t anchor_handle,                                       previous_iteration                                      )    {      return anchor_handle.old_second_vertex();    }    inline void set_lead_dispatch(face_handle_t anchor_handle, first_side)    {      m_lead = get_first_vertex(anchor_handle, Time());      set_edge_to_first_dispatch(anchor_handle, ValueType(), Time());    }        inline void set_lead_dispatch(face_handle_t anchor_handle, second_side)    {      m_lead = get_second_vertex(anchor_handle, Time());      set_edge_to_second_dispatch(anchor_handle, ValueType(), Time());    }    inline void set_edge_to_first_dispatch(face_handle_t anchor_handle,                                            edge_t,                                            current_iteration                                           )    {      m_edge.value = anchor_handle.first_edge();    }    inline void set_edge_to_second_dispatch(face_handle_t anchor_handle,                                             edge_t,                                             current_iteration                                            )    {      m_edge.value = anchor_handle.second_edge();    }    inline void set_edge_to_first_dispatch(face_handle_t anchor_handle,                                            edge_t,                                            previous_iteration                                           )    {      m_edge.value = anchor_handle.old_first_edge();    }    inline void set_edge_to_second_dispatch(face_handle_t anchor_handle,                                             edge_t,                                             previous_iteration                                            )    {      m_edge.value = anchor_handle.old_second_edge();    }        template<typename T>    inline void set_edge_to_first_dispatch(face_handle_t, vertex_t, T)    {}    template<typename T>    inline void set_edge_to_second_dispatch(face_handle_t, vertex_t, T)    {}    void increment()    {      face_handle_t curr_face_handle(m_face_handles[m_lead]);      vertex_t first = get_first_vertex(curr_face_handle, Time());      vertex_t second = get_second_vertex(curr_face_handle, Time());      if (first == m_follow)        {          m_follow = m_lead;          set_edge_to_second_dispatch(curr_face_handle, ValueType(), Time());          m_lead = second;        }      else if (second == m_follow)        {          m_follow = m_lead;          set_edge_to_first_dispatch(curr_face_handle, ValueType(), Time());          m_lead = first;        }      else        m_lead = m_follow = graph_traits<Graph>::null_vertex();    }        bool equal(self const& other) const    {      return m_lead == other.m_lead && m_follow == other.m_follow;    }        ValueType dereference() const     {       return dereference_dispatch(VisitorType(), ValueType());    }        inline ValueType dereference_dispatch(lead_visitor, vertex_t) const     { return m_lead; }        inline ValueType dereference_dispatch(follow_visitor, vertex_t) const     { return m_follow; }    inline ValueType dereference_dispatch(lead_visitor, edge_t) const     { return m_edge.value; }    inline ValueType dereference_dispatch(follow_visitor, edge_t) const     { return m_edge.value; }    vertex_t m_lead;    vertex_t m_follow;	edge_storage<Graph, boost::is_same<ValueType, edge_t>::value > m_edge;    FaceHandlesMap m_face_handles;  };    template <typename Graph,            typename FaceHandlesMap,            typename ValueType,            typename VisitorType,            typename Time            >  class face_iterator     <Graph, FaceHandlesMap, ValueType, both_sides, VisitorType, Time>    : public boost::iterator_facade< face_iterator<Graph,                                                   FaceHandlesMap,                                                   ValueType,                                                   both_sides,                                                   VisitorType,                                                   Time>,                                     ValueType,                                     boost::forward_traversal_tag,                                     ValueType >  {  public:    typedef face_iterator      <Graph,FaceHandlesMap,ValueType,both_sides,VisitorType,Time> self;    typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;    typedef typename FaceHandlesMap::value_type face_handle_t;    face_iterator() {}    face_iterator(face_handle_t anchor_handle, FaceHandlesMap face_handles):      first_itr(anchor_handle, face_handles, first_side()),      second_itr(anchor_handle, face_handles, second_side()),      first_is_active(true),      first_increment(true)    {}    face_iterator(vertex_t anchor, FaceHandlesMap face_handles):      first_itr(face_handles[anchor], face_handles, first_side()),      second_itr(face_handles[anchor], face_handles, second_side()),      first_is_active(true),      first_increment(true)    {}      private:        friend class boost::iterator_core_access;    typedef face_iterator      <Graph, FaceHandlesMap, ValueType, single_side, follow_visitor, Time>       inner_itr_t;        void increment()    {      if (first_increment)        {          ++first_itr;          ++second_itr;          first_increment = false;        }      else if (first_is_active)        ++first_itr;      else        ++second_itr;      first_is_active = !first_is_active;    }        bool equal(self const& other) const    {      //Want this iterator to be equal to the "end" iterator when at least      //one of the iterators has reached the root of the current bicomp.      //This isn't ideal, but it works.      return (first_itr == other.first_itr || second_itr == other.second_itr);    }        ValueType dereference() const     {       return first_is_active ? *first_itr : *second_itr;    }    inner_itr_t first_itr;    inner_itr_t second_itr;    inner_itr_t face_end;    bool first_is_active;    bool first_increment;  };    } /* namespace boost */#endif //__FACE_ITERATORS_HPP__

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -