⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stl_deque.h

📁 著名的SGI的STL lib源码.(C++范型类编成,没有合适的分类,但是放到数据结构类别中也绝对适合)
💻 H
📖 第 1 页 / 共 3 页
字号:
  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 + -