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