| 
									
										
										
										
											2009-08-30 16:42:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard.
 | 
					
						
							| 
									
										
										
										
											2011-06-04 16:17:07 +00:00
										 |  |  | // Copyright (C) 2005-2011 Daniel James
 | 
					
						
							| 
									
										
										
										
											2009-08-30 16:42:28 +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)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef BOOST_UNORDERED_DETAIL_ALL_HPP_INCLUDED
 | 
					
						
							|  |  |  | #define BOOST_UNORDERED_DETAIL_ALL_HPP_INCLUDED
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-04 07:03:04 +00:00
										 |  |  | #include <boost/unordered/detail/buckets.hpp>
 | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  | #include <boost/unordered/detail/util.hpp>
 | 
					
						
							|  |  |  | #include <boost/type_traits/aligned_storage.hpp>
 | 
					
						
							|  |  |  | #include <boost/type_traits/alignment_of.hpp>
 | 
					
						
							|  |  |  | #include <boost/iterator.hpp>
 | 
					
						
							|  |  |  | #include <cmath>
 | 
					
						
							| 
									
										
										
										
											2009-08-30 16:42:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  | namespace boost { namespace unordered { namespace iterator_detail { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  |     // Iterators
 | 
					
						
							|  |  |  |     //
 | 
					
						
							|  |  |  |     // all no throw
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template <typename NodePointer, typename Value> struct iterator; | 
					
						
							| 
									
										
										
										
											2011-10-07 08:19:53 +00:00
										 |  |  |     template <typename ConstNodePointer, typename NodePointer, | 
					
						
							|  |  |  |         typename Value> struct c_iterator; | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |     template <typename NodePointer, typename Value> struct l_iterator; | 
					
						
							| 
									
										
										
										
											2011-10-07 08:19:53 +00:00
										 |  |  |     template <typename ConstNodePointer, typename NodePointer, | 
					
						
							|  |  |  |         typename Value> struct cl_iterator; | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |     // Local Iterators
 | 
					
						
							|  |  |  |     //
 | 
					
						
							|  |  |  |     // all no throw
 | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |     template <typename NodePointer, typename Value> | 
					
						
							|  |  |  |     struct l_iterator | 
					
						
							| 
									
										
										
										
											2011-10-06 08:03:25 +00:00
										 |  |  |         : public boost::iterator< | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |             std::forward_iterator_tag, Value, std::ptrdiff_t, | 
					
						
							|  |  |  |             NodePointer, Value&> | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  | #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
 | 
					
						
							| 
									
										
										
										
											2011-10-07 08:19:53 +00:00
										 |  |  |         template <typename ConstNodePointer, typename NodePointer2, | 
					
						
							|  |  |  |                 typename Value2> | 
					
						
							| 
									
										
										
										
											2011-10-06 08:03:25 +00:00
										 |  |  |         friend struct boost::unordered::iterator_detail::cl_iterator; | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |     private: | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |         typedef NodePointer node_pointer; | 
					
						
							|  |  |  |         node_pointer ptr_; | 
					
						
							|  |  |  |         std::size_t bucket_; | 
					
						
							|  |  |  |         std::size_t bucket_count_; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |     public: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |         l_iterator() : ptr_() {} | 
					
						
							| 
									
										
										
										
											2009-08-30 16:42:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |         l_iterator(node_pointer x, std::size_t b, std::size_t c) | 
					
						
							|  |  |  |             : ptr_(x), bucket_(b), bucket_count_(c) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Value& operator*() const { | 
					
						
							|  |  |  |             return ptr_->value(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Value* operator->() const { | 
					
						
							|  |  |  |             return ptr_->value_ptr(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         l_iterator& operator++() { | 
					
						
							|  |  |  |             ptr_ = static_cast<node_pointer>(ptr_->next_); | 
					
						
							|  |  |  |             if (ptr_ && ptr_->hash_ % bucket_count_ != bucket_) | 
					
						
							|  |  |  |                 ptr_ = node_pointer(); | 
					
						
							|  |  |  |             return *this; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         l_iterator operator++(int) { | 
					
						
							|  |  |  |             l_iterator tmp(*this); | 
					
						
							|  |  |  |             ++(*this); | 
					
						
							|  |  |  |             return tmp; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         bool operator==(l_iterator x) const { | 
					
						
							|  |  |  |             return ptr_ == x.ptr_; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-08-30 16:42:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |         bool operator!=(l_iterator x) const { | 
					
						
							|  |  |  |             return ptr_ != x.ptr_; | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |     }; | 
					
						
							| 
									
										
										
										
											2009-08-30 16:42:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |     template <typename ConstNodePointer, typename NodePointer, typename Value> | 
					
						
							|  |  |  |     struct cl_iterator | 
					
						
							| 
									
										
										
										
											2011-10-06 08:03:25 +00:00
										 |  |  |         : public boost::iterator< | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |             std::forward_iterator_tag, Value, std::ptrdiff_t, | 
					
						
							|  |  |  |             ConstNodePointer, Value const&> | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-10-06 08:03:25 +00:00
										 |  |  |         friend struct boost::unordered::iterator_detail::l_iterator | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |             <NodePointer, Value>; | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |     private: | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         typedef NodePointer node_pointer; | 
					
						
							|  |  |  |         node_pointer ptr_; | 
					
						
							|  |  |  |         std::size_t bucket_; | 
					
						
							|  |  |  |         std::size_t bucket_count_; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         cl_iterator() : ptr_() {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-07 08:19:53 +00:00
										 |  |  |         cl_iterator(node_pointer x, std::size_t b, std::size_t c) : | 
					
						
							|  |  |  |             ptr_(x), bucket_(b), bucket_count_(c) {} | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-07 08:19:53 +00:00
										 |  |  |         cl_iterator(boost::unordered::iterator_detail::l_iterator< | 
					
						
							|  |  |  |                 NodePointer, Value> const& x) : | 
					
						
							|  |  |  |             ptr_(x.ptr_), bucket_(x.bucket_), bucket_count_(x.bucket_count_) | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |         {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Value const& | 
					
						
							|  |  |  |             operator*() const { | 
					
						
							|  |  |  |             return ptr_->value(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Value const* operator->() const { | 
					
						
							|  |  |  |             return ptr_->value_ptr(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         cl_iterator& operator++() { | 
					
						
							|  |  |  |             ptr_ = static_cast<node_pointer>(ptr_->next_); | 
					
						
							|  |  |  |             if (ptr_ && ptr_->hash_ % bucket_count_ != bucket_) | 
					
						
							|  |  |  |                 ptr_ = node_pointer(); | 
					
						
							|  |  |  |             return *this; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         cl_iterator operator++(int) { | 
					
						
							|  |  |  |             cl_iterator tmp(*this); | 
					
						
							|  |  |  |             ++(*this); | 
					
						
							|  |  |  |             return tmp; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         friend bool operator==(cl_iterator const& x, cl_iterator const& y) { | 
					
						
							|  |  |  |             return x.ptr_ == y.ptr_; | 
					
						
							| 
									
										
										
										
											2010-05-21 07:06:33 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |         friend bool operator!=(cl_iterator const& x, cl_iterator const& y) { | 
					
						
							|  |  |  |             return x.ptr_ != y.ptr_; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template <typename NodePointer, typename Value> | 
					
						
							|  |  |  |     struct iterator | 
					
						
							| 
									
										
										
										
											2011-10-06 08:03:25 +00:00
										 |  |  |         : public boost::iterator< | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |             std::forward_iterator_tag, Value, std::ptrdiff_t, | 
					
						
							|  |  |  |             NodePointer, Value&> | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  | #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
 | 
					
						
							| 
									
										
										
										
											2011-10-07 08:19:53 +00:00
										 |  |  |         template <typename ConstNodePointer, typename NodePointer2, | 
					
						
							|  |  |  |                 typename Value2> | 
					
						
							| 
									
										
										
										
											2011-10-06 08:03:25 +00:00
										 |  |  |         friend struct boost::unordered::iterator_detail::c_iterator; | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |     private: | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |         typedef NodePointer node_pointer; | 
					
						
							|  |  |  |         node_pointer node_; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |     public: | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         iterator() : node_() {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         explicit iterator(node_pointer const& x) : node_(x) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Value& operator*() const { | 
					
						
							|  |  |  |             return node_->value(); | 
					
						
							| 
									
										
										
										
											2009-08-30 16:42:28 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         Value* operator->() const { | 
					
						
							|  |  |  |             return &node_->value(); | 
					
						
							| 
									
										
										
										
											2009-09-20 21:55:15 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-08-30 16:42:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |         iterator& operator++() { | 
					
						
							| 
									
										
										
										
											2011-11-21 23:21:11 +00:00
										 |  |  |             node_ = static_cast<node_pointer>(node_->next_); | 
					
						
							| 
									
										
										
										
											2011-10-07 08:19:53 +00:00
										 |  |  |             return *this; | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-09-20 21:55:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |         iterator operator++(int) { | 
					
						
							| 
									
										
										
										
											2011-10-07 08:19:53 +00:00
										 |  |  |             iterator tmp(node_); | 
					
						
							| 
									
										
										
										
											2011-11-21 23:21:11 +00:00
										 |  |  |             node_ = static_cast<node_pointer>(node_->next_); | 
					
						
							| 
									
										
										
										
											2011-10-07 08:19:53 +00:00
										 |  |  |             return tmp; | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         bool operator==(iterator const& x) const { | 
					
						
							|  |  |  |             return node_ == x.node_; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         bool operator!=(iterator const& x) const { | 
					
						
							|  |  |  |             return node_ != x.node_; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template <typename ConstNodePointer, typename NodePointer, typename Value> | 
					
						
							|  |  |  |     struct c_iterator | 
					
						
							| 
									
										
										
										
											2011-10-06 08:03:25 +00:00
										 |  |  |         : public boost::iterator< | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |             std::forward_iterator_tag, Value, std::ptrdiff_t, | 
					
						
							|  |  |  |             ConstNodePointer, Value const&> | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-10-07 08:19:53 +00:00
										 |  |  |         friend struct boost::unordered::iterator_detail::iterator< | 
					
						
							|  |  |  |                 NodePointer, Value>; | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
 | 
					
						
							|  |  |  |         template <typename K, typename T, typename H, typename P, typename A> | 
					
						
							| 
									
										
										
										
											2011-10-06 08:03:25 +00:00
										 |  |  |         friend class boost::unordered::unordered_map; | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |         template <typename K, typename T, typename H, typename P, typename A> | 
					
						
							| 
									
										
										
										
											2011-10-06 08:03:25 +00:00
										 |  |  |         friend class boost::unordered::unordered_multimap; | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |         template <typename T, typename H, typename P, typename A> | 
					
						
							| 
									
										
										
										
											2011-10-06 08:03:25 +00:00
										 |  |  |         friend class boost::unordered::unordered_set; | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |         template <typename T, typename H, typename P, typename A> | 
					
						
							| 
									
										
										
										
											2011-10-06 08:03:25 +00:00
										 |  |  |         friend class boost::unordered::unordered_multiset; | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     private: | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         typedef NodePointer node_pointer; | 
					
						
							|  |  |  |         node_pointer node_; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         c_iterator() : node_() {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         explicit c_iterator(node_pointer const& x) : node_(x) {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-07 08:19:53 +00:00
										 |  |  |         c_iterator(boost::unordered::iterator_detail::iterator< | 
					
						
							|  |  |  |                 NodePointer, Value> const& x) : node_(x.node_) {} | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         Value const& operator*() const { | 
					
						
							|  |  |  |             return node_->value(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Value const* operator->() const { | 
					
						
							|  |  |  |             return &node_->value(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         c_iterator& operator++() { | 
					
						
							| 
									
										
										
										
											2011-10-07 08:19:53 +00:00
										 |  |  |             node_ = static_cast<node_pointer>(node_->next_); | 
					
						
							|  |  |  |             return *this; | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-08-30 16:42:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |         c_iterator operator++(int) { | 
					
						
							| 
									
										
										
										
											2011-10-07 08:19:53 +00:00
										 |  |  |             c_iterator tmp(node_); | 
					
						
							| 
									
										
										
										
											2011-11-21 23:21:11 +00:00
										 |  |  |             node_ = static_cast<node_pointer>(node_->next_); | 
					
						
							| 
									
										
										
										
											2011-10-07 08:19:53 +00:00
										 |  |  |             return tmp; | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         friend bool operator==(c_iterator const& x, c_iterator const& y) { | 
					
						
							|  |  |  |             return x.node_ == y.node_; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         friend bool operator!=(c_iterator const& x, c_iterator const& y) { | 
					
						
							|  |  |  |             return x.node_ != y.node_; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | }}} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace boost { namespace unordered { namespace detail { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  |     // convert double to std::size_t
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-07 08:19:53 +00:00
										 |  |  |     inline std::size_t double_to_size(double f) | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |     { | 
					
						
							|  |  |  |         return f >= static_cast<double>( | 
					
						
							|  |  |  |             (std::numeric_limits<std::size_t>::max)()) ? | 
					
						
							|  |  |  |             (std::numeric_limits<std::size_t>::max)() : | 
					
						
							|  |  |  |             static_cast<std::size_t>(f); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // The space used to store values in a node.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template <typename ValueType> | 
					
						
							|  |  |  |     struct value_base | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         typedef ValueType value_type; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-06 08:03:25 +00:00
										 |  |  |         typename boost::aligned_storage< | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |             sizeof(value_type), | 
					
						
							| 
									
										
										
										
											2011-10-06 08:03:25 +00:00
										 |  |  |             boost::alignment_of<value_type>::value>::type data_; | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         void* address() { | 
					
						
							|  |  |  |             return this; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         value_type& value() { | 
					
						
							|  |  |  |             return *(ValueType*) this; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         value_type* value_ptr() { | 
					
						
							|  |  |  |             return (ValueType*) this; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         value_base& operator=(value_base const&); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template <typename Types> | 
					
						
							|  |  |  |     struct table : | 
					
						
							| 
									
										
										
										
											2011-10-06 08:03:25 +00:00
										 |  |  |         boost::unordered::detail::buckets< | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |             typename Types::allocator, | 
					
						
							|  |  |  |             typename Types::bucket, | 
					
						
							|  |  |  |             typename Types::node>, | 
					
						
							| 
									
										
										
										
											2011-10-06 08:03:25 +00:00
										 |  |  |         boost::unordered::detail::functions< | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |             typename Types::hasher, | 
					
						
							|  |  |  |             typename Types::key_equal> | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     private: | 
					
						
							|  |  |  |         table(table const&); | 
					
						
							|  |  |  |         table& operator=(table const&); | 
					
						
							|  |  |  |     public: | 
					
						
							|  |  |  |         typedef typename Types::hasher hasher; | 
					
						
							|  |  |  |         typedef typename Types::key_equal key_equal; | 
					
						
							|  |  |  |         typedef typename Types::key_type key_type; | 
					
						
							|  |  |  |         typedef typename Types::extractor extractor; | 
					
						
							|  |  |  |         typedef typename Types::value_type value_type; | 
					
						
							|  |  |  |         typedef typename Types::table table_impl; | 
					
						
							|  |  |  |         typedef typename Types::link_pointer link_pointer; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-06 08:03:25 +00:00
										 |  |  |         typedef boost::unordered::detail::functions< | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |             typename Types::hasher, | 
					
						
							|  |  |  |             typename Types::key_equal> functions; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-06 08:03:25 +00:00
										 |  |  |         typedef boost::unordered::detail::buckets< | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |             typename Types::allocator, | 
					
						
							|  |  |  |             typename Types::bucket, | 
					
						
							|  |  |  |             typename Types::node> buckets; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         typedef typename buckets::node_allocator node_allocator; | 
					
						
							|  |  |  |         typedef typename buckets::node_allocator_traits node_allocator_traits; | 
					
						
							|  |  |  |         typedef typename buckets::node_pointer node_pointer; | 
					
						
							|  |  |  |         typedef typename buckets::const_node_pointer const_node_pointer; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-07 08:19:53 +00:00
										 |  |  |         typedef boost::unordered::iterator_detail:: | 
					
						
							|  |  |  |             iterator<node_pointer, value_type> iterator; | 
					
						
							|  |  |  |         typedef boost::unordered::iterator_detail:: | 
					
						
							|  |  |  |             c_iterator<const_node_pointer, node_pointer, value_type> c_iterator; | 
					
						
							|  |  |  |         typedef boost::unordered::iterator_detail:: | 
					
						
							|  |  |  |             l_iterator<node_pointer, value_type> l_iterator; | 
					
						
							|  |  |  |         typedef boost::unordered::iterator_detail:: | 
					
						
							|  |  |  |             cl_iterator<const_node_pointer, node_pointer, value_type> | 
					
						
							|  |  |  |             cl_iterator; | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // Members
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         float mlf_; | 
					
						
							|  |  |  |         std::size_t max_load_; // Only use if this->buckets_.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |         ////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  |         // Load methods
 | 
					
						
							| 
									
										
										
										
											2009-08-30 16:42:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |         std::size_t max_size() const | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             using namespace std; | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |             // size < mlf_ * count
 | 
					
						
							| 
									
										
										
										
											2011-10-07 08:19:53 +00:00
										 |  |  |             return boost::unordered::detail::double_to_size(ceil( | 
					
						
							| 
									
										
										
										
											2011-08-17 07:43:43 +00:00
										 |  |  |                     static_cast<double>(this->mlf_) * | 
					
						
							|  |  |  |                     static_cast<double>(this->max_bucket_count()) | 
					
						
							|  |  |  |                 )) - 1; | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-08-30 16:42:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |         std::size_t calculate_max_load() | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             using namespace std; | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |             // From 6.3.1/13:
 | 
					
						
							|  |  |  |             // Only resize when size >= mlf_ * count
 | 
					
						
							| 
									
										
										
										
											2011-10-07 08:19:53 +00:00
										 |  |  |             return boost::unordered::detail::double_to_size(ceil( | 
					
						
							| 
									
										
										
										
											2011-08-17 07:43:43 +00:00
										 |  |  |                     static_cast<double>(this->mlf_) * | 
					
						
							|  |  |  |                     static_cast<double>(this->bucket_count_) | 
					
						
							| 
									
										
										
										
											2011-08-17 21:29:41 +00:00
										 |  |  |                 )); | 
					
						
							| 
									
										
										
										
											2011-08-17 07:43:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         void max_load_factor(float z) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             BOOST_ASSERT(z > 0); | 
					
						
							|  |  |  |             mlf_ = (std::max)(z, minimum_max_load_factor); | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |             if (this->buckets_) | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |                 this->max_load_ = this->calculate_max_load(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-09-20 21:55:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |         std::size_t min_buckets_for_size(std::size_t size) const | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             BOOST_ASSERT(this->mlf_ != 0); | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |             using namespace std; | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |             // From 6.3.1/13:
 | 
					
						
							|  |  |  |             // size < mlf_ * count
 | 
					
						
							|  |  |  |             // => count > size / mlf_
 | 
					
						
							|  |  |  |             //
 | 
					
						
							|  |  |  |             // Or from rehash post-condition:
 | 
					
						
							|  |  |  |             // count > size / mlf_
 | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-06 08:03:25 +00:00
										 |  |  |             return boost::unordered::detail::next_prime( | 
					
						
							| 
									
										
										
										
											2011-10-07 08:19:53 +00:00
										 |  |  |                 boost::unordered::detail::double_to_size(floor( | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |                     static_cast<double>(size) / | 
					
						
							|  |  |  |                     static_cast<double>(mlf_))) + 1); | 
					
						
							| 
									
										
										
										
											2009-09-20 21:55:15 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-08-30 16:42:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |         ////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  |         // Constructors
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-11 21:18:43 +00:00
										 |  |  |         table(std::size_t num_buckets, | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |                 hasher const& hf, | 
					
						
							|  |  |  |                 key_equal const& eq, | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |                 node_allocator const& a) : | 
					
						
							| 
									
										
										
										
											2011-10-06 08:03:25 +00:00
										 |  |  |             buckets(a, boost::unordered::detail::next_prime(num_buckets)), | 
					
						
							| 
									
										
										
										
											2011-04-17 00:31:35 +00:00
										 |  |  |             functions(hf, eq), | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |             mlf_(1.0f), | 
					
						
							|  |  |  |             max_load_(0) | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |         {} | 
					
						
							| 
									
										
										
										
											2009-08-30 16:42:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |         table(table const& x, node_allocator const& a) : | 
					
						
							|  |  |  |             buckets(a, x.min_buckets_for_size(x.size_)), | 
					
						
							| 
									
										
										
										
											2011-04-17 00:31:35 +00:00
										 |  |  |             functions(x), | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |             mlf_(x.mlf_), | 
					
						
							|  |  |  |             max_load_(0) | 
					
						
							| 
									
										
										
										
											2009-09-20 21:55:15 +00:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |             if(x.size_) { | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |                 table_impl::copy_buckets_to(x, *this); | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |                 this->max_load_ = calculate_max_load(); | 
					
						
							| 
									
										
										
										
											2009-09-20 21:55:15 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |         // TODO: Why calculate_max_load?
 | 
					
						
							| 
									
										
										
										
											2011-10-06 08:03:25 +00:00
										 |  |  |         table(table& x, boost::unordered::detail::move_tag m) : | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |             buckets(x, m), | 
					
						
							| 
									
										
										
										
											2011-04-17 00:31:35 +00:00
										 |  |  |             functions(x), | 
					
						
							| 
									
										
										
										
											2011-08-14 18:53:29 +00:00
										 |  |  |             mlf_(x.mlf_), | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |             max_load_(calculate_max_load()) | 
					
						
							|  |  |  |         {} | 
					
						
							| 
									
										
										
										
											2009-08-30 16:42:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |         // TODO: Why not calculate_max_load?
 | 
					
						
							| 
									
										
										
										
											2011-08-14 18:53:29 +00:00
										 |  |  |         // TODO: Why do I use x's bucket count?
 | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |         table(table& x, node_allocator const& a, | 
					
						
							| 
									
										
										
										
											2011-10-06 08:03:25 +00:00
										 |  |  |                 boost::unordered::detail::move_tag m) : | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |             buckets(a, x.bucket_count_), | 
					
						
							| 
									
										
										
										
											2011-04-17 00:31:35 +00:00
										 |  |  |             functions(x), | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |             mlf_(x.mlf_), | 
					
						
							| 
									
										
										
										
											2011-08-14 18:53:29 +00:00
										 |  |  |             max_load_(x.max_load_) | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |         { | 
					
						
							|  |  |  |             if(a == x.node_alloc()) { | 
					
						
							| 
									
										
										
										
											2011-10-06 08:03:25 +00:00
										 |  |  |                 this->buckets::swap(x, false_type()); | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |             else if(x.size_) { | 
					
						
							| 
									
										
										
										
											2011-08-03 08:34:33 +00:00
										 |  |  |                 // Use a temporary table because move_buckets_to leaves the
 | 
					
						
							|  |  |  |                 // source container in a complete mess.
 | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-14 18:53:03 +00:00
										 |  |  |                 buckets tmp(x, m); | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |                 table_impl::move_buckets_to(tmp, *this); | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |                 this->max_load_ = calculate_max_load(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-09-20 21:55:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |         // Iterators
 | 
					
						
							| 
									
										
										
										
											2009-08-30 16:42:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |         node_pointer begin() const { | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |             return !this->buckets_ ? | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |                 node_pointer() : this->get_start(); | 
					
						
							| 
									
										
										
										
											2009-09-20 21:55:15 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-08-30 16:42:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |         // Assignment
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-11 21:19:05 +00:00
										 |  |  |         void assign(table const& x) | 
					
						
							| 
									
										
										
										
											2011-08-14 18:53:29 +00:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |             assign(x, | 
					
						
							| 
									
										
										
										
											2011-10-06 08:03:25 +00:00
										 |  |  |                 boost::unordered::detail::integral_constant<bool, | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |                     allocator_traits<node_allocator>:: | 
					
						
							|  |  |  |                     propagate_on_container_copy_assignment::value>()); | 
					
						
							| 
									
										
										
										
											2011-08-14 18:53:29 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-06 08:03:25 +00:00
										 |  |  |         void assign(table const& x, false_type) | 
					
						
							| 
									
										
										
										
											2011-08-11 21:19:05 +00:00
										 |  |  |         { | 
					
						
							|  |  |  |             table tmp(x, this->node_alloc()); | 
					
						
							| 
									
										
										
										
											2011-10-06 08:03:25 +00:00
										 |  |  |             this->swap(tmp, false_type()); | 
					
						
							| 
									
										
										
										
											2011-08-14 18:53:29 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-06 08:03:25 +00:00
										 |  |  |         void assign(table const& x, true_type) | 
					
						
							| 
									
										
										
										
											2011-08-14 18:53:29 +00:00
										 |  |  |         { | 
					
						
							|  |  |  |             table tmp(x, x.node_alloc()); | 
					
						
							|  |  |  |             // Need to delete before setting the allocator so that buckets
 | 
					
						
							|  |  |  |             // aren't deleted with the wrong allocator.
 | 
					
						
							|  |  |  |             if(this->buckets_) this->delete_buckets(); | 
					
						
							|  |  |  |             // TODO: Can allocator assignment throw?
 | 
					
						
							| 
									
										
										
										
											2011-08-15 21:34:01 +00:00
										 |  |  |             this->allocators_.assign(x.allocators_); | 
					
						
							| 
									
										
										
										
											2011-10-06 08:03:25 +00:00
										 |  |  |             this->swap(tmp, false_type()); | 
					
						
							| 
									
										
										
										
											2011-08-11 21:19:05 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         void move_assign(table& x) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |             move_assign(x, | 
					
						
							| 
									
										
										
										
											2011-10-06 08:03:25 +00:00
										 |  |  |                 boost::unordered::detail::integral_constant<bool, | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |                     allocator_traits<node_allocator>:: | 
					
						
							|  |  |  |                     propagate_on_container_move_assignment::value>()); | 
					
						
							| 
									
										
										
										
											2011-08-14 18:53:29 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-06 08:03:25 +00:00
										 |  |  |         void move_assign(table& x, true_type) | 
					
						
							| 
									
										
										
										
											2011-08-14 18:53:29 +00:00
										 |  |  |         { | 
					
						
							|  |  |  |             if(this->buckets_) this->delete_buckets(); | 
					
						
							| 
									
										
										
										
											2011-08-15 21:34:01 +00:00
										 |  |  |             this->allocators_.move_assign(x.allocators_); | 
					
						
							| 
									
										
										
										
											2011-08-14 18:53:29 +00:00
										 |  |  |             move_assign_no_alloc(x); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-06 08:03:25 +00:00
										 |  |  |         void move_assign(table& x, false_type) | 
					
						
							| 
									
										
										
										
											2011-08-14 18:53:29 +00:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2011-08-11 21:19:05 +00:00
										 |  |  |             if(this->node_alloc() == x.node_alloc()) { | 
					
						
							| 
									
										
										
										
											2011-08-14 18:53:29 +00:00
										 |  |  |                 if(this->buckets_) this->delete_buckets(); | 
					
						
							|  |  |  |                 move_assign_no_alloc(x); | 
					
						
							| 
									
										
										
										
											2011-08-11 21:19:05 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							| 
									
										
										
										
											2011-10-07 08:19:53 +00:00
										 |  |  |                 boost::unordered::detail::set_hash_functions<hasher, key_equal> | 
					
						
							|  |  |  |                     new_func_this(*this, x); | 
					
						
							| 
									
										
										
										
											2011-08-14 18:53:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-11 21:19:05 +00:00
										 |  |  |                 if (x.size_) { | 
					
						
							| 
									
										
										
										
											2011-10-07 08:19:53 +00:00
										 |  |  |                     buckets b(this->node_alloc(), | 
					
						
							|  |  |  |                         x.min_buckets_for_size(x.size_)); | 
					
						
							| 
									
										
										
										
											2011-08-14 18:53:03 +00:00
										 |  |  |                     buckets tmp(x, move_tag()); | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |                     table_impl::move_buckets_to(tmp, b); | 
					
						
							| 
									
										
										
										
											2011-08-14 18:53:03 +00:00
										 |  |  |                     b.swap(*this); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else { | 
					
						
							| 
									
										
										
										
											2011-08-14 18:53:29 +00:00
										 |  |  |                     this->clear(); | 
					
						
							| 
									
										
										
										
											2011-08-11 21:19:05 +00:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2011-08-14 18:53:29 +00:00
										 |  |  |                  | 
					
						
							|  |  |  |                 this->mlf_ = x.mlf_; | 
					
						
							|  |  |  |                 if (this->buckets_) this->max_load_ = calculate_max_load(); | 
					
						
							|  |  |  |                 new_func_this.commit(); | 
					
						
							| 
									
										
										
										
											2011-08-11 21:19:05 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2011-08-14 18:53:29 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         void move_assign_no_alloc(table& x) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2011-10-07 08:19:53 +00:00
										 |  |  |             boost::unordered::detail::set_hash_functions<hasher, key_equal> | 
					
						
							|  |  |  |                 new_func_this(*this, x); | 
					
						
							| 
									
										
										
										
											2011-08-14 18:53:29 +00:00
										 |  |  |             // No throw from here.
 | 
					
						
							|  |  |  |             this->move_buckets_from(x); | 
					
						
							|  |  |  |             this->mlf_ = x.mlf_; | 
					
						
							|  |  |  |             this->max_load_ = x.max_load_; | 
					
						
							| 
									
										
										
										
											2011-08-11 21:19:05 +00:00
										 |  |  |             new_func_this.commit(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |         ////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  |         // Swap & Move
 | 
					
						
							| 
									
										
										
										
											2009-08-30 16:42:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |         void swap(table& x) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |             swap(x, | 
					
						
							|  |  |  |                 boost::unordered::detail::integral_constant<bool, | 
					
						
							| 
									
										
										
										
											2011-08-14 18:53:29 +00:00
										 |  |  |                     allocator_traits<node_allocator>:: | 
					
						
							|  |  |  |                     propagate_on_container_swap::value>()); | 
					
						
							| 
									
										
										
										
											2009-09-04 07:03:04 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-14 18:53:29 +00:00
										 |  |  |         // Only swaps the allocators if Propagate::value
 | 
					
						
							|  |  |  |         template <typename Propagate> | 
					
						
							|  |  |  |         void swap(table& x, Propagate p) | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2011-10-07 08:19:53 +00:00
										 |  |  |             boost::unordered::detail::set_hash_functions<hasher, key_equal> | 
					
						
							|  |  |  |                 op1(*this, x); | 
					
						
							|  |  |  |             boost::unordered::detail::set_hash_functions<hasher, key_equal> | 
					
						
							|  |  |  |                 op2(x, *this); | 
					
						
							| 
									
										
										
										
											2011-08-14 18:53:29 +00:00
										 |  |  |             // I think swap can throw if Propagate::value,
 | 
					
						
							|  |  |  |             // since the allocators' swap can throw. Not sure though.
 | 
					
						
							|  |  |  |             this->buckets::swap(x, p); | 
					
						
							|  |  |  |             std::swap(this->mlf_, x.mlf_); | 
					
						
							|  |  |  |             std::swap(this->max_load_, x.max_load_); | 
					
						
							|  |  |  |             op1.commit(); | 
					
						
							|  |  |  |             op2.commit(); | 
					
						
							| 
									
										
										
										
											2009-08-30 16:42:28 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-11 21:18:43 +00:00
										 |  |  |         // Swap everything but the allocators, and the functions objects.
 | 
					
						
							| 
									
										
										
										
											2011-08-14 18:53:29 +00:00
										 |  |  |         void swap_contents(table& x) | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2011-08-11 21:18:43 +00:00
										 |  |  |             this->buckets::swap(x, false_type()); | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |             std::swap(this->mlf_, x.mlf_); | 
					
						
							|  |  |  |             std::swap(this->max_load_, x.max_load_); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-08-30 16:42:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |         // Accessors
 | 
					
						
							| 
									
										
										
										
											2009-08-30 16:42:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |         key_type const& get_key(value_type const& x) const | 
					
						
							| 
									
										
										
										
											2009-09-20 21:55:15 +00:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |             return extractor::extract(x); | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-09-20 21:55:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |         // Find Node
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         template <typename Key, typename Hash, typename Pred> | 
					
						
							|  |  |  |         node_pointer generic_find_node( | 
					
						
							|  |  |  |                 Key const& k, | 
					
						
							|  |  |  |                 Hash const& hash_function, | 
					
						
							|  |  |  |                 Pred const& eq) const | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |             if (!this->size_) return node_pointer(); | 
					
						
							|  |  |  |             return static_cast<table_impl const*>(this)-> | 
					
						
							|  |  |  |                 find_node_impl(hash_function(k), k, eq); | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-09-20 21:55:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |         node_pointer find_node( | 
					
						
							|  |  |  |                 std::size_t hash, | 
					
						
							|  |  |  |                 key_type const& k) const | 
					
						
							| 
									
										
										
										
											2009-09-20 21:55:15 +00:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |             if (!this->size_) return node_pointer(); | 
					
						
							|  |  |  |             return static_cast<table_impl const*>(this)-> | 
					
						
							|  |  |  |                 find_node_impl(hash, k, this->key_eq()); | 
					
						
							| 
									
										
										
										
											2009-08-30 16:42:28 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |         node_pointer find_node(key_type const& k) const | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (!this->size_) return node_pointer(); | 
					
						
							|  |  |  |             return static_cast<table_impl const*>(this)-> | 
					
						
							|  |  |  |                 find_node_impl(this->hash_function()(k), k, this->key_eq()); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-08-30 16:42:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |         node_pointer find_matching_node(node_pointer n) const | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |             // TODO: Does this apply to C++11?
 | 
					
						
							|  |  |  |             //
 | 
					
						
							|  |  |  |             // For some stupid reason, I decided to support equality comparison
 | 
					
						
							|  |  |  |             // when different hash functions are used. So I can't use the hash
 | 
					
						
							|  |  |  |             // value from the node here.
 | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |             return find_node(get_key(n->value())); | 
					
						
							| 
									
										
										
										
											2009-08-30 16:42:28 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |         // Reserve and rehash
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |         void reserve_for_insert(std::size_t); | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  |         void rehash(std::size_t); | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-30 16:42:28 +00:00
										 |  |  |     ////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  |     // Reserve & Rehash
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // basic exception safety
 | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |     template <typename Types> | 
					
						
							|  |  |  |     inline void table<Types>::reserve_for_insert(std::size_t size) | 
					
						
							| 
									
										
										
										
											2009-08-30 16:42:28 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-08-14 18:53:29 +00:00
										 |  |  |         if (!this->buckets_) { | 
					
						
							|  |  |  |             this->bucket_count_ = (std::max)(this->bucket_count_, | 
					
						
							|  |  |  |                 this->min_buckets_for_size(size)); | 
					
						
							|  |  |  |             this->create_buckets(); | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |             this->max_load_ = this->calculate_max_load(); | 
					
						
							| 
									
										
										
										
											2011-08-14 18:53:29 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         else if(size >= max_load_) { | 
					
						
							|  |  |  |             std::size_t num_buckets | 
					
						
							|  |  |  |                 = this->min_buckets_for_size((std::max)(size, | 
					
						
							|  |  |  |                     this->size_ + (this->size_ >> 1))); | 
					
						
							|  |  |  |             if (num_buckets != this->bucket_count_) { | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |                 static_cast<table_impl*>(this)->rehash_impl(num_buckets); | 
					
						
							|  |  |  |                 this->max_load_ = this->calculate_max_load(); | 
					
						
							| 
									
										
										
										
											2009-09-20 21:55:15 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2009-08-30 16:42:28 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // if hash function throws, basic exception safety
 | 
					
						
							|  |  |  |     // strong otherwise.
 | 
					
						
							| 
									
										
										
										
											2009-10-04 10:37:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |     template <typename Types> | 
					
						
							|  |  |  |     void table<Types>::rehash(std::size_t min_buckets) | 
					
						
							| 
									
										
										
										
											2009-08-30 16:42:28 +00:00
										 |  |  |     { | 
					
						
							|  |  |  |         using namespace std; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-04 10:37:36 +00:00
										 |  |  |         if(!this->size_) { | 
					
						
							|  |  |  |             if(this->buckets_) this->delete_buckets(); | 
					
						
							| 
									
										
										
										
											2009-09-21 21:17:19 +00:00
										 |  |  |             this->bucket_count_ = next_prime(min_buckets); | 
					
						
							| 
									
										
										
										
											2009-09-20 21:55:15 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-09-21 21:18:01 +00:00
										 |  |  |         else { | 
					
						
							| 
									
										
										
										
											2009-10-04 10:37:36 +00:00
										 |  |  |             min_buckets = next_prime((std::max)(min_buckets, | 
					
						
							| 
									
										
										
										
											2011-10-07 08:19:53 +00:00
										 |  |  |                 boost::unordered::detail::double_to_size(floor( | 
					
						
							| 
									
										
										
										
											2011-08-27 11:53:48 +00:00
										 |  |  |                     static_cast<double>(this->size_) / | 
					
						
							|  |  |  |                     static_cast<double>(mlf_))) + 1)); | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-14 18:53:03 +00:00
										 |  |  |             if(min_buckets != this->bucket_count_) { | 
					
						
							| 
									
										
										
										
											2011-10-05 19:45:14 +00:00
										 |  |  |                 static_cast<table_impl*>(this)->rehash_impl(min_buckets); | 
					
						
							|  |  |  |                 this->max_load_ = this->calculate_max_load(); | 
					
						
							| 
									
										
										
										
											2011-08-14 18:53:03 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2009-09-20 21:55:15 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-08-30 16:42:28 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-04-16 18:47:33 +00:00
										 |  |  | }}} | 
					
						
							| 
									
										
										
										
											2009-08-30 16:42:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #endif
 |