ublas: vector.hpp Source File

- Main Page
- Related Pages
- Classes
- Files

- File List

# vector.hpp

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