Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
core/concept/proxy.hh
1 // Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
2 //
3 // This file is part of Olena.
4 //
5 // Olena is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation, version 2 of the License.
8 //
9 // Olena is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free
18 // software project without restriction. Specifically, if other files
19 // instantiate templates or use macros or inline functions from this
20 // file, or you compile this file and link it with other files to produce
21 // an executable, this file does not by itself cause the resulting
22 // executable to be covered by the GNU General Public License. This
23 // exception does not however invalidate any other reasons why the
24 // executable file might be covered by the GNU General Public License.
25 
26 #ifndef MLN_CORE_CONCEPT_PROXY_HH
27 # define MLN_CORE_CONCEPT_PROXY_HH
28 
39 # include <mln/core/concept/object.hh>
40 # include <mln/value/ops.hh> // So that we can handle builtins, scalars, and objects.
41 
42 # include <mln/convert/from_to.hxx>
43 # include <mln/core/concept/proxy.hxx>
44 
45 
46 # define mln_decl_unop_proxy(Name, Symb) \
47  \
48  template <typename P> \
49  mln_trait_op_##Name(P) \
50  operator Symb (const Proxy<P>& rhs); \
51  \
52  struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
53 
54 
55 # define mln_def_unop_proxy(Name, Symb) \
56  \
57  template <typename P> \
58  inline \
59  mln_trait_op_##Name(P) \
60  operator Symb (const mln::Proxy<P>& rhs) \
61  { \
62  return Symb exact(rhs).unproxy_(); \
63  } \
64  \
65  struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
66 
67 
68 
69 
70 
71 # define mln_decl_binop_proxy(Name, Symb) \
72  \
73  template <typename L, typename R> \
74  mln_trait_op_##Name(L, R) \
75  operator Symb (const Proxy<L>& lhs, const Proxy<R>& rhs); \
76  \
77  template <typename P, typename O> \
78  mln_trait_op_##Name(P, O) \
79  operator Symb (const Proxy<P>& p, const Object<O>& o); \
80  \
81  template <typename O, typename P> \
82  mln_trait_op_##Name(O, P) \
83  operator Symb (const Object<O>& o, const Proxy<P>& p); \
84  \
85  struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
86 
87 
88 
89 # define mln_def_binop_proxy(Name, Symb) \
90  \
91  template <typename L, typename R> \
92  inline \
93  mln_trait_op_##Name(L, R) \
94  operator Symb (const mln::Proxy<L>& lhs, const mln::Proxy<R>& rhs) \
95  { \
96  typedef typename internal::helper_unprox_binop<L, R>::L_helper L_helper; \
97  typedef typename internal::helper_unprox_binop<L, R>::R_helper R_helper; \
98  return L_helper::on(lhs) Symb R_helper::on(rhs); \
99  } \
100  \
101  template <typename P, typename O> \
102  inline \
103  mln_trait_op_##Name(P, O) \
104  operator Symb (const Proxy<P>& p, const Object<O>& o) \
105  { \
106  return exact(p).unproxy_() Symb exact(o); \
107  } \
108  \
109  template <typename O, typename P> \
110  inline \
111  mln_trait_op_##Name(O, P) \
112  operator Symb (const Object<O>& o, const Proxy<P>& p) \
113  { \
114  return exact(o) Symb exact(p).unproxy_(); \
115  } \
116  \
117  template <typename P, typename L> \
118  inline \
119  mln_trait_op_##Name(P, L) \
120  operator Symb (const Proxy<P>& p, const Literal<L>& l) \
121  { \
122  return exact(p).unproxy_() Symb exact(l); \
123  } \
124  \
125  template <typename L, typename P> \
126  inline \
127  mln_trait_op_##Name(L, P) \
128  operator Symb (const Literal<L>& l, const Proxy<P>& p) \
129  { \
130  return exact(l) Symb exact(p).unproxy_(); \
131  } \
132  \
133  struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
134 
135 
136 
137 
138 namespace mln
139 {
140 
141  // Forward declarations.
142  template <typename E> struct Proxy;
143  template <typename E> struct Literal;
144 
145 
146  namespace convert
147  {
148 
149  template <typename F, typename T>
150  void from_to(const F& from, T& to);
151 
152  }
153 
154 
155 
156  namespace trait
157  {
158 
159  // Unary ops.
160 
161  template < template <class> class Op, typename P >
162  struct set_unary_< Op, mln::Proxy, P >
163  {
164  typedef mlc_unqualif(mln_q_subject(P)) S;
165  typedef mln_trait_unary(Op, S) ret;
166  };
167 
168  // Binary ops.
169 
170  template < template <class, class> class Op,
171  typename L, typename R >
172  struct set_binary_< Op, mln::Proxy, L, mln::Proxy, R >
173  {
174  typedef mln::internal::helper_unprox_binop<L, R> helper;
175  typedef mln_trait_binary(Op,
176  typename helper::L_ret,
177  typename helper::R_ret) ret;
178  };
179 
180  template < template <class, class> class Op,
181  typename P, typename O >
182  struct set_binary_< Op, mln::Proxy, P, mln::Object, O >
183  {
184  typedef mlc_unqualif(mln_q_subject(P)) S;
185  typedef mln_trait_binary(Op, S, O) ret;
186  };
187 
188  template < template <class, class> class Op,
189  typename O, typename P >
190  struct set_binary_< Op, mln::Object, O, mln::Proxy, P >
191  {
192  typedef mlc_unqualif(mln_q_subject(P)) S;
193  typedef mln_trait_binary(Op, O, S) ret;
194  };
195 
196 
197  // Disambiguate between (Proxy Op Object) and (Object Op Literal).
198 
199  template < template <class, class> class Op,
200  typename P, typename L >
201  struct set_binary_< Op, mln::Proxy, P, mln::Literal, L >
202  {
203  typedef mlc_unqualif(mln_q_subject(P)) S;
204  typedef mln_trait_binary(Op, S, L) ret;
205  };
206 
207  template < template <class, class> class Op,
208  typename L, typename P >
209  struct set_binary_< Op, mln::Literal, L, mln::Proxy, P >
210  {
211  typedef mlc_unqualif(mln_q_subject(P)) S;
212  typedef mln_trait_binary(Op, L, S) ret;
213  };
214 
215  } // end of namespace mln::trait
216 
217 
218 
219 
221  template <>
222  struct Proxy<void>
223  {
224  typedef Object<void> super;
225  };
226 
227 
231  template <typename E>
232  struct Proxy : Object<E>
233  {
234  typedef Proxy<void> category;
235 
236  /*
237  enum { proxy_level };
238  typedef q_subject;
239  q_subject subj_();
240  */
241 
242  protected:
243  Proxy();
244  };
245 
246 
247  // convert::from_to_
248 
249  namespace convert
250  {
251 
252  namespace over_load
253  {
254 
255  template <typename P, typename T>
256  void
257  from_to_(const Proxy<P>& from, T& to);
258 
259  } // end of namespace mln::convert::over_load
260 
261  } // end of namespace mln::convert
262 
263 
264 
265  // subject
266 
267  template <typename T>
268  struct subject
269  {
270  typedef typename mln::internal::unproxy_rec_<T>::ret q_ret;
271  typedef mlc_unqualif(q_ret) ret;
272  };
273 
274 
275  // unproxy_rec
276 
277  template <typename T>
278  typename mln::internal::unproxy_rec_<T>::ret
279  unproxy_rec(T& t);
280 
281  template <typename T>
282  typename mln::internal::unproxy_rec_<const T>::ret
283  unproxy_rec(const T& t);
284 
285 
286  // operator <<
287 
288  template <typename P>
289  std::ostream& operator<<(std::ostream& ostr, const Proxy<P>& p);
290 
291 
292  // operators
293 
294  mln_decl_unop_proxy(uplus, + );
295  mln_decl_unop_proxy(uminus, - );
296  mln_decl_unop_proxy(preinc, ++ );
297  mln_decl_unop_proxy(predec, -- );
298  mln_decl_unop_proxy(not, ! );
299 
300  mln_decl_binop_proxy(plus, + );
301  mln_decl_binop_proxy(minus, - );
302  mln_decl_binop_proxy(times, * );
303  mln_decl_binop_proxy(div, / );
304  mln_decl_binop_proxy(mod, % );
305 
306  mln_decl_binop_proxy(eq, == );
307  mln_decl_binop_proxy(neq, != );
308 
309  mln_decl_binop_proxy(less, < );
310  mln_decl_binop_proxy(leq, <= );
311  mln_decl_binop_proxy(geq, >= );
312  mln_decl_binop_proxy(greater, > );
313 
314  mln_decl_binop_proxy(and, && );
315  mln_decl_binop_proxy(or, || );
316  mln_decl_binop_proxy(xor, ^ );
317 
318 
319 
320 # ifndef MLN_INCLUDE_ONLY
321 
322 
323  // Proxy
324 
325  template <typename E>
326  inline
327  Proxy<E>::Proxy()
328  {
329  enum { proxy_level = E::proxy_level }; // FIXME: Check that it is >= 0...
330 
331  typedef typename E::q_subject q_subject;
332 
333  q_subject (E::*m_)() = & E::subj_;
334  m_ = 0;
335  }
336 
337 
338 
339  // convert::from_to_
340 
341  namespace convert
342  {
343 
344  namespace over_load
345  {
346 
347  template <typename P, typename T>
348  void
349  from_to_(const Proxy<P>& from, T& to)
350  {
351  convert::from_to(exact(from).unproxy_(), to);
352  }
353 
354  } // end of namespace mln::convert::over_load
355 
356  } // end of namespace mln::convert
357 
358 
359  // unproxy_rec
360 
361  template <typename T>
362  inline
363  typename mln::internal::unproxy_rec_<T>::ret
364  unproxy_rec(T& t)
365  {
366  return mln::internal::unproxy_rec_<T>::on(t);
367  }
368 
369  template <typename T>
370  inline
371  typename mln::internal::unproxy_rec_<const T>::ret
372  unproxy_rec(const T& t)
373  {
374  return mln::internal::unproxy_rec_<const T>::on(t);
375  }
376 
377 
378  // operator <<
379 
380  template <typename P>
381  inline
382  std::ostream& operator<<(std::ostream& ostr, const Proxy<P>& p)
383  {
384  return ostr << unproxy_rec(p);
385  }
386 
387 
388  // Unary operators.
389 
390  mln_def_unop_proxy(uplus, + );
391  mln_def_unop_proxy(uminus, - );
392  mln_def_unop_proxy(preinc, ++ );
393  mln_def_unop_proxy(predec, -- );
394  mln_def_unop_proxy(not, ! );
395 
396 
397  // Binary operators.
398 
399  mln_def_binop_proxy(plus, + );
400  mln_def_binop_proxy(minus, - );
401  mln_def_binop_proxy(times, * );
402  mln_def_binop_proxy(div, / );
403  mln_def_binop_proxy(mod, % );
404 
405  mln_def_binop_proxy(eq, == );
406  mln_def_binop_proxy(neq, != );
407 
408  mln_def_binop_proxy(less, < );
409  mln_def_binop_proxy(leq, <= );
410  mln_def_binop_proxy(geq, >= );
411  mln_def_binop_proxy(greater, > );
412 
413  mln_def_binop_proxy(and, && );
414  mln_def_binop_proxy(or, || );
415  mln_def_binop_proxy(xor, ^ );
416 
417 
418 # endif // ! MLN_INCLUDE_ONLY
419 
420 } // end of namespace mln
421 
422 
423 #endif // ! MLN_CORE_CONCEPT_PROXY_HH