boostorg/multi_index

support allocator awareness

Closed this issue · 5 comments

Currently, we cannot use multi_index with c++17 std::pmr::polymorphic_allocator, because multi_index didn't provide copy/move constructors with an extra allocator parameter.

For example, as shown in https://www.boost.org/doc/libs/1_72_0/libs/multi_index/doc/reference/multi_index_container.html#constructors),
multi_index only provided the following copy/move constructors
multi_index_container(const multi_index_container<Value,IndexSpecifierList,Allocator>& x); multi_index_container(multi_index_container<Value,IndexSpecifierList,Allocator>&& x);

The following two constructors are not provided.
multi_index_container(const multi_index_container<Value,IndexSpecifierList,Allocator>& x, const allocator_type& alloc); multi_index_container(multi_index_container<Value,IndexSpecifierList,Allocator>&& x, const allocator_type& alloc);

According to https://en.cppreference.com/w/cpp/named_req/AllocatorAwareContainer, these two special constructors are required when used with nested containers, such as
std::pmr::vector<boost::multi_index::multi_index_container<T, ..., std::pmr::polymorphic_allocator<T>>>.

Could you please add these special constructors?

I have tested the following code in boost 1.71. It seems working, but I am not very sure about it.
multi_index_container( const multi_index_container<Value,IndexSpecifierList,Allocator>& x, const Allocator& al): bfm_allocator(al), bfm_header(), super(x), node_count(0) { copy_map_type map(bfm_allocator::member,x.size(),x.header(),header()); for(const_iterator it=x.begin(),it_end=x.end();it!=it_end;++it){ map.clone(it.get_node()); } super::copy_(x,map); map.release(); node_count=x.size(); /* Not until this point are the indices required to be consistent, * hence the position of the invariant checker. */ BOOST_MULTI_INDEX_CHECK_INVARIANT; } multi_index_container(BOOST_RV_REF(multi_index_container) x, const Allocator& al): bfm_allocator(al), bfm_header(), super(x,detail::do_not_copy_elements_tag()), node_count(0) { BOOST_MULTI_INDEX_CHECK_INVARIANT; BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x); swap_elements_(x); }

Thanks a lot!

Yes, Boost.MultiIndex is not AllocatorAware, I can add this to the lib backlog.

As for the allocator-aware ctors you sketched:

  • The copy ctor looks right.
  • The move ctor should only use swap_elements_ if x.get_allocator()==al.

Besides, as you know, there's more to being AllocatorAware than providing these two ctors (like handling propagate_on_container_* traits).

Yes, making container allocator aware is not an easy job.
Thank you for your suggestion and I really appreciate your works!

Hi, allocator awareness has been added in the sequence of commits:

You can download the current develop branch code at:

https://github.com/boostorg/multi_index/tree/81dbe86f25c23e075ac31702b2f4d1239d5f1a10

Care to test locally and report any problems you find?

Best regards,

I have tested the code, it works as expected. Great job!
If I encounter any problem in the future, I will post it here asap.

Best regards,