stl_list.h
上传用户:sichengcw
上传日期:2009-02-17
资源大小:202k
文件大小:17k
源码类别:

STL

开发平台:

Visual C++

  1. /*
  2.  *
  3.  * Copyright (c) 1994
  4.  * Hewlett-Packard Company
  5.  *
  6.  * Permission to use, copy, modify, distribute and sell this software
  7.  * and its documentation for any purpose is hereby granted without fee,
  8.  * provided that the above copyright notice appear in all copies and
  9.  * that both that copyright notice and this permission notice appear
  10.  * in supporting documentation.  Hewlett-Packard Company makes no
  11.  * representations about the suitability of this software for any
  12.  * purpose.  It is provided "as is" without express or implied warranty.
  13.  *
  14.  *
  15.  * Copyright (c) 1996,1997
  16.  * Silicon Graphics Computer Systems, Inc.
  17.  *
  18.  * Permission to use, copy, modify, distribute and sell this software
  19.  * and its documentation for any purpose is hereby granted without fee,
  20.  * provided that the above copyright notice appear in all copies and
  21.  * that both that copyright notice and this permission notice appear
  22.  * in supporting documentation.  Silicon Graphics makes no
  23.  * representations about the suitability of this software for any
  24.  * purpose.  It is provided "as is" without express or implied warranty.
  25.  */
  26. /* NOTE: This is an internal header file, included by other STL headers.
  27.  *   You should not attempt to use it directly.
  28.  */
  29. #ifndef __SGI_STL_INTERNAL_LIST_H
  30. #define __SGI_STL_INTERNAL_LIST_H
  31. __STL_BEGIN_NAMESPACE
  32. #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
  33. #pragma set woff 1174
  34. #endif
  35. template <class T>
  36. struct __list_node {
  37.   typedef void* void_pointer;
  38.   void_pointer next;
  39.   void_pointer prev;
  40.   T data;
  41. };
  42. template<class T, class Ref, class Ptr>
  43. struct __list_iterator {
  44.   typedef __list_iterator<T, T&, T*>             iterator;
  45.   typedef __list_iterator<T, const T&, const T*> const_iterator;
  46.   typedef __list_iterator<T, Ref, Ptr>           self;
  47.   typedef bidirectional_iterator_tag iterator_category;
  48.   typedef T value_type;
  49.   typedef Ptr pointer;
  50.   typedef Ref reference;
  51.   typedef __list_node<T>* link_type;
  52.   typedef size_t size_type;
  53.   typedef ptrdiff_t difference_type;
  54.   link_type node;
  55.   __list_iterator(link_type x) : node(x) {}
  56.   __list_iterator() {}
  57.   __list_iterator(const iterator& x) : node(x.node) {}
  58.   bool operator==(const self& x) const { return node == x.node; }
  59.   bool operator!=(const self& x) const { return node != x.node; }
  60.   reference operator*() const { return (*node).data; }
  61. #ifndef __SGI_STL_NO_ARROW_OPERATOR
  62.   pointer operator->() const { return &(operator*()); }
  63. #endif /* __SGI_STL_NO_ARROW_OPERATOR */
  64.   self& operator++() { 
  65.     node = (link_type)((*node).next);
  66.     return *this;
  67.   }
  68.   self operator++(int) { 
  69.     self tmp = *this;
  70.     ++*this;
  71.     return tmp;
  72.   }
  73.   self& operator--() { 
  74.     node = (link_type)((*node).prev);
  75.     return *this;
  76.   }
  77.   self operator--(int) { 
  78.     self tmp = *this;
  79.     --*this;
  80.     return tmp;
  81.   }
  82. };
  83. #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
  84. template <class T, class Ref, class Ptr>
  85. inline bidirectional_iterator_tag
  86. iterator_category(const __list_iterator<T, Ref, Ptr>&) {
  87.   return bidirectional_iterator_tag();
  88. }
  89. template <class T, class Ref, class Ptr>
  90. inline T*
  91. value_type(const __list_iterator<T, Ref, Ptr>&) {
  92.   return 0;
  93. }
  94. template <class T, class Ref, class Ptr>
  95. inline ptrdiff_t*
  96. distance_type(const __list_iterator<T, Ref, Ptr>&) {
  97.   return 0;
  98. }
  99. #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  100. template <class T, class Alloc = alloc>
  101. class list {
  102. protected:
  103.   typedef void* void_pointer;
  104.   typedef __list_node<T> list_node;
  105.   typedef simple_alloc<list_node, Alloc> list_node_allocator;
  106. public:      
  107.   typedef T value_type;
  108.   typedef value_type* pointer;
  109.   typedef const value_type* const_pointer;
  110.   typedef value_type& reference;
  111.   typedef const value_type& const_reference;
  112.   typedef list_node* link_type;
  113.   typedef size_t size_type;
  114.   typedef ptrdiff_t difference_type;
  115. public:
  116.   typedef __list_iterator<T, T&, T*>             iterator;
  117.   typedef __list_iterator<T, const T&, const T*> const_iterator;
  118. #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
  119.   typedef reverse_iterator<const_iterator> const_reverse_iterator;
  120.   typedef reverse_iterator<iterator> reverse_iterator;
  121. #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  122.   typedef reverse_bidirectional_iterator<const_iterator, value_type,
  123.   const_reference, difference_type>
  124.   const_reverse_iterator;
  125.   typedef reverse_bidirectional_iterator<iterator, value_type, reference,
  126.   difference_type>
  127.   reverse_iterator; 
  128. #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  129. protected:
  130.   link_type get_node() { return list_node_allocator::allocate(); }
  131.   void put_node(link_type p) { list_node_allocator::deallocate(p); }
  132.   link_type create_node(const T& x) {
  133.     link_type p = get_node();
  134.     __STL_TRY {
  135.       construct(&p->data, x);
  136.     }
  137.     __STL_UNWIND(put_node(p));
  138.     return p;
  139.   }
  140.   void destroy_node(link_type p) {
  141.     destroy(&p->data);
  142.     put_node(p);
  143.   }
  144. protected:
  145.   void empty_initialize() { 
  146.     node = get_node();
  147.     node->next = node;
  148.     node->prev = node;
  149.   }
  150.   void fill_initialize(size_type n, const T& value) {
  151.     empty_initialize();
  152.     __STL_TRY {
  153.       insert(begin(), n, value);
  154.     }
  155.     __STL_UNWIND(clear(); put_node(node));
  156.   }
  157. #ifdef __STL_MEMBER_TEMPLATES
  158.   template <class InputIterator>
  159.   void range_initialize(InputIterator first, InputIterator last) {
  160.     empty_initialize();
  161.     __STL_TRY {
  162.       insert(begin(), first, last);
  163.     }
  164.     __STL_UNWIND(clear(); put_node(node));
  165.   }
  166. #else  /* __STL_MEMBER_TEMPLATES */
  167.   void range_initialize(const T* first, const T* last) {
  168.     empty_initialize();
  169.     __STL_TRY {
  170.       insert(begin(), first, last);
  171.     }
  172.     __STL_UNWIND(clear(); put_node(node));
  173.   }
  174.   void range_initialize(const_iterator first, const_iterator last) {
  175.     empty_initialize();
  176.     __STL_TRY {
  177.       insert(begin(), first, last);
  178.     }
  179.     __STL_UNWIND(clear(); put_node(node));
  180.   }
  181. #endif /* __STL_MEMBER_TEMPLATES */
  182. protected:
  183.   link_type node;
  184. public:
  185.   list() { empty_initialize(); }
  186.   iterator begin() { return (link_type)((*node).next); }
  187.   const_iterator begin() const { return (link_type)((*node).next); }
  188.   iterator end() { return node; }
  189.   const_iterator end() const { return node; }
  190.   reverse_iterator rbegin() { return reverse_iterator(end()); }
  191.   const_reverse_iterator rbegin() const { 
  192.     return const_reverse_iterator(end()); 
  193.   }
  194.   reverse_iterator rend() { return reverse_iterator(begin()); }
  195.   const_reverse_iterator rend() const { 
  196.     return const_reverse_iterator(begin());
  197.   } 
  198.   bool empty() const { return node->next == node; }
  199.   size_type size() const {
  200.     size_type result = 0;
  201.     distance(begin(), end(), result);
  202.     return result;
  203.   }
  204.   size_type max_size() const { return size_type(-1); }
  205.   reference front() { return *begin(); }
  206.   const_reference front() const { return *begin(); }
  207.   reference back() { return *(--end()); }
  208.   const_reference back() const { return *(--end()); }
  209.   void swap(list<T, Alloc>& x) { __STD::swap(node, x.node); }
  210.   iterator insert(iterator position, const T& x) {
  211.     link_type tmp = create_node(x);
  212.     tmp->next = position.node;
  213.     tmp->prev = position.node->prev;
  214.     (link_type(position.node->prev))->next = tmp;
  215.     position.node->prev = tmp;
  216.     return tmp;
  217.   }
  218.   iterator insert(iterator position) { return insert(position, T()); }
  219. #ifdef __STL_MEMBER_TEMPLATES
  220.   template <class InputIterator>
  221.   void insert(iterator position, InputIterator first, InputIterator last);
  222. #else /* __STL_MEMBER_TEMPLATES */
  223.   void insert(iterator position, const T* first, const T* last);
  224.   void insert(iterator position,
  225.               const_iterator first, const_iterator last);
  226. #endif /* __STL_MEMBER_TEMPLATES */
  227.   void insert(iterator pos, size_type n, const T& x);
  228.   void insert(iterator pos, int n, const T& x) {
  229.     insert(pos, (size_type)n, x);
  230.   }
  231.   void insert(iterator pos, long n, const T& x) {
  232.     insert(pos, (size_type)n, x);
  233.   }
  234.   void push_front(const T& x) { insert(begin(), x); }
  235.   void push_back(const T& x) { insert(end(), x); }
  236.   iterator erase(iterator position) {
  237.     link_type next_node = link_type(position.node->next);
  238.     link_type prev_node = link_type(position.node->prev);
  239.     prev_node->next = next_node;
  240.     next_node->prev = prev_node;
  241.     destroy_node(position.node);
  242.     return iterator(next_node);
  243.   }
  244.   iterator erase(iterator first, iterator last);
  245.   void resize(size_type new_size, const T& x);
  246.   void resize(size_type new_size) { resize(new_size, T()); }
  247.   void clear();
  248.   void pop_front() { erase(begin()); }
  249.   void pop_back() { 
  250.     iterator tmp = end();
  251.     erase(--tmp);
  252.   }
  253.   list(size_type n, const T& value) { fill_initialize(n, value); }
  254.   list(int n, const T& value) { fill_initialize(n, value); }
  255.   list(long n, const T& value) { fill_initialize(n, value); }
  256.   explicit list(size_type n) { fill_initialize(n, T()); }
  257. #ifdef __STL_MEMBER_TEMPLATES
  258.   template <class InputIterator>
  259.   list(InputIterator first, InputIterator last) {
  260.     range_initialize(first, last);
  261.   }
  262. #else /* __STL_MEMBER_TEMPLATES */
  263.   list(const T* first, const T* last) { range_initialize(first, last); }
  264.   list(const_iterator first, const_iterator last) {
  265.     range_initialize(first, last);
  266.   }
  267. #endif /* __STL_MEMBER_TEMPLATES */
  268.   list(const list<T, Alloc>& x) {
  269.     range_initialize(x.begin(), x.end());
  270.   }
  271.   ~list() {
  272.     clear();
  273.     put_node(node);
  274.   }
  275.   list<T, Alloc>& operator=(const list<T, Alloc>& x);
  276. protected:
  277.   void transfer(iterator position, iterator first, iterator last) {
  278.     if (position != last) {
  279.       (*(link_type((*last.node).prev))).next = position.node;
  280.       (*(link_type((*first.node).prev))).next = last.node;
  281.       (*(link_type((*position.node).prev))).next = first.node;  
  282.       link_type tmp = link_type((*position.node).prev);
  283.       (*position.node).prev = (*last.node).prev;
  284.       (*last.node).prev = (*first.node).prev; 
  285.       (*first.node).prev = tmp;
  286.     }
  287.   }
  288. public:
  289.   void splice(iterator position, list& x) {
  290.     if (!x.empty()) 
  291.       transfer(position, x.begin(), x.end());
  292.   }
  293.   void splice(iterator position, list&, iterator i) {
  294.     iterator j = i;
  295.     ++j;
  296.     if (position == i || position == j) return;
  297.     transfer(position, i, j);
  298.   }
  299.   void splice(iterator position, list&, iterator first, iterator last) {
  300.     if (first != last) 
  301.       transfer(position, first, last);
  302.   }
  303.   void remove(const T& value);
  304.   void unique();
  305.   void merge(list& x);
  306.   void reverse();
  307.   void sort();
  308. #ifdef __STL_MEMBER_TEMPLATES
  309.   template <class Predicate> void remove_if(Predicate);
  310.   template <class BinaryPredicate> void unique(BinaryPredicate);
  311.   template <class StrictWeakOrdering> void merge(list&, StrictWeakOrdering);
  312.   template <class StrictWeakOrdering> void sort(StrictWeakOrdering);
  313. #endif /* __STL_MEMBER_TEMPLATES */
  314.   friend bool operator== __STL_NULL_TMPL_ARGS (const list& x, const list& y);
  315. };
  316. template <class T, class Alloc>
  317. inline bool operator==(const list<T,Alloc>& x, const list<T,Alloc>& y) {
  318.   typedef typename list<T,Alloc>::link_type link_type;
  319.   link_type e1 = x.node;
  320.   link_type e2 = y.node;
  321.   link_type n1 = (link_type) e1->next;
  322.   link_type n2 = (link_type) e2->next;
  323.   for ( ; n1 != e1 && n2 != e2 ;
  324.           n1 = (link_type) n1->next, n2 = (link_type) n2->next)
  325.     if (n1->data != n2->data)
  326.       return false;
  327.   return n1 == e1 && n2 == e2;
  328. }
  329. template <class T, class Alloc>
  330. inline bool operator<(const list<T, Alloc>& x, const list<T, Alloc>& y) {
  331.   return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
  332. }
  333. #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
  334. template <class T, class Alloc>
  335. inline void swap(list<T, Alloc>& x, list<T, Alloc>& y) {
  336.   x.swap(y);
  337. }
  338. #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
  339. #ifdef __STL_MEMBER_TEMPLATES
  340. template <class T, class Alloc> template <class InputIterator>
  341. void list<T, Alloc>::insert(iterator position,
  342.                             InputIterator first, InputIterator last) {
  343.   for ( ; first != last; ++first)
  344.     insert(position, *first);
  345. }
  346. #else /* __STL_MEMBER_TEMPLATES */
  347. template <class T, class Alloc>
  348. void list<T, Alloc>::insert(iterator position, const T* first, const T* last) {
  349.   for ( ; first != last; ++first)
  350.     insert(position, *first);
  351. }
  352. template <class T, class Alloc>
  353. void list<T, Alloc>::insert(iterator position,
  354.                             const_iterator first, const_iterator last) {
  355.   for ( ; first != last; ++first)
  356.     insert(position, *first);
  357. }
  358. #endif /* __STL_MEMBER_TEMPLATES */
  359. template <class T, class Alloc>
  360. void list<T, Alloc>::insert(iterator position, size_type n, const T& x) {
  361.   for ( ; n > 0; --n)
  362.     insert(position, x);
  363. }
  364. template <class T, class Alloc>
  365. list<T,Alloc>::iterator list<T, Alloc>::erase(iterator first, iterator last) {
  366.   while (first != last) erase(first++);
  367.   return last;
  368. }
  369. template <class T, class Alloc>
  370. void list<T, Alloc>::resize(size_type new_size, const T& x)
  371. {
  372.   iterator i = begin();
  373.   size_type len = 0;
  374.   for ( ; i != end() && len < new_size; ++i, ++len)
  375.     ;
  376.   if (len == new_size)
  377.     erase(i, end());
  378.   else                          // i == end()
  379.     insert(end(), new_size - len, x);
  380. }
  381. template <class T, class Alloc> 
  382. void list<T, Alloc>::clear()
  383. {
  384.   link_type cur = (link_type) node->next;
  385.   while (cur != node) {
  386.     link_type tmp = cur;
  387.     cur = (link_type) cur->next;
  388.     destroy_node(tmp);
  389.   }
  390.   node->next = node;
  391.   node->prev = node;
  392. }
  393. template <class T, class Alloc>
  394. list<T, Alloc>& list<T, Alloc>::operator=(const list<T, Alloc>& x) {
  395.   if (this != &x) {
  396.     iterator first1 = begin();
  397.     iterator last1 = end();
  398.     const_iterator first2 = x.begin();
  399.     const_iterator last2 = x.end();
  400.     while (first1 != last1 && first2 != last2) *first1++ = *first2++;
  401.     if (first2 == last2)
  402.       erase(first1, last1);
  403.     else
  404.       insert(last1, first2, last2);
  405.   }
  406.   return *this;
  407. }
  408. template <class T, class Alloc>
  409. void list<T, Alloc>::remove(const T& value) {
  410.   iterator first = begin();
  411.   iterator last = end();
  412.   while (first != last) {
  413.     iterator next = first;
  414.     ++next;
  415.     if (*first == value) erase(first);
  416.     first = next;
  417.   }
  418. }
  419. template <class T, class Alloc>
  420. void list<T, Alloc>::unique() {
  421.   iterator first = begin();
  422.   iterator last = end();
  423.   if (first == last) return;
  424.   iterator next = first;
  425.   while (++next != last) {
  426.     if (*first == *next)
  427.       erase(next);
  428.     else
  429.       first = next;
  430.     next = first;
  431.   }
  432. }
  433. template <class T, class Alloc>
  434. void list<T, Alloc>::merge(list<T, Alloc>& x) {
  435.   iterator first1 = begin();
  436.   iterator last1 = end();
  437.   iterator first2 = x.begin();
  438.   iterator last2 = x.end();
  439.   while (first1 != last1 && first2 != last2)
  440.     if (*first2 < *first1) {
  441.       iterator next = first2;
  442.       transfer(first1, first2, ++next);
  443.       first2 = next;
  444.     }
  445.     else
  446.       ++first1;
  447.   if (first2 != last2) transfer(last1, first2, last2);
  448. }
  449. template <class T, class Alloc>
  450. void list<T, Alloc>::reverse() {
  451.   if (node->next == node || link_type(node->next)->next == node) return;
  452.   iterator first = begin();
  453.   ++first;
  454.   while (first != end()) {
  455.     iterator old = first;
  456.     ++first;
  457.     transfer(begin(), old, first);
  458.   }
  459. }    
  460. template <class T, class Alloc>
  461. void list<T, Alloc>::sort() {
  462.   if (node->next == node || link_type(node->next)->next == node) return;
  463.   list<T, Alloc> carry;
  464.   list<T, Alloc> counter[64];
  465.   int fill = 0;
  466.   while (!empty()) {
  467.     carry.splice(carry.begin(), *this, begin());
  468.     int i = 0;
  469.     while(i < fill && !counter[i].empty()) {
  470.       counter[i].merge(carry);
  471.       carry.swap(counter[i++]);
  472.     }
  473.     carry.swap(counter[i]);         
  474.     if (i == fill) ++fill;
  475.   } 
  476.   for (int i = 1; i < fill; ++i) counter[i].merge(counter[i-1]);
  477.   swap(counter[fill-1]);
  478. }
  479. #ifdef __STL_MEMBER_TEMPLATES
  480. template <class T, class Alloc> template <class Predicate>
  481. void list<T, Alloc>::remove_if(Predicate pred) {
  482.   iterator first = begin();
  483.   iterator last = end();
  484.   while (first != last) {
  485.     iterator next = first;
  486.     ++next;
  487.     if (pred(*first)) erase(first);
  488.     first = next;
  489.   }
  490. }
  491. template <class T, class Alloc> template <class BinaryPredicate>
  492. void list<T, Alloc>::unique(BinaryPredicate binary_pred) {
  493.   iterator first = begin();
  494.   iterator last = end();
  495.   if (first == last) return;
  496.   iterator next = first;
  497.   while (++next != last) {
  498.     if (binary_pred(*first, *next))
  499.       erase(next);
  500.     else
  501.       first = next;
  502.     next = first;
  503.   }
  504. }
  505. template <class T, class Alloc> template <class StrictWeakOrdering>
  506. void list<T, Alloc>::merge(list<T, Alloc>& x, StrictWeakOrdering comp) {
  507.   iterator first1 = begin();
  508.   iterator last1 = end();
  509.   iterator first2 = x.begin();
  510.   iterator last2 = x.end();
  511.   while (first1 != last1 && first2 != last2)
  512.     if (comp(*first2, *first1)) {
  513.       iterator next = first2;
  514.       transfer(first1, first2, ++next);
  515.       first2 = next;
  516.     }
  517.     else
  518.       ++first1;
  519.   if (first2 != last2) transfer(last1, first2, last2);
  520. }
  521. template <class T, class Alloc> template <class StrictWeakOrdering>
  522. void list<T, Alloc>::sort(StrictWeakOrdering comp) {
  523.   if (node->next == node || link_type(node->next)->next == node) return;
  524.   list<T, Alloc> carry;
  525.   list<T, Alloc> counter[64];
  526.   int fill = 0;
  527.   while (!empty()) {
  528.     carry.splice(carry.begin(), *this, begin());
  529.     int i = 0;
  530.     while(i < fill && !counter[i].empty()) {
  531.       counter[i].merge(carry, comp);
  532.       carry.swap(counter[i++]);
  533.     }
  534.     carry.swap(counter[i]);         
  535.     if (i == fill) ++fill;
  536.   } 
  537.   for (int i = 1; i < fill; ++i) counter[i].merge(counter[i-1], comp);
  538.   swap(counter[fill-1]);
  539. }
  540. #endif /* __STL_MEMBER_TEMPLATES */
  541. #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
  542. #pragma reset woff 1174
  543. #endif
  544. __STL_END_NAMESPACE 
  545. #endif /* __SGI_STL_INTERNAL_LIST_H */
  546. // Local Variables:
  547. // mode:C++
  548. // End: