ivl 679
ivl/details/array/impl/specialization/wrap_array_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 namespace array_details {
00025 
00026 template <class RESIZEABLE>
00027 struct wrap_array_resize_details { };
00028 
00029 template <class HAS_C_PTR, class T>
00030 struct wrap_array_ptr_details { };
00031 
00032 template <class D, class IS_FORCE>
00033 struct wrap_array_overlap_impl { };
00034 
00035 template <class A>
00036 struct wrap_ices_iterator : public A
00037 {
00038         A& base() { return static_cast<A&>(*this); }
00039         const A& base() const { return static_cast<const A&>(*this); }  
00040         typedef typename A::value_type prv_vt;
00041         typedef ivl::scalar<prv_vt> value_type;
00042         typedef ivl::scalar<prv_vt> reference;
00043         value_type operator*() const { return A::operator*(); }
00044         template<class I>
00045         value_type operator[](I i) const { return A::operator[](i); }
00046         wrap_ices_iterator() {}
00047         template <class O>
00048         wrap_ices_iterator(const O& a) : A(a) { }
00049         wrap_ices_iterator(const wrap_ices_iterator& a) : A(a) { }
00050 
00051         using A::operator -;
00052         ptrdiff_t operator-(const wrap_ices_iterator&o)
00053         {
00054                 return base() - o.base();
00055         }
00056 
00057 
00058         wrap_ices_iterator& operator=(const wrap_ices_iterator& o)
00059                 { A::operator=(o.base()); return *this; }
00060         template<class K>
00061         wrap_ices_iterator& operator=(const K& o)
00062         {
00063                 A::operator=(o);
00064                 return *this;
00065         }
00066         //using A::operator=;
00067 };
00068 
00069 template <class ICES, class A>
00070 struct wrap_ices_it
00071 {
00072         typedef A type;
00073 };
00074 template<class A>
00075 struct wrap_ices_it<types::t_true, A>
00076 {
00077         typedef wrap_ices_iterator<A> type;
00078 };
00079 
00080 } /* namespace array_details */
00081 
00092 template <class T,
00093                  class A,
00094                  class ATTR,
00095                  class DERIVED_INFO
00096              >
00097 class array<T, data::wrap_array<A, ATTR, DERIVED_INFO> >
00098         :
00099         public array_common_base<
00100                 array<T, data::wrap_array<A, ATTR, DERIVED_INFO> > >,
00101 
00102         public data::referer<typename types::derive<
00103                 array<T, data::wrap_array<A, ATTR, DERIVED_INFO> > >::type>,
00104 
00105         public array_details::wrap_array_overlap_impl<
00106                 array<T, data::wrap_array<A, ATTR, DERIVED_INFO> >,
00107                 typename types::t_eq<ATTR, data::force_wrap_array_attr>::type>,
00108                 
00109         public data::wrap_identifier<ATTR>
00110 {
00111 
00112 private:
00113         typedef array_common_base<array<T,
00114                 data::wrap_array<A, ATTR, DERIVED_INFO> > > common_base_class;
00115 
00116         typedef typename
00117                 types::is_base<data::ice_wrap_array_attr_base_identifier, ATTR>
00118                 ::type  prv_is_ice;
00119         typedef typename types::t_or<
00120                         //types::t_eq<ATTR, data::ices_wrap_array_attr>,
00121                         prv_is_ice, // @@@ test
00122                         types::t_eq<ATTR, data::icers_wrap_array_attr<T> >
00123                 >
00124                 ::type prv_is_ices;
00125         typedef typename types::t_not<prv_is_ice>::type prv_is_nice;
00126 
00127         typedef typename types::t_if<typename array::is_writeable,
00128                         typename types::best_iterator<A>::type,
00129                         typename A::const_iterator>::type ref_a_best_iterator;
00130 
00131         typedef typename types::t_if<typename array::is_writeable,
00132                         typename types::best_reverse_iterator<A>::type,
00133                         typename A::const_reverse_iterator>
00134                                 ::type ref_a_best_reverse_iterator;
00135         
00136         typedef typename array_details::
00137                 wrap_ices_it<prv_is_ices, ref_a_best_iterator>
00138                 ::type a_best_iterator;
00139         typedef typename array_details::
00140                 wrap_ices_it<prv_is_ices, ref_a_best_reverse_iterator>
00141                 ::type a_best_reverse_iterator;
00142         typedef typename array_details::
00143                 wrap_ices_it<prv_is_ices, typename A::const_iterator>
00144                 ::type a_const_iterator;
00145         typedef typename array_details::
00146                 wrap_ices_it<prv_is_ices, 
00147                 typename A::const_reverse_iterator>::type a_const_reverse_iterator;
00148 
00149         typedef typename A::this_array_type a_t;
00150 
00151 protected:
00152         typedef typename array::has_random_access prv_has_random_access;
00153 
00154         typedef array_details::elem_func_tools<T,
00155                 prv_has_random_access::value> tool;
00156 
00157         typedef typename types::t_if<prv_is_ice, 
00158                 internal::relinit_pointer_face<A>, A*>
00159                 ::type prv_a_store_t;
00160                 
00161         friend class tool::not_a_type; // allow disabled types only in our class
00162 
00163         typedef typename types::t_if<prv_is_ice, typename tool::not_a_type, array>
00164                 ::type nice_this_type;
00165         typedef typename types::t_if<prv_is_ice, array, typename tool::not_a_type>
00166                 ::type ice_this_type;
00167         typedef typename types::t_if<types::t_and<prv_is_ice, types::t_not<types::is_const<A> > >, const A&, 
00168                 typename tool::not_a_type>::type prv_const_ice_a;
00169 
00170         prv_a_store_t a_ptr;
00171         a_best_iterator a_begin;
00172         size_t len;
00173 
00174 public:
00175         typedef array this_type;
00176 
00177         typedef this_type this_array_type;
00178 
00179         typedef this_type array_type;
00180 
00181         typedef T elem_type;
00182 
00183         typedef typename common_base_class::derived_type derived_type;
00184 
00185         typedef typename common_base_class::base_class base_class;
00186 
00188         typedef size_t size_type;
00189 
00191         typedef ptrdiff_t diff_type;
00192 
00193         using base_class::derived;
00194 
00195         template <class O>
00196         void assign(const O& o)
00197         {
00198                 a_ptr->assign(o);
00199         }
00200         template <class O>
00201         void assign_array(const O& o)
00202         {
00203                 a_ptr->assign_array(o);
00204         }
00205         template <class O>
00206         void assign_element(const O& o)
00207         {
00208                 a_ptr->assign_element(o);
00209         }
00210 
00211         void resize(size_t len)
00212         {
00213                 if(array_details::
00214                         wrap_array_resize_details<typename array::is_resizeable>
00215                         ::resize(a_ptr, len)) {
00216                                 a_begin = a_ptr->begin();
00217                                 len = a_ptr->length();
00218                         }
00219         }
00220 
00221         void resize(size_t len, const T& s) // with padding
00222         {
00223                 if(array_details::
00224                         wrap_array_resize_details<typename array::is_resizeable>
00225                         ::resize(static_cast<a_t*>(a_ptr), len, s)) {
00226                                 a_begin = a_ptr->begin();
00227                                 len = a_ptr->length();
00228                         }
00229         }
00230 
00232         void reshape(size_t len) { resize(len); }
00233         void reshape(size_t len, const T& s) { resize(len, s); }
00234 
00235         void clear() { resize(0); }
00236 
00237         typedef typename types::t_if<typename array::is_writeable,
00238                 a_best_iterator, types::not_a_type>::type iterator;
00239 
00240         typedef a_const_iterator const_iterator;
00241 
00242         typedef typename types::t_if<typename array::is_writeable,
00243                 a_best_reverse_iterator,
00244                 types::not_a_type>::type reverse_iterator;
00245 
00246         typedef a_const_reverse_iterator const_reverse_iterator;
00247 
00248         typedef typename A::iter_border_walker iter_border_walker;
00249 
00250         typedef a_best_iterator best_iterator;
00251         typedef typename std::iterator_traits<best_iterator>::
00252                 reference best_reference;
00253         typedef typename std::iterator_traits<const_iterator>::
00254                 reference const_reference;
00255         typedef best_reference reference;
00256 
00257         best_iterator begin() { return a_begin; }
00258         best_iterator end() { return a_ptr->end(); }
00259         const_iterator begin() const { return const_iterator(a_begin); }
00260         const_iterator end() const { return a_ptr->end(); }
00261 
00262         a_best_reverse_iterator rbegin() { return a_ptr->rbegin(); }
00263         a_best_reverse_iterator rend() { return a_ptr->rend(); }
00264         const_reverse_iterator rbegin() const { return a_ptr->rbegin(); }
00265         const_reverse_iterator rend() const { return a_ptr->rend(); }
00266 
00267         typename types::apply_const<T, types::is_const<A> >::type c_ptr()
00268         {
00269                 return array_details::
00270                         wrap_array_ptr_details<typename array::has_c_ptr, T>
00271                         ::c_ptr(a_ptr);
00272         }
00273 
00274         const T* c_ptr() const
00275         {
00276                 return array_details::
00277                         wrap_array_ptr_details<typename array::has_c_ptr, T>
00278                         ::const_c_ptr(a_ptr);
00279         }
00280 
00283         //TODO: explain this better.
00285         size_t length() const { return len; }
00287         size_type size() const { return length(); }
00289         size_t numel() const { return length(); }
00292         iter_border_walker first_to_last() const { return a_ptr->first_to_last(); }
00293         iter_border_walker begin_to_end() const { return a_ptr->begin_to_end(); }
00294 
00300 
00301         best_reference operator[]
00302                 (typename tool::brackets_arg i)
00303         {
00304                 CHECK(i >= 0 && i < length(), erange);
00305                 typedef typename tool::template brackets_c<best_reference> toolf;
00306                 return toolf::f(a_begin, i);
00307         }
00308 
00310         const_reference operator[]
00311                 (typename tool::brackets_arg i) const
00312         {
00313                 CHECK(i >= 0 && i < length(), erange);
00314                 typedef typename tool::template brackets_c<best_reference> toolf;
00315                 return toolf::f(a_begin, i);
00316         }
00321         void setref(A& a)
00322         {
00323                 a_ptr = &a;
00324                 //a_begin = a.begin();
00325                 a_begin = a_ptr->begin();
00326                 len = a.length();
00327         }
00328         A& getref() { return *a_ptr; }
00329 
00330         void init(A& a)
00331         {
00332                 setref(a);
00333         }
00334         void init(const array& o)
00335         {
00336                 a_ptr = o.a_ptr;
00337                 //a_begin = o.a_begin;
00338                 a_begin = a_ptr->begin();
00339                 len = o.len;
00340         }
00341         template<class J>
00342         void init(J& a) // TODO: const weirdness in ice requires this
00343         {
00344                 a_ptr = &a;
00345                 //a_begin = a.begin();
00346                 a_begin = a_ptr->begin();
00347                 len = a.length();
00348         }
00349 
00350 
00351         template <class X, class Y>
00352         friend struct array_details::wrap_array_overlap_impl;
00353 
00354         using array_details::wrap_array_overlap_impl<
00355                 this_type,
00356                 typename types::t_eq<ATTR, data::force_wrap_array_attr>::type>::overlap;
00357 
00358         operator A&() { return *a_ptr; }
00359         operator typename types::apply_const<A>::type&() const { return *a_ptr; }
00364 
00365         array() { types::r_if<prv_is_nice>(a_ptr, types::skip()) = 0; len = 0; }
00366 
00368         array(A& a) : a_ptr(&a) {
00369                 a_begin = a_ptr->begin(); 
00370                 len = a.length(); 
00371         }
00372 
00373         // construction from const reference arrays for ice
00374         array(prv_const_ice_a a) : a_ptr(&a) {
00375                 a_begin = a_ptr->begin(); 
00376                 len = a.length(); 
00377         }
00378 
00380         array(const array& o) 
00381                 : a_ptr(o.a_ptr) { a_begin = a_ptr->begin(); len = o.len; }
00387 
00388         array(size_t) {}
00389 
00391         template <class J, class D>
00392         array(size_t, const array<J, D>&) {}
00393 
00395         array(size_t, const T*) {}
00396 
00398         template<class J, class S>
00399         array(const array<J, S>& a) { init(a.derived()); }
00401         template<class J, class S>
00402         array(array<J, S>& a) { init(a.derived()); }
00403 
00416         using base_class::operator=;
00417 
00418         this_type& operator=(const nice_this_type& a)
00419         {
00420                 common_base_class::operator=(a);
00421                 return *this;
00422         }
00423         this_type& operator=(const ice_this_type& a)
00424         {
00425                 init(a);
00426                 return *this;
00427         }
00428 
00431 
00432         ~array() { }
00433 
00434 };
00435 
00436 namespace array_details {
00437 
00438 template <>
00439 struct wrap_array_resize_details<types::t_false>
00440 {
00441         template <class A, class S>
00442         static inline
00443         bool resize(A* a, const S& l) { return false; }
00444 
00445         template <class A, class S, class T>
00446         static inline
00447         bool resize(A* a, const S& l, const T& t) { return false; }
00448 };
00449 
00450 template <>
00451 struct wrap_array_resize_details<types::t_true>
00452 {
00453         template <class A, class S>
00454         static inline
00455         bool resize(A* a, const S& l) { a->resize(l); return true; }
00456 
00457         template <class A, class S, class T>
00458         static inline
00459         bool resize(A* a, const S& l, const T& t) { a->resize(l, t); return true; }
00460 };
00461 
00462 template <class T>
00463 struct wrap_array_ptr_details <types::t_false, T>
00464 {
00465         template <class A>
00466         static inline T* c_ptr(A* a) { return 0; }
00467         template <class A>
00468         static inline const T* c_ptr(const A* a) { return 0; }
00469 };
00470 
00471 template <class T>
00472 struct wrap_array_ptr_details <types::t_true, T>
00473 {
00474         template <class A>
00475         static inline T* c_ptr(A* a) { return a->c_ptr(); }
00476         template <class A>
00477         static inline const T* c_ptr(const A* a) { return a->c_ptr(); }
00478 };
00479 
00480 template <class D>
00481 struct wrap_array_overlap_impl<D, types::t_true>
00482 {
00483         template <class A>
00484         bool overlap(const A& a) const { return false; }
00485         template <class A>
00486         bool self_overlap(const A& a) const { return false; }
00487 
00488 };
00489 
00490 template <class D>
00491 struct wrap_array_overlap_impl<D, types::t_false>
00492 {
00493 private:
00494         const D& d() const { return static_cast<const D&>(*this); }
00495 public:
00496         template <class A>
00497         bool overlap(const A& a) const { return d().a_ptr->overlap(a); }
00498         template <class A>
00499         bool self_overlap(const A& a) const { return d().a_ptr->overlap(a); } //TODO: @@@@!!! check!
00500 };
00501 
00502 } /* namespace array_details */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations