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