DriveHQ Start Menu
Cloud Drive Mapping
Folder Sync
Cloud Backup
True Drop Box
FTP/SFTP Hosting
Group Account
DriveHQ Start Menu
Online File Server
My Storage
|
Manage Shares
|
Publishes
|
Drop Boxes
|
Group Account
WebDAV Drive Mapping
Cloud Drive Home
|
WebDAV Guide
|
Drive Mapping Tool
|
Drive Mapping URL
Complete Data Backup
Backup Guide
|
Online Backup Tool
|
Cloud-to-Cloud Backup
FTP, Email & Web Service
FTP Home
|
FTP Hosting FAQ
|
Email Hosting
|
EmailManager
|
Web Hosting
Help & Resources
About
|
Enterprise Service
|
Partnership
|
Comparisons
|
Support
Quick Links
Security and Privacy
Download Software
Service Manual
Use Cases
Group Account
Online Help
Blog
Contact
Cloud Surveillance
Sign Up
Login
Features
Business Features
Online File Server
FTP Hosting
Cloud Drive Mapping
Cloud File Backup
Email Backup & Hosting
Cloud File Sharing
Folder Synchronization
Group Management
True Drop Box
Full-text Search
AD Integration/SSO
Mobile Access
IP Camera & DVR Solution
More...
Personal Features
Personal Cloud Drive
Backup All Devices
Mobile APPs
Personal Web Hosting
Sub-Account (for Kids)
Home/PC/Kids Monitoring
More...
Software
DriveHQ Drive Mapping Tool
DriveHQ FileManager
DriveHQ Online Backup
DriveHQ Mobile Apps
Pricing
Business Plans & Pricing
Personal Plans & Pricing
Price Comparison with Others
Feature Comparison with Others
Install Mobile App
Sign up
Creating account...
Invalid character in username! Only 0-9, a-z, A-Z, _, -, . allowed.
Username is required!
Invalid email address!
E-mail is required!
Password is required!
Password is invalid!
Password and confirmation do not match.
Confirm password is required!
I accept
Membership Agreement
Please read the Membership Agreement and check "I accept"!
Free Quick Sign-up
Sign-up Page
Log in
Signing in...
Username or e-mail address is required!
Password is required!
Keep me logged in
Quick Login
Forgot Password
Up
Upload
Download
Share
Publish
New Folder
New File
Copy
Cut
Delete
Paste
Rate
Upgrade
Rotate
Effect
Edit
Slide
History
// // Copyright (c) 2000-2002 // Joerg Walter, Mathias Koch // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // The authors gratefully acknowledge the support of // GeNeSys mbH & Co. KG in producing this work. // #ifndef _BOOST_UBLAS_MATRIX_PROXY_ #define _BOOST_UBLAS_MATRIX_PROXY_ #include
#include
#include
#include
// Iterators based on ideas of Jeremy Siek namespace boost { namespace numeric { namespace ublas { // Matrix based row vector class template
class matrix_row: public vector_expression
> { typedef matrix_row
self_type; public: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS using vector_expression
::operator (); #endif typedef M matrix_type; typedef typename M::size_type size_type; typedef typename M::difference_type difference_type; typedef typename M::value_type value_type; typedef typename M::const_reference const_reference; typedef typename boost::mpl::if_
, typename M::const_reference, typename M::reference>::type reference; typedef typename boost::mpl::if_
, typename M::const_closure_type, typename M::closure_type>::type matrix_closure_type; typedef const self_type const_closure_type; typedef self_type closure_type; typedef typename storage_restrict_traits
::storage_category storage_category; // Construction and destruction BOOST_UBLAS_INLINE matrix_row (matrix_type &data, size_type i): data_ (data), i_ (i) { // Early checking of preconditions here. // BOOST_UBLAS_CHECK (i_ < data_.size1 (), bad_index ()); } // Accessors BOOST_UBLAS_INLINE size_type size () const { return data_.size2 (); } BOOST_UBLAS_INLINE size_type index () const { return i_; } // Storage accessors BOOST_UBLAS_INLINE const matrix_closure_type &data () const { return data_; } BOOST_UBLAS_INLINE matrix_closure_type &data () { return data_; } // Element access #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER BOOST_UBLAS_INLINE const_reference operator () (size_type j) const { return data_ (i_, j); } BOOST_UBLAS_INLINE reference operator () (size_type j) { return data_ (i_, j); } BOOST_UBLAS_INLINE const_reference operator [] (size_type j) const { return (*this) (j); } BOOST_UBLAS_INLINE reference operator [] (size_type j) { return (*this) (j); } #else BOOST_UBLAS_INLINE reference operator () (size_type j) const { return data_ (i_, j); } BOOST_UBLAS_INLINE reference operator [] (size_type j) const { return (*this) (j); } #endif // Assignment BOOST_UBLAS_INLINE matrix_row &operator = (const matrix_row &mr) { // ISSUE need a temporary, proxy can be overlaping alias vector_assign
(*this, typename vector_temporary_traits
::type (mr)); return *this; } BOOST_UBLAS_INLINE matrix_row &assign_temporary (matrix_row &mr) { // assign elements, proxied container remains the same vector_assign
(*this, mr); return *this; } template
BOOST_UBLAS_INLINE matrix_row &operator = (const vector_expression
&ae) { vector_assign
(*this, typename vector_temporary_traits
::type (ae)); return *this; } template
BOOST_UBLAS_INLINE matrix_row &assign (const vector_expression
&ae) { vector_assign
(*this, ae); return *this; } template
BOOST_UBLAS_INLINE matrix_row &operator += (const vector_expression
&ae) { vector_assign
(*this, typename vector_temporary_traits
::type (*this + ae)); return *this; } template
BOOST_UBLAS_INLINE matrix_row &plus_assign (const vector_expression
&ae) { vector_assign
(*this, ae); return *this; } template
BOOST_UBLAS_INLINE matrix_row &operator -= (const vector_expression
&ae) { vector_assign
(*this, typename vector_temporary_traits
::type (*this - ae)); return *this; } template
BOOST_UBLAS_INLINE matrix_row &minus_assign (const vector_expression
&ae) { vector_assign
(*this, ae); return *this; } template
BOOST_UBLAS_INLINE matrix_row &operator *= (const AT &at) { vector_assign_scalar
(*this, at); return *this; } template
BOOST_UBLAS_INLINE matrix_row &operator /= (const AT &at) { vector_assign_scalar
(*this, at); return *this; } // Closure comparison BOOST_UBLAS_INLINE bool same_closure (const matrix_row &mr) const { return (*this).data_.same_closure (mr.data_); } // Comparison BOOST_UBLAS_INLINE bool operator == (const matrix_row &mr) const { return (*this).data_ == mr.data_ && index () == mr.index (); } // Swapping BOOST_UBLAS_INLINE void swap (matrix_row mr) { if (this != &mr) { BOOST_UBLAS_CHECK (size () == mr.size (), bad_size ()); // Sparse ranges may be nonconformant now. // std::swap_ranges (begin (), end (), mr.begin ()); vector_swap
(*this, mr); } } BOOST_UBLAS_INLINE friend void swap (matrix_row mr1, matrix_row mr2) { mr1.swap (mr2); } // Iterator types private: typedef typename M::const_iterator2 const_subiterator_type; typedef typename boost::mpl::if_
, typename M::const_iterator2, typename M::iterator2>::type subiterator_type; public: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR typedef indexed_iterator
, typename subiterator_type::iterator_category> iterator; typedef indexed_const_iterator
, typename const_subiterator_type::iterator_category> const_iterator; #else class const_iterator; class iterator; #endif // Element lookup BOOST_UBLAS_INLINE const_iterator find (size_type j) const { const_subiterator_type it2 (data_.find2 (1, i_, j)); #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR return const_iterator (*this, it2.index2 ()); #else return const_iterator (*this, it2); #endif } BOOST_UBLAS_INLINE iterator find (size_type j) { subiterator_type it2 (data_.find2 (1, i_, j)); #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR return iterator (*this, it2.index2 ()); #else return iterator (*this, it2); #endif } #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR class const_iterator: public container_const_reference
, public iterator_base_traits
::template iterator_base
::type { public: typedef typename const_subiterator_type::value_type value_type; typedef typename const_subiterator_type::difference_type difference_type; typedef typename const_subiterator_type::reference reference; typedef typename const_subiterator_type::pointer pointer; // Construction and destruction BOOST_UBLAS_INLINE const_iterator (): container_const_reference
(), it_ () {} BOOST_UBLAS_INLINE const_iterator (const self_type &mr, const const_subiterator_type &it): container_const_reference
(mr), it_ (it) {} BOOST_UBLAS_INLINE const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here container_const_reference
(it ()), it_ (it.it_) {} // Arithmetic BOOST_UBLAS_INLINE const_iterator &operator ++ () { ++ it_; return *this; } BOOST_UBLAS_INLINE const_iterator &operator -- () { -- it_; return *this; } BOOST_UBLAS_INLINE const_iterator &operator += (difference_type n) { it_ += n; return *this; } BOOST_UBLAS_INLINE const_iterator &operator -= (difference_type n) { it_ -= n; return *this; } BOOST_UBLAS_INLINE difference_type operator - (const const_iterator &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return it_ - it.it_; } // Dereference BOOST_UBLAS_INLINE const_reference operator * () const { BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ()); return *it_; } BOOST_UBLAS_INLINE const_reference operator [] (difference_type n) const { return *(*this + n); } // Index BOOST_UBLAS_INLINE size_type index () const { return it_.index2 (); } // Assignment BOOST_UBLAS_INLINE const_iterator &operator = (const const_iterator &it) { container_const_reference
::assign (&it ()); it_ = it.it_; return *this; } // Comparison BOOST_UBLAS_INLINE bool operator == (const const_iterator &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return it_ == it.it_; } BOOST_UBLAS_INLINE bool operator < (const const_iterator &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return it_ < it.it_; } private: const_subiterator_type it_; }; #endif BOOST_UBLAS_INLINE const_iterator begin () const { return find (0); } BOOST_UBLAS_INLINE const_iterator end () const { return find (size ()); } #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR class iterator: public container_reference
, public iterator_base_traits
::template iterator_base
::type { public: typedef typename subiterator_type::value_type value_type; typedef typename subiterator_type::difference_type difference_type; typedef typename subiterator_type::reference reference; typedef typename subiterator_type::pointer pointer; // Construction and destruction BOOST_UBLAS_INLINE iterator (): container_reference
(), it_ () {} BOOST_UBLAS_INLINE iterator (self_type &mr, const subiterator_type &it): container_reference
(mr), it_ (it) {} // Arithmetic BOOST_UBLAS_INLINE iterator &operator ++ () { ++ it_; return *this; } BOOST_UBLAS_INLINE iterator &operator -- () { -- it_; return *this; } BOOST_UBLAS_INLINE iterator &operator += (difference_type n) { it_ += n; return *this; } BOOST_UBLAS_INLINE iterator &operator -= (difference_type n) { it_ -= n; return *this; } BOOST_UBLAS_INLINE difference_type operator - (const iterator &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return it_ - it.it_; } // Dereference BOOST_UBLAS_INLINE reference operator * () const { BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ()); return *it_; } BOOST_UBLAS_INLINE reference operator [] (difference_type n) const { return *(*this + n); } // Index BOOST_UBLAS_INLINE size_type index () const { return it_.index2 (); } // Assignment BOOST_UBLAS_INLINE iterator &operator = (const iterator &it) { container_reference
::assign (&it ()); it_ = it.it_; return *this; } // Comparison BOOST_UBLAS_INLINE bool operator == (const iterator &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return it_ == it.it_; } BOOST_UBLAS_INLINE bool operator < (const iterator &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return it_ < it.it_; } private: subiterator_type it_; friend class const_iterator; }; #endif BOOST_UBLAS_INLINE iterator begin () { return find (0); } BOOST_UBLAS_INLINE iterator end () { return find (size ()); } // Reverse iterator typedef reverse_iterator_base
const_reverse_iterator; typedef reverse_iterator_base
reverse_iterator; BOOST_UBLAS_INLINE const_reverse_iterator rbegin () const { return const_reverse_iterator (end ()); } BOOST_UBLAS_INLINE const_reverse_iterator rend () const { return const_reverse_iterator (begin ()); } BOOST_UBLAS_INLINE reverse_iterator rbegin () { return reverse_iterator (end ()); } BOOST_UBLAS_INLINE reverse_iterator rend () { return reverse_iterator (begin ()); } private: matrix_closure_type data_; size_type i_; }; // Projections template
BOOST_UBLAS_INLINE matrix_row
row (M &data, typename M::size_type i) { return matrix_row
(data, i); } template
BOOST_UBLAS_INLINE const matrix_row
row (const M &data, typename M::size_type i) { return matrix_row
(data, i); } // Specialize temporary template
struct vector_temporary_traits< matrix_row
> : vector_temporary_traits< M > {} ; template
struct vector_temporary_traits< const matrix_row
> : vector_temporary_traits< M > {} ; // Matrix based column vector class template
class matrix_column: public vector_expression
> { typedef matrix_column
self_type; public: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS using vector_expression
::operator (); #endif typedef M matrix_type; typedef typename M::size_type size_type; typedef typename M::difference_type difference_type; typedef typename M::value_type value_type; typedef typename M::const_reference const_reference; typedef typename boost::mpl::if_
, typename M::const_reference, typename M::reference>::type reference; typedef typename boost::mpl::if_
, typename M::const_closure_type, typename M::closure_type>::type matrix_closure_type; typedef const self_type const_closure_type; typedef self_type closure_type; typedef typename storage_restrict_traits
::storage_category storage_category; // Construction and destruction BOOST_UBLAS_INLINE matrix_column (matrix_type &data, size_type j): data_ (data), j_ (j) { // Early checking of preconditions here. // BOOST_UBLAS_CHECK (j_ < data_.size2 (), bad_index ()); } // Accessors BOOST_UBLAS_INLINE size_type size () const { return data_.size1 (); } BOOST_UBLAS_INLINE size_type index () const { return j_; } // Storage accessors BOOST_UBLAS_INLINE const matrix_closure_type &data () const { return data_; } BOOST_UBLAS_INLINE matrix_closure_type &data () { return data_; } // Element access #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER BOOST_UBLAS_INLINE const_reference operator () (size_type i) const { return data_ (i, j_); } BOOST_UBLAS_INLINE reference operator () (size_type i) { return data_ (i, j_); } BOOST_UBLAS_INLINE const_reference operator [] (size_type i) const { return (*this) (i); } BOOST_UBLAS_INLINE reference operator [] (size_type i) { return (*this) (i); } #else BOOST_UBLAS_INLINE reference operator () (size_type i) const { return data_ (i, j_); } BOOST_UBLAS_INLINE reference operator [] (size_type i) const { return (*this) (i); } #endif // Assignment BOOST_UBLAS_INLINE matrix_column &operator = (const matrix_column &mc) { // ISSUE need a temporary, proxy can be overlaping alias vector_assign
(*this, typename vector_temporary_traits
::type (mc)); return *this; } BOOST_UBLAS_INLINE matrix_column &assign_temporary (matrix_column &mc) { // assign elements, proxied container remains the same vector_assign
(*this, mc); return *this; } template
BOOST_UBLAS_INLINE matrix_column &operator = (const vector_expression
&ae) { vector_assign
(*this, typename vector_temporary_traits
::type (ae)); return *this; } template
BOOST_UBLAS_INLINE matrix_column &assign (const vector_expression
&ae) { vector_assign
(*this, ae); return *this; } template
BOOST_UBLAS_INLINE matrix_column &operator += (const vector_expression
&ae) { vector_assign
(*this, typename vector_temporary_traits
::type (*this + ae)); return *this; } template
BOOST_UBLAS_INLINE matrix_column &plus_assign (const vector_expression
&ae) { vector_assign
(*this, ae); return *this; } template
BOOST_UBLAS_INLINE matrix_column &operator -= (const vector_expression
&ae) { vector_assign
(*this, typename vector_temporary_traits
::type (*this - ae)); return *this; } template
BOOST_UBLAS_INLINE matrix_column &minus_assign (const vector_expression
&ae) { vector_assign
(*this, ae); return *this; } template
BOOST_UBLAS_INLINE matrix_column &operator *= (const AT &at) { vector_assign_scalar
(*this, at); return *this; } template
BOOST_UBLAS_INLINE matrix_column &operator /= (const AT &at) { vector_assign_scalar
(*this, at); return *this; } // Closure comparison BOOST_UBLAS_INLINE bool same_closure (const matrix_column &mc) const { return (*this).data_.same_closure (mc.data_); } // Comparison BOOST_UBLAS_INLINE bool operator == (const matrix_column &mc) const { return (*this).data_ == mc.data_ && index () == mc.index (); } // Swapping BOOST_UBLAS_INLINE void swap (matrix_column mc) { if (this != &mc) { BOOST_UBLAS_CHECK (size () == mc.size (), bad_size ()); // Sparse ranges may be nonconformant now. // std::swap_ranges (begin (), end (), mc.begin ()); vector_swap
(*this, mc); } } BOOST_UBLAS_INLINE friend void swap (matrix_column mc1, matrix_column mc2) { mc1.swap (mc2); } // Iterator types private: typedef typename M::const_iterator1 const_subiterator_type; typedef typename boost::mpl::if_
, typename M::const_iterator1, typename M::iterator1>::type subiterator_type; public: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR typedef indexed_iterator
, typename subiterator_type::iterator_category> iterator; typedef indexed_const_iterator
, typename const_subiterator_type::iterator_category> const_iterator; #else class const_iterator; class iterator; #endif // Element lookup BOOST_UBLAS_INLINE const_iterator find (size_type i) const { const_subiterator_type it1 (data_.find1 (1, i, j_)); #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR return const_iterator (*this, it1.index1 ()); #else return const_iterator (*this, it1); #endif } BOOST_UBLAS_INLINE iterator find (size_type i) { subiterator_type it1 (data_.find1 (1, i, j_)); #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR return iterator (*this, it1.index1 ()); #else return iterator (*this, it1); #endif } #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR class const_iterator: public container_const_reference
, public iterator_base_traits
::template iterator_base
::type { public: typedef typename const_subiterator_type::value_type value_type; typedef typename const_subiterator_type::difference_type difference_type; typedef typename const_subiterator_type::reference reference; typedef typename const_subiterator_type::pointer pointer; // Construction and destruction BOOST_UBLAS_INLINE const_iterator (): container_const_reference
(), it_ () {} BOOST_UBLAS_INLINE const_iterator (const self_type &mc, const const_subiterator_type &it): container_const_reference
(mc), it_ (it) {} BOOST_UBLAS_INLINE const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here container_const_reference
(it ()), it_ (it.it_) {} // Arithmetic BOOST_UBLAS_INLINE const_iterator &operator ++ () { ++ it_; return *this; } BOOST_UBLAS_INLINE const_iterator &operator -- () { -- it_; return *this; } BOOST_UBLAS_INLINE const_iterator &operator += (difference_type n) { it_ += n; return *this; } BOOST_UBLAS_INLINE const_iterator &operator -= (difference_type n) { it_ -= n; return *this; } BOOST_UBLAS_INLINE difference_type operator - (const const_iterator &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return it_ - it.it_; } // Dereference BOOST_UBLAS_INLINE const_reference operator * () const { BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ()); return *it_; } BOOST_UBLAS_INLINE const_reference operator [] (difference_type n) const { return *(*this + n); } // Index BOOST_UBLAS_INLINE size_type index () const { return it_.index1 (); } // Assignment BOOST_UBLAS_INLINE const_iterator &operator = (const const_iterator &it) { container_const_reference
::assign (&it ()); it_ = it.it_; return *this; } // Comparison BOOST_UBLAS_INLINE bool operator == (const const_iterator &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return it_ == it.it_; } BOOST_UBLAS_INLINE bool operator < (const const_iterator &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return it_ < it.it_; } private: const_subiterator_type it_; }; #endif BOOST_UBLAS_INLINE const_iterator begin () const { return find (0); } BOOST_UBLAS_INLINE const_iterator end () const { return find (size ()); } #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR class iterator: public container_reference
, public iterator_base_traits
::template iterator_base
::type { public: typedef typename subiterator_type::value_type value_type; typedef typename subiterator_type::difference_type difference_type; typedef typename subiterator_type::reference reference; typedef typename subiterator_type::pointer pointer; // Construction and destruction BOOST_UBLAS_INLINE iterator (): container_reference
(), it_ () {} BOOST_UBLAS_INLINE iterator (self_type &mc, const subiterator_type &it): container_reference
(mc), it_ (it) {} // Arithmetic BOOST_UBLAS_INLINE iterator &operator ++ () { ++ it_; return *this; } BOOST_UBLAS_INLINE iterator &operator -- () { -- it_; return *this; } BOOST_UBLAS_INLINE iterator &operator += (difference_type n) { it_ += n; return *this; } BOOST_UBLAS_INLINE iterator &operator -= (difference_type n) { it_ -= n; return *this; } BOOST_UBLAS_INLINE difference_type operator - (const iterator &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return it_ - it.it_; } // Dereference BOOST_UBLAS_INLINE reference operator * () const { BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ()); return *it_; } BOOST_UBLAS_INLINE reference operator [] (difference_type n) const { return *(*this + n); } // Index BOOST_UBLAS_INLINE size_type index () const { return it_.index1 (); } // Assignment BOOST_UBLAS_INLINE iterator &operator = (const iterator &it) { container_reference
::assign (&it ()); it_ = it.it_; return *this; } // Comparison BOOST_UBLAS_INLINE bool operator == (const iterator &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return it_ == it.it_; } BOOST_UBLAS_INLINE bool operator < (const iterator &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return it_ < it.it_; } private: subiterator_type it_; friend class const_iterator; }; #endif BOOST_UBLAS_INLINE iterator begin () { return find (0); } BOOST_UBLAS_INLINE iterator end () { return find (size ()); } // Reverse iterator typedef reverse_iterator_base
const_reverse_iterator; typedef reverse_iterator_base
reverse_iterator; BOOST_UBLAS_INLINE const_reverse_iterator rbegin () const { return const_reverse_iterator (end ()); } BOOST_UBLAS_INLINE const_reverse_iterator rend () const { return const_reverse_iterator (begin ()); } reverse_iterator rbegin () { return reverse_iterator (end ()); } BOOST_UBLAS_INLINE reverse_iterator rend () { return reverse_iterator (begin ()); } private: matrix_closure_type data_; size_type j_; }; // Projections template
BOOST_UBLAS_INLINE matrix_column
column (M &data, typename M::size_type j) { return matrix_column
(data, j); } template
BOOST_UBLAS_INLINE const matrix_column
column (const M &data, typename M::size_type j) { return matrix_column
(data, j); } // Specialize temporary template
struct vector_temporary_traits< matrix_column
> : vector_temporary_traits< M > {} ; template
struct vector_temporary_traits< const matrix_column
> : vector_temporary_traits< M > {} ; // Matrix based vector range class template
class matrix_vector_range: public vector_expression
> { typedef matrix_vector_range
self_type; public: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS using vector_expression
::operator (); #endif typedef M matrix_type; typedef typename M::size_type size_type; typedef typename M::difference_type difference_type; typedef typename M::value_type value_type; typedef typename M::const_reference const_reference; typedef typename boost::mpl::if_
, typename M::const_reference, typename M::reference>::type reference; typedef typename boost::mpl::if_
, typename M::const_closure_type, typename M::closure_type>::type matrix_closure_type; typedef basic_range
range_type; typedef const self_type const_closure_type; typedef self_type closure_type; typedef typename storage_restrict_traits
::storage_category storage_category; // Construction and destruction BOOST_UBLAS_INLINE matrix_vector_range (matrix_type &data, const range_type &r1, const range_type &r2): data_ (data), r1_ (r1.preprocess (data.size1 ())), r2_ (r2.preprocess (data.size2 ())) { // Early checking of preconditions here. // BOOST_UBLAS_CHECK (r1_.start () <= data_.size1 () && // r1_.start () + r1_.size () <= data_.size1 (), bad_index ()); // BOOST_UBLAS_CHECK (r2_.start () <= data_.size2 () && // r2_.start () + r2_.size () <= data_.size2 (), bad_index ()); // BOOST_UBLAS_CHECK (r1_.size () == r2_.size (), bad_size ()); } // Accessors BOOST_UBLAS_INLINE size_type start1 () const { return r1_.start (); } BOOST_UBLAS_INLINE size_type start2 () const { return r2_.start (); } BOOST_UBLAS_INLINE size_type size () const { return BOOST_UBLAS_SAME (r1_.size (), r2_.size ()); } // Storage accessors BOOST_UBLAS_INLINE const matrix_closure_type &data () const { return data_; } BOOST_UBLAS_INLINE matrix_closure_type &data () { return data_; } // Element access #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER BOOST_UBLAS_INLINE const_reference operator () (size_type i) const { return data_ (r1_ (i), r2_ (i)); } BOOST_UBLAS_INLINE reference operator () (size_type i) { return data_ (r1_ (i), r2_ (i)); } BOOST_UBLAS_INLINE const_reference operator [] (size_type i) const { return (*this) (i); } BOOST_UBLAS_INLINE reference operator [] (size_type i) { return (*this) (i); } #else BOOST_UBLAS_INLINE reference operator () (size_type i) const { return data_ (r1_ (i), r2_ (i)); } BOOST_UBLAS_INLINE reference operator [] (size_type i) const { return (*this) (i); } #endif // Assignment BOOST_UBLAS_INLINE matrix_vector_range &operator = (const matrix_vector_range &mvr) { // ISSUE need a temporary, proxy can be overlaping alias vector_assign
(*this, typename vector_temporary_traits
::type (mvr)); return *this; } BOOST_UBLAS_INLINE matrix_vector_range &assign_temporary (matrix_vector_range &mvr) { // assign elements, proxied container remains the same vector_assign
(*this, mvr); return *this; } template
BOOST_UBLAS_INLINE matrix_vector_range &operator = (const vector_expression
&ae) { vector_assign
(*this, typename vector_temporary_traits
::type (ae)); return *this; } template
BOOST_UBLAS_INLINE matrix_vector_range &assign (const vector_expression
&ae) { vector_assign
(*this, ae); return *this; } template
BOOST_UBLAS_INLINE matrix_vector_range &operator += (const vector_expression
&ae) { vector_assign
(*this, typename vector_temporary_traits
::type (*this + ae)); return *this; } template
BOOST_UBLAS_INLINE matrix_vector_range &plus_assign (const vector_expression
&ae) { vector_assign
(*this, ae); return *this; } template
BOOST_UBLAS_INLINE matrix_vector_range &operator -= (const vector_expression
&ae) { vector_assign
(*this, typename vector_temporary_traits
::type (*this - ae)); return *this; } template
BOOST_UBLAS_INLINE matrix_vector_range &minus_assign (const vector_expression
&ae) { vector_assign
(*this, ae); return *this; } template
BOOST_UBLAS_INLINE matrix_vector_range &operator *= (const AT &at) { vector_assign_scalar
(*this, at); return *this; } template
BOOST_UBLAS_INLINE matrix_vector_range &operator /= (const AT &at) { vector_assign_scalar
(*this, at); return *this; } // Closure comparison BOOST_UBLAS_INLINE bool same_closure (const matrix_vector_range &mvr) const { return (*this).data_.same_closure (mvr.data_); } // Comparison BOOST_UBLAS_INLINE bool operator == (const matrix_vector_range &mvr) const { return (*this).data_ == mvr.data_ && r1_ == mvr.r1_ && r2_ == mvr.r2_; } // Swapping BOOST_UBLAS_INLINE void swap (matrix_vector_range mvr) { if (this != &mvr) { BOOST_UBLAS_CHECK (size () == mvr.size (), bad_size ()); // Sparse ranges may be nonconformant now. // std::swap_ranges (begin (), end (), mvr.begin ()); vector_swap
(*this, mvr); } } BOOST_UBLAS_INLINE friend void swap (matrix_vector_range mvr1, matrix_vector_range mvr2) { mvr1.swap (mvr2); } // Iterator types private: // Use range as an index - FIXME this fails for packed assignment typedef typename range_type::const_iterator const_subiterator1_type; typedef typename range_type::const_iterator subiterator1_type; typedef typename range_type::const_iterator const_subiterator2_type; typedef typename range_type::const_iterator subiterator2_type; public: class const_iterator; class iterator; // Element lookup BOOST_UBLAS_INLINE const_iterator find (size_type i) const { return const_iterator (*this, r1_.begin () + i, r2_.begin () + i); } BOOST_UBLAS_INLINE iterator find (size_type i) { return iterator (*this, r1_.begin () + i, r2_.begin () + i); } class const_iterator: public container_const_reference
, public iterator_base_traits
::template iterator_base
::type { public: // FIXME Iterator can never be different code was: // typename iterator_restrict_traits
::iterator_category> BOOST_STATIC_ASSERT ((boost::is_same
::value )); typedef typename matrix_vector_range::value_type value_type; typedef typename matrix_vector_range::difference_type difference_type; typedef typename matrix_vector_range::const_reference reference; typedef const typename matrix_vector_range::value_type *pointer; // Construction and destruction BOOST_UBLAS_INLINE const_iterator (): container_const_reference
(), it1_ (), it2_ () {} BOOST_UBLAS_INLINE const_iterator (const self_type &mvr, const const_subiterator1_type &it1, const const_subiterator2_type &it2): container_const_reference
(mvr), it1_ (it1), it2_ (it2) {} BOOST_UBLAS_INLINE const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here container_const_reference
(it ()), it1_ (it.it1_), it2_ (it.it2_) {} // Arithmetic BOOST_UBLAS_INLINE const_iterator &operator ++ () { ++ it1_; ++ it2_; return *this; } BOOST_UBLAS_INLINE const_iterator &operator -- () { -- it1_; -- it2_; return *this; } BOOST_UBLAS_INLINE const_iterator &operator += (difference_type n) { it1_ += n; it2_ += n; return *this; } BOOST_UBLAS_INLINE const_iterator &operator -= (difference_type n) { it1_ -= n; it2_ -= n; return *this; } BOOST_UBLAS_INLINE difference_type operator - (const const_iterator &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return BOOST_UBLAS_SAME (it1_ - it.it1_, it2_ - it.it2_); } // Dereference BOOST_UBLAS_INLINE const_reference operator * () const { // FIXME replace find with at_element return (*this) ().data_ (*it1_, *it2_); } BOOST_UBLAS_INLINE const_reference operator [] (difference_type n) const { return *(*this + n); } // Index BOOST_UBLAS_INLINE size_type index () const { return BOOST_UBLAS_SAME (it1_.index (), it2_.index ()); } // Assignment BOOST_UBLAS_INLINE const_iterator &operator = (const const_iterator &it) { container_const_reference
::assign (&it ()); it1_ = it.it1_; it2_ = it.it2_; return *this; } // Comparison BOOST_UBLAS_INLINE bool operator == (const const_iterator &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return it1_ == it.it1_ && it2_ == it.it2_; } BOOST_UBLAS_INLINE bool operator < (const const_iterator &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return it1_ < it.it1_ && it2_ < it.it2_; } private: const_subiterator1_type it1_; const_subiterator2_type it2_; }; BOOST_UBLAS_INLINE const_iterator begin () const { return find (0); } BOOST_UBLAS_INLINE const_iterator end () const { return find (size ()); } class iterator: public container_reference
, public iterator_base_traits
::template iterator_base
::type { public: // FIXME Iterator can never be different code was: // typename iterator_restrict_traits
::iterator_category> BOOST_STATIC_ASSERT ((boost::is_same
::value )); typedef typename matrix_vector_range::value_type value_type; typedef typename matrix_vector_range::difference_type difference_type; typedef typename matrix_vector_range::reference reference; typedef typename matrix_vector_range::value_type *pointer; // Construction and destruction BOOST_UBLAS_INLINE iterator (): container_reference
(), it1_ (), it2_ () {} BOOST_UBLAS_INLINE iterator (self_type &mvr, const subiterator1_type &it1, const subiterator2_type &it2): container_reference
(mvr), it1_ (it1), it2_ (it2) {} // Arithmetic BOOST_UBLAS_INLINE iterator &operator ++ () { ++ it1_; ++ it2_; return *this; } BOOST_UBLAS_INLINE iterator &operator -- () { -- it1_; -- it2_; return *this; } BOOST_UBLAS_INLINE iterator &operator += (difference_type n) { it1_ += n; it2_ += n; return *this; } BOOST_UBLAS_INLINE iterator &operator -= (difference_type n) { it1_ -= n; it2_ -= n; return *this; } BOOST_UBLAS_INLINE difference_type operator - (const iterator &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return BOOST_UBLAS_SAME (it1_ - it.it1_, it2_ - it.it2_); } // Dereference BOOST_UBLAS_INLINE reference operator * () const { // FIXME replace find with at_element return (*this) ().data_ (*it1_, *it2_); } BOOST_UBLAS_INLINE reference operator [] (difference_type n) const { return *(*this + n); } // Index BOOST_UBLAS_INLINE size_type index () const { return BOOST_UBLAS_SAME (it1_.index (), it2_.index ()); } // Assignment BOOST_UBLAS_INLINE iterator &operator = (const iterator &it) { container_reference
::assign (&it ()); it1_ = it.it1_; it2_ = it.it2_; return *this; } // Comparison BOOST_UBLAS_INLINE bool operator == (const iterator &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return it1_ == it.it1_ && it2_ == it.it2_; } BOOST_UBLAS_INLINE bool operator < (const iterator &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return it1_ < it.it1_ && it2_ < it.it2_; } private: subiterator1_type it1_; subiterator2_type it2_; friend class const_iterator; }; BOOST_UBLAS_INLINE iterator begin () { return find (0); } BOOST_UBLAS_INLINE iterator end () { return find (size ()); } // Reverse iterator typedef reverse_iterator_base
const_reverse_iterator; typedef reverse_iterator_base
reverse_iterator; BOOST_UBLAS_INLINE const_reverse_iterator rbegin () const { return const_reverse_iterator (end ()); } BOOST_UBLAS_INLINE const_reverse_iterator rend () const { return const_reverse_iterator (begin ()); } BOOST_UBLAS_INLINE reverse_iterator rbegin () { return reverse_iterator (end ()); } BOOST_UBLAS_INLINE reverse_iterator rend () { return reverse_iterator (begin ()); } private: matrix_closure_type data_; range_type r1_; range_type r2_; }; // Specialize temporary template
struct vector_temporary_traits< matrix_vector_range
> : vector_temporary_traits< M > {} ; template
struct vector_temporary_traits< const matrix_vector_range
> : vector_temporary_traits< M > {} ; // Matrix based vector slice class template
class matrix_vector_slice: public vector_expression
> { typedef matrix_vector_slice
self_type; public: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS using vector_expression
::operator (); #endif typedef M matrix_type; typedef typename M::size_type size_type; typedef typename M::difference_type difference_type; typedef typename M::value_type value_type; typedef typename M::const_reference const_reference; typedef typename boost::mpl::if_
, typename M::const_reference, typename M::reference>::type reference; typedef typename boost::mpl::if_
, typename M::const_closure_type, typename M::closure_type>::type matrix_closure_type; typedef basic_range
range_type; typedef basic_slice
slice_type; typedef const self_type const_closure_type; typedef self_type closure_type; typedef typename storage_restrict_traits
::storage_category storage_category; // Construction and destruction BOOST_UBLAS_INLINE matrix_vector_slice (matrix_type &data, const slice_type &s1, const slice_type &s2): data_ (data), s1_ (s1.preprocess (data.size1 ())), s2_ (s2.preprocess (data.size2 ())) { // Early checking of preconditions here. // BOOST_UBLAS_CHECK (s1_.start () <= data_.size1 () && // s1_.start () + s1_.stride () * (s1_.size () - (s1_.size () > 0)) <= data_.size1 (), bad_index ()); // BOOST_UBLAS_CHECK (s2_.start () <= data_.size2 () && // s2_.start () + s2_.stride () * (s2_.size () - (s2_.size () > 0)) <= data_.size2 (), bad_index ()); } // Accessors BOOST_UBLAS_INLINE size_type start1 () const { return s1_.start (); } BOOST_UBLAS_INLINE size_type start2 () const { return s2_.start (); } BOOST_UBLAS_INLINE difference_type stride1 () const { return s1_.stride (); } BOOST_UBLAS_INLINE difference_type stride2 () const { return s2_.stride (); } BOOST_UBLAS_INLINE size_type size () const { return BOOST_UBLAS_SAME (s1_.size (), s2_.size ()); } // Storage accessors BOOST_UBLAS_INLINE const matrix_closure_type &data () const { return data_; } BOOST_UBLAS_INLINE matrix_closure_type &data () { return data_; } // Element access #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER BOOST_UBLAS_INLINE const_reference operator () (size_type i) const { return data_ (s1_ (i), s2_ (i)); } BOOST_UBLAS_INLINE reference operator () (size_type i) { return data_ (s1_ (i), s2_ (i)); } BOOST_UBLAS_INLINE const_reference operator [] (size_type i) const { return (*this) (i); } BOOST_UBLAS_INLINE reference operator [] (size_type i) { return (*this) (i); } #else BOOST_UBLAS_INLINE reference operator () (size_type i) const { return data_ (s1_ (i), s2_ (i)); } BOOST_UBLAS_INLINE reference operator [] (size_type i) const { return (*this) (i); } #endif // Assignment BOOST_UBLAS_INLINE matrix_vector_slice &operator = (const matrix_vector_slice &mvs) { // ISSUE need a temporary, proxy can be overlaping alias vector_assign
(*this, typename vector_temporary_traits
::type (mvs)); return *this; } BOOST_UBLAS_INLINE matrix_vector_slice &assign_temporary (matrix_vector_slice &mvs) { // assign elements, proxied container remains the same vector_assign
(*this, mvs); return *this; } template
BOOST_UBLAS_INLINE matrix_vector_slice &operator = (const vector_expression
&ae) { vector_assign
(*this, typename vector_temporary_traits
::type (ae)); return *this; } template
BOOST_UBLAS_INLINE matrix_vector_slice &assign (const vector_expression
&ae) { vector_assign
(*this, ae); return *this; } template
BOOST_UBLAS_INLINE matrix_vector_slice &operator += (const vector_expression
&ae) { vector_assign
(*this, typename vector_temporary_traits
::type (*this + ae)); return *this; } template
BOOST_UBLAS_INLINE matrix_vector_slice &plus_assign (const vector_expression
&ae) { vector_assign
(*this, ae); return *this; } template
BOOST_UBLAS_INLINE matrix_vector_slice &operator -= (const vector_expression
&ae) { vector_assign
(*this, typename vector_temporary_traits
::type (*this - ae)); return *this; } template
BOOST_UBLAS_INLINE matrix_vector_slice &minus_assign (const vector_expression
&ae) { vector_assign
(*this, ae); return *this; } template
BOOST_UBLAS_INLINE matrix_vector_slice &operator *= (const AT &at) { vector_assign_scalar
(*this, at); return *this; } template
BOOST_UBLAS_INLINE matrix_vector_slice &operator /= (const AT &at) { vector_assign_scalar
(*this, at); return *this; } // Closure comparison BOOST_UBLAS_INLINE bool same_closure (const matrix_vector_slice &mvs) const { return (*this).data_.same_closure (mvs.data_); } // Comparison BOOST_UBLAS_INLINE bool operator == (const matrix_vector_slice &mvs) const { return (*this).data_ == mvs.data_ && s1_ == mvs.s1_ && s2_ == mvs.s2_; } // Swapping BOOST_UBLAS_INLINE void swap (matrix_vector_slice mvs) { if (this != &mvs) { BOOST_UBLAS_CHECK (size () == mvs.size (), bad_size ()); // Sparse ranges may be nonconformant now. // std::swap_ranges (begin (), end (), mvs.begin ()); vector_swap
(*this, mvs); } } BOOST_UBLAS_INLINE friend void swap (matrix_vector_slice mvs1, matrix_vector_slice mvs2) { mvs1.swap (mvs2); } // Iterator types private: // Use slice as an index - FIXME this fails for packed assignment typedef typename slice_type::const_iterator const_subiterator1_type; typedef typename slice_type::const_iterator subiterator1_type; typedef typename slice_type::const_iterator const_subiterator2_type; typedef typename slice_type::const_iterator subiterator2_type; public: class const_iterator; class iterator; // Element lookup BOOST_UBLAS_INLINE const_iterator find (size_type i) const { return const_iterator (*this, s1_.begin () + i, s2_.begin () + i); } BOOST_UBLAS_INLINE iterator find (size_type i) { return iterator (*this, s1_.begin () + i, s2_.begin () + i); } // Iterators simply are indices. class const_iterator: public container_const_reference
, public iterator_base_traits
::template iterator_base
::type { public: // FIXME Iterator can never be different code was: // typename iterator_restrict_traits
::iterator_category> BOOST_STATIC_ASSERT ((boost::is_same
::value )); typedef typename matrix_vector_slice::value_type value_type; typedef typename matrix_vector_slice::difference_type difference_type; typedef typename matrix_vector_slice::const_reference reference; typedef const typename matrix_vector_slice::value_type *pointer; // Construction and destruction BOOST_UBLAS_INLINE const_iterator (): container_const_reference
(), it1_ (), it2_ () {} BOOST_UBLAS_INLINE const_iterator (const self_type &mvs, const const_subiterator1_type &it1, const const_subiterator2_type &it2): container_const_reference
(mvs), it1_ (it1), it2_ (it2) {} BOOST_UBLAS_INLINE const_iterator (const typename self_type::iterator &it): // ISSUE vector:: stops VC8 using std::iterator here container_const_reference
(it ()), it1_ (it.it1_), it2_ (it.it2_) {} // Arithmetic BOOST_UBLAS_INLINE const_iterator &operator ++ () { ++ it1_; ++ it2_; return *this; } BOOST_UBLAS_INLINE const_iterator &operator -- () { -- it1_; -- it2_; return *this; } BOOST_UBLAS_INLINE const_iterator &operator += (difference_type n) { it1_ += n; it2_ += n; return *this; } BOOST_UBLAS_INLINE const_iterator &operator -= (difference_type n) { it1_ -= n; it2_ -= n; return *this; } BOOST_UBLAS_INLINE difference_type operator - (const const_iterator &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return BOOST_UBLAS_SAME (it1_ - it.it1_, it2_ - it.it2_); } // Dereference BOOST_UBLAS_INLINE const_reference operator * () const { // FIXME replace find with at_element return (*this) ().data_ (*it1_, *it2_); } BOOST_UBLAS_INLINE const_reference operator [] (difference_type n) const { return *(*this + n); } // Index BOOST_UBLAS_INLINE size_type index () const { return BOOST_UBLAS_SAME (it1_.index (), it2_.index ()); } // Assignment BOOST_UBLAS_INLINE const_iterator &operator = (const const_iterator &it) { container_const_reference
::assign (&it ()); it1_ = it.it1_; it2_ = it.it2_; return *this; } // Comparison BOOST_UBLAS_INLINE bool operator == (const const_iterator &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return it1_ == it.it1_ && it2_ == it.it2_; } BOOST_UBLAS_INLINE bool operator < (const const_iterator &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return it1_ < it.it1_ && it2_ < it.it2_; } private: const_subiterator1_type it1_; const_subiterator2_type it2_; }; BOOST_UBLAS_INLINE const_iterator begin () const { return find (0); } BOOST_UBLAS_INLINE const_iterator end () const { return find (size ()); } class iterator: public container_reference
, public iterator_base_traits
::template iterator_base
::type { public: // FIXME Iterator can never be different code was: // typename iterator_restrict_traits
::iterator_category> BOOST_STATIC_ASSERT ((boost::is_same
::value )); typedef typename matrix_vector_slice::value_type value_type; typedef typename matrix_vector_slice::difference_type difference_type; typedef typename matrix_vector_slice::reference reference; typedef typename matrix_vector_slice::value_type *pointer; // Construction and destruction BOOST_UBLAS_INLINE iterator (): container_reference
(), it1_ (), it2_ () {} BOOST_UBLAS_INLINE iterator (self_type &mvs, const subiterator1_type &it1, const subiterator2_type &it2): container_reference