Tulip  5.2.0
Large graphs analysis and drawing
ForEach.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 
20 #ifndef Tulip_FOREACH_H
21 #define Tulip_FOREACH_H
22 
23 #include <cassert>
24 #include <tulip/Iterator.h>
25 #include <tulip/StableIterator.h>
26 #include <tulip/tulipconf.h>
27 
28 ///@cond DOXYGEN_HIDDEN
29 namespace tlp {
30 /**
31 * @brief Encapsulation of a Tulip Iterator intended to be allocated on the stack instead of the
32 *heap,
33 * so it gets deleted when out of scope.
34 *
35 **/
36 template <typename TYPE>
37 struct _TLP_IT {
38  _TLP_IT(Iterator<TYPE> *_it) : _it(_it) {}
39  ~_TLP_IT() {
40  delete _it;
41  }
42  Iterator<TYPE> *_it;
43 };
44 
45 /**
46 * @brief
47 **/
48 template <typename TYPE>
49 inline bool _tlp_if_test(TYPE &n, _TLP_IT<TYPE> &_it) {
50  assert(_it._it != nullptr);
51 
52  if (_it._it->hasNext()) {
53  n = _it._it->next();
54  return true;
55  } else {
56  return false;
57  }
58 }
59 }
60 ///@endcond
61 
62 /**
63  * @brief Allows to iterate the nodes or edges of a Graph in a clear and concise way.
64  * It also avoid having to manage a tulip Iterator, whose deletion is often forgotten.
65  *
66  * This code shows how forEach can be used instead of an Iterator to iterate a Graph's nodes
67  * @code
68  * node n;
69  * forEach(n, graph->getNodes()) {
70  * // Do something with node n
71  * }
72  * @endcode
73  *
74  * This macro can be used with any Iterator subclass as it's based on the existence of the next()
75  * and hasNext() methods
76  */
77 #define forEach(A, B) \
78  for (tlp::_TLP_IT<decltype(A)> _it_foreach(B); tlp::_tlp_if_test(A, _it_foreach);)
79 
80 /**
81  * @brief Allows to iterate the nodes or edges of a copy of a Graph in a clear and concise way.
82  * The stable Iterator creates a copy of the Graph, and iterates on the said copy.
83  * It allows deletion operations to be performed without invalidating the iterator.
84  * It also avoid having to manage a tulip Iterator, whose deletion is often forgotten.
85  */
86 #define stableForEach(A, B) \
87  for (tlp::_TLP_IT<decltype(A)> _it_foreach(new tlp::StableIterator<decltype(A)>(B)); \
88  tlp::_tlp_if_test(A, _it_foreach);)
89 
90 #endif