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 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