Fixed Trac #12014: "boost::container::set can not insert const (ref) range"

This commit is contained in:
Ion Gaztañaga
2016-02-24 10:13:07 +01:00
parent 33b331da38
commit a7158c7975
6 changed files with 39 additions and 32 deletions

View File

@@ -1221,6 +1221,7 @@ use [*Boost.Container]? There are several reasons for that:
* [@https://svn.boost.org/trac/boost/ticket/11856 Trac #11856 : ['"pool_resource.cpp error: declaration changes meaning"]].
* [@https://svn.boost.org/trac/boost/ticket/11866 Trac #11866 : ['"small_vector does not have range constructor"]].
* [@https://svn.boost.org/trac/boost/ticket/11867 Trac #11867 : ['"small_vector should have constructor and assignment operator taking other small_vector"]].
* [@https://svn.boost.org/trac/boost/ticket/12014 Trac #12014 : ['"boost::container::set can not insert const (ref) range"]].
* [@https://github.com/boostorg/container/pull/33 GitHub #33: ['Make sure std::string constructor is available]].
[endsect]

View File

@@ -317,6 +317,16 @@ struct is_class_or_union< ::boost::container::container_detail::pair<T1, T2> >
static const bool value = true;
};
template <class T1, class T2>
struct is_class_or_union< std::pair<T1, T2> >
//This specialization is needed to avoid instantiation of pair in
//is_class, and allow recursive maps.
{
static const bool value = true;
};
} //namespace move_detail{

View File

@@ -50,6 +50,7 @@
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/move/detail/fwd_macros.hpp>
#endif
#include <boost/move/detail/move_helpers.hpp>
// other
#include <boost/core/no_exceptions_support.hpp>
@@ -526,12 +527,12 @@ class tree
const const_iterator end_it(this->cend());
if(unique_insertion){
for ( ; first != last; ++first){
this->insert_unique(end_it, *first);
this->insert_unique_convertible(end_it, *first);
}
}
else{
for ( ; first != last; ++first){
this->insert_equal(end_it, *first);
this->insert_equal_convertible(end_it, *first);
}
}
}
@@ -555,7 +556,7 @@ class tree
//for the constructor
const const_iterator end_it(this->cend());
for ( ; first != last; ++first){
this->insert_unique(end_it, *first);
this->insert_unique_convertible(end_it, *first);
}
}
else{
@@ -983,19 +984,8 @@ class tree
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
iterator insert_unique(const_iterator hint, const value_type& v)
{
BOOST_ASSERT((priv_is_linked)(hint));
insert_commit_data data;
std::pair<iterator,bool> ret =
this->insert_unique_check(hint, KeyOfValue()(v), data);
if(!ret.second)
return ret.first;
return this->insert_unique_commit(v, data);
}
template<class MovableConvertible>
iterator insert_unique(const_iterator hint, BOOST_FWD_REF(MovableConvertible) v)
iterator insert_unique_convertible(const_iterator hint, BOOST_FWD_REF(MovableConvertible) v)
{
BOOST_ASSERT((priv_is_linked)(hint));
insert_commit_data data;
@@ -1006,6 +996,8 @@ class tree
return this->insert_unique_commit(boost::forward<MovableConvertible>(v), data);
}
BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert_unique, value_type, iterator, this->insert_unique_convertible, const_iterator, const_iterator)
template <class InputIterator>
void insert_unique(InputIterator first, InputIterator last)
{
@@ -1032,18 +1024,8 @@ class tree
return ret;
}
iterator insert_equal(const_iterator hint, const value_type& v)
{
BOOST_ASSERT((priv_is_linked)(hint));
NodePtr tmp(AllocHolder::create_node(v));
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
iterator ret(this->icont().insert_equal(hint.get(), *tmp));
destroy_deallocator.release();
return ret;
}
template<class MovableConvertible>
iterator insert_equal(const_iterator hint, BOOST_FWD_REF(MovableConvertible) v)
iterator insert_equal_convertible(const_iterator hint, BOOST_FWD_REF(MovableConvertible) v)
{
BOOST_ASSERT((priv_is_linked)(hint));
NodePtr tmp(AllocHolder::create_node(boost::forward<MovableConvertible>(v)));
@@ -1053,6 +1035,8 @@ class tree
return ret;
}
BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert_equal, value_type, iterator, this->insert_equal_convertible, const_iterator, const_iterator)
template <class InputIterator>
void insert_equal(InputIterator first, InputIterator last)
{

View File

@@ -596,7 +596,7 @@ class map
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
//! is inserted right before p.
iterator insert(const_iterator p, BOOST_RV_REF(nonconst_value_type) x)
{ return this->base_t::insert_unique(p, boost::move(x)); }
{ return this->base_t::insert_unique_convertible(p, boost::move(x)); }
//! <b>Effects</b>: Move constructs a new value from x if and only if there is
//! no element in the container with key equivalent to the key of x.
@@ -608,7 +608,7 @@ class map
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
//! is inserted right before p.
iterator insert(const_iterator p, BOOST_RV_REF(movable_value_type) x)
{ return this->base_t::insert_unique(p, boost::move(x)); }
{ return this->base_t::insert_unique_convertible(p, boost::move(x)); }
//! <b>Effects</b>: Inserts a copy of x in the container.
//! p is a hint pointing to where the insert should start to search.
@@ -617,7 +617,7 @@ class map
//!
//! <b>Complexity</b>: Logarithmic.
iterator insert(const_iterator p, const nonconst_value_type& x)
{ return this->base_t::insert_unique(p, x); }
{ return this->base_t::insert_unique_convertible(p, x); }
//! <b>Effects</b>: Inserts an element move constructed from x in the container.
//! p is a hint pointing to where the insert should start to search.
@@ -1291,7 +1291,7 @@ class multimap
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
//! is inserted right before p.
iterator insert(const_iterator p, const nonconst_value_type& x)
{ return this->base_t::insert_equal(p, x); }
{ return this->base_t::insert_equal_convertible(p, x); }
//! <b>Effects</b>: Inserts a new value move constructed from x in the container.
//! p is a hint pointing to where the insert should start to search.
@@ -1302,7 +1302,7 @@ class multimap
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
//! is inserted right before p.
iterator insert(const_iterator p, BOOST_RV_REF(nonconst_value_type) x)
{ return this->base_t::insert_equal(p, boost::move(x)); }
{ return this->base_t::insert_equal_convertible(p, boost::move(x)); }
//! <b>Effects</b>: Inserts a new value move constructed from x in the container.
//! p is a hint pointing to where the insert should start to search.
@@ -1313,7 +1313,7 @@ class multimap
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
//! is inserted right before p.
iterator insert(const_iterator p, BOOST_RV_REF(movable_value_type) x)
{ return this->base_t::insert_equal(p, boost::move(x)); }
{ return this->base_t::insert_equal_convertible(p, boost::move(x)); }
//! <b>Requires</b>: first, last are not iterators into *this.
//!

View File

@@ -79,6 +79,12 @@ int map_test_copyable(boost::container::container_detail::true_type)
MyBoostMultiMap &boostmultimap = *pboostmultimap;
MyStdMultiMap &stdmultimap = *pstdmultimap;
//Just to test move aware catch conversions
boostmap.insert(boostmap.cbegin(), boostmap.cend());
boostmultimap.insert(boostmultimap.cbegin(), boostmultimap.cend());
boostmap.insert(boostmap.begin(), boostmap.end());
boostmultimap.insert(boostmultimap.begin(), boostmultimap.end());
int i;
for(i = 0; i < max; ++i){
{

View File

@@ -65,6 +65,12 @@ int set_test_copyable(boost::container::container_detail::true_type)
MyBoostMultiSet &boostmultiset = *pboostmultiset;
MyStdMultiSet &stdmultiset = *pstdmultiset;
//Just to test move aware catch conversions
boostset.insert(boostset.cbegin(), boostset.cend());
boostmultiset.insert(boostmultiset.cbegin(), boostmultiset.cend());
boostset.insert(boostset.begin(), boostset.end());
boostmultiset.insert(boostmultiset.begin(), boostmultiset.end());
for(int i = 0; i < max; ++i){
IntType move_me(i);
boostset.insert(boost::move(move_me));