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