00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef _BOOST_UBLAS_EXPRESSION_TYPE_
00013 #define _BOOST_UBLAS_EXPRESSION_TYPE_
00014
00015 #include <boost/numeric/ublas/exception.hpp>
00016 #include <boost/numeric/ublas/traits.hpp>
00017 #include <boost/numeric/ublas/functional.hpp>
00018
00019
00020
00021
00022
00023 namespace boost { namespace numeric { namespace ublas {
00024
00032 template<class E>
00033 class ublas_expression {
00034 public:
00035 typedef E expression_type;
00036
00037
00038
00039
00040
00041
00042 protected:
00043 ublas_expression () {}
00044 ~ublas_expression () {}
00045 private:
00046 const ublas_expression& operator= (const ublas_expression &);
00047 };
00048
00049
00060 template<class E>
00061 class scalar_expression:
00062 public ublas_expression<E> {
00063 public:
00064 typedef E expression_type;
00065 typedef scalar_tag type_category;
00066
00067 BOOST_UBLAS_INLINE
00068 const expression_type &operator () () const {
00069 return *static_cast<const expression_type *> (this);
00070 }
00071 BOOST_UBLAS_INLINE
00072 expression_type &operator () () {
00073 return *static_cast<expression_type *> (this);
00074 }
00075 };
00076
00077 template<class T>
00078 class scalar_reference:
00079 public scalar_expression<scalar_reference<T> > {
00080
00081 typedef scalar_reference<T> self_type;
00082 public:
00083 typedef T value_type;
00084 typedef const value_type &const_reference;
00085 typedef typename boost::mpl::if_<boost::is_const<T>,
00086 const_reference,
00087 value_type &>::type reference;
00088 typedef const self_type const_closure_type;
00089 typedef const_closure_type closure_type;
00090
00091
00092 BOOST_UBLAS_INLINE
00093 explicit scalar_reference (reference t):
00094 t_ (t) {}
00095
00096
00097 BOOST_UBLAS_INLINE
00098 operator value_type () const {
00099 return t_;
00100 }
00101
00102
00103 BOOST_UBLAS_INLINE
00104 scalar_reference &operator = (const scalar_reference &s) {
00105 t_ = s.t_;
00106 return *this;
00107 }
00108 template<class AE>
00109 BOOST_UBLAS_INLINE
00110 scalar_reference &operator = (const scalar_expression<AE> &ae) {
00111 t_ = ae;
00112 return *this;
00113 }
00114
00115
00116 BOOST_UBLAS_INLINE
00117 bool same_closure (const scalar_reference &sr) const {
00118 return &t_ == &sr.t_;
00119 }
00120
00121 private:
00122 reference t_;
00123 };
00124
00125 template<class T>
00126 class scalar_value:
00127 public scalar_expression<scalar_value<T> > {
00128
00129 typedef scalar_value<T> self_type;
00130 public:
00131 typedef T value_type;
00132 typedef const value_type &const_reference;
00133 typedef typename boost::mpl::if_<boost::is_const<T>,
00134 const_reference,
00135 value_type &>::type reference;
00136 typedef const scalar_reference<const self_type> const_closure_type;
00137 typedef scalar_reference<self_type> closure_type;
00138
00139
00140 BOOST_UBLAS_INLINE
00141 scalar_value ():
00142 t_ () {}
00143 BOOST_UBLAS_INLINE
00144 scalar_value (const value_type &t):
00145 t_ (t) {}
00146
00147 BOOST_UBLAS_INLINE
00148 operator value_type () const {
00149 return t_;
00150 }
00151
00152
00153 BOOST_UBLAS_INLINE
00154 scalar_value &operator = (const scalar_value &s) {
00155 t_ = s.t_;
00156 return *this;
00157 }
00158 template<class AE>
00159 BOOST_UBLAS_INLINE
00160 scalar_value &operator = (const scalar_expression<AE> &ae) {
00161 t_ = ae;
00162 return *this;
00163 }
00164
00165
00166 BOOST_UBLAS_INLINE
00167 bool same_closure (const scalar_value &sv) const {
00168 return this == &sv;
00169 }
00170
00171 private:
00172 value_type t_;
00173 };
00174
00175
00183 template<class E>
00184 class vector_expression:
00185 public ublas_expression<E> {
00186 public:
00187 static const unsigned complexity = 0;
00188 typedef E expression_type;
00189 typedef vector_tag type_category;
00190
00191
00192
00193
00194 BOOST_UBLAS_INLINE
00195 const expression_type &operator () () const {
00196 return *static_cast<const expression_type *> (this);
00197 }
00198 BOOST_UBLAS_INLINE
00199 expression_type &operator () () {
00200 return *static_cast<expression_type *> (this);
00201 }
00202
00203 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
00204 private:
00205
00206 typedef vector_range<E> vector_range_type;
00207 typedef vector_range<const E> const_vector_range_type;
00208 typedef vector_slice<E> vector_slice_type;
00209 typedef vector_slice<const E> const_vector_slice_type;
00210
00211 typedef basic_range<> default_range;
00212 typedef basic_slice<> default_slice;
00213 public:
00214 BOOST_UBLAS_INLINE
00215 const_vector_range_type operator () (const default_range &r) const {
00216 return const_vector_range_type (operator () (), r);
00217 }
00218 BOOST_UBLAS_INLINE
00219 vector_range_type operator () (const default_range &r) {
00220 return vector_range_type (operator () (), r);
00221 }
00222 BOOST_UBLAS_INLINE
00223 const_vector_slice_type operator () (const default_slice &s) const {
00224 return const_vector_slice_type (operator () (), s);
00225 }
00226 BOOST_UBLAS_INLINE
00227 vector_slice_type operator () (const default_slice &s) {
00228 return vector_slice_type (operator () (), s);
00229 }
00230 template<class A>
00231 BOOST_UBLAS_INLINE
00232 const vector_indirect<const E, indirect_array<A> > operator () (const indirect_array<A> &ia) const {
00233 return vector_indirect<const E, indirect_array<A> > (operator () (), ia);
00234 }
00235 template<class A>
00236 BOOST_UBLAS_INLINE
00237 vector_indirect<E, indirect_array<A> > operator () (const indirect_array<A> &ia) {
00238 return vector_indirect<E, indirect_array<A> > (operator () (), ia);
00239 }
00240
00241 BOOST_UBLAS_INLINE
00242 const_vector_range_type project (const default_range &r) const {
00243 return const_vector_range_type (operator () (), r);
00244 }
00245 BOOST_UBLAS_INLINE
00246 vector_range_type project (const default_range &r) {
00247 return vector_range_type (operator () (), r);
00248 }
00249 BOOST_UBLAS_INLINE
00250 const_vector_slice_type project (const default_slice &s) const {
00251 return const_vector_slice_type (operator () (), s);
00252 }
00253 BOOST_UBLAS_INLINE
00254 vector_slice_type project (const default_slice &s) {
00255 return vector_slice_type (operator () (), s);
00256 }
00257 template<class A>
00258 BOOST_UBLAS_INLINE
00259 const vector_indirect<const E, indirect_array<A> > project (const indirect_array<A> &ia) const {
00260 return vector_indirect<const E, indirect_array<A> > (operator () (), ia);
00261 }
00262 template<class A>
00263 BOOST_UBLAS_INLINE
00264 vector_indirect<E, indirect_array<A> > project (const indirect_array<A> &ia) {
00265 return vector_indirect<E, indirect_array<A> > (operator () (), ia);
00266 }
00267 #endif
00268 };
00269
00277 template<class C>
00278 class vector_container:
00279 public vector_expression<C> {
00280 public:
00281 static const unsigned complexity = 0;
00282 typedef C container_type;
00283 typedef vector_tag type_category;
00284
00285 BOOST_UBLAS_INLINE
00286 const container_type &operator () () const {
00287 return *static_cast<const container_type *> (this);
00288 }
00289 BOOST_UBLAS_INLINE
00290 container_type &operator () () {
00291 return *static_cast<container_type *> (this);
00292 }
00293
00294 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
00295 using vector_expression<C>::operator ();
00296 #endif
00297 };
00298
00299
00307 template<class E>
00308 class matrix_expression:
00309 public ublas_expression<E> {
00310 private:
00311 typedef matrix_expression<E> self_type;
00312 public:
00313 static const unsigned complexity = 0;
00314 typedef E expression_type;
00315 typedef matrix_tag type_category;
00316
00317
00318
00319
00320 BOOST_UBLAS_INLINE
00321 const expression_type &operator () () const {
00322 return *static_cast<const expression_type *> (this);
00323 }
00324 BOOST_UBLAS_INLINE
00325 expression_type &operator () () {
00326 return *static_cast<expression_type *> (this);
00327 }
00328
00329 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
00330 private:
00331
00332 typedef vector_range<E> vector_range_type;
00333 typedef const vector_range<const E> const_vector_range_type;
00334 typedef vector_slice<E> vector_slice_type;
00335 typedef const vector_slice<const E> const_vector_slice_type;
00336 typedef matrix_row<E> matrix_row_type;
00337 typedef const matrix_row<const E> const_matrix_row_type;
00338 typedef matrix_column<E> matrix_column_type;
00339 typedef const matrix_column<const E> const_matrix_column_type;
00340 typedef matrix_range<E> matrix_range_type;
00341 typedef const matrix_range<const E> const_matrix_range_type;
00342 typedef matrix_slice<E> matrix_slice_type;
00343 typedef const matrix_slice<const E> const_matrix_slice_type;
00344
00345 typedef basic_range<> default_range;
00346 typedef basic_slice<> default_slice;
00347
00348 public:
00349 BOOST_UBLAS_INLINE
00350 const_matrix_row_type operator [] (std::size_t i) const {
00351 return const_matrix_row_type (operator () (), i);
00352 }
00353 BOOST_UBLAS_INLINE
00354 matrix_row_type operator [] (std::size_t i) {
00355 return matrix_row_type (operator () (), i);
00356 }
00357 BOOST_UBLAS_INLINE
00358 const_matrix_row_type row (std::size_t i) const {
00359 return const_matrix_row_type (operator () (), i);
00360 }
00361 BOOST_UBLAS_INLINE
00362 matrix_row_type row (std::size_t i) {
00363 return matrix_row_type (operator () (), i);
00364 }
00365 BOOST_UBLAS_INLINE
00366 const_matrix_column_type column (std::size_t j) const {
00367 return const_matrix_column_type (operator () (), j);
00368 }
00369 BOOST_UBLAS_INLINE
00370 matrix_column_type column (std::size_t j) {
00371 return matrix_column_type (operator () (), j);
00372 }
00373
00374 BOOST_UBLAS_INLINE
00375 const_matrix_range_type operator () (const default_range &r1, const default_range &r2) const {
00376 return const_matrix_range_type (operator () (), r1, r2);
00377 }
00378 BOOST_UBLAS_INLINE
00379 matrix_range_type operator () (const default_range &r1, const default_range &r2) {
00380 return matrix_range_type (operator () (), r1, r2);
00381 }
00382 BOOST_UBLAS_INLINE
00383 const_matrix_slice_type operator () (const default_slice &s1, const default_slice &s2) const {
00384 return const_matrix_slice_type (operator () (), s1, s2);
00385 }
00386 BOOST_UBLAS_INLINE
00387 matrix_slice_type operator () (const default_slice &s1, const default_slice &s2) {
00388 return matrix_slice_type (operator () (), s1, s2);
00389 }
00390 template<class A>
00391 BOOST_UBLAS_INLINE
00392 const matrix_indirect<const E, indirect_array<A> > operator () (const indirect_array<A> &ia1, const indirect_array<A> &ia2) const {
00393 return matrix_indirect<const E, indirect_array<A> > (operator () (), ia1, ia2);
00394 }
00395 template<class A>
00396 BOOST_UBLAS_INLINE
00397 matrix_indirect<E, indirect_array<A> > operator () (const indirect_array<A> &ia1, const indirect_array<A> &ia2) {
00398 return matrix_indirect<E, indirect_array<A> > (operator () (), ia1, ia2);
00399 }
00400
00401 BOOST_UBLAS_INLINE
00402 const_matrix_range_type project (const default_range &r1, const default_range &r2) const {
00403 return const_matrix_range_type (operator () (), r1, r2);
00404 }
00405 BOOST_UBLAS_INLINE
00406 matrix_range_type project (const default_range &r1, const default_range &r2) {
00407 return matrix_range_type (operator () (), r1, r2);
00408 }
00409 BOOST_UBLAS_INLINE
00410 const_matrix_slice_type project (const default_slice &s1, const default_slice &s2) const {
00411 return const_matrix_slice_type (operator () (), s1, s2);
00412 }
00413 BOOST_UBLAS_INLINE
00414 matrix_slice_type project (const default_slice &s1, const default_slice &s2) {
00415 return matrix_slice_type (operator () (), s1, s2);
00416 }
00417 template<class A>
00418 BOOST_UBLAS_INLINE
00419 const matrix_indirect<const E, indirect_array<A> > project (const indirect_array<A> &ia1, const indirect_array<A> &ia2) const {
00420 return matrix_indirect<const E, indirect_array<A> > (operator () (), ia1, ia2);
00421 }
00422 template<class A>
00423 BOOST_UBLAS_INLINE
00424 matrix_indirect<E, indirect_array<A> > project (const indirect_array<A> &ia1, const indirect_array<A> &ia2) {
00425 return matrix_indirect<E, indirect_array<A> > (operator () (), ia1, ia2);
00426 }
00427 #endif
00428 };
00429
00430 #ifdef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
00431 struct iterator1_tag {};
00432 struct iterator2_tag {};
00433
00434 template<class I>
00435 BOOST_UBLAS_INLINE
00436 typename I::dual_iterator_type begin (const I &it, iterator1_tag) {
00437 return it ().find2 (1, it.index1 (), 0);
00438 }
00439 template<class I>
00440 BOOST_UBLAS_INLINE
00441 typename I::dual_iterator_type end (const I &it, iterator1_tag) {
00442 return it ().find2 (1, it.index1 (), it ().size2 ());
00443 }
00444 template<class I>
00445 BOOST_UBLAS_INLINE
00446 typename I::dual_reverse_iterator_type rbegin (const I &it, iterator1_tag) {
00447 return typename I::dual_reverse_iterator_type (end (it, iterator1_tag ()));
00448 }
00449 template<class I>
00450 BOOST_UBLAS_INLINE
00451 typename I::dual_reverse_iterator_type rend (const I &it, iterator1_tag) {
00452 return typename I::dual_reverse_iterator_type (begin (it, iterator1_tag ()));
00453 }
00454
00455 template<class I>
00456 BOOST_UBLAS_INLINE
00457 typename I::dual_iterator_type begin (const I &it, iterator2_tag) {
00458 return it ().find1 (1, 0, it.index2 ());
00459 }
00460 template<class I>
00461 BOOST_UBLAS_INLINE
00462 typename I::dual_iterator_type end (const I &it, iterator2_tag) {
00463 return it ().find1 (1, it ().size1 (), it.index2 ());
00464 }
00465 template<class I>
00466 BOOST_UBLAS_INLINE
00467 typename I::dual_reverse_iterator_type rbegin (const I &it, iterator2_tag) {
00468 return typename I::dual_reverse_iterator_type (end (it, iterator2_tag ()));
00469 }
00470 template<class I>
00471 BOOST_UBLAS_INLINE
00472 typename I::dual_reverse_iterator_type rend (const I &it, iterator2_tag) {
00473 return typename I::dual_reverse_iterator_type (begin (it, iterator2_tag ()));
00474 }
00475 #endif
00476
00484 template<class C>
00485 class matrix_container:
00486 public matrix_expression<C> {
00487 public:
00488 static const unsigned complexity = 0;
00489 typedef C container_type;
00490 typedef matrix_tag type_category;
00491
00492 BOOST_UBLAS_INLINE
00493 const container_type &operator () () const {
00494 return *static_cast<const container_type *> (this);
00495 }
00496 BOOST_UBLAS_INLINE
00497 container_type &operator () () {
00498 return *static_cast<container_type *> (this);
00499 }
00500
00501 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
00502 using matrix_expression<C>::operator ();
00503 #endif
00504 };
00505
00506 }}}
00507
00508 #endif