list_base.hpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  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. namespace detail {
  20. //=========================================================================
  21. // Linked-List Generic Implementation Functions
  22. template <class Node, class Next>
  23. inline Node
  24. slist_insert_after(Node pos, Node x,
  25. 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
  34. slist_remove_after(Node pos,
  35. Next next)
  36. {
  37. Node n = next(pos);
  38. next(pos) = next(n);
  39. return n;
  40. }
  41. template <class Node, class Next>
  42. inline Node
  43. slist_remove_range(Node before_first, Node last,
  44. Next next)
  45. {
  46. next(before_first) = last;
  47. return last;
  48. }
  49. template <class Node, class Next>
  50. inline Node
  51. slist_previous(Node head, Node x, Node empty,
  52. Next next)
  53. {
  54. while (head != empty && next(head) != x)
  55. head = next(head);
  56. return head;
  57. }
  58. template<class Node, class Next>
  59. inline void
  60. slist_splice_after(Node pos, Node before_first, Node before_last,
  61. Next next)
  62. {
  63. if (pos != before_first && pos != before_last) {
  64. Node first = next(before_first);
  65. Node after = next(pos);
  66. next(before_first) = next(before_last);
  67. next(pos) = first;
  68. next(before_last) = after;
  69. }
  70. }
  71. template <class Node, class Next>
  72. inline Node
  73. slist_reverse(Node node, Node empty,
  74. Next next)
  75. {
  76. Node result = node;
  77. node = next(node);
  78. next(result) = empty;
  79. while(node) {
  80. Node next = next(node);
  81. next(node) = result;
  82. result = node;
  83. node = next;
  84. }
  85. return result;
  86. }
  87. template <class Node, class Next>
  88. inline std::size_t
  89. slist_size(Node head, Node empty,
  90. Next next)
  91. {
  92. std::size_t s = 0;
  93. for ( ; head != empty; head = next(head))
  94. ++s;
  95. return s;
  96. }
  97. template <class Next, class Data>
  98. class slist_iterator_policies
  99. {
  100. public:
  101. explicit slist_iterator_policies(const Next& n, const Data& d)
  102. : m_next(n), m_data(d) { }
  103. template <class Reference, class Node>
  104. Reference dereference(type<Reference>, const Node& x) const
  105. { return m_data(x); }
  106. template <class Node>
  107. void increment(Node& x) const
  108. { x = m_next(x); }
  109. template <class Node>
  110. bool equal(Node& x, Node& y) const
  111. { return x == y; }
  112. protected:
  113. Next m_next;
  114. Data m_data;
  115. };
  116. //===========================================================================
  117. // Doubly-Linked List Generic Implementation Functions
  118. template <class Node, class Next, class Prev>
  119. inline void
  120. dlist_insert_before(Node pos, Node x,
  121. Next next, Prev prev)
  122. {
  123. next(x) = pos;
  124. prev(x) = prev(pos);
  125. next(prev(pos)) = x;
  126. prev(pos) = x;
  127. }
  128. template <class Node, class Next, class Prev>
  129. void
  130. dlist_remove(Node pos,
  131. Next next, Prev prev)
  132. {
  133. Node next_node = next(pos);
  134. Node prev_node = prev(pos);
  135. next(prev_node) = next_node;
  136. prev(next_node) = prev_node;
  137. }
  138. // This deletes every node in the list except the
  139. // sentinel node.
  140. template <class Node, class Delete>
  141. inline void
  142. dlist_clear(Node sentinel, Delete del)
  143. {
  144. Node i, tmp;
  145. i = next(sentinel);
  146. while (i != sentinel) {
  147. tmp = i;
  148. i = next(i);
  149. del(tmp);
  150. }
  151. }
  152. template <class Node>
  153. inline bool
  154. dlist_empty(Node dummy)
  155. {
  156. return next(dummy) == dummy;
  157. }
  158. template <class Node, class Next, class Prev>
  159. void
  160. dlist_transfer(Node pos, Node first, Node last,
  161. Next next, Prev prev)
  162. {
  163. if (pos != last) {
  164. // Remove [first,last) from its old position
  165. next(prev(last)) = pos;
  166. next(prev(first)) = last;
  167. next(prev(pos)) = first;
  168. // Splice [first,last) into its new position
  169. Node tmp = prev(pos);
  170. prev(pos) = prev(last);
  171. prev(last) = prev(first);
  172. prev(first) = tmp;
  173. }
  174. }
  175. template <class Next, class Prev, class Data>
  176. class dlist_iterator_policies
  177. : public slist_iterator_policies<Next, Data>
  178. {
  179. typedef slist_iterator_policies<Next, Data> Base;
  180. public:
  181. template <class Node>
  182. void decrement(Node& x) const
  183. { x = m_prev(x); }
  184. dlist_iterator_policies(Next n, Prev p, Data d)
  185. : Base(n,d), m_prev(p) { }
  186. protected:
  187. Prev m_prev;
  188. };
  189. } // namespace detail
  190. } // namespace boost
  191. #endif // BOOST_LIST_BASE_HPP