ivl 679
ivl/details/core/keyword_operators/force.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_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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations