Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE) 00002 // 00003 // This file is part of Olena. 00004 // 00005 // Olena is free software: you can redistribute it and/or modify it under 00006 // the terms of the GNU General Public License as published by the Free 00007 // Software Foundation, version 2 of the License. 00008 // 00009 // Olena is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00016 // 00017 // As a special exception, you may use this file as part of a free 00018 // software project without restriction. Specifically, if other files 00019 // instantiate templates or use macros or inline functions from this 00020 // file, or you compile this file and link it with other files to produce 00021 // an executable, this file does not by itself cause the resulting 00022 // executable to be covered by the GNU General Public License. This 00023 // exception does not however invalidate any other reasons why the 00024 // executable file might be covered by the GNU General Public License. 00025 00026 #ifndef MLN_VALUE_BUILTIN_OPS_HH 00027 # define MLN_VALUE_BUILTIN_OPS_HH 00028 00033 00034 # include <mln/value/scalar.hh> 00035 # include <mln/trait/op/all.hh> 00036 # include <mln/value/builtin/promotions.hh> 00037 00038 00039 // The call "built-in (op) Object" inverts the couple of arguments; so 00040 // it results in the effective call: "Object (op) built-in." In the 00041 // definitions of objects, we do not have to handle the possible calls 00042 // "built-in (op) Object". Furthermore, the built-in value is wrapped 00043 // into a value::scalar_ (which is a value::Scalar); as a consequence, 00044 // the definition of an object should only handle the single case 00045 // "Object (op) Scalar". 00046 // 00047 // For instance: 00048 // an expression such as " int * Image<I> " 00049 // is transformed into " I * scalar_<int> " 00050 // with the corresponding return type. 00051 00052 00053 00054 // Operators "object OP built-in" => "object OP scalar". 00055 // and "object OP= built-in" => "object OP= scalar". 00056 00057 # define mln_internal_decl_op_obj_bi_(Symb, Name, Builtin) \ 00058 \ 00059 template <typename O> \ 00060 mln_trait_op_##Name (O, value::scalar_< Builtin >) \ 00061 operator Symb (const Object<O>& lhs, const Builtin & rhs); \ 00062 \ 00063 template <typename O> \ 00064 O& \ 00065 operator Symb##= (Object<O>& lhs, const Builtin & rhs); \ 00066 \ 00067 struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n 00068 00069 00070 # define mln_internal_def_op_obj_bi_(Symb, Name, Builtin) \ 00071 \ 00072 template <typename O> \ 00073 mln_trait_op_##Name (O, value::scalar_< Builtin >) \ 00074 operator Symb (const Object<O>& lhs, const Builtin & rhs) \ 00075 { \ 00076 return exact(lhs) Symb value::scalar(rhs); \ 00077 } \ 00078 \ 00079 template <typename O> \ 00080 O& \ 00081 operator Symb##= (Object<O>& lhs, const Builtin & rhs) \ 00082 { \ 00083 return exact(lhs) Symb##= value::scalar(rhs); \ 00084 } \ 00085 \ 00086 struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n 00087 00088 00089 // Operator "built-in OP object" => "object OP scalar" iff OP commutes. 00090 00091 # define mln_internal_decl_bi_op_obj_(Symb, Name, Builtin) \ 00092 \ 00093 template <typename O> \ 00094 mln_trait_op_##Name (O, value::scalar_< Builtin >) \ 00095 operator Symb (const Builtin & lhs, const Object<O>& rhs); \ 00096 \ 00097 struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n 00098 00099 # define mln_internal_def_bi_op_obj_(Symb, Name, Builtin) \ 00100 \ 00101 template <typename O> \ 00102 mln_trait_op_##Name (O, value::scalar_< Builtin >) \ 00103 operator Symb (const Builtin & lhs, const Object<O>& rhs) \ 00104 { \ 00105 return exact(rhs) Symb value::scalar(lhs); \ 00106 } \ 00107 \ 00108 struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n 00109 00110 00111 00112 // Comparison. 00113 00114 # define mln_internal_decl_op_cmp_(Symb, Name, Builtin) \ 00115 \ 00116 template <typename O> \ 00117 mln_trait_op_##Name (O, value::scalar_< Builtin >) \ 00118 operator Symb (const Object<O>& lhs, const Builtin & rhs); \ 00119 \ 00120 template <typename O> \ 00121 mln_trait_op_##Name (O, value::scalar_< Builtin >) \ 00122 operator Symb (const Builtin & lhs, const Object<O>& rhs); \ 00123 \ 00124 struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n 00125 00126 # define mln_internal_def_op_cmp_(Symb, Name, Builtin) \ 00127 \ 00128 template <typename O> \ 00129 mln_trait_op_##Name (O, value::scalar_< Builtin >) \ 00130 operator Symb (const Object<O>& lhs, const Builtin & rhs) \ 00131 { \ 00132 return exact(lhs) Symb value::scalar(rhs); \ 00133 } \ 00134 \ 00135 template <typename O> \ 00136 mln_trait_op_##Name (O, value::scalar_< Builtin >) \ 00137 operator Symb (const Builtin & lhs, const Object<O>& rhs) \ 00138 { \ 00139 return exact(rhs) Symb value::scalar(lhs); \ 00140 } \ 00141 \ 00142 struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n 00143 00144 00145 00146 00147 00148 00149 00150 # define mln_internal_op_obj_builtins_(De, Symb, Name) \ 00151 \ 00152 mln_internal_##De##_op_obj_bi_(Symb, Name, signed char); \ 00153 mln_internal_##De##_op_obj_bi_(Symb, Name, unsigned char); \ 00154 mln_internal_##De##_op_obj_bi_(Symb, Name, signed short); \ 00155 mln_internal_##De##_op_obj_bi_(Symb, Name, unsigned short); \ 00156 mln_internal_##De##_op_obj_bi_(Symb, Name, signed int); \ 00157 mln_internal_##De##_op_obj_bi_(Symb, Name, unsigned int); \ 00158 mln_internal_##De##_op_obj_bi_(Symb, Name, signed long); \ 00159 mln_internal_##De##_op_obj_bi_(Symb, Name, unsigned long); \ 00160 mln_internal_##De##_op_obj_bi_(Symb, Name, float); \ 00161 mln_internal_##De##_op_obj_bi_(Symb, Name, double); \ 00162 \ 00163 struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n 00164 00165 00166 # define mln_internal_builtins_op_obj_(De, Symb, Name) \ 00167 \ 00168 mln_internal_##De##_bi_op_obj_(Symb, Name, signed char); \ 00169 mln_internal_##De##_bi_op_obj_(Symb, Name, unsigned char); \ 00170 mln_internal_##De##_bi_op_obj_(Symb, Name, signed short); \ 00171 mln_internal_##De##_bi_op_obj_(Symb, Name, unsigned short); \ 00172 mln_internal_##De##_bi_op_obj_(Symb, Name, signed int); \ 00173 mln_internal_##De##_bi_op_obj_(Symb, Name, unsigned int); \ 00174 mln_internal_##De##_bi_op_obj_(Symb, Name, signed long); \ 00175 mln_internal_##De##_bi_op_obj_(Symb, Name, unsigned long); \ 00176 mln_internal_##De##_bi_op_obj_(Symb, Name, float); \ 00177 mln_internal_##De##_bi_op_obj_(Symb, Name, double); \ 00178 \ 00179 struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n 00180 00181 00182 00183 00184 // Operator "Builtin minus Object" is a special case. 00185 00186 # define mln_internal_decl_bi_minus_obj_(Builtin) \ 00187 \ 00188 template <typename O> \ 00189 mln_trait_op_minus(Builtin, O) \ 00190 operator - (const Builtin & lhs, const Object<O>& rhs); \ 00191 \ 00192 struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n 00193 00194 # define mln_internal_def_bi_minus_obj_(Builtin) \ 00195 \ 00196 template <typename O> \ 00197 mln_trait_op_minus(Builtin, O) \ 00198 operator - (const Builtin & lhs, const Object<O>& rhs) \ 00199 { \ 00200 return (- exact(rhs)) + value::scalar(lhs); \ 00201 } \ 00202 \ 00203 struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n 00204 00205 00206 # define mln_internal_builtins_minus_obj_(De) \ 00207 \ 00208 mln_internal_##De##_bi_minus_obj_( signed char); \ 00209 mln_internal_##De##_bi_minus_obj_(unsigned char); \ 00210 mln_internal_##De##_bi_minus_obj_( signed short); \ 00211 mln_internal_##De##_bi_minus_obj_(unsigned short); \ 00212 mln_internal_##De##_bi_minus_obj_( signed int); \ 00213 mln_internal_##De##_bi_minus_obj_(unsigned int); \ 00214 mln_internal_##De##_bi_minus_obj_( signed long); \ 00215 mln_internal_##De##_bi_minus_obj_(unsigned long); \ 00216 mln_internal_##De##_bi_minus_obj_(float); \ 00217 mln_internal_##De##_bi_minus_obj_(double); \ 00218 \ 00219 struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n 00220 00221 00222 00223 00224 // Operator "Builtin 'div or mod' Object" is a special case. 00225 00226 # define mln_internal_decl_bi_dvmd_obj_(Symb, Name, Builtin) \ 00227 \ 00228 template <typename O> \ 00229 mln_trait_op_##Name (value::scalar_< Builtin >, O) \ 00230 operator Symb (const Builtin & lhs, const Object<O>& rhs); \ 00231 \ 00232 struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n 00233 00234 # define mln_internal_def_bi_dvmd_obj_(Symb, Name, Builtin) \ 00235 \ 00236 template <typename O> \ 00237 mln_trait_op_##Name (value::scalar_< Builtin >, O) \ 00238 operator Symb (const Builtin & lhs, const Object<O>& rhs) \ 00239 { \ 00240 return value::scalar(lhs) Symb exact(rhs); \ 00241 } \ 00242 \ 00243 struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n 00244 00245 00246 # define mln_internal_builtins_dvmd_obj_(De, Symb, Name) \ 00247 \ 00248 mln_internal_##De##_bi_dvmd_obj_(Symb, Name, signed char); \ 00249 mln_internal_##De##_bi_dvmd_obj_(Symb, Name, unsigned char); \ 00250 mln_internal_##De##_bi_dvmd_obj_(Symb, Name, signed short); \ 00251 mln_internal_##De##_bi_dvmd_obj_(Symb, Name, unsigned short); \ 00252 mln_internal_##De##_bi_dvmd_obj_(Symb, Name, signed int); \ 00253 mln_internal_##De##_bi_dvmd_obj_(Symb, Name, unsigned int); \ 00254 mln_internal_##De##_bi_dvmd_obj_(Symb, Name, signed long); \ 00255 mln_internal_##De##_bi_dvmd_obj_(Symb, Name, unsigned long); \ 00256 mln_internal_##De##_bi_dvmd_obj_(Symb, Name, float); \ 00257 mln_internal_##De##_bi_dvmd_obj_(Symb, Name, double); \ 00258 \ 00259 struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n 00260 00261 # define mln_internal_op_builtins_cmp_(De, Symb, Name) \ 00262 \ 00263 mln_internal_##De##_op_cmp_(Symb, Name, signed char); \ 00264 mln_internal_##De##_op_cmp_(Symb, Name, unsigned char); \ 00265 mln_internal_##De##_op_cmp_(Symb, Name, signed short); \ 00266 mln_internal_##De##_op_cmp_(Symb, Name, unsigned short); \ 00267 mln_internal_##De##_op_cmp_(Symb, Name, signed int); \ 00268 mln_internal_##De##_op_cmp_(Symb, Name, unsigned int); \ 00269 mln_internal_##De##_op_cmp_(Symb, Name, signed long); \ 00270 mln_internal_##De##_op_cmp_(Symb, Name, unsigned long); \ 00271 mln_internal_##De##_op_cmp_(Symb, Name, float); \ 00272 mln_internal_##De##_op_cmp_(Symb, Name, double); \ 00273 \ 00274 struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n 00275 00276 00277 00278 // Operator "Builtin Op= Object" is a special case. 00279 00280 00281 # define mln_internal_decl_bi_opeq_obj_(Symb, Builtin) \ 00282 \ 00283 template <typename O> \ 00284 Builtin & \ 00285 operator Symb##= (Builtin & lhs, const Object<O>& rhs); \ 00286 \ 00287 struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n 00288 00289 # define mln_internal_def_bi_opeq_obj_(Symb, Builtin) \ 00290 \ 00291 template <typename O> \ 00292 Builtin & \ 00293 operator Symb##= (Builtin & lhs, const Object<O>& rhs) \ 00294 { \ 00295 lhs Symb##= exact(rhs).to_equiv(); \ 00296 return lhs; \ 00297 } \ 00298 \ 00299 struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n 00300 00301 # define mln_internal_builtins_opeq_obj_(De, Symb) \ 00302 \ 00303 mln_internal_##De##_bi_opeq_obj_(Symb, signed char); \ 00304 mln_internal_##De##_bi_opeq_obj_(Symb, unsigned char); \ 00305 mln_internal_##De##_bi_opeq_obj_(Symb, signed short); \ 00306 mln_internal_##De##_bi_opeq_obj_(Symb, unsigned short); \ 00307 mln_internal_##De##_bi_opeq_obj_(Symb, signed int); \ 00308 mln_internal_##De##_bi_opeq_obj_(Symb, unsigned int); \ 00309 mln_internal_##De##_bi_opeq_obj_(Symb, signed long); \ 00310 mln_internal_##De##_bi_opeq_obj_(Symb, unsigned long); \ 00311 mln_internal_##De##_bi_opeq_obj_(Symb, float); \ 00312 mln_internal_##De##_bi_opeq_obj_(Symb, double); \ 00313 \ 00314 struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n 00315 00316 00317 00318 00319 // Operator less (<) is a special case. 00320 00321 # define mln_internal_decl_op_less_(Symb, Name, Builtin) \ 00322 \ 00323 template <typename O> \ 00324 mln_trait_op_##Name (O, value::scalar_< Builtin >) \ 00325 operator Symb (const Object<O>& lhs, const Builtin & rhs); \ 00326 \ 00327 template <typename O> \ 00328 mln_trait_op_##Name (value::scalar_< Builtin >, O) \ 00329 operator Symb (const Builtin & lhs, const Object<O>& rhs); \ 00330 \ 00331 struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n 00332 00333 # define mln_internal_def_op_less_(Symb, Name, Builtin) \ 00334 \ 00335 template <typename O> \ 00336 mln_trait_op_##Name (O, value::scalar_< Builtin >) \ 00337 operator Symb (const Object<O>& lhs, const Builtin & rhs) \ 00338 { \ 00339 return exact(lhs) Symb value::scalar(rhs); \ 00340 } \ 00341 \ 00342 template <typename O> \ 00343 mln_trait_op_##Name (value::scalar_< Builtin >, O) \ 00344 operator Symb (const Builtin & lhs, const Object<O>& rhs) \ 00345 { \ 00346 return value::scalar(lhs) Symb exact(rhs); \ 00347 } \ 00348 \ 00349 struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n 00350 00351 # define mln_internal_builtins_op_less_(De, Symb, Name) \ 00352 \ 00353 mln_internal_##De##_op_less_(Symb, Name, signed char); \ 00354 mln_internal_##De##_op_less_(Symb, Name, unsigned char); \ 00355 mln_internal_##De##_op_less_(Symb, Name, signed short); \ 00356 mln_internal_##De##_op_less_(Symb, Name, unsigned short); \ 00357 mln_internal_##De##_op_less_(Symb, Name, signed int); \ 00358 mln_internal_##De##_op_less_(Symb, Name, unsigned int); \ 00359 mln_internal_##De##_op_less_(Symb, Name, signed long); \ 00360 mln_internal_##De##_op_less_(Symb, Name, unsigned long); \ 00361 mln_internal_##De##_op_less_(Symb, Name, float); \ 00362 mln_internal_##De##_op_less_(Symb, Name, double); \ 00363 \ 00364 struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n 00365 00366 00367 // FIXME: What about pointers, arrays, bool, etc. 00368 00369 // FIXME: Mod is not defined for float and double... 00370 00371 00372 00373 00374 00375 00376 # define mln_internal_set_builtin_trait_is_promotion_(Name) \ 00377 \ 00378 template <typename Bl, typename Br> \ 00379 struct set_binary_< Name, mln::value::Built_In, Bl, mln::value::Built_In, Br > \ 00380 { \ 00381 typedef mln_trait_promote(Bl, Br) ret; \ 00382 }; \ 00383 \ 00384 struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n 00385 00386 00387 # define mln_internal_set_builtin_trait_is_bool_(Name) \ 00388 \ 00389 template <typename Bl, typename Br> \ 00390 struct set_binary_< Name, mln::value::Built_In, Bl, mln::value::Built_In, Br > \ 00391 { \ 00392 typedef bool ret; \ 00393 }; \ 00394 \ 00395 struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n 00396 00397 00398 00399 namespace mln 00400 { 00401 00402 namespace trait 00403 { 00404 00405 // Unary traits. 00406 00407 template< typename B > 00408 struct set_unary_< op::uplus, 00409 mln::value::Built_In, B > 00410 { 00411 typedef B ret; 00412 }; 00413 00414 template<> 00415 struct set_precise_unary_< op::not_, bool > 00416 { 00417 typedef bool ret; 00418 }; 00419 00420 template<> struct set_precise_unary_< op::uminus, signed char > { typedef signed char ret; }; 00421 template<> struct set_precise_unary_< op::uminus, unsigned char > { typedef int ret; }; 00422 template<> struct set_precise_unary_< op::uminus, signed short > { typedef signed short ret; }; 00423 template<> struct set_precise_unary_< op::uminus, unsigned short > { typedef int ret; }; 00424 template<> struct set_precise_unary_< op::uminus, signed int > { typedef signed int ret; }; 00425 00426 template<> struct set_precise_unary_< op::uminus, unsigned int > { typedef signed int ret; }; 00427 template<> struct set_precise_unary_< op::uminus, signed long > { typedef signed long ret; }; 00428 template<> struct set_precise_unary_< op::uminus, unsigned long > { typedef signed long ret; }; 00429 00430 template<> struct set_precise_unary_< op::uminus, bool > {}; 00431 00432 template<> struct set_precise_unary_< op::uminus, float > { typedef float ret; }; 00433 template<> struct set_precise_unary_< op::uminus, double > { typedef double ret; }; 00434 00435 00436 // FIXME: Is that all? 00437 00438 00439 // A couple of builtins => promotion... 00440 00441 mln_internal_set_builtin_trait_is_promotion_(op::plus); 00442 mln_internal_set_builtin_trait_is_promotion_(op::times); 00443 mln_internal_set_builtin_trait_is_promotion_(op::div); 00444 mln_internal_set_builtin_trait_is_promotion_(op::mod); 00445 00446 // mln_internal_set_builtin_trait_is_promotion_(op::minus); 00447 00448 template <typename Bl, typename Br> 00449 struct set_binary_< op::minus, 00450 mln::value::Built_In, Bl, mln::value::Built_In, Br > 00451 { 00452 typedef mln_trait_op_uminus(Br) minus_Br; 00453 typedef mln_trait_promote(Bl, minus_Br) ret; 00454 }; 00455 00456 // For comparisons (such as "less-than"), we get bool. 00457 00458 mln_internal_set_builtin_trait_is_bool_(op::eq); 00459 mln_internal_set_builtin_trait_is_bool_(op::neq); 00460 00461 mln_internal_set_builtin_trait_is_bool_(op::less); 00462 mln_internal_set_builtin_trait_is_bool_(op::leq); 00463 mln_internal_set_builtin_trait_is_bool_(op::geq); 00464 mln_internal_set_builtin_trait_is_bool_(op::greater); 00465 00466 mln_internal_set_builtin_trait_is_bool_(op::and_); 00467 mln_internal_set_builtin_trait_is_bool_(op::or_); 00468 mln_internal_set_builtin_trait_is_bool_(op::xor_); 00469 00470 // FIXME: We want to disable some ops; for instance "bool + int" and "int and int"... 00471 00472 00473 00474 00475 // FIXME: What about +=, etc. 00476 00477 00478 00479 00480 // Operators "Object OP Built_In" => "Object OP scalar_" 00481 00482 template <typename O, typename B> 00483 struct set_binary_< op::plus, mln::Object, O, mln::value::Built_In, B > 00484 { 00485 typedef mln_trait_op_plus(O, mln::value::scalar_<B>) ret; 00486 }; 00487 00488 template <typename O, typename B> 00489 struct set_binary_< op::minus, mln::Object, O, mln::value::Built_In, B > 00490 { 00491 typedef mln_trait_op_minus(O, mln::value::scalar_<B>) ret; 00492 }; 00493 00494 template <typename O, typename B> 00495 struct set_binary_< op::times, mln::Object, O, mln::value::Built_In, B > 00496 { 00497 typedef mln_trait_op_times(O, mln::value::scalar_<B>) ret; 00498 }; 00499 00500 template <typename O, typename B> 00501 struct set_binary_< op::div, mln::Object, O, mln::value::Built_In, B > 00502 { 00503 typedef mln_trait_op_div(O, mln::value::scalar_<B>) ret; 00504 }; 00505 00506 template <typename O, typename B> 00507 struct set_binary_< op::mod, mln::Object, O, mln::value::Built_In, B > 00508 { 00509 typedef mln_trait_op_mod(O, mln::value::scalar_<B>) ret; 00510 }; 00511 00512 template <typename O, typename B> 00513 struct set_binary_< op::less, mln::Object, O, mln::value::Built_In, B > 00514 { 00515 typedef mln_trait_op_less(O, mln::value::scalar_<B>) ret; 00516 }; 00517 00518 template <typename B, typename O> 00519 struct set_binary_< op::less, mln::value::Built_In, B, mln::Object, O > 00520 { 00521 typedef mln_trait_op_less(mln::value::scalar_<B>, O) ret; 00522 }; 00523 00524 00525 // 'Op+' is commutative so "o + b" => "o + scalar(b)". 00526 00527 template <typename B, typename O> 00528 struct set_binary_< op::plus, mln::value::Built_In, B, mln::Object, O > 00529 { 00530 typedef mln_trait_op_plus(O, mln::value::scalar_<B>) ret; 00531 }; 00532 00533 // Likewise for 'Op*'. 00534 00535 template <typename B, typename O> 00536 struct set_binary_< op::times, mln::value::Built_In, B, mln::Object, O > 00537 { 00538 typedef mln_trait_op_times(O, mln::value::scalar_<B>) ret; 00539 }; 00540 00541 00542 // 'Op-' is tricky for "b - o" => "(-o) + scalar(b)". 00543 00544 template <typename B, typename O> 00545 struct set_binary_< op::minus, mln::value::Built_In, B, mln::Object, O > 00546 { 00547 typedef mln_trait_op_uminus(O) minus_O; 00548 typedef mln_trait_op_plus(minus_O, mln::value::scalar_<B>) ret; 00549 }; 00550 00551 00552 // 'Op/' for "b / o" => "scalar(b) / o". 00553 00554 template <typename B, typename O> 00555 struct set_binary_< op::div, mln::value::Built_In, B, mln::Object, O > 00556 { 00557 typedef mln_trait_op_div(mln::value::scalar_<B>, O) ret; 00558 }; 00559 00560 // Likewise for 'Op%'. 00561 00562 template <typename B, typename O> 00563 struct set_binary_< op::mod, mln::value::Built_In, B, mln::Object, O > 00564 { 00565 typedef mln_trait_op_mod(mln::value::scalar_<B>, O) ret; 00566 }; 00567 00568 } // end of namespace mln::trait 00569 00570 00571 mln_internal_op_obj_builtins_(decl, +, plus); 00572 mln_internal_op_obj_builtins_(decl, -, minus); 00573 mln_internal_op_obj_builtins_(decl, *, times); 00574 mln_internal_op_obj_builtins_(decl, /, div); 00575 mln_internal_op_obj_builtins_(decl, %, mod); 00576 00577 // Op+ and op* respectively commute: 00578 mln_internal_builtins_op_obj_(decl, +, plus); 00579 mln_internal_builtins_op_obj_(decl, *, times); 00580 00581 // Op "builtin - object" is special: 00582 mln_internal_builtins_minus_obj_(decl); 00583 00584 00585 // Ops "bi / obj" and "bi % obj" 00586 mln_internal_builtins_dvmd_obj_(decl, /, div); 00587 mln_internal_builtins_dvmd_obj_(decl, %, mod); 00588 00589 00590 // Ops "bi CMP obj" and "bi CMP obj" 00591 mln_internal_op_builtins_cmp_(decl, ==, eq); 00592 mln_internal_op_builtins_cmp_(decl, !=, neq); 00593 // FIXME: ... 00594 00595 00596 // Ops "bi Op= obj" 00597 mln_internal_builtins_opeq_obj_(decl, +); 00598 mln_internal_builtins_opeq_obj_(decl, -); 00599 mln_internal_builtins_opeq_obj_(decl, *); 00600 mln_internal_builtins_opeq_obj_(decl, /); 00601 mln_internal_builtins_opeq_obj_(decl, %); 00602 00603 00604 // Ops "bi < obj" and "obj < bi" 00605 mln_internal_builtins_op_less_(decl, <, less); 00606 00607 00608 00609 # ifndef MLN_INCLUDE_ONLY 00610 00611 mln_internal_op_obj_builtins_(def, +, plus); 00612 mln_internal_op_obj_builtins_(def, -, minus); 00613 mln_internal_op_obj_builtins_(def, *, times); 00614 mln_internal_op_obj_builtins_(def, /, div); 00615 mln_internal_op_obj_builtins_(def, %, mod); 00616 00617 // Op+ and op* respectively commute: 00618 mln_internal_builtins_op_obj_(def, +, plus); 00619 mln_internal_builtins_op_obj_(def, *, times); 00620 00621 // Op "builtin - object" is special: 00622 mln_internal_builtins_minus_obj_(def); 00623 00624 // Ops "bi / obj" and "bi % obj" 00625 mln_internal_builtins_dvmd_obj_(def, /, div); 00626 mln_internal_builtins_dvmd_obj_(def, %, mod); 00627 00628 // Ops "bi CMP obj" and "bi CMP obj" 00629 mln_internal_op_builtins_cmp_(def, ==, eq); 00630 mln_internal_op_builtins_cmp_(def, !=, neq); 00631 00632 // FIXME: Add less, etc. 00633 00634 00635 // Ops "bi Op= obj" 00636 mln_internal_builtins_opeq_obj_(def, +); 00637 mln_internal_builtins_opeq_obj_(def, -); 00638 mln_internal_builtins_opeq_obj_(def, *); 00639 mln_internal_builtins_opeq_obj_(def, /); 00640 mln_internal_builtins_opeq_obj_(def, %); 00641 00642 00643 // Ops "bi < obj" and "obj < bi" 00644 mln_internal_builtins_op_less_(def, <, less); 00645 00646 00647 # endif // ! MLN_INCLUDE_ONLY 00648 00649 } // end of namespace mln 00650 00651 00652 #endif // ! MLN_VALUE_BUILTIN_OPS_HH