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 + -
显示快捷键?