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 #ifndef IVL_ARRAY_DETAILS_COMMON_DEPENDABLE_ARRAY_COMMON_HPP 00025 #define IVL_ARRAY_DETAILS_COMMON_DEPENDABLE_ARRAY_COMMON_HPP 00026 00027 namespace ivl { 00028 00029 namespace array_details { 00030 00031 00032 00033 // This class provides specializations of the array_common_base 00034 // that depend on some traits of the array: is_writeable, is_resizeable. 00035 template < 00036 class T, class S, 00037 class BASE, 00038 class IS_WRITEABLE, class IS_RESIZEABLE> 00039 class dependable_array_common 00040 { 00041 }; 00042 00043 // Writeable but Not Resizeable 00044 template <class T, class S, class B> 00045 class dependable_array_common<T, S, B, types::t_true, types::t_false> 00046 : public readwrite_array_common<T, S, B, types::t_true> 00047 { 00048 private: 00049 typedef array<T, S> t; 00050 typedef dependable_array_common prv_this_type; 00051 t& to_array() { return static_cast<t&>(*this); } 00052 const t& to_array() const { return static_cast<const t&>(*this); } 00053 00054 protected: 00055 typedef dependable_array_common direct_base; 00056 00057 template <class J, class D> 00058 void init_size_with_array(const array<J, D>& o) 00059 { 00060 // need this because we want only first elements 00061 ivl::copy_out(*this, o); 00062 00063 //loop_on<loops::assign_copy_class>(to_array().derived(), o); 00064 } 00065 00066 template <class J> 00067 void init_size_with_element(const J& o) 00068 { 00069 loop_on<loops::assign_copy_class>(to_array(), o); 00070 } 00071 00072 public: 00073 typedef typename prv_this_type::derived_type derived_type; 00074 00075 template <class A> 00076 derived_type& assign_array(const A& o) 00077 { 00078 CHECK(to_array().length() == o.length(), eshape()); 00079 // users guide: is you have a compiler error here it probably means that 00080 // you are calling assign_array with something that is not an ivl array. 00081 00082 loop_on<loops::assign_copy_class>(to_array().derived(), o); 00083 return to_array().derived(); 00084 } 00085 00086 template <class A> 00087 derived_type& assign_array(const ret<A>& o) 00088 { 00089 CHECK(to_array().length() == o.length(), eshape()); 00090 // users guide: is you have a compiler error here it probably means that 00091 // you are calling assign_array with something that is not an ivl array. 00092 00093 to_array().derived().swap(o.ret_base()); 00094 return to_array().derived(); 00095 } 00096 00097 // writeable but not resizeable arrays behave like this: assign 00098 // the value to all elements when assign_element is called. 00099 template <class J> 00100 derived_type& assign_element(const J& o) 00101 { 00102 loop_on<loops::assign_copy_class>(to_array().derived(), o); 00103 return to_array().derived(); 00104 } 00105 00106 dependable_array_common() {} 00107 }; 00108 00109 // Resizeable but Not Writeable (not usual.) 00110 template <class T, class S, class B> 00111 class dependable_array_common<T, S, B, types::t_false, types::t_true> 00112 : public readwrite_array_common<T, S, B, types::t_false> 00113 { 00114 private: 00115 typedef array<T, S> t; 00116 t& to_array() { return static_cast<t&>(*this); } 00117 const t& to_array() const { return static_cast<const t&>(*this); } 00118 00119 protected: 00120 typedef dependable_array_common direct_base; 00121 /* 00122 template <class D, class P> 00123 const derived_type& operator=(const array<T, D, P>& o) const 00124 { 00125 // silently exist but cannot be called 00126 return to_array().derived(); 00127 } 00128 */ 00129 00130 public: 00131 dependable_array_common() {} 00132 }; 00133 00134 // Writeable and Resizeable 00135 template <class T, class S, class B> 00136 class dependable_array_common<T, S, B, types::t_true, types::t_true> 00137 : public readwrite_array_common<T, S, B, types::t_true> 00138 { 00139 private: 00140 typedef array<T, S> t; 00141 typedef dependable_array_common prv_this_type; 00142 00143 t& to_array() { return static_cast<t&>(*this); } 00144 const t& to_array() const { return static_cast<const t&>(*this); } 00145 00146 protected: 00147 typedef dependable_array_common direct_base; 00148 00149 template <class J, class D> 00150 void init_size_with_array(const array<J, D>& o) 00151 { 00152 // need this because we want only first elements 00153 ivl::copy_out(to_array(), o); 00154 00155 //loop_on<loops::assign_copy_class>(to_array().derived(), o); 00156 } 00157 00158 template <class J> 00159 void init_size_with_element(const J& o) 00160 { 00161 loop_on<loops::assign_copy_class>(to_array(), o); 00162 } 00163 00164 public: 00165 typedef typename prv_this_type::derived_type derived_type; 00166 00167 template <class A> 00168 derived_type& assign_array(const A& o) 00169 { 00170 // users guide: is you have a compiler error here it probably means that 00171 // you are calling assign_array with something that is not an ivl array. 00172 00173 //NO WAY: resize(0) before resize() is optimum when assigning. 00174 //to_array().derived().resize(typename A::derived_type::size_type(0)); 00175 00176 00177 //?maybe?:to_array().derived().reshape( 00178 // o.template highest_common_class<derived_type>().size()); // resize_like 00179 //?or?:to_array().template highest_common_class<A>().reshape( 00180 // o.template highest_common_class<derived_type>().size()); // resize_like 00181 00182 00183 to_array().template highest_common_class<A>().reshape( 00184 o.template highest_common_class<t>().size()); // resize_like 00185 00186 00187 //TODO: shouldn't this be: 00188 //to_array().derived().resize( 00189 // o.template highest_common_class<t>().size()); // resize_like 00190 //by resize rule? shouldn't resize be always called on derived()? 00191 //or no, it should handle on itself, for any level, but then 00192 // NEEDS FIX, for all array classes to support this!! 00193 // anyway it certainly wont work well for vector<T>.resize()!!!! :) 00194 00195 loop_on<loops::assign_copy_class>(to_array().derived(), o); 00196 return to_array().derived(); 00197 } 00198 00199 template <class A> 00200 derived_type& assign_array(ret<A>& o) 00201 { 00202 to_array().derived().swap(o.ret_base()); 00203 return to_array().derived(); 00204 } 00205 00206 template <class J> 00207 derived_type& assign_element(const J& s) 00208 { 00209 typedef typename derived_type::size_type sz_t; 00210 // Note: not all arrays support resizing with (1, s) 00211 // however this statement works for all array types because 00212 // fixed dim arrays have size_type of dims<N> which 00213 // has a constructor that initializes all dimensions with 00214 // the argument, e.g. sz_t(1) is [1, 1] in a size_dim<2>. 00215 00216 //to_array().derived().reset(sz_t(1), s); 00217 to_array().derived().resize(sz_t(0)); 00218 to_array().derived().resize(sz_t(1), cast<T>(s)); 00219 return to_array().derived(); 00220 } 00221 00222 dependable_array_common() {} 00223 }; 00224 00225 // Not writeable Not resizeable 00226 template <class T, class S, class B> 00227 class dependable_array_common<T, S, B, types::t_false, types::t_false> 00228 : public readwrite_array_common<T, S, B, types::t_false> 00229 { 00230 private: 00231 typedef array<T, S> t; 00232 t& to_array() { return static_cast<t&>(*this); } 00233 const t& to_array() const { return static_cast<const t&>(*this); } 00234 00235 protected: 00236 typedef dependable_array_common direct_base; 00237 /* 00238 template <class D, class P> 00239 const derived_type& operator=(const array<T, D, P>& o) const 00240 { 00241 // silently exist but cannot be called 00242 } 00243 */ 00244 00245 public: 00246 dependable_array_common() {} 00247 }; 00248 00249 00250 00251 } /* namespace array_details */ 00252 00253 } /* namespace ivl */ 00254 00255 #endif // IVL_ARRAY_DETAILS_COMMON_DEPENDABLE_ARRAY_COMMON_HPP