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_CORE_DETAILS_ITERATOR_ITERATOR_HPP 00025 #define IVL_CORE_DETAILS_ITERATOR_ITERATOR_HPP 00026 00027 00028 namespace ivl { 00029 00030 // forward declaration of array_nd 00031 template <class X, class Y> class array_nd; 00032 00033 namespace data { 00034 00035 namespace data_details { 00036 00037 // expands an iterator class that has a defined base() member with 00038 // const and, if possible, non-const, arrow(->) and dereference(*) 00039 // operators. 00040 // This class is used to avoid specializing iterators as const and mon-const. 00041 template <class C, class T, bool CONST = false, class REF = T&> 00042 class iter_operator_expander 00043 { 00044 }; 00045 00046 template <class C, class T, class REF> 00047 class iter_operator_expander<C, T, false, REF> 00048 { 00049 protected: 00050 C& derived() { return static_cast<C&>(*this); } 00051 const C& derived() const { return static_cast<const C&>(*this); } 00052 00053 public: 00055 T* operator ->() { return &(derived().base()); } 00057 const T* operator ->() const { return &(derived().base()); } 00058 00060 REF operator *() { return (derived().base()); } 00062 typename types::apply_const<REF>::type operator *() const 00063 { return (derived().base()); } 00064 }; 00065 00066 template <class C, class T, class REF> 00067 class iter_operator_expander<C, T, true, REF> 00068 { 00069 protected: 00070 const C& derived() const { return static_cast<const C&>(*this); } 00071 00072 public: 00074 const T* operator ->() const { return &(derived().base()); } 00075 00077 typename types::apply_const<REF>::type // TODO:This does not result to const T&!!!! 00078 operator *() const { return (derived().base()); } 00079 }; 00080 00081 00082 // expands an iterator that has a defined base() and base(size_t) members with 00083 // const and, if possible, non-const, arrow(->), dereference(*) and [] 00084 // (random access) operators. 00085 // This class is used to avoid specializing iterators as const and mon-const. 00086 template <class C, class T, bool CONST = false, class REF = T&> 00087 class rnd_iter_operator_expander 00088 { 00089 }; 00090 00091 template <class C, class T, class REF> 00092 class rnd_iter_operator_expander<C, T, false, REF> 00093 : public iter_operator_expander<C, T, false, REF> 00094 { 00095 private: 00096 friend class iter_operator_expander<C, T, false, REF>; 00097 00098 protected: 00099 using iter_operator_expander<C, T, false, REF>::derived; 00100 00101 public: 00103 REF operator [](size_t j) { return (derived().base(j)); } 00105 typename types::apply_const<REF>::type operator [](size_t j) const 00106 { return (derived().base(j)); } 00107 }; 00108 00109 template <class C, class T, class REF> 00110 class rnd_iter_operator_expander<C, T, true, REF> 00111 : public iter_operator_expander<C, T, true, REF> 00112 { 00113 protected: 00114 using iter_operator_expander<C, T, true, REF>::derived; 00115 00116 public: 00118 typename types::apply_const<REF>::type operator [](size_t j) const 00119 { return (derived().base(j)); } 00120 }; 00121 00122 } /* namespace data_details */ 00123 00124 template <class T, class OWNER, bool CONST = false, class REF = T&> 00125 class index_iterator //: public std::iterator_traits<T*> 00126 : 00127 public data_details:: 00128 rnd_iter_operator_expander< 00129 index_iterator<T, OWNER, CONST, REF>, T, CONST, REF>, 00130 public 00131 types::t_if<types::is_ivl_array<OWNER>, types:: 00132 ivl_array_reference_based_iterator_identifier, types::term>::type, 00133 public 00134 types::past_end_capable_iterator_identifier 00135 { 00136 private: 00137 template <class X, class Y, bool C, class R> friend class index_iterator; 00138 00139 friend class data_details::iter_operator_expander 00140 <index_iterator<T, OWNER, CONST, REF>, T, CONST, REF>; 00141 00142 typedef typename types::apply_const<T, types::t_expr<CONST> > 00143 ::type best_value_type; 00144 00145 typedef typename types::apply_const<REF, types::t_expr<CONST> > 00146 ::type best_ref_type; 00147 00148 // this struct is used to disable specific specialization members 00149 struct not_a_type { OWNER* o; size_t i; operator size_t() { return 0; } }; 00150 00151 typedef typename types::t_if<types::t_expr<CONST>, not_a_type, 00152 types::code_word<> >::type invalid_if_const; 00153 00154 OWNER* o; 00155 size_t i; 00156 00157 protected: 00158 inline const REF base( 00159 types::code_word<> ok = types::code_word<>()) const 00160 { return (*o)[i]; } 00161 00162 inline best_ref_type base( 00163 invalid_if_const disable = invalid_if_const()) 00164 { return (*o)[i]; } 00165 00166 inline const REF base(size_t j, 00167 types::code_word<> ok = types::code_word<>()) const 00168 { return (*o)[i + j]; } 00169 00170 inline best_ref_type base(size_t j, 00171 invalid_if_const disable = invalid_if_const()) 00172 { return (*o)[i + j]; } 00173 00174 00175 public: 00176 typedef index_iterator<T, OWNER, CONST, REF> this_type; 00177 00178 // iterator_traits 00179 typedef std::random_access_iterator_tag iterator_category; 00180 typedef T value_type; 00181 typedef ptrdiff_t difference_type; 00182 typedef best_value_type* pointer; 00183 typedef best_ref_type reference; 00184 00185 // constructors 00186 index_iterator() { } 00187 index_iterator(const this_type& it) : o(it.o), i(it.i) { } 00188 template <bool C> 00189 index_iterator(const index_iterator<T, OWNER, C, REF>& it) 00190 : o(it.o), i(it.i) { } 00191 00192 index_iterator(OWNER& owner, size_t pos) : o(&owner), i(pos) { } 00193 00194 OWNER& owner() { return *o; } 00195 const OWNER& owner() const { return *o; } 00196 00197 // members 00198 00199 // increment-decrement 00200 this_type& operator++() { ++i; return *this; } 00201 this_type& operator--() { --i; return *this; } 00202 00203 this_type operator++(int) { this_type tmp(*this); i++; return tmp; } 00204 this_type operator--(int) { this_type tmp(*this); i--; return tmp; } 00205 00206 // random access 00207 this_type operator +(const size_t j) const 00208 { this_type tmp(o, i + j); return tmp; } 00209 this_type operator -(const size_t j) const 00210 { this_type tmp(o, i - j); return tmp; } 00211 this_type& operator +=(const size_t j) { i += j; return *this; } 00212 this_type& operator -=(const size_t j) { i -= j; return *this; } 00213 00214 // difference 00215 difference_type operator -(const index_iterator& a) const { 00216 return difference_type(i - a.i); 00217 } 00218 00219 //copy same type iterator 00220 this_type& operator=(const this_type& it) { o = it->o; i = it->i; return *this; } 00221 //copy relevant type iterator 00222 template<bool C> 00223 this_type& operator=(const index_iterator<T, OWNER, C>& it) 00224 { o = it->o; i = it->i; return *this; } 00225 00226 bool operator==(const this_type& it) const { return (o == it.o) && (i == it.i); } 00227 bool operator!=(const this_type& it) const { return (i != it.i) || (o != it.o); } 00228 bool operator<(const this_type& it) const { return (i < it.i); } 00229 bool operator<=(const this_type& it) const { return (i <= it.i); } 00230 bool operator>(const this_type& it) const { return (i > it.i); } 00231 bool operator>=(const this_type& it) const { return (i >= it.i); } 00232 }; 00233 00234 00235 template <class T, bool CONST> 00236 class ptr_iterator //: public std::iterator_traits<T*> 00237 : public data_details:: 00238 rnd_iter_operator_expander<ptr_iterator<T, CONST>, T, CONST>, 00239 public 00240 types::pointer_based_iterator_identifier, 00241 public 00242 types::past_end_capable_iterator_identifier 00243 { 00244 private: 00245 template <class X, bool Y> friend class ptr_iterator; 00246 00247 template <class X, class Y, bool C, class Z> 00248 friend class data_details::rnd_iter_operator_expander; 00249 template <class X, class Y, bool C, class Z> 00250 friend class data_details::iter_operator_expander; 00251 00252 typedef typename types::apply_const<T, types::t_expr<CONST> > 00253 ::type best_value_type; 00254 00255 typedef typename types::apply_const<T&, types::t_expr<CONST> > 00256 ::type best_ref_type; 00257 00258 // this struct is used to disable specific specialization members 00259 struct not_a_type { T* ptr; operator size_t() { return 0; } }; 00260 00261 typedef typename types::t_if<types::t_expr<CONST>, not_a_type, 00262 types::code_word<> >::type invalid_if_const; 00263 00264 best_value_type* ptr; 00265 00266 protected: 00267 inline const T& base( 00268 types::code_word<> ok = types::code_word<>()) const 00269 { return *ptr; } 00270 00271 inline best_ref_type base( // TODO:this does not result to T& !!! 00272 invalid_if_const disable = invalid_if_const()) 00273 { return *ptr; } 00274 00275 inline const T& base(size_t j, 00276 types::code_word<> ok = types::code_word<>()) const 00277 { return ptr[j]; } 00278 00279 inline best_ref_type base(size_t j, 00280 invalid_if_const disable = invalid_if_const()) 00281 { return ptr[j]; } 00282 00283 public: 00284 typedef ptr_iterator<T, CONST> this_type; 00285 00286 // iterator_traits 00287 typedef std::random_access_iterator_tag iterator_category; 00288 typedef T value_type; 00289 typedef ptrdiff_t difference_type; 00290 typedef best_value_type* pointer; 00291 typedef best_value_type& reference; 00292 00293 typedef ptrdiff_t iter_border_walker; 00294 00295 // constructors 00296 ptr_iterator() { ptr = 0; } 00297 ptr_iterator(const this_type& it) : ptr(it.ptr) { } 00298 template <bool C> 00299 ptr_iterator(const ptr_iterator<T, C>& it) : ptr(it.ptr) { } 00300 ptr_iterator(pointer ptrdata) : ptr(ptrdata) { } 00301 00302 // members 00303 00304 // increment-decrement 00305 this_type& operator++() { ++ptr; return *this; } 00306 this_type& operator--() { --ptr; return *this; } 00307 00308 this_type operator++(int) { this_type tmp(*this); ptr++; return tmp; } 00309 this_type operator--(int) { this_type tmp(*this); ptr--; return tmp; } 00310 00311 // random access 00312 this_type operator +(const difference_type j) const { this_type tmp(ptr + j); return tmp; } 00313 this_type operator -(const difference_type j) const { this_type tmp(ptr - j); return tmp; } 00314 this_type& operator +=(const difference_type j) { ptr+=j; return *this; } 00315 this_type& operator -=(const difference_type j) { ptr-=j; return *this; } 00316 00317 // difference 00318 difference_type operator -(const ptr_iterator& a) const { return (ptr - a.ptr); } 00319 00320 // copy same type operator 00321 this_type& operator=(const this_type& it) { ptr = it.ptr; return *this; } 00322 // copy relevant type operator 00323 template <bool C> 00324 this_type& operator=(const ptr_iterator<T, C>& it) { ptr = it.ptr; return *this; } 00325 00326 bool operator==(const this_type& it) const { return (ptr == it.ptr); } 00327 bool operator!=(const this_type& it) const { return (ptr != it.ptr); } 00328 bool operator<(const this_type& it) const { return (ptr < it.ptr); } 00329 bool operator<=(const this_type& it) const { return (ptr <= it.ptr); } 00330 bool operator>(const this_type& it) const { return (ptr > it.ptr); } 00331 bool operator>=(const this_type& it) const { return (ptr >= it.ptr); } 00332 }; 00333 00334 00335 00336 } /*namespace data */ 00337 00338 } /*namespace ivl */ 00339 00340 #endif // IVL_CORE_DETAILS_ITERATOR_ITERATOR_HPP