diff --git a/doc/unordered/unordered_map.adoc b/doc/unordered/unordered_map.adoc index fa1d7803..ad9d71ca 100644 --- a/doc/unordered/unordered_map.adoc +++ b/doc/unordered/unordered_map.adoc @@ -875,7 +875,7 @@ Removes the element pointed to by `position`. [horizontal] Returns:;; A `node_type` owning the element. -Notes:;; In C++17 a node extracted using this method can be inserted into a compatible `unordered_multimap`, but that is not supported yet. +Notes:;; A node extracted using this method can be inserted into a compatible `unordered_multimap`. --- @@ -889,7 +889,7 @@ Removes an element with key equivalent to `k`. [horizontal] Returns:;; A `node_type` owning the element if found, otherwise an empty `node_type`. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. -Notes:;; In C++17 a node extracted using this method can be inserted into a compatible `unordered_multimap`, but that is not supported yet. +Notes:;; A node extracted using this method can be inserted into a compatible `unordered_multimap`. --- @@ -905,7 +905,7 @@ This overload only participates in overload resolution if `Hash::is_transparent` [horizontal] Returns:;; A `node_type` owning the element if found, otherwise an empty `node_type`. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. -Notes:;; In C++17 a node extracted using this method can be inserted into a compatible `unordered_multimap`, but that is not supported yet. +Notes:;; A node extracted using this method can be inserted into a compatible `unordered_multimap`. --- @@ -930,7 +930,7 @@ Notes:;; Can invalidate iterators, but only if the insert causes the load factor + Pointers and references to elements are never invalidated. + + -In C++17 this can be used to insert a node extracted from a compatible `unordered_multimap`, but that is not supported yet. +This can be used to insert a node extracted from a compatible `unordered_multimap`. --- @@ -961,7 +961,7 @@ Can invalidate iterators, but only if the insert causes the load factor to be gr + Pointers and references to elements are never invalidated. + + -In C++17 this can be used to insert a node extracted from a compatible `unordered_multimap`, but that is not supported yet. +This can be used to insert a node extracted from a compatible `unordered_multimap`. --- diff --git a/doc/unordered/unordered_multimap.adoc b/doc/unordered/unordered_multimap.adoc index 1eb9963c..be204074 100644 --- a/doc/unordered/unordered_multimap.adoc +++ b/doc/unordered/unordered_multimap.adoc @@ -850,7 +850,7 @@ Removes the element pointed to by `position`. [horizontal] Returns:;; A `node_type` owning the element. -Notes:;; In C++17 a node extracted using this method can be inserted into a compatible `unordered_map`, but that is not supported yet. +Notes:;; A node extracted using this method can be inserted into a compatible `unordered_map`. --- @@ -864,7 +864,7 @@ Removes an element with key equivalent to `k`. [horizontal] Returns:;; A `node_type` owning the element if found, otherwise an empty `node_type`. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. -Notes:;; In C++17 a node extracted using this method can be inserted into a compatible `unordered_map`, but that is not supported yet. +Notes:;; A node extracted using this method can be inserted into a compatible `unordered_map`. --- @@ -880,7 +880,7 @@ This overload only participates in overload resolution if `Hash::is_transparent` [horizontal] Returns:;; A `node_type` owning the element if found, otherwise an empty `node_type`. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. -Notes:;; In C++17 a node extracted using this method can be inserted into a compatible `unordered_map`, but that is not supported yet. +Notes:;; A node extracted using this method can be inserted into a compatible `unordered_map`. --- @@ -903,7 +903,7 @@ Notes:;; Can invalidate iterators, but only if the insert causes the load factor + Pointers and references to elements are never invalidated. + + -In C++17 this can be used to insert a node extracted from a compatible `unordered_map`, but that is not supported yet. +This can be used to insert a node extracted from a compatible `unordered_map`. --- @@ -930,7 +930,7 @@ Can invalidate iterators, but only if the insert causes the load factor to be gr + Pointers and references to elements are never invalidated. + + -In C++17 this can be used to insert a node extracted from a compatible `unordered_map`, but that is not supported yet. +This can be used to insert a node extracted from a compatible `unordered_map`. --- diff --git a/doc/unordered/unordered_multiset.adoc b/doc/unordered/unordered_multiset.adoc index c42e36c2..6325ca51 100644 --- a/doc/unordered/unordered_multiset.adoc +++ b/doc/unordered/unordered_multiset.adoc @@ -810,7 +810,7 @@ Removes the element pointed to by `position`. [horizontal] Returns:;; A `node_type` owning the element. -Notes:;; In C++17 a node extracted using this method can be inserted into a compatible `unordered_set`, but that is not supported yet. +Notes:;; A node extracted using this method can be inserted into a compatible `unordered_set`. --- @@ -824,7 +824,7 @@ Removes an element with key equivalent to `k`. [horizontal] Returns:;; A `node_type` owning the element if found, otherwise an empty `node_type`. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. -Notes:;; In C++17 a node extracted using this method can be inserted into a compatible `unordered_set`, but that is not supported yet. +Notes:;; A node extracted using this method can be inserted into a compatible `unordered_set`. --- @@ -840,7 +840,7 @@ This overload only participates in overload resolution if `Hash::is_transparent` [horizontal] Returns:;; A `node_type` owning the element if found, otherwise an empty `node_type`. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`.[horizontal] -Notes:;; In C++17 a node extracted using this method can be inserted into a compatible `unordered_set`, but that is not supported yet. +Notes:;; A node extracted using this method can be inserted into a compatible `unordered_set`. --- @@ -861,7 +861,9 @@ Otherwise returns an iterator pointing to the newly inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + -Pointers and references to elements are never invalidated. In C++17 this can be used to insert a node extracted from a compatible `unordered_set`, but that is not supported yet. +Pointers and references to elements are never invalidated. + ++ +This can be used to insert a node extracted from a compatible `unordered_set`. --- @@ -888,7 +890,7 @@ Can invalidate iterators, but only if the insert causes the load factor to be gr + Pointers and references to elements are never invalidated. + + -In C++17 this can be used to insert a node extracted from a compatible `unordered_set`, but that is not supported yet. +This can be used to insert a node extracted from a compatible `unordered_set`. --- diff --git a/doc/unordered/unordered_set.adoc b/doc/unordered/unordered_set.adoc index e9634ec2..01b6b612 100644 --- a/doc/unordered/unordered_set.adoc +++ b/doc/unordered/unordered_set.adoc @@ -912,7 +912,7 @@ Can invalidate iterators, but only if the insert causes the load factor to be gr + Pointers and references to elements are never invalidated. + + -In C++17 this can be used to insert a node extracted from a compatible `unordered_multiset`, but that is not supported yet. +This can be used to insert a node extracted from a compatible `unordered_multiset`. --- diff --git a/test/unordered/node_handle_tests.cpp b/test/unordered/node_handle_tests.cpp index 2d5b1eab..89648d0f 100644 --- a/test/unordered/node_handle_tests.cpp +++ b/test/unordered/node_handle_tests.cpp @@ -245,6 +245,49 @@ UNORDERED_AUTO_TEST (node_handle_tests) { node_handle_tests_impl(x2); } +template +typename boost::unordered_map::iterator +insert_empty_node(boost::unordered_map& c) +{ + typedef + typename boost::unordered_map::node_type + node_type; + + return c.insert(node_type()).position; +} + +template +typename boost::unordered_set::iterator +insert_empty_node(boost::unordered_set& c) +{ + typedef typename boost::unordered_set::node_type + node_type; + + return c.insert(node_type()).position; +} + +template +typename boost::unordered_multimap::iterator +insert_empty_node( + boost::unordered_multimap& c) +{ + typedef typename boost::unordered_multimap::node_type node_type; + + return c.insert(node_type()); +} + +template +typename boost::unordered_multiset::iterator +insert_empty_node(boost::unordered_multiset& c) +{ + typedef + typename boost::unordered_multiset::node_type + node_type; + + return c.insert(node_type()); +} + template void insert_node_handle_unique(Container1& c1, Container2& c2) { @@ -253,14 +296,12 @@ void insert_node_handle_unique(Container1& c1, Container2& c2) BOOST_STATIC_ASSERT( (boost::is_same::value)); - typedef typename Container1::insert_return_type insert_return_type1; + typedef typename Container1::iterator iterator1; typedef typename Container2::insert_return_type insert_return_type2; - insert_return_type1 r1 = c1.insert(node_type()); + iterator1 r1 = insert_empty_node(c1); insert_return_type2 r2 = c2.insert(node_type()); - BOOST_TEST(!r1.inserted); - BOOST_TEST(!r1.node); - BOOST_TEST(r1.position == c1.end()); + BOOST_TEST(r1 == c1.end()); BOOST_TEST(!r2.inserted); BOOST_TEST(!r2.node); BOOST_TEST(r2.position == c2.end()); @@ -332,7 +373,7 @@ void insert_node_handle_equiv(Container1& c1, Container2& c2) typedef typename Container1::iterator iterator1; typedef typename Container2::iterator iterator2; - iterator1 r1 = c1.insert(node_type()); + iterator1 r1 = insert_empty_node(c1); iterator2 r2 = c2.insert(node_type()); BOOST_TEST(r1 == c1.end()); BOOST_TEST(r2 == c2.end()); @@ -368,6 +409,17 @@ UNORDERED_AUTO_TEST (insert_node_handle_unique_tests) { BOOST_TEST(x2.size() == 3); } + { + boost::unordered_multiset x1; + boost::unordered_set x2; + x1.emplace(100); + x1.emplace(140); + x1.emplace(-55); + x2.emplace(140); + insert_node_handle_unique(x1, x2); + BOOST_TEST(x2.size() == 3); + } + { boost::unordered_map x1; boost::unordered_map x2; @@ -379,6 +431,18 @@ UNORDERED_AUTO_TEST (insert_node_handle_unique_tests) { insert_node_handle_unique(x1, x2); BOOST_TEST(x2.size() == 4); } + + { + boost::unordered_multimap x1; + boost::unordered_map x2; + x1.emplace(67, 50); + x1.emplace(23, 45); + x1.emplace(18, 19); + x2.emplace(23, 50); + x2.emplace(12, 49); + insert_node_handle_unique(x1, x2); + BOOST_TEST(x2.size() == 4); + } } UNORDERED_AUTO_TEST (insert_node_handle_equiv_tests) { @@ -394,6 +458,45 @@ UNORDERED_AUTO_TEST (insert_node_handle_equiv_tests) { insert_node_handle_equiv(x1, x2); BOOST_TEST(x2.size() == 6); } + + { + boost::unordered_map x1; + boost::unordered_multimap x2; + x1.emplace(67, 50); + x1.emplace(67, 100); + x1.emplace(23, 45); + x1.emplace(18, 19); + x2.emplace(23, 50); + x2.emplace(12, 49); + insert_node_handle_equiv(x1, x2); + BOOST_TEST(x2.size() == 5); + } + + { + boost::unordered_multiset x1; + boost::unordered_multiset x2; + x1.emplace(67); + x1.emplace(67); + x1.emplace(23); + x1.emplace(18); + x2.emplace(23); + x2.emplace(12); + insert_node_handle_equiv(x1, x2); + BOOST_TEST(x2.size() == 6); + } + + { + boost::unordered_set x1; + boost::unordered_multiset x2; + x1.emplace(67); + x1.emplace(67); + x1.emplace(23); + x1.emplace(18); + x2.emplace(23); + x2.emplace(12); + insert_node_handle_equiv(x1, x2); + BOOST_TEST(x2.size() == 5); + } } UNORDERED_AUTO_TEST (insert_node_handle_unique_tests2) { @@ -408,6 +511,17 @@ UNORDERED_AUTO_TEST (insert_node_handle_unique_tests2) { BOOST_TEST(x2.size() == 3); } + { + boost::unordered_multiset x1; + boost::unordered_set x2; + x1.emplace(100); + x1.emplace(140); + x1.emplace(-55); + x2.emplace(140); + insert_node_handle_unique2(x1, x2); + BOOST_TEST(x2.size() == 3); + } + { boost::unordered_map x1; boost::unordered_map x2; @@ -419,6 +533,18 @@ UNORDERED_AUTO_TEST (insert_node_handle_unique_tests2) { insert_node_handle_unique2(x1, x2); BOOST_TEST(x2.size() == 4); } + + { + boost::unordered_multimap x1; + boost::unordered_map x2; + x1.emplace(67, 50); + x1.emplace(23, 45); + x1.emplace(18, 19); + x2.emplace(23, 50); + x2.emplace(12, 49); + insert_node_handle_unique2(x1, x2); + BOOST_TEST(x2.size() == 4); + } } RUN_TESTS()