ivl 679
ivl/details/array_nd/impl/iterator/iterator_nd.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_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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations