diff --git a/doc/container.qbk b/doc/container.qbk index 53d62e5..0ab4a5c 100644 --- a/doc/container.qbk +++ b/doc/container.qbk @@ -1244,7 +1244,9 @@ use [*Boost.Container]? There are several reasons for that: [section:release_notes_boost_1_71_00 Boost 1.71 Release] * [@https://github.com/boostorg/container/pull/109 GitHub #109: ['"Get rid of integer overflow in copy_move_algo.hpp (-fsanitize=integer)"]]. + * [@https://github.com/boostorg/container/pull/110 GitHub #110: ['"Avoid gcc 9 deprecated copy warnings in new_allocator.hpp"]]. * [@https://github.com/boostorg/container/issues/112 GitHub #112: ['"vector::resize() compilation error with msvc-10..12: data is not a member of boost::detail::aligned_storage"]]. + * [@https://github.com/boostorg/container/issues/117 GitHub #117: ['"flat_map/map::insert_or_assign with hint has wrong return types"]]. [endsect] @@ -1260,6 +1262,7 @@ use [*Boost.Container]? There are several reasons for that: * [@https://github.com/boostorg/container/pull/103 GitHub #103: ['"Fix deallocating never-allocated storage in vector.merge()"]]. * [@https://github.com/boostorg/container/pull/104 GitHub #104: ['"Fix -Wmissing-noreturn clang warnings"]]. * [@https://github.com/boostorg/container/pull/105 GitHub #105: ['"Fix gcc -Wdeprecated-copy"]]. + * [@https://github.com/boostorg/container/issues/111 GitHub #111: ['"container::vector of interprocess::offset_ptrs to variants holding incomplete type"]]. [endsect] diff --git a/include/boost/container/flat_map.hpp b/include/boost/container/flat_map.hpp index 283ab33..2b52e14 100644 --- a/include/boost/container/flat_map.hpp +++ b/include/boost/container/flat_map.hpp @@ -788,12 +788,12 @@ class flat_map //! Complexity: Logarithmic in the size of the container in general, but amortized constant if //! the new element is inserted just before hint. template - BOOST_CONTAINER_FORCEINLINE std::pair insert_or_assign(const_iterator hint, const key_type& k, BOOST_FWD_REF(M) obj) + BOOST_CONTAINER_FORCEINLINE iterator insert_or_assign(const_iterator hint, const key_type& k, BOOST_FWD_REF(M) obj) { - return dtl::force_copy< std::pair > + return dtl::force_copy (this->m_flat_tree.insert_or_assign ( dtl::force_copy(hint) - , k, ::boost::forward(obj)) + , k, ::boost::forward(obj)).first ); } @@ -812,12 +812,12 @@ class flat_map //! Complexity: Logarithmic in the size of the container in general, but amortized constant if //! the new element is inserted just before hint. template - BOOST_CONTAINER_FORCEINLINE std::pair insert_or_assign(const_iterator hint, BOOST_RV_REF(key_type) k, BOOST_FWD_REF(M) obj) + BOOST_CONTAINER_FORCEINLINE iterator insert_or_assign(const_iterator hint, BOOST_RV_REF(key_type) k, BOOST_FWD_REF(M) obj) { - return dtl::force_copy< std::pair > + return dtl::force_copy (this->m_flat_tree.insert_or_assign ( dtl::force_copy(hint) - , ::boost::move(k), ::boost::forward(obj)) + , ::boost::move(k), ::boost::forward(obj)).first ); } diff --git a/include/boost/container/map.hpp b/include/boost/container/map.hpp index a21228b..d0c8fc9 100644 --- a/include/boost/container/map.hpp +++ b/include/boost/container/map.hpp @@ -629,7 +629,7 @@ class map //! the new element is inserted just before hint. template BOOST_CONTAINER_FORCEINLINE iterator insert_or_assign(const_iterator hint, const key_type& k, BOOST_FWD_REF(M) obj) - { return this->base_t::insert_or_assign(hint, k, ::boost::forward(obj)); } + { return this->base_t::insert_or_assign(hint, k, ::boost::forward(obj)).first; } //! Effects: If a key equivalent to k already exists in the container, assigns forward(obj) //! to the mapped_type corresponding to the key k. If the key does not exist, inserts the new value @@ -647,7 +647,7 @@ class map //! the new element is inserted just before hint. template BOOST_CONTAINER_FORCEINLINE iterator insert_or_assign(const_iterator hint, BOOST_RV_REF(key_type) k, BOOST_FWD_REF(M) obj) - { return this->base_t::insert_or_assign(hint, ::boost::move(k), ::boost::forward(obj)); } + { return this->base_t::insert_or_assign(hint, ::boost::move(k), ::boost::forward(obj)).first; } //! Returns: A reference to the element whose key is equivalent to x. //! Throws: An exception object of type out_of_range if no such element is present. diff --git a/test/check_equal_containers.hpp b/test/check_equal_containers.hpp index 80a35da..758780a 100644 --- a/test/check_equal_containers.hpp +++ b/test/check_equal_containers.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -130,6 +131,25 @@ struct equal_transparent } }; +struct move_op +{ + template + typename boost::move_detail::add_rvalue_reference::type operator()(T &t) + { + return boost::move(t); + } +}; + +struct const_ref_op +{ + template + const T & operator()(const T &t) + { + return t; + } + +}; + } //namespace test{ } //namespace container { } //namespace boost{ diff --git a/test/map_test.hpp b/test/map_test.hpp index 3d26e3a..99bd42d 100644 --- a/test/map_test.hpp +++ b/test/map_test.hpp @@ -763,56 +763,124 @@ int map_test_indexing(MyBoostMap &boostmap, MyStdMap &stdmap, MyBoostMultiMap &b return 0; } - - -template -int map_test_insert_or_assign(MyBoostMap &boostmap, MyStdMap &stdmap, MyBoostMultiMap &boostmultimap, MyStdMultiMap &stdmultimap) +template< class MyBoostMap, class StdMap, class MaybeMove> +int map_test_insert_or_assign_impl() { - typedef typename MyBoostMap::key_type IntType; - typedef dtl::pair IntPairType; + typedef typename MyBoostMap::key_type IntType; + typedef dtl::pair IntPairType; + typedef typename MyBoostMap::iterator Biterator; + typedef std::pair Bpair; + + MaybeMove maybe_move; { //insert_or_assign test - boostmap.clear(); - boostmultimap.clear(); - stdmap.clear(); - stdmultimap.clear(); - + MyBoostMap boostmap; + StdMap stdmap; IntPairType aux_vect[MaxElem]; for(int i = 0; i < MaxElem; ++i){ IntType i1(i); - IntType i2(i); - new(&aux_vect[i])IntPairType(boost::move(i1), boost::move(i2)); + IntType i2(MaxElem-i); + new(&aux_vect[i])IntPairType(maybe_move(i1), maybe_move(i2)); } IntPairType aux_vect2[MaxElem]; for(int i = 0; i < MaxElem; ++i){ IntType i1(i); - IntType i2(MaxElem-i); - new(&aux_vect2[i])IntPairType(boost::move(i1), boost::move(i2)); + IntType i2(i); + new(&aux_vect2[i])IntPairType(maybe_move(i1), maybe_move(i2)); } for(int i = 0; i < MaxElem; ++i){ - boostmap.insert_or_assign(boost::move(aux_vect[i].first), boost::move(aux_vect[i].second)); - stdmap[i] = i; - } - - if(!CheckEqualPairContainers(boostmap, stdmap)) return 1; - if(!CheckEqualPairContainers(boostmultimap, stdmultimap)) return 1; - - for(int i = 0; i < MaxElem; ++i){ - boostmap.insert_or_assign(boost::move(aux_vect2[i].first), boost::move(aux_vect2[i].second)); + Bpair r = boostmap.insert_or_assign(maybe_move(aux_vect[i].first), maybe_move(aux_vect[i].second)); stdmap[i] = MaxElem-i; + if(!r.second) + return 1; + const IntType key(i); + if(r.first->first != key) + return 1; + const IntType mapped(MaxElem-i); + if(r.first->second != mapped) + return 1; + } + + if(!CheckEqualPairContainers(boostmap, stdmap)) return 1; + + for(int i = 0; i < MaxElem; ++i){ + Bpair r = boostmap.insert_or_assign(maybe_move(aux_vect2[i].first), maybe_move(aux_vect2[i].second)); + stdmap[i] = i; + if(r.second) + return 1; + const IntType key(i); + if(r.first->first != key) + return 1; + const IntType mapped(i); + if(r.first->second != mapped) + return 1; + } + + if(!CheckEqualPairContainers(boostmap, stdmap)) return 1; + } + { //insert_or_assign test with hint + MyBoostMap boostmap; + StdMap stdmap; + IntPairType aux_vect[MaxElem]; + for(int i = 0; i < MaxElem; ++i){ + IntType i1(i); + IntType i2(MaxElem-i); + new(&aux_vect[i])IntPairType(maybe_move(i1), maybe_move(i2)); + } + + IntPairType aux_vect2[MaxElem]; + for(int i = 0; i < MaxElem; ++i){ + IntType i1(i); + IntType i2(i); + new(&aux_vect2[i])IntPairType(maybe_move(i1), maybe_move(i2)); + } + + for(int i = 0; i < MaxElem; ++i){ + Biterator r = boostmap.insert_or_assign(boostmap.end(), maybe_move(aux_vect[i].first), maybe_move(aux_vect[i].second)); + stdmap[i] = MaxElem-i; + const IntType key(i); + if(r->first != key) + return 1; + const IntType mapped(MaxElem-i); + if(r->second != mapped) + return 1; + } + + if(!CheckEqualPairContainers(boostmap, stdmap)) return 1; + + for(int i = 0; i < MaxElem; ++i){ + Biterator r = boostmap.insert_or_assign(boostmap.end(), maybe_move(aux_vect2[i].first), maybe_move(aux_vect2[i].second)); + stdmap[i] = i; + const IntType key(i); + if(r->first != key) + return 1; + const IntType mapped(i); + if(r->second != mapped) + return 1; } if(!CheckEqualPairContainers(boostmap, stdmap)) return 1; - if(!CheckEqualPairContainers(boostmultimap, stdmultimap)) return 1; } return 0; } +template< class MyBoostMap, class StdMap> +int map_test_insert_or_assign(dtl::bool_ )//noncopyable +{ + return map_test_insert_or_assign_impl(); +} + +template< class MyBoostMap, class StdMap> +int map_test_insert_or_assign(dtl::bool_ )//copyable +{ + int r = map_test_insert_or_assign_impl(); + if (r) + r = map_test_insert_or_assign_impl(); + return r; +} + template< class MyBoostMap , class MyStdMap , class MyBoostMultiMap @@ -822,7 +890,7 @@ int map_test_try_emplace(MyBoostMap &boostmap, MyStdMap &stdmap, MyBoostMultiMap typedef typename MyBoostMap::key_type IntType; typedef dtl::pair IntPairType; - { //try_emplace + { //try_emplace boostmap.clear(); boostmultimap.clear(); stdmap.clear(); @@ -1028,6 +1096,7 @@ int map_test() MyStdMap &stdmap = *pstdmap; MyBoostMultiMap &boostmultimap = *pboostmultimap; MyStdMultiMap &stdmultimap = *pstdmultimap; + typedef dtl::bool_::value> copyable_t; if (map_test_step(boostmap, stdmap, boostmultimap, stdmultimap)) return 1; @@ -1047,19 +1116,17 @@ int map_test() if (map_test_indexing(boostmap, stdmap, boostmultimap, stdmultimap)) return 1; - if (map_test_insert_or_assign(boostmap, stdmap, boostmultimap, stdmultimap)) - return 1; - if (map_test_try_emplace(boostmap, stdmap, boostmultimap, stdmultimap)) return 1; if (map_test_merge(boostmap, stdmap, boostmultimap, stdmultimap)) return 1; - if(map_test_copyable - (dtl::bool_::value>())){ + if (map_test_insert_or_assign(copyable_t())) + return 1; + + if(map_test_copyable(copyable_t())) return 1; - } return 0; }