scalar_ops.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
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
00085
00086
00087 CML_UNARY_SCALAR_OP(-, OpNeg)
00088 CML_UNARY_SCALAR_OP(+, OpPos)
00089
00090
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
00097
00098
00099 CML_BINARY_SCALAR_OP(* value_type(1)/, OpDiv)
00100 #else
00101 CML_BINARY_SCALAR_OP(/, OpDiv)
00102 #endif
00103
00104
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
00112
00113
00114 CML_BINARY_SCALAR_OP_ASSIGN(*= value_type(1)/, OpDivAssign)
00115 #else
00116 CML_BINARY_SCALAR_OP_ASSIGN(/=, OpDivAssign)
00117 #endif
00118
00119
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 }
00133 }
00134
00135 #endif
00136
00137
00138