mirror of
https://github.com/boostorg/container.git
synced 2025-08-02 22:14:26 +02:00
Fixed Trac #12014: "boost::container::set can not insert const (ref) range"
This commit is contained in:
@@ -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]
|
||||
|
@@ -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{
|
||||
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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.
|
||||
//!
|
||||
|
@@ -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){
|
||||
{
|
||||
|
@@ -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));
|
||||
|
Reference in New Issue
Block a user