X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2FMoof%2Fcml%2Fet%2Fscalar_ops.h;fp=src%2FMoof%2Fcml%2Fet%2Fscalar_ops.h;h=6bd236d5324bcaf2cf2acd66a92aa97f4ff45b5f;hp=0000000000000000000000000000000000000000;hb=c2321281bf12a7efaedde930422c7ddbc92080d4;hpb=87bc17e55b0c1dc73ecc66df856d3f08fd7a7724 diff --git a/src/Moof/cml/et/scalar_ops.h b/src/Moof/cml/et/scalar_ops.h new file mode 100644 index 0000000..6bd236d --- /dev/null +++ b/src/Moof/cml/et/scalar_ops.h @@ -0,0 +1,138 @@ +/* -*- C++ -*- ------------------------------------------------------------ + +Copyright (c) 2007 Jesse Anders and Demian Nave http://cmldev.net/ + +The Configurable Math Library (CML) is distributed under the terms of the +Boost Software License, v1.0 (see cml/LICENSE for details). + + *-----------------------------------------------------------------------*/ +/** @file + * @brief + */ + +#ifndef ops_h +#define ops_h + +#include +#include + +/** Declare a unary scalar operator, like negation. */ +#define CML_UNARY_SCALAR_OP(_op_, _op_name_) \ +template struct _op_name_ { \ + typedef ExprTraits arg_traits; \ + typedef typename arg_traits::const_reference arg_reference; \ + typedef typename arg_traits::value_type value_type; \ + typedef scalar_result_tag result_tag; \ + value_type apply(arg_reference arg) const { return _op_ arg; } \ +}; + +/** Declare a binary scalar operator, like addition, s1+s2. */ +#define CML_BINARY_SCALAR_OP(_op_, _op_name_) \ +template struct _op_name_ { \ + typedef ExprTraits left_traits; \ + typedef ExprTraits right_traits; \ + typedef typename left_traits::const_reference left_reference; \ + typedef typename right_traits::const_reference right_reference; \ + typedef typename left_traits::value_type left_value; \ + typedef typename right_traits::value_type right_value; \ + typedef typename ScalarPromote::type value_type; \ + typedef scalar_result_tag result_tag; \ + value_type apply(left_reference left, right_reference right) const { \ + return left _op_ right; } \ +}; + +/** Declare an op-assignment operator. + * + * @note The ExprTraits for both argument types must be defined, LeftT must + * have an assignment operator, and ExprTraits::reference must specify + * a type that allows assignment. + */ +#define CML_BINARY_SCALAR_OP_ASSIGN(_op_, _op_name_) \ +template struct _op_name_ { \ + typedef ExprTraits left_traits; \ + typedef ExprTraits right_traits; \ + typedef typename left_traits::reference left_reference; \ + typedef typename right_traits::const_reference right_reference; \ + typedef typename left_traits::value_type left_value; \ + typedef typename right_traits::value_type right_value; \ + typedef typename ScalarPromote::type value_type; \ + typedef scalar_result_tag result_tag; \ + value_type apply(left_reference left, right_reference right) const { \ + return left _op_ (LeftT) right; } \ +}; + +/** Declare a binary boolean operator, like less-than, s1 < s2. + * + * The operator should return the appropriate truth value for the operator. + * + * @note Both scalar types must have operator<() defined. + */ +#define CML_BOOLEAN_SCALAR_OP(_op_, _op_name_) \ +template struct _op_name_ { \ + typedef ExprTraits left_traits; \ + typedef ExprTraits right_traits; \ + typedef typename left_traits::const_reference left_reference; \ + typedef typename right_traits::const_reference right_reference; \ + typedef scalar_result_tag result_tag; \ + bool apply(left_reference left, right_reference right) const { \ + return left _op_ right; } \ +}; + +namespace cml { +namespace et { + +/* Define the operators: */ + +/* Unary scalar ops: */ +CML_UNARY_SCALAR_OP(-, OpNeg) +CML_UNARY_SCALAR_OP(+, OpPos) + +/* Binary scalar ops: */ +CML_BINARY_SCALAR_OP(+, OpAdd) +CML_BINARY_SCALAR_OP(-, OpSub) +CML_BINARY_SCALAR_OP(*, OpMul) + +#if defined(CML_RECIPROCAL_OPTIMIZATION) +/* XXX Yikes... this should really be written out in full. *= 1./ is the + * "_op_" parameter to the macro (see above): + */ +CML_BINARY_SCALAR_OP(* value_type(1)/, OpDiv) +#else +CML_BINARY_SCALAR_OP(/, OpDiv) +#endif + +/* Binary scalar op-assigns: */ +CML_BINARY_SCALAR_OP_ASSIGN( =, OpAssign) +CML_BINARY_SCALAR_OP_ASSIGN(+=, OpAddAssign) +CML_BINARY_SCALAR_OP_ASSIGN(-=, OpSubAssign) +CML_BINARY_SCALAR_OP_ASSIGN(*=, OpMulAssign) + +#if defined(CML_RECIPROCAL_OPTIMIZATION) +/* XXX Yikes... this should really be written out in full. *= 1./ is the + * "_op_" parameter to the macro (see above): + */ +CML_BINARY_SCALAR_OP_ASSIGN(*= value_type(1)/, OpDivAssign) +#else +CML_BINARY_SCALAR_OP_ASSIGN(/=, OpDivAssign) +#endif + +/* Boolean operators for scalars: */ +CML_BOOLEAN_SCALAR_OP(==, OpEqual) +CML_BOOLEAN_SCALAR_OP(!=, OpNotEqual) +CML_BOOLEAN_SCALAR_OP( <, OpLess) +CML_BOOLEAN_SCALAR_OP( >, OpGreater) +CML_BOOLEAN_SCALAR_OP(<=, OpLessEqual) +CML_BOOLEAN_SCALAR_OP(>=, OpGreaterEqual) + +#undef CML_UNARY_SCALAR_OP +#undef CML_BINARY_SCALAR_OP +#undef CML_BINARY_SCALAR_OP_ASSIGN +#undef CML_BOOLEAN_SCALAR_OP + +} // namespace et +} // namespace cml + +#endif + +// ------------------------------------------------------------------------- +// vim:ft=cpp