📄 stl_deque.h
字号:
void push_front(const value_type& t) { if (start.cur != start.first) { construct(start.cur - 1, t); --start.cur; } else push_front_aux(t); } void pop_back() { if (finish.cur != finish.first) { --finish.cur; destroy(finish.cur); } else pop_back_aux(); } void pop_front() { if (start.cur != start.last - 1) { destroy(start.cur); ++start.cur; } else pop_front_aux(); }public: // Insert iterator insert(iterator position, const value_type& x) { if (position.cur == start.cur) { push_front(x); return start; } else if (position.cur == finish.cur) { push_back(x); iterator tmp = finish; --tmp; return tmp; } else { return insert_aux(position, x); } } iterator insert(iterator position) { return insert(position, value_type()); } void insert(iterator pos, size_type n, const value_type& x); void insert(iterator pos, int n, const value_type& x) { insert(pos, (size_type) n, x); } void insert(iterator pos, long n, const value_type& x) { insert(pos, (size_type) n, x); }#ifdef __STL_MEMBER_TEMPLATES template <class InputIterator> void insert(iterator pos, InputIterator first, InputIterator last) { insert(pos, first, last, iterator_category(first)); }#else /* __STL_MEMBER_TEMPLATES */ void insert(iterator pos, const value_type* first, const value_type* last); void insert(iterator pos, const_iterator first, const_iterator last);#endif /* __STL_MEMBER_TEMPLATES */ void resize(size_type new_size, const value_type& x) { const size_type len = size(); if (new_size < len) erase(start + new_size, finish); else insert(finish, new_size - len, x); } void resize(size_type new_size) { resize(new_size, value_type()); }public: // Erase iterator erase(iterator pos) { iterator next = pos; ++next; difference_type index = pos - start; if (index < (size() >> 1)) { copy_backward(start, pos, next); pop_front(); } else { copy(next, finish, pos); pop_back(); } return start + index; } iterator erase(iterator first, iterator last); void clear(); protected: // Internal construction/destruction void create_map_and_nodes(size_type num_elements); void destroy_map_and_nodes(); void fill_initialize(size_type n, const value_type& value);#ifdef __STL_MEMBER_TEMPLATES template <class InputIterator> void range_initialize(InputIterator first, InputIterator last, input_iterator_tag); template <class ForwardIterator> void range_initialize(ForwardIterator first, ForwardIterator last, forward_iterator_tag);#endif /* __STL_MEMBER_TEMPLATES */protected: // Internal push_* and pop_* void push_back_aux(const value_type& t); void push_front_aux(const value_type& t); void pop_back_aux(); void pop_front_aux();protected: // Internal insert functions#ifdef __STL_MEMBER_TEMPLATES template <class InputIterator> void insert(iterator pos, InputIterator first, InputIterator last, input_iterator_tag); template <class ForwardIterator> void insert(iterator pos, ForwardIterator first, ForwardIterator last, forward_iterator_tag);#endif /* __STL_MEMBER_TEMPLATES */ iterator insert_aux(iterator pos, const value_type& x); void insert_aux(iterator pos, size_type n, const value_type& x);#ifdef __STL_MEMBER_TEMPLATES template <class ForwardIterator> void insert_aux(iterator pos, ForwardIterator first, ForwardIterator last, size_type n);#else /* __STL_MEMBER_TEMPLATES */ void insert_aux(iterator pos, const value_type* first, const value_type* last, size_type n); void insert_aux(iterator pos, const_iterator first, const_iterator last, size_type n); #endif /* __STL_MEMBER_TEMPLATES */ iterator reserve_elements_at_front(size_type n) { size_type vacancies = start.cur - start.first; if (n > vacancies) new_elements_at_front(n - vacancies); return start - difference_type(n); } iterator reserve_elements_at_back(size_type n) { size_type vacancies = (finish.last - finish.cur) - 1; if (n > vacancies) new_elements_at_back(n - vacancies); return finish + difference_type(n); } void new_elements_at_front(size_type new_elements); void new_elements_at_back(size_type new_elements); void destroy_nodes_at_front(iterator before_start); void destroy_nodes_at_back(iterator after_finish);protected: // Allocation of map and nodes // Makes sure the map has space for new nodes. Does not actually // add the nodes. Can invalidate map pointers. (And consequently, // deque iterators.) void reserve_map_at_back (size_type nodes_to_add = 1) { if (nodes_to_add + 1 > map_size - (finish.node - map)) reallocate_map(nodes_to_add, false); } void reserve_map_at_front (size_type nodes_to_add = 1) { if (nodes_to_add > start.node - map) reallocate_map(nodes_to_add, true); } void reallocate_map(size_type nodes_to_add, bool add_at_front); pointer allocate_node() { return data_allocator::allocate(buffer_size()); } void deallocate_node(pointer n) { data_allocator::deallocate(n, buffer_size()); }#ifdef __STL_NON_TYPE_TMPL_PARAM_BUGpublic: bool operator==(const deque<T, Alloc, 0>& x) const { return size() == x.size() && equal(begin(), end(), x.begin()); } bool operator!=(const deque<T, Alloc, 0>& x) const { return size() != x.size() || !equal(begin(), end(), x.begin()); } bool operator<(const deque<T, Alloc, 0>& x) const { return lexicographical_compare(begin(), end(), x.begin(), x.end()); }#endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */};// Non-inline member functionstemplate <class T, class Alloc, size_t BufSize>void deque<T, Alloc, BufSize>::insert(iterator pos, size_type n, const value_type& x) { if (pos.cur == start.cur) { iterator new_start = reserve_elements_at_front(n); uninitialized_fill(new_start, start, x); start = new_start; } else if (pos.cur == finish.cur) { iterator new_finish = reserve_elements_at_back(n); uninitialized_fill(finish, new_finish, x); finish = new_finish; } else insert_aux(pos, n, x);}#ifndef __STL_MEMBER_TEMPLATES template <class T, class Alloc, size_t BufSize>void deque<T, Alloc, BufSize>::insert(iterator pos, const value_type* first, const value_type* last) { size_type n = last - first; if (pos.cur == start.cur) { iterator new_start = reserve_elements_at_front(n); __STL_TRY { uninitialized_copy(first, last, new_start); start = new_start; } __STL_UNWIND(destroy_nodes_at_front(new_start)); } else if (pos.cur == finish.cur) { iterator new_finish = reserve_elements_at_back(n); __STL_TRY { uninitialized_copy(first, last, finish); finish = new_finish; } __STL_UNWIND(destroy_nodes_at_back(new_finish)); } else insert_aux(pos, first, last, n);}template <class T, class Alloc, size_t BufSize>void deque<T, Alloc, BufSize>::insert(iterator pos, const_iterator first, const_iterator last){ size_type n = last - first; if (pos.cur == start.cur) { iterator new_start = reserve_elements_at_front(n); __STL_TRY { uninitialized_copy(first, last, new_start); start = new_start; } __STL_UNWIND(destroy_nodes_at_front(new_start)); } else if (pos.cur == finish.cur) { iterator new_finish = reserve_elements_at_back(n); __STL_TRY { uninitialized_copy(first, last, finish); finish = new_finish; } __STL_UNWIND(destroy_nodes_at_back(new_finish)); } else insert_aux(pos, first, last, n);}#endif /* __STL_MEMBER_TEMPLATES */template <class T, class Alloc, size_t BufSize>deque<T, Alloc, BufSize>::iterator deque<T, Alloc, BufSize>::erase(iterator first, iterator last) { if (first == start && last == finish) { clear(); return finish; } else { difference_type n = last - first; difference_type elems_before = first - start; if (elems_before < (size() - n) / 2) { copy_backward(start, first, last); iterator new_start = start + n; destroy(start, new_start); for (map_pointer cur = start.node; cur < new_start.node; ++cur) data_allocator::deallocate(*cur, buffer_size()); start = new_start; } else { copy(last, finish, first); iterator new_finish = finish - n; destroy(new_finish, finish); for (map_pointer cur = new_finish.node + 1; cur <= finish.node; ++cur) data_allocator::deallocate(*cur, buffer_size()); finish = new_finish; } return start + elems_before; }}template <class T, class Alloc, size_t BufSize>void deque<T, Alloc, BufSize>::clear() { for (map_pointer node = start.node + 1; node < finish.node; ++node) { destroy(*node, *node + buffer_size()); data_allocator::deallocate(*node, buffer_size()); } if (start.node != finish.node) { destroy(start.cur, start.last); destroy(finish.first, finish.cur); data_allocator::deallocate(finish.first, buffer_size()); } else destroy(start.cur, finish.cur); finish = start;}template <class T, class Alloc, size_t BufSize>void deque<T, Alloc, BufSize>::create_map_and_nodes(size_type num_elements) { size_type num_nodes = num_elements / buffer_size() + 1; map_size = max(initial_map_size(), num_nodes + 2); map = map_allocator::allocate(map_size); map_pointer nstart = map + (map_size - num_nodes) / 2; map_pointer nfinish = nstart + num_nodes - 1; map_pointer cur; __STL_TRY { for (cur = nstart; cur <= nfinish; ++cur) *cur = allocate_node(); }# ifdef __STL_USE_EXCEPTIONS catch(...) { for (map_pointer n = nstart; n < cur; ++n) deallocate_node(*n); map_allocator::deallocate(map, map_size); throw; }# endif /* __STL_USE_EXCEPTIONS */ start.set_node(nstart); finish.set_node(nfinish); start.cur = start.first; finish.cur = finish.first + num_elements % buffer_size();}// This is only used as a cleanup function in catch clauses.template <class T, class Alloc, size_t BufSize>void deque<T, Alloc, BufSize>::destroy_map_and_nodes() { for (map_pointer cur = start.node; cur <= finish.node; ++cur) deallocate_node(*cur); map_allocator::deallocate(map, map_size);} template <class T, class Alloc, size_t BufSize>void deque<T, Alloc, BufSize>::fill_initialize(size_type n, const value_type& value) { create_map_and_nodes(n); map_pointer cur; __STL_TRY { for (cur = start.node; cur < finish.node; ++cur) uninitialized_fill(*cur, *cur + buffer_size(), value); uninitialized_fill(finish.first, finish.cur, value); }# ifdef __STL_USE_EXCEPTIONS catch(...) { for (map_pointer n = start.node; n < cur; ++n) destroy(*n, *n + buffer_size()); destroy_map_and_nodes(); throw; }# endif /* __STL_USE_EXCEPTIONS */}#ifdef __STL_MEMBER_TEMPLATES template <class T, class Alloc, size_t BufSize>template <class InputIterator>void deque<T, Alloc, BufSize>::range_initialize(InputIterator first, InputIterator last, input_iterator_tag) { create_map_and_nodes(0); for ( ; first != last; ++first) push_back(*first);}template <class T, class Alloc, size_t BufSize>template <class ForwardIterator>void deque<T, Alloc, BufSize>::range_initialize(ForwardIterator first, ForwardIterator last, forward_iterator_tag) { size_type n = 0; distance(first, last, n); create_map_and_nodes(n); __STL_TRY { uninitialized_copy(first, last, start); } __STL_UNWIND(destroy_map_and_nodes());}#endif /* __STL_MEMBER_TEMPLATES */// Called only if finish.cur == finish.last - 1.template <class T, class Alloc, size_t BufSize>void deque<T, Alloc, BufSize>::push_back_aux(const value_type& t) { value_type t_copy = t; reserve_map_at_back(); *(finish.node + 1) = allocate_node(); __STL_TRY { construct(finish.cur, t_copy); finish.set_node(finish.node + 1); finish.cur = finish.first; } __STL_UNWIND(deallocate_node(*(finish.node + 1)));}// Called only if start.cur == start.first.template <class T, class Alloc, size_t BufSize>void deque<T, Alloc, BufSize>::push_front_aux(const value_type& t) { value_type t_copy = t; reserve_map_at_front(); *(start.node - 1) = allocate_node(); __STL_TRY {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -