![]() |
Boost.uBlas 1.49
Linear Algebra in C++: matrices, vectors and numeric algorithms
|
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