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

📄 stl_deque.h

📁 著名的SGI的STL lib源码.(C++范型类编成,没有合适的分类,但是放到数据结构类别中也绝对适合)
💻 H
📖 第 1 页 / 共 3 页
字号:
/* * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation.  Hewlett-Packard Company makes no * representations about the suitability of this software for any * purpose.  It is provided "as is" without express or implied warranty. * * * Copyright (c) 1997 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation.  Silicon Graphics makes no * representations about the suitability of this software for any * purpose.  It is provided "as is" without express or implied warranty. *//* NOTE: This is an internal header file, included by other STL headers. *   You should not attempt to use it directly. */#ifndef __SGI_STL_INTERNAL_DEQUE_H#define __SGI_STL_INTERNAL_DEQUE_H/* Class invariants: *  For any nonsingular iterator i: *    i.node is the address of an element in the map array.  The *      contents of i.node is a pointer to the beginning of a node. *    i.first == *(i.node)  *    i.last  == i.first + node_size *    i.cur is a pointer in the range [i.first, i.last).  NOTE: *      the implication of this is that i.cur is always a dereferenceable *      pointer, even if i is a past-the-end iterator. *  Start and Finish are always nonsingular iterators.  NOTE: this means *    that an empty deque must have one node, and that a deque *    with N elements, where N is the buffer size, must have two nodes. *  For every node other than start.node and finish.node, every element *    in the node is an initialized object.  If start.node == finish.node, *    then [start.cur, finish.cur) are initialized objects, and *    the elements outside that range are uninitialized storage.  Otherwise, *    [start.cur, start.last) and [finish.first, finish.cur) are initialized *    objects, and [start.first, start.cur) and [finish.cur, finish.last) *    are uninitialized storage. *  [map, map + map_size) is a valid, non-empty range.   *  [start.node, finish.node] is a valid range contained within  *    [map, map + map_size).   *  A pointer in the range [map, map + map_size) points to an allocated *    node if and only if the pointer is in the range [start.node, finish.node]. *//* * In previous versions of deque, node_size was fixed by the  * implementation.  In this version, however, users can select * the node size.  Deque has three template parameters; the third, * a number of type size_t, is the number of elements per node. * If the third template parameter is 0 (which is the default),  * then deque will use a default node size. * * The only reason for using an alternate node size is if your application * requires a different performance tradeoff than the default.  If, * for example, your program contains many deques each of which contains * only a few elements, then you might want to save memory (possibly * by sacrificing some speed) by using smaller nodes. * * Unfortunately, some compilers have trouble with non-type template  * parameters; stl_config.h defines __STL_NON_TYPE_TMPL_PARAM_BUG if * that is the case.  If your compiler is one of them, then you will * not be able to use alternate node sizes; you will have to use the * default value. */__STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)#pragma set woff 1174#endif// Note: this function is simply a kludge to work around several compilers'//  bugs in handling constant expressions.inline size_t __deque_buf_size(size_t n, size_t sz){  return n != 0 ? n : (sz < 512 ? size_t(512 / sz) : size_t(1));}#ifndef __STL_NON_TYPE_TMPL_PARAM_BUGtemplate <class T, class Ref, class Ptr, size_t BufSiz>struct __deque_iterator {  typedef __deque_iterator<T, T&, T*, BufSiz>             iterator;  typedef __deque_iterator<T, const T&, const T*, BufSiz> const_iterator;  static size_t buffer_size() {return __deque_buf_size(BufSiz, sizeof(T)); }#else /* __STL_NON_TYPE_TMPL_PARAM_BUG */template <class T, class Ref, class Ptr>struct __deque_iterator {  typedef __deque_iterator<T, T&, T*>             iterator;  typedef __deque_iterator<T, const T&, const T*> const_iterator;  static size_t buffer_size() {return __deque_buf_size(0, sizeof(T)); }#endif  typedef random_access_iterator_tag iterator_category;  typedef T value_type;  typedef Ptr pointer;  typedef Ref reference;  typedef size_t size_type;  typedef ptrdiff_t difference_type;  typedef T** map_pointer;  typedef __deque_iterator self;  T* cur;  T* first;  T* last;  map_pointer node;  __deque_iterator(T* x, map_pointer y)     : cur(x), first(*y), last(*y + buffer_size()), node(y) {}  __deque_iterator() : cur(0), first(0), last(0), node(0) {}  __deque_iterator(const iterator& x)    : cur(x.cur), first(x.first), last(x.last), node(x.node) {}  reference operator*() const { return *cur; }#ifndef __SGI_STL_NO_ARROW_OPERATOR  pointer operator->() const { return &(operator*()); }#endif /* __SGI_STL_NO_ARROW_OPERATOR */  difference_type operator-(const self& x) const {    return difference_type(buffer_size()) * (node - x.node - 1) +      (cur - first) + (x.last - x.cur);  }  self& operator++() {    ++cur;    if (cur == last) {      set_node(node + 1);      cur = first;    }    return *this;   }  self operator++(int)  {    self tmp = *this;    ++*this;    return tmp;  }  self& operator--() {    if (cur == first) {      set_node(node - 1);      cur = last;    }    --cur;    return *this;  }  self operator--(int) {    self tmp = *this;    --*this;    return tmp;  }  self& operator+=(difference_type n) {    difference_type offset = n + (cur - first);    if (offset >= 0 && offset < difference_type(buffer_size()))      cur += n;    else {      difference_type node_offset =        offset > 0 ? offset / difference_type(buffer_size())                   : -difference_type((-offset - 1) / buffer_size()) - 1;      set_node(node + node_offset);      cur = first + (offset - node_offset * difference_type(buffer_size()));    }    return *this;  }  self operator+(difference_type n) const {    self tmp = *this;    return tmp += n;  }  self& operator-=(difference_type n) { return *this += -n; }   self operator-(difference_type n) const {    self tmp = *this;    return tmp -= n;  }  reference operator[](difference_type n) const { return *(*this + n); }  bool operator==(const self& x) const { return cur == x.cur; }  bool operator!=(const self& x) const { return !(*this == x); }  bool operator<(const self& x) const {    return (node == x.node) ? (cur < x.cur) : (node < x.node);  }  void set_node(map_pointer new_node) {    node = new_node;    first = *new_node;    last = first + difference_type(buffer_size());  }};#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION#ifndef __STL_NON_TYPE_TMPL_PARAM_BUGtemplate <class T, class Ref, class Ptr, size_t BufSiz>inline random_access_iterator_tagiterator_category(const __deque_iterator<T, Ref, Ptr, BufSiz>&) {  return random_access_iterator_tag();}template <class T, class Ref, class Ptr, size_t BufSiz>inline T* value_type(const __deque_iterator<T, Ref, Ptr, BufSiz>&) {  return 0;}template <class T, class Ref, class Ptr, size_t BufSiz>inline ptrdiff_t* distance_type(const __deque_iterator<T, Ref, Ptr, BufSiz>&) {  return 0;}#else /* __STL_NON_TYPE_TMPL_PARAM_BUG */template <class T, class Ref, class Ptr>inline random_access_iterator_tagiterator_category(const __deque_iterator<T, Ref, Ptr>&) {  return random_access_iterator_tag();}template <class T, class Ref, class Ptr>inline T* value_type(const __deque_iterator<T, Ref, Ptr>&) { return 0; }template <class T, class Ref, class Ptr>inline ptrdiff_t* distance_type(const __deque_iterator<T, Ref, Ptr>&) {  return 0;}#endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */// See __deque_buf_size().  The only reason that the default value is 0//  is as a workaround for bugs in the way that some compilers handle//  constant expressions.template <class T, class Alloc = alloc, size_t BufSiz = 0> class deque {public:                         // Basic types  typedef T value_type;  typedef value_type* pointer;  typedef const value_type* const_pointer;  typedef value_type& reference;  typedef const value_type& const_reference;  typedef size_t size_type;  typedef ptrdiff_t difference_type;public:                         // Iterators#ifndef __STL_NON_TYPE_TMPL_PARAM_BUG  typedef __deque_iterator<T, T&, T*, BufSiz>              iterator;  typedef __deque_iterator<T, const T&, const T&, BufSiz>  const_iterator;#else /* __STL_NON_TYPE_TMPL_PARAM_BUG */  typedef __deque_iterator<T, T&, T*>                      iterator;  typedef __deque_iterator<T, const T&, const T*>          const_iterator;#endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION  typedef reverse_iterator<const_iterator> const_reverse_iterator;  typedef reverse_iterator<iterator> reverse_iterator;#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */  typedef reverse_iterator<const_iterator, value_type, const_reference,                            difference_type>            const_reverse_iterator;  typedef reverse_iterator<iterator, value_type, reference, difference_type>          reverse_iterator; #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */protected:                      // Internal typedefs  typedef pointer* map_pointer;  typedef simple_alloc<value_type, Alloc> data_allocator;  typedef simple_alloc<pointer, Alloc> map_allocator;  static size_type buffer_size() {    return __deque_buf_size(BufSiz, sizeof(value_type));  }  static size_type initial_map_size() { return 8; }protected:                      // Data members  iterator start;  iterator finish;  map_pointer map;  size_type map_size;public:                         // Basic accessors  iterator begin() { return start; }  iterator end() { return finish; }  const_iterator begin() const { return start; }  const_iterator end() const { return finish; }  reverse_iterator rbegin() { return reverse_iterator(finish); }  reverse_iterator rend() { return reverse_iterator(start); }  const_reverse_iterator rbegin() const {    return const_reverse_iterator(finish);  }  const_reverse_iterator rend() const {    return const_reverse_iterator(start);  }  reference operator[](size_type n) { return start[difference_type(n)]; }  const_reference operator[](size_type n) const {    return start[difference_type(n)];  }  reference front() { return *start; }  reference back() {    iterator tmp = finish;    --tmp;    return *tmp;  }  const_reference front() const { return *start; }  const_reference back() const {    const_iterator tmp = finish;    --tmp;    return *tmp;  }  size_type size() const { return finish - start;; }  size_type max_size() const { return size_type(-1); }  bool empty() const { return finish == start; }public:                         // Constructor, destructor.  deque()    : start(), finish(), map(0), map_size(0)  {    create_map_and_nodes(0);  }  deque(const deque& x)    : start(), finish(), map(0), map_size(0)  {    create_map_and_nodes(x.size());    __STL_TRY {      uninitialized_copy(x.begin(), x.end(), start);    }    __STL_UNWIND(destroy_map_and_nodes());  }  deque(size_type n, const value_type& value)    : start(), finish(), map(0), map_size(0)  {    fill_initialize(n, value);  }  deque(int n, const value_type& value)    : start(), finish(), map(0), map_size(0)  {    fill_initialize(n, value);  }   deque(long n, const value_type& value)    : start(), finish(), map(0), map_size(0)  {    fill_initialize(n, value);  }  explicit deque(size_type n)    : start(), finish(), map(0), map_size(0)  {    fill_initialize(n, value_type());  }#ifdef __STL_MEMBER_TEMPLATES  template <class InputIterator>  deque(InputIterator first, InputIterator last)    : start(), finish(), map(0), map_size(0)  {    range_initialize(first, last, iterator_category(first));  }#else /* __STL_MEMBER_TEMPLATES */  deque(const value_type* first, const value_type* last)    : start(), finish(), map(0), map_size(0)  {    create_map_and_nodes(last - first);    __STL_TRY {      uninitialized_copy(first, last, start);    }    __STL_UNWIND(destroy_map_and_nodes());  }  deque(const_iterator first, const_iterator last)    : start(), finish(), map(0), map_size(0)  {    create_map_and_nodes(last - first);    __STL_TRY {      uninitialized_copy(first, last, start);    }    __STL_UNWIND(destroy_map_and_nodes());  }#endif /* __STL_MEMBER_TEMPLATES */  ~deque() {    destroy(start, finish);    destroy_map_and_nodes();  }  deque& operator= (const deque& x) {    const size_type len = size();    if (&x != this) {      if (len >= x.size())        erase(copy(x.begin(), x.end(), start), finish);      else {        const_iterator mid = x.begin() + difference_type(len);        copy(x.begin(), mid, start);        insert(finish, mid, x.end());      }    }    return *this;  }          void swap(deque& x) {    __STD::swap(start, x.start);    __STD::swap(finish, x.finish);    __STD::swap(map, x.map);    __STD::swap(map_size, x.map_size);  }public:                         // push_* and pop_*    void push_back(const value_type& t) {    if (finish.cur != finish.last - 1) {      construct(finish.cur, t);      ++finish.cur;    }    else      push_back_aux(t);  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -