list.hpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. // Copyright 2008-2009 Daniel James.
  2. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  3. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  4. // Gratuitous single linked list.
  5. //
  6. // Sadly some STL implementations aren't up to scratch and I need a simple
  7. // cross-platform container. So here it is.
  8. #if !defined(UNORDERED_TEST_LIST_HEADER)
  9. #define UNORDERED_TEST_LIST_HEADER
  10. #include <boost/limits.hpp>
  11. #include <functional>
  12. #include <iterator>
  13. namespace test {
  14. template <typename It1, typename It2>
  15. bool equal(It1 begin, It1 end, It2 compare)
  16. {
  17. for (; begin != end; ++begin, ++compare)
  18. if (*begin != *compare)
  19. return false;
  20. return true;
  21. }
  22. template <typename It1, typename It2, typename Pred>
  23. bool equal(It1 begin, It1 end, It2 compare, Pred predicate)
  24. {
  25. for (; begin != end; ++begin, ++compare)
  26. if (!predicate(*begin, *compare))
  27. return false;
  28. return true;
  29. }
  30. template <typename T> class list;
  31. namespace test_detail {
  32. template <typename T> class list_node;
  33. template <typename T> class list_data;
  34. template <typename T> class list_iterator;
  35. template <typename T> class list_const_iterator;
  36. template <typename T> class list_node
  37. {
  38. list_node(list_node const&);
  39. list_node& operator=(list_node const&);
  40. public:
  41. T value_;
  42. list_node* next_;
  43. list_node(T const& v) : value_(v), next_(0) {}
  44. list_node(T const& v, list_node* n) : value_(v), next_(n) {}
  45. };
  46. template <typename T> class list_data
  47. {
  48. public:
  49. typedef list_node<T> node;
  50. typedef unsigned int size_type;
  51. node* first_;
  52. node** last_ptr_;
  53. size_type size_;
  54. list_data() : first_(0), last_ptr_(&first_), size_(0) {}
  55. ~list_data()
  56. {
  57. while (first_) {
  58. node* tmp = first_;
  59. first_ = first_->next_;
  60. delete tmp;
  61. }
  62. }
  63. private:
  64. list_data(list_data const&);
  65. list_data& operator=(list_data const&);
  66. };
  67. template <typename T> class list_iterator
  68. {
  69. friend class list_const_iterator<T>;
  70. friend class test::list<T>;
  71. typedef list_node<T> node;
  72. typedef list_const_iterator<T> const_iterator;
  73. node* ptr_;
  74. public:
  75. typedef T value_type;
  76. typedef T* pointer;
  77. typedef T& reference;
  78. typedef int difference_type;
  79. typedef std::forward_iterator_tag iterator_category;
  80. list_iterator() : ptr_(0) {}
  81. explicit list_iterator(node* x) : ptr_(x) {}
  82. T& operator*() const { return ptr_->value_; }
  83. T* operator->() const { return &ptr_->value_; }
  84. list_iterator& operator++()
  85. {
  86. ptr_ = ptr_->next_;
  87. return *this;
  88. }
  89. list_iterator operator++(int)
  90. {
  91. list_iterator tmp = *this;
  92. ptr_ = ptr_->next_;
  93. return tmp;
  94. }
  95. bool operator==(const_iterator y) const { return ptr_ == y.ptr_; }
  96. bool operator!=(const_iterator y) const { return ptr_ != y.ptr_; }
  97. };
  98. template <typename T> class list_const_iterator
  99. {
  100. friend class list_iterator<T>;
  101. friend class test::list<T>;
  102. typedef list_node<T> node;
  103. typedef list_iterator<T> iterator;
  104. typedef list_const_iterator<T> const_iterator;
  105. node* ptr_;
  106. public:
  107. typedef T value_type;
  108. typedef T const* pointer;
  109. typedef T const& reference;
  110. typedef int difference_type;
  111. typedef std::forward_iterator_tag iterator_category;
  112. list_const_iterator() : ptr_(0) {}
  113. list_const_iterator(list_iterator<T> const& x) : ptr_(x.ptr_) {}
  114. T const& operator*() const { return ptr_->value_; }
  115. T const* operator->() const { return &ptr_->value_; }
  116. list_const_iterator& operator++()
  117. {
  118. ptr_ = ptr_->next_;
  119. return *this;
  120. }
  121. list_const_iterator operator++(int)
  122. {
  123. list_const_iterator tmp = *this;
  124. ptr_ = ptr_->next_;
  125. return tmp;
  126. }
  127. bool operator==(const_iterator y) const { return ptr_ == y.ptr_; }
  128. bool operator!=(const_iterator y) const { return ptr_ != y.ptr_; }
  129. };
  130. }
  131. template <typename T> class list
  132. {
  133. typedef test::test_detail::list_data<T> data;
  134. typedef test::test_detail::list_node<T> node;
  135. data data_;
  136. public:
  137. typedef T value_type;
  138. typedef value_type& reference;
  139. typedef value_type const& const_reference;
  140. typedef unsigned int size_type;
  141. typedef test::test_detail::list_iterator<T> iterator;
  142. typedef test::test_detail::list_const_iterator<T> const_iterator;
  143. list() : data_() {}
  144. list(list const& other) : data_() { insert(other.begin(), other.end()); }
  145. template <class InputIterator>
  146. list(InputIterator i, InputIterator j) : data_()
  147. {
  148. insert(i, j);
  149. }
  150. list& operator=(list const& other)
  151. {
  152. clear();
  153. insert(other.begin(), other.end());
  154. return *this;
  155. }
  156. iterator begin() { return iterator(data_.first_); }
  157. iterator end() { return iterator(); }
  158. const_iterator begin() const { return iterator(data_.first_); }
  159. const_iterator end() const { return iterator(); }
  160. const_iterator cbegin() const { return iterator(data_.first_); }
  161. const_iterator cend() const { return iterator(); }
  162. template <class InputIterator> void insert(InputIterator i, InputIterator j)
  163. {
  164. for (; i != j; ++i)
  165. push_back(*i);
  166. }
  167. void push_front(value_type const& v)
  168. {
  169. data_.first_ = new node(v, data_.first_);
  170. if (!data_.size_)
  171. data_.last_ptr_ = &(*data_.last_ptr_)->next_;
  172. ++data_.size_;
  173. }
  174. void push_back(value_type const& v)
  175. {
  176. *data_.last_ptr_ = new node(v);
  177. data_.last_ptr_ = &(*data_.last_ptr_)->next_;
  178. ++data_.size_;
  179. }
  180. void clear()
  181. {
  182. while (data_.first_) {
  183. node* tmp = data_.first_;
  184. data_.first_ = data_.first_->next_;
  185. --data_.size_;
  186. delete tmp;
  187. }
  188. data_.last_ptr_ = &data_.first_;
  189. }
  190. void erase(const_iterator i, const_iterator j)
  191. {
  192. node** ptr = &data_.first_;
  193. while (*ptr != i.ptr_) {
  194. ptr = &(*ptr)->next_;
  195. }
  196. while (*ptr != j.ptr_) {
  197. node* to_delete = *ptr;
  198. *ptr = (*ptr)->next_;
  199. --data_.size_;
  200. delete to_delete;
  201. }
  202. if (!*ptr)
  203. data_.last_ptr_ = ptr;
  204. }
  205. bool empty() const { return !data_.size_; }
  206. size_type size() const { return data_.size_; }
  207. void sort() { sort(std::less<T>()); }
  208. template <typename Less> void sort(Less less = Less())
  209. {
  210. if (!empty())
  211. merge_sort(
  212. &data_.first_, (std::numeric_limits<size_type>::max)(), less);
  213. }
  214. bool operator==(list const& y) const
  215. {
  216. return size() == y.size() && test::equal(begin(), end(), y.begin());
  217. }
  218. bool operator!=(list const& y) const { return !(*this == y); }
  219. private:
  220. template <typename Less>
  221. node** merge_sort(node** l, size_type recurse_limit, Less less)
  222. {
  223. node** ptr = &(*l)->next_;
  224. for (size_type count = 0; count < recurse_limit && *ptr; ++count) {
  225. ptr = merge_adjacent_ranges(l, ptr, merge_sort(ptr, count, less), less);
  226. }
  227. return ptr;
  228. }
  229. template <typename Less>
  230. node** merge_adjacent_ranges(
  231. node** first, node** second, node** third, Less less)
  232. {
  233. for (;;) {
  234. for (;;) {
  235. if (first == second)
  236. return third;
  237. if (less((*second)->value_, (*first)->value_))
  238. break;
  239. first = &(*first)->next_;
  240. }
  241. swap_adjacent_ranges(first, second, third);
  242. first = &(*first)->next_;
  243. // Since the two ranges we just swapped, the order is now:
  244. // first...third...second
  245. for (;;) {
  246. if (first == third)
  247. return second;
  248. if (!less((*first)->value_, (*third)->value_))
  249. break;
  250. first = &(*first)->next_;
  251. }
  252. swap_adjacent_ranges(first, third, second);
  253. first = &(*first)->next_;
  254. }
  255. }
  256. void swap_adjacent_ranges(node** first, node** second, node** third)
  257. {
  258. node* tmp = *first;
  259. *first = *second;
  260. *second = *third;
  261. *third = tmp;
  262. if (!*second)
  263. data_.last_ptr_ = second;
  264. }
  265. };
  266. }
  267. #endif