Tulip  5.3.0
Large graphs analysis and drawing
BasicIterators.h
1 /*
2  *
3  * This file is part of Tulip (http://tulip.labri.fr)
4  *
5  * Authors: David Auber and the Tulip development Team
6  * from LaBRI, University of Bordeaux
7  *
8  * Tulip is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation, either version 3
11  * of the License, or (at your option) any later version.
12  *
13  * Tulip is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU General Public License for more details.
17  *
18  */
19 ///@cond DOXYGEN_HIDDEN
20 
21 #ifndef TULIP_BASICITERATORS_H
22 #define TULIP_BASICITERATORS_H
23 #include <tulip/Iterator.h>
24 #include <tulip/memorypool.h>
25 #include <tulip/MutableContainer.h>
26 
27 namespace tlp {
28 
29 class Graph;
30 class GraphImpl;
31 class GraphView;
32 
33 struct node;
34 struct edge;
35 class TLP_SCOPE NodeIterator : public Iterator<node> {};
36 
37 class TLP_SCOPE EdgeIterator : public Iterator<edge> {};
38 
39 //===========================================================
40 /// Factorization of code for iterators
41 class TLP_SCOPE FactorNodeIterator : public NodeIterator {
42 protected:
43  Graph *_parentGraph;
44  void *ito;
45  void enableListening(const Graph *sg);
46  void disableListening(const Graph *sg);
47 
48 public:
49  FactorNodeIterator(const Graph *sg) : _parentGraph(sg->getSuperGraph()), ito(nullptr) {}
50 };
51 
52 class TLP_SCOPE FactorEdgeIterator : public EdgeIterator {
53 protected:
54  const Graph *_parentGraph;
55  void *ito;
56  void enableListening(const Graph *sg);
57  void disableListening(const Graph *sg);
58 
59 public:
60  FactorEdgeIterator(const Graph *sg) : _parentGraph(sg->getSuperGraph()), ito(nullptr) {}
61 };
62 //============================================================
63 /// Subgraph node iterator
64 //============================================================
65 /// Node iterator for GraphView
66 template <typename VALUE_TYPE>
67 class SGraphNodeIterator : public FactorNodeIterator,
68  public MemoryPool<SGraphNodeIterator<VALUE_TYPE>> {
69 private:
70  const Graph *sg;
71  Iterator<node> *it;
72  node curNode;
73  VALUE_TYPE value;
74  const MutableContainer<VALUE_TYPE> &_filter;
75 
76 protected:
77  void prepareNext() {
78  while (it->hasNext()) {
79  curNode = it->next();
80 
81  if (_filter.get(curNode) == value)
82  return;
83  }
84 
85  // set curNode as invalid
86  curNode = node();
87  }
88 
89 public:
90  SGraphNodeIterator(const Graph *sG, const MutableContainer<VALUE_TYPE> &filter,
91  typename tlp::StoredType<VALUE_TYPE>::ReturnedConstValue val)
92  : FactorNodeIterator(sG), sg(sG), value(val), _filter(filter) {
93  enableListening(sg);
94  it = sg->getNodes();
95  // anticipate first iteration
96  prepareNext();
97  }
98 
99  ~SGraphNodeIterator() override {
100  disableListening(sg);
101  delete it;
102  }
103 
104  node next() override {
105  assert(curNode.isValid());
106  // we are already pointing to the next
107  node tmp = curNode;
108  // anticipate next iteration
109  prepareNext();
110  return tmp;
111  }
112 
113  bool hasNext() override {
114  return (curNode.isValid());
115  }
116 };
117 
118 //=============================================================
119 /// subgraph edges iterator
120 template <typename VALUE_TYPE>
121 class SGraphEdgeIterator : public FactorEdgeIterator,
122  public MemoryPool<SGraphEdgeIterator<VALUE_TYPE>> {
123 private:
124  const Graph *sg;
125  Iterator<edge> *it;
126  edge curEdge;
127  VALUE_TYPE value;
128  const MutableContainer<VALUE_TYPE> &_filter;
129 
130 protected:
131  void prepareNext() {
132  while (it->hasNext()) {
133  curEdge = it->next();
134 
135  if (_filter.get(curEdge.id) == value)
136  return;
137  }
138 
139  // set curEdge as invalid
140  curEdge = edge();
141  }
142 
143 public:
144  SGraphEdgeIterator(const Graph *sG, const MutableContainer<VALUE_TYPE> &filter,
145  typename tlp::StoredType<VALUE_TYPE>::ReturnedConstValue val)
146  : FactorEdgeIterator(sG), sg(sG), value(val), _filter(filter) {
147  it = sg->getEdges();
148  // anticipate first iteration
149  prepareNext();
150  }
151 
152  ~SGraphEdgeIterator() override {
153  delete it;
154  }
155 
156  edge next() override {
157  assert(curEdge.isValid());
158  // we are already pointing to the next
159  edge tmp = curEdge;
160  // anticipating the next iteration
161  prepareNext();
162  return tmp;
163  }
164 
165  bool hasNext() override {
166  return (curEdge.isValid());
167  }
168 };
169 } // namespace tlp
170 #endif
171 
172 ///@endcond