diff --git a/include/boost/unordered/detail/util.hpp b/include/boost/unordered/detail/util.hpp index 1147965a..f1ff6684 100644 --- a/include/boost/unordered/detail/util.hpp +++ b/include/boost/unordered/detail/util.hpp @@ -27,6 +27,7 @@ #include #include #include +#include #include // Template parameters: @@ -58,10 +59,16 @@ #define BOOST_UNORDERED_TEMPLATE_ARGS(z, num_params) \ BOOST_PP_ENUM_PARAMS_Z(z, num_params, class Arg) + #define BOOST_UNORDERED_FUNCTION_PARAMS(z, num_params) \ - BOOST_PP_ENUM_BINARY_PARAMS_Z(z, num_params, Arg, const& arg) + BOOST_PP_ENUM_##z(num_params, BOOST_UNORDERED_FUNCTION_PARAMS2, _) +#define BOOST_UNORDERED_FUNCTION_PARAMS2(z, i, _) \ + BOOST_FWD_REF(Arg##i) arg##i + #define BOOST_UNORDERED_CALL_PARAMS(z, num_params) \ - BOOST_PP_ENUM_PARAMS_Z(z, num_params, arg) + BOOST_PP_ENUM_##z(num_params, BOOST_UNORDERED_CALL_PARAMS2, _) +#define BOOST_UNORDERED_CALL_PARAMS2(z, i, _) \ + boost::forward(arg##i) #endif @@ -71,6 +78,8 @@ namespace boost { namespace unordered { namespace detail { static const std::size_t default_bucket_count = 11; struct move_tag {}; + struct empty_emplace {}; + template class unique_table; template class equivalent_table; template class node_constructor; diff --git a/include/boost/unordered/unordered_map.hpp b/include/boost/unordered/unordered_map.hpp index 88574013..b0bace5f 100644 --- a/include/boost/unordered/unordered_map.hpp +++ b/include/boost/unordered/unordered_map.hpp @@ -223,10 +223,18 @@ namespace unordered iterator emplace_hint(const_iterator, Args&&...); #else - #if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100)) - std::pair emplace(value_type const& = value_type()); - iterator emplace_hint(const_iterator, value_type const& = value_type()); - #endif +#if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100)) + std::pair emplace( + boost::unordered::detail::empty_emplace + = boost::unordered::detail::empty_emplace(), + value_type v = value_type() + ); + iterator emplace_hint(const_iterator, + boost::unordered::detail::empty_emplace + = boost::unordered::detail::empty_emplace(), + value_type v = value_type() + ); +#endif #define BOOST_UNORDERED_EMPLACE(z, n, _) \ template < \ @@ -250,8 +258,10 @@ namespace unordered #endif - std::pair insert(const value_type&); - iterator insert(const_iterator, const value_type&); + std::pair insert(value_type const&); + std::pair insert(BOOST_RV_REF(value_type)); + iterator insert(const_iterator, value_type const&); + iterator insert(const_iterator, BOOST_RV_REF(value_type)); template void insert(InputIt, InputIt); #if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST) @@ -560,10 +570,18 @@ namespace unordered iterator emplace_hint(const_iterator, Args&&...); #else - #if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100)) - iterator emplace(value_type const& = value_type()); - iterator emplace_hint(const_iterator, value_type const& = value_type()); - #endif +#if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100)) + iterator emplace( + boost::unordered::detail::empty_emplace + = boost::unordered::detail::empty_emplace(), + value_type v = value_type() + ); + iterator emplace_hint(const_iterator, + boost::unordered::detail::empty_emplace + = boost::unordered::detail::empty_emplace(), + value_type v = value_type() + ); +#endif #define BOOST_UNORDERED_EMPLACE(z, n, _) \ template < \ @@ -587,10 +605,11 @@ namespace unordered #endif - iterator insert(const value_type&); - iterator insert(const_iterator, const value_type&); - template - void insert(InputIt, InputIt); + iterator insert(value_type const&); + iterator insert(BOOST_RV_REF(value_type)); + iterator insert(const_iterator, value_type const&); + iterator insert(const_iterator, BOOST_RV_REF(value_type)); + template void insert(InputIt, InputIt); #if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST) void insert(std::initializer_list); @@ -843,17 +862,23 @@ namespace unordered #if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100)) template std::pair::iterator, bool> - unordered_map::emplace(value_type const& v) + unordered_map::emplace( + boost::unordered::detail::empty_emplace, + value_type v + ) { - return BOOST_UNORDERED_PAIR_CAST(iterator, bool, table_.emplace(v)); + return BOOST_UNORDERED_PAIR_CAST(iterator, bool, + table_.emplace(boost::move(v))); } template BOOST_DEDUCED_TYPENAME unordered_map::iterator - unordered_map::emplace_hint( - const_iterator, value_type const& v) + unordered_map::emplace_hint(const_iterator, + boost::unordered::detail::empty_emplace, + value_type v + ) { - return iterator(table_.emplace(v).first); + return iterator(table_.emplace(boost::move(v)).first); } #endif @@ -897,18 +922,36 @@ namespace unordered template std::pair::iterator, bool> - unordered_map::insert(const value_type& obj) + unordered_map::insert(value_type const& obj) { - return BOOST_UNORDERED_PAIR_CAST(iterator, bool, table_.insert(obj)); + return BOOST_UNORDERED_PAIR_CAST(iterator, bool, + table_.emplace(obj)); + } + + template + std::pair::iterator, bool> + unordered_map::insert(BOOST_RV_REF(value_type) obj) + { + return BOOST_UNORDERED_PAIR_CAST(iterator, bool, + table_.emplace(boost::move(obj))); } template BOOST_DEDUCED_TYPENAME unordered_map::iterator - unordered_map::insert(const_iterator, const value_type& obj) + unordered_map::insert(const_iterator, + value_type const& obj) { return iterator(table_.emplace(obj).first); } + template + BOOST_DEDUCED_TYPENAME unordered_map::iterator + unordered_map::insert(const_iterator, + BOOST_RV_REF(value_type) obj) + { + return iterator(table_.emplace(boost::move(obj)).first); + } + template template void unordered_map::insert(InputIt first, InputIt last) @@ -1260,17 +1303,22 @@ namespace unordered #if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100)) template BOOST_DEDUCED_TYPENAME unordered_multimap::iterator - unordered_multimap::emplace(value_type const& v) + unordered_multimap::emplace( + boost::unordered::detail::empty_emplace, + value_type v + ) { - return iterator(table_.emplace(v)); + return iterator(table_.emplace(boost::move(v))); } template BOOST_DEDUCED_TYPENAME unordered_multimap::iterator - unordered_multimap::emplace_hint( - const_iterator, value_type const& v) + unordered_multimap::emplace_hint(const_iterator, + boost::unordered::detail::empty_emplace, + value_type v + ) { - return iterator(table_.emplace(v)); + return iterator(table_.emplace(boost::move(v))); } #endif @@ -1309,7 +1357,22 @@ namespace unordered template BOOST_DEDUCED_TYPENAME unordered_multimap::iterator - unordered_multimap::insert(const value_type& obj) + unordered_multimap::insert(value_type const& obj) + { + return iterator(table_.emplace(obj)); + } + + template + BOOST_DEDUCED_TYPENAME unordered_multimap::iterator + unordered_multimap::insert(BOOST_RV_REF(value_type) obj) + { + return iterator(table_.emplace(boost::move(obj))); + } + + template + BOOST_DEDUCED_TYPENAME unordered_multimap::iterator + unordered_multimap::insert( + const_iterator, value_type const& obj) { return iterator(table_.emplace(obj)); } @@ -1317,9 +1380,9 @@ namespace unordered template BOOST_DEDUCED_TYPENAME unordered_multimap::iterator unordered_multimap::insert( - const_iterator, const value_type& obj) + const_iterator, BOOST_RV_REF(value_type) obj) { - return iterator(table_.emplace(obj)); + return iterator(table_.emplace(boost::move(obj))); } template diff --git a/include/boost/unordered/unordered_set.hpp b/include/boost/unordered/unordered_set.hpp index de5ea512..de692749 100644 --- a/include/boost/unordered/unordered_set.hpp +++ b/include/boost/unordered/unordered_set.hpp @@ -220,8 +220,16 @@ namespace unordered iterator emplace_hint(const_iterator, Args&&...); #else - std::pair emplace(value_type const& = value_type()); - iterator emplace_hint(const_iterator, value_type const& = value_type()); + std::pair emplace( + boost::unordered::detail::empty_emplace + = boost::unordered::detail::empty_emplace(), + value_type v = value_type() + ); + iterator emplace_hint(const_iterator, + boost::unordered::detail::empty_emplace + = boost::unordered::detail::empty_emplace(), + value_type v = value_type() + ); #define BOOST_UNORDERED_EMPLACE(z, n, _) \ template < \ @@ -245,8 +253,10 @@ namespace unordered #endif - std::pair insert(const value_type&); - iterator insert(const_iterator, const value_type&); + std::pair insert(value_type const&); + std::pair insert(BOOST_RV_REF(value_type)); + iterator insert(const_iterator, value_type const&); + iterator insert(const_iterator, BOOST_RV_REF(value_type)); template void insert(InputIt, InputIt); #if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST) @@ -537,8 +547,16 @@ namespace unordered iterator emplace_hint(const_iterator, Args&&...); #else - iterator emplace(value_type const& = value_type()); - iterator emplace_hint(const_iterator, value_type const& = value_type()); + iterator emplace( + boost::unordered::detail::empty_emplace + = boost::unordered::detail::empty_emplace(), + value_type v = value_type() + ); + iterator emplace_hint(const_iterator, + boost::unordered::detail::empty_emplace + = boost::unordered::detail::empty_emplace(), + value_type v = value_type() + ); #define BOOST_UNORDERED_EMPLACE(z, n, _) \ template < \ @@ -562,8 +580,10 @@ namespace unordered #endif - iterator insert(const value_type&); - iterator insert(const_iterator, const value_type&); + iterator insert(value_type const&); + iterator insert(BOOST_RV_REF(value_type)); + iterator insert(const_iterator, value_type const&); + iterator insert(const_iterator, BOOST_RV_REF(value_type)); template void insert(InputIt, InputIt); @@ -806,17 +826,23 @@ namespace unordered template std::pair::iterator, bool> - unordered_set::emplace(value_type const& v) + unordered_set::emplace( + boost::unordered::detail::empty_emplace, + value_type v + ) { - return BOOST_UNORDERED_PAIR_CAST(iterator, bool, table_.emplace(v)); + return BOOST_UNORDERED_PAIR_CAST(iterator, bool, + table_.emplace(boost::move(v))); } template BOOST_DEDUCED_TYPENAME unordered_set::iterator - unordered_set::emplace_hint( - const_iterator, value_type const& v) + unordered_set::emplace_hint(const_iterator, + boost::unordered::detail::empty_emplace, + value_type v + ) { - return iterator(table_.emplace(v).first); + return iterator(table_.emplace(boost::move(v)).first); } #define BOOST_UNORDERED_EMPLACE(z, n, _) \ @@ -859,18 +885,36 @@ namespace unordered template std::pair::iterator, bool> - unordered_set::insert(const value_type& obj) + unordered_set::insert(value_type const& obj) { - return BOOST_UNORDERED_PAIR_CAST(iterator, bool, table_.insert(obj)); + return BOOST_UNORDERED_PAIR_CAST(iterator, bool, + table_.emplace(obj)); + } + + template + std::pair::iterator, bool> + unordered_set::insert(BOOST_RV_REF(value_type) obj) + { + return BOOST_UNORDERED_PAIR_CAST(iterator, bool, + table_.emplace(boost::move(obj))); } template BOOST_DEDUCED_TYPENAME unordered_set::iterator - unordered_set::insert(const_iterator, const value_type& obj) + unordered_set::insert(const_iterator, + value_type const& obj) { return iterator(table_.emplace(obj).first); } + template + BOOST_DEDUCED_TYPENAME unordered_set::iterator + unordered_set::insert(const_iterator, + BOOST_RV_REF(value_type) obj) + { + return iterator(table_.emplace(boost::move(obj)).first); + } + template template void unordered_set::insert(InputIt first, InputIt last) @@ -1169,17 +1213,22 @@ namespace unordered template BOOST_DEDUCED_TYPENAME unordered_multiset::iterator - unordered_multiset::emplace(value_type const& v) + unordered_multiset::emplace( + boost::unordered::detail::empty_emplace, + value_type v + ) { - return iterator(table_.emplace(v)); + return iterator(table_.emplace(boost::move(v))); } template BOOST_DEDUCED_TYPENAME unordered_multiset::iterator - unordered_multiset::emplace_hint( - const_iterator, value_type const& v) + unordered_multiset::emplace_hint(const_iterator, + boost::unordered::detail::empty_emplace, + value_type v + ) { - return iterator(table_.emplace(v)); + return iterator(table_.emplace(boost::move(v))); } #define BOOST_UNORDERED_EMPLACE(z, n, _) \ @@ -1217,18 +1266,34 @@ namespace unordered template BOOST_DEDUCED_TYPENAME unordered_multiset::iterator - unordered_multiset::insert(const value_type& obj) + unordered_multiset::insert(value_type const& obj) { return iterator(table_.emplace(obj)); } template BOOST_DEDUCED_TYPENAME unordered_multiset::iterator - unordered_multiset::insert(const_iterator, const value_type& obj) + unordered_multiset::insert(BOOST_RV_REF(value_type) obj) + { + return iterator(table_.emplace(boost::move(obj))); + } + + template + BOOST_DEDUCED_TYPENAME unordered_multiset::iterator + unordered_multiset::insert(const_iterator, + value_type const& obj) { return iterator(table_.emplace(obj)); } + template + BOOST_DEDUCED_TYPENAME unordered_multiset::iterator + unordered_multiset::insert(const_iterator, + BOOST_RV_REF(value_type) obj) + { + return iterator(table_.emplace(boost::move(obj))); + } + template template void unordered_multiset::insert(InputIt first, InputIt last)