00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef MLN_CORE_ROUTINE_OPS_HH
00028 # define MLN_CORE_ROUTINE_OPS_HH
00029
00033
00092 # include <mln/trait/op/all.hh>
00093 # include <mln/core/concept/object.hh>
00094 # include <mln/metal/converts_to.hh>
00095
00096
00097 namespace mln
00098 {
00099
00100
00101 namespace literal { struct zero_t; struct one_t; }
00102
00103
00104 namespace trait
00105 {
00106
00107
00108
00109
00111 template <typename O>
00112 struct set_unary_< op::uplus, Object,O > { typedef O ret; };
00113
00115 template <typename O>
00116 struct set_unary_< op::uminus, Object,O > { typedef mln_trait_op_minus(O, O) ret; };
00117
00119 template <typename O>
00120 struct set_unary_< op::preinc, Object,O > { typedef O& ret; };
00121
00123 template <typename O>
00124 struct set_unary_< op::predec, Object,O > { typedef O& ret; };
00125
00127 template <typename O>
00128 struct set_unary_< op::postinc, Object,O > { typedef O ret; };
00129
00131 template <typename O>
00132 struct set_unary_< op::postdec, Object,O > { typedef O ret; };
00133
00134
00135
00136
00137
00138 template <typename O1, typename O2>
00139 struct set_binary_< op::eq, Object,O1, Object,O2 > { typedef bool ret; };
00140
00141 template <typename O1, typename O2>
00142 struct set_binary_< op::neq, Object,O1, Object,O2 >
00143 {
00144
00145 typedef mln_trait_op_eq(O1, O2) B_;
00146 typedef mln_trait_op_not(B_) ret;
00147 };
00148
00149 template <typename O1, typename O2>
00150 struct set_binary_< op::less, Object,O1, Object,O2 > { typedef bool ret; };
00151
00152 template <typename O1, typename O2>
00153 struct set_binary_< op::leq, Object,O1, Object,O2 >
00154 {
00155
00156 typedef mln_trait_op_less(O2, O1) B_;
00157 typedef mln_trait_op_not(B_) ret;
00158 };
00159
00160 template <typename O1, typename O2>
00161 struct set_binary_< op::geq, Object,O1, Object,O2 >
00162 {
00163
00164 typedef mln_trait_op_leq(O2, O1) ret;
00165 };
00166
00167 template <typename O1, typename O2>
00168 struct set_binary_< op::greater, Object,O1, Object,O2 >
00169 {
00170
00171 typedef mln_trait_op_less(O2, O1) ret;
00172 };
00173
00174
00175
00176
00177
00178
00179
00180 template< template <class> class Name,
00181 typename O >
00182 struct set_precise_unary_< Name, const O >
00183 {
00184 typedef mln_trait_unary(Name, O) ret;
00185 };
00186
00187 template< template <class,class> class Name,
00188 typename O1, typename O2 >
00189 struct set_precise_binary_< Name, O1, const O2 >
00190 {
00191 typedef mln_trait_binary(Name, O1, O2) ret;
00192 };
00193
00194 template< template <class,class> class Name,
00195 typename O1, typename O2 >
00196 struct set_precise_binary_< Name, const O1, O2 >
00197 {
00198 typedef mln_trait_binary(Name, O1, O2) ret;
00199 };
00200
00201 template< template <class,class> class Name,
00202 typename O1, typename O2 >
00203 struct set_precise_binary_< Name, const O1, const O2 >
00204 {
00205 typedef mln_trait_binary(Name, O1, O2) ret;
00206 };
00207
00208
00209 }
00210
00211
00212
00222 template <typename O1, typename O2>
00223 mln_trait_op_neq(O1, O2)
00224 operator!=(const Object<O1>& lhs, const Object<O2>& rhs);
00225
00226
00236 template <typename O1, typename O2>
00237 mln_trait_op_greater(O1, O2)
00238 operator>(const Object<O1>& lhs, const Object<O2>& rhs);
00239
00240
00251 template <typename O1, typename O2>
00252 mln_trait_op_geq(O1, O2)
00253 operator>=(const Object<O1>& lhs, const Object<O2>& rhs);
00254
00255
00266 template <typename O1, typename O2>
00267 mln_trait_op_leq(O1, O2)
00268 operator<=(const Object<O1>& lhs, const Object<O2>& rhs);
00269
00270
00271
00272
00273
00274
00275 template <typename O>
00276 O operator++(Object<O>& lhs, int);
00277
00278
00279
00280
00281
00282
00283 template <typename O>
00284 O operator--(Object<O>& lhs, int);
00285
00286
00287
00288
00289
00290
00291 template <typename O>
00292 O& operator++(Object<O>& rhs);
00293
00294
00295
00296
00297
00298
00299 template <typename O>
00300 O& operator--(Object<O>& rhs);
00301
00302
00303
00304
00305
00306
00307
00308 template <typename O>
00309 O operator+(const Object<O>& rhs);
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 template <typename O>
00320 mln_trait_op_minus(O, O)
00321 operator-(const Object<O>& rhs);
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332 template <typename L, typename R>
00333 L&
00334 operator+=(Object<L>& lhs, const Object<R>& rhs);
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345 template <typename L, typename R>
00346 L&
00347 operator-=(Object<L>& lhs, const Object<R>& rhs);
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 template <typename L, typename R>
00359 L&
00360 operator*=(Object<L>& lhs, const Object<R>& rhs);
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371 template <typename L, typename R>
00372 L&
00373 operator/=(Object<L>& lhs, const Object<R>& rhs);
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384 template <typename L, typename R>
00385 L&
00386 operator%=(Object<L>& lhs, const Object<R>& rhs);
00387
00388
00389
00390 # ifndef MLN_INCLUDE_ONLY
00391
00392
00393
00394 template <typename L, typename R>
00395 inline
00396 L&
00397 operator+=(Object<L>& lhs, const Object<R>& rhs)
00398 {
00399 typedef mln_trait_op_plus(L, R) P;
00400 mlc_converts_to(P, L)::check();
00401 return exact(lhs) = static_cast<L>(exact(lhs) + exact(rhs));
00402 }
00403
00404
00405
00406 template <typename L, typename R>
00407 inline
00408 L&
00409 operator-=(Object<L>& lhs, const Object<R>& rhs)
00410 {
00411 typedef mln_trait_op_minus(L, R) M;
00412 mlc_converts_to(M, L)::check();
00413 return exact(lhs) = static_cast<L>(exact(lhs) - exact(rhs));
00414 }
00415
00416
00417
00418 template <typename L, typename R>
00419 inline
00420 L&
00421 operator*=(Object<L>& lhs, const Object<R>& rhs)
00422 {
00423 typedef mln_trait_op_times(L, R) T;
00424 mlc_converts_to(T, L)::check();
00425 return exact(lhs) = static_cast<L>(exact(lhs) * exact(rhs));
00426 }
00427
00428
00429
00430 template <typename L, typename R>
00431 inline
00432 L&
00433 operator/=(Object<L>& lhs, const Object<R>& rhs)
00434 {
00435 typedef mln_trait_op_div(L, R) D;
00436 mlc_converts_to(D, L)::check();
00437
00438
00439
00440
00441
00442 return exact(lhs) = static_cast<L>(exact(lhs) / exact(rhs));
00443 }
00444
00445
00446
00447 template <typename L, typename R>
00448 inline
00449 L&
00450 operator%=(Object<L>& lhs, const Object<R>& rhs)
00451 {
00452 typedef mln_trait_op_mod(L, R) M;
00453 mlc_converts_to(M, L)::check();
00454 return exact(lhs) = static_cast<L>(exact(lhs) % exact(rhs));
00455 }
00456
00457
00458
00459 template <typename O>
00460 inline
00461 O
00462 operator+(const Object<O>& rhs)
00463 {
00464 return exact(rhs);
00465 }
00466
00467
00468
00469 template <typename O>
00470 inline
00471 mln_trait_op_minus(O, O)
00472 operator-(const Object<O>& rhs)
00473 {
00474 mlc_converts_to(literal::zero_t, O)::check();
00475 literal::zero_t* p_zero = 0;
00476 return O(*p_zero) - exact(rhs);
00477 }
00478
00479
00480
00481 template <typename O>
00482 inline
00483 O
00484 operator++(Object<O>& lhs, int)
00485 {
00486 O tmp(exact(lhs));
00487 ++exact(lhs);
00488
00489 return tmp;
00490 }
00491
00492
00493
00494 template <typename O>
00495 inline
00496 O
00497 operator--(Object<O>& lhs, int)
00498 {
00499 O tmp(exact(lhs));
00500 --exact(lhs);
00501
00502 return tmp;
00503 }
00504
00505
00506
00507 template <typename O>
00508 inline
00509 O&
00510 operator--(Object<O>& rhs)
00511 {
00512 literal::one_t* p_one;
00513 exact(rhs) -= *p_one;
00514 return exact(rhs);
00515 }
00516
00517
00518
00519 template <typename O>
00520 inline
00521 O&
00522 operator++(Object<O>& rhs)
00523 {
00524 literal::one_t* p_one;
00525 exact(rhs) += *p_one;
00526 return exact(rhs);
00527 }
00528
00529
00530
00531 template <typename O1, typename O2>
00532 inline
00533 mln_trait_op_neq(O1, O2)
00534 operator!=(const Object<O1>& lhs, const Object<O2>& rhs)
00535 {
00536 return ! (exact(lhs) == exact(rhs));
00537 }
00538
00539 template <typename O1, typename O2>
00540 inline
00541 mln_trait_op_greater(O1, O2)
00542 operator>(const Object<O1>& lhs, const Object<O2>& rhs)
00543 {
00544 return exact(rhs) < exact(lhs);
00545 }
00546
00547 template <typename O1, typename O2>
00548 inline
00549 mln_trait_op_geq(O1, O2)
00550 operator>=(const Object<O1>& lhs, const Object<O2>& rhs)
00551 {
00552 return exact(rhs) <= exact(lhs);
00553 }
00554
00555 template <typename O1, typename O2>
00556 inline
00557 mln_trait_op_leq(O1, O2)
00558 operator<=(const Object<O1>& lhs, const Object<O2>& rhs)
00559 {
00560
00561 return ! (exact(rhs) < exact(lhs));
00562 }
00563
00564 # endif // ! MLN_INCLUDE_ONLY
00565
00566 }
00567
00568
00569 #endif // ! MLN_CORE_ROUTINE_OPS_HH