ivl 679
ivl/details/array_nd/impl/specialization/unary_elem_func_nd_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 
00026 
00027 template <class T,
00028                  template <typename, typename> class F,
00029                  class A,
00030                  class DERIVED_INFO
00031              >
00032 class array_nd<T,
00033                 data::unary_elem_func<F, A, DERIVED_INFO> > :
00034 
00035         public
00036         array_common_base<array_nd<T,
00037                 data::unary_elem_func<F, A, DERIVED_INFO> > >,
00038 
00039         public
00040         array_nd_details::basic_iterator_nd_interface<array_nd<T,
00041                 data::unary_elem_func<F, A, DERIVED_INFO> > >
00042 {
00043 private:
00044         typedef array_nd prv_this_type;
00045         typedef typename prv_this_type::common_base_class common_base_class;
00046         typedef typename prv_this_type::iter_nd_interface_class iter_nd_interface;
00047 
00048         class not_a_type {};
00049 
00050 protected:
00051         typedef typename common_base_class::tool tool;
00052 
00053         typedef typename tool::brackets_arg tool_brackets_arg;
00054 
00055 public:
00056         typedef array_nd this_type;
00057 
00058         typedef this_type this_array_nd_type;
00059 
00060         typedef typename types::derive<this_type>::type derived_type;
00061 
00062         typedef typename common_base_class::base_class base_class;
00063 
00064         typedef this_type array_type;
00065 
00067         typedef array<size_t, tiny> size_type;
00068 
00070         typedef typename A::size_nd_ref_type size_nd_ref_type;
00071 
00073         typedef typename A::stride_ref_type stride_ref_type;
00074 
00075 #if 0
00076 // unstable feature
00078         typedef typename A::has_1d_parenthesis has_1d_parenthesis;
00079 
00080         typedef typename A::has_2d_parenthesis has_2d_parenthesis;
00081 
00082         typedef typename A::has_3d_parenthesis has_3d_parenthesis;
00083 
00084         typedef typename A::has_nd_parenthesis has_nd_parenthesis;
00085 #endif
00086 
00087         template<bool PAST_END_CAPABLE = true>
00088         struct const_iterator_nd_class
00089         {
00090         private:
00091                 typedef typename types::t_if<types::t_expr<PAST_END_CAPABLE>,
00092                         typename A::const_iterator_nd,
00093                         typename A::_fast_const_iterator_nd>::type iter_nd;
00094 
00095                 iter_nd it;
00096 
00097         public:
00098 
00099                 // TODO: check others types iterator_traits for nd.
00100                 // probably wrong or missing.
00101                 // esspecially the default iterator nd which
00102                 // for some reason (??) questions random access.
00103                 // iterator_traits
00104 
00105                 typedef std::random_access_iterator_tag iterator_category;
00106                 typedef T value_type;
00107                 typedef ptrdiff_t difference_type;
00108                 //typedef const T* pointer;
00109                 //typedef const T reference;
00110                 typedef internal::pointer_face<const T> pointer;
00111                 // using this to comply with std:: iterators. if it is not optimized-out
00112                 // by the compiler, consider using
00113                 // `const internal::reference_face<const T, types::skip>'
00114                 typedef const internal::reference_face<const T, const_iterator_nd_class>
00115                         reference;
00116 
00117                 typedef const_iterator_nd_class this_type;
00118 
00119                 typedef types::t_false has_base_iterator;
00120 
00121                 struct iter_nd_border_walker
00122                 {
00123                         typedef typename iter_nd::iter_nd_border_walker iw_t;
00124                         iw_t iw;
00125 
00126                         iter_nd_border_walker() {}
00127                         iter_nd_border_walker(ptrdiff_t x) : iw(x) { }
00128                         iter_nd_border_walker(const iw_t& iw) : iw(iw) { }
00129                 };
00130 
00131                 struct iter_nd_dir_type
00132                 {
00133                         typedef typename iter_nd::iter_nd_dir_type id_t;
00134                         id_t id;
00135                         iter_nd_dir_type(const id_t& id1) : id(id) { }
00136                 };
00137 
00138                 // constructors
00139                 const_iterator_nd_class() { }
00140                 const_iterator_nd_class(const iter_nd& it) : it(it) { }
00141                 const_iterator_nd_class(const const_iterator_nd_class& o) : it(o.it) { }
00142 
00143                 // members
00144                 pointer operator ->() const
00145                 {
00146                         return pointer(array_details::elem_func_unary_op<
00147                         T, F<T, typename iter_nd::value_type> >::
00148                         from(*it));
00149                 }
00150 
00151                 reference operator *() const
00152                 {
00153                         return reference(array_details::elem_func_unary_op<
00154                                 T, F<T, typename iter_nd::value_type> >::
00155                                 from(*it), *this);
00156                 }
00157 
00158                 reference operator[] (ptrdiff_t j) const
00159                 {
00160                         return reference(array_details::elem_func_unary_op<
00161                                 T, F<T, typename iter_nd::value_type> >::
00162                                 from(it[j]),
00163                         // hope that the below line will be optimized-out when using T.
00164                         // or disregard the `tight' std:: standard that &(*iter) == &(*iter)
00165                                 const_iterator_nd_class(it + j));
00166                 }
00167 
00168                 // increment-decrement
00169                 this_type& operator++() { ++it; return *this; }
00170                 this_type& operator--() { --it; return *this; }
00171 
00172                 this_type operator++(int)
00173                         { this_type tmp(*this); ++it; return tmp; }
00174 
00175                 this_type operator--(int)
00176                         { this_type tmp(*this); --it; return tmp; }
00177 
00178                 // random access
00179                 this_type operator +(const ptrdiff_t j) const
00180                         { this_type tmp(it + j); return tmp; }
00181 
00182                 this_type operator -(const ptrdiff_t j) const
00183                         { this_type tmp(it - j); return tmp; }
00184 
00185                 this_type& operator +=(const size_t j)
00186                         { it += j; return *this; }
00187 
00188                 this_type& operator -=(const size_t j)
00189                         { it -= j; return *this; }
00190 
00191                 // border walker
00192                 this_type operator +(const iter_nd_border_walker& z)
00193                         { this_type tmp(it + z.iw); return tmp; }
00194 
00195                 this_type operator -(const iter_nd_border_walker& z)
00196                         { this_type tmp(it - z.iw); return tmp; }
00197 
00198                 this_type& operator +=(const iter_nd_border_walker& z)
00199                         { it += z.iw; return *this; }
00200 
00201                 this_type& operator -=(const iter_nd_border_walker& z)
00202                         { it -= z.iw; return *this; }
00203 
00204 
00205                 iter_nd_dir_type dir() const
00206                         { return iter_nd_dir_type(it.dir()); }
00207 
00208                 iter_nd_dir_type dir(ptrdiff_t x) const
00209                         { return iter_nd_dir_type(it.dir(x)); }
00210 
00211                 void inc_along_other_dim_at_begin(const this_type& y)
00212                         { it += y.it.dir(); }
00213 
00214                 void dec_along_other_dim_at_begin(const this_type& y)
00215                         { it -= y.it.dir(); }
00216 
00217                 void move_along(const this_type& y, ptrdiff_t x)
00218                         { it += y.it.dir(x); }
00219 
00220                 // difference
00221                 ptrdiff_t operator -(const this_type& a) const
00222                         { return it - a.it; }
00223 
00224         };
00225 
00226         typedef const_iterator_nd_class<true> const_iterator_nd;
00227         typedef const_iterator_nd_class<false> _fast_const_iterator_nd;
00228 
00229         typedef std::reverse_iterator<const_iterator_nd> const_reverse_iterator_nd;
00230 
00231 //YOU ARE HERE
00232         using base_class::derived;
00233 
00235         base_class& base() { return *this; }
00236         const base_class& base() const { return *this; }
00237 
00238 #if 0
00239 // todo: enable when 'has *d parenthesis is implemented
00240 // for now disable this feature for elem_funcs
00241 
00242         const T& operator()(size_t s1) const;
00243         const T& operator()(size_t s1, size_t s2) const;
00244         const T& operator()(size_t s1, size_t s2, size_t s3) const;
00245         const T& operator()(size_t s1, size_t s2, size_t s3, size_t s4) const;
00246         const T& operator()(size_t s1, size_t s2, size_t s3, size_t s4, size_t s5) const;
00247         const T& operator()(size_t s1, size_t s2, size_t s3, size_t s4, size_t s5, size_t s6) const;
00248 #endif
00249 
00250 
00251         template<class S>
00252         const T operator()(const array<size_t, S>& indx) const
00253         {
00254                 return array_details::elem_func_unary_op<
00255                         T, F<T, typename A::elem_type> >::
00256                         from((this->in1->derived())(indx));
00257         }
00259 
00260 
00263 
00264         array_nd() { }
00265 
00267         array_nd(const A& a1) { this->setref(a1); }
00268 
00270         array_nd(const array_nd& a) : common_base_class(a) { }
00276         // Construct by defining an element count.
00277         explicit array_nd(size_t count) { }
00278 
00279         // Construct by defining an element count and a sigle default value
00280         array_nd(size_t count, const T& s) { }
00281 
00282         // Construct by defining an element count and a pointer to data.
00283         array_nd(size_t count, const T *data) { }
00284 
00285         // Construct from a size_array containing the dimension sizes
00286         template<class S>
00287         array_nd(const array<size_t, S>& sz) { }
00288 
00289         // construct from a size_array containing the dimension sizes and scalar
00290         template<class S>
00291         array_nd(const array<size_t, S>& sz, const T& s) { }
00292 
00293         //Construct from a size_array and pointer
00294         template<class S>
00295         array_nd(const array<size_t, S>& sz, const T* ptr) { }
00296 
00297         //Construct from a size_array and an array with the values.
00298         template<class S, class J, class D>
00299         array_nd(const array<size_t, S>& sz, const array<J, D>& a) { }
00300 
00301         // Constructor using another form of array_nd
00302         template<class J, class S>
00303         array_nd(const array_nd<J, S>& a) { }
00304 
00310 
00311         size_nd_ref_type size_nd() const { return this->in1->size_nd(); }
00312 
00314         size_t size_nd(size_t d) const { return this->in1->size_nd(d); }
00315 
00316         // todo fix this and use a tool::stride
00318         stride_ref_type stride() const
00319         { return this->in1->stride(); }
00320 
00322         size_t stride(size_t dim) const
00323         { return this->in1->stride(dim); }
00324 
00326         size_type size() const { return this->in1->size(); }
00327 
00329         size_t ndims() const { return this->in1->ndims(); }
00333 };
00334 
00335 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations