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_ND_HPP 00025 #define IVL_CORE_DETAILS_ITERATOR_ITERATOR_ND_HPP 00026 00027 00028 namespace ivl { 00029 00030 namespace iterator_nd_details { 00031 00032 template<class T, class IT_T, bool PAST_END_CAPABLE, bool IS_PTR> 00033 class it_wrapper 00034 { 00035 }; 00036 00037 // --- wrapper for past_end_capable 00038 00039 template<class T, class IT_T> 00040 class it_wrapper<T, IT_T, true, false> 00041 : public data::past_end_capable_iterator<IT_T> 00042 { 00043 typedef data::past_end_capable_iterator<IT_T> prv_base_class; 00044 public: 00045 typedef it_wrapper it_wrapper_class; 00046 typedef prv_base_class it_wrapper_base_class; 00047 it_wrapper_base_class& base() 00048 { return static_cast<prv_base_class&>(*this); } 00049 const it_wrapper_base_class& base() const 00050 { return static_cast<const prv_base_class&>(*this); } 00051 00052 it_wrapper() { } 00053 it_wrapper(const it_wrapper& i) : prv_base_class(i) { } 00054 template <class X> 00055 it_wrapper(const X& y) : prv_base_class(y) { } 00056 template <class X> 00057 it_wrapper(types::code_word<>, const X& y) : prv_base_class(0, y) { } 00058 template <class X> 00059 it_wrapper(const X& y, ptrdiff_t n) : prv_base_class(y, n) { } 00060 template <class X, class Z> 00061 it_wrapper(const X& p, const Z& b) : prv_base_class(b, p - b) { } 00062 00063 IT_T begin_pos() const { return base().begin_pos(); } 00064 }; 00065 00066 template<class IT_T> 00067 class it_wrapper<bool, IT_T, true, false> 00068 : public data::past_end_capable_iterator<IT_T> 00069 { 00070 typedef data::past_end_capable_iterator<IT_T> prv_base_class; 00071 public: 00072 typedef it_wrapper it_wrapper_class; 00073 typedef prv_base_class it_wrapper_base_class; 00074 it_wrapper_base_class& base() 00075 { return static_cast<prv_base_class&>(*this); } 00076 const it_wrapper_base_class& base() const 00077 { return static_cast<const prv_base_class&>(*this); } 00078 00079 it_wrapper() { } 00080 it_wrapper(const it_wrapper& i) : prv_base_class(i) { } 00081 template <class X> 00082 it_wrapper(const X& y) : prv_base_class(y) { } 00083 template <class X> 00084 it_wrapper(types::code_word<>, const X& y) : prv_base_class(0, y) { } 00085 template <class X> 00086 it_wrapper(const X& y, ptrdiff_t n) : prv_base_class(y, n) { } 00087 template <class X, class Z> 00088 it_wrapper(const X& p, const Z& b) : prv_base_class(b, p - b) { } 00089 00090 //typename std::iterator_traits<IT_T>::pointer operator->() 00091 bool* operator->() { return NULL; } 00092 IT_T begin_pos() const { return base().begin_pos(); } 00093 }; 00094 00095 // --- wrapper for simply inherited iterator 00096 00097 template<class T, class IT_T> 00098 class it_wrapper<T, IT_T, false, false> 00099 : public IT_T 00100 { 00101 typedef IT_T prv_base_class; 00102 public: 00103 typedef it_wrapper it_wrapper_class; 00104 typedef prv_base_class it_wrapper_base_class; 00105 it_wrapper_base_class& base() 00106 { return static_cast<prv_base_class&>(*this); } 00107 const it_wrapper_base_class& base() const 00108 { return static_cast<const prv_base_class&>(*this); } 00109 00110 it_wrapper() { } 00111 it_wrapper(const it_wrapper& i) : prv_base_class(i) { } 00112 template <class X> 00113 it_wrapper(const X& y) : prv_base_class(y) { } 00114 template <class X> 00115 it_wrapper(types::code_word<>, const X& y) : prv_base_class(y) { } 00116 template <class X> 00117 it_wrapper(const X& y, ptrdiff_t n) : prv_base_class(y + n) { } 00118 template <class X, class Z> 00119 it_wrapper(const X& p, const Z& b) : prv_base_class(p) { } 00120 00121 IT_T begin_pos() const { return base(); } 00122 }; 00123 00124 template<class IT_T> 00125 class it_wrapper<bool, IT_T, false, false> 00126 : public IT_T 00127 { 00128 typedef IT_T prv_base_class; 00129 public: 00130 typedef it_wrapper it_wrapper_class; 00131 typedef prv_base_class it_wrapper_base_class; 00132 it_wrapper_base_class& base() 00133 { return static_cast<prv_base_class&>(*this); } 00134 const it_wrapper_base_class& base() const 00135 { return static_cast<const prv_base_class&>(*this); } 00136 00137 it_wrapper() { } 00138 it_wrapper(const it_wrapper& i) : prv_base_class(i) { } 00139 template <class X> 00140 it_wrapper(const X& y) : prv_base_class(y) { } 00141 template <class X> 00142 it_wrapper(types::code_word<>, const X& y) : prv_base_class(y) { } 00143 template <class X> 00144 it_wrapper(const X& y, ptrdiff_t n) : prv_base_class(y + n) { } 00145 template <class X, class Z> 00146 it_wrapper(const X& p, const Z& b) : prv_base_class(p) { } 00147 00148 //typename std::iterator_traits<IT_T>::pointer operator->() 00149 bool* operator->() { return NULL; } 00150 IT_T begin_pos() const { return base(); } 00151 }; 00152 00153 // --- wrapper for pointer 00154 00155 template<class T> 00156 class it_wrapper<T, T*, false, true> 00157 : public std::iterator_traits<T*> 00158 { 00159 T* ptr; 00160 public: 00161 typedef it_wrapper it_wrapper_class; 00162 typedef T* it_wrapper_base_class; 00163 it_wrapper_base_class& base() { return ptr; } 00164 const it_wrapper_base_class& base() const { return ptr; } 00165 00166 it_wrapper() { } 00167 it_wrapper(const it_wrapper& i) : ptr(i) { } 00168 template <class X> 00169 it_wrapper(const X& y) : ptr(y) { } 00170 template <class X> 00171 it_wrapper(types::code_word<>, const X& y) : ptr(y) { } 00172 template <class X> 00173 it_wrapper(const X& y, ptrdiff_t n) : ptr(y + n) { } 00174 template <class X, class Z> 00175 it_wrapper(const X& p, const Z& b) : ptr(p) { } 00176 00177 operator T*() { return ptr; } 00178 operator const T*() const { return ptr; } 00179 T& operator*() { return *ptr; } 00180 const T& operator*() const { return *ptr; } 00181 T* operator->() { return ptr; } 00182 const T* operator->() const { return ptr; } 00183 const T* begin_pos() const { return ptr; } 00184 }; 00185 00186 template<class T> 00187 class it_wrapper<T, const T*, false, true> 00188 : public std::iterator_traits<const T*> 00189 { 00190 const T* ptr; 00191 public: 00192 typedef it_wrapper it_wrapper_class; 00193 typedef const T* it_wrapper_base_class; 00194 it_wrapper_base_class& base() { return ptr; } 00195 const it_wrapper_base_class& base() const { return ptr; } 00196 00197 it_wrapper() { } 00198 it_wrapper(const it_wrapper& i) : ptr(i) { } 00199 template <class X> 00200 it_wrapper(const X& y) : ptr(y) { } 00201 template <class X> 00202 it_wrapper(types::code_word<>, const X& y) : ptr(y) { } 00203 template <class X> 00204 it_wrapper(const X& y, ptrdiff_t n) : ptr(y + n) { } 00205 template <class X, class Z> 00206 it_wrapper(const X& p, const Z& b) : ptr(p) { } 00207 00208 operator const T*() { return ptr; } 00209 operator const T*() const { return ptr; } 00210 const T& operator*() const { return *ptr; } 00211 const T* operator->() const { return ptr; } 00212 const T* begin_pos() const { return ptr; } 00213 }; 00214 00215 } /* namespace iterator_nd_details */ 00216 00217 //namespace data { 00218 00219 // basic_iterator_nd has random access and needs an IT with random access 00220 // Notice: not all iterator_nd's have a single-dim iterator as a base class. 00221 template <class IT, bool PAST_END_CAPABLE> 00222 class basic_iterator_nd : 00223 protected 00224 iterator_nd_details::it_wrapper<typename 00225 std::iterator_traits<IT>::value_type, IT, 00226 (!data::iterator_extended_traits<IT>::is_past_end_capable::value 00227 && PAST_END_CAPABLE), types::is_ptr<IT>::value>, 00228 public 00229 types::t_if<types::is_base<types::pointer_based_iterator_identifier, IT>, 00230 types::pointer_range_based_iterator_identifier, types::term>::type 00231 { 00232 size_t stride; 00233 00234 template <class X, bool Y> friend class basic_iterator_nd; 00235 //template <class X> friend class data::past_end_capable_iterator; 00236 //template <class X, class Y, class Z> friend class array_nd; 00237 00238 // this class is used to disable non-const operator [] for const_operators 00239 class not_a_type { operator size_t() { return 0; } }; 00240 00241 public: 00242 typedef basic_iterator_nd this_type; 00243 00244 typedef typename this_type::it_wrapper_class it_base_class; 00245 /*typedef iterator_nd_details:: 00246 it_wrapper<typename 00247 std::iterator_traits<IT>::value_type, IT, PAST_END_CAPABLE> 00248 it_base_class;*/ 00249 00250 typedef std::iterator_traits<it_base_class> it_t; 00251 00252 typedef typename it_t::iterator_category iterator_category; 00253 typedef typename it_t::value_type value_type; 00254 typedef typename it_t::difference_type difference_type; 00255 typedef typename it_t::pointer pointer; 00256 typedef typename it_t::reference reference; 00257 00258 typedef types::t_true has_base_iterator; 00259 00260 typedef typename it_base_class::it_wrapper_base_class base_it; 00261 // base() will be either the reference iterator (could be pointer). 00262 // or a past_end_capable iterator (modified) if needed. 00263 // it will therefore be a necessary kind of iterator, 00264 // enough to be able to be based upon for nd_iterator. 00265 typename it_base_class::it_wrapper_base_class& base() 00266 { return static_cast<it_base_class&>(*this).base(); } 00267 const typename it_base_class::it_wrapper_base_class& base() const 00268 { return static_cast<const it_base_class&>(*this).base(); } 00269 00270 struct iter_nd_border_walker 00271 { 00272 ptrdiff_t x; 00273 00274 iter_nd_border_walker() {} 00275 iter_nd_border_walker(ptrdiff_t x) : x(x) { } 00276 iter_nd_border_walker(const iter_nd_border_walker& y) : x(y.x) { } 00277 00278 //TODO: care about this. 00279 void debg(const iter_nd_border_walker& o) { } 00280 template <class Aiter_nd_border_walker> 00281 iter_nd_border_walker& operator=(const Aiter_nd_border_walker& o) 00282 { 00283 debg(o); 00284 x = o.x; 00285 } 00286 }; 00287 00288 typedef ptrdiff_t iter_nd_dir_type ; 00289 00290 // constructors 00291 basic_iterator_nd() : it_base_class() { } 00292 00293 basic_iterator_nd(const basic_iterator_nd& it_nd) 00294 : it_base_class(it_nd.base()), stride(it_nd.stride) { } 00295 00296 template <class CIT, bool PC> 00297 basic_iterator_nd(const basic_iterator_nd<CIT, PC>& it_nd) 00298 : it_base_class(it_nd.base()), stride(it_nd.stride) { } 00299 00300 /*template <class CIT, bool PC> 00301 basic_iterator_nd(const basic_iterator_nd<CIT, PC>& b, ptrdiff_t offs) 00302 : it_base_class(b.base().pos_begin(), offs), stride(b.stride) { }*/ 00303 00304 basic_iterator_nd(types::code_word<>, size_t stride, const IT& it) 00305 : it_base_class(types::code_word<>(), it), stride(stride) { } 00306 00307 00308 basic_iterator_nd(size_t stride, const basic_iterator_nd& it) 00309 : it_base_class(it.base()), stride(stride) { } 00310 00311 basic_iterator_nd(size_t stride, const IT& it, ptrdiff_t offs) 00312 : it_base_class(it, offs), stride(stride) { } 00313 00314 basic_iterator_nd(size_t stride, const IT& it, const IT& b) 00315 : it_base_class(it, b), stride(stride) { } 00316 00317 // dereference 00318 using it_base_class::operator*; 00319 using it_base_class::operator->; 00320 00321 // increment-decrement 00322 this_type& operator++() { base() +=(stride); return *this; } 00323 this_type& operator--() { base() -=(stride); return *this; } 00324 00325 this_type operator++(int) 00326 { this_type tmp(*this); base() +=(stride); return tmp; } 00327 00328 this_type operator--(int) 00329 { this_type tmp(*this); base() -=(stride); return tmp; } 00330 00331 // random access 00332 this_type operator +(const typename it_t::difference_type j) const 00333 { /*TODO: maybe: optimize*/ 00334 this_type tmp(*this); tmp.base() += (stride * j); return tmp; } 00335 00336 this_type operator -(const typename it_t::difference_type j) const 00337 { this_type tmp(*this); tmp.base() -= (stride * j); return tmp; } 00338 00339 this_type& operator +=(const typename it_t::difference_type j) 00340 { base() += (stride * j); return *this; } 00341 00342 this_type& operator -=(const typename it_t::difference_type j) 00343 { base() -= (stride * j); return *this; } 00344 00345 // border walker 00346 // TODO: eliminate typedefs and conversions in several classes of border_walker to size_t cause of ambiguous candidates 00347 this_type operator +(const iter_nd_border_walker& z) 00348 { /*TODO: maybe: optimize*/ 00349 this_type tmp(*this); 00350 tmp.base() += z.x; return tmp; } 00351 00352 this_type operator -(const iter_nd_border_walker& z) 00353 { this_type tmp(*this); tmp.base() -= z.x; return tmp; } 00354 00355 this_type& operator +=(const iter_nd_border_walker& z) 00356 { base() += (z.x); return *this; } 00357 00358 this_type& operator -=(const iter_nd_border_walker& z) 00359 { base() -= (z.x); return *this; } 00360 00361 00362 iter_nd_dir_type dir() const { return stride; } 00363 00364 iter_nd_dir_type dir(ptrdiff_t x) const { return stride * x; } 00365 00366 template<class Y, bool PC> 00367 void inc_along_other_dim_at_begin(const basic_iterator_nd<Y, PC>& y) 00368 { base() += (y.dir()); } 00369 00370 template<class Y, bool PC> 00371 void dec_along_other_dim_at_begin(const basic_iterator_nd<Y, PC>& y) 00372 { base() -= (y.dir()); } 00373 00374 template<class Y, bool PC> 00375 void move_along(const basic_iterator_nd<Y, PC>& y, ptrdiff_t x) 00376 { base() += (y.dir(x)); } 00377 00378 // const random access operator 00379 typename types::apply_const<typename it_t::reference>::type operator [] ( 00380 size_t j) const 00381 { return base() [(stride * j)]; } 00382 00383 // non-const random access, enabled only for non-const T 00384 typename it_t::reference operator [] (typename 00385 types::t_if<types::is_const<typename it_t::reference>, 00386 not_a_type, size_t>::type j) 00387 { return base [(stride * j)]; } 00388 00389 // difference 00390 typename it_t::difference_type operator -(const this_type& a) const 00391 { return (base() - (a)) / stride; } 00392 00393 // comparing 00394 bool operator==(const this_type& it) const { return base() == it.base(); } 00395 bool operator!=(const this_type& it) const { return base() != it.base(); } 00396 bool operator<(const this_type& it) const { return base() < it.base(); } 00397 bool operator<=(const this_type& it) const { return base() <= it.base(); } 00398 bool operator>(const this_type& it) const { return base() > it.base(); } 00399 bool operator>=(const this_type& it) const { return base() >= it.base(); } 00400 00401 }; 00402 00403 00404 00405 //} /*namespace data */ 00406 00407 } /*namespace ivl */ 00408 00409 #endif // IVL_CORE_DETAILS_ITERATOR_ITERATOR_ND_HPP