00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef MTL_DETAIL_RANGE_GENERATOR_INCLUDE
00013 #define MTL_DETAIL_RANGE_GENERATOR_INCLUDE
00014
00015 #include <boost/numeric/mtl/mtl_fwd.hpp>
00016 #include <boost/numeric/mtl/concept/collection.hpp>
00017 #include <boost/numeric/mtl/utility/glas_tag.hpp>
00018 #include <boost/numeric/mtl/utility/complexity.hpp>
00019 #include <boost/numeric/mtl/detail/base_cursor.hpp>
00020 #include <boost/mpl/less.hpp>
00021
00022 namespace mtl { namespace traits { namespace detail {
00023
00025
00028 template <typename Collection, typename Cursor, typename Complexity>
00029 struct dense_element_range_generator
00030 {
00031 typedef Complexity complexity;
00032 typedef Cursor type;
00033 static int const level = 1;
00034
00035 type begin(Collection const& collection)
00036 {
00037 return collection.elements();
00038 }
00039 type end(Collection const& collection)
00040 {
00041 return collection.elements() + collection.used_memory();
00042 }
00043 };
00044
00046 template <typename Collection, typename Ref, typename Traversor>
00047 struct strided_element_range_generator
00048 {
00049 typedef complexity_classes::linear complexity;
00050 typedef Traversor type;
00051 static int const level = 1;
00052
00053 type begin(Ref& c)
00054 {
00055 return type(c.address_data(), c.stride());
00056 }
00057 type end(Ref& c)
00058 {
00059 using mtl::size;
00060 return type(c.address_data() + size(c) + c.stride(), c.stride());
00061 }
00062 };
00063
00064
00065
00066
00067 template <typename Matrix, typename Cursor, typename Complexity>
00068 struct all_offsets_range_generator
00069 {
00070 typedef Complexity complexity;
00071 typedef Cursor type;
00072 static int const level = 1;
00073
00074 type begin(Matrix const& matrix) const
00075 {
00076 return type(matrix, 0);
00077 }
00078 type end(Matrix const& matrix) const
00079 {
00080 return type(matrix, matrix.nnz());
00081 }
00082 };
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 template <typename Matrix, typename Tag, int Level>
00094 struct sub_matrix_cursor
00095 : mtl::detail::base_cursor<int>
00096 {
00097 typedef sub_matrix_cursor self;
00098 typedef mtl::detail::base_cursor<int> base;
00099 static int const level = Level;
00100
00101 sub_matrix_cursor(int i, Matrix const& c)
00102 : base(i), ref(c)
00103 {}
00104
00105 self operator+(int offset) const
00106 {
00107 return self(key + offset, ref);
00108 }
00109
00110 Matrix const& ref;
00111 };
00112
00113
00114 template <typename Matrix, typename Complexity, int Level>
00115 struct all_rows_range_generator
00116 {
00117 typedef Complexity complexity;
00118 static int const level = Level;
00119 typedef sub_matrix_cursor<Matrix, glas::tag::row, Level> type;
00120 typedef typename Collection<Matrix>::size_type size_type;
00121
00122 type begin(Matrix const& c)
00123 {
00124 return type(c.begin_row(), c);
00125 }
00126 type end(Matrix const& c)
00127 {
00128 return type(c.end_row(), c);
00129 }
00130 type lower_bound(Matrix const& c, size_type position)
00131 {
00132 return type(std::min(c.end_row(), position), c);
00133 }
00134 };
00135
00136
00137 template <typename Matrix, typename Complexity, int Level>
00138 struct all_cols_range_generator
00139 {
00140 typedef Complexity complexity;
00141 static int const level = Level;
00142 typedef sub_matrix_cursor<Matrix, glas::tag::col, Level> type;
00143 typedef typename Collection<Matrix>::size_type size_type;
00144
00145 type begin(Matrix const& c)
00146 {
00147 return type(c.begin_col(), c);
00148 }
00149 type end(Matrix const& c)
00150 {
00151 return type(c.end_col(), c);
00152 }
00153 type lower_bound(Matrix const& c, size_type position)
00154 {
00155 return type(std::min(c.end_col(), position), c);
00156 }
00157 };
00158
00159
00160 template <typename Coll, typename RangeGenerator>
00161 struct referred_range_generator
00162 {
00163 typedef typename RangeGenerator::complexity complexity;
00164 static int const level = RangeGenerator::level;
00165 typedef typename RangeGenerator::type type;
00166 typedef typename Collection<Coll>::size_type size_type;
00167
00168 type begin(const Coll& c)
00169 {
00170 return RangeGenerator().begin(c.ref);
00171 }
00172
00173 type end(const Coll& c)
00174 {
00175 return RangeGenerator().end(c.ref);
00176 }
00177 type lower_bound(const Coll& c, size_type position)
00178 {
00179 return RangeGenerator().lower_bound(c.ref, position);
00180 }
00181 };
00182
00183 }
00184
00185 namespace range {
00186
00187 template <typename Range1, typename Range2>
00188 struct min
00189 : public boost::mpl::if_<
00190 boost::mpl::less<
00191 typename Range1::complexity,
00192 typename Range2::complexity>
00193 , Range1
00194 , Range2
00195 >
00196 {};
00197 }
00198
00199 }}
00200
00201 #endif // MTL_DETAIL_RANGE_GENERATOR_INCLUDE