• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

proxy.hh

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   struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
00118 
00119 
00120 
00121 
00122 namespace mln
00123 {
00124 
00125   // Forward declarations.
00126   template <typename E> struct Proxy;
00127 
00128   namespace convert
00129   {
00130 
00131     template <typename F, typename T>
00132     void from_to(const F& from, T& to);
00133 
00134   }
00135 
00136 
00137 
00138   namespace trait
00139   {
00140 
00141     // Unary ops.
00142 
00143     template < template <class> class Op, typename P >
00144     struct set_unary_< Op, mln::Proxy, P >
00145     {
00146       typedef mlc_unqualif(mln_q_subject(P)) S;
00147       typedef mln_trait_unary(Op, S) ret;
00148     };
00149 
00150     // Binary ops.
00151 
00152     template < template <class, class> class Op,
00153                typename L, typename R >
00154     struct set_binary_< Op, mln::Proxy, L, mln::Proxy, R >
00155     {
00156       typedef mln::internal::helper_unprox_binop<L, R> helper;
00157       typedef mln_trait_binary(Op,
00158                                typename helper::L_ret,
00159                                typename helper::R_ret) ret;
00160     };
00161 
00162     template < template <class, class> class Op,
00163                typename P, typename O >
00164     struct set_binary_< Op, mln::Proxy, P, mln::Object, O >
00165     {
00166       typedef mlc_unqualif(mln_q_subject(P)) S;
00167       typedef mln_trait_binary(Op, S, O) ret;
00168     };
00169 
00170     template < template <class, class> class Op,
00171                typename O, typename P >
00172     struct set_binary_< Op, mln::Object, O, mln::Proxy, P  >
00173     {
00174       typedef mlc_unqualif(mln_q_subject(P)) S;
00175       typedef mln_trait_binary(Op, O, S) ret;
00176     };
00177 
00178   } // end of namespace mln::trait
00179 
00180 
00181 
00182 
00184   template <>
00185   struct Proxy<void>
00186   {
00187     typedef Object<void> super;
00188   };
00189 
00190 
00194   template <typename E>
00195   struct Proxy : Object<E>
00196   {
00197     typedef Proxy<void> category;
00198 
00199     /*
00200       enum { proxy_level };
00201       typedef q_subject;
00202       q_subject subj_();
00203     */
00204     
00205   protected:
00206     Proxy();
00207   };
00208 
00209 
00210   // convert::from_to_
00211 
00212   namespace convert
00213   {
00214 
00215     namespace over_load
00216     {
00217 
00218       template <typename P, typename T>
00219       void
00220       from_to_(const Proxy<P>& from, T& to);
00221 
00222     } // end of namespace mln::convert::over_load
00223 
00224   } // end of namespace mln::convert
00225 
00226 
00227 
00228   // subject
00229 
00230   template <typename T>
00231   struct subject
00232   {
00233     typedef typename mln::internal::unproxy_rec_<T>::ret q_ret;
00234     typedef mlc_unqualif(q_ret) ret;
00235   };
00236 
00237 
00238   // unproxy_rec
00239 
00240   template <typename T>
00241   typename mln::internal::unproxy_rec_<T>::ret
00242   unproxy_rec(T& t);
00243 
00244   template <typename T>
00245   typename mln::internal::unproxy_rec_<const T>::ret
00246   unproxy_rec(const T& t);
00247  
00248 
00249   // operator <<
00250 
00251   template <typename P>
00252   std::ostream& operator<<(std::ostream& ostr, const Proxy<P>& p);
00253 
00254 
00255   // operators
00256 
00257   mln_decl_unop_proxy(uplus,  + );
00258   mln_decl_unop_proxy(uminus, - );
00259   mln_decl_unop_proxy(preinc, ++ );
00260   mln_decl_unop_proxy(predec, -- );
00261   mln_decl_unop_proxy(not,    ! );
00262 
00263   mln_decl_binop_proxy(plus,  + );
00264   mln_decl_binop_proxy(minus, - );
00265   mln_decl_binop_proxy(times, * );
00266   mln_decl_binop_proxy(div,   / );
00267   mln_decl_binop_proxy(mod,   % );
00268 
00269   mln_decl_binop_proxy(eq,  == );
00270   mln_decl_binop_proxy(neq, != );
00271 
00272   mln_decl_binop_proxy(less,    <  );
00273   mln_decl_binop_proxy(leq,     <= );
00274   mln_decl_binop_proxy(geq,     >= );
00275   mln_decl_binop_proxy(greater, >  );
00276 
00277   mln_decl_binop_proxy(and, && );
00278   mln_decl_binop_proxy(or,  || );
00279   mln_decl_binop_proxy(xor, ^  );
00280 
00281 
00282 
00283 # ifndef MLN_INCLUDE_ONLY
00284 
00285 
00286   // Proxy
00287 
00288   template <typename E>
00289   inline
00290   Proxy<E>::Proxy()
00291   {
00292     enum { proxy_level = E::proxy_level }; // FIXME: Check that it is >= 0...
00293 
00294     typedef typename E::q_subject q_subject;
00295 
00296     q_subject (E::*m_)() = & E::subj_;
00297     m_ = 0;
00298   }
00299 
00300 
00301 
00302   // convert::from_to_
00303 
00304   namespace convert
00305   {
00306 
00307     namespace over_load
00308     {
00309 
00310       template <typename P, typename T>
00311       void
00312       from_to_(const Proxy<P>& from, T& to)
00313       {
00314         convert::from_to(exact(from).unproxy_(), to);
00315       }
00316 
00317     } // end of namespace mln::convert::over_load
00318 
00319   } // end of namespace mln::convert
00320 
00321 
00322   // unproxy_rec
00323 
00324   template <typename T>
00325   inline
00326   typename mln::internal::unproxy_rec_<T>::ret
00327   unproxy_rec(T& t)
00328   {
00329     return mln::internal::unproxy_rec_<T>::on(t);
00330   }
00331 
00332   template <typename T>
00333   inline
00334   typename mln::internal::unproxy_rec_<const T>::ret
00335   unproxy_rec(const T& t)
00336   {
00337     return mln::internal::unproxy_rec_<const T>::on(t);
00338   }
00339 
00340 
00341   // operator <<
00342 
00343   template <typename P>
00344   inline
00345   std::ostream& operator<<(std::ostream& ostr, const Proxy<P>& p)
00346   {
00347     return ostr << unproxy_rec(p);
00348   }
00349 
00350 
00351   // Unary operators.
00352 
00353   mln_def_unop_proxy(uplus,  + );
00354   mln_def_unop_proxy(uminus, - );
00355   mln_def_unop_proxy(preinc, ++ );
00356   mln_def_unop_proxy(predec, -- );
00357   mln_def_unop_proxy(not,    ! );
00358 
00359 
00360   // Binary operators.
00361 
00362   mln_def_binop_proxy(plus,  + );
00363   mln_def_binop_proxy(minus, - );
00364   mln_def_binop_proxy(times, * );
00365   mln_def_binop_proxy(div,   / );
00366   mln_def_binop_proxy(mod,   % );
00367 
00368   mln_def_binop_proxy(eq,  == );
00369   mln_def_binop_proxy(neq, != );
00370 
00371   mln_def_binop_proxy(less,    <  );
00372   mln_def_binop_proxy(leq,     <= );
00373   mln_def_binop_proxy(geq,     >= );
00374   mln_def_binop_proxy(greater, >  );
00375 
00376   mln_def_binop_proxy(and, && );
00377   mln_def_binop_proxy(or,  || );
00378   mln_def_binop_proxy(xor, ^  );
00379 
00380 
00381 # endif // ! MLN_INCLUDE_ONLY
00382 
00383 } // end of namespace mln
00384 
00385 
00386 #endif // ! MLN_CORE_CONCEPT_PROXY_HH

Generated on Thu Sep 8 2011 18:32:21 for Milena (Olena) by  doxygen 1.7.1