ivl 679
ivl/details/core/safety_check/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 A, class IS_ARRAY>
00031 class force_impl { };
00032 
00033 template <class A>
00034 class force_impl<A, types::t_false>
00035 {
00036         A& a;
00037         typedef force_impl derived_type;
00038         derived_type& derived() { return static_cast<derived_type&>(*this); }
00039 
00040 public:
00041         typedef A base_class;
00042         base_class& base() { return a; }
00043         const base_class& base() const { return a; }
00044 
00045         force_impl(A& a) : a(a) { }
00046 
00047         derived_type& operator=(const force_impl& b) { a = b; return *this; }
00048 
00049         template <class B>
00050         derived_type& operator=(const B& b) { a = b; return derived(); }
00051 
00052         template <class B>
00053         derived_type& operator+=(const B& b) { a += b; return derived(); }
00054 
00055         template <class B>
00056         derived_type& operator-=(const B& b) { a -= b; return derived(); }
00057 
00058         template <class B>
00059         derived_type& operator*=(const B& b) { a *= b; return derived(); }
00060 
00061         template <class B>
00062         derived_type& operator/=(const B& b) { a /= b; return derived(); }
00063 
00064         template <class B>
00065         derived_type& operator%=(const B& b) { a %= b; return derived(); }
00066 
00067         template <class B>
00068         derived_type& operator&=(const B& b) { a &= b; return derived(); }
00069 
00070         template <class B>
00071         derived_type& operator|=(const B& b) { a |= b; return derived(); }
00072 
00073         template <class B>
00074         derived_type& operator^=(const B& b) { a ^= b; return derived(); }
00075 
00076         template <class B>
00077         derived_type& operator<<=(const B& b) { a <<= b; return derived(); }
00078 
00079         template <class B>
00080         derived_type& operator>>=(const B& b) { a >>= b; return derived(); }
00081 };
00082 
00083 template <class A>
00084 struct force_array_type
00085 {
00086         typedef typename types::bare_type<A>::type a_t;
00087 
00088         typedef typename types::change_data_class_set<data::force
00089                                 <typename a_t::derived_type>,
00090                         typename types::normal_type<a_t>::type>::type arr_type;
00091 
00092         typedef typename types::apply_const<arr_type, types::is_const<A> >
00093                 ::type type;
00094 };
00095 
00096 template <class A>
00097 class force_impl<A, types::t_true>
00098 :
00099 public force_array_type<A>::type
00100 {
00101         typedef force_impl derived_type;
00102         derived_type& derived() { return static_cast<derived_type&>(*this); }
00103 public:
00104         typedef typename force_array_type<A>::type base_class;
00105         base_class& base() { return static_cast<base_class&>(*this); }
00106         const base_class& base() const
00107                 { return static_cast<const base_class&>(*this); }
00108 
00109         force_impl(A& a) : base_class(a) { }
00110 
00111         derived_type& operator=(const force_impl& b)
00112         {
00113                 base().assign(b.base());
00114                 return *this;
00115         }
00116 
00117         template <class B>
00118         derived_type& operator=(const B& b)
00119         {
00120                 base().assign(b);
00121                 return derived();
00122         }
00123 
00124         template <class B>
00125         derived_type& operator+=(const B& b)
00126         {
00127                 base().plus_assign(b);
00128                 return derived();
00129         }
00130 
00131         template <class B>
00132         derived_type& operator-=(const B& b)
00133         {
00134                 base().minus_assign(b);
00135                 return derived();
00136         }
00137 
00138         template <class B>
00139         derived_type& operator*=(const B& b)
00140         {
00141                 base().times_assign(b);
00142                 return derived();
00143         }
00144 
00145         template <class B>
00146         derived_type& operator/=(const B& b)
00147         {
00148                 base().divide_assign(b);
00149                 return derived();
00150         }
00151 
00152         template <class B>
00153         derived_type& operator&=(const B& b)
00154         {
00155                 base().mod_assign(b);
00156                 return derived();
00157         }
00158 
00159         template <class B>
00160         derived_type& operator|=(const B& b)
00161         {
00162                 base().bitor_assign(b);
00163                 return derived();
00164         }
00165 
00166         template <class B>
00167         derived_type& operator<<=(const B& b)
00168         {
00169                 base().bitlshift_assign(b);
00170                 return derived();
00171         }
00172 
00173         template <class B>
00174         derived_type& operator>>=(const B& b)
00175         {
00176                 base().bitrshift_assign(b);
00177                 return derived();
00178         }
00179 
00180         template <class B>
00181         derived_type& operator^=(const B& b)
00182         {
00183                 base().bitxor_assign(b);
00184                 return derived();
00185         }
00186 };
00187 /*
00188 template <class A>
00189 class force_wrapper
00190 :
00191 public internal::reference_face<A>,
00192 public force_impl<A, typename types::is_ivl_array<A>::type, force_wrapper<A> >
00193 {
00194         typedef internal::reference_face<A> ref_base;
00195         typedef force_impl<A, typename
00196                 types::is_ivl_array<A>::type, force_wrapper<A> >
00197                         base_impl;
00198 public:
00199         typedef typename ref_base::base_class 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 
00204         force_wrapper(A& a) : ref_base(a) { }
00205 
00206         using base_impl::operator=;
00207         force_wrapper& operator=(const force_wrapper& o)
00208         {
00209                 base_impl::operator=(o);
00210                 return *this;
00211         }
00212 };
00213 */
00214 /*
00215 template <class A>
00216 struct force_return
00217 {
00218         typedef typename types::bare_type<A>::type a_t;
00219 
00220         types::t_if<typename types::is_ivl_array<a_t>::type,
00221                 typename types::change_data_class_set<data::force
00222                                 <typename a_t::derived_type>,
00223                         typename types::normal_type<a_t>::type>::type,
00224                 force_val<A>
00225 
00226 }
00227 */
00228 } /* namespace array_details */
00229 
00230 template <class A>
00231 array_details::force_impl<A, typename
00232         types::is_ivl_array<A>::type> force(A& a)
00233 {
00234         return a;
00235 }
00236 
00237 template <class A>
00238 array_details::force_impl<const A, typename
00239         types::is_ivl_array<A>::type> force(const A& a)
00240 {
00241         return a;
00242 }
00243 
00244 } /* namespace ivl */
00245 
00246 #endif // IVL_CORE_DETAILS_SAFETY_CHECK_FORCE_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations