📄 yasli_vector.h
字号:
ebo_.beg_ = yasli_nstd::allocator_traits<Allocator>::reallocate( ebo_, ebo_.beg_, end_, n); } end_ = ebo_.beg_ + s; eos_ = ebo_.beg_ + n; assert(capacity() >= n); assert(size() == s); } bool reserve_inplace_nstd(size_type n) { if (capacity() >= n) return true; if (!yasli_nstd::allocator_traits<Allocator>::reallocate_inplace( ebo_, ebo_.beg_, n)) { return false; } eos_ = ebo_.beg_ + n; return true; } // element access: reference operator[](size_type n) { assert(n < size()); return ebo_.beg_[n]; } const_reference operator[](size_type n) const { assert(n < size()); return ebo_.beg_[n]; } const_reference at(size_type n) const { // Fix by Joseph Canedo if (n >= size()) throw std::range_error("vector<>::at"); return ebo_.beg_[n]; } reference at(size_type n) { // Fix by Joseph Canedo if (n >= size()) throw std::range_error("vector<>::at"); return ebo_.beg_[n]; } reference front() { assert(!empty()); return *ebo_.beg_; } const_reference front() const { assert(!empty()); return *ebo_.beg_; } reference back() { assert(!empty()); return end_[-1]; } const_reference back() const { assert(!empty()); return end_[-1]; } private: void prepare_growth(size_type delta) { const size_type s = size(); // @@@ todo: replace magic constant with something meaningful const size_type smallThreshold = 8; if (s < smallThreshold) { reserve(std::max(smallThreshold, delta)); } else { const size_type multiply = 3; const size_type divide = 2; const size_type suggestedSize = (s * multiply) / divide; reserve(std::max(s + delta, suggestedSize)); } } public: // 23.2.4.3 modifiers: void push_back(const T& x) { if (size() == capacity()) { prepare_growth(1); } new(end_) T(x); ++end_; } void pop_back() { assert(!empty()); ebo_.destroy(--end_); } void move_back_nstd(T& x) { if (size() == capacity()) { prepare_growth(1); } yasli_protocols::move_traits<T>::nondestructive_move(&x, &x + 1, end_); } // 23.2.4.3 modifiers: iterator insert(iterator position, const T& x) { // @@@ be smarter about this reservation reserve(size() + 1); const size_type pos = position - begin(); insert(position, (size_type)1, x); return ebo_.beg_ + pos; } void insert(iterator position, size_type n, const T& x) { insert(position, yasli_nstd::fill_iterator<const T&>(x), yasli_nstd::fill_iterator<const T&>(x, n) ); } template <class InputIterator> void insert(iterator position, InputIterator first, InputIterator last) { insert_pre_impl(position, first, last, Loki::Int2Type<yasli_nstd::is_class<InputIterator>::value|| yasli_nstd::is_pointer<InputIterator>::value>()); } private: template<class InputIterator, class looks_like_iterator> void insert_pre_impl(iterator position, InputIterator first, InputIterator last, looks_like_iterator) { insert_impl(position, first, last, typename std::iterator_traits<InputIterator>::iterator_category()); } template <class non_iterator> void insert_pre_impl(iterator position, non_iterator n, non_iterator x, Loki::Int2Type<false>) { //used if e.g. T is int and insert(itr, 10, 6) is called insert(position, static_cast<size_type>(n), static_cast<value_type>(x)); } template <class InputIterator> void insert_impl(iterator position, InputIterator first, InputIterator last, std::input_iterator_tag) { for (; first != last; ++first) { position = insert(position, *first) + 1; } } template <class FwdIterator> void insert_impl(iterator position, FwdIterator first, FwdIterator last, std::forward_iterator_tag) { typedef yasli_protocols::move_traits<T> mt; const typename std::iterator_traits<FwdIterator>::difference_type count = std::distance(first, last); if (eos_ - end_ > count || reserve_inplace_nstd(size() + count)) // there's enough room { if (count > end_ - &*position) { // Step 1: fill the hole between end_ and position+count FwdIterator i1 = first; std::advance(i1, end_ - &*position); FwdIterator i2 = i1; std::advance(i2, &*position + count - end_);//why not i2 = first; advance(i2,count); T* const oldEnd = end_; end_ = copy(i1, i2, end_); assert(end_ == &*position + count); // Step 2: move existing data to the end mt::nondestructive_move( position, oldEnd, end_); end_ = oldEnd + count; // Step 3: copy in the remaining data copy(first, i1, position); } else // simpler case { mt::nondestructive_move( end_ - count, end_, end_); end_ += count; mt::nondestructive_assign_move( position, end_ - count, position + count); copy(first, last, position); } } else { vector<T, Allocator> temp(ebo_); temp.reserve(size() + count); // The calls below won't cause infinite recursion // because they will fall on the other branch // of the if statement temp.insert(temp.end(), begin(), position); temp.insert(temp.end(), first, last); temp.insert(temp.end(), position, end()); assert(temp.size() == size() + count); temp.swap(*this); } } public: iterator erase(iterator position) { erase(position, position + 1); return position; } iterator erase(iterator first, iterator last) { yasli_protocols::move_traits<T>::nondestructive_assign_move( last, end(), first); Allocator& a = ebo_; const size_type destroyed = last - first; yasli_nstd::destroy(a, end_ - destroyed, destroyed); end_ -= destroyed; return first; } void swap(vector<T,Allocator>& rhs)//COULD DO THIS WITH LESS TEMPORARIES { std::swap(static_cast<Allocator&>(ebo_), static_cast<Allocator&>(rhs.ebo_)); std::swap(ebo_.beg_, rhs.ebo_.beg_); std::swap(end_, rhs.end_); std::swap(eos_, rhs.eos_); } void clear() { Allocator& a = ebo_; yasli_nstd::destroy(a, ebo_.beg_, size()); end_ = ebo_.beg_; } };//vector template <class T, class Allocator> bool operator==(const vector<T,Allocator>& x, const vector<T,Allocator>& y); template <class T, class Allocator> bool operator< (const vector<T,Allocator>& x, const vector<T,Allocator>& y); template <class T, class Allocator> bool operator!=(const vector<T,Allocator>& x, const vector<T,Allocator>& y); template <class T, class Allocator> bool operator> (const vector<T,Allocator>& x, const vector<T,Allocator>& y); template <class T, class Allocator> bool operator>=(const vector<T,Allocator>& x, const vector<T,Allocator>& y); template <class T, class Allocator> bool operator<=(const vector<T,Allocator>& x, const vector<T,Allocator>& y); // specialized algorithms: template <class T, class Allocator> void swap(vector<T,Allocator>& x, vector<T,Allocator>& y); }//yaslinamespace yasli_protocols{ template <class T, class A> struct move_traits< yasli::vector<T, A> >:public yasli_nstd::type_selector< sizeof(yasli::vector<T, A>) != (3 * sizeof(T*)), memmove_traits< std::complex<T> >, safe_move_traits< std::complex<T> > >::result { };}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -