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_CORE_DETAILS_SAFETY_CHECK_FORCE_HPP 00025 #define IVL_CORE_DETAILS_SAFETY_CHECK_FORCE_HPP 00026 00027 namespace ivl { 00028 namespace array_details { 00029 00030 template <class BASE> 00031 class force_op 00032 : 00033 public BASE 00034 { 00035 typedef force_op derived_type; 00036 derived_type& derived() { return static_cast<derived_type&>(*this); } 00037 public: 00038 typedef typename BASE::type type; 00039 typedef typename BASE::base_class base_class; 00040 typedef force_op this_type; 00041 00042 template<class A> 00043 force_op(A& a) : BASE(a) { } 00044 00045 derived_type& operator=(const this_type& b) 00046 { 00047 this->base().assign(b.base()); 00048 return *this; 00049 } 00050 00051 template <class B> 00052 derived_type& operator=(const B& b) 00053 { 00054 this->base().assign(b); 00055 return derived(); 00056 } 00057 00058 template <class B> 00059 derived_type& operator+=(const B& b) 00060 { 00061 this->base().plus_assign(b); 00062 return derived(); 00063 } 00064 00065 template <class B> 00066 derived_type& operator-=(const B& b) 00067 { 00068 this->base().minus_assign(b); 00069 return derived(); 00070 } 00071 00072 template <class B> 00073 derived_type& operator*=(const B& b) 00074 { 00075 this->base().times_assign(b); 00076 return derived(); 00077 } 00078 00079 template <class B> 00080 derived_type& operator/=(const B& b) 00081 { 00082 this->base().divide_assign(b); 00083 return derived(); 00084 } 00085 00086 template <class B> 00087 derived_type& operator&=(const B& b) 00088 { 00089 this->base().mod_assign(b); 00090 return derived(); 00091 } 00092 00093 template <class B> 00094 derived_type& operator|=(const B& b) 00095 { 00096 this->base().bitor_assign(b); 00097 return derived(); 00098 } 00099 00100 template <class B> 00101 derived_type& operator<<=(const B& b) 00102 { 00103 this->base().bitlshift_assign(b); 00104 return derived(); 00105 } 00106 00107 template <class B> 00108 derived_type& operator>>=(const B& b) 00109 { 00110 this->base().bitrshift_assign(b); 00111 return derived(); 00112 } 00113 00114 template <class B> 00115 derived_type& operator^=(const B& b) 00116 { 00117 this->base().bitxor_assign(b); 00118 return derived(); 00119 } 00120 }; 00121 00122 template <class A, class IS_ARRAY> 00123 class force_impl { }; 00124 00125 template <class A> 00126 class force_impl<A, types::t_false> 00127 { 00128 /*A& a; 00129 typedef force_impl derived_type; 00130 derived_type& derived() { return static_cast<derived_type&>(*this); } 00131 */ 00132 public: 00133 typedef A& type; 00134 /* 00135 typedef A base_class; 00136 base_class& base() { return a; } 00137 const base_class& base() const { return a; } 00138 00139 force_impl(A& a) : a(a) { } 00140 00141 derived_type& operator=(const force_impl& b) { a = b; return *this; } 00142 00143 template <class B> 00144 derived_type& operator=(const B& b) { a = b; return derived(); } 00145 00146 template <class B> 00147 derived_type& operator+=(const B& b) { a += b; return derived(); } 00148 00149 template <class B> 00150 derived_type& operator-=(const B& b) { a -= b; return derived(); } 00151 00152 template <class B> 00153 derived_type& operator*=(const B& b) { a *= b; return derived(); } 00154 00155 template <class B> 00156 derived_type& operator/=(const B& b) { a /= b; return derived(); } 00157 00158 template <class B> 00159 derived_type& operator%=(const B& b) { a %= b; return derived(); } 00160 00161 template <class B> 00162 derived_type& operator&=(const B& b) { a &= b; return derived(); } 00163 00164 template <class B> 00165 derived_type& operator|=(const B& b) { a |= b; return derived(); } 00166 00167 template <class B> 00168 derived_type& operator^=(const B& b) { a ^= b; return derived(); } 00169 00170 template <class B> 00171 derived_type& operator<<=(const B& b) { a <<= b; return derived(); } 00172 00173 template <class B> 00174 derived_type& operator>>=(const B& b) { a >>= b; return derived(); } 00175 */ 00176 }; 00177 00178 template <class A> 00179 struct force_array_type 00180 { 00181 typedef typename types::bare_type<A>::type a_t; 00182 00183 typedef typename types::change_data_class_set<data::wrap_array 00184 <typename a_t::derived_type, data::force_wrap_array_attr>, 00185 typename types::normal_type<a_t>::type>::type arr_type; 00186 00187 typedef typename types::apply_const<arr_type, types::is_const<A> > 00188 ::type type; 00189 }; 00190 00191 template <class A> 00192 class force_impl<A, types::t_true> 00193 : 00194 public force_array_type<A>::type 00195 { 00196 public: 00197 typedef force_op<force_impl> type; 00198 00199 typedef typename force_array_type<A>::type base_class; 00200 base_class& base() { return static_cast<base_class&>(*this); } 00201 const base_class& base() const 00202 { return static_cast<const base_class&>(*this); } 00203 //base_class& base() const{ return const_cast<base_class&>(*this); } 00204 00205 force_impl() {} 00206 force_impl(A& a) : base_class(a) { } 00207 }; 00208 00209 template <class A, class B> 00210 class base_referer 00211 : 00212 public B 00213 { 00214 A r; 00215 public: 00216 base_referer(const A& a) : r(a) 00217 { 00218 this->base().init(r); 00219 } 00220 }; 00221 00222 /* 00223 template <class A> 00224 class force_wrapper 00225 : 00226 public internal::reference_face<A>, 00227 public force_impl<A, typename types::is_ivl_array<A>::type, force_wrapper<A> > 00228 { 00229 typedef internal::reference_face<A> ref_base; 00230 typedef force_impl<A, typename 00231 types::is_ivl_array<A>::type, force_wrapper<A> > 00232 base_impl; 00233 public: 00234 typedef typename ref_base::base_class base_class; 00235 base_class& base() { return static_cast<base_class&>(*this); } 00236 const base_class& base() const 00237 { return static_cast<const base_class&>(*this); } 00238 00239 force_wrapper(A& a) : ref_base(a) { } 00240 00241 using base_impl::operator=; 00242 force_wrapper& operator=(const force_wrapper& o) 00243 { 00244 base_impl::operator=(o); 00245 return *this; 00246 } 00247 }; 00248 */ 00249 /* 00250 template <class A> 00251 struct force_return 00252 { 00253 typedef typename types::bare_type<A>::type a_t; 00254 00255 types::t_if<typename types::is_ivl_array<a_t>::type, 00256 typename types::change_data_class_set<data::force 00257 <typename a_t::derived_type>, 00258 typename types::normal_type<a_t>::type>::type, 00259 force_val<A> 00260 00261 } 00262 */ 00263 } /* namespace array_details */ 00264 00265 template <class A> 00266 typename array_details::force_impl<A, typename 00267 types::is_ivl_array<A>::type>::type force(A& a) 00268 { 00269 return a; 00270 } 00271 00272 // holds the object in a new temporary array when we have a referer object. 00273 template <class X> 00274 array_details::force_op<array_details:: 00275 base_referer<X, array_details::force_impl<X, types::t_true> > > 00276 force(const data::referer<X>& x) 00277 { 00278 return x.derived(); 00279 } 00280 00281 // --------------------------------------------- 00282 00283 namespace core_details { 00284 00285 template<class IS_ARRAY> 00286 struct force_assign_tool 00287 { 00288 template<class X, class Y> 00289 static inline void assign(X& x, const Y& y) { x = y; } 00290 }; 00291 template<> 00292 struct force_assign_tool<types::t_true> 00293 { 00294 template<class X, class Y> 00295 static inline void assign(X& x, const Y& y) { x.assign(y); } 00296 }; 00297 00298 } /* namespace core_details */ 00299 00300 template <class X, class Y> 00301 void force_assign(X& x, const Y& y) 00302 { 00303 using namespace core_details; 00304 force_assign_tool<typename types::is_ivl_array<X>::type>::assign(x, y); 00305 } 00306 00307 /* 00308 template <class A> 00309 array_details::force_impl<A, typename // not <const A..> but <A..> 00310 types::is_ivl_array<A>::type> force(const A& a) 00311 { 00312 return const_cast<A&>(a); 00313 } 00314 */ 00315 } /* namespace ivl */ 00316 00317 #endif // IVL_CORE_DETAILS_SAFETY_CHECK_FORCE_HPP