00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef MTL_MATRIX_BRACKETS_INCLUDE
00013 #define MTL_MATRIX_BRACKETS_INCLUDE
00014
00015 #include <algorithm>
00016 #include <boost/utility/enable_if.hpp>
00017 #include <boost/type_traits.hpp>
00018 #include <boost/mpl/bool.hpp>
00019 #include <boost/numeric/mtl/mtl_fwd.hpp>
00020 #include <boost/numeric/mtl/utility/irange.hpp>
00021 #include <boost/numeric/mtl/concept/collection.hpp>
00022 #include <boost/numeric/mtl/operation/column_in_matrix.hpp>
00023 #include <boost/numeric/mtl/operation/row_in_matrix.hpp>
00024
00025 namespace mtl { namespace operations {
00026
00027 template <typename Matrix, typename Ref, typename ValueRef>
00028 struct bracket_proxy
00029 {
00030 typedef typename Matrix::value_type value_type;
00031 typedef typename Matrix::size_type size_type;
00032 typedef RowInMatrix<typename boost::remove_reference<Ref>::type> row_traits;
00033
00034 explicit bracket_proxy(Ref matrix, size_type row) : matrix(matrix), row(row) {}
00035
00036 ValueRef operator[] (size_type col) { return matrix(row, col); }
00037
00038 template <typename T>
00039 typename boost::lazy_enable_if_c<boost::is_same<T, mtl::irange>::value && row_traits::exists, row_traits>::type
00040 operator[] (const T& col_range)
00041 {
00042 return row_traits::apply(matrix, row, col_range);
00043 }
00044
00045 protected:
00046 Ref matrix;
00047 size_type row;
00048 };
00049
00050 #if 0 // Doesn't compile either -> to be deleted soon
00051 template <typename T, bool ok, typename Ref, typename ValueRef> struct range_bracket_proxy_impl {};
00052
00053 template <bool ok, typename Ref, typename ValueRef>
00054 struct range_bracket_proxy_impl<irange, ok, Ref, ValueRef>
00055 {
00056 typedef ValueRef type;
00057 type static inline apply(Ref matrix, const irange& row_range, const irange& col_range)
00058 {
00059 return sub_matrix(matrix, row_range.start(), row_range.finish(),
00060 col_range.start(), col_range.finish());
00061 }
00062 };
00063
00064 template <typename T, typename Ref, typename ValueRef>
00065 struct range_bracket_proxy_impl<T, true, Ref, ValueRef>
00066 {
00067 typedef ColumnInMatrix<typename boost::remove_reference<Ref>::type> col_traits;
00068 typedef typename col_traits::type type;
00069
00070 type static inline apply(Ref matrix, const irange& row_range, const T& col)
00071 {
00072 return col_traits::apply(matrix, row_range, col);
00073 }
00074 };
00075
00076 template <typename Matrix, typename Ref, typename ValueRef>
00077 struct range_bracket_proxy
00078 {
00079 typedef typename Matrix::size_type size_type;
00080 typedef ColumnInMatrix<typename boost::remove_reference<Ref>::type> col_traits;
00081
00082 explicit range_bracket_proxy(Ref matrix, const irange& row_range) : matrix(matrix), row_range(row_range) {}
00083
00084 template <typename T>
00085 typename range_bracket_proxy_impl<T, boost::is_integral<T>::value && col_traits::exists, Ref, ValueRef>::type operator[] (const T& col)
00086 { return range_bracket_proxy_impl<T, boost::is_integral<T>::value && col_traits::exists, Ref, ValueRef>::apply(matrix, row_range, col); }
00087
00088 protected:
00089 Ref matrix;
00090 irange row_range;
00091 };
00092 #endif
00093
00094
00095 #if 1 // Doesn't compile on Intel!!!
00096 template <typename Matrix, typename Ref, typename ValueRef>
00097 struct range_bracket_proxy
00098 {
00099 typedef typename Matrix::size_type size_type;
00100 typedef ColumnInMatrix<typename boost::remove_reference<Ref>::type> col_traits;
00101
00102 explicit range_bracket_proxy(Ref matrix, const irange& row_range) : matrix(matrix), row_range(row_range) {}
00103
00104 ValueRef operator[] (const irange& col_range)
00105 {
00106 return sub_matrix(matrix, row_range.start(), row_range.finish(),
00107 col_range.start(), col_range.finish());
00108 }
00109
00110 template <typename T>
00111 typename boost::lazy_enable_if_c<boost::is_integral<T>::value && col_traits::exists, col_traits>::type
00112 operator[] (T col) { return col_traits::apply(matrix, row_range, col); }
00113
00114 protected:
00115 Ref matrix;
00116 irange row_range;
00117 };
00118 #endif
00119
00120
00121
00122
00123 }
00124
00125 }
00126
00127 #endif // MTL_MATRIX_BRACKETS_INCLUDE