ModErn Text Analysis
META Enumerates Textual Applications
edge_iterator.h
Go to the documentation of this file.
1 
10 // forward declare (if necessary) both graph types so they can be used in
11 // edge_iterator constructor
12 #ifndef META_UNDIRECTED_GRAPH_H_
13 template <class A, class B>
15 #endif
16 #ifndef META_DIRECTED_GRAPH_H_
17 template <class A, class B>
19 #endif
20 
21 template <class Iter>
22 class edge_iterator : public std::iterator<std::forward_iterator_tag, Edge>
23 {
24  public:
25  typedef typename graph<Node, Edge>::adjacency_list adj_list;
26  typedef edge_iterator self_type;
27  typedef typename std::
28  conditional<std::is_same<Iter, typename vec_t::const_iterator>::value,
29  const Edge, Edge>::type value_type;
30  typedef value_type& reference;
31  typedef value_type* pointer;
32  typedef std::forward_iterator_tag iterator_category;
33  typedef ptrdiff_t difference_type;
34 
35  friend bool operator==(const self_type& lhs, const self_type& rhs)
36  {
37  return lhs.iter_ == rhs.iter_ && lhs.end_ == rhs.end_;
38  }
39 
40  friend bool operator!=(const self_type& lhs, const self_type& rhs)
41  {
42  return !(lhs == rhs);
43  }
44 
45  edge_iterator(const undirected_graph<Node, Edge>* handle, const Iter& iter,
46  const Iter& end_iter)
47  : iter_{iter},
48  end_{iter == end_iter},
49  beg_iter_{iter},
50  end_iter_{end_iter},
51  is_undirected_{true}
52  {
53  init(handle->num_edges());
54  }
55 
56  edge_iterator(const directed_graph<Node, Edge>* handle, const Iter& iter,
57  const Iter& end_iter)
58  : iter_{iter},
59  end_{iter == end_iter},
60  beg_iter_{iter},
61  end_iter_{end_iter},
62  is_undirected_{false}
63  {
64  init(handle->num_edges());
65  }
66 
67  void init(uint64_t num_edges)
68  {
69  if (num_edges == 0)
70  {
71  iter_ = end_iter_;
72  end_ = true;
73  }
74  else if (iter_ != end_iter_)
75  {
76  al_iter_ = iter_->second.begin();
77  if (iter_->second.empty())
78  ++(*this);
79  }
80  }
81 
82  self_type operator++()
83  {
84  if (++al_iter_ == iter_->second.end())
85  {
86  while (++iter_ != end_iter_ && iter_->second.empty())
87  /* nothing */;
88  if (iter_ != end_iter_)
89  al_iter_ = iter_->second.begin();
90  else
91  end_ = true;
92  }
93 
94  // use this inequality to not display duplicate edges since each edge is
95  // stored twice in an undirected graph
96  if (is_undirected_ && !end_
97  && al_iter_->first
98  < static_cast<uint64_t>(std::distance(beg_iter_, iter_)))
99  return ++(*this);
100 
101  return *this;
102  }
103 
104  self_type operator++(int)
105  {
106  self_type saved{*this};
107  ++(*this);
108  return saved;
109  }
110 
111  reference operator*()
112  {
113  return al_iter_->second;
114  }
115 
116  pointer operator->()
117  {
118  return &al_iter_->second;
119  }
120 
121  private:
122  Iter iter_;
123  typename std::
124  conditional<std::is_same<Iter, typename vec_t::const_iterator>::value,
125  typename adj_list::const_iterator,
126  typename adj_list::iterator>::type al_iter_;
127  bool end_;
128  Iter beg_iter_;
129  Iter end_iter_;
130  bool is_undirected_;
131 };
Definition: edge_iterator.h:22
Definition: edge_iterator.h:18
Definition: edge_iterator.h:14