00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef MTL_COLUMN_IN_MATRIX_INCLUDE
00013 #define MTL_COLUMN_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
00022
00024 template <typename Matrix>
00025 struct ColumnInMatrix
00026 {
00027 static const bool exists= false;
00028 };
00029
00030 template <typename Value, typename Parameters>
00031 struct ColumnInMatrix<dense2D<Value, Parameters> >
00032 {
00033 typedef dense2D<Value, Parameters> ref_type;
00034 typedef typename ref_type::size_type size_type;
00035 typedef typename ref_type::value_type value_type;
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 , vector::dense_vector<Value, vector::parameters<> >
00043 , vector::strided_vector_ref<Value, vector::parameters<> >
00044 >::type type;
00045
00046 static inline type apply(ref_type& A, const irange& row_range, size_type col)
00047 {
00048 return dispatch<type, ref_type>(A, row_range, col, boost::mpl::bool_<aligned>());
00049 }
00050
00051 template <typename Ref>
00052 static inline size_type vector_size(const Ref& A, const irange& row_range)
00053 {
00054 using std::min;
00055 size_type finish= min(row_range.finish(), num_rows(A));
00056 return row_range.start() < finish ? finish - row_range.start() : 0;
00057 }
00058
00059 template <typename Return, typename Ref>
00060 static inline Return dispatch(Ref& A, const irange& row_range, size_type col, boost::mpl::true_)
00061 {
00062 return Return(vector_size(A, row_range), const_cast<value_type*>(&A[row_range.start()][col]));
00063 }
00064
00065 template <typename Return, typename Ref>
00066 static inline Return dispatch(Ref& A, const irange& row_range, size_type col, boost::mpl::false_)
00067 {
00068 return Return(vector_size(A, row_range), &A[row_range.start()][col], num_cols(A));
00069 }
00070 };
00071
00072 template <typename Value, typename Parameters>
00073 struct ColumnInMatrix<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
00079 static const bool aligned= !boost::is_same<typename Parameters::orientation, row_major>::value;
00080 static const bool exists= true;
00081
00082 typedef typename boost::mpl::if_c<
00083 aligned
00084 , vector::dense_vector<Value, vector::parameters<> >
00085 , vector::strided_vector_ref<const Value, vector::parameters<> >
00086 >::type type;
00087
00088 static inline type apply(ref_type& A, const irange& row_range, size_type col)
00089 {
00090 return ColumnInMatrix<ref2_type>::template dispatch<type, ref_type>(A, row_range, col, boost::mpl::bool_<aligned>());
00091 }
00092 };
00093
00094 }
00095
00096 #endif // MTL_COLUMN_IN_MATRIX_INCLUDE