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_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