accessor_iterator.hxx

Go to the documentation of this file.
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 // binary arithmetic operators
00122 template<class A, bool isConst>
00123    AccessorIterator<A, isConst> operator+(const size_t, const AccessorIterator<A, isConst>&);
00124 
00125 // implementation of AccessorIterator
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_]; // whether this works depends on the accessor
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_]; // whether this works depends on the accessor
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; // copy
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; // copy
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; // copy
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; // copy
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    //gcc 4.6 bugfix
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 // implementation of binary arithmetic operators
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 } // namespace opengm
00406 
00407 #endif // #ifndef OPENGM_ACCESSOR_ITERATOR
00408 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Mon Jun 17 16:31:01 2013 for OpenGM by  doxygen 1.6.3