list_base.hpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. //=======================================================================
  2. // Copyright 2002 Indiana University.
  3. // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See
  6. // accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //=======================================================================
  9. #ifndef BOOST_LIST_BASE_HPP
  10. #define BOOST_LIST_BASE_HPP
  11. #include <boost/iterator_adaptors.hpp>
  12. // Perhaps this should go through formal review, and move to <boost/>.
  13. /*
  14. An alternate interface idea:
  15. Extend the std::list functionality by creating remove/insert
  16. functions that do not require the container object!
  17. */
  18. namespace boost
  19. {
  20. namespace detail
  21. {
  22. //=========================================================================
  23. // Linked-List Generic Implementation Functions
  24. template < class Node, class Next >
  25. inline Node slist_insert_after(Node pos, Node x, Next next)
  26. {
  27. next(x) = next(pos);
  28. next(pos) = x;
  29. return x;
  30. }
  31. // return next(pos) or next(next(pos)) ?
  32. template < class Node, class Next >
  33. inline Node slist_remove_after(Node pos, Next next)
  34. {
  35. Node n = next(pos);
  36. next(pos) = next(n);
  37. return n;
  38. }
  39. template < class Node, class Next >
  40. inline Node slist_remove_range(Node before_first, Node last, Next next)
  41. {
  42. next(before_first) = last;
  43. return last;
  44. }
  45. template < class Node, class Next >
  46. inline Node slist_previous(Node head, Node x, Node empty, Next next)
  47. {
  48. while (head != empty && next(head) != x)
  49. head = next(head);
  50. return head;
  51. }
  52. template < class Node, class Next >
  53. inline void slist_splice_after(
  54. Node pos, Node before_first, Node before_last, Next next)
  55. {
  56. if (pos != before_first && pos != before_last)
  57. {
  58. Node first = next(before_first);
  59. Node after = next(pos);
  60. next(before_first) = next(before_last);
  61. next(pos) = first;
  62. next(before_last) = after;
  63. }
  64. }
  65. template < class Node, class Next >
  66. inline Node slist_reverse(Node node, Node empty, Next next)
  67. {
  68. Node result = node;
  69. node = next(node);
  70. next(result) = empty;
  71. while (node)
  72. {
  73. Node next = next(node);
  74. next(node) = result;
  75. result = node;
  76. node = next;
  77. }
  78. return result;
  79. }
  80. template < class Node, class Next >
  81. inline std::size_t slist_size(Node head, Node empty, Next next)
  82. {
  83. std::size_t s = 0;
  84. for (; head != empty; head = next(head))
  85. ++s;
  86. return s;
  87. }
  88. template < class Next, class Data > class slist_iterator_policies
  89. {
  90. public:
  91. explicit slist_iterator_policies(const Next& n, const Data& d)
  92. : m_next(n), m_data(d)
  93. {
  94. }
  95. template < class Reference, class Node >
  96. Reference dereference(type< Reference >, const Node& x) const
  97. {
  98. return m_data(x);
  99. }
  100. template < class Node > void increment(Node& x) const { x = m_next(x); }
  101. template < class Node > bool equal(Node& x, Node& y) const
  102. {
  103. return x == y;
  104. }
  105. protected:
  106. Next m_next;
  107. Data m_data;
  108. };
  109. //===========================================================================
  110. // Doubly-Linked List Generic Implementation Functions
  111. template < class Node, class Next, class Prev >
  112. inline void dlist_insert_before(Node pos, Node x, Next next, Prev prev)
  113. {
  114. next(x) = pos;
  115. prev(x) = prev(pos);
  116. next(prev(pos)) = x;
  117. prev(pos) = x;
  118. }
  119. template < class Node, class Next, class Prev >
  120. void dlist_remove(Node pos, Next next, Prev prev)
  121. {
  122. Node next_node = next(pos);
  123. Node prev_node = prev(pos);
  124. next(prev_node) = next_node;
  125. prev(next_node) = prev_node;
  126. }
  127. // This deletes every node in the list except the
  128. // sentinel node.
  129. template < class Node, class Delete >
  130. inline void dlist_clear(Node sentinel, Delete del)
  131. {
  132. Node i, tmp;
  133. i = next(sentinel);
  134. while (i != sentinel)
  135. {
  136. tmp = i;
  137. i = next(i);
  138. del(tmp);
  139. }
  140. }
  141. template < class Node > inline bool dlist_empty(Node dummy)
  142. {
  143. return next(dummy) == dummy;
  144. }
  145. template < class Node, class Next, class Prev >
  146. void dlist_transfer(Node pos, Node first, Node last, Next next, Prev prev)
  147. {
  148. if (pos != last)
  149. {
  150. // Remove [first,last) from its old position
  151. next(prev(last)) = pos;
  152. next(prev(first)) = last;
  153. next(prev(pos)) = first;
  154. // Splice [first,last) into its new position
  155. Node tmp = prev(pos);
  156. prev(pos) = prev(last);
  157. prev(last) = prev(first);
  158. prev(first) = tmp;
  159. }
  160. }
  161. template < class Next, class Prev, class Data >
  162. class dlist_iterator_policies : public slist_iterator_policies< Next, Data >
  163. {
  164. typedef slist_iterator_policies< Next, Data > Base;
  165. public:
  166. template < class Node > void decrement(Node& x) const { x = m_prev(x); }
  167. dlist_iterator_policies(Next n, Prev p, Data d) : Base(n, d), m_prev(p)
  168. {
  169. }
  170. protected:
  171. Prev m_prev;
  172. };
  173. } // namespace detail
  174. } // namespace boost
  175. #endif // BOOST_LIST_BASE_HPP