diff --git a/include/boost/container/allocator_traits.hpp b/include/boost/container/allocator_traits.hpp
index 55e0771..985bb26 100644
--- a/include/boost/container/allocator_traits.hpp
+++ b/include/boost/container/allocator_traits.hpp
@@ -349,12 +349,12 @@ struct allocator_traits
#endif
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- //! Returns: a.storage_can_be_propagated(p, to, propagate_a)
if is_partially_propagable::value is true; otherwise,
- //! a == to
.
- static bool storage_can_be_propagated(const Allocator &a, pointer p, const Allocator &to, bool propagate_a) BOOST_NOEXCEPT_OR_NOTHROW
+ //! Returns: a.storage_is_unpropagable(p)
if is_partially_propagable::value is true; otherwise,
+ //! false
.
+ static bool storage_is_unpropagable(const Allocator &a, pointer p) BOOST_NOEXCEPT_OR_NOTHROW
{
container_detail::bool_ flag;
- return allocator_traits::priv_storage_can_be_propagated(flag, a, p, to, propagate_a);
+ return allocator_traits::priv_storage_is_unpropagable(flag, a, p);
}
//! Returns: true
if is_always_equal::value == true
, otherwise,
@@ -471,11 +471,11 @@ struct allocator_traits
static void priv_construct_dispatch_next(container_detail::false_type, Allocator &, T *p, const ::boost::container::default_init_t&)
{ ::new((void*)p) T; }
- static bool priv_storage_can_be_propagated(container_detail::true_type, const Allocator &a, pointer p, const Allocator &to, const bool propagate_a)
- { return a.storage_can_be_propagated(p, to, propagate_a); }
+ static bool priv_storage_is_unpropagable(container_detail::true_type, const Allocator &a, pointer p)
+ { return a.storage_is_unpropagable(p); }
- static bool priv_storage_can_be_propagated(container_detail::false_type, const Allocator &a, pointer, const Allocator &to, const bool propagate_a)
- { return allocator_traits::equal(a, to) || propagate_a; }
+ static bool priv_storage_is_unpropagable(container_detail::false_type, const Allocator &, pointer)
+ { return false; }
static bool priv_equal(container_detail::true_type, const Allocator &, const Allocator &)
{ return true; }
diff --git a/include/boost/container/small_vector.hpp b/include/boost/container/small_vector.hpp
index 75f7663..01bbf74 100644
--- a/include/boost/container/small_vector.hpp
+++ b/include/boost/container/small_vector.hpp
@@ -193,11 +193,8 @@ class small_vector_allocator
small_vector_allocator select_on_container_copy_construction() const
{ return small_vector_allocator(allocator_traits_type::select_on_container_copy_construction(this->as_base())); }
- bool storage_can_be_propagated(pointer p, const small_vector_allocator &to, const bool propagate_a) const
- {
- return !this->is_internal_storage(p) &&
- allocator_traits_type::storage_can_be_propagated(this->as_base(), p, to.as_base(), propagate_a);
- }
+ bool storage_is_unpropagable(pointer p) const
+ { return this->is_internal_storage(p) || allocator_traits_type::storage_is_unpropagable(this->as_base(), p); }
//!Swaps two allocators, does nothing
//!because this small_vector_allocator is stateless
@@ -507,7 +504,7 @@ class small_vector : public small_vector_base
private:
void move_construct_impl(small_vector &x, const allocator_type &a)
{
- if(base_type::is_propagable_from(x, a, true)){
+ if(base_type::is_propagable_from(x.get_stored_allocator(), x.data(), a, true)){
this->steal_resources(x);
}
else{
diff --git a/include/boost/container/vector.hpp b/include/boost/container/vector.hpp
index 1cda294..0c6e2ff 100644
--- a/include/boost/container/vector.hpp
+++ b/include/boost/container/vector.hpp
@@ -278,6 +278,23 @@ struct vector_alloc_holder
typedef typename allocator_traits_type::size_type size_type;
typedef typename allocator_traits_type::value_type value_type;
+ static bool is_propagable_from(const allocator_type &from_alloc, pointer p, const allocator_type &to_alloc, bool const propagate_allocator)
+ {
+ (void)propagate_allocator; (void)p; (void)to_alloc; (void)from_alloc;
+ return (!allocator_traits_type::is_partially_propagable::value ||
+ !allocator_traits_type::storage_is_unpropagable(from_alloc, p)) &&
+ (propagate_allocator || allocator_traits_type::equal(from_alloc, to_alloc));
+ }
+
+ static bool are_swap_propagable(const allocator_type &l_a, pointer l_p, const allocator_type &r_a, pointer r_p, bool const propagate_allocator)
+ {
+ (void)propagate_allocator; (void)l_p; (void)r_p; (void)l_a; (void)r_a;
+ return (!allocator_traits_type::is_partially_propagable::value ||
+ (!allocator_traits_type::storage_is_unpropagable(r_a, r_p) &&
+ !allocator_traits_type::storage_is_unpropagable(l_a, l_p))
+ ) && (propagate_allocator || allocator_traits_type::equal(l_a, r_a));
+ }
+
//Constructor, does not throw
vector_alloc_holder()
BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible::value)
@@ -335,7 +352,7 @@ struct vector_alloc_holder
{
allocator_type &this_alloc = this->alloc();
allocator_type &x_alloc = holder.alloc();
- if(allocator_traits_type::storage_can_be_propagated(x_alloc, holder.start(), this_alloc, true)){
+ if(this->is_propagable_from(x_alloc, holder.start(), this_alloc, true)){
if(this->m_capacity){
this->alloc().deallocate(this->m_start, this->m_capacity);
}
@@ -624,8 +641,8 @@ class vector
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
typedef typename container_detail::version::type alloc_version;
- boost::container::container_detail::vector_alloc_holder
- m_holder;
+ typedef boost::container::container_detail::vector_alloc_holder alloc_holder_t;
+ alloc_holder_t m_holder;
typedef allocator_traits allocator_traits_type;
template
friend class vector;
@@ -635,25 +652,12 @@ class vector
typedef container_detail::vec_iterator const_iterator_impl;
protected:
- static bool is_propagable_from(const vector &x, const Allocator &a, bool const propagate_allocator)
- {
- (void)propagate_allocator;
- return (allocator_traits_type::is_partially_propagable::value &&
- allocator_traits_type::storage_can_be_propagated(x.get_stored_allocator(), x.m_holder.start(), a, propagate_allocator)) ||
- (!allocator_traits_type::is_partially_propagable::value && allocator_traits_type::equal(a, x.get_stored_allocator()));
- }
+ static bool is_propagable_from(const Allocator &from_alloc, pointer_impl p, const Allocator &to_alloc, bool const propagate_allocator)
+ { return alloc_holder_t::is_propagable_from(from_alloc, p, to_alloc, propagate_allocator); }
- static bool are_swap_propagable(const vector &l, const vector &r, bool const propagate_allocator)
- {
- (void)propagate_allocator;
- const allocator_type &l_a = l.get_stored_allocator();
- const allocator_type &r_a = r.get_stored_allocator();
- return ( allocator_traits_type::is_partially_propagable::value &&
- allocator_traits_type::storage_can_be_propagated(r_a, r.m_holder.start(), l_a, propagate_allocator) &&
- allocator_traits_type::storage_can_be_propagated(l_a, l.m_holder.start(), r_a, propagate_allocator)
- ) ||
- ( !allocator_traits_type::is_partially_propagable::value && allocator_traits_type::equal(l_a, r_a) );
- }
+ static bool are_swap_propagable( const Allocator &l_a, pointer_impl l_p
+ , const Allocator &r_a, pointer_impl r_p, bool const propagate_allocator)
+ { return alloc_holder_t::are_swap_propagable(l_a, l_p, r_a, r_p, propagate_allocator); }
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
@@ -949,9 +953,11 @@ class vector
//!
//! Complexity: Constant if a == x.get_allocator(), linear otherwise.
vector(BOOST_RV_REF(vector) x, const allocator_type &a)
- : m_holder(container_detail::uninitialized_size, a, is_propagable_from(x, a, true) ? 0 : x.size())
+ : m_holder( container_detail::uninitialized_size, a
+ , is_propagable_from(x.get_stored_allocator(), x.m_holder.start(), a, true) ? 0 : x.size()
+ )
{
- if(is_propagable_from(x, a, true)){
+ if(is_propagable_from(x.get_stored_allocator(), x.m_holder.start(), a, true)){
this->m_holder.steal_resources(x.m_holder);
}
else{
@@ -2117,8 +2123,8 @@ class vector
allocator_type &x_alloc = x.m_holder.alloc();
const bool propagate_alloc = allocator_traits_type::propagate_on_container_move_assignment::value;
- const bool is_propagable_from_x = is_propagable_from(x, this_alloc, propagate_alloc);
- const bool is_propagable_from_t = is_propagable_from(*this, x_alloc, propagate_alloc);
+ const bool is_propagable_from_x = is_propagable_from(x_alloc, x.m_holder.start(), this_alloc, propagate_alloc);
+ const bool is_propagable_from_t = is_propagable_from(this_alloc, m_holder.start(), x_alloc, propagate_alloc);
const bool are_both_propagable = is_propagable_from_x && is_propagable_from_t;
//Resources can be transferred if both allocators are
@@ -2187,7 +2193,8 @@ class vector
void priv_swap(Vector &x, container_detail::false_type) //version_N
{
const bool propagate_alloc = allocator_traits_type::propagate_on_container_swap::value;
- if(are_swap_propagable(*this, x, propagate_alloc)){
+ if(are_swap_propagable( this->get_stored_allocator(), this->m_holder.start()
+ , x.get_stored_allocator(), this->m_holder.start(), propagate_alloc)){
//Just swap internals
this->m_holder.swap_resources(x.m_holder);
}
diff --git a/test/allocator_traits_test.cpp b/test/allocator_traits_test.cpp
index 53dd273..3f4dff0 100644
--- a/test/allocator_traits_test.cpp
+++ b/test/allocator_traits_test.cpp
@@ -100,7 +100,7 @@ class ComplexAllocator
mutable bool max_size_called_;
mutable bool select_on_container_copy_construction_called_;
bool construct_called_;
- mutable bool storage_can_be_propagated_;
+ mutable bool storage_is_unpropagable_;
typedef T value_type;
typedef SimpleSmartPtr pointer;
@@ -174,8 +174,8 @@ class ComplexAllocator
void construct(U *p, boost::container::default_init_t)
{ construct_called_ = true; ::new(p)U; }
- bool storage_can_be_propagated(pointer p, const ComplexAllocator &, bool) const
- { storage_can_be_propagated_ = true; return p ? true : false; }
+ bool storage_is_unpropagable(pointer p) const
+ { storage_is_unpropagable_ = true; return !p; }
//getters
bool allocate_called() const
@@ -199,8 +199,8 @@ class ComplexAllocator
bool construct_called() const
{ return construct_called_; }
- bool storage_can_be_propagated_called() const
- { return storage_can_be_propagated_; }
+ bool storage_is_unpropagable_called() const
+ { return storage_is_unpropagable_; }
};
class copymovable
@@ -422,22 +422,22 @@ int main()
SAllocTraits::construct(s_alloc, &c, 0, 1, 2);
BOOST_TEST(!c.copymoveconstructed() && !c.moved());
}
- //storage_can_be_propagated
+ //storage_is_unpropagable
{
SAlloc s_alloc2;
- BOOST_TEST(SAllocTraits::storage_can_be_propagated(s_alloc, SAllocTraits::pointer(), s_alloc2, true));
+ BOOST_TEST(!SAllocTraits::storage_is_unpropagable(s_alloc, SAllocTraits::pointer()));
}
{
{
CAlloc c_alloc2;
CAlloc::value_type v;
- BOOST_TEST( CAllocTraits::storage_can_be_propagated(c_alloc, CAllocTraits::pointer(&v), c_alloc2, true));
- BOOST_TEST(c_alloc.storage_can_be_propagated_called());
+ BOOST_TEST(!CAllocTraits::storage_is_unpropagable(c_alloc, CAllocTraits::pointer(&v)));
+ BOOST_TEST(c_alloc.storage_is_unpropagable_called());
}
{
CAlloc c_alloc2;
- BOOST_TEST(!CAllocTraits::storage_can_be_propagated(c_alloc2, CAllocTraits::pointer(), c_alloc, true));
- BOOST_TEST(c_alloc2.storage_can_be_propagated_called());
+ BOOST_TEST( CAllocTraits::storage_is_unpropagable(c_alloc2, CAllocTraits::pointer()));
+ BOOST_TEST(c_alloc2.storage_is_unpropagable_called());
}
}