Fixes #117 ("flat_map/map::insert_or_assign with hint has wrong return types")

This commit is contained in:
Ion Gaztañaga
2019-04-23 17:03:09 +02:00
parent 690bb0a852
commit e46210e046
5 changed files with 133 additions and 43 deletions

View File

@@ -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]

View File

@@ -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 <class M>
BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> 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<iterator, bool> >
return dtl::force_copy<iterator>
(this->m_flat_tree.insert_or_assign
( dtl::force_copy<impl_const_iterator>(hint)
, k, ::boost::forward<M>(obj))
, k, ::boost::forward<M>(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 <class M>
BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> 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<iterator, bool> >
return dtl::force_copy<iterator>
(this->m_flat_tree.insert_or_assign
( dtl::force_copy<impl_const_iterator>(hint)
, ::boost::move(k), ::boost::forward<M>(obj))
, ::boost::move(k), ::boost::forward<M>(obj)).first
);
}

View File

@@ -629,7 +629,7 @@ class map
//! the new element is inserted just before hint.
template <class M>
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<M>(obj)); }
{ return this->base_t::insert_or_assign(hint, k, ::boost::forward<M>(obj)).first; }
//! <b>Effects</b>: If a key equivalent to k already exists in the container, assigns forward<M>(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 <class M>
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<M>(obj)); }
{ return this->base_t::insert_or_assign(hint, ::boost::move(k), ::boost::forward<M>(obj)).first; }
//! <b>Returns</b>: 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.

View File

@@ -15,6 +15,7 @@
#include <boost/container/detail/pair.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/move/unique_ptr.hpp>
#include <boost/move/utility_core.hpp>
#include <cstddef>
#include <boost/container/detail/iterator.hpp>
@@ -130,6 +131,25 @@ struct equal_transparent
}
};
struct move_op
{
template<class T>
typename boost::move_detail::add_rvalue_reference<T>::type operator()(T &t)
{
return boost::move(t);
}
};
struct const_ref_op
{
template<class T>
const T & operator()(const T &t)
{
return t;
}
};
} //namespace test{
} //namespace container {
} //namespace boost{

View File

@@ -763,56 +763,124 @@ int map_test_indexing(MyBoostMap &boostmap, MyStdMap &stdmap, MyBoostMultiMap &b
return 0;
}
template<class MyBoostMap
, class MyStdMap
, class MyBoostMultiMap
, class MyStdMultiMap>
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<IntType, IntType> IntPairType;
typedef typename MyBoostMap::key_type IntType;
typedef dtl::pair<IntType, IntType> IntPairType;
typedef typename MyBoostMap::iterator Biterator;
typedef std::pair<Biterator, bool> 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_<false> )//noncopyable
{
return map_test_insert_or_assign_impl<MyBoostMap, StdMap, move_op>();
}
template< class MyBoostMap, class StdMap>
int map_test_insert_or_assign(dtl::bool_<true> )//copyable
{
int r = map_test_insert_or_assign_impl<MyBoostMap, StdMap, const_ref_op>();
if (r)
r = map_test_insert_or_assign_impl<MyBoostMap, StdMap, move_op>();
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<IntType, IntType> 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_<boost::container::test::is_copyable<IntType>::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<MyBoostMap, MyStdMap, MyBoostMultiMap, MyStdMultiMap>
(dtl::bool_<boost::container::test::is_copyable<IntType>::value>())){
if (map_test_insert_or_assign<MyBoostMap, MyStdMap>(copyable_t()))
return 1;
if(map_test_copyable<MyBoostMap, MyStdMap, MyBoostMultiMap, MyStdMultiMap>(copyable_t()))
return 1;
}
return 0;
}