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