From 3dffa64f58082b7a9a5ff172fd66e32951a40072 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Wed, 15 May 2019 01:24:53 -0400 Subject: [PATCH] Bind allocator to element type, not scalar type --- .../smart_ptr/allocate_local_shared_array.hpp | 76 ++++----- .../boost/smart_ptr/allocate_shared_array.hpp | 151 +++++++++--------- .../smart_ptr/make_local_shared_array.hpp | 12 +- include/boost/smart_ptr/make_shared_array.hpp | 12 +- 4 files changed, 117 insertions(+), 134 deletions(-) diff --git a/include/boost/smart_ptr/allocate_local_shared_array.hpp b/include/boost/smart_ptr/allocate_local_shared_array.hpp index 8b7a426..0890849 100644 --- a/include/boost/smart_ptr/allocate_local_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_local_shared_array.hpp @@ -72,21 +72,19 @@ inline typename enable_if_::value, local_shared_ptr >::type allocate_local_shared(const A& allocator, std::size_t count) { - typedef typename remove_extent::type type; - typedef typename detail::sp_array_scalar::type scalar; - typedef typename detail::sp_bind_allocator::type other; + typedef typename detail::sp_array_element::type element; + typedef typename detail::sp_bind_allocator::type other; typedef detail::lsp_array_state state; typedef detail::sp_array_base base; - std::size_t size = count * detail::sp_array_count::value; - detail::sp_array_result result(allocator, size); + detail::sp_array_result result(allocator, count); base* node = result.get(); - scalar* start = detail::sp_array_start(node); - ::new(static_cast(node)) base(allocator, size, start); + element* start = detail::sp_array_start(node); + ::new(static_cast(node)) base(allocator, start, count); detail::lsp_array_base& local = node->state().base(); local.set(node); result.release(); - return local_shared_ptr(detail::lsp_internal_constructor_tag(), - reinterpret_cast(start), &local); + return local_shared_ptr(detail::lsp_internal_constructor_tag(), start, + &local); } template @@ -94,23 +92,22 @@ inline typename enable_if_::value, local_shared_ptr >::type allocate_local_shared(const A& allocator) { - typedef typename remove_extent::type type; - typedef typename detail::sp_array_scalar::type scalar; - typedef typename detail::sp_bind_allocator::type other; enum { - size = detail::sp_array_count::value + count = extent::value }; - typedef detail::lsp_size_array_state state; + typedef typename detail::sp_array_element::type element; + typedef typename detail::sp_bind_allocator::type other; + typedef detail::lsp_size_array_state state; typedef detail::sp_array_base base; - detail::sp_array_result result(allocator, size); + detail::sp_array_result result(allocator, count); base* node = result.get(); - scalar* start = detail::sp_array_start(node); - ::new(static_cast(node)) base(allocator, size, start); + element* start = detail::sp_array_start(node); + ::new(static_cast(node)) base(allocator, start, count); detail::lsp_array_base& local = node->state().base(); local.set(node); result.release(); - return local_shared_ptr(detail::lsp_internal_constructor_tag(), - reinterpret_cast(start), &local); + return local_shared_ptr(detail::lsp_internal_constructor_tag(), start, + &local); } template @@ -119,25 +116,19 @@ inline typename enable_if_::value, allocate_local_shared(const A& allocator, std::size_t count, const typename remove_extent::type& value) { - typedef typename remove_extent::type type; - typedef typename detail::sp_array_scalar::type scalar; - typedef typename detail::sp_bind_allocator::type other; + typedef typename detail::sp_array_element::type element; + typedef typename detail::sp_bind_allocator::type other; typedef detail::lsp_array_state state; typedef detail::sp_array_base base; - enum { - total = detail::sp_array_count::value - }; - std::size_t size = count * total; - detail::sp_array_result result(allocator, size); + detail::sp_array_result result(allocator, count); base* node = result.get(); - scalar* start = detail::sp_array_start(node); - ::new(static_cast(node)) base(allocator, size, - reinterpret_cast(&value), total, start); + element* start = detail::sp_array_start(node); + ::new(static_cast(node)) base(allocator, start, count, value); detail::lsp_array_base& local = node->state().base(); local.set(node); result.release(); - return local_shared_ptr(detail::lsp_internal_constructor_tag(), - reinterpret_cast(start), &local); + return local_shared_ptr(detail::lsp_internal_constructor_tag(), start, + &local); } template @@ -146,25 +137,22 @@ inline typename enable_if_::value, allocate_local_shared(const A& allocator, const typename remove_extent::type& value) { - typedef typename remove_extent::type type; - typedef typename detail::sp_array_scalar::type scalar; - typedef typename detail::sp_bind_allocator::type other; enum { - size = detail::sp_array_count::value + count = extent::value }; - typedef detail::lsp_size_array_state state; + typedef typename detail::sp_array_element::type element; + typedef typename detail::sp_bind_allocator::type other; + typedef detail::lsp_size_array_state state; typedef detail::sp_array_base base; - detail::sp_array_result result(allocator, size); + detail::sp_array_result result(allocator, count); base* node = result.get(); - scalar* start = detail::sp_array_start(node); - ::new(static_cast(node)) base(allocator, size, - reinterpret_cast(&value), - detail::sp_array_count::value, start); + element* start = detail::sp_array_start(node); + ::new(static_cast(node)) base(allocator, start, count, value); detail::lsp_array_base& local = node->state().base(); local.set(node); result.release(); - return local_shared_ptr(detail::lsp_internal_constructor_tag(), - reinterpret_cast(start), &local); + return local_shared_ptr(detail::lsp_internal_constructor_tag(), start, + &local); } template diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index b1f57da..bca9865 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -9,12 +9,13 @@ Distributed under the Boost Software License, Version 1.0. #define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP #include +#include #include #include #include +#include #include #include -#include #include #include #include @@ -23,15 +24,22 @@ namespace boost { namespace detail { template -struct sp_array_scalar { +struct sp_array_element { typedef typename boost::remove_cv::type>::type type; + boost::remove_extent::type>::type type; }; -template +template struct sp_array_count { enum { - value = sizeof(T) / sizeof(U) + value = 1 + }; +}; + +template +struct sp_array_count { + enum { + value = N * sp_array_count::value }; }; @@ -127,39 +135,32 @@ struct sp_array_offset { }; }; -template -struct sp_array_storage { - enum { - value = sp_array_alignment::value - }; - typedef typename boost::type_with_alignment::type type; -}; - -template +template inline U* -sp_array_start(void* base) BOOST_SP_NOEXCEPT +sp_array_start(T* base) BOOST_SP_NOEXCEPT { enum { size = sp_array_offset::value }; - return reinterpret_cast(static_cast(base) + size); + return reinterpret_cast(reinterpret_cast(base) + size); } template class sp_array_creator { - typedef typename A::value_type scalar; + typedef typename A::value_type element; enum { - offset = sp_array_offset::value + offset = sp_array_offset::value }; - typedef typename sp_array_storage::type type; + typedef typename boost::type_with_alignment::value>::type type; public: template sp_array_creator(const U& other, std::size_t size) BOOST_SP_NOEXCEPT : other_(other), - size_(sp_objects(offset + sizeof(scalar) * size)) { } + size_(sp_objects(offset + sizeof(element) * size)) { } T* create() { return reinterpret_cast(other_.allocate(size_)); @@ -183,17 +184,22 @@ public: typedef typename allocator::value_type type; template - sp_array_base(const A& other, std::size_t size, type* start) + sp_array_base(const A& other, type* start, std::size_t size) : state_(other, size) { - boost::alloc_construct_n(state_.allocator(), start, state_.size()); + boost::alloc_construct_n(state_.allocator(), + boost::first_scalar(start), + state_.size() * sp_array_count::value); } - template - sp_array_base(const A& other, std::size_t size, const type* list, - std::size_t count, type* start) + template + sp_array_base(const A& other, type* start, std::size_t size, const U& list) : state_(other, size) { - boost::alloc_construct_n(state_.allocator(), start, state_.size(), - list, count); + enum { + count = sp_array_count::value + }; + boost::alloc_construct_n(state_.allocator(), + boost::first_scalar(start), state_.size() * count, + boost::first_scalar(&list), count); } T& state() BOOST_SP_NOEXCEPT { @@ -202,7 +208,8 @@ public: virtual void dispose() BOOST_SP_NOEXCEPT { boost::alloc_destroy_n(state_.allocator(), - sp_array_start(this), state_.size()); + boost::first_scalar(sp_array_start(this)), + state_.size() * sp_array_count::value); } virtual void destroy() BOOST_SP_NOEXCEPT { @@ -242,11 +249,11 @@ public: } } - T* get() const { + T* get() const BOOST_SP_NOEXCEPT { return result_; } - void release() { + void release() BOOST_SP_NOEXCEPT { result_ = 0; } @@ -264,40 +271,37 @@ template inline typename enable_if_::value, shared_ptr >::type allocate_shared(const A& allocator, std::size_t count) { - typedef typename remove_extent::type type; - typedef typename detail::sp_array_scalar::type scalar; - typedef typename detail::sp_bind_allocator::type other; + typedef typename detail::sp_array_element::type element; + typedef typename detail::sp_bind_allocator::type other; typedef detail::sp_array_state state; typedef detail::sp_array_base base; - std::size_t size = count * detail::sp_array_count::value; - detail::sp_array_result result(allocator, size); - detail::sp_counted_base* node = result.get(); - scalar* start = detail::sp_array_start(node); - ::new(static_cast(node)) base(allocator, size, start); + detail::sp_array_result result(allocator, count); + base* node = result.get(); + element* start = detail::sp_array_start(node); + ::new(static_cast(node)) base(allocator, start, count); result.release(); - return shared_ptr(detail::sp_internal_constructor_tag(), - reinterpret_cast(start), detail::shared_count(node)); + return shared_ptr(detail::sp_internal_constructor_tag(), start, + detail::shared_count(static_cast(node))); } template inline typename enable_if_::value, shared_ptr >::type allocate_shared(const A& allocator) { - typedef typename remove_extent::type type; - typedef typename detail::sp_array_scalar::type scalar; - typedef typename detail::sp_bind_allocator::type other; enum { - size = detail::sp_array_count::value + count = extent::value }; - typedef detail::sp_size_array_state state; + typedef typename detail::sp_array_element::type element; + typedef typename detail::sp_bind_allocator::type other; + typedef detail::sp_size_array_state::value> state; typedef detail::sp_array_base base; - detail::sp_array_result result(allocator, size); - detail::sp_counted_base* node = result.get(); - scalar* start = detail::sp_array_start(node); - ::new(static_cast(node)) base(allocator, size, start); + detail::sp_array_result result(allocator, count); + base* node = result.get(); + element* start = detail::sp_array_start(node); + ::new(static_cast(node)) base(allocator, start, count); result.release(); - return shared_ptr(detail::sp_internal_constructor_tag(), - reinterpret_cast(start), detail::shared_count(node)); + return shared_ptr(detail::sp_internal_constructor_tag(), start, + detail::shared_count(static_cast(node))); } template @@ -305,23 +309,17 @@ inline typename enable_if_::value, shared_ptr >::type allocate_shared(const A& allocator, std::size_t count, const typename remove_extent::type& value) { - typedef typename remove_extent::type type; - typedef typename detail::sp_array_scalar::type scalar; - typedef typename detail::sp_bind_allocator::type other; + typedef typename detail::sp_array_element::type element; + typedef typename detail::sp_bind_allocator::type other; typedef detail::sp_array_state state; typedef detail::sp_array_base base; - enum { - total = detail::sp_array_count::value - }; - std::size_t size = count * total; - detail::sp_array_result result(allocator, size); - detail::sp_counted_base* node = result.get(); - scalar* start = detail::sp_array_start(node); - ::new(static_cast(node)) base(allocator, size, - reinterpret_cast(&value), total, start); + detail::sp_array_result result(allocator, count); + base* node = result.get(); + element* start = detail::sp_array_start(node); + ::new(static_cast(node)) base(allocator, start, count, value); result.release(); - return shared_ptr(detail::sp_internal_constructor_tag(), - reinterpret_cast(start), detail::shared_count(node)); + return shared_ptr(detail::sp_internal_constructor_tag(), start, + detail::shared_count(static_cast(node))); } template @@ -329,23 +327,20 @@ inline typename enable_if_::value, shared_ptr >::type allocate_shared(const A& allocator, const typename remove_extent::type& value) { - typedef typename remove_extent::type type; - typedef typename detail::sp_array_scalar::type scalar; - typedef typename detail::sp_bind_allocator::type other; enum { - size = detail::sp_array_count::value + count = extent::value }; - typedef detail::sp_size_array_state state; + typedef typename detail::sp_array_element::type element; + typedef typename detail::sp_bind_allocator::type other; + typedef detail::sp_size_array_state::value> state; typedef detail::sp_array_base base; - detail::sp_array_result result(allocator, size); - detail::sp_counted_base* node = result.get(); - scalar* start = detail::sp_array_start(node); - ::new(static_cast(node)) base(allocator, size, - reinterpret_cast(&value), - detail::sp_array_count::value, start); + detail::sp_array_result result(allocator, count); + base* node = result.get(); + element* start = detail::sp_array_start(node); + ::new(static_cast(node)) base(allocator, start, count, value); result.release(); - return shared_ptr(detail::sp_internal_constructor_tag(), - reinterpret_cast(start), detail::shared_count(node)); + return shared_ptr(detail::sp_internal_constructor_tag(), start, + detail::shared_count(static_cast(node))); } template diff --git a/include/boost/smart_ptr/make_local_shared_array.hpp b/include/boost/smart_ptr/make_local_shared_array.hpp index cbc6a0f..ba88c73 100644 --- a/include/boost/smart_ptr/make_local_shared_array.hpp +++ b/include/boost/smart_ptr/make_local_shared_array.hpp @@ -20,7 +20,7 @@ inline typename enable_if_::value, make_local_shared() { return boost::allocate_local_shared(boost::default_allocator::type>()); + detail::sp_array_element::type>()); } template @@ -29,7 +29,7 @@ inline typename enable_if_::value, make_local_shared(const typename remove_extent::type& value) { return boost::allocate_local_shared(boost::default_allocator::type>(), value); + detail::sp_array_element::type>(), value); } template @@ -38,7 +38,7 @@ inline typename enable_if_::value, make_local_shared(std::size_t size) { return boost::allocate_local_shared(boost::default_allocator::type>(), size); + detail::sp_array_element::type>(), size); } template @@ -48,7 +48,7 @@ make_local_shared(std::size_t size, const typename remove_extent::type& value) { return boost::allocate_local_shared(boost::default_allocator::type>(), size, value); + detail::sp_array_element::type>(), size, value); } template @@ -57,7 +57,7 @@ inline typename enable_if_::value, make_local_shared_noinit() { return boost::allocate_local_shared_noinit(boost:: - default_allocator::type>()); + default_allocator::type>()); } template @@ -66,7 +66,7 @@ inline typename enable_if_::value, make_local_shared_noinit(std::size_t size) { return boost::allocate_local_shared_noinit(boost:: - default_allocator::type>(), size); + default_allocator::type>(), size); } } /* boost */ diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index ce4b59f..785eb87 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -18,7 +18,7 @@ inline typename enable_if_::value, shared_ptr >::type make_shared() { return boost::allocate_shared(boost::default_allocator::type>()); + detail::sp_array_element::type>()); } template @@ -26,7 +26,7 @@ inline typename enable_if_::value, shared_ptr >::type make_shared(const typename remove_extent::type& value) { return boost::allocate_shared(boost::default_allocator::type>(), value); + detail::sp_array_element::type>(), value); } template @@ -34,7 +34,7 @@ inline typename enable_if_::value, shared_ptr >::type make_shared(std::size_t size) { return boost::allocate_shared(boost::default_allocator::type>(), size); + detail::sp_array_element::type>(), size); } template @@ -42,7 +42,7 @@ inline typename enable_if_::value, shared_ptr >::type make_shared(std::size_t size, const typename remove_extent::type& value) { return boost::allocate_shared(boost::default_allocator::type>(), size, value); + detail::sp_array_element::type>(), size, value); } template @@ -50,7 +50,7 @@ inline typename enable_if_::value, shared_ptr >::type make_shared_noinit() { return boost::allocate_shared_noinit(boost::default_allocator::type>()); + detail::sp_array_element::type>()); } template @@ -58,7 +58,7 @@ inline typename enable_if_::value, shared_ptr >::type make_shared_noinit(std::size_t size) { return boost::allocate_shared_noinit(boost::default_allocator::type>(), size); + detail::sp_array_element::type>(), size); } } /* boost */