ivl 679
|
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