00001
00049 #ifndef UTIL_FORALL_HPP
00050 #define UTIL_FORALL_HPP
00051 #include <config.h>
00052 #include <iterator>
00053 #include <utility>
00054
00055
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