...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
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