$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
core/routine/ops.hh
1 // Copyright (C) 2007, 2008, 2009, 2012 EPITA Research and Development
2 // 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_ROUTINE_OPS_HH
28 # define MLN_CORE_ROUTINE_OPS_HH
29 
33 
92 # include <mln/trait/op/all.hh>
93 # include <mln/core/concept/object.hh>
94 # include <mln/metal/converts_to.hh>
95 
96 
97 namespace mln
98 {
99 
100  // Fwd decls.
101  namespace literal { struct zero_t; struct one_t; }
102 
103 
104  namespace trait
105  {
106 
107  // For unary operators.
108 
109 
114  template <typename O>
115  struct set_unary_< op::uplus, Object,O > { typedef O ret; };
116 
121  template <typename O>
122  struct set_unary_< op::uminus, Object,O > { typedef mln_trait_op_minus(O, O) ret; };
123 
128  template <typename O>
129  struct set_unary_< op::preinc, Object,O > { typedef O& ret; };
130 
135  template <typename O>
136  struct set_unary_< op::predec, Object,O > { typedef O& ret; };
137 
142  template <typename O>
143  struct set_unary_< op::postinc, Object,O > { typedef O ret; };
144 
149  template <typename O>
150  struct set_unary_< op::postdec, Object,O > { typedef O ret; };
151 
152 
153 
154  // For binary operators.
155 
156  template <typename O1, typename O2>
157  struct set_binary_< op::eq, Object,O1, Object,O2 > { typedef bool ret; };
158 
159  template <typename O1, typename O2>
160  struct set_binary_< op::neq, Object,O1, Object,O2 >
161  {
162  // O1 != O2 --> ! (O1 == O2)
163  typedef mln_trait_op_eq(O1, O2) B_;
164  typedef mln_trait_op_not(B_) ret;
165  };
166 
167  template <typename O1, typename O2>
168  struct set_binary_< op::less, Object,O1, Object,O2 > { typedef bool ret; };
169 
170  template <typename O1, typename O2>
171  struct set_binary_< op::leq, Object,O1, Object,O2 >
172  {
173  // O1 <= O2 --> ! (O2 < 01)
174  typedef mln_trait_op_less(O2, O1) B_;
175  typedef mln_trait_op_not(B_) ret;
176  };
177 
178  template <typename O1, typename O2>
179  struct set_binary_< op::geq, Object,O1, Object,O2 >
180  {
181  // O1 >= O2 --> O2 <= O1
182  typedef mln_trait_op_leq(O2, O1) ret;
183  };
184 
185  template <typename O1, typename O2>
186  struct set_binary_< op::greater, Object,O1, Object,O2 >
187  {
188  // O1 > O2 --> O2 < O1
189  typedef mln_trait_op_less(O2, O1) ret;
190  };
191 
192  // FIXME: Same for the other definitions below...
193 
194 
195 
196  // Case of "const" in types.
197 
198  template< template <class> class Name,
199  typename O >
200  struct set_precise_unary_< Name, const O >
201  {
202  typedef mln_trait_unary(Name, O) ret;
203  };
204 
205  template< template <class,class> class Name,
206  typename O1, typename O2 >
207  struct set_precise_binary_< Name, O1, const O2 >
208  {
209  typedef mln_trait_binary(Name, O1, O2) ret;
210  };
211 
212  template< template <class,class> class Name,
213  typename O1, typename O2 >
214  struct set_precise_binary_< Name, const O1, O2 >
215  {
216  typedef mln_trait_binary(Name, O1, O2) ret;
217  };
218 
219  template< template <class,class> class Name,
220  typename O1, typename O2 >
221  struct set_precise_binary_< Name, const O1, const O2 >
222  {
223  typedef mln_trait_binary(Name, O1, O2) ret;
224  };
225 
226 
227  } // end of mln::trait
228 
229 
230 
240  template <typename O1, typename O2>
241  mln_trait_op_neq(O1, O2)
242  operator!=(const Object<O1>& lhs, const Object<O2>& rhs);
243 
244 
254  template <typename O1, typename O2>
255  mln_trait_op_greater(O1, O2)
256  operator>(const Object<O1>& lhs, const Object<O2>& rhs);
257 
258 
269  template <typename O1, typename O2>
270  mln_trait_op_geq(O1, O2)
271  operator>=(const Object<O1>& lhs, const Object<O2>& rhs);
272 
273 
284  template <typename O1, typename O2>
285  mln_trait_op_leq(O1, O2)
286  operator<=(const Object<O1>& lhs, const Object<O2>& rhs);
287 
288 
289  /* \brief Default definition of the post-incrementation operator.
290  *
291  * It relies on the definition of the pre-incrementation operator.
292  */
293  template <typename O>
294  O operator++(Object<O>& lhs, int);
295 
296 
297  /* \brief Default definition of the post-decrementation operator.
298  *
299  * It relies on the definition of the pre-decrementation operator.
300  */
301  template <typename O>
302  O operator--(Object<O>& lhs, int);
303 
304 
305  /* \brief Default definition of the pre-incrementation operator.
306  *
307  * It relies on "+ literal::one".
308  */
309  template <typename O>
310  O& operator++(Object<O>& rhs);
311 
312 
313  /* \brief Default definition of the pre-decrementation operator.
314  *
315  * It relies on "- literal::one".
316  */
317  template <typename O>
318  O& operator--(Object<O>& rhs);
319 
320 
321  /* \brief Default definitions of the "unary plus" operator.
322  *
323  * \param[in] rhs An object
324  * \return A copy of \p rhs.
325  */
326  template <typename O>
327  O operator+(const Object<O>& rhs);
328 
329 
330  /* \brief Default definition of the "unary minus" operator.
331  *
332  * \param[in] rhs An object
333  * \return 0 - \p rhs.
334  *
335  * It relies on "O(literal::zero) - rhs".
336  */
337  template <typename O>
338  mln_trait_op_minus(O, O)
339  operator-(const Object<O>& rhs);
340 
341 
342  /* \brief Default definition of the "plus equal" operator.
343  *
344  * \param[in,out] lhs The target object.
345  * \param[in] rhs The auxiliary object.
346  * \return The target object \p lhs once modified.
347  *
348  * It relies on "lhs = L(lhs) + rhs".
349  */
350  template <typename L, typename R>
351  L&
352  operator+=(Object<L>& lhs, const Object<R>& rhs);
353 
354 
355  /* \brief Default definition of the "minus equal" operator.
356  *
357  * \param[in,out] lhs The target object.
358  * \param[in] rhs The auxiliary object.
359  * \return The target object \p lhs once modified.
360  *
361  * It relies on "lhs = L(lhs) - rhs".
362  */
363  template <typename L, typename R>
364  L&
365  operator-=(Object<L>& lhs, const Object<R>& rhs);
366 
367 
368  /* \brief Default definition of the "times equal" operator.
369  *
370  * \param[in,out] lhs The target object.
371  * \param[in] rhs The auxiliary object.
372  * \return The target object \p lhs once modified.
373  *
374  * It relies on "lhs = L(lhs) * rhs".
375  */
376  template <typename L, typename R>
377  L&
378  operator*=(Object<L>& lhs, const Object<R>& rhs);
379 
380 
381  /* \brief Default definition of the "div equal" operator.
382  *
383  * \param[in,out] lhs The target object.
384  * \param[in] rhs The auxiliary object.
385  * \return The target object \p lhs once modified.
386  *
387  * It relies on "lhs = L(lhs) / rhs".
388  */
389  template <typename L, typename R>
390  L&
391  operator/=(Object<L>& lhs, const Object<R>& rhs);
392 
393 
394  /* \brief Default definition of the "mod equal" operator.
395  *
396  * \param[in,out] lhs The target object.
397  * \param[in] rhs The auxiliary object.
398  * \return The target object \p lhs once modified.
399  *
400  * It relies on "lhs = L(lhs) % rhs".
401  */
402  template <typename L, typename R>
403  L&
404  operator%=(Object<L>& lhs, const Object<R>& rhs);
405 
406 
407 
408 # ifndef MLN_INCLUDE_ONLY
409 
410  // Plus equal.
411 
412  template <typename L, typename R>
413  inline
414  L&
415  operator+=(Object<L>& lhs, const Object<R>& rhs)
416  {
417  typedef mln_trait_op_plus(L, R) P;
418  mlc_converts_to(P, L)::check();
419  return exact(lhs) = static_cast<L>(exact(lhs) + exact(rhs));
420  }
421 
422  // Minus equal.
423 
424  template <typename L, typename R>
425  inline
426  L&
427  operator-=(Object<L>& lhs, const Object<R>& rhs)
428  {
429  typedef mln_trait_op_minus(L, R) M;
430  mlc_converts_to(M, L)::check();
431  return exact(lhs) = static_cast<L>(exact(lhs) - exact(rhs));
432  }
433 
434  // Times equal.
435 
436  template <typename L, typename R>
437  inline
438  L&
439  operator*=(Object<L>& lhs, const Object<R>& rhs)
440  {
441  typedef mln_trait_op_times(L, R) T;
442  mlc_converts_to(T, L)::check();
443  return exact(lhs) = static_cast<L>(exact(lhs) * exact(rhs));
444  }
445 
446  // Div equal.
447 
448  template <typename L, typename R>
449  inline
450  L&
451  operator/=(Object<L>& lhs, const Object<R>& rhs)
452  {
453  typedef mln_trait_op_div(L, R) D;
454  mlc_converts_to(D, L)::check();
455  // Remark:
456  // The code below gives a warning with g++-3.3 with the test file
457  // tests/value/int_u8.cc. It is normal since writing "i /= f"
458  // means casting eventually float to int. Yet what do we want in
459  // that case? A quiet compilation or a warning?
460  return exact(lhs) = static_cast<L>(exact(lhs) / exact(rhs));
461  }
462 
463  // Mod equal.
464 
465  template <typename L, typename R>
466  inline
467  L&
468  operator%=(Object<L>& lhs, const Object<R>& rhs)
469  {
470  typedef mln_trait_op_mod(L, R) M;
471  mlc_converts_to(M, L)::check();
472  return exact(lhs) = static_cast<L>(exact(lhs) % exact(rhs));
473  }
474 
475  // Unary plus.
476 
477  template <typename O>
478  inline
479  O
480  operator+(const Object<O>& rhs)
481  {
482  return exact(rhs); // Cpy.
483  }
484 
485  // Unary minus.
486 
487  template <typename O>
488  inline
489  mln_trait_op_minus(O, O)
490  operator-(const Object<O>& rhs)
491  {
492  mlc_converts_to(literal::zero_t, O)::check();
493  literal::zero_t* p_zero = 0;
494  return O(*p_zero) - exact(rhs);
495  }
496 
497  // Post-incrementation.
498 
499  template <typename O>
500  inline
501  O
502  operator++(Object<O>& lhs, int)
503  {
504  O tmp(exact(lhs)); // Copy.
505  ++exact(lhs); // Pre-inc.
506  // FIXME: Activate: mln_postcondition(exact(lhs) == tmp + literal::one);
507  return tmp;
508  }
509 
510  // Post-decrementation.
511 
512  template <typename O>
513  inline
514  O
515  operator--(Object<O>& lhs, int)
516  {
517  O tmp(exact(lhs)); // Copy.
518  --exact(lhs); // Pre-dec.
519  // FIXME: Activate: mln_postcondition(exact(lhs) == tmp - literal::one);
520  return tmp;
521  }
522 
523  // Pre-decrementation.
524 
525  template <typename O>
526  inline
527  O&
528  operator--(Object<O>& rhs)
529  {
530  literal::one_t* p_one;
531  exact(rhs) -= *p_one;
532  return exact(rhs);
533  }
534 
535  // Pre-incrementation.
536 
537  template <typename O>
538  inline
539  O&
540  operator++(Object<O>& rhs)
541  {
542  literal::one_t* p_one;
543  exact(rhs) += *p_one;
544  return exact(rhs);
545  }
546 
547  // Comparisons.
548 
549  template <typename O1, typename O2>
550  inline
551  mln_trait_op_neq(O1, O2)
552  operator!=(const Object<O1>& lhs, const Object<O2>& rhs)
553  {
554  return ! (exact(lhs) == exact(rhs));
555  }
556 
557  template <typename O1, typename O2>
558  inline
559  mln_trait_op_greater(O1, O2)
560  operator>(const Object<O1>& lhs, const Object<O2>& rhs)
561  {
562  return exact(rhs) < exact(lhs);
563  }
564 
565  template <typename O1, typename O2>
566  inline
567  mln_trait_op_geq(O1, O2)
568  operator>=(const Object<O1>& lhs, const Object<O2>& rhs)
569  {
570  return exact(rhs) <= exact(lhs);
571  }
572 
573  template <typename O1, typename O2>
574  inline
575  mln_trait_op_leq(O1, O2)
576  operator<=(const Object<O1>& lhs, const Object<O2>& rhs)
577  {
578  // if partial ordering, this operator should be re-defined!
579  return ! (exact(rhs) < exact(lhs));
580  }
581 
582 # endif // ! MLN_INCLUDE_ONLY
583 
584 } // end of namespace mln
585 
586 
587 #endif // ! MLN_CORE_ROUTINE_OPS_HH