• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

ops.hh

00001 // Copyright (C) 2007, 2008, 2009 EPITA Research and Development
00002 // Laboratory (LRDE)
00003 //
00004 // This file is part of Olena.
00005 //
00006 // Olena is free software: you can redistribute it and/or modify it under
00007 // the terms of the GNU General Public License as published by the Free
00008 // Software Foundation, version 2 of the License.
00009 //
00010 // Olena is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with Olena.  If not, see <http://www.gnu.org/licenses/>.
00017 //
00018 // As a special exception, you may use this file as part of a free
00019 // software project without restriction.  Specifically, if other files
00020 // instantiate templates or use macros or inline functions from this
00021 // file, or you compile this file and link it with other files to produce
00022 // an executable, this file does not by itself cause the resulting
00023 // executable to be covered by the GNU General Public License.  This
00024 // exception does not however invalidate any other reasons why the
00025 // executable file might be covered by the GNU General Public License.
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   // Fwd decls.
00101   namespace literal { struct zero_t; struct one_t; }
00102 
00103 
00104   namespace trait
00105   {
00106 
00107     // For unary operators.
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     // For binary operators.
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       // O1 != O2  -->  ! (O1 == O2)
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       // O1 <= O2  -->  ! (O2 < 01)
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       // O1 >= O2  -->  O2 <= O1
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       // O1 > O2  -->  O2 < O1
00171       typedef mln_trait_op_less(O2, O1) ret;
00172     };
00173 
00174     // FIXME: Same for the other definitions below...
00175 
00176 
00177 
00178     // Case of "const" in types.
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   } // end of mln::trait
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   /* \brief Default definition of the post-incrementation operator.
00272    *
00273    * It relies on the definition of the pre-incrementation operator.
00274    */
00275   template <typename O>
00276   O operator++(Object<O>& lhs, int);
00277 
00278 
00279   /* \brief Default definition of the post-decrementation operator.
00280    *
00281    * It relies on the definition of the pre-decrementation operator.
00282    */
00283   template <typename O>
00284   O operator--(Object<O>& lhs, int);
00285 
00286 
00287   /* \brief Default definition of the pre-incrementation operator.
00288    *
00289    * It relies on "+ literal::one".
00290    */
00291   template <typename O>
00292   O& operator++(Object<O>& rhs);
00293 
00294 
00295   /* \brief Default definition of the pre-decrementation operator.
00296    *
00297    * It relies on "- literal::one".
00298    */
00299   template <typename O>
00300   O& operator--(Object<O>& rhs);
00301 
00302 
00303   /* \brief Default definitions of the "unary plus" operator.
00304    *
00305    * \param[in] rhs An object
00306    * \return A copy of \p rhs.
00307    */
00308   template <typename O>
00309   O operator+(const Object<O>& rhs);
00310 
00311 
00312   /* \brief Default definition of the "unary minus" operator.
00313    *
00314    * \param[in] rhs An object
00315    * \return 0 - \p rhs.
00316    *
00317    * It relies on "O(literal::zero) - rhs".
00318    */
00319   template <typename O>
00320   mln_trait_op_minus(O, O)
00321   operator-(const Object<O>& rhs);
00322 
00323 
00324   /* \brief Default definition of the "plus equal" operator.
00325    *
00326    * \param[in,out] lhs The target object.
00327    * \param[in] rhs The auxiliary object.
00328    * \return The target object \p lhs once modified.
00329    *
00330    * It relies on "lhs = L(lhs) + rhs".
00331    */
00332   template <typename L, typename R>
00333   L&
00334   operator+=(Object<L>& lhs, const Object<R>& rhs);
00335 
00336 
00337   /* \brief Default definition of the "minus equal" operator.
00338    *
00339    * \param[in,out] lhs The target object.
00340    * \param[in] rhs The auxiliary object.
00341    * \return The target object \p lhs once modified.
00342    *
00343    * It relies on "lhs = L(lhs) - rhs".
00344    */
00345   template <typename L, typename R>
00346   L&
00347   operator-=(Object<L>& lhs, const Object<R>& rhs);
00348 
00349 
00350   /* \brief Default definition of the "times equal" operator.
00351    *
00352    * \param[in,out] lhs The target object.
00353    * \param[in] rhs The auxiliary object.
00354    * \return The target object \p lhs once modified.
00355    *
00356    * It relies on "lhs = L(lhs) * rhs".
00357    */
00358   template <typename L, typename R>
00359   L&
00360   operator*=(Object<L>& lhs, const Object<R>& rhs);
00361 
00362 
00363   /* \brief Default definition of the "div equal" operator.
00364    *
00365    * \param[in,out] lhs The target object.
00366    * \param[in] rhs The auxiliary object.
00367    * \return The target object \p lhs once modified.
00368    *
00369    * It relies on "lhs = L(lhs) / rhs".
00370    */
00371   template <typename L, typename R>
00372   L&
00373   operator/=(Object<L>& lhs, const Object<R>& rhs);
00374 
00375 
00376   /* \brief Default definition of the "mod equal" operator.
00377    *
00378    * \param[in,out] lhs The target object.
00379    * \param[in] rhs The auxiliary object.
00380    * \return The target object \p lhs once modified.
00381    *
00382    * It relies on "lhs = L(lhs) % rhs".
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   // Plus equal.
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   // Minus equal.
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   // Times equal.
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   // Div equal.
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     // Remark:
00438     // The code below gives a warning with g++-3.3 with the test file
00439     // tests/value/int_u8.cc.  It is normal since writing "i /= f"
00440     // means casting eventually float to int.  Yet what do we want in
00441     // that case?  A quiet compilation or a warning?
00442     return exact(lhs) = static_cast<L>(exact(lhs) / exact(rhs));
00443   }
00444 
00445   // Mod equal.
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   // Unary plus.
00458 
00459   template <typename O>
00460   inline
00461   O
00462   operator+(const Object<O>& rhs)
00463   {
00464     return exact(rhs); // Cpy.
00465   }
00466 
00467   // Unary minus.
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   // Post-incrementation.
00480 
00481   template <typename O>
00482   inline
00483   O
00484   operator++(Object<O>& lhs, int)
00485   {
00486     O tmp(exact(lhs)); // Copy.
00487     ++exact(lhs);      // Pre-inc.
00488     // FIXME: Activate: mln_postcondition(exact(lhs) == tmp + literal::one);
00489     return tmp;
00490   }
00491 
00492   // Post-decrementation.
00493 
00494   template <typename O>
00495   inline
00496   O
00497   operator--(Object<O>& lhs, int)
00498   {
00499     O tmp(exact(lhs)); // Copy.
00500     --exact(lhs);      // Pre-dec.
00501     // FIXME: Activate: mln_postcondition(exact(lhs) == tmp - literal::one);
00502     return tmp;
00503   }
00504 
00505   // Pre-decrementation.
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   // Pre-incrementation.
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   // Comparisons.
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     // if partial ordering, this operator should be re-defined!
00561     return ! (exact(rhs) < exact(lhs));
00562   }
00563 
00564 # endif // ! MLN_INCLUDE_ONLY
00565 
00566 } // end of namespace mln
00567 
00568 
00569 #endif // ! MLN_CORE_ROUTINE_OPS_HH

Generated on Tue Oct 4 2011 15:24:07 for Milena (Olena) by  doxygen 1.7.1