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