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