Boost.uBlas 1.49
Linear Algebra in C++: matrices, vectors and numeric algorithms

vector.hpp

Go to the documentation of this file.
00001 //  Copyright (c) 2000-2011 Joerg Walter, Mathias Koch, David Bellot
00002 //
00003 //  Distributed under the Boost Software License, Version 1.0. (See
00004 //  accompanying file LICENSE_1_0.txt or copy at
00005 //  http://www.boost.org/LICENSE_1_0.txt)
00006 
00007 #ifndef _BOOST_UBLAS_VECTOR_
00008 #define _BOOST_UBLAS_VECTOR_
00009 
00010 #include <boost/numeric/ublas/storage.hpp>
00011 #include <boost/numeric/ublas/vector_expression.hpp>
00012 #include <boost/numeric/ublas/detail/vector_assign.hpp>
00013 #include <boost/serialization/collection_size_type.hpp>
00014 #include <boost/serialization/nvp.hpp>
00015 
00016 
00017 // Iterators based on ideas of Jeremy Siek
00018 
00019 namespace boost { namespace numeric { namespace ublas {
00020 
00030     template<class T, class A>
00031     class vector:
00032         public vector_container<vector<T, A> > {
00033 
00034         typedef vector<T, A> self_type;
00035     public:
00036 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
00037         using vector_container<self_type>::operator ();
00038 #endif
00039 
00040     typedef typename A::size_type size_type;
00041         typedef typename A::difference_type difference_type;
00042         typedef T value_type;
00043         typedef typename type_traits<T>::const_reference const_reference;
00044         typedef T &reference;
00045         typedef T *pointer;
00046         typedef const T *const_pointer;
00047         typedef A array_type;
00048         typedef const vector_reference<const self_type> const_closure_type;
00049         typedef vector_reference<self_type> closure_type;
00050         typedef self_type vector_temporary_type;
00051         typedef dense_tag storage_category;
00052 
00053         // Construction and destruction
00054     
00057         BOOST_UBLAS_INLINE
00058         vector ():
00059             vector_container<self_type> (),
00060             data_ () {}
00061 
00065         explicit BOOST_UBLAS_INLINE
00066         vector (size_type size):
00067             vector_container<self_type> (),
00068             data_ (size) {
00069         }
00070 
00076         BOOST_UBLAS_INLINE
00077         vector (size_type size, const array_type &data):
00078             vector_container<self_type> (),
00079             data_ (data) {}
00080 
00084         BOOST_UBLAS_INLINE
00085         vector (const array_type &data):
00086             vector_container<self_type> (),
00087             data_ (data) {}
00088 
00092         BOOST_UBLAS_INLINE
00093         vector (size_type size, const value_type &init):
00094             vector_container<self_type> (),
00095             data_ (size, init) {}
00096 
00099         BOOST_UBLAS_INLINE
00100         vector (const vector &v):
00101             vector_container<self_type> (),
00102             data_ (v.data_) {}
00103 
00108         template<class AE>
00109         BOOST_UBLAS_INLINE
00110         vector (const vector_expression<AE> &ae):
00111             vector_container<self_type> (),
00112             data_ (ae ().size ()) {
00113             vector_assign<scalar_assign> (*this, ae);
00114         }
00115 
00116     // -----------------------
00117         // Random Access Container
00118     // -----------------------
00119     
00122         BOOST_UBLAS_INLINE
00123         size_type max_size () const {
00124             return data_.max_size ();
00125         }
00126         
00129         BOOST_UBLAS_INLINE
00130         bool empty () const {
00131             return data_.size () == 0;
00132         }
00133 
00134     // ---------
00135         // Accessors
00136     // ---------
00137     
00139         BOOST_UBLAS_INLINE
00140         size_type size () const {
00141             return data_.size ();
00142         }
00143 
00144     // -----------------
00145         // Storage accessors
00146     // -----------------
00147     
00149         BOOST_UBLAS_INLINE
00150         const array_type &data () const {
00151             return data_;
00152         }
00153 
00155         BOOST_UBLAS_INLINE
00156         array_type &data () {
00157             return data_;
00158         }
00159 
00160     // --------
00161         // Resizing
00162     // --------
00163     
00168         BOOST_UBLAS_INLINE
00169         void resize (size_type size, bool preserve = true) {
00170             if (preserve)
00171                 data ().resize (size, typename A::value_type ());
00172             else
00173                 data ().resize (size);
00174         }
00175 
00176     // ---------------
00177         // Element support
00178     // ---------------
00179     
00182     // XXX this semantic is not the one expected by the name of this method
00183         BOOST_UBLAS_INLINE
00184         pointer find_element (size_type i) {
00185             return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i));
00186         }
00187 
00190     // XXX  this semantic is not the one expected by the name of this method
00191         BOOST_UBLAS_INLINE
00192         const_pointer find_element (size_type i) const {
00193             return & (data () [i]);
00194         }
00195 
00196     // --------------
00197         // Element access
00198     // --------------
00199 
00203         BOOST_UBLAS_INLINE
00204         const_reference operator () (size_type i) const {
00205             return data () [i];
00206         }
00207     
00211         BOOST_UBLAS_INLINE
00212         reference operator () (size_type i) {
00213             return data () [i];
00214         }
00215 
00218         BOOST_UBLAS_INLINE
00219         const_reference operator [] (size_type i) const {
00220             return (*this) (i);
00221         }
00222     
00225         BOOST_UBLAS_INLINE
00226         reference operator [] (size_type i) {
00227             return (*this) (i);
00228         }
00229 
00230     // ------------------
00231         // Element assignment
00232     // ------------------
00233     
00237     // XXX semantic of this is to insert a new element and therefore size=size+1 ?
00238         BOOST_UBLAS_INLINE
00239         reference insert_element (size_type i, const_reference t) {
00240             return (data () [i] = t);
00241         }
00242 
00245         BOOST_UBLAS_INLINE
00246         void erase_element (size_type i) {
00247             data () [i] = value_type/*zero*/();
00248         }
00249         
00250     // -------
00251         // Zeroing
00252     // -------
00253     
00255         BOOST_UBLAS_INLINE
00256         void clear () {
00257             std::fill (data ().begin (), data ().end (), value_type/*zero*/());
00258         }
00259 
00260         // Assignment
00261 #ifdef BOOST_UBLAS_MOVE_SEMANTICS
00262 
00266 
00267         BOOST_UBLAS_INLINE
00268         vector &operator = (vector v) {
00269             assign_temporary(v);
00270             return *this;
00271         }
00272 #else
00273 
00274 
00275 
00276         BOOST_UBLAS_INLINE
00277         vector &operator = (const vector &v) {
00278             data () = v.data ();
00279             return *this;
00280         }
00281 #endif
00282 
00287         template<class C>          // Container assignment without temporary
00288         BOOST_UBLAS_INLINE
00289         vector &operator = (const vector_container<C> &v) {
00290             resize (v ().size (), false);
00291             assign (v);
00292             return *this;
00293         }
00294 
00298         BOOST_UBLAS_INLINE
00299         vector &assign_temporary (vector &v) {
00300             swap (v);
00301             return *this;
00302         }
00303 
00309         template<class AE>
00310         BOOST_UBLAS_INLINE
00311         vector &operator = (const vector_expression<AE> &ae) {
00312             self_type temporary (ae);
00313             return assign_temporary (temporary);
00314         }
00315 
00321         template<class AE>
00322         BOOST_UBLAS_INLINE
00323         vector &assign (const vector_expression<AE> &ae) {
00324             vector_assign<scalar_assign> (*this, ae);
00325             return *this;
00326         }
00327 
00328     // -------------------
00329         // Computed assignment
00330     // -------------------
00331     
00338         template<class AE>
00339         BOOST_UBLAS_INLINE
00340         vector &operator += (const vector_expression<AE> &ae) {
00341             self_type temporary (*this + ae);
00342             return assign_temporary (temporary);
00343         }
00344 
00351         template<class C>          // Container assignment without temporary
00352         BOOST_UBLAS_INLINE
00353         vector &operator += (const vector_container<C> &v) {
00354             plus_assign (v);
00355             return *this;
00356         }
00357 
00364         template<class AE>
00365         BOOST_UBLAS_INLINE
00366         vector &plus_assign (const vector_expression<AE> &ae) {
00367             vector_assign<scalar_plus_assign> (*this, ae);
00368             return *this;
00369         }
00370     
00376         template<class AE>
00377         BOOST_UBLAS_INLINE
00378         vector &operator -= (const vector_expression<AE> &ae) {
00379             self_type temporary (*this - ae);
00380             return assign_temporary (temporary);
00381         }
00382 
00389         template<class C>          // Container assignment without temporary
00390         BOOST_UBLAS_INLINE
00391         vector &operator -= (const vector_container<C> &v) {
00392             minus_assign (v);
00393             return *this;
00394         }
00395 
00402         template<class AE>
00403         BOOST_UBLAS_INLINE
00404         vector &minus_assign (const vector_expression<AE> &ae) {
00405             vector_assign<scalar_minus_assign> (*this, ae);
00406             return *this;
00407         }
00408 
00415         template<class AT>
00416         BOOST_UBLAS_INLINE
00417         vector &operator *= (const AT &at) {
00418             vector_assign_scalar<scalar_multiplies_assign> (*this, at);
00419             return *this;
00420         }
00421 
00428         template<class AT>
00429         BOOST_UBLAS_INLINE
00430         vector &operator /= (const AT &at) {
00431             vector_assign_scalar<scalar_divides_assign> (*this, at);
00432             return *this;
00433         }
00434 
00435     // --------
00436         // Swapping
00437     // --------
00438 
00441         BOOST_UBLAS_INLINE
00442         void swap (vector &v) {
00443             if (this != &v) {
00444                 data ().swap (v.data ());
00445             }
00446         }
00447 
00451         BOOST_UBLAS_INLINE
00452         friend void swap (vector &v1, vector &v2) {
00453             v1.swap (v2);
00454         }
00455 
00456         // Iterator types
00457     private:
00458         // Use the storage array iterator
00459         typedef typename A::const_iterator const_subiterator_type;
00460         typedef typename A::iterator subiterator_type;
00461 
00462     public:
00463 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
00464         typedef indexed_iterator<self_type, dense_random_access_iterator_tag> iterator;
00465         typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
00466 #else
00467         class const_iterator;
00468         class iterator;
00469 #endif
00470 
00471     // --------------
00472         // Element lookup
00473     // --------------
00474     
00477         BOOST_UBLAS_INLINE
00478         const_iterator find (size_type i) const {
00479 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
00480             return const_iterator (*this, data ().begin () + i);
00481 #else
00482             return const_iterator (*this, i);
00483 #endif
00484         }
00485 
00488         BOOST_UBLAS_INLINE
00489         iterator find (size_type i) {
00490 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
00491             return iterator (*this, data ().begin () + i);
00492 #else
00493             return iterator (*this, i);
00494 #endif
00495         }
00496 
00497 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
00498         class const_iterator:
00499             public container_const_reference<vector>,
00500             public random_access_iterator_base<dense_random_access_iterator_tag,
00501                    const_iterator, value_type, difference_type> {
00502         public:
00503             typedef typename vector::difference_type difference_type;
00504             typedef typename vector::value_type value_type;
00505             typedef typename vector::const_reference reference;
00506             typedef const typename vector::pointer pointer;
00507 
00508         // ----------------------------
00509             // Construction and destruction
00510         // ----------------------------
00511 
00512 
00513             BOOST_UBLAS_INLINE
00514             const_iterator ():
00515                 container_const_reference<self_type> (), it_ () {}
00516             BOOST_UBLAS_INLINE
00517             const_iterator (const self_type &v, const const_subiterator_type &it):
00518                 container_const_reference<self_type> (v), it_ (it) {}
00519             BOOST_UBLAS_INLINE
00520             const_iterator (const typename self_type::iterator &it):  // ISSUE vector:: stops VC8 using std::iterator here
00521                 container_const_reference<self_type> (it ()), it_ (it.it_) {}
00522 
00523         // ----------
00524             // Arithmetic
00525         // ----------
00526 
00529             BOOST_UBLAS_INLINE
00530             const_iterator &operator ++ () {
00531                 ++ it_;
00532                 return *this;
00533             }
00534 
00537             BOOST_UBLAS_INLINE
00538             const_iterator &operator -- () {
00539                 -- it_;
00540                 return *this;
00541             }
00542       
00545             BOOST_UBLAS_INLINE
00546             const_iterator &operator += (difference_type n) {
00547                 it_ += n;
00548                 return *this;
00549             }
00550 
00553             BOOST_UBLAS_INLINE
00554             const_iterator &operator -= (difference_type n) {
00555                 it_ -= n;
00556                 return *this;
00557             }
00558 
00560             BOOST_UBLAS_INLINE
00561             difference_type operator - (const const_iterator &it) const {
00562                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00563                 return it_ - it.it_;
00564             }
00565 
00569             BOOST_UBLAS_INLINE
00570             const_reference operator * () const {
00571                 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
00572                 return *it_;
00573             }
00574 
00579             BOOST_UBLAS_INLINE
00580             const_reference operator [] (difference_type n) const {
00581                 return *(it_ + n);
00582             }
00583 
00584             // Index
00586             BOOST_UBLAS_INLINE
00587             size_type index () const {
00588                 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
00589                 return it_ - (*this) ().begin ().it_;
00590             }
00591 
00592             // Assignment
00593             BOOST_UBLAS_INLINE
00595             const_iterator &operator = (const const_iterator &it) {
00596                 container_const_reference<self_type>::assign (&it ());
00597                 it_ = it.it_;
00598                 return *this;
00599             }
00600 
00601             // Comparison
00604             BOOST_UBLAS_INLINE
00605             bool operator == (const const_iterator &it) const {
00606                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00607                 return it_ == it.it_;
00608             }
00609 
00610     
00613             BOOST_UBLAS_INLINE
00614             bool operator < (const const_iterator &it) const {
00615                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00616                 return it_ < it.it_;
00617             }
00618 
00619         private:
00620             const_subiterator_type it_;
00621 
00622             friend class iterator;
00623         };
00624 #endif
00625 
00627         BOOST_UBLAS_INLINE
00628         const_iterator begin () const {
00629             return find (0);
00630         }
00631 
00633         BOOST_UBLAS_INLINE
00634         const_iterator end () const {
00635             return find (data_.size ());
00636         }
00637 
00638 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
00639         class iterator:
00640             public container_reference<vector>,
00641             public random_access_iterator_base<dense_random_access_iterator_tag,
00642                                                iterator, value_type, difference_type> {
00643         public:
00644             typedef typename vector::difference_type difference_type;
00645             typedef typename vector::value_type value_type;
00646             typedef typename vector::reference reference;
00647             typedef typename vector::pointer pointer;
00648 
00649 
00650             // Construction and destruction
00651             BOOST_UBLAS_INLINE
00652             iterator ():
00653                 container_reference<self_type> (), it_ () {}
00654             BOOST_UBLAS_INLINE
00655             iterator (self_type &v, const subiterator_type &it):
00656                 container_reference<self_type> (v), it_ (it) {}
00657 
00658             // Arithmetic
00659             BOOST_UBLAS_INLINE
00660             iterator &operator ++ () {
00661                 ++ it_;
00662                 return *this;
00663             }
00664             BOOST_UBLAS_INLINE
00665             iterator &operator -- () {
00666                 -- it_;
00667                 return *this;
00668             }
00669             BOOST_UBLAS_INLINE
00670             iterator &operator += (difference_type n) {
00671                 it_ += n;
00672                 return *this;
00673             }
00674             BOOST_UBLAS_INLINE
00675             iterator &operator -= (difference_type n) {
00676                 it_ -= n;
00677                 return *this;
00678             }
00679             BOOST_UBLAS_INLINE
00680             difference_type operator - (const iterator &it) const {
00681                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00682                 return it_ - it.it_;
00683             }
00684 
00685             // Dereference
00686             BOOST_UBLAS_INLINE
00687             reference operator * () const {
00688                 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ());
00689                 return *it_;
00690             }
00691             BOOST_UBLAS_INLINE
00692             reference operator [] (difference_type n) const {
00693                 return *(it_ + n);
00694             }
00695 
00696             // Index
00697             BOOST_UBLAS_INLINE
00698             size_type index () const {
00699                 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ());
00700                 return it_ - (*this) ().begin ().it_;
00701             }
00702 
00703             // Assignment
00704             BOOST_UBLAS_INLINE
00705             iterator &operator = (const iterator &it) {
00706                 container_reference<self_type>::assign (&it ());
00707                 it_ = it.it_;
00708                 return *this;
00709             }
00710 
00711             // Comparison
00712             BOOST_UBLAS_INLINE
00713             bool operator == (const iterator &it) const {
00714                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00715                 return it_ == it.it_;
00716             }
00717             BOOST_UBLAS_INLINE
00718             bool operator < (const iterator &it) const {
00719                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00720                 return it_ < it.it_;
00721             }
00722 
00723         private:
00724             subiterator_type it_;
00725 
00726             friend class const_iterator;
00727         };
00728 #endif
00729 
00731         BOOST_UBLAS_INLINE
00732         iterator begin () {
00733             return find (0);
00734         }
00735 
00737         BOOST_UBLAS_INLINE
00738         iterator end () {
00739             return find (data_.size ());
00740         }
00741 
00742         // Reverse iterator
00743         typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
00744         typedef reverse_iterator_base<iterator> reverse_iterator;
00745 
00747         BOOST_UBLAS_INLINE
00748         const_reverse_iterator rbegin () const {
00749             return const_reverse_iterator (end ());
00750         }
00751 
00753         BOOST_UBLAS_INLINE
00754         const_reverse_iterator rend () const {
00755             return const_reverse_iterator (begin ());
00756         }
00757 
00759         BOOST_UBLAS_INLINE
00760         reverse_iterator rbegin () {
00761             return reverse_iterator (end ());
00762         }
00763 
00765         BOOST_UBLAS_INLINE
00766         reverse_iterator rend () {
00767             return reverse_iterator (begin ());
00768         }
00769 
00770     // -------------
00771         // Serialization
00772     // -------------
00773     
00777         template<class Archive>
00778         void serialize(Archive & ar, const unsigned int /* file_version */){
00779             ar & serialization::make_nvp("data",data_);
00780         }
00781 
00782     private:
00783         array_type data_;
00784     };
00785 
00786 
00787     // --------------------
00788     // Bounded vector class
00789     // --------------------
00790 
00794     template<class T, std::size_t N>
00795     class bounded_vector:
00796         public vector<T, bounded_array<T, N> > {
00797 
00798         typedef vector<T, bounded_array<T, N> > vector_type;
00799     public:
00800         typedef typename vector_type::size_type size_type;
00801         static const size_type max_size = N;
00802 
00803         // Construction and destruction
00804         BOOST_UBLAS_INLINE
00805         bounded_vector ():
00806             vector_type (N) {}
00807         BOOST_UBLAS_INLINE
00808         bounded_vector (size_type size):
00809             vector_type (size) {}
00810         BOOST_UBLAS_INLINE
00811         bounded_vector (const bounded_vector &v):
00812             vector_type (v) {}
00813         template<class A2>              // Allow vector<T,bounded_array<N> construction
00814         BOOST_UBLAS_INLINE
00815         bounded_vector (const vector<T, A2> &v):
00816             vector_type (v) {}
00817         template<class AE>
00818         BOOST_UBLAS_INLINE
00819         bounded_vector (const vector_expression<AE> &ae):
00820             vector_type (ae) {}
00821         BOOST_UBLAS_INLINE
00822         ~bounded_vector () {}
00823 
00824         // Assignment
00825 #ifdef BOOST_UBLAS_MOVE_SEMANTICS
00826 
00828         BOOST_UBLAS_INLINE
00829         bounded_vector &operator = (bounded_vector v) {
00830             vector_type::operator = (v);
00831             return *this;
00832         }
00833 #else
00834         BOOST_UBLAS_INLINE
00835         bounded_vector &operator = (const bounded_vector &v) {
00836             vector_type::operator = (v);
00837             return *this;
00838         }
00839 #endif
00840         template<class A2>         // Generic vector assignment
00841         BOOST_UBLAS_INLINE
00842         bounded_vector &operator = (const vector<T, A2> &v) {
00843             vector_type::operator = (v);
00844             return *this;
00845         }
00846         template<class C>          // Container assignment without temporary
00847         BOOST_UBLAS_INLINE
00848         bounded_vector &operator = (const vector_container<C> &v) {
00849             vector_type::operator = (v);
00850             return *this;
00851         }
00852         template<class AE>
00853         BOOST_UBLAS_INLINE
00854         bounded_vector &operator = (const vector_expression<AE> &ae) {
00855             vector_type::operator = (ae);
00856             return *this;
00857         }
00858     };
00859 
00860 
00861     // -----------------
00862     // Zero vector class
00863     // -----------------
00864     
00869     template<class T, class ALLOC>
00870     class zero_vector:
00871         public vector_container<zero_vector<T, ALLOC> > {
00872 
00873         typedef const T *const_pointer;
00874         typedef zero_vector<T, ALLOC> self_type;
00875     public:
00876 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
00877         using vector_container<self_type>::operator ();
00878 #endif
00879         typedef typename ALLOC::size_type size_type;
00880         typedef typename ALLOC::difference_type difference_type;
00881         typedef T value_type;
00882         typedef const T &const_reference;
00883         typedef T &reference;
00884         typedef const vector_reference<const self_type> const_closure_type;
00885         typedef vector_reference<self_type> closure_type;
00886         typedef sparse_tag storage_category;
00887 
00888         // Construction and destruction
00889         BOOST_UBLAS_INLINE
00890         zero_vector ():
00891             vector_container<self_type> (),
00892             size_ (0) {}
00893         explicit BOOST_UBLAS_INLINE
00894         zero_vector (size_type size):
00895             vector_container<self_type> (),
00896             size_ (size) {}
00897         BOOST_UBLAS_INLINE
00898         zero_vector (const zero_vector &v):
00899             vector_container<self_type> (),
00900             size_ (v.size_) {}
00901 
00902         // Accessors
00903         BOOST_UBLAS_INLINE
00904         size_type size () const {
00905             return size_;
00906         }
00907 
00908         // Resizing
00909         BOOST_UBLAS_INLINE
00910         void resize (size_type size, bool /*preserve*/ = true) {
00911             size_ = size;
00912         }
00913 
00914         // Element support
00915         BOOST_UBLAS_INLINE
00916         const_pointer find_element (size_type i) const {
00917             return & zero_;
00918         }
00919 
00920         // Element access
00921         BOOST_UBLAS_INLINE
00922         const_reference operator () (size_type /* i */) const {
00923             return zero_;
00924         }
00925 
00926         BOOST_UBLAS_INLINE
00927         const_reference operator [] (size_type i) const {
00928             return (*this) (i);
00929         }
00930 
00931         // Assignment
00932         BOOST_UBLAS_INLINE
00933         zero_vector &operator = (const zero_vector &v) {
00934             size_ = v.size_;
00935             return *this;
00936         }
00937         BOOST_UBLAS_INLINE
00938         zero_vector &assign_temporary (zero_vector &v) {
00939             swap (v);
00940             return *this;
00941         }
00942 
00943         // Swapping
00944         BOOST_UBLAS_INLINE
00945         void swap (zero_vector &v) {
00946             if (this != &v) {
00947                 std::swap (size_, v.size_);
00948             }
00949         }
00950         BOOST_UBLAS_INLINE
00951         friend void swap (zero_vector &v1, zero_vector &v2) {
00952             v1.swap (v2);
00953         }
00954 
00955         // Iterator types
00956     public:
00957         class const_iterator;
00958 
00959         // Element lookup
00960         BOOST_UBLAS_INLINE
00961         const_iterator find (size_type /*i*/) const {
00962             return const_iterator (*this);
00963         }
00964 
00965         class const_iterator:
00966             public container_const_reference<zero_vector>,
00967             public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
00968                                                const_iterator, value_type> {
00969         public:
00970             typedef typename zero_vector::difference_type difference_type;
00971             typedef typename zero_vector::value_type value_type;
00972             typedef typename zero_vector::const_reference reference;
00973             typedef typename zero_vector::const_pointer pointer;
00974 
00975             // Construction and destruction
00976             BOOST_UBLAS_INLINE
00977             const_iterator ():
00978                 container_const_reference<self_type> () {}
00979             BOOST_UBLAS_INLINE
00980             const_iterator (const self_type &v):
00981                 container_const_reference<self_type> (v) {}
00982 
00983             // Arithmetic
00984             BOOST_UBLAS_INLINE
00985             const_iterator &operator ++ () {
00986                 BOOST_UBLAS_CHECK_FALSE (bad_index ());
00987                 return *this;
00988             }
00989             BOOST_UBLAS_INLINE
00990             const_iterator &operator -- () {
00991                 BOOST_UBLAS_CHECK_FALSE (bad_index ());
00992                 return *this;
00993             }
00994 
00995             // Dereference
00996             BOOST_UBLAS_INLINE
00997             const_reference operator * () const {
00998                 BOOST_UBLAS_CHECK_FALSE (bad_index ());
00999                 return zero_;   // arbitary return value
01000             }
01001 
01002             // Index
01003             BOOST_UBLAS_INLINE
01004             size_type index () const {
01005                 BOOST_UBLAS_CHECK_FALSE (bad_index ());
01006                 return 0;   // arbitary return value
01007             }
01008 
01009             // Assignment
01010             BOOST_UBLAS_INLINE
01011             const_iterator &operator = (const const_iterator &it) {
01012                 container_const_reference<self_type>::assign (&it ());
01013                 return *this;
01014             }
01015 
01016             // Comparison
01017             BOOST_UBLAS_INLINE
01018             bool operator == (const const_iterator &it) const {
01019                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01020                 detail::ignore_unused_variable_warning(it);
01021                 return true;
01022             }
01023         };
01024 
01025         typedef const_iterator iterator;
01026 
01027         BOOST_UBLAS_INLINE
01028         const_iterator begin () const {
01029             return const_iterator (*this);
01030         }
01031         BOOST_UBLAS_INLINE
01032         const_iterator end () const {
01033             return const_iterator (*this);
01034         }
01035 
01036         // Reverse iterator
01037         typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
01038 
01039         BOOST_UBLAS_INLINE
01040         const_reverse_iterator rbegin () const {
01041             return const_reverse_iterator (end ());
01042         }
01043         BOOST_UBLAS_INLINE
01044         const_reverse_iterator rend () const {
01045             return const_reverse_iterator (begin ());
01046         }
01047 
01048          // Serialization
01049         template<class Archive>
01050         void serialize(Archive & ar, const unsigned int /* file_version */){
01051             serialization::collection_size_type s (size_);
01052             ar & serialization::make_nvp("size",s);
01053             if (Archive::is_loading::value) {
01054                 size_ = s;
01055             }
01056         }
01057 
01058     private:
01059         size_type size_;
01060         typedef const value_type const_value_type;
01061         static const_value_type zero_;
01062     };
01063 
01064     template<class T, class ALLOC>
01065     typename zero_vector<T, ALLOC>::const_value_type zero_vector<T, ALLOC>::zero_ = T(/*zero*/);
01066 
01067 
01068     // Unit vector class
01074     template<class T, class ALLOC>
01075     class unit_vector:
01076         public vector_container<unit_vector<T, ALLOC> > {
01077 
01078         typedef const T *const_pointer;
01079         typedef unit_vector<T, ALLOC> self_type;
01080     public:
01081 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
01082         using vector_container<self_type>::operator ();
01083 #endif
01084         typedef typename ALLOC::size_type size_type;
01085         typedef typename ALLOC::difference_type difference_type;
01086         typedef T value_type;
01087         typedef const T &const_reference;
01088         typedef T &reference;
01089         typedef const vector_reference<const self_type> const_closure_type;
01090         typedef vector_reference<self_type> closure_type;
01091         typedef sparse_tag storage_category;
01092 
01093         // Construction and destruction
01095         BOOST_UBLAS_INLINE
01096         unit_vector ():
01097             vector_container<self_type> (),
01098             size_ (0), index_ (0) {}
01099 
01103         BOOST_UBLAS_INLINE
01104         explicit unit_vector (size_type size, size_type index = 0):
01105             vector_container<self_type> (),
01106             size_ (size), index_ (index) {}
01107 
01109         BOOST_UBLAS_INLINE
01110         unit_vector (const unit_vector &v):
01111             vector_container<self_type> (),
01112             size_ (v.size_), index_ (v.index_) {}
01113 
01114         // Accessors
01115     //----------
01116     
01118         BOOST_UBLAS_INLINE
01119         size_type size () const {
01120             return size_;
01121         }
01122 
01124         BOOST_UBLAS_INLINE
01125         size_type index () const {
01126             return index_;
01127         }
01128 
01129         // Resizing
01130     // --------
01131     
01134         BOOST_UBLAS_INLINE
01135         void resize (size_type size, bool /*preserve*/ = true) {
01136             size_ = size;
01137         }
01138 
01139         // Element support
01140     // ---------------
01141     
01143         BOOST_UBLAS_INLINE
01144         const_pointer find_element (size_type i) const {
01145             if (i == index_)
01146                 return & one_;
01147             else
01148                 return & zero_;
01149         }
01150 
01151         // Element access
01152         BOOST_UBLAS_INLINE
01153         const_reference operator () (size_type i) const {
01154             if (i == index_)
01155                 return one_;
01156             else
01157                 return zero_;
01158         }
01159 
01160         BOOST_UBLAS_INLINE
01161         const_reference operator [] (size_type i) const {
01162             return (*this) (i);
01163         }
01164 
01165         // Assignment
01166         BOOST_UBLAS_INLINE
01167         unit_vector &operator = (const unit_vector &v) {
01168             size_ = v.size_;
01169             index_ = v.index_;
01170             return *this;
01171         }
01172         BOOST_UBLAS_INLINE
01173         unit_vector &assign_temporary (unit_vector &v) {
01174             swap (v);
01175             return *this;
01176         }
01177 
01178         // Swapping
01179         BOOST_UBLAS_INLINE
01180         void swap (unit_vector &v) {
01181             if (this != &v) {
01182                 std::swap (size_, v.size_);
01183                 std::swap (index_, v.index_);
01184             }
01185         }
01186         BOOST_UBLAS_INLINE
01187         friend void swap (unit_vector &v1, unit_vector &v2) {
01188             v1.swap (v2);
01189         }
01190 
01191         // Iterator types
01192     private:
01193         // Use bool to indicate begin (one_ as value)
01194         typedef bool const_subiterator_type;
01195     public:
01196         class const_iterator;
01197 
01198         // Element lookup
01199         BOOST_UBLAS_INLINE
01200         const_iterator find (size_type i) const {
01201             return const_iterator (*this, i <= index_);
01202         }
01203 
01204         class const_iterator:
01205             public container_const_reference<unit_vector>,
01206             public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
01207                                                const_iterator, value_type> {
01208         public:
01209             typedef typename unit_vector::difference_type difference_type;
01210             typedef typename unit_vector::value_type value_type;
01211             typedef typename unit_vector::const_reference reference;
01212             typedef typename unit_vector::const_pointer pointer;
01213 
01214             // Construction and destruction
01215             BOOST_UBLAS_INLINE
01216             const_iterator ():
01217                 container_const_reference<unit_vector> (), it_ () {}
01218             BOOST_UBLAS_INLINE
01219             const_iterator (const unit_vector &v, const const_subiterator_type &it):
01220                 container_const_reference<unit_vector> (v), it_ (it) {}
01221 
01222             // Arithmetic
01223             BOOST_UBLAS_INLINE
01224             const_iterator &operator ++ () {
01225                 BOOST_UBLAS_CHECK (it_, bad_index ());
01226                 it_ = !it_;
01227                 return *this;
01228             }
01229             BOOST_UBLAS_INLINE
01230             const_iterator &operator -- () {
01231                 BOOST_UBLAS_CHECK (!it_, bad_index ());
01232                 it_ = !it_;
01233                 return *this;
01234             }
01235 
01236             // Dereference
01237             BOOST_UBLAS_INLINE
01238             const_reference operator * () const {
01239                 BOOST_UBLAS_CHECK (it_, bad_index ());
01240                 return one_;
01241             }
01242 
01243             // Index
01244             BOOST_UBLAS_INLINE
01245             size_type index () const {
01246                 BOOST_UBLAS_CHECK (it_, bad_index ());
01247                 return (*this) ().index_;
01248             }
01249 
01250             // Assignment
01251             BOOST_UBLAS_INLINE
01252             const_iterator &operator = (const const_iterator &it) {
01253                 container_const_reference<unit_vector>::assign (&it ());
01254                 it_ = it.it_;
01255                 return *this;
01256             }
01257 
01258             // Comparison
01259             BOOST_UBLAS_INLINE
01260             bool operator == (const const_iterator &it) const {
01261                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01262                 return it_ == it.it_;
01263             }
01264 
01265         private:
01266             const_subiterator_type it_;
01267         };
01268 
01269         typedef const_iterator iterator;
01270 
01271         BOOST_UBLAS_INLINE
01272         const_iterator begin () const {
01273             return const_iterator (*this, true);
01274         }
01275         BOOST_UBLAS_INLINE
01276         const_iterator end () const {
01277             return const_iterator (*this, false);
01278         }
01279 
01280         // Reverse iterator
01281         typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
01282 
01283         BOOST_UBLAS_INLINE
01284         const_reverse_iterator rbegin () const {
01285             return const_reverse_iterator (end ());
01286         }
01287         BOOST_UBLAS_INLINE
01288         const_reverse_iterator rend () const {
01289             return const_reverse_iterator (begin ());
01290         }
01291 
01292          // Serialization
01293         template<class Archive>
01294         void serialize(Archive & ar, const unsigned int /* file_version */){
01295             serialization::collection_size_type s (size_);
01296             ar & serialization::make_nvp("size",s);
01297             if (Archive::is_loading::value) {
01298                 size_ = s;
01299             }
01300             ar & serialization::make_nvp("index", index_);
01301         }
01302 
01303     private:
01304         size_type size_;
01305         size_type index_;
01306         typedef const value_type const_value_type;
01307         static const_value_type zero_;
01308         static const_value_type one_;
01309     };
01310 
01311     template<class T, class ALLOC>
01312     typename unit_vector<T, ALLOC>::const_value_type unit_vector<T, ALLOC>::zero_ = T(/*zero*/);
01313     template<class T, class ALLOC>
01314     typename unit_vector<T, ALLOC>::const_value_type unit_vector<T, ALLOC>::one_ (1);  // ISSUE: need 'one'-traits here
01315 
01321     template<class T, class ALLOC>
01322     class scalar_vector:
01323         public vector_container<scalar_vector<T, ALLOC> > {
01324 
01325         typedef const T *const_pointer;
01326         typedef scalar_vector<T, ALLOC> self_type;
01327     public:
01328 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
01329         using vector_container<self_type>::operator ();
01330 #endif
01331         typedef typename ALLOC::size_type size_type;
01332         typedef typename ALLOC::difference_type difference_type;
01333         typedef T value_type;
01334         typedef const T &const_reference;
01335         typedef T &reference;
01336         typedef const vector_reference<const self_type> const_closure_type;
01337         typedef vector_reference<self_type> closure_type;
01338         typedef dense_tag storage_category;
01339 
01340         // Construction and destruction
01341         BOOST_UBLAS_INLINE
01342         scalar_vector ():
01343             vector_container<self_type> (),
01344             size_ (0), value_ () {}
01345         BOOST_UBLAS_INLINE
01346         explicit scalar_vector (size_type size, const value_type &value = value_type(1)):
01347             vector_container<self_type> (),
01348             size_ (size), value_ (value) {}
01349         BOOST_UBLAS_INLINE
01350         scalar_vector (const scalar_vector &v):
01351             vector_container<self_type> (),
01352             size_ (v.size_), value_ (v.value_) {}
01353 
01354         // Accessors
01355         BOOST_UBLAS_INLINE
01356         size_type size () const {
01357             return size_;
01358         }
01359 
01360         // Resizing
01361         BOOST_UBLAS_INLINE
01362         void resize (size_type size, bool /*preserve*/ = true) {
01363             size_ = size;
01364         }
01365 
01366         // Element support
01367         BOOST_UBLAS_INLINE
01368         const_pointer find_element (size_type /*i*/) const {
01369             return & value_;
01370         }
01371 
01372         // Element access
01373         BOOST_UBLAS_INLINE
01374         const_reference operator () (size_type /*i*/) const {
01375             return value_;
01376         }
01377 
01378         BOOST_UBLAS_INLINE
01379         const_reference operator [] (size_type /*i*/) const {
01380             return value_;
01381         }
01382 
01383         // Assignment
01384         BOOST_UBLAS_INLINE
01385         scalar_vector &operator = (const scalar_vector &v) {
01386             size_ = v.size_;
01387             value_ = v.value_;
01388             return *this;
01389         }
01390         BOOST_UBLAS_INLINE
01391         scalar_vector &assign_temporary (scalar_vector &v) {
01392             swap (v);
01393             return *this;
01394         }
01395 
01396         // Swapping
01397         BOOST_UBLAS_INLINE
01398         void swap (scalar_vector &v) {
01399             if (this != &v) {
01400                 std::swap (size_, v.size_);
01401                 std::swap (value_, v.value_);
01402             }
01403         }
01404         BOOST_UBLAS_INLINE
01405         friend void swap (scalar_vector &v1, scalar_vector &v2) {
01406             v1.swap (v2);
01407         }
01408 
01409         // Iterator types
01410     private:
01411         // Use an index
01412         typedef size_type const_subiterator_type;
01413 
01414     public:
01415 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
01416         typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> iterator;
01417         typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
01418 #else
01419         class const_iterator;
01420 #endif
01421 
01422         // Element lookup
01423         BOOST_UBLAS_INLINE
01424         const_iterator find (size_type i) const {
01425             return const_iterator (*this, i);
01426         }
01427 
01428 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
01429         class const_iterator:
01430             public container_const_reference<scalar_vector>,
01431             public random_access_iterator_base<dense_random_access_iterator_tag,
01432                                                const_iterator, value_type> {
01433         public:
01434             typedef typename scalar_vector::difference_type difference_type;
01435             typedef typename scalar_vector::value_type value_type;
01436             typedef typename scalar_vector::const_reference reference;
01437             typedef typename scalar_vector::const_pointer pointer;
01438 
01439             // Construction and destruction
01440             BOOST_UBLAS_INLINE
01441             const_iterator ():
01442                 container_const_reference<scalar_vector> (), it_ () {}
01443             BOOST_UBLAS_INLINE
01444             const_iterator (const scalar_vector &v, const const_subiterator_type &it):
01445                 container_const_reference<scalar_vector> (v), it_ (it) {}
01446 
01447             // Arithmetic
01448             BOOST_UBLAS_INLINE
01449             const_iterator &operator ++ () {
01450                 ++ it_;
01451                 return *this;
01452             }
01453             BOOST_UBLAS_INLINE
01454             const_iterator &operator -- () {
01455                 -- it_;
01456                 return *this;
01457             }
01458             BOOST_UBLAS_INLINE
01459             const_iterator &operator += (difference_type n) {
01460                 it_ += n;
01461                 return *this;
01462             }
01463             BOOST_UBLAS_INLINE
01464             const_iterator &operator -= (difference_type n) {
01465                 it_ -= n;
01466                 return *this;
01467             }
01468             BOOST_UBLAS_INLINE
01469             difference_type operator - (const const_iterator &it) const {
01470                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01471                 return it_ - it.it_;
01472             }
01473 
01474             // Dereference
01475             BOOST_UBLAS_INLINE
01476             const_reference operator * () const {
01477                 BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ());
01478                 return (*this) () (index ());
01479             }
01480             BOOST_UBLAS_INLINE
01481             const_reference operator [] (difference_type n) const {
01482                 return *(*this + n);
01483             }
01484 
01485             // Index
01486             BOOST_UBLAS_INLINE
01487             size_type index () const {
01488                 BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ());
01489                 return it_;
01490             }
01491 
01492             // Assignment
01493             BOOST_UBLAS_INLINE
01494             const_iterator &operator = (const const_iterator &it) {
01495                 container_const_reference<scalar_vector>::assign (&it ());
01496                 it_ = it.it_;
01497                 return *this;
01498             }
01499 
01500             // Comparison
01501             BOOST_UBLAS_INLINE
01502             bool operator == (const const_iterator &it) const {
01503                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01504                 return it_ == it.it_;
01505             }
01506             BOOST_UBLAS_INLINE
01507             bool operator < (const const_iterator &it) const {
01508                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01509                 return it_ < it.it_;
01510             }
01511 
01512         private:
01513             const_subiterator_type it_;
01514         };
01515 
01516         typedef const_iterator iterator;
01517 #endif
01518 
01519         BOOST_UBLAS_INLINE
01520         const_iterator begin () const {
01521             return find (0);
01522         }
01523         BOOST_UBLAS_INLINE
01524         const_iterator end () const {
01525             return find (size_);
01526         }
01527 
01528         // Reverse iterator
01529         typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
01530 
01531         BOOST_UBLAS_INLINE
01532         const_reverse_iterator rbegin () const {
01533             return const_reverse_iterator (end ());
01534         }
01535         BOOST_UBLAS_INLINE
01536         const_reverse_iterator rend () const {
01537             return const_reverse_iterator (begin ());
01538         }
01539 
01540          // Serialization
01541         template<class Archive>
01542         void serialize(Archive & ar, const unsigned int /* file_version */){
01543             serialization::collection_size_type s (size_);
01544             ar & serialization::make_nvp("size",s);
01545             if (Archive::is_loading::value) {
01546                 size_ = s;
01547             }
01548             ar & serialization::make_nvp("value", value_);
01549         }
01550 
01551     private:
01552         size_type size_;
01553         value_type value_;
01554     };
01555 
01556     // ------------------------
01557     // Array based vector class
01558     // ------------------------
01559 
01561     template<class T, std::size_t N>
01562     class c_vector:
01563         public vector_container<c_vector<T, N> > {
01564 
01565         typedef c_vector<T, N> self_type;
01566     public:
01567 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
01568         using vector_container<self_type>::operator ();
01569 #endif
01570         typedef std::size_t size_type;
01571         typedef std::ptrdiff_t difference_type;
01572         typedef T value_type;
01573         typedef const T &const_reference;
01574         typedef T &reference;
01575         typedef value_type array_type[N];
01576         typedef T *pointer;
01577         typedef const T *const_pointer;
01578         typedef const vector_reference<const self_type> const_closure_type;
01579         typedef vector_reference<self_type> closure_type;
01580         typedef self_type vector_temporary_type;
01581         typedef dense_tag storage_category;
01582 
01583         // Construction and destruction
01584         BOOST_UBLAS_INLINE
01585         c_vector ():
01586             size_ (N) /* , data_ () */ {}
01587         explicit BOOST_UBLAS_INLINE
01588         c_vector (size_type size):
01589             size_ (size) /* , data_ () */ {
01590             if (size_ > N)
01591                 bad_size ().raise ();
01592         }
01593         BOOST_UBLAS_INLINE
01594         c_vector (const c_vector &v):
01595             size_ (v.size_) /* , data_ () */ {
01596             if (size_ > N)
01597                 bad_size ().raise ();
01598             assign(v);
01599         }
01600         template<class AE>
01601         BOOST_UBLAS_INLINE
01602         c_vector (const vector_expression<AE> &ae):
01603             size_ (ae ().size ()) /* , data_ () */ {
01604             if (size_ > N)
01605                 bad_size ().raise ();
01606             vector_assign<scalar_assign> (*this, ae);
01607         }
01608 
01609         // Accessors
01610         BOOST_UBLAS_INLINE
01611         size_type size () const {
01612             return size_;
01613         }
01614         BOOST_UBLAS_INLINE
01615         const_pointer data () const {
01616             return data_;
01617         }
01618         BOOST_UBLAS_INLINE
01619         pointer data () {
01620             return data_;
01621         }
01622 
01623         // Resizing
01624         BOOST_UBLAS_INLINE
01625         void resize (size_type size, bool preserve = true) {
01626             if (size > N)
01627                 bad_size ().raise ();
01628             size_ = size;
01629         }
01630 
01631         // Element support
01632         BOOST_UBLAS_INLINE
01633         pointer find_element (size_type i) {
01634             return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i));
01635         }
01636         BOOST_UBLAS_INLINE
01637         const_pointer find_element (size_type i) const {
01638             return & data_ [i];
01639         }
01640 
01641         // Element access
01642         BOOST_UBLAS_INLINE
01643         const_reference operator () (size_type i) const {
01644             BOOST_UBLAS_CHECK (i < size_,  bad_index ());
01645             return data_ [i];
01646         }
01647         BOOST_UBLAS_INLINE
01648         reference operator () (size_type i) {
01649             BOOST_UBLAS_CHECK (i < size_, bad_index ());
01650             return data_ [i];
01651         }
01652 
01653         BOOST_UBLAS_INLINE
01654         const_reference operator [] (size_type i) const {
01655             return (*this) (i);
01656         }
01657         BOOST_UBLAS_INLINE
01658         reference operator [] (size_type i) {
01659             return (*this) (i);
01660         }
01661 
01662         // Element assignment
01663         BOOST_UBLAS_INLINE
01664         reference insert_element (size_type i, const_reference t) {
01665             BOOST_UBLAS_CHECK (i < size_, bad_index ());
01666             return (data_ [i] = t);
01667         }
01668         BOOST_UBLAS_INLINE
01669         void erase_element (size_type i) {
01670             BOOST_UBLAS_CHECK (i < size_, bad_index ());
01671             data_ [i] = value_type/*zero*/();
01672         }
01673         
01674         // Zeroing
01675         BOOST_UBLAS_INLINE
01676         void clear () {
01677             std::fill (data_, data_ + size_, value_type/*zero*/());
01678         }
01679 
01680         // Assignment
01681 #ifdef BOOST_UBLAS_MOVE_SEMANTICS
01682 
01684         BOOST_UBLAS_INLINE
01685         c_vector &operator = (c_vector v) {
01686             assign_temporary(v);
01687             return *this;
01688         }
01689 #else
01690         BOOST_UBLAS_INLINE
01691         c_vector &operator = (const c_vector &v) {
01692             size_ = v.size_;
01693             std::copy (v.data_, v.data_ + v.size_, data_);
01694             return *this;
01695         }
01696 #endif
01697         template<class C>          // Container assignment without temporary
01698         BOOST_UBLAS_INLINE
01699         c_vector &operator = (const vector_container<C> &v) {
01700             resize (v ().size (), false);
01701             assign (v);
01702             return *this;
01703         }
01704         BOOST_UBLAS_INLINE
01705         c_vector &assign_temporary (c_vector &v) {
01706             swap (v);
01707             return *this;
01708         }
01709         template<class AE>
01710         BOOST_UBLAS_INLINE
01711         c_vector &operator = (const vector_expression<AE> &ae) {
01712             self_type temporary (ae);
01713             return assign_temporary (temporary);
01714         }
01715         template<class AE>
01716         BOOST_UBLAS_INLINE
01717         c_vector &assign (const vector_expression<AE> &ae) {
01718             vector_assign<scalar_assign> (*this, ae);
01719             return *this;
01720         }
01721 
01722         // Computed assignment
01723         template<class AE>
01724         BOOST_UBLAS_INLINE
01725         c_vector &operator += (const vector_expression<AE> &ae) {
01726             self_type temporary (*this + ae);
01727             return assign_temporary (temporary);
01728         }
01729         template<class C>          // Container assignment without temporary
01730         BOOST_UBLAS_INLINE
01731         c_vector &operator += (const vector_container<C> &v) {
01732             plus_assign (v);
01733             return *this;
01734         }
01735         template<class AE>
01736         BOOST_UBLAS_INLINE
01737         c_vector &plus_assign (const vector_expression<AE> &ae) {
01738             vector_assign<scalar_plus_assign> ( *this, ae);
01739             return *this;
01740         }
01741         template<class AE>
01742         BOOST_UBLAS_INLINE
01743         c_vector &operator -= (const vector_expression<AE> &ae) {
01744             self_type temporary (*this - ae);
01745             return assign_temporary (temporary);
01746         }
01747         template<class C>          // Container assignment without temporary
01748         BOOST_UBLAS_INLINE
01749         c_vector &operator -= (const vector_container<C> &v) {
01750             minus_assign (v);
01751             return *this;
01752         }
01753         template<class AE>
01754         BOOST_UBLAS_INLINE
01755         c_vector &minus_assign (const vector_expression<AE> &ae) {
01756             vector_assign<scalar_minus_assign> (*this, ae);
01757             return *this;
01758         }
01759         template<class AT>
01760         BOOST_UBLAS_INLINE
01761         c_vector &operator *= (const AT &at) {
01762             vector_assign_scalar<scalar_multiplies_assign> (*this, at);
01763             return *this;
01764         }
01765         template<class AT>
01766         BOOST_UBLAS_INLINE
01767         c_vector &operator /= (const AT &at) {
01768             vector_assign_scalar<scalar_divides_assign> (*this, at);
01769             return *this;
01770         }
01771 
01772         // Swapping
01773         BOOST_UBLAS_INLINE
01774         void swap (c_vector &v) {
01775             if (this != &v) {
01776                 BOOST_UBLAS_CHECK (size_ == v.size_, bad_size ());
01777                 std::swap (size_, v.size_);
01778                 std::swap_ranges (data_, data_ + size_, v.data_);
01779             }
01780         }
01781         BOOST_UBLAS_INLINE
01782         friend void swap (c_vector &v1, c_vector &v2) {
01783             v1.swap (v2);
01784         }
01785 
01786         // Iterator types
01787     private:
01788         // Use pointers for iterator
01789         typedef const_pointer const_subiterator_type;
01790         typedef pointer subiterator_type;
01791 
01792     public:
01793 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
01794         typedef indexed_iterator<self_type, dense_random_access_iterator_tag> iterator;
01795         typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
01796 #else
01797         class const_iterator;
01798         class iterator;
01799 #endif
01800 
01801         // Element lookup
01802         BOOST_UBLAS_INLINE
01803         const_iterator find (size_type i) const {
01804 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
01805             return const_iterator (*this, &data_ [i]);
01806 #else
01807             return const_iterator (*this, i);
01808 #endif
01809         }
01810         BOOST_UBLAS_INLINE
01811         iterator find (size_type i) {
01812 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
01813             return iterator (*this, &data_ [i]);
01814 #else
01815             return iterator (*this, i);
01816 #endif
01817         }
01818 
01819 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
01820         class const_iterator:
01821             public container_const_reference<c_vector>,
01822             public random_access_iterator_base<dense_random_access_iterator_tag,
01823                                                const_iterator, value_type> {
01824         public:
01825             typedef typename c_vector::difference_type difference_type;
01826             typedef typename c_vector::value_type value_type;
01827             typedef typename c_vector::const_reference reference;
01828             typedef typename c_vector::const_pointer pointer;
01829 
01830             // Construction and destruction
01831             BOOST_UBLAS_INLINE
01832             const_iterator ():
01833                 container_const_reference<self_type> (), it_ () {}
01834             BOOST_UBLAS_INLINE
01835             const_iterator (const self_type &v, const const_subiterator_type &it):
01836                 container_const_reference<self_type> (v), it_ (it) {}
01837             BOOST_UBLAS_INLINE
01838             const_iterator (const typename self_type::iterator &it):  // ISSUE self_type:: stops VC8 using std::iterator here
01839                 container_const_reference<self_type> (it ()), it_ (it.it_) {}
01840 
01841             // Arithmetic
01842             BOOST_UBLAS_INLINE
01843             const_iterator &operator ++ () {
01844                 ++ it_;
01845                 return *this;
01846             }
01847             BOOST_UBLAS_INLINE
01848             const_iterator &operator -- () {
01849                 -- it_;
01850                 return *this;
01851             }
01852             BOOST_UBLAS_INLINE
01853             const_iterator &operator += (difference_type n) {
01854                 it_ += n;
01855                 return *this;
01856             }
01857             BOOST_UBLAS_INLINE
01858             const_iterator &operator -= (difference_type n) {
01859                 it_ -= n;
01860                 return *this;
01861             }
01862             BOOST_UBLAS_INLINE
01863             difference_type operator - (const const_iterator &it) const {
01864                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01865                 return it_ - it.it_;
01866             }
01867 
01868             // Dereference
01869             BOOST_UBLAS_INLINE
01870             const_reference operator * () const {
01871                 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
01872                 return *it_;
01873             }
01874             BOOST_UBLAS_INLINE
01875             const_reference operator [] (difference_type n) const {
01876                 return *(it_ + n);
01877             }
01878 
01879             // Index
01880             BOOST_UBLAS_INLINE
01881             size_type index () const {
01882                 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
01883                 const self_type &v = (*this) ();
01884                 return it_ - v.begin ().it_;
01885             }
01886 
01887             // Assignment
01888             BOOST_UBLAS_INLINE
01889             const_iterator &operator = (const const_iterator &it) {
01890                 container_const_reference<self_type>::assign (&it ());
01891                 it_ = it.it_;
01892                 return *this;
01893             }
01894 
01895             // Comparison
01896             BOOST_UBLAS_INLINE
01897             bool operator == (const const_iterator &it) const {
01898                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01899                 return it_ == it.it_;
01900             }
01901             BOOST_UBLAS_INLINE
01902             bool operator < (const const_iterator &it) const {
01903                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01904                 return it_ < it.it_;
01905             }
01906 
01907         private:
01908             const_subiterator_type it_;
01909 
01910             friend class iterator;
01911         };
01912 #endif
01913 
01914         BOOST_UBLAS_INLINE
01915         const_iterator begin () const {
01916             return find (0);
01917         }
01918         BOOST_UBLAS_INLINE
01919         const_iterator end () const {
01920             return find (size_);
01921         }
01922 
01923 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
01924         class iterator:
01925             public container_reference<c_vector>,
01926             public random_access_iterator_base<dense_random_access_iterator_tag,
01927                                                iterator, value_type> {
01928         public:
01929             typedef typename c_vector::difference_type difference_type;
01930             typedef typename c_vector::value_type value_type;
01931             typedef typename c_vector::reference reference;
01932             typedef typename c_vector::pointer pointer;
01933 
01934             // Construction and destruction
01935             BOOST_UBLAS_INLINE
01936             iterator ():
01937                 container_reference<self_type> (), it_ () {}
01938             BOOST_UBLAS_INLINE
01939             iterator (self_type &v, const subiterator_type &it):
01940                 container_reference<self_type> (v), it_ (it) {}
01941 
01942             // Arithmetic
01943             BOOST_UBLAS_INLINE
01944             iterator &operator ++ () {
01945                 ++ it_;
01946                 return *this;
01947             }
01948             BOOST_UBLAS_INLINE
01949             iterator &operator -- () {
01950                 -- it_;
01951                 return *this;
01952             }
01953             BOOST_UBLAS_INLINE
01954             iterator &operator += (difference_type n) {
01955                 it_ += n;
01956                 return *this;
01957             }
01958             BOOST_UBLAS_INLINE
01959             iterator &operator -= (difference_type n) {
01960                 it_ -= n;
01961                 return *this;
01962             }
01963             BOOST_UBLAS_INLINE
01964             difference_type operator - (const iterator &it) const {
01965                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01966                 return it_ - it.it_;
01967             }
01968 
01969             // Dereference
01970             BOOST_UBLAS_INLINE
01971             reference operator * () const {
01972                 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
01973                 return *it_;
01974             }
01975             BOOST_UBLAS_INLINE
01976             reference operator [] (difference_type n) const {
01977                 return *(it_ + n);
01978             }
01979 
01980             // Index
01981             BOOST_UBLAS_INLINE
01982             size_type index () const {
01983                 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
01984                 // EDG won't allow const self_type it doesn't allow friend access to it_
01985                 self_type &v = (*this) ();
01986                 return it_ - v.begin ().it_;
01987             }
01988 
01989             // Assignment
01990             BOOST_UBLAS_INLINE
01991             iterator &operator = (const iterator &it) {
01992                 container_reference<self_type>::assign (&it ());
01993                 it_ = it.it_;
01994                 return *this;
01995             }
01996 
01997             // Comparison
01998             BOOST_UBLAS_INLINE
01999             bool operator == (const iterator &it) const {
02000                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
02001                 return it_ == it.it_;
02002             }
02003             BOOST_UBLAS_INLINE
02004             bool operator < (const iterator &it) const {
02005                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
02006                 return it_ < it.it_;
02007             }
02008 
02009         private:
02010             subiterator_type it_;
02011 
02012             friend class const_iterator;
02013         };
02014 #endif
02015 
02016         BOOST_UBLAS_INLINE
02017         iterator begin () {
02018             return find (0);
02019         }
02020         BOOST_UBLAS_INLINE
02021         iterator end () {
02022             return find (size_);
02023         }
02024 
02025         // Reverse iterator
02026         typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
02027         typedef reverse_iterator_base<iterator> reverse_iterator;
02028 
02029         BOOST_UBLAS_INLINE
02030         const_reverse_iterator rbegin () const {
02031             return const_reverse_iterator (end ());
02032         }
02033         BOOST_UBLAS_INLINE
02034         const_reverse_iterator rend () const {
02035             return const_reverse_iterator (begin ());
02036         }
02037         BOOST_UBLAS_INLINE
02038         reverse_iterator rbegin () {
02039             return reverse_iterator (end ());
02040         }
02041         BOOST_UBLAS_INLINE
02042         reverse_iterator rend () {
02043             return reverse_iterator (begin ());
02044         }
02045 
02046         // Serialization
02047         template<class Archive>
02048         void serialize(Archive & ar, const unsigned int /* file_version */){
02049             serialization::collection_size_type s (size_);
02050             ar & serialization::make_nvp("size",s);
02051             
02052             // copy the value back if loading
02053             if (Archive::is_loading::value) {
02054               if (s > N) bad_size("too large size in bounded_vector::load()\n").raise();
02055               size_ = s;
02056             }
02057             // ISSUE: this writes the full array
02058             ar & serialization::make_nvp("data",data_);
02059         }
02060 
02061     private:
02062         size_type size_;
02063         array_type data_;
02064     };
02065 
02066 }}}
02067 
02068 #endif