matrix_promotions.h

Go to the documentation of this file.
00001 /* -*- C++ -*- ------------------------------------------------------------
00002  
00003 Copyright (c) 2007 Jesse Anders and Demian Nave http://cmldev.net/
00004 
00005 The Configurable Math Library (CML) is distributed under the terms of the
00006 Boost Software License, v1.0 (see cml/LICENSE for details).
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 /* This is used below to create a more meaningful compile-time error when
00029  * either argument to OuterPromote has the wrong orientation.
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     /* Default matrix type promotion template. */
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         /* Promote the arrays: */
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         /* The deduced matrix result type: */
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         /* The deduced temporary type: */
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         /* The deduced matrix result type (the array type is the same): */
00077         typedef cml::matrix<typename ScalarPromote<E,S>::type, AT, BO, L> type;
00078 
00079         /* The deduced temporary type: */
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         /* The deduced matrix result type (the array type is the same): */
00088         typedef cml::matrix<typename ScalarPromote<S,E>::type, AT, BO, L> type;
00089 
00090         /* The deduced temporary type: */
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         /* Get matrix size: */
00103         enum {
00104             array_rows = left_type::array_size,
00105             array_cols = right_type::array_size
00106         };
00107 
00108         /* Deduce the corresponding matrix types for the vectors: */
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         /* Finally, promote the matrix types to get the result: */
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 } // namespace et
00182 } // namespace cml
00183 
00184 #endif
00185 
00186 // -------------------------------------------------------------------------
00187 // vim:ft=cpp

Generated on Sat Jul 18 19:35:25 2009 for CML 1.0 by  doxygen 1.5.9