00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef MTL_DENSE_VECTOR_INCLUDE
00016 #define MTL_DENSE_VECTOR_INCLUDE
00017
00018
00019 #include <iostream>
00020 #include <cassert>
00021 #include <vector>
00022 #include <algorithm>
00023 #include <boost/static_assert.hpp>
00024 #include <boost/type_traits.hpp>
00025 #include <boost/utility/enable_if.hpp>
00026
00027 #include <boost/numeric/mtl/mtl_fwd.hpp>
00028 #include <boost/numeric/mtl/utility/exception.hpp>
00029 #include <boost/numeric/mtl/utility/ashape.hpp>
00030 #include <boost/numeric/mtl/utility/common_include.hpp>
00031 #include <boost/numeric/mtl/vector/all_vec_expr.hpp>
00032 #include <boost/numeric/mtl/vector/parameter.hpp>
00033 #include <boost/numeric/mtl/detail/contiguous_memory_block.hpp>
00034 #include <boost/numeric/mtl/vector/crtp_base_vector.hpp>
00035 #include <boost/numeric/mtl/utility/dense_el_cursor.hpp>
00036 #include <boost/numeric/mtl/utility/range_generator.hpp>
00037 #include <boost/numeric/mtl/utility/property_map.hpp>
00038 #include <boost/numeric/mtl/utility/irange.hpp>
00039 #include <boost/numeric/mtl/utility/is_static.hpp>
00040 #include <boost/numeric/mtl/utility/is_row_major.hpp>
00041
00042
00043 namespace mtl { namespace vector {
00044
00045 template <class Value, typename Parameters = parameters<> >
00046 class dense_vector
00047 : public vec_expr<dense_vector<Value, Parameters> >,
00048 public ::mtl::detail::contiguous_memory_block< Value, Parameters::on_stack, Parameters::dimension::value >,
00049 public crtp_base_vector< dense_vector<Value, Parameters>, Value, std::size_t >
00050 {
00051 typedef dense_vector self;
00052 typedef ::mtl::detail::contiguous_memory_block< Value, Parameters::on_stack,
00053 Parameters::dimension::value > memory_base;
00054 typedef crtp_base_vector< self, Value, std::size_t > crtp_base;
00055 typedef crtp_vector_assign< self, Value, std::size_t > assign_base;
00056 typedef vec_expr<dense_vector<Value, Parameters> > expr_base;
00057 public:
00058 typedef Value value_type ;
00059 typedef std::size_t size_type ;
00060 typedef value_type& reference ;
00061 typedef value_type const& const_reference ;
00062 typedef Value* pointer ;
00063 typedef Value const* const_pointer ;
00064 typedef typename Parameters::orientation orientation;
00065
00066 typedef const_pointer key_type;
00067
00068 void check_index( size_type i ) const
00069 {
00070 MTL_DEBUG_THROW_IF( i < 0 || i >= size(), index_out_of_range());
00071 }
00072
00073 void check_dim( size_type s ) const
00074 {
00075 MTL_DEBUG_THROW_IF( size() != 0 && size() != s, incompatible_size());
00076 }
00077
00078 void static_check( size_type s) const
00079 {
00080 assert(!traits::is_static<self>::value || s == (typename Parameters::dimension()).size());
00081 }
00082
00083 template <class E>
00084 void check_consistent_shape( vec_expr<E> const& e ) const
00085 {
00086 MTL_DEBUG_THROW_IF((!boost::is_same<
00087 typename ashape::ashape<self>::type
00088 , typename ashape::ashape<E>::type
00089 >::value),
00090 incompatible_shape());
00091 }
00092
00093
00094 dense_vector( ) : memory_base( Parameters::dimension::value ) {}
00095
00096 explicit dense_vector( size_type n ) : memory_base( n ) { static_check( n ); }
00097
00098 explicit dense_vector( size_type n, value_type value )
00099 : memory_base( n )
00100 {
00101 static_check( n );
00102 std::fill(begin(), end(), value);
00103 }
00104
00105 explicit dense_vector( size_type n, value_type *address )
00106 : memory_base( address, n )
00107 { static_check( n ); }
00108
00109 dense_vector( const self& src )
00110 : memory_base( src.size() )
00111 {
00112 using std::copy;
00113 copy(src.begin(), src.end(), begin());
00114 }
00115
00116 template <typename VectorSrc>
00117 explicit dense_vector(const VectorSrc& src,
00118 typename boost::disable_if<boost::is_integral<VectorSrc>, int >::type= 0)
00119 {
00120 *this= src;
00121 }
00122
00123 #if 0
00124
00125 template <class Value2, typename Parameters2>
00126 explicit dense_vector( const dense_vector<Value2, Parameters2>& src )
00127 : memory_base( src.size() )
00128 {
00129 using std::copy;
00130 check_consistent_shape(src);
00131 copy(src.begin(), src.end(), begin());
00132 }
00133 #endif
00134
00135 size_type size() const { return this->used_memory() ; }
00136
00137 size_type stride() const { return 1 ; }
00138
00139 reference operator()( size_type i )
00140 {
00141 check_index(i);
00142 return this->value_n( i ) ;
00143 }
00144
00145 const_reference operator()( size_type i ) const
00146 {
00147 check_index(i);
00148 return this->value_n( i ) ;
00149 }
00150
00151 reference operator[]( size_type i ) { return (*this)( i ) ; }
00152 const_reference operator[]( size_type i ) const { return (*this)( i ) ; }
00153
00154 self operator[]( irange r ) { return sub_vector(*this, r.start(), r.finish()); }
00155 const self operator[]( irange r ) const { return sub_vector(*this, r.start(), r.finish()); }
00156
00157 void delay_assign() const {}
00158
00159 const_pointer begin() const { return this->elements() ; }
00160 const_pointer end() const { return this->elements() + size() ; }
00161
00162 pointer begin() { return this->elements() ; }
00163 pointer end() { return this->elements() + size() ; }
00164
00166 value_type* address_data() { return begin(); }
00167 const value_type* address_data() const { return begin(); }
00168
00169 #if 0 // Cannot be called with mtl::num_rows(x);
00170 friend size_type inline num_rows(const self& v) { return traits::is_row_major<self>::value ? 1 : v.size(); }
00171 friend size_type inline num_cols(const self& v) { return traits::is_row_major<self>::value ? v.size() : 1; }
00172 #endif
00173
00174 #if 0
00175
00176
00177
00178
00179 vec_vec_asgn_expr<self, self> operator=( self const& e )
00180 {
00181 return vec_vec_asgn_expr<self, self>( *this, e );
00182 }
00183 #endif
00184
00185 self& operator=(self src)
00186 {
00187
00188 assert(this != &src);
00189
00190 check_dim(src.size());
00191 memory_base::move_assignment(src);
00192 return *this;
00193 }
00194
00195
00196 using assign_base::operator=;
00197
00198 template <typename Value2> friend void fill(self&, const Value2&);
00199
00200 friend void swap(self& vector1, self& vector2)
00201 {
00202 swap(static_cast<memory_base&>(vector1), static_cast<memory_base&>(vector2));
00203 }
00204
00205 void change_dim(size_type n) { this->realloc(n); }
00206 void checked_change_dim(size_type n) { check_dim(n); change_dim(n); }
00207
00208 void crop() {}
00209
00210 } ;
00211
00212
00213
00214
00215
00216
00217 template <typename Value, typename Parameters, typename Value2>
00218 inline void fill(dense_vector<Value, Parameters>& vector, const Value2& value)
00219 {
00220 std::fill(vector.begin(), vector.end(), value);
00221 }
00222
00223
00224 template <typename Value, typename Parameters>
00225 typename dense_vector<Value, Parameters>::size_type
00226 inline size(const dense_vector<Value, Parameters>& vector)
00227 {
00228 return vector.size();
00229 }
00230
00231 template <typename Value, typename Parameters>
00232 typename dense_vector<Value, Parameters>::size_type
00233 inline num_rows_aux(const dense_vector<Value, Parameters>& vector, tag::row_major)
00234 {
00235 return 1;
00236 }
00237
00238 template <typename Value, typename Parameters>
00239 typename dense_vector<Value, Parameters>::size_type
00240 inline num_rows_aux(const dense_vector<Value, Parameters>& vector, tag::col_major)
00241 {
00242 return vector.size();
00243 }
00244
00245
00246 template <typename Value, typename Parameters>
00247 typename dense_vector<Value, Parameters>::size_type
00248 inline num_rows(const dense_vector<Value, Parameters>& vector)
00249 {
00250 return num_rows_aux(vector, typename Parameters::orientation());
00251 }
00252
00253
00254 template <typename Value, typename Parameters>
00255 typename dense_vector<Value, Parameters>::size_type
00256 inline num_cols(const dense_vector<Value, Parameters>& vector)
00257 {
00258 return num_rows_aux(vector, typename transposed_orientation<typename Parameters::orientation>::type());
00259 }
00260
00261 template <typename Value, typename Parameters>
00262 dense_vector<Value, Parameters>
00263 inline sub_vector(dense_vector<Value, Parameters>& v,
00264 typename dense_vector<Value, Parameters>::size_type start,
00265 typename dense_vector<Value, Parameters>::size_type finish)
00266 {
00267 typedef dense_vector<Value, Parameters> Vector;
00268
00269 MTL_DEBUG_THROW_IF( start < 0 || finish < 0, index_out_of_range());
00270 irange r= intersection(irange(start, finish), irange(0, size(v)));
00271 return r.empty() ? Vector() : Vector(r.size(), &v[r.start()]);
00272
00273 #if 0
00274 finish= min(finish, size(v));
00275 start= min(start, finish);
00276 return start < finish ? Vector(finish - start, &v[start]) : Vector();
00277 #endif
00278 }
00279
00280 template <typename Value, typename Parameters>
00281 const dense_vector<Value, Parameters>
00282 inline sub_vector(const dense_vector<Value, Parameters>& v,
00283 typename dense_vector<Value, Parameters>::size_type start,
00284 typename dense_vector<Value, Parameters>::size_type finish)
00285 {
00286 typedef dense_vector<Value, Parameters> Vector;
00287 return sub_vector(const_cast<Vector&>(v), start, finish);
00288 }
00289
00290
00291 }}
00292
00293
00294 namespace mtl { namespace traits {
00295
00296
00297
00298
00299
00300
00301
00302 template <typename Value, class Parameters>
00303 struct range_generator<tag::all, dense_vector<Value, Parameters> >
00304 : public detail::dense_element_range_generator<dense_vector<Value, Parameters>,
00305 dense_el_cursor<Value>, complexity_classes::linear_cached>
00306 {};
00307
00308 template <typename Value, class Parameters>
00309 struct range_generator<tag::nz, dense_vector<Value, Parameters> >
00310 : public range_generator<tag::all, dense_vector<Value, Parameters> >
00311 {};
00312
00313 template <typename Value, class Parameters>
00314 struct range_generator<tag::iter::all, dense_vector<Value, Parameters> >
00315 {
00316 typedef dense_vector<Value, Parameters> collection_t;
00317 typedef complexity_classes::linear_cached complexity;
00318 static int const level = 1;
00319 typedef typename collection_t::pointer type;
00320
00321 type begin(collection_t& collection)
00322 {
00323 return collection.begin();
00324 }
00325 type end(collection_t& collection)
00326 {
00327 return collection.end();
00328 }
00329 };
00330
00331 template <typename Value, class Parameters>
00332 struct range_generator<tag::iter::nz, dense_vector<Value, Parameters> >
00333 : public range_generator<tag::iter::all, dense_vector<Value, Parameters> >
00334 {};
00335
00336 template <typename Value, class Parameters>
00337 struct range_generator<tag::const_iter::all, dense_vector<Value, Parameters> >
00338 {
00339 typedef dense_vector<Value, Parameters> collection_t;
00340 typedef complexity_classes::linear_cached complexity;
00341 static int const level = 1;
00342 typedef typename collection_t::const_pointer type;
00343
00344 type begin(const collection_t& collection) const
00345 {
00346 return collection.begin();
00347 }
00348 type end(const collection_t& collection) const
00349 {
00350 return collection.end();
00351 }
00352 };
00353
00354 template <typename Value, class Parameters>
00355 struct range_generator<tag::const_iter::nz, dense_vector<Value, Parameters> >
00356 : public range_generator<tag::const_iter::all, dense_vector<Value, Parameters> >
00357 {};
00358
00359
00360 }}
00361
00362
00363 #endif // MTL_DENSE_VECTOR_INCLUDE
00364