$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
value/ops.hh
1 // Copyright (C) 2007, 2008, 2009, 2010 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_VALUE_OPS_HH
28 # define MLN_VALUE_OPS_HH
29 
33 
34 # include <mln/trait/op/all.hh>
35 # include <mln/value/builtin/all.hh>
36 # include <mln/value/concept/all.hh>
37 # include <mln/value/equiv.hh>
38 # include <mln/trait/value_.hh>
39 # include <mln/literal/zero.hh>
40 # include <mln/literal/one.hh>
41 # include <mln/literal/ops.hh>
42 # include <mln/metal/ret.hh>
43 
44 
46 # define mln_trait_value_sum_product(T, U) \
47  typename mln::trait::value_< mln_trait_op_times(T,U) >::sum
48 # define mln_trait_value_sum_product_(T, U) \
49  mln::trait::value_< mln_trait_op_times_(T,U) >::sum
50 
51 
53 # define mln_sum_product(T, U) mln_trait_value_sum_product(T, U)
54 # define mln_sum_product_(T, U) mln_trait_value_sum_product_(T, U)
55 
56 
57 // FIXME: In the definitions below, is that equiv or interop?
58 
59 
60 
61 namespace mln
62 {
63 
64  namespace trait
65  {
66 
67  // Unary traits for any Scalar type.
68 
69  template < template <class> class Name,
70  typename V >
71  struct set_unary_< Name, mln::value::Scalar, V >
72  {
73  typedef mln_trait_unary(Name, mln_value_equiv(V)) ret;
74  };
75 
76 
77  // Binary traits for any Scalar type...
78 
79  template < template <class, class> class Name,
80  typename Vl, typename Vr >
81  struct set_binary_< Name, mln::value::Scalar, Vl, mln::value::Scalar, Vr >
82  {
83  typedef mln_trait_binary(Name, mln_value_equiv(Vl), mln_value_equiv(Vr)) ret;
84  };
85 
86  // ...and for the special case of a couple of value::scalar_.
87 
88  template < template <class, class> class Name,
89  typename Sl, typename Sr >
90  struct set_binary_< Name,
91  mln::value::Scalar, mln::value::scalar_<Sl>,
92  mln::value::Scalar, mln::value::scalar_<Sr> >
93  {
94  typedef mln_trait_binary(Name, mln_value_equiv(Sl), mln_value_equiv(Sr)) ret;
95  };
96 
97 
98  template < template <class, class> class Name,
99  typename S, typename L >
100  struct set_binary_< Name,
101  mln::value::Scalar, S,
102  mln::Literal, L >
103  {
104  typedef mln_value_equiv(S) S_;
105  typedef mln_trait_binary(Name, S_, S_) ret;
106  };
107 
108  template < template <class, class> class Name,
109  typename L, typename S >
110  struct set_binary_< Name,
111  mln::Literal, L,
112  mln::value::Scalar, S >
113  {
114  typedef mln_value_equiv(S) S_;
115  typedef mln_trait_binary(Name, S_, S_) ret;
116  };
117 
118 
119  // Some binary traits for "scalar(s) OP obj" when OP commutes => "obj OP scalar(s)".
120 
121  template < typename S, typename O >
122  struct set_binary_< op::plus,
123  mln::value::Scalar, mln::value::scalar_<S>,
124  mln::Object, O >
125  {
126  typedef mln_trait_op_plus(O, mln::value::scalar_<S>) ret;
127  };
128 
129  template < typename S, typename O >
130  struct set_binary_< op::times,
131  mln::value::Scalar, mln::value::scalar_<S>,
132  mln::Object, O >
133  {
134  typedef mln_trait_op_times(O, mln::value::scalar_<S>) ret;
135  };
136 
137  } // end of namespace mln::trait
138 
139 
140  // Arithmetical binary operators.
141 
142  template <typename Vl, typename Vr>
143  mln_trait_op_plus(Vl, Vr)
144  operator + (const value::Scalar<Vl>& lhs, const value::Scalar<Vr>& rhs);
145 
146  template <typename Vl, typename Vr>
147  mln_trait_op_minus(Vl, Vr)
148  operator - (const value::Scalar<Vl>& lhs, const value::Scalar<Vr>& rhs);
149 
150  template <typename Vl, typename Vr>
151  mln_trait_op_times(Vl, Vr)
152  operator * (const value::Scalar<Vl>& lhs, const value::Scalar<Vr>& rhs);
153 
154  template <typename Vl, typename Vr>
155  mln_trait_op_div(Vl, Vr)
156  operator / (const value::Scalar<Vl>& lhs, const value::Scalar<Vr>& rhs);
157 
158  template <typename Vl, typename Vr>
159  mln_trait_op_mod(Vl, Vr)
160  operator % (const value::Scalar<Vl>& lhs, const value::Scalar<Vr>& rhs);
161 
162 
163  // Swap arguments so that "scalar_ OP Object" is "Object OP
164  // scalar_". As a consequence, the user only has to define what
165  // happens with a scalar as a rhs.
166 
167  template <typename S, typename O>
168  mln_trait_op_plus(O, value::scalar_<S>)
169  operator + (const value::scalar_<S>& lhs, const Object<O>& rhs);
170 
171  template <typename S, typename O>
172  mln_trait_op_times(O, value::scalar_<S>)
173  operator * (const value::scalar_<S>& lhs, const Object<O>& rhs);
174 
175 
176  // Arithmetical unary operators.
177 
178  template <typename S>
179  mln_trait_op_uminus(S)
180  operator - (const value::scalar_<S>& rhs); // Overload of op-(Object) in core/ops.
181  // FIXME: It is dedicated to value::scalar_ so move elsewhere?
182 
183 
184 
185  // Logical operators.
186 
187  // FIXME: ...
188 
189 
190 
191  // Case of value::scalar_ OP value::scalar_.
192 
193  template <typename Sl, typename Sr>
194  mln_trait_op_plus(Sl, Sr)
195  operator + (const value::scalar_<Sl>& lhs, const value::scalar_<Sr>& rhs);
196 
197  template <typename Sl, typename Sr>
198  mln_trait_op_minus(Sl, Sr)
199  operator - (const value::scalar_<Sl>& lhs, const value::scalar_<Sr>& rhs);
200 
201  template <typename Sl, typename Sr>
202  mln_trait_op_times(Sl, Sr)
203  operator * (const value::scalar_<Sl>& lhs, const value::scalar_<Sr>& rhs);
204 
205  template <typename Sl, typename Sr>
206  mln_trait_op_div(Sl, Sr)
207  operator / (const value::scalar_<Sl>& lhs, const value::scalar_<Sr>& rhs);
208 
209  template <typename Sl, typename Sr>
210  mln_trait_op_mod(Sl, Sr)
211  operator % (const value::scalar_<Sl>& lhs, const value::scalar_<Sr>& rhs);
212 
213 
214  // Operator ==.
215 
216  template <typename Sl, typename Sr>
217  mln_trait_op_eq(Sl, Sr)
218  operator == (const value::scalar_<Sl>& lhs, const value::scalar_<Sr>& rhs);
219 
220  bool
221  operator == (const value::scalar_<int>& lhs, const value::scalar_<unsigned>& rhs);
222 
223  bool
224  operator == (const value::scalar_<unsigned>& lhs, const value::scalar_<int>& rhs);
225 
226  template <typename O, typename L>
227  mln_trait_op_eq(O, O)
228  operator==(const value::scalar_<O>& lhs, const Literal<L>& rhs);
229 
230  template <typename L, typename O>
231  mln_trait_op_eq(O, O)
232  operator==(const Literal<L>& lhs, const value::scalar_<O>& rhs);
233 
234 
235  // Operator <.
236 
237  template <typename Sl, typename Sr>
238  mln_trait_op_less(Sl, Sr)
239  operator < (const value::scalar_<Sl>& lhs, const value::scalar_<Sr>& rhs);
240 
241  template <typename O, typename L>
242  mln_trait_op_less(O, O)
243  operator < (const value::scalar_<O>& lhs, const Literal<L>& rhs);
244 
245  template <typename L, typename O>
246  mln_trait_op_less(O, O)
247  operator < (const Literal<L>& lhs, const value::scalar_<O>& rhs);
248 
249 
250 
251 # ifndef MLN_INCLUDE_ONLY
252 
253  template <typename Vl, typename Vr>
254  inline
255  mln_trait_op_plus(Vl, Vr)
256  operator + (const value::Scalar<Vl>& lhs, const value::Scalar<Vr>& rhs)
257  {
258  typedef mln_trait_op_plus(Vl, Vr) R;
259  return static_cast<R>(value::equiv(lhs)) + static_cast<R>(value::equiv(rhs));
260  }
261 
262  template <typename Vl, typename Vr>
263  inline
264  mln_trait_op_minus(Vl, Vr)
265  operator - (const value::Scalar<Vl>& lhs, const value::Scalar<Vr>& rhs)
266  {
267  typedef mln_trait_op_minus(Vl, Vr) R;
268  return static_cast<R>(value::equiv(lhs)) - static_cast<R>(value::equiv(rhs));
269  }
270 
271  template <typename Vl, typename Vr>
272  inline
273  mln_trait_op_times(Vl, Vr)
274  operator * (const value::Scalar<Vl>& lhs, const value::Scalar<Vr>& rhs)
275  {
276  typedef mln_trait_op_times(Vl, Vr) R;
277  return static_cast<R>(value::equiv(lhs)) * static_cast<R>(value::equiv(rhs));
278  }
279 
280  template <typename Vl, typename Vr>
281  inline
282  mln_trait_op_div(Vl, Vr)
283  operator / (const value::Scalar<Vl>& lhs, const value::Scalar<Vr>& rhs)
284  {
285  typedef mln_trait_op_div(Vl, Vr) R;
286  return static_cast<R>(value::equiv(lhs)) / static_cast<R>(value::equiv(rhs));
287  }
288 
289  template <typename Vl, typename Vr>
290  inline
291  mln_trait_op_mod(Vl, Vr)
292  operator % (const value::Scalar<Vl>& lhs, const value::Scalar<Vr>& rhs)
293  {
294  return value::equiv(lhs) % value::equiv(rhs);
295  }
296 
297  template <typename S>
298  inline
299  mln_trait_op_uminus(S)
300  operator - (const value::scalar_<S>& rhs)
301  {
302  typedef mln_trait_op_uminus(S) R;
303  return static_cast<R>(- rhs.to_equiv());
304  }
305 
306  template <typename S, typename O>
307  inline
308  mln_trait_op_plus(O, value::scalar_<S>)
309  operator + (const value::scalar_<S>& lhs, const Object<O>& rhs)
310  {
311  return exact(rhs) + lhs;
312  }
313 
314  template <typename S, typename O>
315  inline
316  mln_trait_op_times(O, value::scalar_<S>)
317  operator * (const value::scalar_<S>& lhs, const Object<O>& rhs)
318  {
319  return exact(rhs) * lhs;
320  }
321 
322  // ...
323 
324 
325  // With scalar_ OP scalar_.
326 
327  template <typename Sl, typename Sr>
328  inline
329  mln_trait_op_plus(Sl, Sr)
330  operator + (const value::scalar_<Sl>& lhs, const value::scalar_<Sr>& rhs)
331  {
332  return value::equiv(lhs) + value::equiv(rhs);
333  }
334 
335  template <typename Sl, typename Sr>
336  inline
337  mln_trait_op_minus(Sl, Sr)
338  operator - (const value::scalar_<Sl>& lhs, const value::scalar_<Sr>& rhs)
339  {
340  return value::equiv(lhs) - value::equiv(rhs);
341  }
342 
343  template <typename Sl, typename Sr>
344  inline
345  mln_trait_op_times(Sl, Sr)
346  operator * (const value::scalar_<Sl>& lhs, const value::scalar_<Sr>& rhs)
347  {
348  return value::equiv(lhs) * value::equiv(rhs);
349  }
350 
351  template <typename Sl, typename Sr>
352  inline
353  mln_trait_op_div(Sl, Sr)
354  operator / (const value::scalar_<Sl>& lhs, const value::scalar_<Sr>& rhs)
355  {
356  return value::equiv(lhs) / value::equiv(rhs);
357  }
358 
359  template <typename Sl, typename Sr>
360  inline
361  mln_trait_op_mod(Sl, Sr)
362  operator % (const value::scalar_<Sl>& lhs, const value::scalar_<Sr>& rhs)
363  {
364  return value::equiv(lhs) % value::equiv(rhs);
365  }
366 
367 
368  // Operator ==.
369 
370  template <typename Sl, typename Sr>
371  inline
372  mln_trait_op_eq(Sl, Sr)
373  operator == (const value::scalar_<Sl>& lhs, const value::scalar_<Sr>& rhs)
374  {
375  return value::equiv(lhs) == value::equiv(rhs);
376  }
377 
378  inline
379  bool
380  operator == (const value::scalar_<int>& lhs, const value::scalar_<unsigned>& rhs)
381  {
382  return lhs.to_equiv() == int(rhs.to_equiv());
383  }
384 
385  inline
386  bool
387  operator == (const value::scalar_<unsigned>& lhs, const value::scalar_<int>& rhs)
388  {
389  return int(lhs.to_equiv()) == rhs.to_equiv();
390  }
391 
392  template <typename O, typename L>
393  inline
394  mln_trait_op_eq(O, O)
395  operator==(const value::scalar_<O>& lhs, const Literal<L>& rhs)
396  {
397  return exact(lhs) == mln_value_equiv(O)(exact(rhs));
398  }
399 
400  template <typename L, typename O>
401  inline
402  mln_trait_op_eq(O, O)
403  operator==(const Literal<L>& lhs, const value::scalar_<O>& rhs)
404  {
405  return mln_value_equiv(O)(exact(lhs)) == exact(rhs);
406  }
407 
408 
409  // Operator <.
410 
411  template <typename Sl, typename Sr>
412  inline
413  mln_trait_op_less(Sl, Sr)
414  operator < (const value::scalar_<Sl>& lhs, const value::scalar_<Sr>& rhs)
415  {
416  return value::equiv(lhs) < value::equiv(rhs);
417  }
418 
419  template <typename O, typename L>
420  inline
421  mln_trait_op_less(O, O)
422  operator < (const value::scalar_<O>& lhs, const Literal<L>& rhs)
423  {
424  return exact(lhs) < mln_value_equiv(O)(exact(rhs));
425  }
426 
427  template <typename L, typename O>
428  inline
429  mln_trait_op_less(O, O)
430  operator < (const Literal<L>& lhs, const value::scalar_<O>& rhs)
431  {
432  return mln_value_equiv(O)(exact(lhs)) < exact(rhs);
433  }
434 
435 # endif // ! MLN_INCLUDE_ONLY
436 
437 } // end of namespace mln
438 
439 
440 #endif // ! MLN_VALUE_OPS_HH