forall.h

Go to the documentation of this file.
00001 
00049 #ifndef UTIL_FORALL_HPP
00050 #define UTIL_FORALL_HPP
00051 #include <config.h>
00052 #include <iterator>
00053 #include <utility>
00054 
00055 // Functions begin and end of the new standard
00056 namespace std
00057 {
00058   template <typename T>
00059   const T& begin(const pair<T,T>& p)
00060   {
00061     return p.first;
00062   }
00063   template <typename T>
00064   const T& end(const pair<T,T>& p)
00065   {
00066     return p.second;
00067   }
00068 };
00069 
00070 namespace util
00071 {
00073   namespace ForAll
00074   {
00075     struct BaseForwardIter
00076     {
00077       virtual ~BaseForwardIter() {}
00078     };
00079 
00080     template <typename iterator>
00081       struct ForwardIter : public BaseForwardIter
00082       {
00083         typedef typename std::iterator_traits<iterator>::value_type value_type;
00084         typedef typename std::iterator_traits<iterator>::reference reference;
00085 
00086         ForwardIter( const iterator& fst, const iterator& lst )
00087           : it( fst )
00088           , end( lst )
00089           , brk( 0 ) {}
00090 
00091         const reference value() const { ++brk; return *it; }
00092         bool is_end() const { return brk || ( it == end ); }
00093         bool is_simple_end() const { return it == end; }
00094         mutable iterator it;
00095         iterator end;
00096         mutable int brk;
00097       };
00098 
00099     template <typename Pair, typename iterator>
00100       inline ForwardIter<iterator>
00101       forwardIter( const Pair& range, const iterator* )
00102       {
00103         return ForwardIter<iterator>( range.first, range.second );
00104       }
00105 
00106     template <typename iterator>
00107       inline const ForwardIter<iterator>*
00108       castForwardIter( const BaseForwardIter* base, const iterator* )
00109       {
00110         return static_cast< const ForwardIter<iterator>* >( base );
00111       }
00112 
00113     template <typename T> inline T* pointer( const T& ) { return 0; }
00114 
00115     template <typename Container>
00116       std::pair<typename Container::iterator, typename Container::iterator> make_range( Container& cont )
00117       {
00118         return std::make_pair( cont.begin(), cont.end() );
00119       }
00120 
00121     template <typename Container>
00122       std::pair<typename Container::const_iterator, typename Container::const_iterator> make_range( const Container& cont )
00123       {
00124         return std::make_pair( cont.begin(), cont.end() );
00125       }
00126 
00127     template <typename Iterator>
00128       std::pair<Iterator,Iterator> make_range( const std::pair<Iterator,Iterator>& cont )
00129       {
00130         return cont;
00131       }
00132 
00133     template <typename Container>
00134       std::pair<typename Container::reverse_iterator, typename Container::reverse_iterator> make_reverse_range( Container& cont )
00135       {
00136         return std::make_pair( cont.rbegin(), cont.rend() );
00137       }
00138 
00139     template <typename Container>
00140       std::pair<typename Container::const_reverse_iterator, typename Container::const_reverse_iterator> make_reverse_range( const Container& cont )
00141       {
00142         return std::make_pair( cont.rbegin(), cont.rend() );
00143       }
00144 
00145     template <typename Iterator>
00146       std::pair<std::reverse_iterator<Iterator>,std::reverse_iterator<Iterator> > make_reverse_range( const std::pair<Iterator,Iterator>& cont )
00147       {
00148         typedef std::reverse_iterator<Iterator> reverse_it;
00149         return make_pair(reverse_it(cont.second), reverse_it(cont.first));
00150       }
00151 
00152     template <typename Iterator>
00153       struct Range
00154     {
00155       typedef Iterator iterator;
00156 
00157       Range(const Iterator& first, const Iterator& second)
00158         : it(first)
00159         , last(second)
00160         {}
00161 
00162       iterator begin() { return it; }
00163       iterator end() { return last; }
00164 
00165       bool atEnd() { return it == last; }
00166       Range& operator++() { ++it; return *this; }
00167 
00168       iterator current() { return it; }
00169 
00170       iterator it, last;
00171     };
00172 
00173     template <typename Iterator>
00174     Range<Iterator> range(const std::pair<Iterator,Iterator>& cont) { return Range<Iterator>(cont.first, cont.second); }
00175 
00176     template <typename Container>
00177     Range<typename Container::iterator> range(Container& cont) { return Range<typename Container::iterator>(cont.begin(), cont.end()); }
00178 
00179     template <typename Container>
00180     Range<typename Container::const_iterator> range(const Container& cont) { return Range<typename Container::const_iterator>(cont.begin(), cont.end()); }
00181 
00182   }
00183 
00184 #define forall_pointer( obj ) ( true ? 0 : util::ForAll::pointer( obj ) )
00185 
00186 
00191 #define forall_range( typed_var, range ) \
00192 for( const util::ForAll::BaseForwardIter& iter = util::ForAll::forwardIter( range, forall_pointer( (range).first ) ) ; \
00193 !util::ForAll::castForwardIter( &iter, forall_pointer( (range).first ) )->is_end() ;\
00194 ++( util::ForAll::castForwardIter( &iter, forall_pointer( (range).first ) )->it ) ) \
00195 for( typed_var = util::ForAll::castForwardIter( &iter, forall_pointer( (range).first ) )->value() ; \
00196 util::ForAll::castForwardIter( &iter, forall_pointer( (range).first ) )->brk ; \
00197 --( util::ForAll::castForwardIter( &iter, forall_pointer( (range).first ) )->brk ) )
00198 
00209 #ifdef USE_CXX0X
00210 #  define forall( typed_var, cont ) for( typed_var : util::ForAll::range( cont ) )
00211 #else
00212 #  define forall( typed_var, cont ) forall_range( typed_var, util::ForAll::make_range( cont ) )
00213 #endif
00214 
00226 #define forall_reverse( typed_var, cont ) forall_range( typed_var, util::ForAll::make_reverse_range( cont ) )
00227 
00234 #define forall_named( typed_var, cont, name ) forall_range( typed_var, std::make_pair( (cont).begin_##name(), (cont).end_##name() ) )
00235 }
00236 
00237 #endif // UTIL_FORALL_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Fri May 31 15:37:53 2013 for VVE by  doxygen 1.6.3