vector.hpp
来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 1,703 行 · 第 1/5 页
HPP
1,703 行
{ \ T* back_pos = detail::get_pointer(this->members_.m_start) + this->members_.m_size; \ if (this->members_.m_size < this->members_.m_capacity){ \ new((void*)(back_pos))value_type \ (BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \ ++this->members_.m_size; \ } \ else{ \ detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \ <value_type, T*, BOOST_PP_ENUM_PARAMS(n, P)> \ proxy(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \ priv_range_insert(back_pos, 1, proxy); \ } \ } \ \ template<BOOST_PP_ENUM_PARAMS(n, class P)> \ iterator emplace(const_iterator pos, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \ { \ size_type pos_n = pos - cbegin(); \ detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \ <value_type, T*, BOOST_PP_ENUM_PARAMS(n, P)> \ proxy(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \ priv_range_insert(detail::get_pointer(pos.get_ptr()), 1, proxy); \ return iterator(this->members_.m_start + pos_n); \ } \ //! #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS) #include BOOST_PP_LOCAL_ITERATE() #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING //! <b>Effects</b>: Swaps the contents of *this and x. //! If this->allocator_type() != x.allocator_type() //! allocators are also swapped. //! //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE void swap(vector<T, A>& x) #else void swap(vector<T, A> && x) #endif { allocator_type &this_al = this->alloc(), &other_al = x.alloc(); //Just swap internals detail::do_swap(this->members_.m_start, x.members_.m_start); detail::do_swap(this->members_.m_size, x.members_.m_size); detail::do_swap(this->members_.m_capacity, x.members_.m_capacity); if (this_al != other_al){ detail::do_swap(this_al, other_al); } } #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE //! <b>Effects</b>: Swaps the contents of *this and x. //! If this->allocator_type() != x.allocator_type() //! allocators are also swapped. //! //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. void swap(const detail::moved_object<vector<T, A> >& mx) { vector<T, A> &x = mx.get(); this->swap(x); } #endif //! <b>Requires</b>: position must be a valid iterator of *this. //! //! <b>Effects</b>: Insert a copy of x before position. //! //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws. //! //! <b>Complexity</b>: If position is end(), amortized constant time //! Linear time otherwise. iterator insert(const_iterator position, const T& x) { //Just call more general insert(pos, size, value) and return iterator size_type pos_n = position - cbegin(); this->insert(position, (size_type)1, x); return iterator(this->members_.m_start + pos_n); } //! <b>Requires</b>: position must be a valid iterator of *this. //! //! <b>Effects</b>: Insert a new element before position with mx's resources. //! //! <b>Throws</b>: If memory allocation throws. //! //! <b>Complexity</b>: If position is end(), amortized constant time //! Linear time otherwise. #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE iterator insert(const_iterator position, const detail::moved_object<T> &mx) { value_type &x = mx.get(); #else iterator insert(const_iterator position, T &&x) { #endif //Just call more general insert(pos, size, value) and return iterator size_type pos_n = position - cbegin(); this->insert(position ,repeat_move_it(repeat_it(x, 1)) ,repeat_move_it(repeat_it())); return iterator(this->members_.m_start + pos_n); } //! <b>Requires</b>: pos must be a valid iterator of *this. //! //! <b>Effects</b>: Insert a copy of the [first, last) range before pos. //! //! <b>Throws</b>: If memory allocation throws, T's constructor from a //! dereferenced InpIt throws or T's copy constructor throws. //! //! <b>Complexity</b>: Linear to std::distance [first, last). template <class InIt> void insert(const_iterator pos, InIt first, InIt last) { //Dispatch depending on integer/iterator const bool aux_boolean = detail::is_convertible<InIt, std::size_t>::value; typedef detail::bool_<aux_boolean> Result; this->priv_insert_dispatch(pos, first, last, Result()); } //! <b>Requires</b>: pos must be a valid iterator of *this. //! //! <b>Effects</b>: Insert n copies of x before pos. //! //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws. //! //! <b>Complexity</b>: Linear to n. void insert(const_iterator p, size_type n, const T& x) { this->insert(p, cvalue_iterator(x, n), cvalue_iterator()); } //! <b>Effects</b>: Removes the last element from the vector. //! //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant time. void pop_back() { //Destroy last element --this->members_.m_size; this->destroy(detail::get_pointer(this->members_.m_start) + this->members_.m_size); } //! <b>Effects</b>: Erases the element at position pos. //! //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Linear to the elements between pos and the //! last element. Constant if pos is the first or the last element. iterator erase(const_iterator position) { T *pos = detail::get_pointer(position.get_ptr()); T *beg = detail::get_pointer(this->members_.m_start); typedef typename value_traits::assign_move_it assign_move_it; std::copy(assign_move_it(pos + 1), assign_move_it(beg + this->members_.m_size), pos); --this->members_.m_size; //Destroy last element base_t::destroy(detail::get_pointer(this->members_.m_start) + this->members_.m_size); return iterator(position.get_ptr()); } //! <b>Effects</b>: Erases the elements pointed by [first, last). //! //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Linear to the distance between first and last. iterator erase(const_iterator first, const_iterator last) { typedef typename value_traits::assign_move_it assign_move_it; if (first != last){ // worth doing, copy down over hole T* end_pos = detail::get_pointer(this->members_.m_start) + this->members_.m_size; T* ptr = detail::get_pointer(std::copy (assign_move_it(detail::get_pointer(last.get_ptr())) ,assign_move_it(end_pos) ,detail::get_pointer(first.get_ptr()) )); size_type destroyed = (end_pos - ptr); this->destroy_n(ptr, destroyed); this->members_.m_size -= destroyed; } return iterator(first.get_ptr()); } //! <b>Effects</b>: Inserts or erases elements at the end such that //! the size becomes n. New elements are copy constructed from x. //! //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws. //! //! <b>Complexity</b>: Linear to the difference between size() and new_size. void resize(size_type new_size, const T& x) { pointer finish = this->members_.m_start + this->members_.m_size; if (new_size < size()){ //Destroy last elements this->erase(const_iterator(this->members_.m_start + new_size), this->end()); } else{ //Insert new elements at the end this->insert(const_iterator(finish), new_size - this->size(), x); } } //! <b>Effects</b>: Inserts or erases elements at the end such that //! the size becomes n. New elements are default constructed. //! //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws. //! //! <b>Complexity</b>: Linear to the difference between size() and new_size. void resize(size_type new_size) { if (new_size < this->size()){ //Destroy last elements this->erase(const_iterator(this->members_.m_start + new_size), this->end()); } else{ size_type n = new_size - this->size(); this->reserve(new_size); detail::default_construct_aux_proxy<T, T*, size_type> proxy(n); priv_range_insert(this->cend().get_ptr(), n, proxy); } } //! <b>Effects</b>: Erases all the elements of the vector. //! //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Linear to the number of elements in the vector. void clear() { this->priv_destroy_all(); } /// @cond //! <b>Effects</b>: Tries to deallocate the excess of memory created //! with previous allocations. The size of the vector is unchanged //! //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws. //! //! <b>Complexity</b>: Linear to size(). void shrink_to_fit() { priv_shrink_to_fit(alloc_version()); } private: void priv_shrink_to_fit(allocator_v1) { if(this->members_.m_capacity){ if(!size()){ this->prot_deallocate(); } else{ //This would not work with stateful allocators vector<T, A>(*this).swap(*this); } } } void priv_shrink_to_fit(allocator_v2) { if(this->members_.m_capacity){ if(!size()){ this->prot_deallocate(); } else{ size_type received_size; if(this->alloc().allocation_command ( shrink_in_place | nothrow_allocation , this->capacity(), this->size() , received_size, this->members_.m_start).first){ this->members_.m_capacity = received_size; #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS ++this->num_shrink; #endif } } } } void priv_destroy_all() { this->destroy_n(detail::get_pointer(this->members_.m_start), this->members_.m_size); this->members_.m_size = 0; } template <class FwdIt> void priv_range_insert(pointer pos, FwdIt first, FwdIt last, std::forward_iterator_tag) { if(first != last){ const size_type n = std::distance(first, last); detail::advanced_insert_aux_proxy<T, FwdIt, T*> proxy(first, last); priv_range_insert(pos, n, proxy); } } void priv_range_insert(pointer pos, const size_type n, #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING advanced_insert_aux_int_t &&interf #else advanced_insert_aux_int_t &interf #endif ) { //Check if we have enough memory or try to expand current memory size_type remaining = this->members_.m_capacity - this->members_.m_size; bool same_buffer_start; std::pair<pointer, bool> ret; size_type real_cap = this->members_.m_capacity; //Check if we already have room if (n <= remaining){ same_buffer_start = true; } else{ //There is not enough memory, allocate a new //buffer or expand the old one. size_type new_cap = this->next_capacity(n); ret = this->allocation_command (allocate_new | expand_fwd | expand_bwd, this->members_.m_size + n, new_cap, real_cap, this->members_.m_start); //Check for forward expansion same_buffer_start = ret.second && this->members_.m_start == ret.first; if(same_buffer_start){ this->members_.m_capacity = real_cap; } } //If we had room or we have expanded forward if (same_buffer_start){ #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS ++this->num_expand_fwd; #endif this->priv_range_insert_expand_forward (detail::get_pointer(pos), n, interf); } //Backwards (and possibly forward) expansion else if(ret.second){
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?