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 00025 00044 template <class T, 00045 class A, 00046 class I, 00047 class DERIVED_INFO 00048 > 00049 class array_nd<T, data::subarray<A, I, DERIVED_INFO> > 00050 : 00051 public 00052 array_common_base<array_nd<T, 00053 data::subarray<A, I, DERIVED_INFO> > > 00054 00055 { 00056 private: 00057 typedef array_nd prv_this_type; 00058 typedef typename prv_this_type::common_base_class common_base_class; 00059 00060 typedef typename common_base_class::base_class prv_base_class; 00061 00062 class not_a_type { typedef not_a_type reference; }; 00063 00064 typedef array_nd_details::subarray_common_tools::sub_type sub_type; 00065 static inline sub_type type_from_indtype(ivl::index_array:: 00066 index_array_type y) 00067 { 00068 return array_nd_details::subarray_common_tools:: 00069 type_from_indtype(y); 00070 } 00071 00072 protected: 00073 typedef typename array_nd::best_reference_iterator 00074 best_reference_iterator; 00075 00076 typedef typename array_nd::const_reference_iterator 00077 const_reference_iterator; 00078 00079 typedef typename array_nd::tool tool; 00080 00081 using prv_base_class::in; 00082 using prv_base_class::idx; 00083 00084 using prv_base_class::all_sizes; 00085 using prv_base_class::all_len; 00086 using prv_base_class::diffs_ar; 00087 using prv_base_class::diffs; 00088 using prv_base_class::sizes; 00089 using prv_base_class::steps; 00090 using prv_base_class::iter; 00091 using prv_base_class::back_diffs; 00092 using prv_base_class::begin_to_ends; 00093 using prv_base_class::first_to_lasts; 00094 00095 using prv_base_class::nonsing_map; 00096 using prv_base_class::nonsing_rmap; 00097 using prv_base_class::idx_ar_map; 00098 using prv_base_class::idx_ar_rmap; 00099 00100 using prv_base_class::get_iter; 00101 00102 public: 00103 typedef array_nd this_type; 00104 00105 typedef this_type this_array_nd_type; 00106 00107 typedef typename this_type::derived_type derived_type; 00108 00109 typedef typename common_base_class::base_class base_class; 00110 00111 typedef this_type array_type; 00112 00114 typedef array<size_t, tiny> size_type; 00115 00117 typedef const array<size_t, tiny>& size_nd_ref_type; 00118 00120 //note: why should a non-ra array have stride anyway???? 00121 typedef array<size_t, tiny> stride_ref_type; 00122 00124 typedef types::t_true has_1d_parenthesis; 00125 typedef types::t_true has_2d_parenthesis; 00126 typedef types::t_true has_3d_parenthesis; 00127 typedef types::t_true has_nd_parenthesis; 00128 00129 00130 00131 // typedefs for class iterators 00132 typedef typename types::t_if<typename array_nd::is_writeable, 00133 data::subarray_nd_iterator<T, 00134 typename base_class::best_reference_iterator, 00135 typename base_class::const_reference_iterator, 00136 base_class::reference_iterator_is_nd::value, false>, 00137 not_a_type>::type iterator_nd; 00138 00139 typedef data::subarray_nd_iterator<T, 00140 typename base_class::const_reference_iterator, 00141 typename base_class::const_reference_iterator, 00142 base_class::reference_iterator_is_nd::value, true> const_iterator_nd; 00143 00144 typedef typename types::t_if<typename array_nd::is_writeable, 00145 data::subarray_nd_iterator<T, 00146 typename base_class::best_reference_iterator, 00147 typename base_class::const_reference_iterator, 00148 base_class::reference_iterator_is_nd::value, false, 0, false>, 00149 not_a_type>::type _fast_iterator_nd; 00150 00151 typedef data::subarray_nd_iterator<T, 00152 typename base_class::const_reference_iterator, 00153 typename base_class::const_reference_iterator, 00154 base_class::reference_iterator_is_nd::value, true, 0, false> 00155 _fast_const_iterator_nd; 00156 00157 typedef std::reverse_iterator<iterator_nd> reverse_iterator_nd; 00158 00159 typedef std::reverse_iterator<const_iterator_nd> 00160 const_reverse_iterator_nd; 00161 00162 template<int SPC> 00163 struct s_iterator_nd 00164 { 00165 typedef typename types::t_if<typename array_nd::is_writeable, 00166 data::subarray_nd_iterator<T, 00167 typename base_class::best_reference_iterator, 00168 typename base_class::const_reference_iterator, 00169 base_class::reference_iterator_is_nd::value, false, SPC>, 00170 not_a_type>::type type; 00171 }; 00172 template<int SPC> 00173 struct const_s_iterator_nd 00174 { 00175 typedef data::subarray_nd_iterator<T, 00176 typename base_class::const_reference_iterator, 00177 typename base_class::const_reference_iterator, 00178 base_class::reference_iterator_is_nd::value, true, SPC> type; 00179 }; 00180 00181 template<int SPC> 00182 struct _fast_s_iterator_nd 00183 { 00184 typedef typename types::t_if<typename array_nd::is_writeable, 00185 data::subarray_nd_iterator<T, 00186 typename base_class::best_reference_iterator, 00187 typename base_class::const_reference_iterator, 00188 base_class::reference_iterator_is_nd::value, false, SPC, false>, 00189 not_a_type>::type type; 00190 }; 00191 template<int SPC> 00192 struct _fast_const_s_iterator_nd 00193 { 00194 typedef data::subarray_nd_iterator<T, 00195 typename base_class::const_reference_iterator, 00196 typename base_class::const_reference_iterator, 00197 base_class::reference_iterator_is_nd::value, true, SPC, false> type; 00198 }; 00199 00200 template<int SPC> 00201 struct reverse_s_iterator_nd 00202 { 00203 typedef std::reverse_iterator<s_iterator_nd<SPC> > type; 00204 }; 00205 template<int SPC> 00206 struct const_reverse_s_iterator 00207 { 00208 typedef std::reverse_iterator<const_s_iterator_nd<SPC> > type; 00209 }; 00210 int iter_specialization_nd(size_t dim) const 00211 { 00212 return ((*idx)[dim].is_array()) ? 2 : 1; 00213 } 00214 00215 typedef typename const_iterator_nd:: 00216 iter_nd_border_walker iter_nd_border_walker; 00217 00218 00219 00220 /* 00221 size_t begin_pos(size_t d, size_t pos) 00222 { 00223 size_t mod = pos % nd().stride(d); 00224 if(d == nd().ndim() - 1) return mod; 00225 return pos - pos % nd().stride(d + 1) + mod; 00226 } 00227 00228 size_t end_pos(size_t d, size_t pos) 00229 { 00230 size_t mod = pos % nd().stride(d); 00231 if(d == nd().ndim() - 1) return mod + nd().length(); 00232 return pos - pos % nd().stride(d + 1) + mod + 00233 nd().stride(d + 1); 00234 } 00235 */ 00236 00237 // friend declarations for subarray iterator helper construction functions. 00238 template<class IT, class X> 00239 friend IT subarray_iter_create::_begin(X& a, size_t d); 00240 template <class IT, class X> 00241 friend IT subarray_iter_create::_begin(X& a, size_t d, const IT& it); 00242 template <class IT, class ITS, class X> 00243 friend IT subarray_iter_create::_iter(X& a, size_t d, const ITS& it); 00244 template <class IT, class S, class X> 00245 friend IT subarray_iter_create::_iter(X& a, size_t d, 00246 const array<size_t, S>& ind); 00247 template <class IT, class X> 00248 friend IT subarray_iter_create::_next(X& a, size_t d, const IT& it); 00249 template <class IT, class X> 00250 friend IT subarray_iter_create::_end(X& a, size_t d); 00251 template <class IT, class X> 00252 friend IT subarray_iter_create::_last(X& a, size_t d); 00253 00254 // non-const iterator 00255 iterator_nd _begin(size_t d) 00256 { return subarray_iter_create::_begin<iterator_nd>(*this, d); } 00257 00258 iterator_nd _begin(size_t d, const iterator_nd& it) 00259 { return subarray_iter_create::_begin<iterator_nd>(*this, d, it); } 00260 00261 iterator_nd _iter(size_t d, const typename 00262 array_nd::best_iterator& it) 00263 { return subarray_iter_create::_iter<iterator_nd>(*this, d, it); } 00264 00265 template <class S> 00266 iterator_nd _iter(size_t d, const array<size_t, S>& ind) 00267 { return subarray_iter_create::_iter<iterator_nd>(*this, d, ind); } 00268 00269 iterator_nd _next(size_t d, const iterator_nd& it) 00270 { return subarray_iter_create::_next<iterator_nd>(*this, d, it); } 00271 00272 iterator_nd _end(size_t d) 00273 { return subarray_iter_create::_end<iterator_nd>(*this, d); } 00274 00275 iterator_nd _last(size_t d) 00276 { return subarray_iter_create::_last<iterator_nd>(*this, d); } 00277 00278 // const iterator 00279 const_iterator_nd _begin(size_t d) const 00280 { return subarray_iter_create::_begin<const_iterator_nd>(*this, d); } 00281 00282 const_iterator_nd _begin(size_t d, const const_iterator_nd& it) const 00283 { return subarray_iter_create::_begin<const_iterator_nd>(*this, d, it); } 00284 00285 const_iterator_nd _iter(size_t d, const typename 00286 array_nd::const_iterator& it) const 00287 { return subarray_iter_create::_iter<const_iterator_nd>(*this, d, it); } 00288 00289 template <class S> 00290 const_iterator_nd _iter(size_t d, const array<size_t, S>& ind) const 00291 { return subarray_iter_create::_iter<const_iterator_nd>(*this, d, ind); } 00292 00293 const_iterator_nd _next(size_t d, const const_iterator_nd& it) const 00294 { return subarray_iter_create::_next<const_iterator_nd>(*this, d, it); } 00295 00296 const_iterator_nd _end(size_t d) const 00297 { return subarray_iter_create::_end<const_iterator_nd>(*this, d); } 00298 00299 const_iterator_nd _last(size_t d) const 00300 { return subarray_iter_create::_last<const_iterator_nd>(*this, d); } 00301 00302 // fast 00303 _fast_iterator_nd _fast_begin(size_t d) 00304 { return subarray_iter_create::_begin<_fast_iterator_nd>(*this, d); } 00305 _fast_iterator_nd _fast_last(size_t d) 00306 { return subarray_iter_create::_last<_fast_iterator_nd>(*this, d); } 00307 _fast_const_iterator_nd _fast_begin(size_t d) const 00308 { return subarray_iter_create::_begin<_fast_const_iterator_nd>(*this, d); } 00309 _fast_const_iterator_nd _fast_last(size_t d) const 00310 { return subarray_iter_create::_last<_fast_const_iterator_nd>(*this, d); } 00311 00312 #if 0 00313 // non-const reverse iterator 00314 reverse_iterator_nd _rbegin(size_t d); 00315 reverse_iterator_nd _rbegin(size_t d, const reverse_iterator_nd& itr); 00316 reverse_iterator_nd _riter(size_t d, const 00317 typename array_nd::best_iterator& it); 00318 template <class S> 00319 reverse_iterator_nd _riter(size_t d, array<size_t, S> ind); 00320 reverse_iterator_nd _rnext(size_t d, const reverse_iterator_nd& itr); 00321 reverse_iterator_nd _rend(size_t d); 00322 reverse_iterator_nd _rlast(size_t d); 00323 // const reverse reverse_iterator 00324 const_reverse_iterator_nd _rbegin(size_t d) const; 00325 const_reverse_iterator_nd _rbegin(size_t d, 00326 const const_reverse_iterator_nd& itr) const; 00327 const_reverse_iterator_nd _riter(size_t d, 00328 const typename array_nd::const_iterator& it) const; 00329 template <class S> 00330 const_reverse_iterator_nd _riter(size_t d, array<size_t, S> ind) const; 00331 const_reverse_iterator_nd _rnext(size_t d, 00332 const const_reverse_iterator_nd& itr) const; 00333 const_reverse_iterator_nd _rend(size_t d) const; 00334 const_reverse_iterator_nd _rlast(size_t d) const; 00335 #endif 00336 00337 // iter_nd_border_walker functions 00338 iter_nd_border_walker first_to_last(size_t d) const 00339 { 00340 size_t j = nonsing_rmap[d]; 00341 ptrdiff_t k = idx_ar_rmap[d]; 00342 return iter_nd_border_walker(iter[j], first_to_lasts[j], 00343 sizes[j] - 1, k); 00344 } 00345 00346 iter_nd_border_walker begin_to_end(size_t d) const 00347 { 00348 size_t j = nonsing_rmap[d]; 00349 ptrdiff_t k = idx_ar_rmap[d]; 00350 return iter_nd_border_walker(iter[j], begin_to_ends[j], 00351 sizes[j], k); 00352 } 00353 00354 00355 00356 using base_class::derived; 00357 00358 00359 00360 00361 00363 base_class& base() { return *this; } 00364 const base_class& base() const { return *this; } 00365 00366 00373 using base_class::operator[]; 00374 using base_class::length; 00375 using base_class::numel; 00376 00377 using common_base_class::operator(); 00378 00382 #if 0 00383 // TODO: have to implement 00388 T& operator()(size_t s1); 00389 T& operator()(size_t s1, size_t s2); 00390 T& operator()(size_t s1, size_t s2, size_t s3); 00391 T& operator()(size_t s1, size_t s2, size_t s3, size_t s4); 00392 T& operator()(size_t s1, size_t s2, size_t s3, size_t s4, size_t s5); 00393 T& operator()(size_t s1, size_t s2, size_t s3, size_t s4, size_t s5, size_t s6); 00394 #endif 00395 00398 template<class S> 00399 typename types::best_iterator<array_nd>::type::reference operator()( 00400 const array<size_t, S>& indx) 00401 { 00402 iterator_nd p(_begin(0) + indx[0]); 00403 for(size_t i = 1; i < indx.length(); i++) 00404 p.move_along(_begin(i), indx[i]); 00405 return *p; 00406 } 00407 00408 #if 0 00409 const T& operator()(size_t s1) const; 00410 const T& operator()(size_t s1, size_t s2) const; 00411 const T& operator()(size_t s1, size_t s2, size_t s3) const; 00412 const T& operator()(size_t s1, size_t s2, size_t s3, size_t s4) const; 00413 const T& operator()(size_t s1, size_t s2, size_t s3, size_t s4, size_t s5) const; 00414 const T& operator()(size_t s1, size_t s2, size_t s3, size_t s4, size_t s5, size_t s6) const; 00415 #endif 00416 00419 template<class S> 00420 typename array_nd::const_iterator::reference operator() 00421 (const array<size_t, S>& indx) const 00422 { 00423 const_iterator_nd p(_begin(0) + indx[0]); 00424 00425 for(size_t i = 1; i < indx.length(); i++) 00426 p.move_along(_begin(i), indx[i]); 00427 00428 return *p; 00429 } 00430 00431 00434 00435 array_nd() { in = NULL; } 00436 00438 array_nd(A& a, const I& idx) { this->setref(a, idx); } 00439 00441 array_nd(const this_type& a) : 00442 common_base_class(a) {}; 00449 // Construct by defining an element count. 00450 explicit array_nd(size_t count) { } 00451 00452 // Construct by defining an element count and a sigle default value 00453 array_nd(size_t count, const T& s) { } 00454 00455 // Construct by defining an element count and a pointer to data. 00456 array_nd(size_t count, const T *data) { } 00457 00458 // Construct from a size_array containing the dimension sizes 00459 template<class S> 00460 array_nd(const array<size_t, S>& sz) { } 00461 00462 // construct from a size_array containing the dimension sizes and scalar 00463 template<class S> 00464 array_nd(const array<size_t, S>& sz, const T& s) { } 00465 00466 //Construct from a size_array and pointer 00467 template<class S> 00468 array_nd(const array<size_t, S>& sz, const T* ptr) { } 00469 00470 //Construct from a size_array and an array with the values. 00471 template<class S, class J, class D> 00472 array_nd(const array<size_t, S>& sz, const array<J, D>& a) { } 00473 00474 // Constructor using another form of array_nd 00475 template<class J, class S> 00476 array_nd(const array_nd<J, S>& a) { } 00477 00483 00484 size_nd_ref_type size_nd() const { return all_sizes; } 00485 00487 size_t size_nd(size_t d) const { return all_sizes[d]; } 00488 00489 stride_ref_type stride() const 00490 { 00491 // no stored stride information because subarray has no random access 00492 return cumprod(shift(all_sizes, 1, size_t(1))); 00493 } 00494 00496 size_type size() const { return all_sizes; } 00497 00499 size_t size(size_t d) const { return all_sizes[d]; } 00500 00502 size_t ndims() const { return all_sizes.length(); } 00508 // TODO: need to perform cut on resize(0) for special index_array values 00515 template<class K> 00516 derived_type& operator=(const K& k) 00517 { common_base_class::operator=(k); return derived(); } 00518 //using common_base_class::operator=; 00519 00521 this_type& operator=(const this_type& in) 00522 { common_base_class::operator=(in); return *this; } 00523 /* 00525 derived_type& operator=(const T& s) 00526 { 00527 base_class::operator=(array<T, 00528 data::ref_val_repeat, types::term>(this->length(), s)); 00529 return this->derived(); 00530 } 00531 00533 template<class S, class K> 00534 derived_type& operator=(const array_nd<T, S, K>& a) 00535 { base_class::operator=(a); return *this; } 00536 */ 00539 }; 00540