| 
									
										
										
										
											2008-05-01 09:23:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-09 20:56:23 +00:00
										 |  |  | // Copyright 2008-2009 Daniel James.
 | 
					
						
							| 
									
										
										
										
											2008-05-01 09:23:22 +00:00
										 |  |  | // Distributed under the Boost Software License, Version 1.0. (See accompanying
 | 
					
						
							|  |  |  | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Gratuitous single linked list.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Sadly some STL implementations aren't up to scratch and I need a simple
 | 
					
						
							|  |  |  | // cross-platform container. So here it is.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if !defined(UNORDERED_TEST_LIST_HEADER)
 | 
					
						
							|  |  |  | #define UNORDERED_TEST_LIST_HEADER
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <boost/limits.hpp>
 | 
					
						
							|  |  |  | #include <functional>
 | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | #include <iterator>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace test { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   template <typename It1, typename It2> | 
					
						
							|  |  |  |   bool equal(It1 begin, It1 end, It2 compare) | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     for (; begin != end; ++begin, ++compare) | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       if (*begin != *compare) | 
					
						
							|  |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     return true; | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   template <typename It1, typename It2, typename Pred> | 
					
						
							|  |  |  |   bool equal(It1 begin, It1 end, It2 compare, Pred predicate) | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     for (; begin != end; ++begin, ++compare) | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       if (!predicate(*begin, *compare)) | 
					
						
							|  |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     return true; | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   template <typename T> class list; | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   namespace test_detail { | 
					
						
							|  |  |  |     template <typename T> class list_node; | 
					
						
							|  |  |  |     template <typename T> class list_data; | 
					
						
							|  |  |  |     template <typename T> class list_iterator; | 
					
						
							|  |  |  |     template <typename T> class list_const_iterator; | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |     template <typename T> class list_node | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       list_node(list_node const&); | 
					
						
							|  |  |  |       list_node& operator=(list_node const&); | 
					
						
							| 
									
										
										
										
											2008-05-01 09:23:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |     public: | 
					
						
							|  |  |  |       T value_; | 
					
						
							|  |  |  |       list_node* next_; | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       list_node(T const& v) : value_(v), next_(0) {} | 
					
						
							|  |  |  |       list_node(T const& v, list_node* n) : value_(v), next_(n) {} | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |     template <typename T> class list_data | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     public: | 
					
						
							|  |  |  |       typedef list_node<T> node; | 
					
						
							|  |  |  |       typedef unsigned int size_type; | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       node* first_; | 
					
						
							|  |  |  |       node** last_ptr_; | 
					
						
							|  |  |  |       size_type size_; | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       list_data() : first_(0), last_ptr_(&first_), size_(0) {} | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       ~list_data() | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |         while (first_) { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |           node* tmp = first_; | 
					
						
							|  |  |  |           first_ = first_->next_; | 
					
						
							|  |  |  |           delete tmp; | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2009-11-10 08:15:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |     private: | 
					
						
							|  |  |  |       list_data(list_data const&); | 
					
						
							|  |  |  |       list_data& operator=(list_data const&); | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-28 11:44:57 +00:00
										 |  |  |     template <typename T> class list_iterator | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |     { | 
					
						
							|  |  |  |       friend class list_const_iterator<T>; | 
					
						
							|  |  |  |       friend class test::list<T>; | 
					
						
							|  |  |  |       typedef list_node<T> node; | 
					
						
							|  |  |  |       typedef list_const_iterator<T> const_iterator; | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       node* ptr_; | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |     public: | 
					
						
							| 
									
										
										
										
											2017-12-28 12:00:59 +01:00
										 |  |  |       typedef T value_type; | 
					
						
							|  |  |  |       typedef T* pointer; | 
					
						
							|  |  |  |       typedef T& reference; | 
					
						
							|  |  |  |       typedef int difference_type; | 
					
						
							|  |  |  |       typedef std::forward_iterator_tag iterator_category; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       list_iterator() : ptr_(0) {} | 
					
						
							|  |  |  |       explicit list_iterator(node* x) : ptr_(x) {} | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       T& operator*() const { return ptr_->value_; } | 
					
						
							|  |  |  |       T* operator->() const { return &ptr_->value_; } | 
					
						
							|  |  |  |       list_iterator& operator++() | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |         ptr_ = ptr_->next_; | 
					
						
							|  |  |  |         return *this; | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       } | 
					
						
							|  |  |  |       list_iterator operator++(int) | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |         list_iterator tmp = *this; | 
					
						
							|  |  |  |         ptr_ = ptr_->next_; | 
					
						
							|  |  |  |         return tmp; | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-11-18 10:19:46 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       bool operator==(list_iterator y) const { return ptr_ == y.ptr_; } | 
					
						
							|  |  |  |       bool operator!=(list_iterator y) const { return ptr_ != y.ptr_; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       bool operator==(const_iterator y) const { return ptr_ == y.ptr_; } | 
					
						
							|  |  |  |       bool operator!=(const_iterator y) const { return ptr_ != y.ptr_; } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-28 11:44:57 +00:00
										 |  |  |     template <typename T> class list_const_iterator | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |     { | 
					
						
							|  |  |  |       friend class list_iterator<T>; | 
					
						
							|  |  |  |       friend class test::list<T>; | 
					
						
							|  |  |  |       typedef list_node<T> node; | 
					
						
							|  |  |  |       typedef list_iterator<T> iterator; | 
					
						
							|  |  |  |       typedef list_const_iterator<T> const_iterator; | 
					
						
							| 
									
										
										
										
											2008-05-01 09:23:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       node* ptr_; | 
					
						
							| 
									
										
										
										
											2010-01-04 22:49:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |     public: | 
					
						
							| 
									
										
										
										
											2017-12-28 12:00:59 +01:00
										 |  |  |       typedef T value_type; | 
					
						
							|  |  |  |       typedef T const* pointer; | 
					
						
							|  |  |  |       typedef T const& reference; | 
					
						
							|  |  |  |       typedef int difference_type; | 
					
						
							|  |  |  |       typedef std::forward_iterator_tag iterator_category; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       list_const_iterator() : ptr_(0) {} | 
					
						
							|  |  |  |       list_const_iterator(list_iterator<T> const& x) : ptr_(x.ptr_) {} | 
					
						
							| 
									
										
										
										
											2010-01-04 22:49:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       T const& operator*() const { return ptr_->value_; } | 
					
						
							|  |  |  |       T const* operator->() const { return &ptr_->value_; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       list_const_iterator& operator++() | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |         ptr_ = ptr_->next_; | 
					
						
							|  |  |  |         return *this; | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2010-01-04 22:49:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       list_const_iterator operator++(int) | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |         list_const_iterator tmp = *this; | 
					
						
							|  |  |  |         ptr_ = ptr_->next_; | 
					
						
							|  |  |  |         return tmp; | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2008-05-01 09:23:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       bool operator==(const_iterator y) const { return ptr_ == y.ptr_; } | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       bool operator!=(const_iterator y) const { return ptr_ != y.ptr_; } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   template <typename T> class list | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     typedef test::test_detail::list_data<T> data; | 
					
						
							|  |  |  |     typedef test::test_detail::list_node<T> node; | 
					
						
							|  |  |  |     data data_; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   public: | 
					
						
							|  |  |  |     typedef T value_type; | 
					
						
							|  |  |  |     typedef value_type& reference; | 
					
						
							|  |  |  |     typedef value_type const& const_reference; | 
					
						
							|  |  |  |     typedef unsigned int size_type; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     typedef test::test_detail::list_iterator<T> iterator; | 
					
						
							|  |  |  |     typedef test::test_detail::list_const_iterator<T> const_iterator; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     list() : data_() {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     list(list const& other) : data_() { insert(other.begin(), other.end()); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template <class InputIterator> | 
					
						
							|  |  |  |     list(InputIterator i, InputIterator j) : data_() | 
					
						
							| 
									
										
										
										
											2008-05-01 09:23:22 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       insert(i, j); | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-05-01 09:23:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     list& operator=(list const& other) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       clear(); | 
					
						
							|  |  |  |       insert(other.begin(), other.end()); | 
					
						
							|  |  |  |       return *this; | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-05-01 09:23:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     iterator begin() { return iterator(data_.first_); } | 
					
						
							|  |  |  |     iterator end() { return iterator(); } | 
					
						
							|  |  |  |     const_iterator begin() const { return iterator(data_.first_); } | 
					
						
							|  |  |  |     const_iterator end() const { return iterator(); } | 
					
						
							|  |  |  |     const_iterator cbegin() const { return iterator(data_.first_); } | 
					
						
							|  |  |  |     const_iterator cend() const { return iterator(); } | 
					
						
							| 
									
										
										
										
											2008-05-01 09:23:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     template <class InputIterator> void insert(InputIterator i, InputIterator j) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       for (; i != j; ++i) | 
					
						
							|  |  |  |         push_back(*i); | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-05-01 09:23:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     void push_front(value_type const& v) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       data_.first_ = new node(v, data_.first_); | 
					
						
							|  |  |  |       if (!data_.size_) | 
					
						
							|  |  |  |         data_.last_ptr_ = &(*data_.last_ptr_)->next_; | 
					
						
							|  |  |  |       ++data_.size_; | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-05-01 09:23:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     void push_back(value_type const& v) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       *data_.last_ptr_ = new node(v); | 
					
						
							|  |  |  |       data_.last_ptr_ = &(*data_.last_ptr_)->next_; | 
					
						
							|  |  |  |       ++data_.size_; | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-05-01 09:23:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     void clear() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       while (data_.first_) { | 
					
						
							|  |  |  |         node* tmp = data_.first_; | 
					
						
							|  |  |  |         data_.first_ = data_.first_->next_; | 
					
						
							|  |  |  |         --data_.size_; | 
					
						
							|  |  |  |         delete tmp; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       data_.last_ptr_ = &data_.first_; | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-05-01 09:23:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     void erase(const_iterator i, const_iterator j) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       node** ptr = &data_.first_; | 
					
						
							| 
									
										
										
										
											2008-05-01 09:23:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       while (*ptr != i.ptr_) { | 
					
						
							|  |  |  |         ptr = &(*ptr)->next_; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2008-05-01 09:23:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       while (*ptr != j.ptr_) { | 
					
						
							|  |  |  |         node* to_delete = *ptr; | 
					
						
							|  |  |  |         *ptr = (*ptr)->next_; | 
					
						
							|  |  |  |         --data_.size_; | 
					
						
							|  |  |  |         delete to_delete; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2008-05-01 09:23:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       if (!*ptr) | 
					
						
							|  |  |  |         data_.last_ptr_ = ptr; | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-05-01 09:23:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     bool empty() const { return !data_.size_; } | 
					
						
							| 
									
										
										
										
											2008-05-01 09:23:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     size_type size() const { return data_.size_; } | 
					
						
							| 
									
										
										
										
											2008-05-01 09:23:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     void sort() { sort(std::less<T>()); } | 
					
						
							| 
									
										
										
										
											2008-05-01 09:23:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     template <typename Less> void sort(Less less = Less()) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       if (!empty()) | 
					
						
							|  |  |  |         merge_sort( | 
					
						
							|  |  |  |           &data_.first_, (std::numeric_limits<size_type>::max)(), less); | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-05-01 09:23:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     bool operator==(list const& y) const | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       return size() == y.size() && test::equal(begin(), end(), y.begin()); | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bool operator!=(list const& y) const { return !(*this == y); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   private: | 
					
						
							|  |  |  |     template <typename Less> | 
					
						
							|  |  |  |     node** merge_sort(node** l, size_type recurse_limit, Less less) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       node** ptr = &(*l)->next_; | 
					
						
							|  |  |  |       for (size_type count = 0; count < recurse_limit && *ptr; ++count) { | 
					
						
							|  |  |  |         ptr = merge_adjacent_ranges(l, ptr, merge_sort(ptr, count, less), less); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       return ptr; | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template <typename Less> | 
					
						
							|  |  |  |     node** merge_adjacent_ranges( | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       node** first, node** second, node** third, Less less) | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       for (;;) { | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |         for (;;) { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |           if (first == second) | 
					
						
							|  |  |  |             return third; | 
					
						
							|  |  |  |           if (less((*second)->value_, (*first)->value_)) | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |           first = &(*first)->next_; | 
					
						
							| 
									
										
										
										
											2008-05-01 09:23:22 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         swap_adjacent_ranges(first, second, third); | 
					
						
							|  |  |  |         first = &(*first)->next_; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Since the two ranges we just swapped, the order is now:
 | 
					
						
							|  |  |  |         // first...third...second
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (;;) { | 
					
						
							|  |  |  |           if (first == third) | 
					
						
							|  |  |  |             return second; | 
					
						
							|  |  |  |           if (!less((*first)->value_, (*third)->value_)) | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |           first = &(*first)->next_; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         swap_adjacent_ranges(first, third, second); | 
					
						
							|  |  |  |         first = &(*first)->next_; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void swap_adjacent_ranges(node** first, node** second, node** third) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       node* tmp = *first; | 
					
						
							|  |  |  |       *first = *second; | 
					
						
							|  |  |  |       *second = *third; | 
					
						
							|  |  |  |       *third = tmp; | 
					
						
							|  |  |  |       if (!*second) | 
					
						
							|  |  |  |         data_.last_ptr_ = second; | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   }; | 
					
						
							| 
									
										
										
										
											2008-05-01 09:23:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 |