From f6f5ecdc008b10224a00e864ea527e1b2aaa11d0 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 23 Apr 2017 10:09:18 +0100 Subject: [PATCH 01/11] Expand calls to emplace implementation Also manually call the emplace macro up to 9 arguments, nicer error messages for little effort. Does it matter that there's no longer a nice backend for `please_ignore_this_overload`? I don't think so, I was worried that it would be confusing if triggered, but I'm not really aware of that ever happening. --- .../boost/unordered/detail/implementation.hpp | 125 ------------- include/boost/unordered/unordered_map.hpp | 168 ++++++++++++------ include/boost/unordered/unordered_set.hpp | 160 +++++++++++------ 3 files changed, 224 insertions(+), 229 deletions(-) diff --git a/include/boost/unordered/detail/implementation.hpp b/include/boost/unordered/detail/implementation.hpp index 89ac1fbf..086bc613 100644 --- a/include/boost/unordered/detail/implementation.hpp +++ b/include/boost/unordered/detail/implementation.hpp @@ -3890,81 +3890,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) @@ -4786,56 +4711,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()); diff --git a/include/boost/unordered/unordered_map.hpp b/include/boost/unordered/unordered_map.hpp index 32d8f0ae..34122ff6 100644 --- a/include/boost/unordered/unordered_map.hpp +++ b/include/boost/unordered/unordered_map.hpp @@ -220,7 +220,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 +246,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 +282,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 +304,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 +342,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 +653,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 @@ -972,7 +1000,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 +1024,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 +1060,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 +1082,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 +1120,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 diff --git a/include/boost/unordered/unordered_set.hpp b/include/boost/unordered/unordered_set.hpp index ec7cfd1d..336a9472 100644 --- a/include/boost/unordered/unordered_set.hpp +++ b/include/boost/unordered/unordered_set.hpp @@ -218,7 +218,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 +244,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 +280,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 +302,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 +340,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 @@ -695,9 +723,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 +750,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 +786,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 +808,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 +846,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 From 814926ef31e5a1f21dfc2a84a31d0b20488eb6f6 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 23 Apr 2017 10:09:18 +0100 Subject: [PATCH 02/11] Expand calls to clear implementation --- .../boost/unordered/detail/implementation.hpp | 11 -------- include/boost/unordered/unordered_map.hpp | 16 +++++++++--- include/boost/unordered/unordered_set.hpp | 26 ++++++++++++------- 3 files changed, 29 insertions(+), 24 deletions(-) diff --git a/include/boost/unordered/detail/implementation.hpp b/include/boost/unordered/detail/implementation.hpp index 086bc613..35d03f4b 100644 --- a/include/boost/unordered/detail/implementation.hpp +++ b/include/boost/unordered/detail/implementation.hpp @@ -3078,17 +3078,6 @@ struct table : boost::unordered::detail::functions 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::link_pointer link_pointer; public: typedef typename value_allocator_traits::pointer pointer; @@ -836,6 +837,7 @@ 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::link_pointer link_pointer; public: typedef typename value_allocator_traits::pointer pointer; @@ -1483,7 +1485,7 @@ template unordered_map& unordered_map::operator=( std::initializer_list list) { - table_.clear(); + this->clear(); table_.insert_range(list.begin(), list.end()); return *this; } @@ -1557,7 +1559,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 @@ -1912,7 +1917,7 @@ template unordered_multimap& unordered_multimap::operator=( std::initializer_list list) { - table_.clear(); + this->clear(); table_.insert_range(list.begin(), list.end()); return *this; } @@ -1987,7 +1992,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 diff --git a/include/boost/unordered/unordered_set.hpp b/include/boost/unordered/unordered_set.hpp index 336a9472..75fde4fa 100644 --- a/include/boost/unordered/unordered_set.hpp +++ b/include/boost/unordered/unordered_set.hpp @@ -53,6 +53,7 @@ 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::link_pointer link_pointer; public: typedef typename value_allocator_traits::pointer pointer; @@ -562,6 +563,7 @@ 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::link_pointer link_pointer; public: typedef typename value_allocator_traits::pointer pointer; @@ -1179,7 +1181,7 @@ template unordered_set& unordered_set::operator=( std::initializer_list list) { - table_.clear(); + this->clear(); table_.insert_range(list.begin(), list.end()); return *this; } @@ -1245,13 +1247,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 @@ -1553,7 +1552,7 @@ template unordered_multiset& unordered_multiset::operator=( std::initializer_list list) { - table_.clear(); + this->clear(); table_.insert_range(list.begin(), list.end()); return *this; } @@ -1617,6 +1616,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 From a41a0f3a068723fb3baf4ef62edbdb43d1a9b1af Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 23 Apr 2017 10:09:18 +0100 Subject: [PATCH 03/11] Expand calls to load_factor implementation --- include/boost/unordered/detail/implementation.hpp | 6 ------ include/boost/unordered/unordered_map.hpp | 8 ++++++-- include/boost/unordered/unordered_set.hpp | 8 ++++++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/include/boost/unordered/detail/implementation.hpp b/include/boost/unordered/detail/implementation.hpp index 35d03f4b..deb3a480 100644 --- a/include/boost/unordered/detail/implementation.hpp +++ b/include/boost/unordered/detail/implementation.hpp @@ -2758,12 +2758,6 @@ 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); diff --git a/include/boost/unordered/unordered_map.hpp b/include/boost/unordered/unordered_map.hpp index f6eeda96..dc8600ba 100644 --- a/include/boost/unordered/unordered_map.hpp +++ b/include/boost/unordered/unordered_map.hpp @@ -1716,7 +1716,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 @@ -2129,7 +2131,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 diff --git a/include/boost/unordered/unordered_set.hpp b/include/boost/unordered/unordered_set.hpp index 75fde4fa..99d1fa2f 100644 --- a/include/boost/unordered/unordered_set.hpp +++ b/include/boost/unordered/unordered_set.hpp @@ -1352,7 +1352,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 @@ -1732,7 +1734,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 From 435b7450d4c4fcf3118a164053ddda57d30c72de Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 23 Apr 2017 10:09:18 +0100 Subject: [PATCH 04/11] Expand calls to max_size implementation --- .../boost/unordered/detail/implementation.hpp | 11 ----------- include/boost/unordered/unordered_map.hpp | 16 ++++++++++++++-- include/boost/unordered/unordered_set.hpp | 16 ++++++++++++++-- 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/include/boost/unordered/detail/implementation.hpp b/include/boost/unordered/detail/implementation.hpp index deb3a480..f680283c 100644 --- a/include/boost/unordered/detail/implementation.hpp +++ b/include/boost/unordered/detail/implementation.hpp @@ -2776,17 +2776,6 @@ struct table : boost::unordered::detail::functions(mlf_) * - static_cast(max_bucket_count()))) - - 1; - } - void recalculate_max_load() { using namespace std; diff --git a/include/boost/unordered/unordered_map.hpp b/include/boost/unordered/unordered_map.hpp index dc8600ba..b0e7055d 100644 --- a/include/boost/unordered/unordered_map.hpp +++ b/include/boost/unordered/unordered_map.hpp @@ -1497,7 +1497,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 @@ -1931,7 +1937,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 diff --git a/include/boost/unordered/unordered_set.hpp b/include/boost/unordered/unordered_set.hpp index 99d1fa2f..86f553c4 100644 --- a/include/boost/unordered/unordered_set.hpp +++ b/include/boost/unordered/unordered_set.hpp @@ -1193,7 +1193,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 @@ -1566,7 +1572,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 From 19a45e028af268d51bae2ab4150dce199733c9e1 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 23 Apr 2017 10:09:18 +0100 Subject: [PATCH 05/11] Expand calls to generic_find_node --- include/boost/unordered/detail/implementation.hpp | 7 ------- include/boost/unordered/unordered_map.hpp | 12 ++++++++---- include/boost/unordered/unordered_set.hpp | 6 ++++-- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/include/boost/unordered/detail/implementation.hpp b/include/boost/unordered/detail/implementation.hpp index f680283c..b7f18498 100644 --- a/include/boost/unordered/detail/implementation.hpp +++ b/include/boost/unordered/detail/implementation.hpp @@ -3230,13 +3230,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()); diff --git a/include/boost/unordered/unordered_map.hpp b/include/boost/unordered/unordered_map.hpp index b0e7055d..d5c45f3e 100644 --- a/include/boost/unordered/unordered_map.hpp +++ b/include/boost/unordered/unordered_map.hpp @@ -1647,7 +1647,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 @@ -1656,7 +1657,8 @@ 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 @@ -2096,7 +2098,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 @@ -2105,7 +2108,8 @@ 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 diff --git a/include/boost/unordered/unordered_set.hpp b/include/boost/unordered/unordered_set.hpp index 86f553c4..cda04175 100644 --- a/include/boost/unordered/unordered_set.hpp +++ b/include/boost/unordered/unordered_set.hpp @@ -1328,7 +1328,8 @@ 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 @@ -1716,7 +1717,8 @@ 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 From b6c229e2bb0fafaede1adda55ee112c181eb82df Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 23 Apr 2017 10:09:18 +0100 Subject: [PATCH 06/11] Expand calls to reserve implementation --- include/boost/unordered/detail/implementation.hpp | 7 ------- include/boost/unordered/unordered_map.hpp | 6 ++++-- include/boost/unordered/unordered_set.hpp | 6 ++++-- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/include/boost/unordered/detail/implementation.hpp b/include/boost/unordered/detail/implementation.hpp index b7f18498..d3612c21 100644 --- a/include/boost/unordered/detail/implementation.hpp +++ b/include/boost/unordered/detail/implementation.hpp @@ -3358,13 +3358,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) { diff --git a/include/boost/unordered/unordered_map.hpp b/include/boost/unordered/unordered_map.hpp index d5c45f3e..08135a57 100644 --- a/include/boost/unordered/unordered_map.hpp +++ b/include/boost/unordered/unordered_map.hpp @@ -1744,7 +1744,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 @@ -2167,7 +2168,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 cda04175..705c9b87 100644 --- a/include/boost/unordered/unordered_set.hpp +++ b/include/boost/unordered/unordered_set.hpp @@ -1379,7 +1379,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 @@ -1768,7 +1769,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 From da835e88b8f4b50a5313105b189a6c029795e8c2 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 23 Apr 2017 10:09:18 +0100 Subject: [PATCH 07/11] Expand calls to insert_range --- .../boost/unordered/detail/implementation.hpp | 6 --- include/boost/unordered/unordered_map.hpp | 37 ++++++++++--------- include/boost/unordered/unordered_set.hpp | 37 ++++++++++--------- 3 files changed, 40 insertions(+), 40 deletions(-) diff --git a/include/boost/unordered/detail/implementation.hpp b/include/boost/unordered/detail/implementation.hpp index d3612c21..9e7e01e8 100644 --- a/include/boost/unordered/detail/implementation.hpp +++ b/include/boost/unordered/detail/implementation.hpp @@ -4071,12 +4071,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) { diff --git a/include/boost/unordered/unordered_map.hpp b/include/boost/unordered/unordered_map.hpp index 08135a57..3aa0d12a 100644 --- a/include/boost/unordered/unordered_map.hpp +++ b/include/boost/unordered/unordered_map.hpp @@ -1369,7 +1369,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 @@ -1409,7 +1409,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 @@ -1435,7 +1435,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 @@ -1445,7 +1445,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) @@ -1458,7 +1458,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 @@ -1469,7 +1469,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 @@ -1486,7 +1486,7 @@ unordered_map& unordered_map::operator=( std::initializer_list list) { this->clear(); - table_.insert_range(list.begin(), list.end()); + this->insert(list.begin(), list.end()); return *this; } @@ -1512,7 +1512,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) @@ -1520,7 +1523,7 @@ template void unordered_map::insert( std::initializer_list list) { - table_.insert_range(list.begin(), list.end()); + this->insert(list.begin(), list.end()); } #endif @@ -1811,7 +1814,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 @@ -1852,7 +1855,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 @@ -1878,7 +1881,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 @@ -1888,7 +1891,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) @@ -1901,7 +1904,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 @@ -1912,7 +1915,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 @@ -1929,7 +1932,7 @@ unordered_multimap& unordered_multimap::operator=( std::initializer_list list) { this->clear(); - table_.insert_range(list.begin(), list.end()); + this->insert(list.begin(), list.end()); return *this; } @@ -1963,7 +1966,7 @@ template void unordered_multimap::insert( std::initializer_list list) { - table_.insert_range(list.begin(), list.end()); + this->insert(list.begin(), list.end()); } #endif diff --git a/include/boost/unordered/unordered_set.hpp b/include/boost/unordered/unordered_set.hpp index 705c9b87..4cb8eaa9 100644 --- a/include/boost/unordered/unordered_set.hpp +++ b/include/boost/unordered/unordered_set.hpp @@ -1068,7 +1068,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 @@ -1108,7 +1108,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 @@ -1133,7 +1133,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 @@ -1143,7 +1143,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) @@ -1155,7 +1155,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 @@ -1165,7 +1165,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 @@ -1182,7 +1182,7 @@ unordered_set& unordered_set::operator=( std::initializer_list list) { this->clear(); - table_.insert_range(list.begin(), list.end()); + this->insert(list.begin(), list.end()); return *this; } @@ -1208,14 +1208,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 @@ -1445,7 +1448,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 @@ -1486,7 +1489,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 @@ -1512,7 +1515,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 @@ -1522,7 +1525,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) @@ -1535,7 +1538,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 @@ -1546,7 +1549,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 @@ -1563,7 +1566,7 @@ unordered_multiset& unordered_multiset::operator=( std::initializer_list list) { this->clear(); - table_.insert_range(list.begin(), list.end()); + this->insert(list.begin(), list.end()); return *this; } @@ -1597,7 +1600,7 @@ template void unordered_multiset::insert( std::initializer_list list) { - table_.insert_range(list.begin(), list.end()); + this->insert(list.begin(), list.end()); } #endif From 25b0b66e527036a9e2d50193426e8ae254381de0 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 23 Apr 2017 10:09:18 +0100 Subject: [PATCH 08/11] Expand calls to erase implementation Doesn't work as well as the previous changes. --- .../boost/unordered/detail/implementation.hpp | 34 +---------------- include/boost/unordered/unordered_map.hpp | 38 ++++++++++++++++--- include/boost/unordered/unordered_set.hpp | 26 +++++++++++-- 3 files changed, 56 insertions(+), 42 deletions(-) diff --git a/include/boost/unordered/detail/implementation.hpp b/include/boost/unordered/detail/implementation.hpp index 9e7e01e8..0b7fe3b0 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 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_); @@ -4832,22 +4818,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 3aa0d12a..2b17ab04 100644 --- a/include/boost/unordered/unordered_map.hpp +++ b/include/boost/unordered/unordered_map.hpp @@ -55,6 +55,7 @@ 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: @@ -837,6 +838,7 @@ 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: @@ -1531,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 @@ -1552,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 @@ -1974,14 +1988,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 @@ -1996,7 +2018,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 diff --git a/include/boost/unordered/unordered_set.hpp b/include/boost/unordered/unordered_set.hpp index 4cb8eaa9..be316fd2 100644 --- a/include/boost/unordered/unordered_set.hpp +++ b/include/boost/unordered/unordered_set.hpp @@ -53,6 +53,7 @@ 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: @@ -563,6 +564,7 @@ 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: @@ -1226,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 @@ -1240,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 @@ -1608,7 +1618,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 @@ -1622,7 +1636,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 From 13ff1e7fb136aae192a67aecb606eaef66c96007 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 23 Apr 2017 10:09:18 +0100 Subject: [PATCH 09/11] Expand calls to count and equal_range implementation --- .../boost/unordered/detail/implementation.hpp | 27 ------------------- include/boost/unordered/unordered_map.hpp | 21 ++++++++++----- include/boost/unordered/unordered_set.hpp | 13 ++++++--- 3 files changed, 24 insertions(+), 37 deletions(-) diff --git a/include/boost/unordered/detail/implementation.hpp b/include/boost/unordered/detail/implementation.hpp index 0b7fe3b0..ed0f8c32 100644 --- a/include/boost/unordered/detail/implementation.hpp +++ b/include/boost/unordered/detail/implementation.hpp @@ -3771,11 +3771,6 @@ struct table_unique : boost::unordered::detail::table // 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_) { @@ -3788,13 +3783,6 @@ struct table_unique : boost::unordered::detail::table 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 bool equals(table_unique const& other) const @@ -4493,21 +4481,6 @@ struct table_equiv : boost::unordered::detail::table 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)); - } - // Equality bool equals(table_equiv const& other) const diff --git a/include/boost/unordered/unordered_map.hpp b/include/boost/unordered/unordered_map.hpp index 2b17ab04..8deca06d 100644 --- a/include/boost/unordered/unordered_map.hpp +++ b/include/boost/unordered/unordered_map.hpp @@ -1682,7 +1682,7 @@ 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 @@ -1690,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 @@ -1698,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 @@ -2146,7 +2150,8 @@ 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 @@ -2154,7 +2159,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 @@ -2162,7 +2169,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 diff --git a/include/boost/unordered/unordered_set.hpp b/include/boost/unordered/unordered_set.hpp index be316fd2..7bb86954 100644 --- a/include/boost/unordered/unordered_set.hpp +++ b/include/boost/unordered/unordered_set.hpp @@ -1349,7 +1349,7 @@ 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 @@ -1357,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 @@ -1747,7 +1749,8 @@ 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 @@ -1755,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 From 4f1c6e1ebf98b667bb143785fb590afb309eff84 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 23 Apr 2017 10:09:18 +0100 Subject: [PATCH 10/11] Expand calls to init/move_init --- .../boost/unordered/detail/implementation.hpp | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/include/boost/unordered/detail/implementation.hpp b/include/boost/unordered/detail/implementation.hpp index ed0f8c32..599ec1c7 100644 --- a/include/boost/unordered/detail/implementation.hpp +++ b/include/boost/unordered/detail/implementation.hpp @@ -2853,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 // @@ -3749,24 +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); + 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); + } } // Accessors @@ -4461,24 +4451,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); + 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 From 7941771d617a7df14319ade31ed30c69af27c2af Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 23 Apr 2017 10:09:18 +0100 Subject: [PATCH 11/11] Expand calls to at implementation --- .../boost/unordered/detail/implementation.hpp | 14 -------------- include/boost/unordered/unordered_map.hpp | 18 ++++++++++++++++-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/include/boost/unordered/detail/implementation.hpp b/include/boost/unordered/detail/implementation.hpp index 599ec1c7..afbfb2a2 100644 --- a/include/boost/unordered/detail/implementation.hpp +++ b/include/boost/unordered/detail/implementation.hpp @@ -3759,20 +3759,6 @@ struct table_unique : boost::unordered::detail::table } } - // Accessors - - value_type& at(const_key_type& k) const - { - if (this->size_) { - node_pointer n = this->find_node(k); - if (n) - return n->value(); - } - - boost::throw_exception( - std::out_of_range("Unable to find key in unordered_map.")); - } - // equals bool equals(table_unique const& other) const diff --git a/include/boost/unordered/unordered_map.hpp b/include/boost/unordered/unordered_map.hpp index 8deca06d..a55e2b5c 100644 --- a/include/boost/unordered/unordered_map.hpp +++ b/include/boost/unordered/unordered_map.hpp @@ -1723,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