Tulip  4.2.0
Better Visualization Through Research
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties Groups Pages
ForEach.h
1 /*
2  *
3  * This file is part of Tulip (www.tulip-software.org)
4  *
5  * Authors: David Auber and the Tulip development Team
6  * from LaBRI, University of Bordeaux 1 and Inria Bordeaux - Sud Ouest
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 #ifndef DOXYGEN_NOTFOR_DEVEL
29 namespace tlp {
30 /**
31 * @brief Encapsulation of a Tulip Iterator intended to be allocated on the stack instead of the heap,
32 * so it gets deleted when out of scope.
33 *
34 **/
35 template<typename TYPE>
36 struct _TLP_IT {
37  _TLP_IT(Iterator<TYPE> *_it) : _it(_it) {
38  }
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 != NULL);
51 
52  if(_it._it->hasNext()) {
53  n = _it._it->next();
54  return true;
55  }
56  else {
57  return false;
58  }
59 }
60 }
61 #endif //DOXYGEN_NOTFOR_DEVEL
62 
63 /**
64  * @brief Allows to iterate on the nodes or edges of a Graph in a clear and concise way.
65  * It also avoid having to manage a tulip Iterator, whose deletion is often forgotten.
66  *
67  * This code shows how forEach can be used instead of an Iterator to iterate over a Graph's nodes
68  * @code
69  * node n;
70  * forEach(n, graph->getNodes()) {
71  * // Do something with node n
72  * }
73  * @endcode
74  *
75  * This macro can be used with any Iterator subclass as it's based on the existence of the next() and hasNext() methods
76  */
77 #define forEach(A, B) \
78 for(tlp::_TLP_IT<TYPEOF(A) > _it_foreach(B); tlp::_tlp_if_test(A, _it_foreach);)
79 
80 /**
81  * @brief Allows to iterate on 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<TYPEOF(A) > _it_foreach(new StableIterator<TYPEOF(A) >(B)); tlp::_tlp_if_test(A, _it_foreach);)
88 
89 #if defined(__GXX_EXPERIMENTAL_CXX0X__)
90 namespace tlp {
91 
92 template<typename T>
93 class iterator_t {
94 public:
95  enum IteratorType {
96  Begin = 0,
97  End = 1
98  };
99 
100  iterator_t(tlp::Iterator<T>* it, IteratorType begin = End) : _finished(false), _iteratorType(begin), _it(it) {
101  if(_iteratorType == Begin) {
102  if(_it->hasNext()) {
103  _current = _it->next();
104  }
105  else {
106  _finished = true;
107  }
108  }
109  }
110 
111  ~iterator_t() {
112  if(_iteratorType == Begin) {
113  delete _it;
114  }
115  }
116 
117  bool operator!=(const iterator_t&) const {
118  return !_finished;
119  }
120 
121  const iterator_t& operator++() {
122  _finished = !_it->hasNext();
123 
124  if(!_finished)
125  _current = _it->next();
126 
127  return *this;
128  }
129 
130  T operator*() const {
131  return _current;
132  }
133 
134 protected:
135  bool _finished;
136  IteratorType _iteratorType;
137  tlp::Iterator<T>* _it;
138  T _current;
139 };
140 
141 template<typename T>
142 iterator_t<T> begin(tlp::Iterator<T>* it) {
143  return iterator_t<T>(it, iterator_t<T>::Begin);
144 }
145 
146 template<typename T>
147 iterator_t<T> end(tlp::Iterator<T>* it) {
148  return iterator_t<T>(it);
149 }
150 
151 }
152 #endif //__GXX_EXPERIMENTAL_CXX0X__
153 
154 #endif