scalar_ops.h

Go to the documentation of this file.
00001 /* -*- C++ -*- ------------------------------------------------------------
00002  
00003 Copyright (c) 2007 Jesse Anders and Demian Nave http://cmldev.net/
00004 
00005 The Configurable Math Library (CML) is distributed under the terms of the
00006 Boost Software License, v1.0 (see cml/LICENSE for details).
00007 
00008  *-----------------------------------------------------------------------*/
00013 #ifndef ops_h
00014 #define ops_h
00015 
00016 #include <cml/et/traits.h>
00017 #include <cml/et/scalar_promotions.h>
00018 
00020 #define CML_UNARY_SCALAR_OP(_op_, _op_name_)                            \
00021 template<typename ArgT> struct _op_name_ {                              \
00022     typedef ExprTraits<ArgT> arg_traits;                                \
00023     typedef typename arg_traits::const_reference arg_reference;         \
00024     typedef typename arg_traits::value_type value_type;                 \
00025     typedef scalar_result_tag result_tag;                               \
00026     value_type apply(arg_reference arg) const { return _op_ arg; }      \
00027 };
00028 
00030 #define CML_BINARY_SCALAR_OP(_op_, _op_name_)                            \
00031 template<typename LeftT, typename RightT> struct _op_name_ {             \
00032     typedef ExprTraits<LeftT> left_traits;                               \
00033     typedef ExprTraits<RightT> right_traits;                             \
00034     typedef typename left_traits::const_reference left_reference;        \
00035     typedef typename right_traits::const_reference right_reference;      \
00036     typedef typename left_traits::value_type left_value;                 \
00037     typedef typename right_traits::value_type right_value;               \
00038     typedef typename ScalarPromote<left_value,right_value>::type value_type; \
00039     typedef scalar_result_tag result_tag;                               \
00040     value_type apply(left_reference left, right_reference right) const { \
00041         return left _op_ right; }                                        \
00042 };
00043 
00050 #define CML_BINARY_SCALAR_OP_ASSIGN(_op_, _op_name_)                     \
00051 template<typename LeftT, typename RightT> struct _op_name_ {             \
00052     typedef ExprTraits<LeftT> left_traits;                               \
00053     typedef ExprTraits<RightT> right_traits;                             \
00054     typedef typename left_traits::reference left_reference;              \
00055     typedef typename right_traits::const_reference right_reference;      \
00056     typedef typename left_traits::value_type left_value;                 \
00057     typedef typename right_traits::value_type right_value;               \
00058     typedef typename ScalarPromote<left_value,right_value>::type value_type; \
00059     typedef scalar_result_tag result_tag;                                \
00060     value_type apply(left_reference left, right_reference right) const { \
00061         return left _op_ (LeftT) right; }                                \
00062 };
00063 
00070 #define CML_BOOLEAN_SCALAR_OP(_op_, _op_name_)                           \
00071 template<typename LeftT, typename RightT> struct _op_name_ {             \
00072     typedef ExprTraits<LeftT> left_traits;                               \
00073     typedef ExprTraits<RightT> right_traits;                             \
00074     typedef typename left_traits::const_reference left_reference;        \
00075     typedef typename right_traits::const_reference right_reference;      \
00076     typedef scalar_result_tag result_tag;                                \
00077     bool apply(left_reference left, right_reference right) const {       \
00078         return left _op_ right; }                                        \
00079 };
00080 
00081 namespace cml {
00082 namespace et {
00083 
00084 /* Define the operators: */
00085 
00086 /* Unary scalar ops: */
00087 CML_UNARY_SCALAR_OP(-, OpNeg)
00088 CML_UNARY_SCALAR_OP(+, OpPos)
00089 
00090 /* Binary scalar ops: */
00091 CML_BINARY_SCALAR_OP(+, OpAdd)
00092 CML_BINARY_SCALAR_OP(-, OpSub)
00093 CML_BINARY_SCALAR_OP(*, OpMul)
00094 
00095 #if defined(CML_RECIPROCAL_OPTIMIZATION)
00096 /* XXX Yikes... this should really be written out in full. *= 1./ is the
00097  * "_op_" parameter to the macro (see above):
00098  */
00099 CML_BINARY_SCALAR_OP(* value_type(1)/, OpDiv)
00100 #else
00101 CML_BINARY_SCALAR_OP(/, OpDiv)
00102 #endif
00103 
00104 /* Binary scalar op-assigns: */
00105 CML_BINARY_SCALAR_OP_ASSIGN( =, OpAssign)
00106 CML_BINARY_SCALAR_OP_ASSIGN(+=, OpAddAssign)
00107 CML_BINARY_SCALAR_OP_ASSIGN(-=, OpSubAssign)
00108 CML_BINARY_SCALAR_OP_ASSIGN(*=, OpMulAssign)
00109 
00110 #if defined(CML_RECIPROCAL_OPTIMIZATION)
00111 /* XXX Yikes... this should really be written out in full. *= 1./ is the
00112  * "_op_" parameter to the macro (see above):
00113  */
00114 CML_BINARY_SCALAR_OP_ASSIGN(*= value_type(1)/, OpDivAssign)
00115 #else
00116 CML_BINARY_SCALAR_OP_ASSIGN(/=, OpDivAssign)
00117 #endif
00118 
00119 /* Boolean operators for scalars: */
00120 CML_BOOLEAN_SCALAR_OP(==, OpEqual)
00121 CML_BOOLEAN_SCALAR_OP(!=, OpNotEqual)
00122 CML_BOOLEAN_SCALAR_OP( <, OpLess)
00123 CML_BOOLEAN_SCALAR_OP( >, OpGreater)
00124 CML_BOOLEAN_SCALAR_OP(<=, OpLessEqual)
00125 CML_BOOLEAN_SCALAR_OP(>=, OpGreaterEqual)
00126 
00127 #undef CML_UNARY_SCALAR_OP
00128 #undef CML_BINARY_SCALAR_OP
00129 #undef CML_BINARY_SCALAR_OP_ASSIGN
00130 #undef CML_BOOLEAN_SCALAR_OP
00131 
00132 } // namespace et
00133 } // namespace cml
00134 
00135 #endif
00136 
00137 // -------------------------------------------------------------------------
00138 // vim:ft=cpp

Generated on Sat Jul 18 19:35:20 2009 for CML 1.0 by  doxygen 1.5.9