diff --git a/include/boost/container/devector.hpp b/include/boost/container/devector.hpp index e201fe1..d4dcedc 100644 --- a/include/boost/container/devector.hpp +++ b/include/boost/container/devector.hpp @@ -224,7 +224,7 @@ class devector * **Complexity**: Constant. */ devector(size_type n, reserve_only_tag_t, const allocator_type& allocator = allocator_type()) - : m_(allocator, this->allocate(n), 0u, 0u, n) + : m_(allocator, 0u, 0u, n) {} /** @@ -240,7 +240,7 @@ class devector * **Complexity**: Constant. */ devector(size_type front_cap, size_type back_cap, reserve_only_tag_t, const allocator_type& allocator = allocator_type()) - : m_(allocator, this->allocate(front_cap + back_cap), front_cap, front_cap, front_cap + back_cap) + : m_( allocator, front_cap, back_cap, front_cap + back_cap) {} /** @@ -257,7 +257,7 @@ class devector * **Complexity**: Linear in `n`. */ explicit devector(size_type n, const allocator_type& allocator = allocator_type()) - : m_(allocator, n ? allocate(n): pointer(), 0u, n, n) + : m_(allocator, 0u, n, n) { // Cannot use construct_from_range/constant_iterator and copy_range, // because we are not allowed to default construct T @@ -347,7 +347,7 @@ class devector BOOST_MOVE_I dtl::is_input_iterator >::type * = 0) ) - : m_(allocator, pointer(), 0u, 0u, 0u) + : m_(allocator) { const size_type n = boost::container::iterator_udistance(first, last); m_.buffer = n ? allocate(n) : pointer(); @@ -376,8 +376,7 @@ class devector * **Complexity**: Linear in the size of `x`. */ devector(const devector& x) - : m_( allocator_traits_type::select_on_container_copy_construction(x.get_allocator_ref()) - , pointer(), 0u, 0u, 0u) + : m_( allocator_traits_type::select_on_container_copy_construction(x.get_allocator_ref())) { const size_type n = x.size(); m_.buffer = n ? allocate(n) : pointer(); @@ -467,7 +466,7 @@ class devector * **Equivalent to**: `devector(il.begin(), il.end())` or `devector(il.begin(), il.end(), allocator)`. */ devector(const std::initializer_list& il, const allocator_type& allocator = allocator_type()) - : m_(allocator, pointer(), 0u, 0u, 0u) + : m_(allocator) { const size_type n = il.size(); m_.buffer = n ? allocate(n) : pointer(); @@ -2059,15 +2058,11 @@ class devector pointer allocate(size_type capacity) { - //First detect overflow on smaller stored_size_types - if (capacity > stored_size_type(-1)){ - boost::container::throw_length_error("get_next_capacity, allocator's max size reached"); - } - //(clamp_by_stored_size_type)(prefer_in_recvd_out_size, stored_size_type()); + pointer const p = impl::do_allocate(get_allocator_ref(), capacity); #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS ++m_.capacity_alloc_count; #endif // BOOST_CONTAINER_DEVECTOR_ALLOC_STATS - return allocator_traits_type::allocate(get_allocator_ref(), capacity); + return p; } void destroy_elements(pointer begin, pointer end) @@ -2082,7 +2077,7 @@ class devector { if (m_.buffer) { - allocator_traits_type::deallocate(get_allocator_ref(), m_.buffer, m_.capacity); + allocator_traits_type::deallocate(get_allocator_ref(), m_.buffer, m_.capacity); } } @@ -2922,17 +2917,49 @@ class devector struct impl : allocator_type { + private: + impl(const impl &i); + + public: + allocator_type &get_al() + { return *this; } + + static pointer do_allocate(allocator_type &a, size_type cap) + { + if (cap) { + //First detect overflow on smaller stored_size_types + if (cap > stored_size_type(-1)){ + boost::container::throw_length_error("get_next_capacity, allocator's max size reached"); + } + return allocator_traits_type::allocate(a, cap); + } + else { + return pointer(); + } + } + impl() : allocator_type(), buffer(), front_idx(), back_idx(), capacity() #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS - , capacity_alloc_count() + , capacity_alloc_count(0) #endif {} explicit impl(const allocator_type &a) : allocator_type(a), buffer(), front_idx(), back_idx(), capacity() #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS - , capacity_alloc_count() + , capacity_alloc_count(0) + #endif + {} + + impl(const allocator_type &a, size_type f, size_type b, size_type c) + : allocator_type(a), buffer(do_allocate(get_al(), c)) + //static cast sizes, as the allocation function will take care of overflows + , front_idx(static_cast(f)) + , back_idx(static_cast(b)) + , capacity(static_cast(c)) + #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS + , capacity_alloc_count(size_type(buffer != pointer())) #endif {} @@ -2943,7 +2970,7 @@ class devector , back_idx(static_cast(b)) , capacity(static_cast(c)) #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS - , capacity_alloc_count() + , capacity_alloc_count(0) #endif {} @@ -2954,7 +2981,7 @@ class devector , back_idx(static_cast(b)) , capacity(static_cast(c)) #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS - , capacity_alloc_count() + , capacity_alloc_count(0) #endif {}