Regression in Multi-index, 1.35?

Hi, I am trying to migrate my project to 1.35. The following used to compile and work with 1.34.1: bmx::multi_index_container<wstring, bmx::indexed_by<bmx::ordered_unique<bmx::identity<wstring> >, bmx::random_access<> >, boost::fast_pool_allocator<wstring> > But refuses to compile with 1.35 (I use Intel compiler 10.1 with MSVC7.1 STL). Something to do with allocator rebind. I am including some of the compiler output below. Can someone please suggest a resolution (hopefully keeping the pool allocator intact)? Thanks Amit C:\DevLibraries\Boost\include\boost-1_35_0\boost/pool/pool_alloc.hpp(130): error: reference to void is not allowed typedef value_type & reference; ^ detected during: instantiation of class "boost::fast_pool_allocator<T, UserAllocator, Mutex, NextSize> [with T=void, UserAllocator=boost::default_user_allocator_new_delete, Mutex=boost::details::pool::default_mutex, NextSize=32U]" at line 149 of "C:\Boost\include\boost-1_35_0\boost/detail/allocator_utilities.hpp" instantiation of class "boost::detail::allocator::rebinder<Allocator>::result<Type> [with Allocator=boost::fast_pool_allocator<void, boost::default_user_allocator_new_delete, boost::details::pool::default_mutex, 32U>, Type=boost::multi_index::detail::random_access_index_node_impl< boost::fast_pool_allocator<void, boost::default_user_allocator_new_delete, boost::details::pool::default_mutex, 32U>>]" at line 158 of "C:\Boost\include\boost-1_35_0\boost/detail/allocator_utilities.hpp" instantiation of class "boost::detail::allocator::compliant_allocator_rebind_to<Allocator, Type> [with Allocator=boost::fast_pool_allocator<void, boost::default_user_allocator_new_delete, boost::details::pool::default_mutex, 32U>, Type=boost::multi_index::detail::random_access_index_node_impl< boost::fast_pool_allocator<void, boost::default_user_allocator_new_delete, boost::details::pool::default_mutex, 32U>>]" at line 62 of "C:\Boost\include\boost-1_35_0\boost/mpl/eval_if.hpp" instantiation of class "boost::mpl::eval_if_c<C, F1, F2> [with C=false, F1=boost::detail::allocator::partial_std_allocator_rebind_to< boost::fast_pool_allocator<void, boost::default_user_allocator_new_delete, boost::details::pool::default_mutex, 32U>, boost::multi_index::detail::random_access_index_node_impl< boost::fast_pool_allocator<void, boost::default_user_allocator_new_delete, boost::details::pool::default_mutex, 32U>>>,

Amit <contact.lipik <at> gmail.com> writes:
Hi Amit, Steven is right on spot: boost::fast_pool_allocator is not correctly specialized for void, as it should. I'll file a bug report about this. In the meantime, you can simply replace fast_pool_allocator with the following fixed_fast_pool_allocator class: template< typename T, typename UserAllocator=boost::default_user_allocator_new_delete
class fixed_fast_pool_allocator: public boost::fast_pool_allocator<T,UserAllocator> { typedef boost::fast_pool_allocator<T,UserAllocator> super; public: template<typename U> struct rebind {typedef fixed_fast_pool_allocator<U, UserAllocator> other;}; fixed_fast_pool_allocator(){} fixed_fast_pool_allocator(const fixed_fast_pool_allocator&x):super(x){} template<typename U> fixed_fast_pool_allocator( const fixed_fast_pool_allocator<U,UserAllocator>& x):super(x){} }; template<typename UserAllocator> class fixed_fast_pool_allocator<void,UserAllocator> { public: typedef void* pointer; typedef const void* const_pointer; typedef void value_type; template<typename U> struct rebind {typedef fixed_fast_pool_allocator<U, UserAllocator> other;}; }; Does this solve your problem? Please report back. Thanks for using Boost.MultiIndex, Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

Joaquin M Lopez Munoz <joaquin <at> tid.es> writes:
Many thanks. Your specialization makes the code compile OK - have to make other changes (for new thread interface) before I can run it, will report on the outcome. I think whole of pool needs a review - I think it hasn't been updated for a while. Maybe I'll volunteer once I have shipped my current project :) By the way, the release notes for 1.35 state that equal_range is now more efficient - are we talking better computational complexity here, or less overhead? Could you please point me to a description of the changes so I know what sort of improvement should be expected. And does this mean that the predicate based range lookup functions exposed by multi-index (ones that take a lower & uper bounder) are more efficient as well? Thanks again. Multiindex is an amazingly useful library. Amit

Amit escribió:
That'd be great! Something must be done with the handful of abandoned libs in Boost.
Prior to 1.35, equal_range(k) was simply implemented as make_pair(lower_bound(x),upper_bound(x)), that is, both ends of the range were computed independently. The new implementation takes advantage of the fact that search paths down a rb-tree for the left and right ends of the range share their initial portion (from the tree root down to the "top" element in the range). In terms of algorithmic complexity the operation is still O(log n), but the work can de reduced by as much as 50% (when the range has only one element, for instance). If you're curious about the code, look for "ordered_index_equal_range" at http://boost.org/doc/libs/1_35_0/boost/multi_index/detail/ord_index_ops.hpp .
And does this mean that the predicate based range lookup functions exposed by multi-index (ones that take a lower & uper bounder) are more efficient as well?
Yep, range() has also been improved, the release notes mention both equal_range and range. Best, Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
participants (4)
-
Amit
-
Joaquin M Lopez Munoz
-
joaquin@tid.es
-
Steven Watanabe