Tulip  4.6.0
Better Visualization Through Research
library/tulip-core/include/tulip/ForEach.h
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
 All Classes Files Functions Variables Enumerations Enumerator Properties