vector_sparse.hpp
来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 1,787 行 · 第 1/5 页
HPP
1,787 行
vector_assign<scalar_minus_assign> (*this, ae); return *this; } template<class AT> BOOST_UBLAS_INLINE compressed_vector &operator *= (const AT &at) { vector_assign_scalar<scalar_multiplies_assign> (*this, at); return *this; } template<class AT> BOOST_UBLAS_INLINE compressed_vector &operator /= (const AT &at) { vector_assign_scalar<scalar_divides_assign> (*this, at); return *this; } // Swapping BOOST_UBLAS_INLINE void swap (compressed_vector &v) { if (this != &v) { std::swap (size_, v.size_); std::swap (capacity_, v.capacity_); std::swap (filled_, v.filled_); index_data_.swap (v.index_data_); value_data_.swap (v.value_data_); } storage_invariants (); } BOOST_UBLAS_INLINE friend void swap (compressed_vector &v1, compressed_vector &v2) { v1.swap (v2); } // Back element insertion and erasure BOOST_UBLAS_INLINE void push_back (size_type i, const_reference t) { BOOST_UBLAS_CHECK (filled_ == 0 || index_data_ [filled_ - 1] < k_based (i), external_logic ()); if (filled_ >= capacity_) reserve (2 * capacity_, true); BOOST_UBLAS_CHECK (filled_ < capacity_, internal_logic ()); index_data_ [filled_] = k_based (i); value_data_ [filled_] = t; ++ filled_; storage_invariants (); } BOOST_UBLAS_INLINE void pop_back () { BOOST_UBLAS_CHECK (filled_ > 0, external_logic ()); -- filled_; storage_invariants (); } // Iterator types private: // Use index array iterator typedef typename IA::const_iterator const_subiterator_type; typedef typename IA::iterator subiterator_type; BOOST_UBLAS_INLINE true_reference at_element (size_type i) { BOOST_UBLAS_CHECK (i < size_, bad_index ()); subiterator_type it (detail::lower_bound (index_data_.begin (), index_data_.begin () + filled_, k_based (i), std::less<size_type> ())); BOOST_UBLAS_CHECK (it != index_data_.begin () + filled_ && *it == k_based (i), bad_index ()); return value_data_ [it - index_data_.begin ()]; } public: class const_iterator; class iterator; // Element lookup // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it. const_iterator find (size_type i) const { return const_iterator (*this, detail::lower_bound (index_data_.begin (), index_data_.begin () + filled_, k_based (i), std::less<size_type> ())); } // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it. iterator find (size_type i) { return iterator (*this, detail::lower_bound (index_data_.begin (), index_data_.begin () + filled_, k_based (i), std::less<size_type> ())); } class const_iterator: public container_const_reference<compressed_vector>, public bidirectional_iterator_base<sparse_bidirectional_iterator_tag, const_iterator, value_type> { public: typedef typename compressed_vector::value_type value_type; typedef typename compressed_vector::difference_type difference_type; typedef typename compressed_vector::const_reference reference; typedef const typename compressed_vector::pointer pointer; // Construction and destruction BOOST_UBLAS_INLINE const_iterator (): container_const_reference<self_type> (), it_ () {} BOOST_UBLAS_INLINE const_iterator (const self_type &v, const const_subiterator_type &it): container_const_reference<self_type> (v), it_ (it) {} BOOST_UBLAS_INLINE const_iterator (const typename self_type::iterator &it): // ISSUE self_type:: stops VC8 using std::iterator here container_const_reference<self_type> (it ()), it_ (it.it_) {} // Arithmetic BOOST_UBLAS_INLINE const_iterator &operator ++ () { ++ it_; return *this; } BOOST_UBLAS_INLINE const_iterator &operator -- () { -- it_; return *this; } // Dereference BOOST_UBLAS_INLINE const_reference operator * () const { BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ()); return (*this) ().value_data_ [it_ - (*this) ().index_data_.begin ()]; } // Index BOOST_UBLAS_INLINE size_type index () const { BOOST_UBLAS_CHECK (*this != (*this) ().end (), bad_index ()); BOOST_UBLAS_CHECK ((*this) ().zero_based (*it_) < (*this) ().size (), bad_index ()); return (*this) ().zero_based (*it_); } // Assignment BOOST_UBLAS_INLINE const_iterator &operator = (const const_iterator &it) { container_const_reference<self_type>::assign (&it ()); it_ = it.it_; return *this; } // Comparison BOOST_UBLAS_INLINE bool operator == (const const_iterator &it) const { BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); return it_ == it.it_; } private: const_subiterator_type it_; }; BOOST_UBLAS_INLINE const_iterator begin () const { return find (0); } BOOST_UBLAS_INLINE const_iterator end () const { return find (size_); } class iterator: public container_reference<compressed_vector>, public bidirectional_iterator_base<sparse_bidirectional_iterator_tag, iterator, value_type> { public: typedef typename compressed_vector::value_type value_type; typedef typename compressed_vector::difference_type difference_type; typedef typename compressed_vector::true_reference reference; typedef typename compressed_vector::pointer pointer; // Construction and destruction BOOST_UBLAS_INLINE iterator (): container_reference<self_type> (), it_ () {} BOOST_UBLAS_INLINE iterator (self_type &v, const subiterator_type &it): container_reference<self_type> (v), it_ (it) {} // Arithmetic BOOST_UBLAS_INLINE iterator &operator ++ () { ++ it_; return *this; } BOOST_UBLAS_INLINE iterator &operator -- () { -- it_; return *this; } // Dereference BOOST_UBLAS_INLINE reference operator * () const { BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ()); return (*this) ().value_data_ [it_ - (*this) ().index_data_.begin ()]; } // Index BOOST_UBLAS_INLINE size_type index () const { BOOST_UBLAS_CHECK (*this != (*this) ().end (), bad_index ()); BOOST_UBLAS_CHECK ((*this) ().zero_based (*it_) < (*this) ().size (), bad_index ()); return (*this) ().zero_based (*it_); } // Assignment BOOST_UBLAS_INLINE iterator &operator = (const iterator &it) { container_reference<self_type>::assign (&it ()); it_ = it.it_; return *this; } // Comparison BOOST_UBLAS_INLINE bool operator == (const iterator &it) const { BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); return it_ == it.it_; } private: subiterator_type it_; friend class const_iterator; }; BOOST_UBLAS_INLINE iterator begin () { return find (0); } BOOST_UBLAS_INLINE iterator end () { return find (size_); } // Reverse iterator typedef reverse_iterator_base<const_iterator> const_reverse_iterator; typedef reverse_iterator_base<iterator> reverse_iterator; BOOST_UBLAS_INLINE const_reverse_iterator rbegin () const { return const_reverse_iterator (end ()); } BOOST_UBLAS_INLINE const_reverse_iterator rend () const { return const_reverse_iterator (begin ()); } BOOST_UBLAS_INLINE reverse_iterator rbegin () { return reverse_iterator (end ()); } BOOST_UBLAS_INLINE reverse_iterator rend () { return reverse_iterator (begin ()); } // Serialization template<class Archive> void serialize(Archive & ar, const unsigned int /* file_version */){ serialization::collection_size_type s (size_); ar & serialization::make_nvp("size",s); if (Archive::is_loading::value) { size_ = s; } // ISSUE: filled may be much less than capacity // ISSUE: index_data_ and value_data_ are undefined between filled and capacity (trouble with 'nan'-values) ar & serialization::make_nvp("capacity", capacity_); ar & serialization::make_nvp("filled", filled_); ar & serialization::make_nvp("index_data", index_data_); ar & serialization::make_nvp("value_data", value_data_); storage_invariants(); } private: void storage_invariants () const { BOOST_UBLAS_CHECK (capacity_ == index_data_.size (), internal_logic ()); BOOST_UBLAS_CHECK (capacity_ == value_data_.size (), internal_logic ()); BOOST_UBLAS_CHECK (filled_ <= capacity_, internal_logic ()); BOOST_UBLAS_CHECK ((0 == filled_) || (zero_based(index_data_[filled_ - 1]) < size_), internal_logic ()); } size_type size_; typename index_array_type::size_type capacity_; typename index_array_type::size_type filled_; index_array_type index_data_; value_array_type value_data_; static const value_type zero_; BOOST_UBLAS_INLINE static size_type zero_based (size_type k_based_index) { return k_based_index - IB; } BOOST_UBLAS_INLINE static size_type k_based (size_type zero_based_index) { return zero_based_index + IB; } friend class iterator; friend class const_iterator; }; template<class T, std::size_t IB, class IA, class TA> const typename compressed_vector<T, IB, IA, TA>::value_type compressed_vector<T, IB, IA, TA>::zero_ = value_type/*zero*/(); // Coordimate array based sparse vector class // Thanks to Kresimir Fresl for extending this to cover different index bases. template<class T, std::size_t IB, class IA, class TA> class coordinate_vector: public vector_container<coordinate_vector<T, IB, IA, TA> > { typedef T &true_reference; typedef T *pointer; typedef const T *const_pointer; typedef coordinate_vector<T, IB, IA, TA> self_type; public:#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS using vector_container<self_type>::operator ();#endif // ISSUE require type consistency check // is_convertable (IA::size_type, TA::size_type) typedef typename IA::value_type size_type; typedef typename IA::difference_type difference_type; typedef T value_type; typedef const T &const_reference;#ifndef BOOST_UBLAS_STRICT_VECTOR_SPARSE typedef T &reference;#else typedef sparse_vector_element<self_type> reference;#endif typedef IA index_array_type; typedef TA value_array_type; typedef const vector_reference<const self_type> const_closure_type; typedef vector_reference<self_type> closure_type; typedef self_type vector_temporary_type; typedef sparse_tag storage_category; // Construction and destruction BOOST_UBLAS_INLINE coordinate_vector (): vector_container<self_type> (), size_ (0), capacity_ (restrict_capacity (0)), filled_ (0), sorted_filled_ (filled_), sorted_ (true), index_data_ (capacity_), value_data_ (capacity_) { storage_invariants (); } explicit BOOST_UBLAS_INLINE coordinate_vector (size_type size, size_type non_zeros = 0): vector_container<self_type> (), size_ (size), capacity_ (restrict_capacity (non_zeros)), filled_ (0), sorted_filled_ (filled_), sorted_ (true), index_data_ (capacity_), value_data_ (capacity_) { storage_invariants (); } BOOST_UBLAS_INLINE coordinate_vector (const coordinate_vector &v): vector_container<self_type> (), size_ (v.size_), capacity_ (v.capacity_), filled_ (v.filled_), sorted_filled_ (v.sorted_filled_), sorted_ (v.sorted_), index_data_ (v.index_data_), value_data_ (v.value_data_) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?