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