/* -*- 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 Defines the various combinations of vector expressions. * * Create unary and binary operators with macros. The available combinations * are: * * Unary expressions: * * op Vector -> Vector * op VecXpr -> VecXpr * * Binary expressions: * * Vector op Vector -> Vector * VecXpr op Vector -> VecXpr * Vector op VecXpr -> VecXpr * VecXpr op VecXpr -> VecXpr * * Vector op Scalar -> Vector * Scalar op Vector -> Vector * VecXpr op Scalar -> VecXpr * Scalar op VecXpr -> VecXpr * * All of the generator functions compress the expression tree by hoisting * subexpressions into the containing expression. This has the effect of * forcing only the root node of the expression tree to be a VectorXpr. * Every other node is a Unary or BinaryVectorOp. * * @todo Should ScalarT in expressions be passed by reference or by value? */ #ifndef vecop_macros_h #define vecop_macros_h /** Declare a unary operator taking a vector operand. */ #define CML_VEC_UNIOP(_op_, _OpT_) \ template \ inline et::VectorXpr< \ et::UnaryVectorOp< vector, _OpT_ > \ > \ \ _op_ (const vector& arg) \ { \ typedef et::UnaryVectorOp< \ vector, _OpT_ \ > ExprT; \ return et::VectorXpr(ExprT(arg)); \ } /** Declare a unary operator taking a et::VectorXpr operand. */ #define CML_VECXPR_UNIOP(_op_, _OpT_) \ template \ inline et::VectorXpr< \ et::UnaryVectorOp< XprT, _OpT_ > \ > \ \ _op_ (VECXPR_ARG_TYPE arg) \ { \ typedef et::UnaryVectorOp< \ XprT, _OpT_ \ > ExprT; \ return et::VectorXpr(ExprT(arg.expression())); \ } /** Declare an operator taking two vector operands. */ #define CML_VEC_VEC_BINOP(_op_, _OpT_) \ template \ inline et::VectorXpr< \ et::BinaryVectorOp< \ vector, vector, _OpT_ \ > \ > \ \ _op_ ( \ const vector& left, \ const vector& right) \ { \ typedef et::BinaryVectorOp< \ vector, vector, _OpT_ \ > ExprT; \ return et::VectorXpr(ExprT(left,right)); \ } /** Declare an operator taking a vector and a et::VectorXpr. */ #define CML_VEC_VECXPR_BINOP(_op_, _OpT_) \ template \ inline et::VectorXpr< \ et::BinaryVectorOp< \ vector, XprT, _OpT_ \ > \ > \ \ _op_ ( \ const vector& left, \ VECXPR_ARG_TYPE right) \ { \ typedef et::BinaryVectorOp< \ vector, XprT, \ _OpT_ \ > ExprT; \ return et::VectorXpr(ExprT(left,right.expression())); \ } /** Declare an operator taking an et::VectorXpr and a vector. */ #define CML_VECXPR_VEC_BINOP(_op_, _OpT_) \ template \ inline et::VectorXpr< \ et::BinaryVectorOp< \ XprT, vector, _OpT_ \ > \ > \ \ _op_ ( \ VECXPR_ARG_TYPE left, \ const vector& right) \ { \ typedef et::BinaryVectorOp< \ XprT, vector, \ _OpT_ \ > ExprT; \ return et::VectorXpr(ExprT(left.expression(),right)); \ } /** Declare an operator taking two et::VectorXpr operands. */ #define CML_VECXPR_VECXPR_BINOP(_op_, _OpT_) \ template \ inline et::VectorXpr< \ et::BinaryVectorOp< \ XprT1, XprT2, \ _OpT_ < \ typename XprT1::value_type, \ typename XprT2::value_type \ > \ > \ > \ \ _op_ ( \ VECXPR_ARG_TYPE_N(1) left, \ VECXPR_ARG_TYPE_N(2) right) \ { \ typedef et::BinaryVectorOp< \ XprT1, XprT2, \ _OpT_ < \ typename XprT1::value_type, \ typename XprT2::value_type> \ > ExprT; \ return et::VectorXpr( \ ExprT(left.expression(),right.expression())); \ } /** Declare an operator taking a vector and a scalar. */ #define CML_VEC_SCALAR_BINOP(_op_, _OpT_) \ template \ inline et::VectorXpr< \ et::BinaryVectorOp< \ vector, ScalarT, _OpT_ \ > \ > \ \ _op_ ( \ const vector& left, \ SCALAR_ARG_TYPE right) \ { \ typedef et::BinaryVectorOp< \ vector, ScalarT, _OpT_ \ > ExprT; \ return et::VectorXpr(ExprT(left,right)); \ } /** Declare an operator taking a scalar and a vector. */ #define CML_SCALAR_VEC_BINOP(_op_, _OpT_) \ template \ inline et::VectorXpr< \ et::BinaryVectorOp< \ ScalarT, vector, _OpT_ \ > \ > \ \ _op_ ( \ SCALAR_ARG_TYPE left, \ const vector& right) \ { \ typedef et::BinaryVectorOp< \ ScalarT, vector, _OpT_ \ > ExprT; \ return et::VectorXpr(ExprT(left,right)); \ } /** Declare an operator taking a et::VectorXpr and a scalar. */ #define CML_VECXPR_SCALAR_BINOP(_op_, _OpT_) \ template \ inline et::VectorXpr< \ et::BinaryVectorOp< \ XprT, ScalarT, _OpT_ \ > \ > \ \ _op_ ( \ VECXPR_ARG_TYPE left, \ SCALAR_ARG_TYPE right) \ { \ typedef et::BinaryVectorOp< \ XprT, ScalarT, _OpT_ \ > ExprT; \ return et::VectorXpr(ExprT(left.expression(),right)); \ } /** Declare an operator taking a scalar and a et::VectorXpr. */ #define CML_SCALAR_VECXPR_BINOP(_op_, _OpT_) \ template \ inline et::VectorXpr< \ et::BinaryVectorOp< \ ScalarT, XprT, _OpT_ \ > \ > \ \ _op_ ( \ SCALAR_ARG_TYPE left, \ VECXPR_ARG_TYPE right) \ { \ typedef et::BinaryVectorOp< \ ScalarT, XprT, \ _OpT_ \ > ExprT; \ return et::VectorXpr(ExprT(left,right.expression())); \ } #endif // ------------------------------------------------------------------------- // vim:ft=cpp