Go to the documentation of this file.
   38 #ifndef NEKTAR_LIB_UTILITIES_BASIC_UTILS_OPERATOR_GENERATORS_HPP 
   39 #define NEKTAR_LIB_UTILITIES_BASIC_UTILS_OPERATOR_GENERATORS_HPP 
   41 #include <boost/preprocessor/repetition/enum_binary_params.hpp> 
   42 #include <boost/preprocessor/control/expr_if.hpp> 
   43 #include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp> 
   44 #include <boost/preprocessor/control/if.hpp> 
   45 #include <boost/preprocessor/logical/and.hpp> 
   46 #include <boost/preprocessor/logical/or.hpp> 
   47 #include <boost/preprocessor/comparison/greater.hpp> 
   48 #include <boost/preprocessor/repetition/enum_params.hpp> 
   49 #include <boost/preprocessor/stringize.hpp> 
   50 #include <boost/preprocessor/tuple/eat.hpp> 
   52 #include <ExpressionTemplates/Operators.hpp> 
   54 #ifdef NEKTAR_USE_EXPRESSION_TEMPLATES 
   55 #include <ExpressionTemplates/Node.hpp> 
   56 #endif //NEKTAR_USE_EXPRESSION_TEMPLATES 
   61     #define TEMPLATE() template< 
   62     #define CLOSE_TEMPLATE() >  
   64     #define NEKTAR_TYPENAME() typename  
   65     #define SHOW_TYPENAME(LhsNumber, RhsNumber) \ 
   66         BOOST_PP_IF( BOOST_PP_OR(BOOST_PP_GREATER(LhsNumber,0), BOOST_PP_GREATER(RhsNumber,0)), NEKTAR_TYPENAME, BOOST_PP_EMPTY)() 
   68     #define PP_ENUM_TWO_SETS_OF_TYPES(LhsTypeName, LhsNumber, RhsTypeName, RhsNumber) \ 
   69         BOOST_PP_IF( BOOST_PP_OR(BOOST_PP_GREATER(LhsNumber,0), BOOST_PP_GREATER(RhsNumber,0)), TEMPLATE, BOOST_PP_EMPTY)() \ 
   70         BOOST_PP_ENUM_PARAMS(LhsNumber, typename LhsTypeName) \ 
   71         BOOST_PP_COMMA_IF(BOOST_PP_AND(BOOST_PP_GREATER(LhsNumber,0), BOOST_PP_GREATER(RhsNumber,0))) \ 
   72         BOOST_PP_ENUM_PARAMS(RhsNumber, typename RhsTypeName) \ 
   73         BOOST_PP_IF( BOOST_PP_OR(BOOST_PP_GREATER(LhsNumber,0), BOOST_PP_GREATER(RhsNumber,0)), CLOSE_TEMPLATE, BOOST_PP_EMPTY)()  
   75     #define GET_TEMPLATED_TYPE(TypeName, TemplateTypeName, Number) TypeName<BOOST_PP_ENUM_PARAMS(Number, TemplateTypeName)> 
   77     #define GET_TYPE(TypeName, TemplateTypeName, Number) \ 
   78         BOOST_PP_IF(BOOST_PP_GREATER(Number, 0), GET_TEMPLATED_TYPE, TypeName BOOST_PP_TUPLE_EAT(3))(TypeName, TemplateTypeName, Number) 
   80     #define DECLARE_MULTIPLICATION_OPERATOR(LeftType, NumLeftParams, RightType, NumRightParams) \ 
   81          PP_ENUM_TWO_SETS_OF_TYPES(LhsType, NumLeftParams, RhsType, NumRightParams) \ 
   82          expt::Node<expt::Node<GET_TYPE(LeftType, LhsType, NumLeftParams) >, expt::MultiplyOp, expt::Node<GET_TYPE(RightType, RhsType, NumRightParams) > > \ 
   83          operator*(const GET_TYPE(LeftType, LhsType, NumLeftParams)& lhs, \ 
   84                const GET_TYPE(RightType, RhsType, NumRightParams)& rhs); 
   86      #define DECLARE_DIVISION_OPERATOR(LeftType, NumLeftParams, RightType, NumRightParams) \ 
   87          PP_ENUM_TWO_SETS_OF_TYPES(LhsType, NumLeftParams, RhsType, NumRightParams) \ 
   88          expt::Node<expt::Node<GET_TYPE(LeftType, LhsType, NumLeftParams) >, expt::DivideOp, expt::Node<GET_TYPE(RightType, RhsType, NumRightParams) > >  \ 
   89          operator/(const GET_TYPE(LeftType, LhsType, NumLeftParams)& lhs, \ 
   90                const GET_TYPE(RightType, RhsType, NumRightParams)& rhs); 
   92      #define DECLARE_ADDITION_OPERATOR(LeftType, NumLeftParams, RightType, NumRightParams) \ 
   93          PP_ENUM_TWO_SETS_OF_TYPES(LhsType, NumLeftParams, RhsType, NumRightParams) \ 
   94          expt::Node<expt::Node<GET_TYPE(LeftType, LhsType, NumLeftParams) >, expt::AddOp, expt::Node<GET_TYPE(RightType, RhsType, NumRightParams) > > \ 
   95          operator+(const GET_TYPE(LeftType, LhsType, NumLeftParams)& lhs, \ 
   96                const GET_TYPE(RightType, RhsType, NumRightParams)& rhs); 
   98      #define DECLARE_SUBTRACTION_OPERATOR(LeftType, NumLeftParams, RightType, NumRightParams) \ 
   99          PP_ENUM_TWO_SETS_OF_TYPES(LhsType, NumLeftParams, RhsType, NumRightParams) \ 
  100          expt::Node<expt::Node<GET_TYPE(LeftType, LhsType, NumLeftParams) >, expt::SubtractOp, expt::Node<GET_TYPE(RightType, RhsType, NumRightParams) > >  \ 
  101          operator-(const GET_TYPE(LeftType, LhsType, NumLeftParams)& lhs, \ 
  102                const GET_TYPE(RightType, RhsType, NumRightParams)& rhs); 
  104  #ifdef NEKTAR_USE_EXPRESSION_TEMPLATES 
  105      #define GENERATE_MULTIPLICATION_OPERATOR(LeftType, NumLeftParams, RightType, NumRightParams) \ 
  106          PP_ENUM_TWO_SETS_OF_TYPES(LhsType, NumLeftParams, RhsType, NumRightParams) \ 
  107          expt::Node<expt::Node<GET_TYPE(LeftType, LhsType, NumLeftParams) >, expt::MultiplyOp, expt::Node<GET_TYPE(RightType, RhsType, NumRightParams) > > \ 
  108          operator*(const GET_TYPE(LeftType, LhsType, NumLeftParams)& lhs, \ 
  109                const GET_TYPE(RightType, RhsType, NumRightParams)& rhs) \ 
  111              return expt::CreateBinaryExpression<expt::MultiplyOp>(lhs, rhs); \ 
  114      #define GENERATE_DIVISION_OPERATOR(LeftType, NumLeftParams, RightType, NumRightParams) \ 
  115          PP_ENUM_TWO_SETS_OF_TYPES(LhsType, NumLeftParams, RhsType, NumRightParams) \ 
  116          expt::Node<expt::Node<GET_TYPE(LeftType, LhsType, NumLeftParams) >, expt::DivideOp, expt::Node<GET_TYPE(RightType, RhsType, NumRightParams) > >  \ 
  117          operator/(const GET_TYPE(LeftType, LhsType, NumLeftParams)& lhs, \ 
  118                const GET_TYPE(RightType, RhsType, NumRightParams)& rhs) \ 
  120              return expt::CreateBinaryExpression<expt::DivideOp>(lhs, rhs); \ 
  123      #define GENERATE_ADDITION_OPERATOR(LeftType, NumLeftParams, RightType, NumRightParams) \ 
  124          PP_ENUM_TWO_SETS_OF_TYPES(LhsType, NumLeftParams, RhsType, NumRightParams) \ 
  125          expt::Node<expt::Node<GET_TYPE(LeftType, LhsType, NumLeftParams) >, expt::AddOp, expt::Node<GET_TYPE(RightType, RhsType, NumRightParams) > > \ 
  126          operator+(const GET_TYPE(LeftType, LhsType, NumLeftParams)& lhs, \ 
  127                const GET_TYPE(RightType, RhsType, NumRightParams)& rhs) \ 
  129              return expt::CreateBinaryExpression<expt::AddOp>(lhs, rhs); \ 
  132      #define GENERATE_SUBTRACTION_OPERATOR(LeftType, NumLeftParams, RightType, NumRightParams) \ 
  133          PP_ENUM_TWO_SETS_OF_TYPES(LhsType, NumLeftParams, RhsType, NumRightParams) \ 
  134          expt::Node<expt::Node<GET_TYPE(LeftType, LhsType, NumLeftParams) >, expt::SubtractOp, expt::Node<GET_TYPE(RightType, RhsType, NumRightParams) > >  \ 
  135          operator-(const GET_TYPE(LeftType, LhsType, NumLeftParams)& lhs, \ 
  136                const GET_TYPE(RightType, RhsType, NumRightParams)& rhs) \ 
  138              return expt::CreateBinaryExpression<expt::SubtractOp>(lhs, rhs); \ 
  141  #else //NEKTAR_USE_EXPRESSION_TEMPLATES 
  143     #define GENERATE_MULTIPLICATION_OPERATOR(LeftType, NumLeftParams, RightType, NumRightParams) \ 
  144         PP_ENUM_TWO_SETS_OF_TYPES(LhsType, NumLeftParams, RhsType, NumRightParams) \ 
  145         SHOW_TYPENAME(NumLeftParams, NumRightParams) expt::MultiplyOp::ResultType<GET_TYPE(LeftType, LhsType, NumLeftParams), GET_TYPE(RightType, RhsType, NumRightParams)>::type \ 
  146         operator*(const GET_TYPE(LeftType, LhsType, NumLeftParams)& lhs, \ 
  147               const GET_TYPE(RightType, RhsType, NumRightParams)& rhs) \ 
  149             return Multiply(lhs, rhs); \ 
  153     #define GENERATE_DIVISION_OPERATOR(LeftType, NumLeftParams, RightType, NumRightParams) \ 
  154         PP_ENUM_TWO_SETS_OF_TYPES(LhsType, NumLeftParams, RhsType, NumRightParams) \ 
  155         SHOW_TYPENAME(NumLeftParams, NumRightParams) expt::DivideOp::ResultType<GET_TYPE(LeftType, LhsType, NumLeftParams), GET_TYPE(RightType, RhsType, NumRightParams)>::type \ 
  156         operator/(const GET_TYPE(LeftType, LhsType, NumLeftParams)& lhs, \ 
  157               const GET_TYPE(RightType, RhsType, NumRightParams)& rhs) \ 
  159             return Divide(lhs, rhs); \ 
  162     #define GENERATE_ADDITION_OPERATOR(LeftType, NumLeftParams, RightType, NumRightParams) \ 
  163         PP_ENUM_TWO_SETS_OF_TYPES(LhsType, NumLeftParams, RhsType, NumRightParams) \ 
  164         SHOW_TYPENAME(NumLeftParams, NumRightParams) expt::AddOp::ResultType<GET_TYPE(LeftType, LhsType, NumLeftParams), GET_TYPE(RightType, RhsType, NumRightParams)>::type \ 
  165         operator+(const GET_TYPE(LeftType, LhsType, NumLeftParams)& lhs, \ 
  166               const GET_TYPE(RightType, RhsType, NumRightParams)& rhs) \ 
  168             return Add(lhs, rhs); \ 
  172     #define GENERATE_SUBTRACTION_OPERATOR(LeftType, NumLeftParams, RightType, NumRightParams) \ 
  173         PP_ENUM_TWO_SETS_OF_TYPES(LhsType, NumLeftParams, RhsType, NumRightParams) \ 
  174         SHOW_TYPENAME(NumLeftParams, NumRightParams) expt::SubtractOp::ResultType<GET_TYPE(LeftType, LhsType, NumLeftParams), GET_TYPE(RightType, RhsType, NumRightParams)>::type \ 
  175         operator-(const GET_TYPE(LeftType, LhsType, NumLeftParams)& lhs, \ 
  176               const GET_TYPE(RightType, RhsType, NumRightParams)& rhs) \ 
  178             return Subtract(lhs, rhs); \ 
  181 #endif //NEKTAR_USE_EXPRESSION_TEMPLATES 
  184 #endif //NEKTAR_LIB_UTILITIES_BASIC_UTILS_OPERATOR_GENERATORS_HPP