Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE) 00002 // 00003 // This file is part of Olena. 00004 // 00005 // Olena is free software: you can redistribute it and/or modify it under 00006 // the terms of the GNU General Public License as published by the Free 00007 // Software Foundation, version 2 of the License. 00008 // 00009 // Olena is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00016 // 00017 // As a special exception, you may use this file as part of a free 00018 // software project without restriction. Specifically, if other files 00019 // instantiate templates or use macros or inline functions from this 00020 // file, or you compile this file and link it with other files to produce 00021 // an executable, this file does not by itself cause the resulting 00022 // executable to be covered by the GNU General Public License. This 00023 // exception does not however invalidate any other reasons why the 00024 // executable file might be covered by the GNU General Public License. 00025 00026 #ifndef MLN_CORE_CONCEPT_PROXY_HH 00027 # define MLN_CORE_CONCEPT_PROXY_HH 00028 00039 # include <mln/core/concept/object.hh> 00040 # include <mln/value/ops.hh> // So that we can handle builtins, scalars, and objects. 00041 00042 # include <mln/convert/from_to.hxx> 00043 # include <mln/core/concept/proxy.hxx> 00044 00045 00046 # define mln_decl_unop_proxy(Name, Symb) \ 00047 \ 00048 template <typename P> \ 00049 mln_trait_op_##Name(P) \ 00050 operator Symb (const Proxy<P>& rhs); \ 00051 \ 00052 struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n 00053 00054 00055 # define mln_def_unop_proxy(Name, Symb) \ 00056 \ 00057 template <typename P> \ 00058 inline \ 00059 mln_trait_op_##Name(P) \ 00060 operator Symb (const mln::Proxy<P>& rhs) \ 00061 { \ 00062 return Symb exact(rhs).unproxy_(); \ 00063 } \ 00064 \ 00065 struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n 00066 00067 00068 00069 00070 00071 # define mln_decl_binop_proxy(Name, Symb) \ 00072 \ 00073 template <typename L, typename R> \ 00074 mln_trait_op_##Name(L, R) \ 00075 operator Symb (const Proxy<L>& lhs, const Proxy<R>& rhs); \ 00076 \ 00077 template <typename P, typename O> \ 00078 mln_trait_op_##Name(P, O) \ 00079 operator Symb (const Proxy<P>& p, const Object<O>& o); \ 00080 \ 00081 template <typename O, typename P> \ 00082 mln_trait_op_##Name(O, P) \ 00083 operator Symb (const Object<O>& o, const Proxy<P>& p); \ 00084 \ 00085 struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n 00086 00087 00088 00089 # define mln_def_binop_proxy(Name, Symb) \ 00090 \ 00091 template <typename L, typename R> \ 00092 inline \ 00093 mln_trait_op_##Name(L, R) \ 00094 operator Symb (const mln::Proxy<L>& lhs, const mln::Proxy<R>& rhs) \ 00095 { \ 00096 typedef typename internal::helper_unprox_binop<L, R>::L_helper L_helper; \ 00097 typedef typename internal::helper_unprox_binop<L, R>::R_helper R_helper; \ 00098 return L_helper::on(lhs) Symb R_helper::on(rhs); \ 00099 } \ 00100 \ 00101 template <typename P, typename O> \ 00102 inline \ 00103 mln_trait_op_##Name(P, O) \ 00104 operator Symb (const Proxy<P>& p, const Object<O>& o) \ 00105 { \ 00106 return exact(p).unproxy_() Symb exact(o); \ 00107 } \ 00108 \ 00109 template <typename O, typename P> \ 00110 inline \ 00111 mln_trait_op_##Name(O, P) \ 00112 operator Symb (const Object<O>& o, const Proxy<P>& p) \ 00113 { \ 00114 return exact(o) Symb exact(p).unproxy_(); \ 00115 } \ 00116 \ 00117 template <typename P, typename L> \ 00118 inline \ 00119 mln_trait_op_##Name(P, L) \ 00120 operator Symb (const Proxy<P>& p, const Literal<L>& l) \ 00121 { \ 00122 return exact(p).unproxy_() Symb exact(l); \ 00123 } \ 00124 \ 00125 template <typename L, typename P> \ 00126 inline \ 00127 mln_trait_op_##Name(L, P) \ 00128 operator Symb (const Literal<L>& l, const Proxy<P>& p) \ 00129 { \ 00130 return exact(l) Symb exact(p).unproxy_(); \ 00131 } \ 00132 \ 00133 struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n 00134 00135 00136 00137 00138 namespace mln 00139 { 00140 00141 // Forward declarations. 00142 template <typename E> struct Proxy; 00143 template <typename E> struct Literal; 00144 00145 00146 namespace convert 00147 { 00148 00149 template <typename F, typename T> 00150 void from_to(const F& from, T& to); 00151 00152 } 00153 00154 00155 00156 namespace trait 00157 { 00158 00159 // Unary ops. 00160 00161 template < template <class> class Op, typename P > 00162 struct set_unary_< Op, mln::Proxy, P > 00163 { 00164 typedef mlc_unqualif(mln_q_subject(P)) S; 00165 typedef mln_trait_unary(Op, S) ret; 00166 }; 00167 00168 // Binary ops. 00169 00170 template < template <class, class> class Op, 00171 typename L, typename R > 00172 struct set_binary_< Op, mln::Proxy, L, mln::Proxy, R > 00173 { 00174 typedef mln::internal::helper_unprox_binop<L, R> helper; 00175 typedef mln_trait_binary(Op, 00176 typename helper::L_ret, 00177 typename helper::R_ret) ret; 00178 }; 00179 00180 template < template <class, class> class Op, 00181 typename P, typename O > 00182 struct set_binary_< Op, mln::Proxy, P, mln::Object, O > 00183 { 00184 typedef mlc_unqualif(mln_q_subject(P)) S; 00185 typedef mln_trait_binary(Op, S, O) ret; 00186 }; 00187 00188 template < template <class, class> class Op, 00189 typename O, typename P > 00190 struct set_binary_< Op, mln::Object, O, mln::Proxy, P > 00191 { 00192 typedef mlc_unqualif(mln_q_subject(P)) S; 00193 typedef mln_trait_binary(Op, O, S) ret; 00194 }; 00195 00196 00197 // Disambiguate between (Proxy Op Object) and (Object Op Literal). 00198 00199 template < template <class, class> class Op, 00200 typename P, typename L > 00201 struct set_binary_< Op, mln::Proxy, P, mln::Literal, L > 00202 { 00203 typedef mlc_unqualif(mln_q_subject(P)) S; 00204 typedef mln_trait_binary(Op, S, L) ret; 00205 }; 00206 00207 template < template <class, class> class Op, 00208 typename L, typename P > 00209 struct set_binary_< Op, mln::Literal, L, mln::Proxy, P > 00210 { 00211 typedef mlc_unqualif(mln_q_subject(P)) S; 00212 typedef mln_trait_binary(Op, L, S) ret; 00213 }; 00214 00215 } // end of namespace mln::trait 00216 00217 00218 00219 00221 template <> 00222 struct Proxy<void> 00223 { 00224 typedef Object<void> super; 00225 }; 00226 00227 00231 template <typename E> 00232 struct Proxy : Object<E> 00233 { 00234 typedef Proxy<void> category; 00235 00236 /* 00237 enum { proxy_level }; 00238 typedef q_subject; 00239 q_subject subj_(); 00240 */ 00241 00242 protected: 00243 Proxy(); 00244 }; 00245 00246 00247 // convert::from_to_ 00248 00249 namespace convert 00250 { 00251 00252 namespace over_load 00253 { 00254 00255 template <typename P, typename T> 00256 void 00257 from_to_(const Proxy<P>& from, T& to); 00258 00259 } // end of namespace mln::convert::over_load 00260 00261 } // end of namespace mln::convert 00262 00263 00264 00265 // subject 00266 00267 template <typename T> 00268 struct subject 00269 { 00270 typedef typename mln::internal::unproxy_rec_<T>::ret q_ret; 00271 typedef mlc_unqualif(q_ret) ret; 00272 }; 00273 00274 00275 // unproxy_rec 00276 00277 template <typename T> 00278 typename mln::internal::unproxy_rec_<T>::ret 00279 unproxy_rec(T& t); 00280 00281 template <typename T> 00282 typename mln::internal::unproxy_rec_<const T>::ret 00283 unproxy_rec(const T& t); 00284 00285 00286 // operator << 00287 00288 template <typename P> 00289 std::ostream& operator<<(std::ostream& ostr, const Proxy<P>& p); 00290 00291 00292 // operators 00293 00294 mln_decl_unop_proxy(uplus, + ); 00295 mln_decl_unop_proxy(uminus, - ); 00296 mln_decl_unop_proxy(preinc, ++ ); 00297 mln_decl_unop_proxy(predec, -- ); 00298 mln_decl_unop_proxy(not, ! ); 00299 00300 mln_decl_binop_proxy(plus, + ); 00301 mln_decl_binop_proxy(minus, - ); 00302 mln_decl_binop_proxy(times, * ); 00303 mln_decl_binop_proxy(div, / ); 00304 mln_decl_binop_proxy(mod, % ); 00305 00306 mln_decl_binop_proxy(eq, == ); 00307 mln_decl_binop_proxy(neq, != ); 00308 00309 mln_decl_binop_proxy(less, < ); 00310 mln_decl_binop_proxy(leq, <= ); 00311 mln_decl_binop_proxy(geq, >= ); 00312 mln_decl_binop_proxy(greater, > ); 00313 00314 mln_decl_binop_proxy(and, && ); 00315 mln_decl_binop_proxy(or, || ); 00316 mln_decl_binop_proxy(xor, ^ ); 00317 00318 00319 00320 # ifndef MLN_INCLUDE_ONLY 00321 00322 00323 // Proxy 00324 00325 template <typename E> 00326 inline 00327 Proxy<E>::Proxy() 00328 { 00329 enum { proxy_level = E::proxy_level }; // FIXME: Check that it is >= 0... 00330 00331 typedef typename E::q_subject q_subject; 00332 00333 q_subject (E::*m_)() = & E::subj_; 00334 m_ = 0; 00335 } 00336 00337 00338 00339 // convert::from_to_ 00340 00341 namespace convert 00342 { 00343 00344 namespace over_load 00345 { 00346 00347 template <typename P, typename T> 00348 void 00349 from_to_(const Proxy<P>& from, T& to) 00350 { 00351 convert::from_to(exact(from).unproxy_(), to); 00352 } 00353 00354 } // end of namespace mln::convert::over_load 00355 00356 } // end of namespace mln::convert 00357 00358 00359 // unproxy_rec 00360 00361 template <typename T> 00362 inline 00363 typename mln::internal::unproxy_rec_<T>::ret 00364 unproxy_rec(T& t) 00365 { 00366 return mln::internal::unproxy_rec_<T>::on(t); 00367 } 00368 00369 template <typename T> 00370 inline 00371 typename mln::internal::unproxy_rec_<const T>::ret 00372 unproxy_rec(const T& t) 00373 { 00374 return mln::internal::unproxy_rec_<const T>::on(t); 00375 } 00376 00377 00378 // operator << 00379 00380 template <typename P> 00381 inline 00382 std::ostream& operator<<(std::ostream& ostr, const Proxy<P>& p) 00383 { 00384 return ostr << unproxy_rec(p); 00385 } 00386 00387 00388 // Unary operators. 00389 00390 mln_def_unop_proxy(uplus, + ); 00391 mln_def_unop_proxy(uminus, - ); 00392 mln_def_unop_proxy(preinc, ++ ); 00393 mln_def_unop_proxy(predec, -- ); 00394 mln_def_unop_proxy(not, ! ); 00395 00396 00397 // Binary operators. 00398 00399 mln_def_binop_proxy(plus, + ); 00400 mln_def_binop_proxy(minus, - ); 00401 mln_def_binop_proxy(times, * ); 00402 mln_def_binop_proxy(div, / ); 00403 mln_def_binop_proxy(mod, % ); 00404 00405 mln_def_binop_proxy(eq, == ); 00406 mln_def_binop_proxy(neq, != ); 00407 00408 mln_def_binop_proxy(less, < ); 00409 mln_def_binop_proxy(leq, <= ); 00410 mln_def_binop_proxy(geq, >= ); 00411 mln_def_binop_proxy(greater, > ); 00412 00413 mln_def_binop_proxy(and, && ); 00414 mln_def_binop_proxy(or, || ); 00415 mln_def_binop_proxy(xor, ^ ); 00416 00417 00418 # endif // ! MLN_INCLUDE_ONLY 00419 00420 } // end of namespace mln 00421 00422 00423 #endif // ! MLN_CORE_CONCEPT_PROXY_HH