ivl 679
ivl/details/array/impl/iterator/past_end_capable_iterator.hpp
00001 /* This file is part of the ivl C++ library <http://image.ntua.gr/ivl>.
00002    A C++ template library extending syntax towards mathematical notation.
00003 
00004    Copyright (C) 2012 Yannis Avrithis <iavr@image.ntua.gr>
00005    Copyright (C) 2012 Kimon Kontosis <kimonas@image.ntua.gr>
00006 
00007    ivl is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU Lesser General Public License 
00009    version 3 as published by the Free Software Foundation.
00010 
00011    Alternatively, you can redistribute it and/or modify it under the terms 
00012    of the GNU General Public License version 2 as published by the Free 
00013    Software Foundation.
00014 
00015    ivl is distributed in the hope that it will be useful,
00016    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00018    See the GNU General Public License for more details.
00019 
00020    You should have received a copy of the GNU General Public License 
00021    and a copy of the GNU Lesser General Public License along 
00022    with ivl. If not, see <http://www.gnu.org/licenses/>. */
00023 
00024 #ifndef IVL_ARRAY_DETAILS_ITERATOR_PAST_END_CAPABLE_ITERATOR_HPP
00025 #define IVL_ARRAY_DETAILS_ITERATOR_PAST_END_CAPABLE_ITERATOR_HPP
00026 
00027 namespace ivl {
00028 
00029 namespace data {
00030 
00031 template<class IT>
00032 class past_end_capable_iterator
00033 {
00034 protected:
00035         IT base_it;
00036         ptrdiff_t npos;
00037 
00038         template <class F> friend class past_end_capable_iterator;
00039 
00040 public:
00041         // note about this iterator:
00042         // on differences, equalities etc. considers that the base is
00043         // always the beginning, and that it is the same among operands.
00044         // this disables us from using rbegin based iterators as reference,
00045         // and compare them to begin based ones.
00046 
00047         typedef past_end_capable_iterator this_type;
00048 
00049         // iterator_traits
00050     typedef std::random_access_iterator_tag iterator_category;
00051     typedef typename IT::value_type value_type;
00052         typedef ptrdiff_t difference_type;
00053         typedef typename IT::pointer pointer;
00054         typedef typename IT::reference reference;
00055 
00056         typedef ptrdiff_t iter_border_walker;
00057 
00058         // constructors
00059         past_end_capable_iterator() { }
00060         // constructor with the iterator and the position of 
00061         // the iterator from begin()
00062         past_end_capable_iterator(const IT& it, ptrdiff_t nps)
00063                 : base_it(it), npos(nps) { }
00064         // constructor with the iterator for begin() only. possibly faster.
00065         past_end_capable_iterator(int, const IT& it)
00066                 : base_it(it), npos(0) { }
00067         // copy constructors
00068         past_end_capable_iterator(const past_end_capable_iterator& it)
00069                 : base_it(it.base_it) { npos = it.npos; }
00070         template <class O>
00071         past_end_capable_iterator(const past_end_capable_iterator<O>& it)
00072                 : base_it(it.base_it) { npos = it.npos; }
00073 
00074         // members
00075 
00076         //TODO: nat yet: operator IT() const { return base_it + npos; }
00077 
00078         const IT& begin_pos() const { return base_it; }
00079 
00080         // dereference
00081         value_type* operator ->() { return (base_it + npos).operator ->(); }
00082 
00083         reference operator*() { return base_it[npos]; }
00084 
00085         reference operator*() const { return base_it[npos]; }
00086 
00087         reference operator[] (ptrdiff_t i) { return base_it[i + npos]; }
00088 
00089         reference operator[] (ptrdiff_t i) const { return base_it[i + npos]; }
00090 
00091         // increment-decrement
00092         this_type& operator++() { ++npos; return *this; }
00093         this_type& operator--() { --npos; return *this; }
00094 
00095         this_type operator++(int) { this_type tmp(*this); npos++; return tmp; }
00096         this_type operator--(int) { this_type tmp(*this); npos--; return tmp; }
00097 
00098         // random access
00099         this_type operator +(const difference_type j) const
00100                 { this_type tmp(base_it, npos + j); return tmp; }
00101         this_type operator -(const difference_type j) const
00102                 { this_type tmp(base_it, npos - j); return tmp; }
00103         this_type& operator +=(const difference_type j) { npos+=j; return *this; }
00104         this_type& operator -=(const difference_type j) { npos-=j; return *this; }
00105 
00106         // difference
00107         difference_type operator -(const this_type& a) const
00108                 { return (npos - a.npos); }
00109 
00110         // copy same type operator
00111         this_type& operator=(const this_type& it)
00112                 { base_it = it.base_it; npos = it.npos; return *this; }
00113         // copy relevant type operator
00114         template <class O>
00115         this_type& operator=(const past_end_capable_iterator<O>& it)
00116                 { base_it = it.base_it; npos = it.npos; return *this; }
00117 
00118         bool operator==(const this_type& it) const { return (npos == it.npos); }
00119         bool operator!=(const this_type& it) const { return (npos != it.npos); }
00120         bool operator<(const this_type& it) const { return (npos < it.npos); }
00121         bool operator<=(const this_type& it) const { return (npos <= it.npos); }
00122         bool operator>(const this_type& it) const { return (npos > it.npos); }
00123         bool operator>=(const this_type& it) const { return (npos >= it.npos); }
00124 
00125 };
00126 
00127 } /* namespace data */
00128 
00129 
00130 template<class IT>
00131 class auto_past_end_capable_iterator
00132 {
00133 protected:
00134         IT base_it;
00135         ptrdiff_t npos;
00136 
00137         template <class F> friend class auto_past_end_capable_iterator;
00138 
00139 public:
00140         // note about this iterator:
00141         // on differences, equalities etc. considers that the base is
00142         // always the beginning, and that it is the same among operands.
00143         // this disables us from using rbegin based iterators as reference,
00144         // and compare them to begin based ones.
00145 
00146         typedef auto_past_end_capable_iterator this_type;
00147 
00148         // iterator_traits
00149     typedef std::random_access_iterator_tag iterator_category;
00150     typedef typename IT::value_type value_type;
00151         typedef ptrdiff_t difference_type;
00152         typedef typename IT::pointer pointer;
00153         typedef typename IT::reference reference;
00154 
00155         typedef ptrdiff_t iter_border_walker;
00156 
00157         // constructors
00158         auto_past_end_capable_iterator() { }
00159         auto_past_end_capable_iterator(const IT& it)
00160                 : base_it(it), npos(0) { }
00161         auto_past_end_capable_iterator(const IT& it, ptrdiff_t n)
00162                 : base_it(it), npos(n) { }
00163 
00164         auto_past_end_capable_iterator(const auto_past_end_capable_iterator& it)
00165                 : base_it(it.base_it) { npos = it.npos; }
00166         template <class O>
00167         auto_past_end_capable_iterator(const auto_past_end_capable_iterator<O>& it)
00168                 : base_it(it.base_it) { npos = it.npos; }
00169 
00170         // members
00171         operator IT() const { return base_it + npos; }
00172 
00173         //const IT& begin_pos() const { return base_it; }
00174 
00175         // dereference
00176         value_type* operator ->() { return (base_it + npos).operator ->(); }
00177 
00178         reference operator*() { return base_it[npos]; }
00179 
00180         reference operator*() const { return base_it[npos]; }
00181 
00182         reference operator[] (ptrdiff_t i) { return base_it[i + npos]; }
00183 
00184         reference operator[] (ptrdiff_t i) const { return base_it[i + npos]; }
00185 
00186         // increment-decrement
00187         this_type& operator++() { ++npos; return *this; }
00188         this_type& operator--() { --npos; return *this; }
00189 
00190         this_type operator++(int) { this_type tmp(*this); npos++; return tmp; }
00191         this_type operator--(int) { this_type tmp(*this); npos--; return tmp; }
00192 
00193         // random access
00194         this_type operator +(const difference_type j) const
00195                 { this_type tmp(base_it, npos + j); return tmp; }
00196         this_type operator -(const difference_type j) const
00197                 { this_type tmp(base_it, npos - j); return tmp; }
00198         this_type& operator +=(const difference_type j) { npos+=j; return *this; }
00199         this_type& operator -=(const difference_type j) { npos-=j; return *this; }
00200 
00201         // difference
00202         difference_type operator -(const this_type& a) const
00203                 { return (base_it - a.base_it + npos - a.npos); }
00204 
00205         // copy same type operator
00206         this_type& operator=(const this_type& it)
00207                 { base_it = it.base_it; npos = it.npos; return *this; }
00208         // copy relevant type operator
00209         template <class O>
00210         this_type& operator=(const auto_past_end_capable_iterator<O>& it)
00211                 { base_it = it.base_it; npos = it.npos; return *this; }
00212 
00213         bool operator==(const this_type& it) const 
00214                 { return (base_it - it.base_it + npos == it.npos); }
00215         bool operator!=(const this_type& it) const 
00216                 { return (base_it - it.base_it + npos != it.npos); }
00217         bool operator<(const this_type& it) const 
00218                 { return (base_it - it.base_it + npos < it.npos); }
00219         bool operator<=(const this_type& it) const 
00220                 { return (base_it - it.base_it + npos <= it.npos); }
00221         bool operator>(const this_type& it) const 
00222                 { return (base_it - it.base_it + npos > it.npos); }
00223         bool operator>=(const this_type& it) const 
00224                 { return (base_it - it.base_it + npos >= it.npos); }
00225 
00226 };
00227 
00228 
00229 } /* namespace ivl */
00230 
00231 #endif // IVL_ARRAY_DETAILS_ITERATOR_PAST_END_CAPABLE_ITERATOR_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations