ivl 679
ivl/details/array/impl/common/dependable_array_common.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 #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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations