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

ops.hh

00001 // Copyright (C) 2007, 2008, 2009, 2010 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_VALUE_OPS_HH
00028 # define MLN_VALUE_OPS_HH
00029 
00033 
00034 # include <mln/trait/op/all.hh>
00035 # include <mln/value/builtin/all.hh>
00036 # include <mln/value/concept/all.hh>
00037 # include <mln/value/equiv.hh>
00038 # include <mln/trait/value_.hh>
00039 # include <mln/literal/zero.hh>
00040 # include <mln/literal/one.hh>
00041 # include <mln/literal/ops.hh>
00042 # include <mln/metal/ret.hh>
00043 
00044 
00046 # define mln_trait_value_sum_product(T, U)                      \
00047    typename mln::trait::value_< mln_trait_op_times(T,U) >::sum
00048 # define mln_trait_value_sum_product_(T, U)                     \
00049    mln::trait::value_< mln_trait_op_times_(T,U) >::sum
00050 
00051 
00053 # define mln_sum_product(T, U)  mln_trait_value_sum_product(T, U)
00054 # define mln_sum_product_(T, U)  mln_trait_value_sum_product_(T, U)
00055 
00056 
00057 // FIXME: In the definitions below, is that equiv or interop?
00058 
00059 
00060 
00061 namespace mln
00062 {
00063 
00064   namespace trait
00065   {
00066 
00067     // Unary traits for any Scalar type.
00068 
00069     template < template <class> class Name,
00070                typename V >
00071     struct set_unary_< Name, mln::value::Scalar, V >
00072     {
00073       typedef mln_trait_unary(Name, mln_value_equiv(V)) ret;
00074     };
00075 
00076 
00077     // Binary traits for any Scalar type...
00078 
00079     template < template <class, class> class Name,
00080                typename Vl, typename Vr >
00081     struct set_binary_< Name, mln::value::Scalar, Vl, mln::value::Scalar, Vr >
00082     {
00083       typedef mln_trait_binary(Name, mln_value_equiv(Vl), mln_value_equiv(Vr)) ret;
00084     };
00085 
00086     // ...and for the special case of a couple of value::scalar_.
00087 
00088     template < template <class, class> class Name,
00089                typename Sl, typename Sr >
00090     struct set_binary_< Name,
00091                         mln::value::Scalar, mln::value::scalar_<Sl>,
00092                         mln::value::Scalar, mln::value::scalar_<Sr> >
00093     {
00094       typedef mln_trait_binary(Name, mln_value_equiv(Sl), mln_value_equiv(Sr)) ret;
00095     };
00096 
00097 
00098     template < template <class, class> class Name,
00099                typename S, typename L >
00100     struct set_binary_< Name,
00101                         mln::value::Scalar, S,
00102                         mln::Literal,       L >
00103     {
00104       typedef mln_value_equiv(S) S_;
00105       typedef mln_trait_binary(Name, S_, S_) ret;
00106     };
00107 
00108     template < template <class, class> class Name,
00109                typename L, typename S >
00110     struct set_binary_< Name,
00111                         mln::Literal,       L,
00112                         mln::value::Scalar, S >
00113     {
00114       typedef mln_value_equiv(S) S_;
00115       typedef mln_trait_binary(Name, S_, S_) ret;
00116     };
00117 
00118 
00119     // Some binary traits for "scalar(s) OP obj" when OP commutes => "obj OP scalar(s)".
00120 
00121     template < typename S, typename O >
00122     struct set_binary_< op::plus,
00123                         mln::value::Scalar, mln::value::scalar_<S>,
00124                         mln::Object,        O >
00125     {
00126       typedef mln_trait_op_plus(O, mln::value::scalar_<S>) ret;
00127     };
00128 
00129     template < typename S, typename O >
00130     struct set_binary_< op::times,
00131                         mln::value::Scalar, mln::value::scalar_<S>,
00132                         mln::Object,        O >
00133     {
00134       typedef mln_trait_op_times(O, mln::value::scalar_<S>) ret;
00135     };
00136 
00137   } // end of namespace mln::trait
00138 
00139 
00140   // Arithmetical binary operators.
00141 
00142   template <typename Vl, typename Vr>
00143   mln_trait_op_plus(Vl, Vr)
00144     operator + (const value::Scalar<Vl>& lhs, const value::Scalar<Vr>& rhs);
00145 
00146   template <typename Vl, typename Vr>
00147   mln_trait_op_minus(Vl, Vr)
00148     operator - (const value::Scalar<Vl>& lhs, const value::Scalar<Vr>& rhs);
00149 
00150   template <typename Vl, typename Vr>
00151   mln_trait_op_times(Vl, Vr)
00152     operator * (const value::Scalar<Vl>& lhs, const value::Scalar<Vr>& rhs);
00153 
00154   template <typename Vl, typename Vr>
00155   mln_trait_op_div(Vl, Vr)
00156     operator / (const value::Scalar<Vl>& lhs, const value::Scalar<Vr>& rhs);
00157 
00158   template <typename Vl, typename Vr>
00159   mln_trait_op_mod(Vl, Vr)
00160     operator % (const value::Scalar<Vl>& lhs, const value::Scalar<Vr>& rhs);
00161 
00162 
00163   // Swap arguments so that "scalar_ OP Object" is "Object OP
00164   // scalar_".  As a consequence, the user only has to define what
00165   // happens with a scalar as a rhs.
00166 
00167   template <typename S, typename O>
00168   mln_trait_op_plus(O, value::scalar_<S>)
00169     operator + (const value::scalar_<S>& lhs, const Object<O>& rhs);
00170 
00171   template <typename S, typename O>
00172   mln_trait_op_times(O, value::scalar_<S>)
00173     operator * (const value::scalar_<S>& lhs, const Object<O>& rhs);
00174 
00175 
00176   // Arithmetical unary operators.
00177 
00178   template <typename S>
00179   mln_trait_op_uminus(S)
00180     operator - (const value::scalar_<S>& rhs); // Overload of op-(Object) in core/ops.
00181   // FIXME: It is dedicated to value::scalar_ so move elsewhere?
00182 
00183 
00184 
00185   // Logical operators.
00186 
00187   // FIXME: ...
00188 
00189 
00190 
00191   // Case of value::scalar_ OP value::scalar_.
00192 
00193   template <typename Sl, typename Sr>
00194   mln_trait_op_plus(Sl, Sr)
00195     operator + (const value::scalar_<Sl>& lhs, const value::scalar_<Sr>& rhs);
00196 
00197   template <typename Sl, typename Sr>
00198   mln_trait_op_minus(Sl, Sr)
00199     operator - (const value::scalar_<Sl>& lhs, const value::scalar_<Sr>& rhs);
00200 
00201   template <typename Sl, typename Sr>
00202   mln_trait_op_times(Sl, Sr)
00203     operator * (const value::scalar_<Sl>& lhs, const value::scalar_<Sr>& rhs);
00204 
00205   template <typename Sl, typename Sr>
00206   mln_trait_op_div(Sl, Sr)
00207     operator / (const value::scalar_<Sl>& lhs, const value::scalar_<Sr>& rhs);
00208 
00209   template <typename Sl, typename Sr>
00210   mln_trait_op_mod(Sl, Sr)
00211     operator % (const value::scalar_<Sl>& lhs, const value::scalar_<Sr>& rhs);
00212 
00213 
00214   // Operator ==.
00215 
00216   template <typename Sl, typename Sr>
00217   mln_trait_op_eq(Sl, Sr)
00218   operator == (const value::scalar_<Sl>& lhs, const value::scalar_<Sr>& rhs);
00219 
00220   bool
00221   operator == (const value::scalar_<int>& lhs, const value::scalar_<unsigned>& rhs);
00222 
00223   bool
00224   operator == (const value::scalar_<unsigned>& lhs, const value::scalar_<int>& rhs);
00225 
00226   template <typename O, typename L>
00227   mln_trait_op_eq(O, O)
00228   operator==(const value::scalar_<O>& lhs, const Literal<L>& rhs);
00229 
00230   template <typename L, typename O>
00231   mln_trait_op_eq(O, O)
00232   operator==(const Literal<L>& lhs, const value::scalar_<O>& rhs);
00233 
00234 
00235   // Operator <.
00236 
00237   template <typename Sl, typename Sr>
00238   mln_trait_op_less(Sl, Sr)
00239   operator < (const value::scalar_<Sl>& lhs, const value::scalar_<Sr>& rhs);
00240 
00241   template <typename O, typename L>
00242   mln_trait_op_less(O, O)
00243   operator < (const value::scalar_<O>& lhs, const Literal<L>& rhs);
00244 
00245   template <typename L, typename O>
00246   mln_trait_op_less(O, O)
00247   operator < (const Literal<L>& lhs, const value::scalar_<O>& rhs);
00248 
00249 
00250 
00251 # ifndef MLN_INCLUDE_ONLY
00252 
00253   template <typename Vl, typename Vr>
00254   inline
00255   mln_trait_op_plus(Vl, Vr)
00256     operator + (const value::Scalar<Vl>& lhs, const value::Scalar<Vr>& rhs)
00257   {
00258     typedef mln_trait_op_plus(Vl, Vr) R;
00259     return static_cast<R>(value::equiv(lhs)) + static_cast<R>(value::equiv(rhs));
00260   }
00261 
00262   template <typename Vl, typename Vr>
00263   inline
00264   mln_trait_op_minus(Vl, Vr)
00265     operator - (const value::Scalar<Vl>& lhs, const value::Scalar<Vr>& rhs)
00266   {
00267     typedef mln_trait_op_minus(Vl, Vr) R;
00268     return static_cast<R>(value::equiv(lhs)) - static_cast<R>(value::equiv(rhs));
00269   }
00270 
00271   template <typename Vl, typename Vr>
00272   inline
00273   mln_trait_op_times(Vl, Vr)
00274   operator * (const value::Scalar<Vl>& lhs, const value::Scalar<Vr>& rhs)
00275   {
00276     typedef mln_trait_op_times(Vl, Vr) R;
00277     return static_cast<R>(value::equiv(lhs)) * static_cast<R>(value::equiv(rhs));
00278   }
00279 
00280   template <typename Vl, typename Vr>
00281   inline
00282   mln_trait_op_div(Vl, Vr)
00283   operator / (const value::Scalar<Vl>& lhs, const value::Scalar<Vr>& rhs)
00284   {
00285     typedef mln_trait_op_div(Vl, Vr) R;
00286     return static_cast<R>(value::equiv(lhs)) / static_cast<R>(value::equiv(rhs));
00287   }
00288 
00289   template <typename Vl, typename Vr>
00290   inline
00291   mln_trait_op_mod(Vl, Vr)
00292   operator % (const value::Scalar<Vl>& lhs, const value::Scalar<Vr>& rhs)
00293   {
00294     return value::equiv(lhs) % value::equiv(rhs);
00295   }
00296 
00297   template <typename S>
00298   inline
00299   mln_trait_op_uminus(S)
00300   operator - (const value::scalar_<S>& rhs)
00301   {
00302     typedef mln_trait_op_uminus(S) R;
00303     return static_cast<R>(- rhs.to_equiv());
00304   }
00305 
00306   template <typename S, typename O>
00307   inline
00308   mln_trait_op_plus(O, value::scalar_<S>)
00309   operator + (const value::scalar_<S>& lhs, const Object<O>& rhs)
00310   {
00311     return exact(rhs) + lhs;
00312   }
00313 
00314   template <typename S, typename O>
00315   inline
00316   mln_trait_op_times(O, value::scalar_<S>)
00317   operator * (const value::scalar_<S>& lhs, const Object<O>& rhs)
00318   {
00319     return exact(rhs) * lhs;
00320   }
00321 
00322   // ...
00323 
00324 
00325   // With scalar_ OP scalar_.
00326 
00327   template <typename Sl, typename Sr>
00328   inline
00329   mln_trait_op_plus(Sl, Sr)
00330   operator + (const value::scalar_<Sl>& lhs, const value::scalar_<Sr>& rhs)
00331   {
00332     return value::equiv(lhs) + value::equiv(rhs);
00333   }
00334 
00335   template <typename Sl, typename Sr>
00336   inline
00337   mln_trait_op_minus(Sl, Sr)
00338   operator - (const value::scalar_<Sl>& lhs, const value::scalar_<Sr>& rhs)
00339   {
00340     return value::equiv(lhs) - value::equiv(rhs);
00341   }
00342 
00343   template <typename Sl, typename Sr>
00344   inline
00345   mln_trait_op_times(Sl, Sr)
00346   operator * (const value::scalar_<Sl>& lhs, const value::scalar_<Sr>& rhs)
00347   {
00348     return value::equiv(lhs) * value::equiv(rhs);
00349   }
00350 
00351   template <typename Sl, typename Sr>
00352   inline
00353   mln_trait_op_div(Sl, Sr)
00354   operator / (const value::scalar_<Sl>& lhs, const value::scalar_<Sr>& rhs)
00355   {
00356     return value::equiv(lhs) / value::equiv(rhs);
00357   }
00358 
00359   template <typename Sl, typename Sr>
00360   inline
00361   mln_trait_op_mod(Sl, Sr)
00362   operator % (const value::scalar_<Sl>& lhs, const value::scalar_<Sr>& rhs)
00363   {
00364     return value::equiv(lhs) % value::equiv(rhs);
00365   }
00366 
00367 
00368   // Operator ==.
00369 
00370   template <typename Sl, typename Sr>
00371   inline
00372   mln_trait_op_eq(Sl, Sr)
00373   operator == (const value::scalar_<Sl>& lhs, const value::scalar_<Sr>& rhs)
00374   {
00375     return value::equiv(lhs) == value::equiv(rhs);
00376   }
00377 
00378   inline
00379   bool
00380   operator == (const value::scalar_<int>& lhs, const value::scalar_<unsigned>& rhs)
00381   {
00382     return lhs.to_equiv() == int(rhs.to_equiv());
00383   }
00384 
00385   inline
00386   bool
00387   operator == (const value::scalar_<unsigned>& lhs, const value::scalar_<int>& rhs)
00388   {
00389     return int(lhs.to_equiv()) == rhs.to_equiv();
00390   }
00391 
00392   template <typename O, typename L>
00393   inline
00394   mln_trait_op_eq(O, O)
00395   operator==(const value::scalar_<O>& lhs, const Literal<L>& rhs)
00396   {
00397     return exact(lhs) == mln_value_equiv(O)(exact(rhs));
00398   }
00399 
00400   template <typename L, typename O>
00401   inline
00402   mln_trait_op_eq(O, O)
00403   operator==(const Literal<L>& lhs, const value::scalar_<O>& rhs)
00404   {
00405     return mln_value_equiv(O)(exact(lhs)) == exact(rhs);
00406   }
00407 
00408 
00409   // Operator <.
00410 
00411   template <typename Sl, typename Sr>
00412   inline
00413   mln_trait_op_less(Sl, Sr)
00414   operator < (const value::scalar_<Sl>& lhs, const value::scalar_<Sr>& rhs)
00415   {
00416     return value::equiv(lhs) < value::equiv(rhs);
00417   }
00418 
00419   template <typename O, typename L>
00420   inline
00421   mln_trait_op_less(O, O)
00422   operator < (const value::scalar_<O>& lhs, const Literal<L>& rhs)
00423   {
00424     return exact(lhs) < mln_value_equiv(O)(exact(rhs));
00425   }
00426 
00427   template <typename L, typename O>
00428   inline
00429   mln_trait_op_less(O, O)
00430   operator < (const Literal<L>& lhs, const value::scalar_<O>& rhs)
00431   {
00432     return mln_value_equiv(O)(exact(lhs)) < exact(rhs);
00433   }
00434 
00435 # endif // ! MLN_INCLUDE_ONLY
00436 
00437 } // end of namespace mln
00438 
00439 
00440 #endif // ! MLN_VALUE_OPS_HH

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