global_ops.hh

00001 // Copyright (C) 2001, 2002, 2003, 2004  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, Inc., 51 Franklin Street, Fifth Floor,
00016 // Boston, MA 02110-1301, 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/real/builtin_float.hh>
00042 # include <ntg/real/optraits_builtin_int.hh>
00043 # include <ntg/core/internal/global_ops_traits.hh>
00044 # include <ntg/core/macros.hh>
00045 # include <ntg/core/value.hh>
00046 # include <ntg/utils/debug.hh>
00047 
00048 // macros defs
00049 # include <ntg/core/internal/global_ops_defs.hh>
00050 
00051 // min and max
00052 # include <algorithm>
00053 
00054 namespace ntg
00055 {
00056 
00057   /*
00058     Global operators are defined in the internal namespace to avoid
00059     any possible clash, even when "using namespace ntg" directive is
00060     used.
00061   */
00062 
00063   namespace internal
00064   {
00065 
00066     /*------------------------.
00067     | Arithmetic assignements |
00068     `------------------------*/
00069 
00070     GLOBAL_ASSIGN_OP(operator+=, plus_equal)
00071     GLOBAL_ASSIGN_OP_BUILTIN_INT(operator+=, plus_equal)
00072     GLOBAL_ASSIGN_OP_BUILTIN_FLOAT(operator+=, plus_equal)
00073 
00074     GLOBAL_ASSIGN_OP(operator-=, minus_equal)
00075     GLOBAL_ASSIGN_OP_BUILTIN_INT(operator-=, minus_equal)
00076     GLOBAL_ASSIGN_OP_BUILTIN_FLOAT(operator-=, minus_equal)
00077 
00078     GLOBAL_ASSIGN_OP(operator*=, times_equal)
00079     GLOBAL_ASSIGN_OP_BUILTIN_INT(operator*=, times_equal)
00080     GLOBAL_ASSIGN_OP_BUILTIN_FLOAT(operator*=, times_equal)
00081 
00082     GLOBAL_ASSIGN_OP(operator/=, div_equal)
00083     GLOBAL_ASSIGN_OP_BUILTIN_INT(operator/=, div_equal)
00084     GLOBAL_ASSIGN_OP_BUILTIN_FLOAT(operator/=, div_equal)
00085 
00086     GLOBAL_ASSIGN_OP(operator%=, mod_equal)
00087     GLOBAL_ASSIGN_OP_BUILTIN_INT(operator%=, mod_equal)
00088 
00089     /*---------------------.
00090     | Logical assignements |
00091     `---------------------*/
00092 
00093     // FIXME: implement |=, &= and ^= in optraits<bool>.
00094 
00095     GLOBAL_ASSIGN_OP(operator|=, logical_or_equal)
00096     //    GLOBAL_ASSIGN_OP_BUILTIN_BOOL(operator|=, logical_or_equal)
00097 
00098     GLOBAL_ASSIGN_OP(operator&=, logical_and_equal)
00099     //    GLOBAL_ASSIGN_OP_BUILTIN_BOOL(operator&=, logical_and_equal)
00100 
00101     GLOBAL_ASSIGN_OP(operator^=, logical_xor_equal)
00102     //    GLOBAL_ASSIGN_OP_BUILTIN_BOOL(operator^=, logical_xor_equal)
00103 
00104     /*----------------------.
00105     | Arithmetic operations |
00106     `----------------------*/
00107 
00108     GLOBAL_ARITH_OP(operator+, plus)
00109     GLOBAL_ARITH_OP(operator-, minus)
00110     GLOBAL_ARITH_OP(operator*, times)
00111     GLOBAL_ARITH_OP(operator/, div)
00112     GLOBAL_ARITH_OP(operator%, mod)
00113 
00114     /*------------------.
00115     | Logical operators |
00116     `------------------*/
00117 
00118     GLOBAL_LOGICAL_OP(operator|, logical_or)
00119     GLOBAL_LOGICAL_OP(operator&, logical_and)
00120     GLOBAL_LOGICAL_OP(operator^, logical_xor)
00121 
00122     /*---------------------.
00123     | Comparison operators |
00124     `---------------------*/
00125 
00126     GLOBAL_CMP_OP(operator==, cmp_eq)
00127 
00128     template <class T1, class T2> inline
00129     bool
00130     operator!=(const T1& lhs, const T2& rhs)
00131     { return !(lhs == rhs); }
00132 
00133     // >, >= and <= operators are defined using <. They are not
00134     // implicitely defined so we have to do so by hand.
00135 
00136     GLOBAL_CMP_OP(operator<, cmp_lt)
00137 
00138     template <class T1, class T2> inline
00139     bool
00140     operator>(const T1& lhs, const T2& rhs)
00141     { return rhs < lhs; }
00142 
00143     template <class T1, class T2> inline
00144     bool
00145     operator>=(const T1& lhs, const T2& rhs)
00146     { return !(lhs < rhs); }
00147 
00148     template <class T1, class T2> inline
00149     bool
00150     operator<=(const T1& lhs, const T2& rhs)
00151     { return !(rhs < lhs); }
00152 
00153     /*-----------------------------.
00154     | Arithmetical unary operators |
00155     `-----------------------------*/
00156 
00157     // plus
00158 
00159     template <class T> inline
00160     const T&
00161     operator+(const T& val)
00162     {
00163       return val;
00164     }
00165 
00166     template<class T> inline
00167     const T&
00168     operator++(T& val)
00169     {
00170       val += ntg_unit_val(T);
00171       return val;
00172     }
00173 
00174     template<class T> inline
00175     T
00176     operator++(T& val, int)
00177     {
00178       T tmp(val);
00179       val += ntg_unit_val(T);
00180       return tmp;
00181     }
00182 
00183     // minus
00184 
00185     template <class T> inline
00186     const ntg_signed_type(T)
00187     operator-(const T& val)
00188     {
00189       typedef ntg_signed_type(T) signed_type;
00190       return static_cast<signed_type>(ntg_zero_val(T)) - val;
00191     }
00192 
00193     template<class T> inline
00194     const T& operator--(T& val)
00195     {
00196       val -= ntg_unit_val(T);
00197       return val;
00198     }
00199 
00200     template<class T> inline
00201     T operator--(T& val, int)
00202     {
00203       T tmp(val);
00204       val -= ntg_unit_val(T);
00205       return tmp;
00206     }
00207 
00208     /*------------------.
00209     | Min/Max operators |
00210     `------------------*/
00211 
00212     /*
00213       These operators are slighly different from standard library ones
00214       since they can operate on values of 2 different types.
00215     */
00216 
00217     template <class T1, class T2> inline
00218     ntg_return_type(min, T1, T2)
00219     min (const T1& lhs, const T2& rhs)
00220     {
00221       typedef ntg_return_type(max, T1, T2) result_type;
00222       return (lhs < rhs) ? result_type(lhs) : result_type(rhs);
00223     }
00224 
00225     template <class T1, class T2> inline
00226     ntg_return_type(max, T1, T2)
00227     max (const T1& lhs, const T2& rhs)
00228     {
00229       typedef ntg_return_type(max, T1, T2) result_type;
00230       return (lhs > rhs) ? result_type(lhs) : result_type(rhs);
00231     }
00232 
00233   } // end of internal.
00234 
00235   // FIXME: those are needed to handle max and min between two builtin
00236   // types. Maybe std::min and std::max should be extended to work
00237   // with builtin types?
00238   using internal::min;
00239   using internal::max;
00240 
00241 } // end of ntg.
00242 
00243 #endif // ndef NTG_CORE_INTERNAL_GLOBAL_OPS_HH

Generated on Tue Feb 20 20:19:50 2007 for Olena by  doxygen 1.5.1