mirror of
https://github.com/boostorg/container.git
synced 2025-08-02 14:04:26 +02:00
Fix for Trac #11820 ("compiler error when using operator[] of map")
This commit is contained in:
@@ -1216,6 +1216,7 @@ use [*Boost.Container]? There are several reasons for that:
|
|||||||
[section:release_notes_boost_1_61_00 Boost 1.61 Release]
|
[section:release_notes_boost_1_61_00 Boost 1.61 Release]
|
||||||
|
|
||||||
* Fixed bugs:
|
* Fixed bugs:
|
||||||
|
* [@https://svn.boost.org/trac/boost/ticket/11820 Trac #11820 : ['"compilier error when using operator[] of map"]].
|
||||||
* [@https://svn.boost.org/trac/boost/ticket/11856 Trac #11856 : ['"pool_resource.cpp error: declaration changes meaning"]].
|
* [@https://svn.boost.org/trac/boost/ticket/11856 Trac #11856 : ['"pool_resource.cpp error: declaration changes meaning"]].
|
||||||
* [@https://github.com/boostorg/container/pull/33 GitHub #33: ['Make sure std::string constructor is available]].
|
* [@https://github.com/boostorg/container/pull/33 GitHub #33: ['Make sure std::string constructor is available]].
|
||||||
|
|
||||||
|
@@ -60,14 +60,17 @@ struct node_alloc_holder
|
|||||||
{
|
{
|
||||||
//If the intrusive container is an associative container, obtain the predicate, which will
|
//If the intrusive container is an associative container, obtain the predicate, which will
|
||||||
//be of type node_compare<>. If not an associative container value_compare will be a "nat" type.
|
//be of type node_compare<>. If not an associative container value_compare will be a "nat" type.
|
||||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, ICont,
|
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
|
||||||
value_compare, container_detail::nat) intrusive_value_compare;
|
( boost::container::container_detail::
|
||||||
|
, ICont, value_compare, container_detail::nat) intrusive_value_compare;
|
||||||
//In that case obtain the value predicate from the node predicate via predicate_type
|
//In that case obtain the value predicate from the node predicate via predicate_type
|
||||||
//if intrusive_value_compare is node_compare<>, nat otherwise
|
//if intrusive_value_compare is node_compare<>, nat otherwise
|
||||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, intrusive_value_compare,
|
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
|
||||||
predicate_type, container_detail::nat) value_compare;
|
( boost::container::container_detail::
|
||||||
|
, intrusive_value_compare
|
||||||
|
, predicate_type, container_detail::nat) value_compare;
|
||||||
|
|
||||||
typedef allocator_traits<Allocator> allocator_traits_type;
|
typedef allocator_traits<Allocator> allocator_traits_type;
|
||||||
typedef typename allocator_traits_type::value_type value_type;
|
typedef typename allocator_traits_type::value_type value_type;
|
||||||
typedef ICont intrusive_container;
|
typedef ICont intrusive_container;
|
||||||
typedef typename ICont::value_type Node;
|
typedef typename ICont::value_type Node;
|
||||||
@@ -75,19 +78,19 @@ struct node_alloc_holder
|
|||||||
portable_rebind_alloc<Node>::type NodeAlloc;
|
portable_rebind_alloc<Node>::type NodeAlloc;
|
||||||
typedef allocator_traits<NodeAlloc> node_allocator_traits_type;
|
typedef allocator_traits<NodeAlloc> node_allocator_traits_type;
|
||||||
typedef container_detail::allocator_version_traits<NodeAlloc> node_allocator_version_traits_type;
|
typedef container_detail::allocator_version_traits<NodeAlloc> node_allocator_version_traits_type;
|
||||||
typedef Allocator ValAlloc;
|
typedef Allocator ValAlloc;
|
||||||
typedef typename node_allocator_traits_type::pointer NodePtr;
|
typedef typename node_allocator_traits_type::pointer NodePtr;
|
||||||
typedef container_detail::scoped_deallocator<NodeAlloc> Deallocator;
|
typedef container_detail::scoped_deallocator<NodeAlloc> Deallocator;
|
||||||
typedef typename node_allocator_traits_type::size_type size_type;
|
typedef typename node_allocator_traits_type::size_type size_type;
|
||||||
typedef typename node_allocator_traits_type::difference_type difference_type;
|
typedef typename node_allocator_traits_type::difference_type difference_type;
|
||||||
typedef container_detail::integral_constant<unsigned,
|
typedef container_detail::integral_constant<unsigned,
|
||||||
boost::container::container_detail::
|
boost::container::container_detail::
|
||||||
version<NodeAlloc>::value> alloc_version;
|
version<NodeAlloc>::value> alloc_version;
|
||||||
typedef typename ICont::iterator icont_iterator;
|
typedef typename ICont::iterator icont_iterator;
|
||||||
typedef typename ICont::const_iterator icont_citerator;
|
typedef typename ICont::const_iterator icont_citerator;
|
||||||
typedef allocator_destroyer<NodeAlloc> Destroyer;
|
typedef allocator_destroyer<NodeAlloc> Destroyer;
|
||||||
typedef allocator_traits<NodeAlloc> NodeAllocTraits;
|
typedef allocator_traits<NodeAlloc> NodeAllocTraits;
|
||||||
typedef allocator_version_traits<NodeAlloc> AllocVersionTraits;
|
typedef allocator_version_traits<NodeAlloc> AllocVersionTraits;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BOOST_COPYABLE_AND_MOVABLE(node_alloc_holder)
|
BOOST_COPYABLE_AND_MOVABLE(node_alloc_holder)
|
||||||
@@ -208,6 +211,29 @@ struct node_alloc_holder
|
|||||||
return (p);
|
return (p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class KeyConvertible>
|
||||||
|
NodePtr create_node_from_key(BOOST_FWD_REF(KeyConvertible) key)
|
||||||
|
{
|
||||||
|
NodePtr p = this->allocate_one();
|
||||||
|
NodeAlloc &na = this->node_alloc();
|
||||||
|
Deallocator node_deallocator(p, this->node_alloc());
|
||||||
|
node_allocator_traits_type::construct
|
||||||
|
(na, container_detail::addressof(p->m_data.first), boost::forward<KeyConvertible>(key));
|
||||||
|
BOOST_TRY{
|
||||||
|
node_allocator_traits_type::construct(na, container_detail::addressof(p->m_data.second));
|
||||||
|
}
|
||||||
|
BOOST_CATCH(...){
|
||||||
|
node_allocator_traits_type::destroy(na, container_detail::addressof(p->m_data.first));
|
||||||
|
BOOST_RETHROW;
|
||||||
|
}
|
||||||
|
BOOST_CATCH_END
|
||||||
|
node_deallocator.release();
|
||||||
|
//This does not throw
|
||||||
|
typedef typename Node::hook_type hook_type;
|
||||||
|
::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
|
||||||
|
return (p);
|
||||||
|
}
|
||||||
|
|
||||||
void destroy_node(const NodePtr &nodep)
|
void destroy_node(const NodePtr &nodep)
|
||||||
{
|
{
|
||||||
allocator_traits<NodeAlloc>::destroy(this->node_alloc(), container_detail::to_raw_pointer(nodep));
|
allocator_traits<NodeAlloc>::destroy(this->node_alloc(), container_detail::to_raw_pointer(nodep));
|
||||||
|
@@ -1060,6 +1060,29 @@ class tree
|
|||||||
this->insert_equal(*first);
|
this->insert_equal(*first);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class KeyConvertible>
|
||||||
|
iterator insert_from_key(BOOST_FWD_REF(KeyConvertible) key)
|
||||||
|
{
|
||||||
|
insert_commit_data data;
|
||||||
|
const key_type & k = key; //Support emulated rvalue references
|
||||||
|
std::pair<iiterator, bool> ret =
|
||||||
|
this->icont().insert_unique_check(k, KeyNodeCompare(value_comp()), data);
|
||||||
|
return ret.second
|
||||||
|
? this->insert_unique_key_commit(boost::forward<KeyConvertible>(key), data)
|
||||||
|
: iterator(ret.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class KeyConvertible>
|
||||||
|
iterator insert_unique_key_commit
|
||||||
|
(BOOST_FWD_REF(KeyConvertible) key, insert_commit_data &data)
|
||||||
|
{
|
||||||
|
NodePtr tmp = AllocHolder::create_node_from_key(boost::forward<KeyConvertible>(key));
|
||||||
|
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
|
||||||
|
iterator ret(this->icont().insert_unique_commit(*tmp, data));
|
||||||
|
destroy_deallocator.release();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
iterator erase(const_iterator position)
|
iterator erase(const_iterator position)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(position != this->cend() && (priv_is_linked)(position));
|
BOOST_ASSERT(position != this->cend() && (priv_is_linked)(position));
|
||||||
|
@@ -847,31 +847,10 @@ class map
|
|||||||
|
|
||||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||||
private:
|
private:
|
||||||
mapped_type& priv_subscript(const key_type &k)
|
template<class KeyConvertible>
|
||||||
|
mapped_type& priv_subscript(BOOST_FWD_REF(KeyConvertible) k)
|
||||||
{
|
{
|
||||||
//we can optimize this
|
return this->insert_from_key(boost::forward<KeyConvertible>(k))->second;
|
||||||
iterator i = this->lower_bound(k);
|
|
||||||
// i->first is greater than or equivalent to k.
|
|
||||||
if (i == this->end() || this->key_comp()(k, (*i).first)){
|
|
||||||
container_detail::value_init<mapped_type> m;
|
|
||||||
movable_value_type val(k, boost::move(m.m_t));
|
|
||||||
i = insert(i, boost::move(val));
|
|
||||||
}
|
|
||||||
return (*i).second;
|
|
||||||
}
|
|
||||||
|
|
||||||
mapped_type& priv_subscript(BOOST_RV_REF(key_type) mk)
|
|
||||||
{
|
|
||||||
key_type &k = mk;
|
|
||||||
//we can optimize this
|
|
||||||
iterator i = this->lower_bound(k);
|
|
||||||
// i->first is greater than or equivalent to k.
|
|
||||||
if (i == this->end() || this->key_comp()(k, (*i).first)){
|
|
||||||
container_detail::value_init<mapped_type> m;
|
|
||||||
movable_value_type val(boost::move(k), boost::move(m.m_t));
|
|
||||||
i = insert(i, boost::move(val));
|
|
||||||
}
|
|
||||||
return (*i).second;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||||
|
Reference in New Issue
Block a user