list.hpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // list.hpp
  3. // A simple implementation of std::list that allows incomplete
  4. // types, does no dynamic allocation in the default constructor,
  5. // and has a guarnteed O(1) splice.
  6. //
  7. // Copyright 2009 Eric Niebler. Distributed under the Boost
  8. // Software License, Version 1.0. (See accompanying file
  9. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  10. #ifndef BOOST_XPRESSIVE_DETAIL_CORE_LIST_HPP_EAN_10_26_2009
  11. #define BOOST_XPRESSIVE_DETAIL_CORE_LIST_HPP_EAN_10_26_2009
  12. // MS compatible compilers support #pragma once
  13. #if defined(_MSC_VER)
  14. # pragma once
  15. #endif
  16. #include <cstddef>
  17. #include <iterator>
  18. #include <algorithm>
  19. #include <boost/assert.hpp>
  20. #include <boost/iterator/iterator_facade.hpp>
  21. namespace boost { namespace xpressive { namespace detail
  22. {
  23. ///////////////////////////////////////////////////////////////////////////////
  24. // list
  25. //
  26. template<typename T>
  27. struct list
  28. {
  29. private:
  30. struct node_base
  31. {
  32. node_base *_prev;
  33. node_base *_next;
  34. };
  35. struct node : node_base
  36. {
  37. explicit node(T const &value)
  38. : _value(value)
  39. {}
  40. T _value;
  41. };
  42. node_base _sentry;
  43. template<typename Ref = T &>
  44. struct list_iterator
  45. : boost::iterator_facade<list_iterator<Ref>, T, std::bidirectional_iterator_tag, Ref>
  46. {
  47. list_iterator(list_iterator<> const &it) : _node(it._node) {}
  48. explicit list_iterator(node_base *n = 0) : _node(n) {}
  49. private:
  50. friend struct list<T>;
  51. friend class boost::iterator_core_access;
  52. Ref dereference() const { return static_cast<node *>(_node)->_value; }
  53. void increment() { _node = _node->_next; }
  54. void decrement() { _node = _node->_prev; }
  55. bool equal(list_iterator const &it) const { return _node == it._node; }
  56. node_base *_node;
  57. };
  58. public:
  59. typedef T *pointer;
  60. typedef T const *const_pointer;
  61. typedef T &reference;
  62. typedef T const &const_reference;
  63. typedef list_iterator<> iterator;
  64. typedef list_iterator<T const &> const_iterator;
  65. typedef std::size_t size_type;
  66. list()
  67. {
  68. _sentry._next = _sentry._prev = &_sentry;
  69. }
  70. list(list const &that)
  71. {
  72. _sentry._next = _sentry._prev = &_sentry;
  73. const_iterator it = that.begin(), e = that.end();
  74. for( ; it != e; ++it)
  75. push_back(*it);
  76. }
  77. list &operator =(list const &that)
  78. {
  79. list(that).swap(*this);
  80. return *this;
  81. }
  82. ~list()
  83. {
  84. clear();
  85. }
  86. void clear()
  87. {
  88. while(!empty())
  89. pop_front();
  90. }
  91. void swap(list &that) // throw()
  92. {
  93. list temp;
  94. temp.splice(temp.begin(), that); // move that to temp
  95. that.splice(that.begin(), *this); // move this to that
  96. splice(begin(), temp); // move temp to this
  97. }
  98. void push_front(T const &t)
  99. {
  100. node *new_node = new node(t);
  101. new_node->_next = _sentry._next;
  102. new_node->_prev = &_sentry;
  103. _sentry._next->_prev = new_node;
  104. _sentry._next = new_node;
  105. }
  106. void push_back(T const &t)
  107. {
  108. node *new_node = new node(t);
  109. new_node->_next = &_sentry;
  110. new_node->_prev = _sentry._prev;
  111. _sentry._prev->_next = new_node;
  112. _sentry._prev = new_node;
  113. }
  114. void pop_front()
  115. {
  116. BOOST_ASSERT(!empty());
  117. node *old_node = static_cast<node *>(_sentry._next);
  118. _sentry._next = old_node->_next;
  119. _sentry._next->_prev = &_sentry;
  120. delete old_node;
  121. }
  122. void pop_back()
  123. {
  124. BOOST_ASSERT(!empty());
  125. node *old_node = static_cast<node *>(_sentry._prev);
  126. _sentry._prev = old_node->_prev;
  127. _sentry._prev->_next = &_sentry;
  128. delete old_node;
  129. }
  130. bool empty() const
  131. {
  132. return _sentry._next == &_sentry;
  133. }
  134. void splice(iterator it, list &x)
  135. {
  136. if(x.empty())
  137. return;
  138. x._sentry._prev->_next = it._node;
  139. x._sentry._next->_prev = it._node->_prev;
  140. it._node->_prev->_next = x._sentry._next;
  141. it._node->_prev = x._sentry._prev;
  142. x._sentry._prev = x._sentry._next = &x._sentry;
  143. }
  144. void splice(iterator it, list &, iterator xit)
  145. {
  146. xit._node->_prev->_next = xit._node->_next;
  147. xit._node->_next->_prev = xit._node->_prev;
  148. xit._node->_next = it._node;
  149. xit._node->_prev = it._node->_prev;
  150. it._node->_prev = it._node->_prev->_next = xit._node;
  151. }
  152. reference front()
  153. {
  154. BOOST_ASSERT(!empty());
  155. return static_cast<node *>(_sentry._next)->_value;
  156. }
  157. const_reference front() const
  158. {
  159. BOOST_ASSERT(!empty());
  160. return static_cast<node *>(_sentry._next)->_value;
  161. }
  162. reference back()
  163. {
  164. BOOST_ASSERT(!empty());
  165. return static_cast<node *>(_sentry._prev)->_value;
  166. }
  167. const_reference back() const
  168. {
  169. BOOST_ASSERT(!empty());
  170. return static_cast<node *>(_sentry._prev)->_value;
  171. }
  172. iterator begin()
  173. {
  174. return iterator(_sentry._next);
  175. }
  176. const_iterator begin() const
  177. {
  178. return const_iterator(_sentry._next);
  179. }
  180. iterator end()
  181. {
  182. return iterator(&_sentry);
  183. }
  184. const_iterator end() const
  185. {
  186. return const_iterator(const_cast<node_base *>(&_sentry));
  187. }
  188. size_type size() const
  189. {
  190. return static_cast<size_type>(std::distance(begin(), end()));
  191. }
  192. };
  193. template<typename T>
  194. void swap(list<T> &lhs, list<T> &rhs)
  195. {
  196. lhs.swap(rhs);
  197. }
  198. }}} // namespace boost::xpressive::detail
  199. #endif