$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
value/builtin/ops.hh
1 // Copyright (C) 2007, 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_VALUE_BUILTIN_OPS_HH
27 # define MLN_VALUE_BUILTIN_OPS_HH
28 
33 
34 # include <mln/value/scalar.hh>
35 # include <mln/trait/op/all.hh>
36 # include <mln/value/builtin/promotions.hh>
37 
38 
39 // The call "built-in (op) Object" inverts the couple of arguments; so
40 // it results in the effective call: "Object (op) built-in." In the
41 // definitions of objects, we do not have to handle the possible calls
42 // "built-in (op) Object". Furthermore, the built-in value is wrapped
43 // into a value::scalar_ (which is a value::Scalar); as a consequence,
44 // the definition of an object should only handle the single case
45 // "Object (op) Scalar".
46 //
47 // For instance:
48 // an expression such as " int * Image<I> "
49 // is transformed into " I * scalar_<int> "
50 // with the corresponding return type.
51 
52 
53 
54 // Operators "object OP built-in" => "object OP scalar".
55 // and "object OP= built-in" => "object OP= scalar".
56 
57 # define mln_internal_decl_op_obj_bi_(Symb, Name, Builtin) \
58  \
59  template <typename O> \
60  mln_trait_op_##Name (O, value::scalar_< Builtin >) \
61  operator Symb (const Object<O>& lhs, const Builtin & rhs); \
62  \
63  template <typename O> \
64  O& \
65  operator Symb##= (Object<O>& lhs, const Builtin & rhs); \
66  \
67  struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
68 
69 
70 # define mln_internal_def_op_obj_bi_(Symb, Name, Builtin) \
71  \
72  template <typename O> \
73  mln_trait_op_##Name (O, value::scalar_< Builtin >) \
74  operator Symb (const Object<O>& lhs, const Builtin & rhs) \
75  { \
76  return exact(lhs) Symb value::scalar(rhs); \
77  } \
78  \
79  template <typename O> \
80  O& \
81  operator Symb##= (Object<O>& lhs, const Builtin & rhs) \
82  { \
83  return exact(lhs) Symb##= value::scalar(rhs); \
84  } \
85  \
86  struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
87 
88 
89 // Operator "built-in OP object" => "object OP scalar" iff OP commutes.
90 
91 # define mln_internal_decl_bi_op_obj_(Symb, Name, Builtin) \
92  \
93  template <typename O> \
94  mln_trait_op_##Name (O, value::scalar_< Builtin >) \
95  operator Symb (const Builtin & lhs, const Object<O>& rhs); \
96  \
97  struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
98 
99 # define mln_internal_def_bi_op_obj_(Symb, Name, Builtin) \
100  \
101  template <typename O> \
102  mln_trait_op_##Name (O, value::scalar_< Builtin >) \
103  operator Symb (const Builtin & lhs, const Object<O>& rhs) \
104  { \
105  return exact(rhs) Symb value::scalar(lhs); \
106  } \
107  \
108  struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
109 
110 
111 
112 // Comparison.
113 
114 # define mln_internal_decl_op_cmp_(Symb, Name, Builtin) \
115  \
116  template <typename O> \
117  mln_trait_op_##Name (O, value::scalar_< Builtin >) \
118  operator Symb (const Object<O>& lhs, const Builtin & rhs); \
119  \
120  template <typename O> \
121  mln_trait_op_##Name (O, value::scalar_< Builtin >) \
122  operator Symb (const Builtin & lhs, const Object<O>& rhs); \
123  \
124  struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
125 
126 # define mln_internal_def_op_cmp_(Symb, Name, Builtin) \
127  \
128  template <typename O> \
129  mln_trait_op_##Name (O, value::scalar_< Builtin >) \
130  operator Symb (const Object<O>& lhs, const Builtin & rhs) \
131  { \
132  return exact(lhs) Symb value::scalar(rhs); \
133  } \
134  \
135  template <typename O> \
136  mln_trait_op_##Name (O, value::scalar_< Builtin >) \
137  operator Symb (const Builtin & lhs, const Object<O>& rhs) \
138  { \
139  return exact(rhs) Symb value::scalar(lhs); \
140  } \
141  \
142  struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
143 
144 
145 
146 
147 
148 
149 
150 # define mln_internal_op_obj_builtins_(De, Symb, Name) \
151  \
152  mln_internal_##De##_op_obj_bi_(Symb, Name, signed char); \
153  mln_internal_##De##_op_obj_bi_(Symb, Name, unsigned char); \
154  mln_internal_##De##_op_obj_bi_(Symb, Name, signed short); \
155  mln_internal_##De##_op_obj_bi_(Symb, Name, unsigned short); \
156  mln_internal_##De##_op_obj_bi_(Symb, Name, signed int); \
157  mln_internal_##De##_op_obj_bi_(Symb, Name, unsigned int); \
158  mln_internal_##De##_op_obj_bi_(Symb, Name, signed long); \
159  mln_internal_##De##_op_obj_bi_(Symb, Name, unsigned long); \
160  mln_internal_##De##_op_obj_bi_(Symb, Name, float); \
161  mln_internal_##De##_op_obj_bi_(Symb, Name, double); \
162  \
163  struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
164 
165 
166 # define mln_internal_builtins_op_obj_(De, Symb, Name) \
167  \
168  mln_internal_##De##_bi_op_obj_(Symb, Name, signed char); \
169  mln_internal_##De##_bi_op_obj_(Symb, Name, unsigned char); \
170  mln_internal_##De##_bi_op_obj_(Symb, Name, signed short); \
171  mln_internal_##De##_bi_op_obj_(Symb, Name, unsigned short); \
172  mln_internal_##De##_bi_op_obj_(Symb, Name, signed int); \
173  mln_internal_##De##_bi_op_obj_(Symb, Name, unsigned int); \
174  mln_internal_##De##_bi_op_obj_(Symb, Name, signed long); \
175  mln_internal_##De##_bi_op_obj_(Symb, Name, unsigned long); \
176  mln_internal_##De##_bi_op_obj_(Symb, Name, float); \
177  mln_internal_##De##_bi_op_obj_(Symb, Name, double); \
178  \
179  struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
180 
181 
182 
183 
184 // Operator "Builtin minus Object" is a special case.
185 
186 # define mln_internal_decl_bi_minus_obj_(Builtin) \
187  \
188  template <typename O> \
189  mln_trait_op_minus(Builtin, O) \
190  operator - (const Builtin & lhs, const Object<O>& rhs); \
191  \
192  struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
193 
194 # define mln_internal_def_bi_minus_obj_(Builtin) \
195  \
196  template <typename O> \
197  mln_trait_op_minus(Builtin, O) \
198  operator - (const Builtin & lhs, const Object<O>& rhs) \
199  { \
200  return (- exact(rhs)) + value::scalar(lhs); \
201  } \
202  \
203  struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
204 
205 
206 # define mln_internal_builtins_minus_obj_(De) \
207  \
208  mln_internal_##De##_bi_minus_obj_( signed char); \
209  mln_internal_##De##_bi_minus_obj_(unsigned char); \
210  mln_internal_##De##_bi_minus_obj_( signed short); \
211  mln_internal_##De##_bi_minus_obj_(unsigned short); \
212  mln_internal_##De##_bi_minus_obj_( signed int); \
213  mln_internal_##De##_bi_minus_obj_(unsigned int); \
214  mln_internal_##De##_bi_minus_obj_( signed long); \
215  mln_internal_##De##_bi_minus_obj_(unsigned long); \
216  mln_internal_##De##_bi_minus_obj_(float); \
217  mln_internal_##De##_bi_minus_obj_(double); \
218  \
219  struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
220 
221 
222 
223 
224 // Operator "Builtin 'div or mod' Object" is a special case.
225 
226 # define mln_internal_decl_bi_dvmd_obj_(Symb, Name, Builtin) \
227  \
228  template <typename O> \
229  mln_trait_op_##Name (value::scalar_< Builtin >, O) \
230  operator Symb (const Builtin & lhs, const Object<O>& rhs); \
231  \
232  struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
233 
234 # define mln_internal_def_bi_dvmd_obj_(Symb, Name, Builtin) \
235  \
236  template <typename O> \
237  mln_trait_op_##Name (value::scalar_< Builtin >, O) \
238  operator Symb (const Builtin & lhs, const Object<O>& rhs) \
239  { \
240  return value::scalar(lhs) Symb exact(rhs); \
241  } \
242  \
243  struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
244 
245 
246 # define mln_internal_builtins_dvmd_obj_(De, Symb, Name) \
247  \
248  mln_internal_##De##_bi_dvmd_obj_(Symb, Name, signed char); \
249  mln_internal_##De##_bi_dvmd_obj_(Symb, Name, unsigned char); \
250  mln_internal_##De##_bi_dvmd_obj_(Symb, Name, signed short); \
251  mln_internal_##De##_bi_dvmd_obj_(Symb, Name, unsigned short); \
252  mln_internal_##De##_bi_dvmd_obj_(Symb, Name, signed int); \
253  mln_internal_##De##_bi_dvmd_obj_(Symb, Name, unsigned int); \
254  mln_internal_##De##_bi_dvmd_obj_(Symb, Name, signed long); \
255  mln_internal_##De##_bi_dvmd_obj_(Symb, Name, unsigned long); \
256  mln_internal_##De##_bi_dvmd_obj_(Symb, Name, float); \
257  mln_internal_##De##_bi_dvmd_obj_(Symb, Name, double); \
258  \
259  struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
260 
261 # define mln_internal_op_builtins_cmp_(De, Symb, Name) \
262  \
263  mln_internal_##De##_op_cmp_(Symb, Name, signed char); \
264  mln_internal_##De##_op_cmp_(Symb, Name, unsigned char); \
265  mln_internal_##De##_op_cmp_(Symb, Name, signed short); \
266  mln_internal_##De##_op_cmp_(Symb, Name, unsigned short); \
267  mln_internal_##De##_op_cmp_(Symb, Name, signed int); \
268  mln_internal_##De##_op_cmp_(Symb, Name, unsigned int); \
269  mln_internal_##De##_op_cmp_(Symb, Name, signed long); \
270  mln_internal_##De##_op_cmp_(Symb, Name, unsigned long); \
271  mln_internal_##De##_op_cmp_(Symb, Name, float); \
272  mln_internal_##De##_op_cmp_(Symb, Name, double); \
273  \
274  struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
275 
276 
277 
278 // Operator "Builtin Op= Object" is a special case.
279 
280 
281 # define mln_internal_decl_bi_opeq_obj_(Symb, Builtin) \
282  \
283  template <typename O> \
284  Builtin & \
285  operator Symb##= (Builtin & lhs, const Object<O>& rhs); \
286  \
287  struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
288 
289 # define mln_internal_def_bi_opeq_obj_(Symb, Builtin) \
290  \
291  template <typename O> \
292  Builtin & \
293  operator Symb##= (Builtin & lhs, const Object<O>& rhs) \
294  { \
295  lhs Symb##= exact(rhs).to_equiv(); \
296  return lhs; \
297  } \
298  \
299  struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
300 
301 # define mln_internal_builtins_opeq_obj_(De, Symb) \
302  \
303  mln_internal_##De##_bi_opeq_obj_(Symb, signed char); \
304  mln_internal_##De##_bi_opeq_obj_(Symb, unsigned char); \
305  mln_internal_##De##_bi_opeq_obj_(Symb, signed short); \
306  mln_internal_##De##_bi_opeq_obj_(Symb, unsigned short); \
307  mln_internal_##De##_bi_opeq_obj_(Symb, signed int); \
308  mln_internal_##De##_bi_opeq_obj_(Symb, unsigned int); \
309  mln_internal_##De##_bi_opeq_obj_(Symb, signed long); \
310  mln_internal_##De##_bi_opeq_obj_(Symb, unsigned long); \
311  mln_internal_##De##_bi_opeq_obj_(Symb, float); \
312  mln_internal_##De##_bi_opeq_obj_(Symb, double); \
313  \
314  struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
315 
316 
317 
318 
319 // Operator less (<) is a special case.
320 
321 # define mln_internal_decl_op_less_(Symb, Name, Builtin) \
322  \
323  template <typename O> \
324  mln_trait_op_##Name (O, value::scalar_< Builtin >) \
325  operator Symb (const Object<O>& lhs, const Builtin & rhs); \
326  \
327  template <typename O> \
328  mln_trait_op_##Name (value::scalar_< Builtin >, O) \
329  operator Symb (const Builtin & lhs, const Object<O>& rhs); \
330  \
331  struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
332 
333 # define mln_internal_def_op_less_(Symb, Name, Builtin) \
334  \
335  template <typename O> \
336  mln_trait_op_##Name (O, value::scalar_< Builtin >) \
337  operator Symb (const Object<O>& lhs, const Builtin & rhs) \
338  { \
339  return exact(lhs) Symb value::scalar(rhs); \
340  } \
341  \
342  template <typename O> \
343  mln_trait_op_##Name (value::scalar_< Builtin >, O) \
344  operator Symb (const Builtin & lhs, const Object<O>& rhs) \
345  { \
346  return value::scalar(lhs) Symb exact(rhs); \
347  } \
348  \
349  struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
350 
351 # define mln_internal_builtins_op_less_(De, Symb, Name) \
352  \
353  mln_internal_##De##_op_less_(Symb, Name, signed char); \
354  mln_internal_##De##_op_less_(Symb, Name, unsigned char); \
355  mln_internal_##De##_op_less_(Symb, Name, signed short); \
356  mln_internal_##De##_op_less_(Symb, Name, unsigned short); \
357  mln_internal_##De##_op_less_(Symb, Name, signed int); \
358  mln_internal_##De##_op_less_(Symb, Name, unsigned int); \
359  mln_internal_##De##_op_less_(Symb, Name, signed long); \
360  mln_internal_##De##_op_less_(Symb, Name, unsigned long); \
361  mln_internal_##De##_op_less_(Symb, Name, float); \
362  mln_internal_##De##_op_less_(Symb, Name, double); \
363  \
364  struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
365 
366 
367 // FIXME: What about pointers, arrays, bool, etc.
368 
369 // FIXME: Mod is not defined for float and double...
370 
371 
372 
373 
374 
375 
376 # define mln_internal_set_builtin_trait_is_promotion_(Name) \
377  \
378  template <typename Bl, typename Br> \
379  struct set_binary_< Name, mln::value::Built_In, Bl, mln::value::Built_In, Br > \
380  { \
381  typedef mln_trait_promote(Bl, Br) ret; \
382  }; \
383  \
384  struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
385 
386 
387 # define mln_internal_set_builtin_trait_is_bool_(Name) \
388  \
389  template <typename Bl, typename Br> \
390  struct set_binary_< Name, mln::value::Built_In, Bl, mln::value::Built_In, Br > \
391  { \
392  typedef bool ret; \
393  }; \
394  \
395  struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n
396 
397 
398 
399 namespace mln
400 {
401 
402  namespace trait
403  {
404 
405  // Unary traits.
406 
407  template< typename B >
408  struct set_unary_< op::uplus,
409  mln::value::Built_In, B >
410  {
411  typedef B ret;
412  };
413 
414  template<>
415  struct set_precise_unary_< op::not_, bool >
416  {
417  typedef bool ret;
418  };
419 
420  template<> struct set_precise_unary_< op::uminus, signed char > { typedef signed char ret; };
421  template<> struct set_precise_unary_< op::uminus, unsigned char > { typedef int ret; };
422  template<> struct set_precise_unary_< op::uminus, signed short > { typedef signed short ret; };
423  template<> struct set_precise_unary_< op::uminus, unsigned short > { typedef int ret; };
424  template<> struct set_precise_unary_< op::uminus, signed int > { typedef signed int ret; };
425 
426  template<> struct set_precise_unary_< op::uminus, unsigned int > { typedef signed int ret; };
427  template<> struct set_precise_unary_< op::uminus, signed long > { typedef signed long ret; };
428  template<> struct set_precise_unary_< op::uminus, unsigned long > { typedef signed long ret; };
429 
430  template<> struct set_precise_unary_< op::uminus, bool > {};
431 
432  template<> struct set_precise_unary_< op::uminus, float > { typedef float ret; };
433  template<> struct set_precise_unary_< op::uminus, double > { typedef double ret; };
434 
435 
436  // FIXME: Is that all?
437 
438 
439  // A couple of builtins => promotion...
440 
441  mln_internal_set_builtin_trait_is_promotion_(op::plus);
442  mln_internal_set_builtin_trait_is_promotion_(op::times);
443  mln_internal_set_builtin_trait_is_promotion_(op::div);
444  mln_internal_set_builtin_trait_is_promotion_(op::mod);
445 
446  // mln_internal_set_builtin_trait_is_promotion_(op::minus);
447 
448  template <typename Bl, typename Br>
449  struct set_binary_< op::minus,
450  mln::value::Built_In, Bl, mln::value::Built_In, Br >
451  {
452  typedef mln_trait_op_uminus(Br) minus_Br;
453  typedef mln_trait_promote(Bl, minus_Br) ret;
454  };
455 
456  // For comparisons (such as "less-than"), we get bool.
457 
458  mln_internal_set_builtin_trait_is_bool_(op::eq);
459  mln_internal_set_builtin_trait_is_bool_(op::neq);
460 
461  mln_internal_set_builtin_trait_is_bool_(op::less);
462  mln_internal_set_builtin_trait_is_bool_(op::leq);
463  mln_internal_set_builtin_trait_is_bool_(op::geq);
464  mln_internal_set_builtin_trait_is_bool_(op::greater);
465 
466  mln_internal_set_builtin_trait_is_bool_(op::and_);
467  mln_internal_set_builtin_trait_is_bool_(op::or_);
468  mln_internal_set_builtin_trait_is_bool_(op::xor_);
469 
470  // FIXME: We want to disable some ops; for instance "bool + int" and "int and int"...
471 
472 
473 
474 
475  // FIXME: What about +=, etc.
476 
477 
478 
479 
480  // Operators "Object OP Built_In" => "Object OP scalar_"
481 
482  template <typename O, typename B>
483  struct set_binary_< op::plus, mln::Object, O, mln::value::Built_In, B >
484  {
485  typedef mln_trait_op_plus(O, mln::value::scalar_<B>) ret;
486  };
487 
488  template <typename O, typename B>
489  struct set_binary_< op::minus, mln::Object, O, mln::value::Built_In, B >
490  {
491  typedef mln_trait_op_minus(O, mln::value::scalar_<B>) ret;
492  };
493 
494  template <typename O, typename B>
495  struct set_binary_< op::times, mln::Object, O, mln::value::Built_In, B >
496  {
497  typedef mln_trait_op_times(O, mln::value::scalar_<B>) ret;
498  };
499 
500  template <typename O, typename B>
501  struct set_binary_< op::div, mln::Object, O, mln::value::Built_In, B >
502  {
503  typedef mln_trait_op_div(O, mln::value::scalar_<B>) ret;
504  };
505 
506  template <typename O, typename B>
507  struct set_binary_< op::mod, mln::Object, O, mln::value::Built_In, B >
508  {
509  typedef mln_trait_op_mod(O, mln::value::scalar_<B>) ret;
510  };
511 
512  template <typename O, typename B>
513  struct set_binary_< op::less, mln::Object, O, mln::value::Built_In, B >
514  {
515  typedef mln_trait_op_less(O, mln::value::scalar_<B>) ret;
516  };
517 
518  template <typename B, typename O>
519  struct set_binary_< op::less, mln::value::Built_In, B, mln::Object, O >
520  {
521  typedef mln_trait_op_less(mln::value::scalar_<B>, O) ret;
522  };
523 
524 
525  // 'Op+' is commutative so "o + b" => "o + scalar(b)".
526 
527  template <typename B, typename O>
528  struct set_binary_< op::plus, mln::value::Built_In, B, mln::Object, O >
529  {
530  typedef mln_trait_op_plus(O, mln::value::scalar_<B>) ret;
531  };
532 
533  // Likewise for 'Op*'.
534 
535  template <typename B, typename O>
536  struct set_binary_< op::times, mln::value::Built_In, B, mln::Object, O >
537  {
538  typedef mln_trait_op_times(O, mln::value::scalar_<B>) ret;
539  };
540 
541 
542  // 'Op-' is tricky for "b - o" => "(-o) + scalar(b)".
543 
544  template <typename B, typename O>
545  struct set_binary_< op::minus, mln::value::Built_In, B, mln::Object, O >
546  {
547  typedef mln_trait_op_uminus(O) minus_O;
548  typedef mln_trait_op_plus(minus_O, mln::value::scalar_<B>) ret;
549  };
550 
551 
552  // 'Op/' for "b / o" => "scalar(b) / o".
553 
554  template <typename B, typename O>
555  struct set_binary_< op::div, mln::value::Built_In, B, mln::Object, O >
556  {
557  typedef mln_trait_op_div(mln::value::scalar_<B>, O) ret;
558  };
559 
560  // Likewise for 'Op%'.
561 
562  template <typename B, typename O>
563  struct set_binary_< op::mod, mln::value::Built_In, B, mln::Object, O >
564  {
565  typedef mln_trait_op_mod(mln::value::scalar_<B>, O) ret;
566  };
567 
568  } // end of namespace mln::trait
569 
570 
571  mln_internal_op_obj_builtins_(decl, +, plus);
572  mln_internal_op_obj_builtins_(decl, -, minus);
573  mln_internal_op_obj_builtins_(decl, *, times);
574  mln_internal_op_obj_builtins_(decl, /, div);
575  mln_internal_op_obj_builtins_(decl, %, mod);
576 
577  // Op+ and op* respectively commute:
578  mln_internal_builtins_op_obj_(decl, +, plus);
579  mln_internal_builtins_op_obj_(decl, *, times);
580 
581  // Op "builtin - object" is special:
582  mln_internal_builtins_minus_obj_(decl);
583 
584 
585  // Ops "bi / obj" and "bi % obj"
586  mln_internal_builtins_dvmd_obj_(decl, /, div);
587  mln_internal_builtins_dvmd_obj_(decl, %, mod);
588 
589 
590  // Ops "bi CMP obj" and "bi CMP obj"
591  mln_internal_op_builtins_cmp_(decl, ==, eq);
592  mln_internal_op_builtins_cmp_(decl, !=, neq);
593  // FIXME: ...
594 
595 
596  // Ops "bi Op= obj"
597  mln_internal_builtins_opeq_obj_(decl, +);
598  mln_internal_builtins_opeq_obj_(decl, -);
599  mln_internal_builtins_opeq_obj_(decl, *);
600  mln_internal_builtins_opeq_obj_(decl, /);
601  mln_internal_builtins_opeq_obj_(decl, %);
602 
603 
604  // Ops "bi < obj" and "obj < bi"
605  mln_internal_builtins_op_less_(decl, <, less);
606 
607 
608 
609 # ifndef MLN_INCLUDE_ONLY
610 
611  mln_internal_op_obj_builtins_(def, +, plus);
612  mln_internal_op_obj_builtins_(def, -, minus);
613  mln_internal_op_obj_builtins_(def, *, times);
614  mln_internal_op_obj_builtins_(def, /, div);
615  mln_internal_op_obj_builtins_(def, %, mod);
616 
617  // Op+ and op* respectively commute:
618  mln_internal_builtins_op_obj_(def, +, plus);
619  mln_internal_builtins_op_obj_(def, *, times);
620 
621  // Op "builtin - object" is special:
622  mln_internal_builtins_minus_obj_(def);
623 
624  // Ops "bi / obj" and "bi % obj"
625  mln_internal_builtins_dvmd_obj_(def, /, div);
626  mln_internal_builtins_dvmd_obj_(def, %, mod);
627 
628  // Ops "bi CMP obj" and "bi CMP obj"
629  mln_internal_op_builtins_cmp_(def, ==, eq);
630  mln_internal_op_builtins_cmp_(def, !=, neq);
631 
632  // FIXME: Add less, etc.
633 
634 
635  // Ops "bi Op= obj"
636  mln_internal_builtins_opeq_obj_(def, +);
637  mln_internal_builtins_opeq_obj_(def, -);
638  mln_internal_builtins_opeq_obj_(def, *);
639  mln_internal_builtins_opeq_obj_(def, /);
640  mln_internal_builtins_opeq_obj_(def, %);
641 
642 
643  // Ops "bi < obj" and "obj < bi"
644  mln_internal_builtins_op_less_(def, <, less);
645 
646 
647 # endif // ! MLN_INCLUDE_ONLY
648 
649 } // end of namespace mln
650 
651 
652 #endif // ! MLN_VALUE_BUILTIN_OPS_HH