BALL
1.4.1
|
00001 // -*- Mode: C++; tab-width: 2; -*- 00002 // vi: set ts=2: 00003 // 00004 00005 #ifndef BALL_CONCEPT_BIDIRECTIONALITERATOR_H 00006 #define BALL_CONCEPT_BIDIRECTIONALITERATOR_H 00007 00008 #ifndef BALL_CONCEPT_FORWARDITERATOR_H 00009 # include <BALL/CONCEPT/forwardIterator.h> 00010 #endif 00011 00012 namespace BALL 00013 { 00014 00019 00022 template <typename Container, typename DataType, typename Position, typename Traits> 00023 class ConstBidirectionalIterator 00024 : public ConstForwardIterator<Container, DataType, Position, Traits> 00025 { 00026 public: 00027 00031 00033 typedef std::bidirectional_iterator_tag iterator_category; 00034 // convenience typedef 00035 typedef ConstForwardIterator<Container, DataType, Position, Traits> Base; 00037 00041 00043 BALL_INLINE ConstBidirectionalIterator() {} 00044 00046 BALL_INLINE ConstBidirectionalIterator(const ConstBidirectionalIterator& iterator) 00047 : Base(iterator) 00048 { 00049 } 00050 00052 BALL_INLINE ~ConstBidirectionalIterator() {} 00054 00058 00062 BALL_INLINE void toBegin(); 00063 00065 BALL_INLINE bool isBegin() const { return Base::getTraits().isBegin(); } 00066 00070 void toEnd(); 00071 00073 BALL_INLINE bool isEnd() const { return Base::getTraits().isEnd(); } 00074 00078 void toRBegin(); 00079 00081 BALL_INLINE bool isRBegin() const { return Base::getTraits().isRBegin(); } 00082 00086 void toREnd(); 00087 00089 BALL_INLINE bool isREnd() const { return Base::getTraits().isREnd(); } 00090 00094 BALL_INLINE ConstBidirectionalIterator& operator ++ (); 00095 00099 BALL_INLINE ConstBidirectionalIterator operator ++ (int); 00100 00104 BALL_INLINE ConstBidirectionalIterator& operator -- (); 00105 00109 BALL_INLINE ConstBidirectionalIterator operator -- (int); 00110 00114 static ConstBidirectionalIterator begin(const Container& container); 00115 00119 static ConstBidirectionalIterator end(const Container& container); 00120 00124 static ConstBidirectionalIterator rbegin(const Container& container); 00125 00129 static ConstBidirectionalIterator rend(const Container& container); 00131 00132 protected: 00133 00135 BALL_INLINE ConstBidirectionalIterator(const Container& container) 00136 : Base(container) 00137 { 00138 } 00139 }; 00141 00142 template <typename Container, typename DataType, typename Position, typename Traits> 00143 BALL_INLINE 00144 void ConstBidirectionalIterator<Container, DataType, Position, Traits>::toBegin() 00145 { 00146 BALL_PRECONDITION_EXCEPTION(!Base::getTraits().isSingular(), "cannot set unbound iterator to begin") 00147 Base::getTraits().toBegin(); 00148 } 00149 00150 template <typename Container, typename DataType, typename Position, typename Traits> 00151 BALL_INLINE 00152 void ConstBidirectionalIterator<Container, DataType, Position, Traits>::toEnd() 00153 { 00154 BALL_PRECONDITION_EXCEPTION(!Base::getTraits().isSingular(), "cannot set unbound iterator to end") 00155 Base::getTraits().toEnd(); 00156 } 00157 00158 template <typename Container, typename DataType, typename Position, typename Traits> 00159 BALL_INLINE 00160 void ConstBidirectionalIterator<Container, DataType, Position, Traits>::toRBegin() 00161 { 00162 BALL_PRECONDITION_EXCEPTION(!Base::getTraits().isSingular(), "cannot set unbound iterator to reverse begin") 00163 Base::getTraits().toRBegin(); 00164 } 00165 00166 template <typename Container, typename DataType, typename Position, typename Traits> 00167 BALL_INLINE 00168 void ConstBidirectionalIterator<Container, DataType, Position, Traits>::toREnd() 00169 { 00170 BALL_PRECONDITION_EXCEPTION(!Base::getTraits().isSingular(), "cannot set unbound iterator to reverse end") 00171 Base::getTraits().toREnd(); 00172 } 00173 00174 template <typename Container, typename DataType, typename Position, typename Traits> 00175 BALL_INLINE 00176 ConstBidirectionalIterator<Container, DataType, Position, Traits>& 00177 ConstBidirectionalIterator<Container, DataType, Position, Traits>::operator ++ () 00178 { 00179 BALL_PRECONDITION_EXCEPTION(Base::getTraits().isValid(), "cannot increment an invalid iterator") 00180 Base::getTraits().forward(); 00181 return *this; 00182 } 00183 00184 template <typename Container, typename DataType, typename Position, typename Traits> 00185 BALL_INLINE 00186 ConstBidirectionalIterator<Container, DataType, Position, Traits> 00187 ConstBidirectionalIterator<Container, DataType, Position, Traits>::operator ++ (int) 00188 { 00189 BALL_PRECONDITION_EXCEPTION(Base::getTraits().isValid(), "cannot increment an invalid iterator") 00190 ConstBidirectionalIterator iterator(*this); 00191 ++(*this); 00192 return iterator; 00193 } 00194 00195 template <typename Container, typename DataType, typename Position, typename Traits> 00196 BALL_INLINE 00197 ConstBidirectionalIterator<Container, DataType, Position, Traits>& 00198 ConstBidirectionalIterator<Container, DataType, Position, Traits>::operator -- () 00199 { 00200 BALL_PRECONDITION_EXCEPTION(!Base::getTraits().isSingular(), "cannot decrement unbound iterator") 00201 Base::getTraits().backward(); 00202 return *this; 00203 } 00204 00205 template <typename Container, typename DataType, typename Position, typename Traits> 00206 BALL_INLINE 00207 ConstBidirectionalIterator<Container, DataType, Position, Traits> 00208 ConstBidirectionalIterator<Container, DataType, Position, Traits>::operator -- (int) 00209 { 00210 BALL_PRECONDITION_EXCEPTION(!Base::getTraits().isSingular(), "cannot decrement an unbound iterator") 00211 ConstBidirectionalIterator iterator(*this); 00212 --(*this); 00213 return iterator; 00214 } 00215 00216 template <typename Container, typename DataType, typename Position, typename Traits> 00217 BALL_INLINE 00218 ConstBidirectionalIterator<Container, DataType, Position, Traits> 00219 ConstBidirectionalIterator<Container, DataType, Position, Traits>::begin(const Container& container) 00220 { 00221 ConstBidirectionalIterator iterator(container); 00222 iterator.toBegin(); 00223 return iterator; 00224 } 00225 00226 template <typename Container, typename DataType, typename Position, typename Traits> 00227 BALL_INLINE 00228 ConstBidirectionalIterator<Container, DataType, Position, Traits> 00229 ConstBidirectionalIterator<Container, DataType, Position, Traits>::end(const Container& container) 00230 { 00231 ConstBidirectionalIterator iterator(container); 00232 iterator.toEnd(); 00233 return iterator; 00234 } 00235 00236 template <typename Container, typename DataType, typename Position, typename Traits> 00237 BALL_INLINE 00238 ConstBidirectionalIterator<Container, DataType, Position, Traits> 00239 ConstBidirectionalIterator<Container, DataType, Position, Traits>::rbegin(const Container& container) 00240 { 00241 ConstBidirectionalIterator iterator(container); 00242 iterator.toRBegin(); 00243 return iterator; 00244 } 00245 00246 template <typename Container, typename DataType, typename Position, typename Traits> 00247 BALL_INLINE 00248 ConstBidirectionalIterator<Container, DataType, Position, Traits> 00249 ConstBidirectionalIterator<Container, DataType, Position, Traits>::rend(const Container& container) 00250 { 00251 ConstBidirectionalIterator iterator(container); 00252 iterator.toREnd(); 00253 return iterator; 00254 } 00255 00257 template <typename Container, typename DataType, typename Position, typename Traits> 00258 class BidirectionalIterator 00259 : public ConstBidirectionalIterator<Container, DataType, Position, Traits> 00260 { 00261 public: 00262 00266 00268 typedef DataType& reference; 00270 typedef DataType* pointer; 00271 // convenience typedef 00272 typedef ConstBidirectionalIterator<Container, DataType, Position, Traits> Base; 00274 00278 00280 BALL_INLINE BidirectionalIterator() {} 00281 00283 BALL_INLINE BidirectionalIterator(const BidirectionalIterator& iterator) 00284 00285 : ConstBidirectionalIterator<Container, DataType, Position, Traits>(iterator) 00286 { 00287 } 00288 00290 BALL_INLINE ~BidirectionalIterator() {} 00291 00293 00297 00299 BALL_INLINE reference operator * () const { return (reference)Base::getTraits().getData(); } 00300 00302 BALL_INLINE pointer operator -> () const { return (pointer)&Base::getTraits().getData(); } 00303 00307 BALL_INLINE BidirectionalIterator& operator ++ (); 00308 00312 BALL_INLINE BidirectionalIterator operator ++ (int); 00313 00317 BALL_INLINE BidirectionalIterator& operator -- (); 00318 00322 BALL_INLINE BidirectionalIterator operator -- (int); 00323 00327 static BidirectionalIterator begin(const Container& container); 00328 00332 static BidirectionalIterator end(const Container& container); 00333 00337 static BidirectionalIterator rbegin(const Container& container); 00338 00342 static BidirectionalIterator rend(const Container& container); 00344 00345 protected: 00346 00348 BALL_INLINE BidirectionalIterator(const Container& container) ; 00349 }; 00350 00351 00352 template <typename Container, typename DataType, typename Position, typename Traits> 00353 BALL_INLINE 00354 BidirectionalIterator<Container, DataType, Position, Traits>& 00355 BidirectionalIterator<Container, DataType, Position, Traits>::operator ++ () 00356 { 00357 Base::operator ++ (); 00358 return *this; 00359 } 00360 00361 template <typename Container, typename DataType, typename Position, typename Traits> 00362 BALL_INLINE 00363 BidirectionalIterator<Container, DataType, Position, Traits> 00364 BidirectionalIterator<Container, DataType, Position, Traits>::operator ++ (int) 00365 { 00366 BidirectionalIterator iterator(*this); 00367 this->operator ++ (); 00368 return iterator; 00369 } 00370 00371 template <typename Container, typename DataType, typename Position, typename Traits> 00372 BALL_INLINE 00373 BidirectionalIterator<Container, DataType, Position, Traits>& 00374 BidirectionalIterator<Container, DataType, Position, Traits>::operator -- () 00375 { 00376 Base::operator -- (); 00377 return *this; 00378 } 00379 00380 template <typename Container, typename DataType, typename Position, typename Traits> 00381 BALL_INLINE 00382 BidirectionalIterator<Container, DataType, Position, Traits> 00383 BidirectionalIterator<Container, DataType, Position, Traits>::operator -- (int) 00384 { 00385 BidirectionalIterator iterator(*this); 00386 this->operator -- (); 00387 return iterator; 00388 } 00389 00390 template <typename Container, typename DataType, typename Position, typename Traits> 00391 BALL_INLINE 00392 BidirectionalIterator<Container, DataType, Position, Traits> 00393 BidirectionalIterator<Container, DataType, Position, Traits>::begin(const Container& container) 00394 { 00395 BidirectionalIterator iterator(container); 00396 iterator.toBegin(); 00397 return iterator; 00398 } 00399 00400 template <typename Container, typename DataType, typename Position, typename Traits> 00401 BALL_INLINE 00402 BidirectionalIterator<Container, DataType, Position, Traits> 00403 BidirectionalIterator<Container, DataType, Position, Traits>::end(const Container& container) 00404 { 00405 BidirectionalIterator iterator(container); 00406 iterator.toEnd(); 00407 return iterator; 00408 } 00409 00410 template <typename Container, typename DataType, typename Position, typename Traits> 00411 BALL_INLINE 00412 BidirectionalIterator<Container, DataType, Position, Traits> 00413 BidirectionalIterator<Container, DataType, Position, Traits>::rbegin(const Container& container) 00414 { 00415 BidirectionalIterator iterator(container); 00416 iterator.toRBegin(); 00417 return iterator; 00418 } 00419 00420 template <typename Container, typename DataType, typename Position, typename Traits> 00421 BALL_INLINE 00422 BidirectionalIterator<Container, DataType, Position, Traits> 00423 BidirectionalIterator<Container, DataType, Position, Traits>::rend(const Container& container) 00424 { 00425 BidirectionalIterator iterator(container); 00426 iterator.toREnd(); 00427 return iterator; 00428 } 00429 00430 template <typename Container, typename DataType, typename Position, typename Traits> 00431 BALL_INLINE 00432 BidirectionalIterator<Container, DataType, Position, Traits>::BidirectionalIterator(const Container& container) 00433 00434 : ConstBidirectionalIterator<Container, DataType, Position, Traits>(container) 00435 { 00436 } 00437 00438 00439 } // namespace BALL 00440 00441 #endif // BALL_CONCEPT_BIDIRECTIONALITERATOR_H