Initial commit
This commit is contained in:
138
Lib/Include/CML/et/scalar_ops.h
Normal file
138
Lib/Include/CML/et/scalar_ops.h
Normal file
@@ -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 <cml/et/traits.h>
|
||||
#include <cml/et/scalar_promotions.h>
|
||||
|
||||
/** Declare a unary scalar operator, like negation. */
|
||||
#define CML_UNARY_SCALAR_OP(_op_, _op_name_) \
|
||||
template<typename ArgT> struct _op_name_ { \
|
||||
typedef ExprTraits<ArgT> 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<typename LeftT, typename RightT> struct _op_name_ { \
|
||||
typedef ExprTraits<LeftT> left_traits; \
|
||||
typedef ExprTraits<RightT> 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<left_value,right_value>::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<LeftT>::reference must specify
|
||||
* a type that allows assignment.
|
||||
*/
|
||||
#define CML_BINARY_SCALAR_OP_ASSIGN(_op_, _op_name_) \
|
||||
template<typename LeftT, typename RightT> struct _op_name_ { \
|
||||
typedef ExprTraits<LeftT> left_traits; \
|
||||
typedef ExprTraits<RightT> 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<left_value,right_value>::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<typename LeftT, typename RightT> struct _op_name_ { \
|
||||
typedef ExprTraits<LeftT> left_traits; \
|
||||
typedef ExprTraits<RightT> 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
|
||||
Reference in New Issue
Block a user