00001 #pragma once
00002 #ifndef OPENGM_ACCESSOR_ITERATOR
00003 #define OPENGM_ACCESSOR_ITERATOR
00004
00005 #include <iterator>
00006
00007 #include "opengm/opengm.hxx"
00008 #include "opengm/utilities/metaprogramming.hxx"
00009
00010 namespace opengm {
00011
00013
00060 template<class A, bool isConst = false>
00061 class AccessorIterator {
00062 public:
00063 typedef A Accessor;
00064 typedef typename Accessor::value_type value_type;
00065 typedef typename meta::If<isConst, const value_type*, value_type*>::type pointer;
00066 typedef typename meta::If
00067 <
00068 isConst,
00069 typename meta::If
00070 <
00071 meta::IsFundamental<value_type>::value,
00072 const value_type,
00073 const value_type&
00074 >::type,
00075 value_type&
00076 >::type reference;
00077 typedef size_t difference_type;
00078 typedef std::random_access_iterator_tag iterator_category;
00079
00080 AccessorIterator(const Accessor& = Accessor(), const size_t = 0);
00081
00082 template<bool isConstLocal>
00083 bool operator==(const AccessorIterator<A, isConstLocal>&) const;
00084 template<bool isConstLocal>
00085 bool operator!=(const AccessorIterator<A, isConstLocal>&) const;
00086 template<bool isConstLocal>
00087 bool operator<=(const AccessorIterator<A, isConstLocal>&) const;
00088 template<bool isConstLocal>
00089 bool operator>=(const AccessorIterator<A, isConstLocal>&) const;
00090 template<bool isConstLocal>
00091 bool operator<(const AccessorIterator<A, isConstLocal>&) const;
00092 template<bool isConstLocal>
00093 bool operator>(const AccessorIterator<A, isConstLocal>&) const;
00094
00095 pointer operator->();
00096 const value_type* operator->() const;
00097 reference operator*();
00098 const value_type& operator*() const;
00099 reference operator[](const size_t);
00100 const value_type& operator[](const size_t) const;
00101
00102 AccessorIterator<A, isConst>& operator++();
00103 AccessorIterator<A, isConst> operator++(int);
00104 AccessorIterator<A, isConst>& operator--();
00105 AccessorIterator<A, isConst> operator--(int);
00106 AccessorIterator<A, isConst> operator+=(const size_t);
00107 AccessorIterator<A, isConst> operator-=(const size_t);
00108
00109 AccessorIterator<A, isConst> operator+(const size_t) const;
00110 AccessorIterator<A, isConst> operator-(const size_t) const;
00111 template<bool isConstLocal>
00112 size_t operator-(const AccessorIterator<A, isConstLocal>&) const;
00113
00114 private:
00115 void testInvariant() const;
00116
00117 Accessor accessor_;
00118 size_t index_;
00119 };
00120
00121
00122 template<class A, bool isConst>
00123 AccessorIterator<A, isConst> operator+(const size_t, const AccessorIterator<A, isConst>&);
00124
00125
00126
00127 template<class A, bool isConst>
00128 inline
00129 AccessorIterator<A, isConst>::AccessorIterator
00130 (
00131 const typename AccessorIterator<A, isConst>::Accessor& accessor,
00132 const size_t index
00133 )
00134 : accessor_(accessor),
00135 index_(index)
00136 {}
00137
00138 template<class A, bool isConst>
00139 template<bool isConstLocal>
00140 inline bool
00141 AccessorIterator<A, isConst>::operator==
00142 (
00143 const AccessorIterator<A, isConstLocal>& it
00144 ) const
00145 {
00146 OPENGM_ASSERT(it.accessor_ == accessor_);
00147 return it.index_ == index_;
00148 }
00149
00150 template<class A, bool isConst>
00151 template<bool isConstLocal>
00152 inline bool
00153 AccessorIterator<A, isConst>::operator!=
00154 (
00155 const AccessorIterator<A, isConstLocal>& it
00156 ) const
00157 {
00158 OPENGM_ASSERT(it.accessor_ == accessor_);
00159 return it.index_ != index_;
00160 }
00161
00162 template<class A, bool isConst>
00163 template<bool isConstLocal>
00164 inline bool
00165 AccessorIterator<A, isConst>::operator<=
00166 (
00167 const AccessorIterator<A, isConstLocal>& it
00168 ) const
00169 {
00170 OPENGM_ASSERT(it.accessor_ == accessor_);
00171 return index_ <= it.index_;
00172 }
00173
00174 template<class A, bool isConst>
00175 template<bool isConstLocal>
00176 inline bool
00177 AccessorIterator<A, isConst>::operator>=
00178 (
00179 const AccessorIterator<A, isConstLocal>& it
00180 ) const
00181 {
00182 OPENGM_ASSERT(it.accessor_ == accessor_);
00183 return index_ >= it.index_;
00184 }
00185
00186 template<class A, bool isConst>
00187 template<bool isConstLocal>
00188 inline bool
00189 AccessorIterator<A, isConst>::operator<
00190 (
00191 const AccessorIterator<A, isConstLocal>& it
00192 ) const
00193 {
00194 OPENGM_ASSERT(it.accessor_ == accessor_);
00195 return index_ < it.index_;
00196 }
00197
00198 template<class A, bool isConst>
00199 template<bool isConstLocal>
00200 inline bool
00201 AccessorIterator<A, isConst>::operator>
00202 (
00203 const AccessorIterator<A, isConstLocal>& it
00204 ) const
00205 {
00206 OPENGM_ASSERT(it.accessor_ == accessor_);
00207 return index_ > it.index_;
00208 }
00209
00210 template<class A, bool isConst>
00211 inline typename AccessorIterator<A, isConst>::pointer
00212 AccessorIterator<A, isConst>::operator->()
00213 {
00214 OPENGM_ASSERT(index_ < accessor_.size());
00215 return &accessor_[index_];
00216 }
00217
00218 template<class A, bool isConst>
00219 inline const typename AccessorIterator<A, isConst>::value_type*
00220 AccessorIterator<A, isConst>::operator->() const
00221 {
00222 OPENGM_ASSERT(index_ < accessor_.size());
00223 return &accessor_[index_];
00224 }
00225
00226 template<class A, bool isConst>
00227 inline const typename AccessorIterator<A, isConst>::value_type&
00228 AccessorIterator<A, isConst>::operator*() const
00229 {
00230 OPENGM_ASSERT(index_ < accessor_.size());
00231 return accessor_[index_];
00232 }
00233
00234 template<class A, bool isConst>
00235 inline typename AccessorIterator<A, isConst>::reference
00236 AccessorIterator<A, isConst>::operator*()
00237 {
00238 OPENGM_ASSERT(index_ < accessor_.size());
00239 return accessor_[index_];
00240 }
00241
00242 template<class A, bool isConst>
00243 inline const typename AccessorIterator<A, isConst>::value_type&
00244 AccessorIterator<A, isConst>::operator[]
00245 (
00246 const size_t j
00247 ) const
00248 {
00249 OPENGM_ASSERT(index_ + j < accessor_.size());
00250 return accessor_[index_ + j];
00251 }
00252
00253 template<class A, bool isConst>
00254 inline typename AccessorIterator<A, isConst>::reference
00255 AccessorIterator<A, isConst>::operator[]
00256 (
00257 const size_t j
00258 )
00259 {
00260 OPENGM_ASSERT(index_ + j < accessor_.size());
00261 return accessor_[index_ + j];
00262 }
00263
00264 template<class A, bool isConst>
00265 inline AccessorIterator<A, isConst>&
00266 AccessorIterator<A, isConst>::operator++()
00267 {
00268 if(index_ < accessor_.size()) {
00269 ++index_;
00270 }
00271 testInvariant();
00272 return *this;
00273 }
00274
00275 template<class A, bool isConst>
00276 inline AccessorIterator<A, isConst>
00277 AccessorIterator<A, isConst>::operator++(int)
00278 {
00279 if(index_ < accessor_.size()) {
00280 AccessorIterator it = *this;
00281 ++index_;
00282 testInvariant();
00283 return it;
00284 }
00285 else {
00286 return *this;
00287 }
00288 }
00289
00290 template<class A, bool isConst>
00291 inline AccessorIterator<A, isConst>&
00292 AccessorIterator<A, isConst>::operator--()
00293 {
00294 OPENGM_ASSERT(index_ > 0);
00295 --index_;
00296 testInvariant();
00297 return *this;
00298 }
00299
00300 template<class A, bool isConst>
00301 inline AccessorIterator<A, isConst>
00302 AccessorIterator<A, isConst>::operator--(int)
00303 {
00304 OPENGM_ASSERT(index_ > 0);
00305 AccessorIterator it = *this;
00306 --index_;
00307 testInvariant();
00308 return it;
00309 }
00310
00311 template<class A, bool isConst>
00312 inline AccessorIterator<A, isConst>
00313 AccessorIterator<A, isConst>::operator+=
00314 (
00315 const size_t j
00316 )
00317 {
00318 if(index_ + j <= accessor_.size()) {
00319 index_ += j;
00320 }
00321 else {
00322 index_ = accessor_.size();
00323 }
00324 testInvariant();
00325 return *this;
00326 }
00327
00328 template<class A, bool isConst>
00329 inline AccessorIterator<A, isConst>
00330 AccessorIterator<A, isConst>::operator-=
00331 (
00332 const size_t j
00333 )
00334 {
00335 OPENGM_ASSERT(index_ >= j);
00336 index_ -= j;
00337 testInvariant();
00338 return *this;
00339 }
00340
00341 template<class A, bool isConst>
00342 inline void
00343 AccessorIterator<A, isConst>::testInvariant() const
00344 {
00345 OPENGM_ASSERT(index_ <= accessor_.size());
00346 }
00347
00348 template<class A, bool isConst>
00349 inline AccessorIterator<A, isConst>
00350 AccessorIterator<A, isConst>::operator+
00351 (
00352 const size_t j
00353 ) const
00354 {
00355 AccessorIterator<A, isConst> it = *this;
00356 it += j;
00357 return it;
00358 }
00359
00360 template<class A, bool isConst>
00361 inline AccessorIterator<A, isConst>
00362 AccessorIterator<A, isConst>::operator-
00363 (
00364 const size_t j
00365 ) const
00366 {
00367 AccessorIterator<A, isConst> it = *this;
00368 it -= j;
00369 return it;
00370 }
00371
00372 template<class A, bool isConst>
00373 template<bool isConstLocal>
00374 inline size_t
00375 AccessorIterator<A, isConst>::operator-
00376 (
00377 const AccessorIterator<A, isConstLocal>& it
00378 ) const
00379 {
00380
00381 #if __GNUC__ == 4 && __GNUC_MINOR__ >= 6
00382 typedef std::ptrdiff_t difference_type;
00383 #else
00384 typedef ptrdiff_t difference_type;
00385 #endif
00386 OPENGM_ASSERT(this->accessor_ == it.accessor_);
00387 return static_cast<difference_type>(index_) - static_cast<difference_type>(it.index_);
00388 }
00389
00390
00391
00392 template<class A, bool isConst>
00393 inline AccessorIterator<A, isConst>
00394 operator+
00395 (
00396 const size_t j,
00397 const AccessorIterator<A, isConst>& it
00398 )
00399 {
00400 return it + j;
00401 }
00402
00404
00405 }
00406
00407 #endif // #ifndef OPENGM_ACCESSOR_ITERATOR
00408