00001
00002
00003
00004
00005
00006
00007
00008
00019 #ifndef matrix_promotions_h
00020 #define matrix_promotions_h
00021
00022 #include <cml/core/cml_meta.h>
00023 #include <cml/et/scalar_promotions.h>
00024 #include <cml/et/array_promotions.h>
00025 #include <cml/fixed.h>
00026 #include <cml/dynamic.h>
00027
00028
00029
00030
00031 struct outer_promote_expects_properly_oriented_args_error;
00032
00033 namespace cml {
00034 namespace et {
00035
00037 template<typename LeftT, typename RightT> struct MatrixPromote
00038 {
00039
00040 template<typename M1, typename M2> struct MatrixPromoteHelper;
00041
00048 template<typename E1, class AT1, typename L1, typename BO1,
00049 typename E2, class AT2, typename L2, typename BO2>
00050 struct MatrixPromoteHelper<
00051 cml::matrix<E1,AT1,BO1,L1>, cml::matrix<E2,AT2,BO2,L2>
00052 >
00053 {
00054
00055 typedef typename ArrayPromote<
00056 typename cml::matrix<E1,AT1,BO1,L1>::array_type,
00057 typename cml::matrix<E2,AT2,BO2,L2>::array_type
00058 >::type promoted_array;
00059
00060
00061 typedef cml::matrix<
00062 typename promoted_array::value_type,
00063 typename promoted_array::generator_type,
00064 BO1,
00065 typename promoted_array::layout
00066 > type;
00067
00068
00069 typedef typename type::temporary_type temporary_type;
00070 };
00071
00073 template<typename E, class AT, typename BO, typename L, typename S>
00074 struct MatrixPromoteHelper<cml::matrix<E,AT,BO,L>, S>
00075 {
00076
00077 typedef cml::matrix<typename ScalarPromote<E,S>::type, AT, BO, L> type;
00078
00079
00080 typedef typename type::temporary_type temporary_type;
00081 };
00082
00084 template<typename S, typename E, class AT, typename BO, typename L>
00085 struct MatrixPromoteHelper<S, cml::matrix<E,AT,BO,L> >
00086 {
00087
00088 typedef cml::matrix<typename ScalarPromote<S,E>::type, AT, BO, L> type;
00089
00090
00091 typedef typename type::temporary_type temporary_type;
00092 };
00093
00095 template<typename E1, class AT1, typename E2, class AT2>
00096 struct MatrixPromoteHelper< cml::vector<E1,AT1>, cml::vector<E2,AT2> >
00097 {
00098 typedef cml::vector<E1,AT1> left_type;
00099 typedef cml::vector<E2,AT2> right_type;
00100 typedef CML_DEFAULT_BASIS_ORIENTATION basis_orient;
00101
00102
00103 enum {
00104 array_rows = left_type::array_size,
00105 array_cols = right_type::array_size
00106 };
00107
00108
00109 typedef CML_DEFAULT_ARRAY_LAYOUT layout;
00110 typedef typename select_if<
00111 array_rows == -1, dynamic<>, fixed<array_rows,1>
00112 >::result left_storage;
00113 typedef cml::matrix<E1,left_storage,basis_orient,layout> left_matrix;
00114
00115 typedef typename select_if<
00116 array_cols == -1, dynamic<>, fixed<1,array_cols>
00117 >::result right_storage;
00118 typedef cml::matrix<E2,right_storage,basis_orient,layout> right_matrix;
00119
00120
00121 typedef typename et::MatrixPromote<left_matrix,right_matrix>::type type;
00122 typedef typename type::temporary_type temporary_type;
00123 };
00124
00126 typedef typename remove_const<
00127 typename remove_reference<LeftT>::type>::type LeftBaseT;
00128 typedef typename remove_const<
00129 typename remove_reference<RightT>::type>::type RightBaseT;
00130
00131 typedef typename MatrixPromoteHelper<LeftBaseT,RightBaseT>::type type;
00132 typedef typename type::temporary_type temporary_type;
00133 };
00134
00141 template < class Mat1_T, class Mat2_T >
00142 struct MatrixPromote2
00143 {
00144 typedef typename MatrixPromote<
00145 typename Mat1_T::temporary_type, typename Mat2_T::temporary_type
00146 >::temporary_type temporary_type;
00147 typedef typename temporary_type::value_type value_type;
00148 };
00149
00151 template < class Mat1_T, class Mat2_T, class Mat3_T >
00152 struct MatrixPromote3
00153 {
00154 typedef typename MatrixPromote<
00155 typename Mat1_T::temporary_type,
00156 typename MatrixPromote<
00157 typename Mat2_T::temporary_type,
00158 typename Mat3_T::temporary_type
00159 >::temporary_type
00160 >::temporary_type temporary_type;
00161 typedef typename temporary_type::value_type value_type;
00162 };
00163
00165 template < class Mat1_T, class Mat2_T, class Mat3_T, class Mat4_T >
00166 struct MatrixPromote4
00167 {
00168 typedef typename MatrixPromote<
00169 typename Mat1_T::temporary_type,
00170 typename MatrixPromote<
00171 typename Mat2_T::temporary_type,
00172 typename MatrixPromote<
00173 typename Mat3_T::temporary_type,
00174 typename Mat4_T::temporary_type
00175 >::temporary_type
00176 >::temporary_type
00177 >::temporary_type temporary_type;
00178 typedef typename temporary_type::value_type value_type;
00179 };
00180
00181 }
00182 }
00183
00184 #endif
00185
00186
00187