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

ops.hh

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

Generated on Thu Sep 8 2011 18:32:10 for Milena (Olena) by  doxygen 1.7.1