diff --git a/include/boost/unordered/detail/hash_table.hpp b/include/boost/unordered/detail/hash_table.hpp index 1bdcced8..c6ded509 100644 --- a/include/boost/unordered/detail/hash_table.hpp +++ b/include/boost/unordered/detail/hash_table.hpp @@ -224,53 +224,15 @@ namespace boost { functions_ptr func_; // The currently active functions. }; +#if defined(BOOST_MSVC) +# define BOOST_UNORDERED_DESTRUCT(x, type) (x)->~type(); +#else +# define BOOST_UNORDERED_DESTRUCT(x, type) boost::unordered_detail::destroy(x) template void destroy(T* x) { x->~T(); } - - // Some classes for the data structure - - template - struct bucket_impl - { - private: - bucket_impl& operator=(bucket_impl const&); - public: - typedef BOOST_DEDUCED_TYPENAME - boost::unordered_detail::rebind_wrap::type - bucket_allocator; - typedef BOOST_DEDUCED_TYPENAME - allocator_pointer::type bucket_ptr; - typedef bucket_ptr link_ptr; - - link_ptr next_; - - bucket_impl() : next_() - { - BOOST_UNORDERED_MSVC_RESET_PTR(next_); - } - - bucket_impl(bucket_impl const& x) : next_(x.next_) - { - // Only copy construct when allocating. - BOOST_ASSERT(!x.next_); - } - - bool empty() const - { - return !this->next_; - } - }; - - template - struct value_base { - typename boost::aligned_storage< - sizeof(T), - boost::alignment_of::value>::type data_; - - void* address() { return this; } - }; +#endif } } diff --git a/include/boost/unordered/detail/hash_table_impl.hpp b/include/boost/unordered/detail/hash_table_impl.hpp index c7ab515d..a8e86ad4 100644 --- a/include/boost/unordered/detail/hash_table_impl.hpp +++ b/include/boost/unordered/detail/hash_table_impl.hpp @@ -6,7 +6,6 @@ #if BOOST_UNORDERED_EQUIVALENT_KEYS #define BOOST_UNORDERED_TABLE hash_table_equivalent_keys -#define BOOST_UNORDERED_TABLE_NODE node_equivalent_keys #define BOOST_UNORDERED_TABLE_DATA hash_table_data_equivalent_keys #define BOOST_UNORDERED_ITERATOR hash_iterator_equivalent_keys #define BOOST_UNORDERED_CONST_ITERATOR hash_const_iterator_equivalent_keys @@ -14,7 +13,6 @@ #define BOOST_UNORDERED_CONST_LOCAL_ITERATOR hash_const_local_iterator_equivalent_keys #else #define BOOST_UNORDERED_TABLE hash_table_unique_keys -#define BOOST_UNORDERED_TABLE_NODE node_unique_keys #define BOOST_UNORDERED_TABLE_DATA hash_table_data_unique_keys #define BOOST_UNORDERED_ITERATOR hash_iterator_unique_keys #define BOOST_UNORDERED_CONST_ITERATOR hash_const_iterator_unique_keys @@ -25,32 +23,6 @@ namespace boost { namespace unordered_detail { - template - struct BOOST_UNORDERED_TABLE_NODE : - value_base::type>, - bucket_impl - { - typedef BOOST_DEDUCED_TYPENAME bucket_impl::link_ptr link_ptr; - typedef BOOST_DEDUCED_TYPENAME allocator_value_type::type value_type; - - typedef BOOST_DEDUCED_TYPENAME - boost::unordered_detail::rebind_wrap::type - node_allocator; - -#if BOOST_UNORDERED_EQUIVALENT_KEYS - BOOST_UNORDERED_TABLE_NODE() : group_prev_() - { - BOOST_UNORDERED_MSVC_RESET_PTR(group_prev_); - } - - link_ptr group_prev_; -#endif - - value_type& value() { - return *static_cast(this->address()); - } - }; - // // Hash Table Data // @@ -62,24 +34,86 @@ namespace boost { public: typedef BOOST_UNORDERED_TABLE_DATA data; + struct node; + struct bucket; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; typedef Alloc value_allocator; - typedef bucket_impl bucket; - typedef BOOST_DEDUCED_TYPENAME bucket::bucket_allocator bucket_allocator; - typedef BOOST_DEDUCED_TYPENAME bucket::bucket_ptr bucket_ptr; - typedef BOOST_DEDUCED_TYPENAME bucket::link_ptr link_ptr; - - typedef BOOST_UNORDERED_TABLE_NODE node; - typedef BOOST_DEDUCED_TYPENAME node::node_allocator node_allocator; + typedef BOOST_DEDUCED_TYPENAME + boost::unordered_detail::rebind_wrap::type + node_allocator; + typedef BOOST_DEDUCED_TYPENAME + boost::unordered_detail::rebind_wrap::type + bucket_allocator; typedef BOOST_DEDUCED_TYPENAME allocator_value_type::type value_type; typedef BOOST_DEDUCED_TYPENAME allocator_pointer::type node_ptr; + typedef BOOST_DEDUCED_TYPENAME allocator_pointer::type bucket_ptr; typedef BOOST_DEDUCED_TYPENAME allocator_reference::type reference; typedef BOOST_DEDUCED_TYPENAME allocator_reference::type bucket_reference; + typedef bucket_ptr link_ptr; + + // Hash Bucket + // + // all no throw + + struct bucket + { + private: + bucket& operator=(bucket const&); + public: + link_ptr next_; + + bucket() : next_() + { + BOOST_UNORDERED_MSVC_RESET_PTR(next_); + } + + bucket(bucket const& x) : next_(x.next_) + { + // Only copy construct when allocating. + BOOST_ASSERT(!x.next_); + } + + bool empty() const + { + return !this->next_; + } + }; + + // Value Base + + struct value_base { + typename boost::aligned_storage< + sizeof(value_type), + boost::alignment_of::value>::type data_; + + void* address() { return this; } + }; + + // Hash Node + // + // all no throw + + struct node : value_base, bucket { +#if BOOST_UNORDERED_EQUIVALENT_KEYS + public: + node() : group_prev_() + { + BOOST_UNORDERED_MSVC_RESET_PTR(group_prev_); + } + + link_ptr group_prev_; +#endif + + value_type& value() { + return *static_cast(this->address()); + } + }; + // allocators // // Stores all the allocators that we're going to need. @@ -96,7 +130,7 @@ namespace boost { void destroy(link_ptr ptr) { node* raw_ptr = static_cast(&*ptr); - boost::unordered_detail::destroy(&raw_ptr->value()); + BOOST_UNORDERED_DESTRUCT(&raw_ptr->value(), value_type); node_ptr n(node_alloc_.address(*raw_ptr)); node_alloc_.destroy(n); node_alloc_.deallocate(n, 1); @@ -138,7 +172,7 @@ namespace boost { { if (node_) { if (value_constructed_) { - boost::unordered_detail::destroy(&node_->value()); + BOOST_UNORDERED_DESTRUCT(&node_->value(), value_type); } if (node_constructed_) @@ -2291,7 +2325,6 @@ namespace boost { } #undef BOOST_UNORDERED_TABLE -#undef BOOST_UNORDERED_TABLE_NODE #undef BOOST_UNORDERED_TABLE_DATA #undef BOOST_UNORDERED_ITERATOR #undef BOOST_UNORDERED_CONST_ITERATOR