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

Generated on Tue Oct 4 2011 15:24:20 for Milena (Olena) by  doxygen 1.7.1