00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef MTL_ROW_IN_MATRIX_INCLUDE
00013 #define MTL_ROW_IN_MATRIX_INCLUDE
00014
00015 #include <boost/mpl/if.hpp>
00016 #include <boost/numeric/mtl/mtl_fwd.hpp>
00017 #include <boost/numeric/mtl/vector/parameter.hpp>
00018 #include <boost/numeric/mtl/utility/irange.hpp>
00019
00020 namespace mtl {
00021
00023 template <typename Matrix>
00024 struct RowInMatrix
00025 {
00026 static const bool exists= false;
00027 };
00028
00029 template <typename Value, typename Parameters>
00030 struct RowInMatrix<mtl::matrix::dense2D<Value, Parameters> >
00031 {
00032 typedef mtl::matrix::dense2D<Value, Parameters> ref_type;
00033 typedef typename ref_type::size_type size_type;
00034 typedef typename ref_type::value_type value_type;
00035 typedef mtl::vector::parameters<row_major> vec_para;
00036
00037 static const bool aligned= boost::is_same<typename Parameters::orientation, row_major>::value;
00038 static const bool exists= true;
00039
00040 typedef typename boost::mpl::if_c<
00041 aligned
00042 , mtl::vector::dense_vector<Value, vec_para>
00043 , mtl::vector::strided_vector_ref<Value, vec_para>
00044 >::type type;
00045
00046 static inline type apply(ref_type& A, size_type row, const irange& col_range)
00047 {
00048 return dispatch<type, ref_type>(A, row, col_range, boost::mpl::bool_<aligned>());
00049 }
00050
00051 template <typename Ref>
00052 static inline size_type vector_size(const Ref& A, const irange& col_range)
00053 {
00054 using std::min;
00055 size_type finish= min(col_range.finish(), num_cols(A));
00056 return col_range.start() < finish ? finish - col_range.start() : 0;
00057 }
00058
00059 template <typename Return, typename Ref>
00060 static inline Return dispatch(Ref& A, size_type row, const irange& col_range, boost::mpl::true_)
00061 {
00062 return Return(vector_size(A, col_range), const_cast<value_type*>(&A[row][col_range.start()]));
00063 }
00064
00065 template <typename Return, typename Ref>
00066 static inline Return dispatch(Ref& A, size_type row, const irange& col_range, boost::mpl::false_)
00067 {
00068 return Return(vector_size(A, col_range), &A[row][col_range.start()], num_rows(A));
00069 }
00070 };
00071
00072 template <typename Value, typename Parameters>
00073 struct RowInMatrix<const dense2D<Value, Parameters> >
00074 {
00075 typedef dense2D<Value, Parameters> const ref_type;
00076 typedef dense2D<Value, Parameters> ref2_type;
00077 typedef typename ref2_type::size_type size_type;
00078 typedef vector::parameters<row_major> vec_para;
00079
00080 static const bool aligned= boost::is_same<typename Parameters::orientation, row_major>::value;
00081 static const bool exists= true;
00082
00083 typedef typename boost::mpl::if_c<
00084 aligned
00085 , vector::dense_vector<Value, vec_para>
00086 , vector::strided_vector_ref<const Value, vec_para>
00087 >::type type;
00088
00089 static inline type apply(ref_type& A, size_type row, const irange& col_range)
00090 {
00091 return RowInMatrix<ref2_type>::template dispatch<type, ref_type>(A, row, col_range, boost::mpl::bool_<aligned>());
00092 }
00093 };
00094
00095
00096 }
00097
00098 #endif // MTL_ROW_IN_MATRIX_INCLUDE