00001 #ifndef VIENNAMATH_COMPILETIME_OPERATIONS_CT_EXPR_HPP
00002 #define VIENNAMATH_COMPILETIME_OPERATIONS_CT_EXPR_HPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "viennamath/forwards.h"
00021
00022
00023 #include "viennamath/compiletime/ct_binary_expr.hpp"
00024
00025
00030 namespace viennamath
00031 {
00033
00035 template <typename ScalarType, long value_1, typename RHS, long value_2>
00036 ct_binary_expr<ct_constant< value_1 + value_2 >,
00037 op_plus<ScalarType>,
00038 RHS >
00039 operator+(ct_binary_expr<ct_constant<value_1>, op_plus<ScalarType>, RHS> const & lhs,
00040 ct_constant<value_2> const & other)
00041 {
00042 return ct_binary_expr<ct_constant< value_1 + value_2 >,
00043 op_plus<ScalarType>,
00044 RHS >(ct_constant< value_1 + value_2 >(),
00045 lhs.rhs());
00046 }
00047
00048
00050 template <typename ScalarType, long value_1, typename RHS, long value_2>
00051 ct_binary_expr<ct_constant< value_1 + value_2 >,
00052 op_minus<ScalarType>,
00053 RHS >
00054 operator+(ct_binary_expr<ct_constant<value_1>, op_minus<ScalarType>, RHS> const & lhs,
00055 ct_constant<value_2> const & other)
00056 {
00057 return ct_binary_expr<ct_constant< value_1 + value_2 >,
00058 op_minus<ScalarType>,
00059 RHS >(ct_constant< value_1 + value_2 >(),
00060 lhs.rhs());
00061 }
00062
00064 template <typename ScalarType, typename OtherScalarType, typename RHS, long value>
00065 ct_binary_expr< rt_constant<typename promote_traits<OtherScalarType, op_plus<ScalarType>, long>::result_type >,
00066 op_minus<ScalarType>,
00067 RHS >
00068 operator+(ct_binary_expr<rt_constant<OtherScalarType>, op_minus<ScalarType>, RHS> const & lhs,
00069 ct_constant<value> const & other)
00070 {
00071 typedef rt_constant< typename promote_traits<OtherScalarType, op_plus<ScalarType>, long>::result_type > result_constant;
00072 return ct_binary_expr<result_constant,
00073 op_minus<ScalarType>,
00074 RHS >(result_constant(static_cast<OtherScalarType>(lhs.lhs()) + value),
00075 lhs.rhs());
00076 }
00077
00078
00080
00082 template <typename ScalarType, id_type id, typename RHS>
00083 RHS
00084 operator-(ct_binary_expr<ct_variable<id>, op_plus<ScalarType>, RHS> const & lhs,
00085 ct_variable<id> const & other)
00086 {
00087 return lhs.rhs();
00088 }
00089
00090
00092 template <long value_1, typename RHS, long value_2, typename T>
00093 ct_binary_expr< ct_constant< value_1 - value_2 >,
00094 op_plus<T>,
00095 RHS >
00096 operator-(ct_binary_expr<ct_constant<value_1>, op_plus<T>, RHS> const & lhs,
00097 ct_constant<value_2> const & other)
00098 {
00099 return ct_binary_expr<ct_constant< value_1 - value_2 >,
00100 op_plus<T>,
00101 RHS >(ct_constant< value_1 - value_2 >(),
00102 lhs.rhs());
00103 }
00104
00106 template <typename OtherScalarType, typename RHS, long value, typename T>
00107 ct_binary_expr< rt_constant<typename promote_traits<OtherScalarType, op_plus<T>, long>::result_type >,
00108 op_plus<T>,
00109 RHS >
00110 operator-(ct_binary_expr<rt_constant<OtherScalarType>, op_plus<T>, RHS> const & lhs,
00111 ct_constant<value> const & other)
00112 {
00113 typedef rt_constant< typename promote_traits<OtherScalarType, op_plus<T>, long>::result_type > result_constant;
00114 return ct_binary_expr<result_constant,
00115 op_plus<T>,
00116 RHS >(result_constant(static_cast<OtherScalarType>(lhs.lhs()) - value),
00117 lhs.rhs());
00118 }
00119
00121 template <long value_1, typename RHS, long value_2, typename T>
00122 ct_binary_expr< ct_constant< value_1 - value_2 >,
00123 op_minus<T>,
00124 RHS >
00125 operator-(ct_binary_expr<ct_constant<value_1>, op_minus<T>, RHS> const & lhs,
00126 ct_constant<value_2> const & other)
00127 {
00128 return ct_binary_expr<ct_constant< value_1 - value_2 >,
00129 op_minus<T>,
00130 RHS >(ct_constant< value_1 - value_2 >(),
00131 lhs.rhs());
00132 }
00133
00135 template <typename OtherScalarType, typename RHS, long value, typename T>
00136 ct_binary_expr< rt_constant<typename promote_traits<OtherScalarType, op_plus<T>, long>::result_type >,
00137 op_minus<T>,
00138 RHS >
00139 operator-(ct_binary_expr<rt_constant<OtherScalarType>, op_minus<T>, RHS> const & lhs,
00140 ct_constant<value> const & other)
00141 {
00142 typedef rt_constant< typename promote_traits<OtherScalarType, op_plus<T>, long>::result_type > result_constant;
00143 return ct_binary_expr<result_constant,
00144 op_minus<T>,
00145 RHS >(result_constant(static_cast<OtherScalarType>(lhs.lhs()) - value),
00146 lhs.rhs());
00147 }
00148
00149
00150
00152
00153
00154
00156
00158 template <typename LHS, typename OP, typename RHS>
00159 ct_constant<1>
00160 operator/(ct_binary_expr<LHS, OP, RHS> const & lhs,
00161 ct_binary_expr<LHS, OP, RHS> const & other)
00162 {
00163 return ct_constant<1>();
00164 }
00165
00166 }
00167
00168 #endif