diff --git a/include/boost/unordered/detail/implementation.hpp b/include/boost/unordered/detail/implementation.hpp index 89ac1fbf..afbfb2a2 100644 --- a/include/boost/unordered/detail/implementation.hpp +++ b/include/boost/unordered/detail/implementation.hpp @@ -2708,6 +2708,8 @@ struct table : boost::unordered::detail::functions(size_) / static_cast(bucket_count_); - } - std::size_t bucket_size(std::size_t index) const { node_pointer n = begin(index); @@ -2782,17 +2778,6 @@ struct table : boost::unordered::detail::functions(mlf_) * - static_cast(max_bucket_count()))) - - 1; - } - void recalculate_max_load() { using namespace std; @@ -2868,26 +2853,6 @@ struct table : boost::unordered::detail::functions(this)->copy_buckets(x); - } - } - - void move_init(table& x) - { - if (node_alloc() == x.node_alloc()) { - move_buckets_from(x); - } else if (x.size_) { - // TODO: Could pick new bucket size? - static_cast(this)->move_buckets(x); - } - } - //////////////////////////////////////////////////////////////////////// // Clear buckets and Create buckets // @@ -3078,17 +3043,6 @@ struct table : boost::unordered::detail::functions - node_pointer generic_find_node( - Key const& k, Hash const& hf, Pred const& eq) const - { - return this->find_node_impl(policy::apply_hash(hf, k), k, eq); - } - node_pointer find_node(std::size_t key_hash, const_key_type& k) const { return this->find_node_impl(key_hash, k, this->key_eq()); @@ -3393,13 +3340,6 @@ inline void table::rehash(std::size_t min_buckets) } } -template -inline void table::reserve(std::size_t num_elements) -{ - rehash(static_cast( - std::ceil(static_cast(num_elements) / mlf_))); -} - template inline void table::rehash_impl(std::size_t num_buckets) { @@ -3789,50 +3729,34 @@ struct table_unique : boost::unordered::detail::table : table(x, node_allocator_traits::select_on_container_copy_construction( x.node_alloc())) { - this->init(x); + if (x.size_) { + this->copy_buckets(x); + } } table_unique(table_unique const& x, node_allocator const& a) : table(x, a) { - this->init(x); + if (x.size_) { + this->copy_buckets(x); + } } table_unique(table_unique& x, boost::unordered::detail::move_tag m) : table(x, m) { + // The move is done in the base class. } table_unique(table_unique& x, node_allocator const& a, boost::unordered::detail::move_tag m) : table(x, a, m) { - this->move_init(x); - } - - // Accessors - - std::size_t count(const_key_type& k) const - { - return this->find_node(k) ? 1 : 0; - } - - value_type& at(const_key_type& k) const - { - if (this->size_) { - node_pointer n = this->find_node(k); - if (n) - return n->value(); + if (this->node_alloc() == x.node_alloc()) { + this->move_buckets_from(x); + } else if (x.size_) { + // TODO: Could pick new bucket size? + this->move_buckets(x); } - - boost::throw_exception( - std::out_of_range("Unable to find key in unordered_map.")); - } - - std::pair equal_range(const_key_type& k) const - { - node_pointer n = this->find_node(k); - return std::make_pair( - iterator(n), iterator(n ? node_algo::next_node(n) : n)); } // equals @@ -3890,81 +3814,6 @@ struct table_unique : boost::unordered::detail::table return this->add_node(b.release(), key_hash); } -#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) -#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - emplace_return emplace(boost::unordered::detail::emplace_args1< - boost::unordered::detail::please_ignore_this_overload> const&) - { - BOOST_ASSERT(false); - return emplace_return(iterator(), false); - } - - iterator emplace_hint( - c_iterator, - boost::unordered::detail::emplace_args1< - boost::unordered::detail::please_ignore_this_overload> const&) - { - BOOST_ASSERT(false); - return iterator(); - } -#else - emplace_return emplace( - boost::unordered::detail::please_ignore_this_overload const&) - { - BOOST_ASSERT(false); - return emplace_return(iterator(), false); - } - - iterator emplace_hint(c_iterator, - boost::unordered::detail::please_ignore_this_overload const&) - { - BOOST_ASSERT(false); - return iterator(); - } -#endif -#endif - - template - emplace_return emplace(BOOST_UNORDERED_EMPLACE_ARGS) - { -#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - return emplace_impl(extractor::extract(BOOST_UNORDERED_EMPLACE_FORWARD), - BOOST_UNORDERED_EMPLACE_FORWARD); -#else - return emplace_impl(extractor::extract(args.a0, args.a1), - BOOST_UNORDERED_EMPLACE_FORWARD); -#endif - } - - template - iterator emplace_hint(c_iterator hint, BOOST_UNORDERED_EMPLACE_ARGS) - { -#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - return emplace_hint_impl(hint, - extractor::extract(BOOST_UNORDERED_EMPLACE_FORWARD), - BOOST_UNORDERED_EMPLACE_FORWARD); -#else - return emplace_hint_impl(hint, extractor::extract(args.a0, args.a1), - BOOST_UNORDERED_EMPLACE_FORWARD); -#endif - } - -#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - template - emplace_return emplace( - boost::unordered::detail::emplace_args1 const& args) - { - return emplace_impl(extractor::extract(args.a0), args); - } - - template - iterator emplace_hint(c_iterator hint, - boost::unordered::detail::emplace_args1 const& args) - { - return emplace_hint_impl(hint, extractor::extract(args.a0), args); - } -#endif - template iterator emplace_hint_impl( c_iterator hint, const_key_type& k, BOOST_UNORDERED_EMPLACE_ARGS) @@ -4188,12 +4037,6 @@ struct table_unique : boost::unordered::detail::table // if hash function throws, or inserting > 1 element, basic exception // safety strong otherwise - template void insert_range(InputIt i, InputIt j) - { - if (i != j) - return insert_range_impl(extractor::extract(*i), i, j); - } - template void insert_range_impl(const_key_type& k, InputIt i, InputIt j) { @@ -4298,22 +4141,6 @@ struct table_unique : boost::unordered::detail::table return 1; } - iterator erase(c_iterator r) - { - BOOST_ASSERT(r.node_); - node_pointer next = node_algo::next_node(r.node_); - erase_nodes(r.node_, next); - return iterator(next); - } - - iterator erase_range(c_iterator r1, c_iterator r2) - { - if (r1 == r2) - return iterator(r2.node_); - erase_nodes(r1.node_, r2.node_); - return iterator(r2.node_); - } - void erase_nodes(node_pointer i, node_pointer j) { std::size_t bucket_index = this->hash_to_bucket(i->hash_); @@ -4610,39 +4437,34 @@ struct table_equiv : boost::unordered::detail::table : table(x, node_allocator_traits::select_on_container_copy_construction( x.node_alloc())) { - this->init(x); + if (x.size_) { + copy_buckets(x); + } } table_equiv(table_equiv const& x, node_allocator const& a) : table(x, a) { - this->init(x); + if (x.size_) { + copy_buckets(x); + } } table_equiv(table_equiv& x, boost::unordered::detail::move_tag m) : table(x, m) { + // The move is done in the base class. } table_equiv(table_equiv& x, node_allocator const& a, boost::unordered::detail::move_tag m) : table(x, a, m) { - this->move_init(x); - } - - // Accessors - - std::size_t count(const_key_type& k) const - { - node_pointer n = this->find_node(k); - return n ? node_algo::count(n, this) : 0; - } - - std::pair equal_range(const_key_type& k) const - { - node_pointer n = this->find_node(k); - return std::make_pair( - iterator(n), iterator(n ? node_algo::next_group(n, this) : n)); + if (this->node_alloc() == x.node_alloc()) { + this->move_buckets_from(x); + } else if (x.size_) { + // TODO: Could pick new bucket size? + this->move_buckets(x); + } } // Equality @@ -4786,56 +4608,6 @@ struct table_equiv : boost::unordered::detail::table return n; } -#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) -#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - iterator emplace(boost::unordered::detail::emplace_args1< - boost::unordered::detail::please_ignore_this_overload> const&) - { - BOOST_ASSERT(false); - return iterator(); - } - - iterator emplace_hint( - c_iterator, - boost::unordered::detail::emplace_args1< - boost::unordered::detail::please_ignore_this_overload> const&) - { - BOOST_ASSERT(false); - return iterator(); - } -#else - iterator emplace( - boost::unordered::detail::please_ignore_this_overload const&) - { - BOOST_ASSERT(false); - return iterator(); - } - - iterator emplace_hint(c_iterator, - boost::unordered::detail::please_ignore_this_overload const&) - { - BOOST_ASSERT(false); - return iterator(); - } -#endif -#endif - - template - iterator emplace(BOOST_UNORDERED_EMPLACE_ARGS) - { - return iterator(emplace_impl( - boost::unordered::detail::func::construct_node_from_args( - this->node_alloc(), BOOST_UNORDERED_EMPLACE_FORWARD))); - } - - template - iterator emplace_hint(c_iterator hint, BOOST_UNORDERED_EMPLACE_ARGS) - { - return iterator(emplace_hint_impl( - hint, boost::unordered::detail::func::construct_node_from_args( - this->node_alloc(), BOOST_UNORDERED_EMPLACE_FORWARD))); - } - iterator emplace_impl(node_pointer n) { node_tmp a(n, this->node_alloc()); @@ -5005,22 +4777,6 @@ struct table_equiv : boost::unordered::detail::table return deleted_count; } - iterator erase(c_iterator r) - { - BOOST_ASSERT(r.node_); - node_pointer next = node_algo::next_node(r.node_); - erase_nodes(r.node_, next); - return iterator(next); - } - - iterator erase_range(c_iterator r1, c_iterator r2) - { - if (r1 == r2) - return iterator(r2.node_); - erase_nodes(r1.node_, r2.node_); - return iterator(r2.node_); - } - link_pointer erase_nodes(node_pointer i, node_pointer j) { std::size_t bucket_index = this->hash_to_bucket(i->hash_); diff --git a/include/boost/unordered/unordered_map.hpp b/include/boost/unordered/unordered_map.hpp index 32d8f0ae..a55e2b5c 100644 --- a/include/boost/unordered/unordered_map.hpp +++ b/include/boost/unordered/unordered_map.hpp @@ -55,6 +55,8 @@ template class unordered_map typedef boost::unordered::detail::map types; typedef typename types::value_allocator_traits value_allocator_traits; typedef typename types::table table; + typedef typename table::node_pointer node_pointer; + typedef typename table::link_pointer link_pointer; public: typedef typename value_allocator_traits::pointer pointer; @@ -220,7 +222,9 @@ template class unordered_map template std::pair emplace(BOOST_FWD_REF(Args)... args) { - return table_.emplace(boost::forward(args)...); + return table_.emplace_impl( + table::extractor::extract(boost::forward(args)...), + boost::forward(args)...); } #else @@ -244,25 +248,33 @@ template class unordered_map template std::pair emplace(BOOST_FWD_REF(A0) a0) { - return table_.emplace(boost::unordered::detail::create_emplace_args( - boost::forward(a0))); + return table_.emplace_impl( + table::extractor::extract(boost::forward(a0)), + boost::unordered::detail::create_emplace_args( + boost::forward(a0))); } template std::pair emplace( BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1) { - return table_.emplace(boost::unordered::detail::create_emplace_args( - boost::forward(a0), boost::forward(a1))); + return table_.emplace_impl( + table::extractor::extract( + boost::forward(a0), boost::forward(a1)), + boost::unordered::detail::create_emplace_args( + boost::forward(a0), boost::forward(a1))); } template std::pair emplace( BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2) { - return table_.emplace(boost::unordered::detail::create_emplace_args( - boost::forward(a0), boost::forward(a1), - boost::forward(a2))); + return table_.emplace_impl( + table::extractor::extract( + boost::forward(a0), boost::forward(a1)), + boost::unordered::detail::create_emplace_args( + boost::forward(a0), boost::forward(a1), + boost::forward(a2))); } #endif @@ -272,7 +284,9 @@ template class unordered_map template iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args) { - return table_.emplace_hint(hint, boost::forward(args)...); + return table_.emplace_hint_impl(hint, + table::extractor::extract(boost::forward(args)...), + boost::forward(args)...); } #else @@ -292,28 +306,33 @@ template class unordered_map template iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(A0) a0) { - return table_.emplace_hint( - hint, boost::unordered::detail::create_emplace_args( - boost::forward(a0))); + return table_.emplace_hint_impl(hint, + table::extractor::extract(boost::forward(a0)), + boost::unordered::detail::create_emplace_args( + boost::forward(a0))); } template iterator emplace_hint( const_iterator hint, BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1) { - return table_.emplace_hint( - hint, boost::unordered::detail::create_emplace_args( - boost::forward(a0), boost::forward(a1))); + return table_.emplace_hint_impl( + hint, table::extractor::extract( + boost::forward(a0), boost::forward(a1)), + boost::unordered::detail::create_emplace_args( + boost::forward(a0), boost::forward(a1))); } template iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2) { - return table_.emplace_hint( - hint, boost::unordered::detail::create_emplace_args( - boost::forward(a0), boost::forward(a1), - boost::forward(a2))); + return table_.emplace_hint_impl( + hint, table::extractor::extract( + boost::forward(a0), boost::forward(a1)), + boost::unordered::detail::create_emplace_args( + boost::forward(a0), boost::forward(a1), + boost::forward(a2))); } #endif @@ -325,21 +344,32 @@ template class unordered_map std::pair emplace( \ BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a)) \ { \ - return table_.emplace(boost::unordered::detail::create_emplace_args( \ - BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))); \ + return table_.emplace_impl( \ + table::extractor::extract( \ + boost::forward(a0), boost::forward(a1)), \ + boost::unordered::detail::create_emplace_args( \ + BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))); \ } \ \ template \ iterator emplace_hint(const_iterator hint, \ BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a)) \ { \ - return table_.emplace_hint( \ - hint, boost::unordered::detail::create_emplace_args( \ - BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))); \ + return table_.emplace_hint_impl( \ + hint, table::extractor::extract( \ + boost::forward(a0), boost::forward(a1)), \ + boost::unordered::detail::create_emplace_args( \ + BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))); \ } - BOOST_PP_REPEAT_FROM_TO( - 4, BOOST_PP_INC(BOOST_UNORDERED_EMPLACE_LIMIT), BOOST_UNORDERED_EMPLACE, _) + BOOST_UNORDERED_EMPLACE(1, 4, _) + BOOST_UNORDERED_EMPLACE(1, 5, _) + BOOST_UNORDERED_EMPLACE(1, 6, _) + BOOST_UNORDERED_EMPLACE(1, 7, _) + BOOST_UNORDERED_EMPLACE(1, 8, _) + BOOST_UNORDERED_EMPLACE(1, 9, _) + BOOST_PP_REPEAT_FROM_TO(10, BOOST_PP_INC(BOOST_UNORDERED_EMPLACE_LIMIT), + BOOST_UNORDERED_EMPLACE, _) #undef BOOST_UNORDERED_EMPLACE @@ -625,8 +655,8 @@ template class unordered_map n, BOOST_UNORDERED_CALL_FORWARD, a))); \ } - BOOST_PP_REPEAT_FROM_TO( - 4, BOOST_PP_INC(BOOST_UNORDERED_EMPLACE_LIMIT), BOOST_UNORDERED_TRY_EMPLACE, _) + BOOST_PP_REPEAT_FROM_TO(4, BOOST_PP_INC(BOOST_UNORDERED_EMPLACE_LIMIT), + BOOST_UNORDERED_TRY_EMPLACE, _) #undef BOOST_UNORDERED_TRY_EMPLACE @@ -808,6 +838,8 @@ template class unordered_multimap typedef boost::unordered::detail::multimap types; typedef typename types::value_allocator_traits value_allocator_traits; typedef typename types::table table; + typedef typename table::node_pointer node_pointer; + typedef typename table::link_pointer link_pointer; public: typedef typename value_allocator_traits::pointer pointer; @@ -972,7 +1004,9 @@ template class unordered_multimap template iterator emplace(BOOST_FWD_REF(Args)... args) { - return table_.emplace(boost::forward(args)...); + return iterator(table_.emplace_impl( + boost::unordered::detail::func::construct_node_from_args( + table_.node_alloc(), boost::forward(args)...))); } #else @@ -994,24 +1028,33 @@ template class unordered_multimap template iterator emplace(BOOST_FWD_REF(A0) a0) { - return table_.emplace(boost::unordered::detail::create_emplace_args( - boost::forward(a0))); + return iterator(table_.emplace_impl( + boost::unordered::detail::func::construct_node_from_args( + table_.node_alloc(), + boost::unordered::detail::create_emplace_args( + boost::forward(a0))))); } template iterator emplace(BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1) { - return table_.emplace(boost::unordered::detail::create_emplace_args( - boost::forward(a0), boost::forward(a1))); + return iterator(table_.emplace_impl( + boost::unordered::detail::func::construct_node_from_args( + table_.node_alloc(), + boost::unordered::detail::create_emplace_args( + boost::forward(a0), boost::forward(a1))))); } template iterator emplace( BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2) { - return table_.emplace(boost::unordered::detail::create_emplace_args( - boost::forward(a0), boost::forward(a1), - boost::forward(a2))); + return iterator(table_.emplace_impl( + boost::unordered::detail::func::construct_node_from_args( + table_.node_alloc(), + boost::unordered::detail::create_emplace_args( + boost::forward(a0), boost::forward(a1), + boost::forward(a2))))); } #endif @@ -1021,7 +1064,9 @@ template class unordered_multimap template iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args) { - return table_.emplace_hint(hint, boost::forward(args)...); + return iterator(table_.emplace_hint_impl( + hint, boost::unordered::detail::func::construct_node_from_args( + table_.node_alloc(), boost::forward(args)...))); } #else @@ -1041,27 +1086,34 @@ template class unordered_multimap template iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(A0) a0) { - return table_.emplace_hint( - hint, boost::unordered::detail::create_emplace_args( - boost::forward(a0))); + return iterator(table_.emplace_hint_impl( + hint, boost::unordered::detail::func::construct_node_from_args( + table_.node_alloc(), + boost::unordered::detail::create_emplace_args( + boost::forward(a0))))); } + template iterator emplace_hint( const_iterator hint, BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1) { - return table_.emplace_hint( - hint, boost::unordered::detail::create_emplace_args( - boost::forward(a0), boost::forward(a1))); + return iterator(table_.emplace_hint_impl( + hint, boost::unordered::detail::func::construct_node_from_args( + table_.node_alloc(), + boost::unordered::detail::create_emplace_args( + boost::forward(a0), boost::forward(a1))))); } template iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2) { - return table_.emplace_hint( - hint, boost::unordered::detail::create_emplace_args( - boost::forward(a0), boost::forward(a1), - boost::forward(a2))); + return iterator(table_.emplace_hint_impl( + hint, boost::unordered::detail::func::construct_node_from_args( + table_.node_alloc(), + boost::unordered::detail::create_emplace_args( + boost::forward(a0), boost::forward(a1), + boost::forward(a2))))); } #endif @@ -1072,21 +1124,33 @@ template class unordered_multimap template \ iterator emplace(BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a)) \ { \ - return table_.emplace(boost::unordered::detail::create_emplace_args( \ - BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))); \ + return iterator(table_.emplace_impl( \ + boost::unordered::detail::func::construct_node_from_args( \ + table_.node_alloc(), \ + boost::unordered::detail::create_emplace_args( \ + BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))))); \ } \ \ template \ iterator emplace_hint(const_iterator hint, \ BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a)) \ { \ - return table_.emplace_hint( \ - hint, boost::unordered::detail::create_emplace_args( \ - BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))); \ + return iterator(table_.emplace_hint_impl( \ + hint, \ + boost::unordered::detail::func::construct_node_from_args( \ + table_.node_alloc(), \ + boost::unordered::detail::create_emplace_args( \ + BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))))); \ } - BOOST_PP_REPEAT_FROM_TO( - 4, BOOST_PP_INC(BOOST_UNORDERED_EMPLACE_LIMIT), BOOST_UNORDERED_EMPLACE, _) + BOOST_UNORDERED_EMPLACE(1, 4, _) + BOOST_UNORDERED_EMPLACE(1, 5, _) + BOOST_UNORDERED_EMPLACE(1, 6, _) + BOOST_UNORDERED_EMPLACE(1, 7, _) + BOOST_UNORDERED_EMPLACE(1, 8, _) + BOOST_UNORDERED_EMPLACE(1, 9, _) + BOOST_PP_REPEAT_FROM_TO(10, BOOST_PP_INC(BOOST_UNORDERED_EMPLACE_LIMIT), + BOOST_UNORDERED_EMPLACE, _) #undef BOOST_UNORDERED_EMPLACE @@ -1307,7 +1371,7 @@ unordered_map::unordered_map(InputIt f, InputIt l, size_type n, const hasher& hf, const key_equal& eql, const allocator_type& a) : table_(boost::unordered::detail::initial_size(f, l, n), hf, eql, a) { - table_.insert_range(f, l); + this->insert(f, l); } template @@ -1347,7 +1411,7 @@ unordered_map::unordered_map( boost::unordered::detail::initial_size(list.begin(), list.end(), n), hf, eql, a) { - table_.insert_range(list.begin(), list.end()); + this->insert(list.begin(), list.end()); } #endif @@ -1373,7 +1437,7 @@ unordered_map::unordered_map( : table_(boost::unordered::detail::initial_size(f, l, n), hasher(), key_equal(), a) { - table_.insert_range(f, l); + this->insert(f, l); } template @@ -1383,7 +1447,7 @@ unordered_map::unordered_map(InputIt f, InputIt l, size_type n, : table_( boost::unordered::detail::initial_size(f, l, n), hf, key_equal(), a) { - table_.insert_range(f, l); + this->insert(f, l); } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) @@ -1396,7 +1460,7 @@ unordered_map::unordered_map( boost::unordered::detail::initial_size(list.begin(), list.end(), n), hasher(), key_equal(), a) { - table_.insert_range(list.begin(), list.end()); + this->insert(list.begin(), list.end()); } template @@ -1407,7 +1471,7 @@ unordered_map::unordered_map( boost::unordered::detail::initial_size(list.begin(), list.end(), n), hf, key_equal(), a) { - table_.insert_range(list.begin(), list.end()); + this->insert(list.begin(), list.end()); } #endif @@ -1423,8 +1487,8 @@ template unordered_map& unordered_map::operator=( std::initializer_list list) { - table_.clear(); - table_.insert_range(list.begin(), list.end()); + this->clear(); + this->insert(list.begin(), list.end()); return *this; } @@ -1435,7 +1499,13 @@ unordered_map& unordered_map::operator=( template std::size_t unordered_map::max_size() const BOOST_NOEXCEPT { - return table_.max_size(); + using namespace std; + + // size <= mlf_ * count + return boost::unordered::detail::double_to_size( + ceil(static_cast(table_.mlf_) * + static_cast(table_.max_bucket_count()))) - + 1; } // modifiers @@ -1444,7 +1514,10 @@ template template void unordered_map::insert(InputIt first, InputIt last) { - table_.insert_range(first, last); + if (first != last) { + table_.insert_range_impl( + table::extractor::extract(*first), first, last); + } } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) @@ -1452,7 +1525,7 @@ template void unordered_map::insert( std::initializer_list list) { - table_.insert_range(list.begin(), list.end()); + this->insert(list.begin(), list.end()); } #endif @@ -1460,14 +1533,22 @@ template typename unordered_map::iterator unordered_map::erase(iterator position) { - return table_.erase(position); + node_pointer node = table::get_node(position); + BOOST_ASSERT(node); + node_pointer next = table::node_algo::next_node(node); + table_.erase_nodes(node, next); + return iterator(next); } template typename unordered_map::iterator unordered_map::erase(const_iterator position) { - return table_.erase(position); + node_pointer node = table::get_node(position); + BOOST_ASSERT(node); + node_pointer next = table::node_algo::next_node(node); + table_.erase_nodes(node, next); + return iterator(next); } template @@ -1481,7 +1562,11 @@ template typename unordered_map::iterator unordered_map::erase(const_iterator first, const_iterator last) { - return table_.erase_range(first, last); + node_pointer last_node = table::get_node(last); + if (first == last) + return iterator(last_node); + table_.erase_nodes(table::get_node(first), last_node); + return iterator(last_node); } template @@ -1497,7 +1582,10 @@ void unordered_map::swap(unordered_map& other) template void unordered_map::clear() BOOST_NOEXCEPT { - table_.clear(); + if (table_.size_) { + table_.clear_buckets(); + table_.delete_nodes(table_.get_previous_start(), link_pointer()); + } } template @@ -1576,7 +1664,8 @@ typename unordered_map::iterator unordered_map::find(CompatibleKey const& k, CompatibleHash const& hash, CompatiblePredicate const& eq) { - return iterator(table_.generic_find_node(k, hash, eq)); + return iterator( + table_.find_node_impl(table::policy::apply_hash(hash, k), k, eq)); } template @@ -1585,14 +1674,15 @@ typename unordered_map::const_iterator unordered_map::find(CompatibleKey const& k, CompatibleHash const& hash, CompatiblePredicate const& eq) const { - return const_iterator(table_.generic_find_node(k, hash, eq)); + return const_iterator( + table_.find_node_impl(table::policy::apply_hash(hash, k), k, eq)); } template typename unordered_map::size_type unordered_map::count(const key_type& k) const { - return table_.count(k); + return table_.find_node(k) ? 1 : 0; } template @@ -1600,7 +1690,9 @@ std::pair::iterator, typename unordered_map::iterator> unordered_map::equal_range(const key_type& k) { - return table_.equal_range(k); + node_pointer n = table_.find_node(k); + return std::make_pair( + iterator(n), iterator(n ? table::node_algo::next_node(n) : n)); } template @@ -1608,7 +1700,9 @@ std::pair::const_iterator, typename unordered_map::const_iterator> unordered_map::equal_range(const key_type& k) const { - return table_.equal_range(k); + node_pointer n = table_.find_node(k); + return std::make_pair(const_iterator(n), + const_iterator(n ? table::node_algo::next_node(n) : n)); } template @@ -1629,14 +1723,28 @@ template typename unordered_map::mapped_type& unordered_map::at(const key_type& k) { - return table_.at(k).second; + if (table_.size_) { + node_pointer n = table_.find_node(k); + if (n) + return n->value().second; + } + + boost::throw_exception( + std::out_of_range("Unable to find key in unordered_map.")); } template typename unordered_map::mapped_type const& unordered_map::at(const key_type& k) const { - return table_.at(k).second; + if (table_.size_) { + node_pointer n = table_.find_node(k); + if (n) + return n->value().second; + } + + boost::throw_exception( + std::out_of_range("Unable to find key in unordered_map.")); } template @@ -1651,7 +1759,9 @@ unordered_map::bucket_size(size_type n) const template float unordered_map::load_factor() const BOOST_NOEXCEPT { - return table_.load_factor(); + BOOST_ASSERT(table_.bucket_count_ != 0); + return static_cast(table_.size_) / + static_cast(table_.bucket_count_); } template @@ -1669,7 +1779,8 @@ void unordered_map::rehash(size_type n) template void unordered_map::reserve(size_type n) { - table_.reserve(n); + table_.rehash(static_cast( + std::ceil(static_cast(n) / table_.mlf_))); } template @@ -1735,7 +1846,7 @@ unordered_multimap::unordered_multimap(InputIt f, InputIt l, const allocator_type& a) : table_(boost::unordered::detail::initial_size(f, l, n), hf, eql, a) { - table_.insert_range(f, l); + this->insert(f, l); } template @@ -1776,7 +1887,7 @@ unordered_multimap::unordered_multimap( boost::unordered::detail::initial_size(list.begin(), list.end(), n), hf, eql, a) { - table_.insert_range(list.begin(), list.end()); + this->insert(list.begin(), list.end()); } #endif @@ -1802,7 +1913,7 @@ unordered_multimap::unordered_multimap( : table_(boost::unordered::detail::initial_size(f, l, n), hasher(), key_equal(), a) { - table_.insert_range(f, l); + this->insert(f, l); } template @@ -1812,7 +1923,7 @@ unordered_multimap::unordered_multimap(InputIt f, InputIt l, : table_( boost::unordered::detail::initial_size(f, l, n), hf, key_equal(), a) { - table_.insert_range(f, l); + this->insert(f, l); } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) @@ -1825,7 +1936,7 @@ unordered_multimap::unordered_multimap( boost::unordered::detail::initial_size(list.begin(), list.end(), n), hasher(), key_equal(), a) { - table_.insert_range(list.begin(), list.end()); + this->insert(list.begin(), list.end()); } template @@ -1836,7 +1947,7 @@ unordered_multimap::unordered_multimap( boost::unordered::detail::initial_size(list.begin(), list.end(), n), hf, key_equal(), a) { - table_.insert_range(list.begin(), list.end()); + this->insert(list.begin(), list.end()); } #endif @@ -1852,8 +1963,8 @@ template unordered_multimap& unordered_multimap::operator=( std::initializer_list list) { - table_.clear(); - table_.insert_range(list.begin(), list.end()); + this->clear(); + this->insert(list.begin(), list.end()); return *this; } @@ -1864,7 +1975,13 @@ unordered_multimap& unordered_multimap::operator=( template std::size_t unordered_multimap::max_size() const BOOST_NOEXCEPT { - return table_.max_size(); + using namespace std; + + // size <= mlf_ * count + return boost::unordered::detail::double_to_size( + ceil(static_cast(table_.mlf_) * + static_cast(table_.max_bucket_count()))) - + 1; } // modifiers @@ -1881,7 +1998,7 @@ template void unordered_multimap::insert( std::initializer_list list) { - table_.insert_range(list.begin(), list.end()); + this->insert(list.begin(), list.end()); } #endif @@ -1889,14 +2006,22 @@ template typename unordered_multimap::iterator unordered_multimap::erase(iterator position) { - return table_.erase(position); + node_pointer node = table::get_node(position); + BOOST_ASSERT(node); + node_pointer next = table::node_algo::next_node(node); + table_.erase_nodes(node, next); + return iterator(next); } template typename unordered_multimap::iterator unordered_multimap::erase(const_iterator position) { - return table_.erase(position); + node_pointer node = table::get_node(position); + BOOST_ASSERT(node); + node_pointer next = table::node_algo::next_node(node); + table_.erase_nodes(node, next); + return iterator(next); } template @@ -1911,7 +2036,11 @@ typename unordered_multimap::iterator unordered_multimap::erase( const_iterator first, const_iterator last) { - return table_.erase_range(first, last); + node_pointer last_node = table::get_node(last); + if (first == last) + return iterator(last_node); + table_.erase_nodes(table::get_node(first), last_node); + return iterator(last_node); } template @@ -1927,7 +2056,10 @@ void unordered_multimap::swap(unordered_multimap& other) template void unordered_multimap::clear() BOOST_NOEXCEPT { - table_.clear(); + if (table_.size_) { + table_.clear_buckets(); + table_.delete_nodes(table_.get_previous_start(), link_pointer()); + } } // observers @@ -2014,7 +2146,8 @@ typename unordered_multimap::iterator unordered_multimap::find(CompatibleKey const& k, CompatibleHash const& hash, CompatiblePredicate const& eq) { - return iterator(table_.generic_find_node(k, hash, eq)); + return iterator( + table_.find_node_impl(table::policy::apply_hash(hash, k), k, eq)); } template @@ -2023,14 +2156,16 @@ typename unordered_multimap::const_iterator unordered_multimap::find(CompatibleKey const& k, CompatibleHash const& hash, CompatiblePredicate const& eq) const { - return const_iterator(table_.generic_find_node(k, hash, eq)); + return const_iterator( + table_.find_node_impl(table::policy::apply_hash(hash, k), k, eq)); } template typename unordered_multimap::size_type unordered_multimap::count(const key_type& k) const { - return table_.count(k); + node_pointer n = table_.find_node(k); + return n ? table::node_algo::count(n, &table_) : 0; } template @@ -2038,7 +2173,9 @@ std::pair::iterator, typename unordered_multimap::iterator> unordered_multimap::equal_range(const key_type& k) { - return table_.equal_range(k); + node_pointer n = table_.find_node(k); + return std::make_pair(iterator(n), + iterator(n ? table::node_algo::next_group(n, &table_) : n)); } template @@ -2046,7 +2183,9 @@ std::pair::const_iterator, typename unordered_multimap::const_iterator> unordered_multimap::equal_range(const key_type& k) const { - return table_.equal_range(k); + node_pointer n = table_.find_node(k); + return std::make_pair(const_iterator(n), + const_iterator(n ? table::node_algo::next_group(n, &table_) : n)); } template @@ -2061,7 +2200,9 @@ unordered_multimap::bucket_size(size_type n) const template float unordered_multimap::load_factor() const BOOST_NOEXCEPT { - return table_.load_factor(); + BOOST_ASSERT(table_.bucket_count_ != 0); + return static_cast(table_.size_) / + static_cast(table_.bucket_count_); } template @@ -2079,7 +2220,8 @@ void unordered_multimap::rehash(size_type n) template void unordered_multimap::reserve(size_type n) { - table_.reserve(n); + table_.rehash(static_cast( + std::ceil(static_cast(n) / table_.mlf_))); } template diff --git a/include/boost/unordered/unordered_set.hpp b/include/boost/unordered/unordered_set.hpp index ec7cfd1d..7bb86954 100644 --- a/include/boost/unordered/unordered_set.hpp +++ b/include/boost/unordered/unordered_set.hpp @@ -53,6 +53,8 @@ template class unordered_set typedef boost::unordered::detail::set types; typedef typename types::value_allocator_traits value_allocator_traits; typedef typename types::table table; + typedef typename table::node_pointer node_pointer; + typedef typename table::link_pointer link_pointer; public: typedef typename value_allocator_traits::pointer pointer; @@ -218,7 +220,9 @@ template class unordered_set template std::pair emplace(BOOST_FWD_REF(Args)... args) { - return table_.emplace(boost::forward(args)...); + return table_.emplace_impl( + table::extractor::extract(boost::forward(args)...), + boost::forward(args)...); } #else @@ -242,25 +246,33 @@ template class unordered_set template std::pair emplace(BOOST_FWD_REF(A0) a0) { - return table_.emplace(boost::unordered::detail::create_emplace_args( - boost::forward(a0))); + return table_.emplace_impl( + table::extractor::extract(boost::forward(a0)), + boost::unordered::detail::create_emplace_args( + boost::forward(a0))); } template std::pair emplace( BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1) { - return table_.emplace(boost::unordered::detail::create_emplace_args( - boost::forward(a0), boost::forward(a1))); + return table_.emplace_impl( + table::extractor::extract( + boost::forward(a0), boost::forward(a1)), + boost::unordered::detail::create_emplace_args( + boost::forward(a0), boost::forward(a1))); } template std::pair emplace( BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2) { - return table_.emplace(boost::unordered::detail::create_emplace_args( - boost::forward(a0), boost::forward(a1), - boost::forward(a2))); + return table_.emplace_impl( + table::extractor::extract( + boost::forward(a0), boost::forward(a1)), + boost::unordered::detail::create_emplace_args( + boost::forward(a0), boost::forward(a1), + boost::forward(a2))); } #endif @@ -270,7 +282,9 @@ template class unordered_set template iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args) { - return table_.emplace_hint(hint, boost::forward(args)...); + return table_.emplace_hint_impl(hint, + table::extractor::extract(boost::forward(args)...), + boost::forward(args)...); } #else @@ -290,28 +304,33 @@ template class unordered_set template iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(A0) a0) { - return table_.emplace_hint( - hint, boost::unordered::detail::create_emplace_args( - boost::forward(a0))); + return table_.emplace_hint_impl(hint, + table::extractor::extract(boost::forward(a0)), + boost::unordered::detail::create_emplace_args( + boost::forward(a0))); } template iterator emplace_hint( const_iterator hint, BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1) { - return table_.emplace_hint( - hint, boost::unordered::detail::create_emplace_args( - boost::forward(a0), boost::forward(a1))); + return table_.emplace_hint_impl( + hint, table::extractor::extract( + boost::forward(a0), boost::forward(a1)), + boost::unordered::detail::create_emplace_args( + boost::forward(a0), boost::forward(a1))); } template iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2) { - return table_.emplace_hint( - hint, boost::unordered::detail::create_emplace_args( - boost::forward(a0), boost::forward(a1), - boost::forward(a2))); + return table_.emplace_hint_impl( + hint, table::extractor::extract( + boost::forward(a0), boost::forward(a1)), + boost::unordered::detail::create_emplace_args( + boost::forward(a0), boost::forward(a1), + boost::forward(a2))); } #endif @@ -323,20 +342,31 @@ template class unordered_set std::pair emplace( \ BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a)) \ { \ - return table_.emplace(boost::unordered::detail::create_emplace_args( \ - BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))); \ + return table_.emplace_impl( \ + table::extractor::extract( \ + boost::forward(a0), boost::forward(a1)), \ + boost::unordered::detail::create_emplace_args( \ + BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))); \ } \ \ template \ iterator emplace_hint(const_iterator hint, \ BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a)) \ { \ - return table_.emplace_hint( \ - hint, boost::unordered::detail::create_emplace_args( \ - BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))); \ + return table_.emplace_hint_impl( \ + hint, table::extractor::extract( \ + boost::forward(a0), boost::forward(a1)), \ + boost::unordered::detail::create_emplace_args( \ + BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))); \ } - BOOST_PP_REPEAT_FROM_TO(4, BOOST_PP_INC(BOOST_UNORDERED_EMPLACE_LIMIT), + BOOST_UNORDERED_EMPLACE(1, 4, _) + BOOST_UNORDERED_EMPLACE(1, 5, _) + BOOST_UNORDERED_EMPLACE(1, 6, _) + BOOST_UNORDERED_EMPLACE(1, 7, _) + BOOST_UNORDERED_EMPLACE(1, 8, _) + BOOST_UNORDERED_EMPLACE(1, 9, _) + BOOST_PP_REPEAT_FROM_TO(10, BOOST_PP_INC(BOOST_UNORDERED_EMPLACE_LIMIT), BOOST_UNORDERED_EMPLACE, _) #undef BOOST_UNORDERED_EMPLACE @@ -534,6 +564,8 @@ template class unordered_multiset typedef boost::unordered::detail::multiset types; typedef typename types::value_allocator_traits value_allocator_traits; typedef typename types::table table; + typedef typename table::node_pointer node_pointer; + typedef typename table::link_pointer link_pointer; public: typedef typename value_allocator_traits::pointer pointer; @@ -695,9 +727,12 @@ template class unordered_multiset // emplace #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + template iterator emplace(BOOST_FWD_REF(Args)... args) { - return table_.emplace(boost::forward(args)...); + return iterator(table_.emplace_impl( + boost::unordered::detail::func::construct_node_from_args( + table_.node_alloc(), boost::forward(args)...))); } #else @@ -719,24 +754,33 @@ template class unordered_multiset template iterator emplace(BOOST_FWD_REF(A0) a0) { - return table_.emplace(boost::unordered::detail::create_emplace_args( - boost::forward(a0))); + return iterator(table_.emplace_impl( + boost::unordered::detail::func::construct_node_from_args( + table_.node_alloc(), + boost::unordered::detail::create_emplace_args( + boost::forward(a0))))); } template iterator emplace(BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1) { - return table_.emplace(boost::unordered::detail::create_emplace_args( - boost::forward(a0), boost::forward(a1))); + return iterator(table_.emplace_impl( + boost::unordered::detail::func::construct_node_from_args( + table_.node_alloc(), + boost::unordered::detail::create_emplace_args( + boost::forward(a0), boost::forward(a1))))); } template iterator emplace( BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2) { - return table_.emplace(boost::unordered::detail::create_emplace_args( - boost::forward(a0), boost::forward(a1), - boost::forward(a2))); + return iterator(table_.emplace_impl( + boost::unordered::detail::func::construct_node_from_args( + table_.node_alloc(), + boost::unordered::detail::create_emplace_args( + boost::forward(a0), boost::forward(a1), + boost::forward(a2))))); } #endif @@ -746,7 +790,9 @@ template class unordered_multiset template iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args) { - return table_.emplace_hint(hint, boost::forward(args)...); + return iterator(table_.emplace_hint_impl( + hint, boost::unordered::detail::func::construct_node_from_args( + table_.node_alloc(), boost::forward(args)...))); } #else @@ -766,28 +812,34 @@ template class unordered_multiset template iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(A0) a0) { - return table_.emplace_hint( - hint, boost::unordered::detail::create_emplace_args( - boost::forward(a0))); + return iterator(table_.emplace_hint_impl( + hint, boost::unordered::detail::func::construct_node_from_args( + table_.node_alloc(), + boost::unordered::detail::create_emplace_args( + boost::forward(a0))))); } template iterator emplace_hint( const_iterator hint, BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1) { - return table_.emplace_hint( - hint, boost::unordered::detail::create_emplace_args( - boost::forward(a0), boost::forward(a1))); + return iterator(table_.emplace_hint_impl( + hint, boost::unordered::detail::func::construct_node_from_args( + table_.node_alloc(), + boost::unordered::detail::create_emplace_args( + boost::forward(a0), boost::forward(a1))))); } template iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2) { - return table_.emplace_hint( - hint, boost::unordered::detail::create_emplace_args( - boost::forward(a0), boost::forward(a1), - boost::forward(a2))); + return iterator(table_.emplace_hint_impl( + hint, boost::unordered::detail::func::construct_node_from_args( + table_.node_alloc(), + boost::unordered::detail::create_emplace_args( + boost::forward(a0), boost::forward(a1), + boost::forward(a2))))); } #endif @@ -798,20 +850,32 @@ template class unordered_multiset template \ iterator emplace(BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a)) \ { \ - return table_.emplace(boost::unordered::detail::create_emplace_args( \ - BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))); \ + return iterator(table_.emplace_impl( \ + boost::unordered::detail::func::construct_node_from_args( \ + table_.node_alloc(), \ + boost::unordered::detail::create_emplace_args( \ + BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))))); \ } \ \ template \ iterator emplace_hint(const_iterator hint, \ BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a)) \ { \ - return table_.emplace_hint( \ - hint, boost::unordered::detail::create_emplace_args( \ - BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))); \ + return iterator(table_.emplace_hint_impl( \ + hint, \ + boost::unordered::detail::func::construct_node_from_args( \ + table_.node_alloc(), \ + boost::unordered::detail::create_emplace_args( \ + BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))))); \ } - BOOST_PP_REPEAT_FROM_TO(4, BOOST_PP_INC(BOOST_UNORDERED_EMPLACE_LIMIT), + BOOST_UNORDERED_EMPLACE(1, 4, _) + BOOST_UNORDERED_EMPLACE(1, 5, _) + BOOST_UNORDERED_EMPLACE(1, 6, _) + BOOST_UNORDERED_EMPLACE(1, 7, _) + BOOST_UNORDERED_EMPLACE(1, 8, _) + BOOST_UNORDERED_EMPLACE(1, 9, _) + BOOST_PP_REPEAT_FROM_TO(10, BOOST_PP_INC(BOOST_UNORDERED_EMPLACE_LIMIT), BOOST_UNORDERED_EMPLACE, _) #undef BOOST_UNORDERED_EMPLACE @@ -1006,7 +1070,7 @@ unordered_set::unordered_set(InputIt f, InputIt l, size_type n, const hasher& hf, const key_equal& eql, const allocator_type& a) : table_(boost::unordered::detail::initial_size(f, l, n), hf, eql, a) { - table_.insert_range(f, l); + this->insert(f, l); } template @@ -1046,7 +1110,7 @@ unordered_set::unordered_set(std::initializer_list list, boost::unordered::detail::initial_size(list.begin(), list.end(), n), hf, eql, a) { - table_.insert_range(list.begin(), list.end()); + this->insert(list.begin(), list.end()); } #endif @@ -1071,7 +1135,7 @@ unordered_set::unordered_set( : table_(boost::unordered::detail::initial_size(f, l, n), hasher(), key_equal(), a) { - table_.insert_range(f, l); + this->insert(f, l); } template @@ -1081,7 +1145,7 @@ unordered_set::unordered_set(InputIt f, InputIt l, size_type n, : table_( boost::unordered::detail::initial_size(f, l, n), hf, key_equal(), a) { - table_.insert_range(f, l); + this->insert(f, l); } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) @@ -1093,7 +1157,7 @@ unordered_set::unordered_set(std::initializer_list list, boost::unordered::detail::initial_size(list.begin(), list.end(), n), hasher(), key_equal(), a) { - table_.insert_range(list.begin(), list.end()); + this->insert(list.begin(), list.end()); } template @@ -1103,7 +1167,7 @@ unordered_set::unordered_set(std::initializer_list list, boost::unordered::detail::initial_size(list.begin(), list.end(), n), hf, key_equal(), a) { - table_.insert_range(list.begin(), list.end()); + this->insert(list.begin(), list.end()); } #endif @@ -1119,8 +1183,8 @@ template unordered_set& unordered_set::operator=( std::initializer_list list) { - table_.clear(); - table_.insert_range(list.begin(), list.end()); + this->clear(); + this->insert(list.begin(), list.end()); return *this; } @@ -1131,7 +1195,13 @@ unordered_set& unordered_set::operator=( template std::size_t unordered_set::max_size() const BOOST_NOEXCEPT { - return table_.max_size(); + using namespace std; + + // size < mlf_ * count + return boost::unordered::detail::double_to_size( + ceil(static_cast(table_.mlf_) * + static_cast(table_.max_bucket_count()))) - + 1; } // modifiers @@ -1140,14 +1210,17 @@ template template void unordered_set::insert(InputIt first, InputIt last) { - table_.insert_range(first, last); + if (first != last) { + table_.insert_range_impl( + table::extractor::extract(*first), first, last); + } } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) template void unordered_set::insert(std::initializer_list list) { - table_.insert_range(list.begin(), list.end()); + this->insert(list.begin(), list.end()); } #endif @@ -1155,7 +1228,11 @@ template typename unordered_set::iterator unordered_set::erase( const_iterator position) { - return table_.erase(position); + node_pointer node = table::get_node(position); + BOOST_ASSERT(node); + node_pointer next = table::node_algo::next_node(node); + table_.erase_nodes(node, next); + return iterator(next); } template @@ -1169,7 +1246,11 @@ template typename unordered_set::iterator unordered_set::erase( const_iterator first, const_iterator last) { - return table_.erase_range(first, last); + node_pointer last_node = table::get_node(last); + if (first == last) + return iterator(last_node); + table_.erase_nodes(table::get_node(first), last_node); + return iterator(last_node); } template @@ -1185,13 +1266,10 @@ void unordered_set::swap(unordered_set& other) template void unordered_set::clear() BOOST_NOEXCEPT { - table_.clear(); -} - -template -void unordered_multiset::clear() BOOST_NOEXCEPT -{ - table_.clear(); + if (table_.size_) { + table_.clear_buckets(); + table_.delete_nodes(table_.get_previous_start(), link_pointer()); + } } // observers @@ -1263,14 +1341,15 @@ typename unordered_set::const_iterator unordered_set::find(CompatibleKey const& k, CompatibleHash const& hash, CompatiblePredicate const& eq) const { - return const_iterator(table_.generic_find_node(k, hash, eq)); + return const_iterator( + table_.find_node_impl(table::policy::apply_hash(hash, k), k, eq)); } template typename unordered_set::size_type unordered_set::count( const key_type& k) const { - return table_.count(k); + return table_.find_node(k) ? 1 : 0; } template @@ -1278,7 +1357,9 @@ std::pair::const_iterator, typename unordered_set::const_iterator> unordered_set::equal_range(const key_type& k) const { - return table_.equal_range(k); + node_pointer n = table_.find_node(k); + return std::make_pair(const_iterator(n), + const_iterator(n ? table::node_algo::next_node(n) : n)); } template @@ -1293,7 +1374,9 @@ unordered_set::bucket_size(size_type n) const template float unordered_set::load_factor() const BOOST_NOEXCEPT { - return table_.load_factor(); + BOOST_ASSERT(table_.bucket_count_ != 0); + return static_cast(table_.size_) / + static_cast(table_.bucket_count_); } template @@ -1311,7 +1394,8 @@ void unordered_set::rehash(size_type n) template void unordered_set::reserve(size_type n) { - table_.reserve(n); + table_.rehash(static_cast( + std::ceil(static_cast(n) / table_.mlf_))); } template @@ -1376,7 +1460,7 @@ unordered_multiset::unordered_multiset(InputIt f, InputIt l, const allocator_type& a) : table_(boost::unordered::detail::initial_size(f, l, n), hf, eql, a) { - table_.insert_range(f, l); + this->insert(f, l); } template @@ -1417,7 +1501,7 @@ unordered_multiset::unordered_multiset( boost::unordered::detail::initial_size(list.begin(), list.end(), n), hf, eql, a) { - table_.insert_range(list.begin(), list.end()); + this->insert(list.begin(), list.end()); } #endif @@ -1443,7 +1527,7 @@ unordered_multiset::unordered_multiset( : table_(boost::unordered::detail::initial_size(f, l, n), hasher(), key_equal(), a) { - table_.insert_range(f, l); + this->insert(f, l); } template @@ -1453,7 +1537,7 @@ unordered_multiset::unordered_multiset(InputIt f, InputIt l, : table_( boost::unordered::detail::initial_size(f, l, n), hf, key_equal(), a) { - table_.insert_range(f, l); + this->insert(f, l); } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) @@ -1466,7 +1550,7 @@ unordered_multiset::unordered_multiset( boost::unordered::detail::initial_size(list.begin(), list.end(), n), hasher(), key_equal(), a) { - table_.insert_range(list.begin(), list.end()); + this->insert(list.begin(), list.end()); } template @@ -1477,7 +1561,7 @@ unordered_multiset::unordered_multiset( boost::unordered::detail::initial_size(list.begin(), list.end(), n), hf, key_equal(), a) { - table_.insert_range(list.begin(), list.end()); + this->insert(list.begin(), list.end()); } #endif @@ -1493,8 +1577,8 @@ template unordered_multiset& unordered_multiset::operator=( std::initializer_list list) { - table_.clear(); - table_.insert_range(list.begin(), list.end()); + this->clear(); + this->insert(list.begin(), list.end()); return *this; } @@ -1505,7 +1589,13 @@ unordered_multiset& unordered_multiset::operator=( template std::size_t unordered_multiset::max_size() const BOOST_NOEXCEPT { - return table_.max_size(); + using namespace std; + + // size < mlf_ * count + return boost::unordered::detail::double_to_size( + ceil(static_cast(table_.mlf_) * + static_cast(table_.max_bucket_count()))) - + 1; } // modifiers @@ -1522,7 +1612,7 @@ template void unordered_multiset::insert( std::initializer_list list) { - table_.insert_range(list.begin(), list.end()); + this->insert(list.begin(), list.end()); } #endif @@ -1530,7 +1620,11 @@ template typename unordered_multiset::iterator unordered_multiset::erase(const_iterator position) { - return table_.erase(position); + node_pointer node = table::get_node(position); + BOOST_ASSERT(node); + node_pointer next = table::node_algo::next_node(node); + table_.erase_nodes(node, next); + return iterator(next); } template @@ -1544,7 +1638,11 @@ template typename unordered_multiset::iterator unordered_multiset::erase(const_iterator first, const_iterator last) { - return table_.erase_range(first, last); + node_pointer last_node = table::get_node(last); + if (first == last) + return iterator(last_node); + table_.erase_nodes(table::get_node(first), last_node); + return iterator(last_node); } template @@ -1557,6 +1655,15 @@ void unordered_multiset::swap(unordered_multiset& other) table_.swap(other.table_); } +template +void unordered_multiset::clear() BOOST_NOEXCEPT +{ + if (table_.size_) { + table_.clear_buckets(); + table_.delete_nodes(table_.get_previous_start(), link_pointer()); + } +} + // observers template @@ -1634,14 +1741,16 @@ typename unordered_multiset::const_iterator unordered_multiset::find(CompatibleKey const& k, CompatibleHash const& hash, CompatiblePredicate const& eq) const { - return const_iterator(table_.generic_find_node(k, hash, eq)); + return const_iterator( + table_.find_node_impl(table::policy::apply_hash(hash, k), k, eq)); } template typename unordered_multiset::size_type unordered_multiset::count(const key_type& k) const { - return table_.count(k); + node_pointer n = table_.find_node(k); + return n ? table::node_algo::count(n, &table_) : 0; } template @@ -1649,7 +1758,9 @@ std::pair::const_iterator, typename unordered_multiset::const_iterator> unordered_multiset::equal_range(const key_type& k) const { - return table_.equal_range(k); + node_pointer n = table_.find_node(k); + return std::make_pair(const_iterator(n), + const_iterator(n ? table::node_algo::next_group(n, &table_) : n)); } template @@ -1664,7 +1775,9 @@ unordered_multiset::bucket_size(size_type n) const template float unordered_multiset::load_factor() const BOOST_NOEXCEPT { - return table_.load_factor(); + BOOST_ASSERT(table_.bucket_count_ != 0); + return static_cast(table_.size_) / + static_cast(table_.bucket_count_); } template @@ -1682,7 +1795,8 @@ void unordered_multiset::rehash(size_type n) template void unordered_multiset::reserve(size_type n) { - table_.reserve(n); + table_.rehash(static_cast( + std::ceil(static_cast(n) / table_.mlf_))); } template