ivl 679
ivl/details/array_nd/impl/iterator/iterator_nd_interface.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_ARRAY_ND_DETAILS_ARRAY_ND_ITERATOR_ND_INTERFACE_HPP
00025 #define IVL_ARRAY_ND_DETAILS_ARRAY_ND_ITERATOR_ND_INTERFACE_HPP
00026 
00027 namespace ivl {
00028 namespace array_nd_details {
00029 
00030 // an interface for basic_iterator_nd which has random access
00031 template <class C>
00032 class basic_iterator_nd_interface
00033 {
00034 };
00035 
00036 template <class T, class OPTS>
00037 class basic_iterator_nd_interface<array_nd<T, OPTS> >
00038 {
00039 private:
00040         typedef ivl::array_nd<T, OPTS> C;
00041 
00042         typedef array<T, typename types::derive_opts<
00043                 array_nd<T, OPTS> >::type> base_class;
00044 
00045         typedef typename base_class::derived_type derived_type;
00046 
00047         struct not_a_type { };
00048 
00049         typedef typename
00050                 types::t_if<typename base_class::is_writeable,
00051                 typename types::best_iterator<base_class>::type, not_a_type>::type
00052                         iter;
00053 
00054         typedef typename
00055                 types::t_if<typename base_class::is_writeable,
00056                 typename types::best_reverse_iterator<base_class>::type,
00057                         not_a_type>::type reverse_iter;
00058 
00059         typedef typename base_class::const_iterator const_iter;
00060         typedef typename base_class::const_reverse_iterator const_reverse_iter;
00061 
00062         C& nd() { return static_cast<C&>(*this); }
00063         const C& nd() const { return static_cast<const C&>(*this); }
00064 
00065 protected:
00066         typedef basic_iterator_nd_interface iter_nd_interface_class;
00067 
00068 public:
00069         typedef ivl::basic_iterator_nd<iter, true> iterator_nd;
00070         typedef basic_iterator_nd<const_iter, true> const_iterator_nd;
00071         typedef std::reverse_iterator<iterator_nd> reverse_iterator_nd;
00072         typedef std::reverse_iterator<const_iterator_nd> const_reverse_iterator_nd;
00073 
00074         typedef ivl::basic_iterator_nd<iter, false> _fast_iterator_nd;
00075         typedef basic_iterator_nd<const_iter, false> _fast_const_iterator_nd;
00076         //typedef std::reverse_iterator<iterator_nd, false> reverse_iterator_nd;
00077         //typedef std::reverse_iterator<const_iterator_nd, false> const_reverse_iterator_nd;
00078 
00079         typedef typename ivl::basic_iterator_nd<const_iter, true>::
00080                 iter_nd_border_walker iter_nd_border_walker;
00081 
00082 
00083         size_t begin_pos(size_t d, size_t pos)
00084         {
00085                 size_t mod = pos % nd().stride(d);
00086                 if(d == nd().ndim() - 1) return mod;
00087                 return pos - pos % nd().stride(d + 1) + mod;
00088         }
00089 
00090         size_t end_pos(size_t d, size_t pos)
00091         {
00092                 size_t mod = pos % nd().stride(d);
00093                 if(d == nd().ndim() - 1) return mod + nd().length();
00094                 return pos - pos % nd().stride(d + 1) + mod +
00095                         nd().stride(d + 1);
00096         }
00097 
00098         // non-const iterator
00099         iterator_nd _begin(size_t d)
00100                 { return iterator_nd(types::code_word<>(), nd().stride(d), nd().begin()); }
00101 
00102         iterator_nd _begin(size_t d, const iterator_nd& it)
00103                 { return iterator_nd(nd().stride(d), it); }
00104 
00105         iterator_nd _iter(size_t d, const iter& it)
00106                 { return iterator_nd(nd().stride(d), it, nd().begin()); }
00107 
00108         template<class S>
00109         iterator_nd _iter(size_t d, array<size_t, S> ind)
00110                 { return iterator_nd(nd().stride(d), nd().begin(),
00111                         ivl::sub2ind(nd().stride(), ind)); }
00112 
00113         iterator_nd _next(size_t d, const iterator_nd& it)
00114                 { return iterator_nd(nd().stride(d), it,
00115                         (d == nd().ndims() -1 ? nd().length() : nd().stride(d + 1))); }
00116 
00117         iterator_nd _end(size_t d)
00118                 { return iterator_nd(nd().stride(d), nd().begin(),
00119                         (d == nd().ndims() - 1 ? nd().length() : nd().stride(d + 1))); }
00120 
00121         iterator_nd _last(size_t d)
00122                 { return iterator_nd(nd().stride(d), nd().begin(),
00123                         (d == nd().ndims() - 1 ? nd().length() : nd().stride(d + 1))
00124                         - nd().stride(d)); }
00125 
00126         // const iterator
00127 
00128         const_iterator_nd _begin(size_t d) const
00129                 { return const_iterator_nd(types::code_word<>(), nd().stride(d), nd().begin()); }
00130 
00131         const_iterator_nd _begin(size_t d, const const_iterator_nd& it) const
00132                 { return const_iterator_nd(nd().stride(d), it); }
00133 
00134         const_iterator_nd _iter(size_t d, const const_iter& it) const
00135                 { return const_iterator_nd(nd().stride(d), it, nd().begin()); }
00136 
00137         template<class S>
00138         const_iterator_nd _iter(size_t d, array<size_t, S> ind) const
00139                 { return const_iterator_nd(nd().stride(d), nd().begin(),
00140                         sub2ind(nd().stride(), ind)); }
00141 
00142         const_iterator_nd _next(size_t d, const const_iterator_nd& it) const
00143                 { return const_iterator_nd(nd().stride(d), it,
00144                         (d == nd().ndims() - 1 ? nd().length() : nd().stride(d + 1))); }
00145 
00146         const_iterator_nd _end(size_t d) const
00147                 { return const_iterator_nd(nd().stride(d), nd().begin(),
00148                         (d == nd().ndims() - 1 ? nd().length() : nd().stride(d + 1))); }
00149 
00150         const_iterator_nd _last(size_t d) const
00151                 { return const_iterator_nd(nd().stride(d), nd().begin(),
00152                         (d == nd().ndims() - 1 ? nd().length() : nd().stride(d + 1))
00153                         - nd().stride(d)); }
00154 
00155         // non-const reverse iterator
00156 #if 0 // disable completely the reverse ones, for now TODO: some time enable
00157         reverse_iterator_nd _rbegin(size_t d)
00158                 { return reverse_iterator_nd(types::code_word<>(), iterator_nd(
00159                         nd().stride(d), nd().rbegin().base())); }
00160 
00161         reverse_iterator_nd _rbegin(size_t d, const reverse_iterator_nd& it)
00162                 { return reverse_iterator_nd(iterator_nd(nd().stride(d),
00163                                 it.base().base())); }
00164 
00165         reverse_iterator_nd _riter(size_t d, const reverse_iter& it)
00166                 { return reverse_iterator_nd(iterator_nd(nd().stride(d), it.base())); }
00167 
00168         // TODO: BIG QUESTION WHETHER IT IS LIKE THIS OR FROM END
00169         template<class S>
00170         reverse_iterator_nd _riter(size_t d, array<size_t, S> ind)
00171                 { return reverse_iterator_nd(iterator_nd(nd().stride(d), nd().begin() +
00172                         sub2ind(nd().stride(), ind))); }
00173 
00174         reverse_iterator_nd _rnext(size_t d, const reverse_iter& it)
00175                 { return reverse_iterator_nd(iterator_nd(nd().stride(d), (it +
00176                         (d == nd().ndims() - 1 ? nd().length() : nd().stride(d + 1)))
00177                         .base())); }
00178 
00179         reverse_iterator_nd _rend(size_t d)
00180                 { return reverse_iterator_nd(iterator_nd(
00181                         nd().stride(d), (nd().rbegin() +
00182                         (d == nd().ndims() - 1 ? nd().length() : nd().stride(d + 1)))
00183                         .base())); }
00184 
00185         reverse_iterator_nd _rlast(size_t d)
00186                 { return reverse_iterator_nd(iterator_nd(
00187                         nd().stride(d), (nd().rbegin() +
00188                         (d == nd().ndims() - 1 ? nd().length() : nd().stride(d + 1))
00189                         - nd().stride(d)).base())); }
00190 
00191         // const reverse reverse_iterator
00192 
00193         const_reverse_iterator_nd _rbegin(size_t d) const
00194                 { return const_reverse_iterator_nd(types::code_word<>(), const_iterator_nd(
00195                         nd().stride(d), nd().rbegin().base())); }
00196 
00197         const_reverse_iterator_nd _rbegin(size_t d, const
00198                 const_reverse_iterator_nd& it) const
00199                 { return const_reverse_iterator_nd(const_iterator_nd(
00200                         nd().stride(d), it.base().base())); }
00201 
00202         const_reverse_iterator_nd _riter(size_t d, const
00203                 const_reverse_iter& it) const
00204                 { return const_reverse_iterator_nd(const_iterator_nd(
00205                         nd().stride(d), it.base())); }
00206 
00207         // TODO: BIG QUESTION WHETHER IT IS LIKE THIS OR FROM END
00208         template<class S>
00209         const_reverse_iterator_nd _riter(size_t d, array<size_t, S> ind) const
00210                 { return const_reverse_iterator_nd(const_iterator_nd(
00211                         nd().stride(d), (nd().begin() +
00212                         sub2ind(nd().stride(), ind)).base())); }
00213 
00214         const_reverse_iterator_nd _rnext(size_t d, const
00215                 const_reverse_iter& it) const
00216                 { return const_reverse_iterator_nd(const_iterator_nd(
00217                         nd().stride(d), (it +
00218                         (d == nd().ndims() - 1 ? nd().length() : nd().stride(d + 1)))
00219                         .base())); }
00220 
00221         const_reverse_iterator_nd _rend(size_t d) const
00222                 { return const_reverse_iterator_nd(const_iterator_nd(
00223                         nd().stride(d), (nd().rbegin() +
00224                         (d == nd().ndims() - 1 ? nd().length() : nd().stride(d + 1)))
00225                         .base())); }
00226 
00227         const_reverse_iterator_nd _rlast(size_t d) const
00228                 { return const_reverse_iterator_nd(const_iterator_nd(
00229                         nd().stride(d), (nd().rbegin() +
00230                         (d == nd().ndims() - 1 ? nd().length() : nd().stride(d + 1))
00231                         - nd().stride(d)).base())); }
00232 #endif
00233         // ----------
00234 
00235         // faster non past end capable minimal methods
00236 
00237         // non-const iterator
00238         _fast_iterator_nd _fast_begin(size_t d)
00239                 { return _fast_iterator_nd(nd().stride(d), nd().begin()); }
00240 
00241         _fast_iterator_nd _fast_last(size_t d)
00242                 { return _fast_iterator_nd(nd().stride(d), nd().begin() +
00243                         (d == nd().ndims() - 1 ? nd().length() : nd().stride(d + 1))
00244                         - nd().stride(d)); }
00245 
00246         // const iterator
00247 
00248         _fast_const_iterator_nd _fast_begin(size_t d) const
00249                 { return _fast_const_iterator_nd(nd().stride(d), nd().begin()); }
00250 
00251         _fast_const_iterator_nd _fast_last(size_t d) const
00252                 { return _fast_const_iterator_nd(nd().stride(d), nd().begin() +
00253                         (d == nd().ndims() - 1 ? nd().length() : nd().stride(d + 1))
00254                         - nd().stride(d)); }
00255 
00256 
00257         // ----------
00258 
00259         // iter_nd_border_walker functions
00260         iter_nd_border_walker first_to_last(size_t d) const
00261                 { return (d == nd().ndims() - 1 ? nd().length() : nd().stride(d + 1)) -
00262                         nd().stride(d); }
00263 
00264         iter_nd_border_walker begin_to_end(size_t d) const
00265                 { return (d == nd().ndims() - 1 ? nd().length() : nd().stride(d + 1)); }
00266 
00267 };
00268 
00269 } /* namespace array_nd_details */
00270 } /* namespace ivl */
00271 
00272 
00273 
00274 #endif // IVL_ARRAY_ND_DETAILS_ARRAY_ND_ITERATOR_ND_INTERFACE_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations