Tulip
4.6.0
Better Visualization Through Research
|
00001 /* 00002 * 00003 * This file is part of Tulip (www.tulip-software.org) 00004 * 00005 * Authors: David Auber and the Tulip development Team 00006 * from LaBRI, University of Bordeaux 00007 * 00008 * Tulip is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU Lesser General Public License 00010 * as published by the Free Software Foundation, either version 3 00011 * of the License, or (at your option) any later version. 00012 * 00013 * Tulip is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00016 * See the GNU General Public License for more details. 00017 * 00018 */ 00019 00020 #ifndef Tulip_FOREACH_H 00021 #define Tulip_FOREACH_H 00022 00023 #include <cassert> 00024 #include <tulip/Iterator.h> 00025 #include <tulip/StableIterator.h> 00026 #include <tulip/tulipconf.h> 00027 00028 #ifndef DOXYGEN_NOTFOR_DEVEL 00029 namespace tlp { 00030 /** 00031 * @brief Encapsulation of a Tulip Iterator intended to be allocated on the stack instead of the heap, 00032 * so it gets deleted when out of scope. 00033 * 00034 **/ 00035 template<typename TYPE> 00036 struct _TLP_IT { 00037 _TLP_IT(Iterator<TYPE> *_it) : _it(_it) { 00038 } 00039 ~_TLP_IT() { 00040 delete _it; 00041 } 00042 Iterator<TYPE> *_it; 00043 }; 00044 00045 /** 00046 * @brief 00047 **/ 00048 template<typename TYPE> 00049 inline bool _tlp_if_test(TYPE &n, _TLP_IT<TYPE> &_it) { 00050 assert(_it._it != NULL); 00051 00052 if(_it._it->hasNext()) { 00053 n = _it._it->next(); 00054 return true; 00055 } 00056 else { 00057 return false; 00058 } 00059 } 00060 } 00061 #endif //DOXYGEN_NOTFOR_DEVEL 00062 00063 /** 00064 * @brief Allows to iterate the nodes or edges of a Graph in a clear and concise way. 00065 * It also avoid having to manage a tulip Iterator, whose deletion is often forgotten. 00066 * 00067 * This code shows how forEach can be used instead of an Iterator to iterate a Graph's nodes 00068 * @code 00069 * node n; 00070 * forEach(n, graph->getNodes()) { 00071 * // Do something with node n 00072 * } 00073 * @endcode 00074 * 00075 * This macro can be used with any Iterator subclass as it's based on the existence of the next() and hasNext() methods 00076 */ 00077 #define forEach(A, B) \ 00078 for(tlp::_TLP_IT<TYPEOF(A) > _it_foreach(B); tlp::_tlp_if_test(A, _it_foreach);) 00079 00080 /** 00081 * @brief Allows to iterate the nodes or edges of a copy of a Graph in a clear and concise way. 00082 * The stable Iterator creates a copy of the Graph, and iterates on the said copy. 00083 * It allows deletion operations to be performed without invalidating the iterator. 00084 * It also avoid having to manage a tulip Iterator, whose deletion is often forgotten. 00085 */ 00086 #define stableForEach(A, B) \ 00087 for(tlp::_TLP_IT<TYPEOF(A) > _it_foreach(new StableIterator<TYPEOF(A) >(B)); tlp::_tlp_if_test(A, _it_foreach);) 00088 00089 #if defined(__GXX_EXPERIMENTAL_CXX0X__) 00090 namespace tlp { 00091 00092 template<typename T> 00093 class iterator_t { 00094 public: 00095 enum IteratorType { 00096 Begin = 0, 00097 End = 1 00098 }; 00099 00100 iterator_t(tlp::Iterator<T>* it, IteratorType begin = End) : _finished(false), _iteratorType(begin), _it(it) { 00101 if(_iteratorType == Begin) { 00102 if(_it->hasNext()) { 00103 _current = _it->next(); 00104 } 00105 else { 00106 _finished = true; 00107 } 00108 } 00109 } 00110 00111 ~iterator_t() { 00112 if(_iteratorType == Begin) { 00113 delete _it; 00114 } 00115 } 00116 00117 bool operator!=(const iterator_t&) const { 00118 return !_finished; 00119 } 00120 00121 const iterator_t& operator++() { 00122 _finished = !_it->hasNext(); 00123 00124 if(!_finished) 00125 _current = _it->next(); 00126 00127 return *this; 00128 } 00129 00130 T operator*() const { 00131 return _current; 00132 } 00133 00134 protected: 00135 bool _finished; 00136 IteratorType _iteratorType; 00137 tlp::Iterator<T>* _it; 00138 T _current; 00139 }; 00140 00141 template<typename T> 00142 iterator_t<T> begin(tlp::Iterator<T>* it) { 00143 return iterator_t<T>(it, iterator_t<T>::Begin); 00144 } 00145 00146 template<typename T> 00147 iterator_t<T> end(tlp::Iterator<T>* it) { 00148 return iterator_t<T>(it); 00149 } 00150 00151 } 00152 #endif //__GXX_EXPERIMENTAL_CXX0X__ 00153 00154 #endif