global_ops.hh

00001 // Copyright (C) 2001, 2002, 2003  EPITA Research and Development Laboratory
00002 //
00003 // This file is part of the Olena Library.  This library is free
00004 // software; you can redistribute it and/or modify it under the terms
00005 // of the GNU General Public License version 2 as published by the
00006 // Free Software Foundation.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU General Public License
00014 // along with this library; see the file COPYING.  If not, write to
00015 // the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
00016 // MA 02111-1307, USA.
00017 //
00018 // As a special exception, you may use this file as part of a free
00019 // software library 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
00022 // produce an executable, this file does not by itself cause the
00023 // resulting executable to be covered by the GNU General Public
00024 // License.  This exception does not however invalidate any other
00025 // reasons why the executable file might be covered by the GNU General
00026 // Public License.
00027 
00028 #ifndef NTG_CORE_INTERNAL_GLOBAL_OPS_HH
00029 # define NTG_CORE_INTERNAL_GLOBAL_OPS_HH
00030 
00031 /*
00032   This header defines global operators (arithmetic, logical, and
00033   comparison). They are examined when at least one ntg type is
00034   involved. They are required to have a precise dispatch, you can
00035   check the documentation for more details.
00036 */
00037 
00038 # include <mlc/contract.hh>
00039 # include <mlc/is_a.hh>
00040 
00041 # include <ntg/core/internal/global_ops_traits.hh>
00042 # include <ntg/core/macros.hh>
00043 # include <ntg/core/value.hh>
00044 # include <ntg/utils/debug.hh>
00045 
00046 // macros defs
00047 # include <ntg/core/internal/global_ops_defs.hh>
00048 
00049 // min and max
00050 # include <algorithm>
00051 
00052 namespace ntg
00053 {
00054 
00055   /*
00056     Global operators are defined in the internal namespace to avoid
00057     any possible clash, even when "using namespace ntg" directive is
00058     used.
00059   */
00060 
00061   namespace internal
00062   {
00063 
00064     /*------------------------.
00065     | Arithmetic assignements |
00066     `------------------------*/
00067 
00068     GLOBAL_ASSIGN_OP(operator+=, plus_equal)
00069     GLOBAL_ASSIGN_OP_BUILTIN_INT(operator+=, plus_equal)
00070     GLOBAL_ASSIGN_OP_BUILTIN_FLOAT(operator+=, plus_equal)
00071 
00072     GLOBAL_ASSIGN_OP(operator-=, minus_equal)
00073     GLOBAL_ASSIGN_OP_BUILTIN_INT(operator-=, minus_equal)
00074     GLOBAL_ASSIGN_OP_BUILTIN_FLOAT(operator-=, minus_equal)
00075 
00076     GLOBAL_ASSIGN_OP(operator*=, times_equal)
00077     GLOBAL_ASSIGN_OP_BUILTIN_INT(operator*=, times_equal)
00078     GLOBAL_ASSIGN_OP_BUILTIN_FLOAT(operator*=, times_equal)
00079 
00080     GLOBAL_ASSIGN_OP(operator/=, div_equal)
00081     GLOBAL_ASSIGN_OP_BUILTIN_INT(operator/=, div_equal)
00082     GLOBAL_ASSIGN_OP_BUILTIN_FLOAT(operator/=, div_equal)
00083 
00084     GLOBAL_ASSIGN_OP(operator%=, mod_equal)
00085     GLOBAL_ASSIGN_OP_BUILTIN_INT(operator%=, mod_equal)
00086 
00087     /*---------------------.
00088     | Logical assignements |
00089     `---------------------*/
00090 
00091     // FIXME: implement |=, &= and ^= in optraits<bool>.
00092 
00093     GLOBAL_ASSIGN_OP(operator|=, logical_or_equal)
00094     //    GLOBAL_ASSIGN_OP_BUILTIN_BOOL(operator|=, logical_or_equal)
00095 
00096     GLOBAL_ASSIGN_OP(operator&=, logical_and_equal)
00097     //    GLOBAL_ASSIGN_OP_BUILTIN_BOOL(operator&=, logical_and_equal)
00098 
00099     GLOBAL_ASSIGN_OP(operator^=, logical_xor_equal)
00100     //    GLOBAL_ASSIGN_OP_BUILTIN_BOOL(operator^=, logical_xor_equal)
00101 
00102     /*----------------------.
00103     | Arithmetic operations |
00104     `----------------------*/
00105                             
00106     GLOBAL_ARITH_OP(operator+, plus)
00107     GLOBAL_ARITH_OP(operator-, minus)
00108     GLOBAL_ARITH_OP(operator*, times)
00109     GLOBAL_ARITH_OP(operator/, div)
00110     GLOBAL_ARITH_OP(operator%, mod)
00111 
00112     /*------------------.
00113     | Logical operators |
00114     `------------------*/
00115 
00116     GLOBAL_LOGICAL_OP(operator|, logical_or)
00117     GLOBAL_LOGICAL_OP(operator&, logical_and)
00118     GLOBAL_LOGICAL_OP(operator^, logical_xor)
00119 
00120     /*---------------------.
00121     | Comparison operators |
00122     `---------------------*/
00123 
00124     GLOBAL_CMP_OP(operator==, cmp_eq)
00125 
00126     template <class T1, class T2> inline
00127     bool 
00128     operator!=(const T1& lhs, const T2& rhs)
00129     { return !(lhs == rhs); }
00130 
00131     // >, >= and <= operators are defined using <. They are not
00132     // implicitely defined so we have to do so by hand.
00133 
00134     GLOBAL_CMP_OP(operator<, cmp_lt)
00135 
00136     template <class T1, class T2> inline
00137     bool
00138     operator>(const T1& lhs, const T2& rhs)
00139     { return rhs < lhs; }
00140 
00141     template <class T1, class T2> inline
00142     bool
00143     operator>=(const T1& lhs, const T2& rhs)
00144     { return !(lhs < rhs); }
00145 
00146     template <class T1, class T2> inline
00147     bool
00148     operator<=(const T1& lhs, const T2& rhs)
00149     { return !(rhs < lhs); }
00150 
00151     /*-----------------------------.
00152     | Arithmetical unary operators |
00153     `-----------------------------*/
00154 
00155     // plus
00156 
00157     template <class T> inline
00158     const T&
00159     operator+(const T& val)
00160     {
00161       return val;
00162     }
00163 
00164     template<class T> inline
00165     const T&
00166     operator++(T& val)
00167     {
00168       val += ntg_unit_val(T);
00169       return val;
00170     }
00171 
00172     template<class T> inline
00173     T
00174     operator++(T& val, int)
00175     {
00176       T tmp(val);
00177       val += ntg_unit_val(T);
00178       return tmp;
00179     }
00180 
00181     // minus
00182 
00183     template <class T> inline
00184     const ntg_signed_type(T)
00185     operator-(const T& val)
00186     {       
00187       typedef ntg_signed_type(T) signed_type;
00188       return static_cast<signed_type>(ntg_zero_val(T)) - val;
00189     }
00190 
00191     template<class T> inline
00192     const T& operator--(T& val)
00193     {
00194       val -= ntg_unit_val(T);
00195       return val;
00196     }
00197     
00198     template<class T> inline
00199     T operator--(T& val, int)
00200     {
00201       T tmp(val);
00202       val -= ntg_unit_val(T);
00203       return tmp;
00204     }
00205 
00206     /*------------------.
00207     | Min/Max operators |
00208     `------------------*/
00209 
00210     /*
00211       These operators are slighly different from standard library ones
00212       since they can operate on values of 2 different types.
00213     */
00214 
00215     template <class T1, class T2> inline
00216     ntg_return_type(min, T1, T2)
00217     min (const T1& lhs, const T2& rhs)
00218     {
00219       typedef ntg_return_type(max, T1, T2) result_type;     
00220       return (lhs < rhs) ? result_type(lhs) : result_type(rhs);
00221     }
00222     
00223     template <class T1, class T2> inline
00224     ntg_return_type(max, T1, T2)
00225     max (const T1& lhs, const T2& rhs)
00226     {
00227       typedef ntg_return_type(max, T1, T2) result_type;
00228       return (lhs > rhs) ? result_type(lhs) : result_type(rhs);
00229     }
00230 
00231   } // end of internal.
00232 
00233   // FIXME: those are needed to handle max and min between two builtin
00234   // types. Maybe std::min and std::max should be extended to work
00235   // with builtin types?
00236   using internal::min;
00237   using internal::max;
00238 
00239 } // end of ntg.
00240 
00241 #endif // ndef NTG_CORE_INTERNAL_GLOBAL_OPS_HH

Generated on Thu Apr 15 20:13:09 2004 for Olena by doxygen 1.3.6-20040222