diff --git a/include/boost/smart_ptr/allocate_local_shared_array.hpp b/include/boost/smart_ptr/allocate_local_shared_array.hpp index 9760eea..a894616 100644 --- a/include/boost/smart_ptr/allocate_local_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_local_shared_array.hpp @@ -34,7 +34,7 @@ class lsp_array_base : public local_counted_base { public: void set(sp_counted_base* base) BOOST_SP_NOEXCEPT { - shared_count(base).swap(count_); + count_ = shared_count(base); } virtual void local_cb_destroy() BOOST_SP_NOEXCEPT { @@ -55,7 +55,8 @@ class lsp_array_state public: typedef A type; - lsp_array_state(const A& allocator, std::size_t size) BOOST_SP_NOEXCEPT + template + lsp_array_state(const U& allocator, std::size_t size) BOOST_SP_NOEXCEPT : allocator_(allocator), size_(size) { } @@ -78,7 +79,8 @@ class lsp_size_array_state public: typedef A type; - lsp_size_array_state(const A& allocator, std::size_t) BOOST_SP_NOEXCEPT + template + lsp_size_array_state(const U& allocator, std::size_t) BOOST_SP_NOEXCEPT : allocator_(allocator) { } A& allocator() BOOST_SP_NOEXCEPT { @@ -107,36 +109,36 @@ allocate_local_shared(const A& allocator, std::size_t count) std::size_t size = count * detail::sp_array_count::value; detail::sp_array_result result(allocator, size); base* node = result.get(); - ::new(static_cast(node)) base(allocator, size); + scalar* start = detail::sp_array_start(node); + ::new(static_cast(node)) base(allocator, size, start); detail::lsp_array_base& local = node->state(); local.set(node); - void* start = detail::sp_array_start(node); result.release(); return local_shared_ptr(detail::lsp_internal_constructor_tag(), - static_cast(start), &local); + reinterpret_cast(start), &local); } template inline typename detail::lsp_if_size_array::type allocate_local_shared(const A& allocator) { - typedef typename detail::sp_array_element::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 }; + typedef typename detail::sp_array_element::type type; + typedef typename detail::sp_array_scalar::type scalar; + 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); base* node = result.get(); - ::new(static_cast(node)) base(allocator, size); + scalar* start = detail::sp_array_start(node); + ::new(static_cast(node)) base(allocator, size, start); detail::lsp_array_base& local = node->state(); local.set(node); - void* start = detail::sp_array_start(node); result.release(); return local_shared_ptr(detail::lsp_internal_constructor_tag(), - static_cast(start), &local); + reinterpret_cast(start), &local); } template @@ -152,15 +154,15 @@ allocate_local_shared(const A& allocator, std::size_t count, std::size_t size = count * detail::sp_array_count::value; detail::sp_array_result result(allocator, size); 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); + detail::sp_array_count::value, start); detail::lsp_array_base& local = node->state(); local.set(node); - void* start = detail::sp_array_start(node); result.release(); return local_shared_ptr(detail::lsp_internal_constructor_tag(), - static_cast(start), &local); + reinterpret_cast(start), &local); } template @@ -168,25 +170,25 @@ inline typename detail::lsp_if_size_array::type allocate_local_shared(const A& allocator, const typename detail::sp_array_element::type& value) { - typedef typename detail::sp_array_element::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 }; + typedef typename detail::sp_array_element::type type; + typedef typename detail::sp_array_scalar::type scalar; + 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); 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); + detail::sp_array_count::value, start); detail::lsp_array_base& local = node->state(); local.set(node); - void* start = detail::sp_array_start(node); result.release(); return local_shared_ptr(detail::lsp_internal_constructor_tag(), - static_cast(start), &local); + reinterpret_cast(start), &local); } template @@ -201,38 +203,38 @@ allocate_local_shared_noinit(const A& allocator, std::size_t count) std::size_t size = count * detail::sp_array_count::value; detail::sp_array_result result(allocator, size); base* node = result.get(); - ::new(static_cast(node)) base(detail::sp_default(), - allocator, size); + scalar* start = detail::sp_array_start(node); + ::new(static_cast(node)) base(detail::sp_default(), allocator, + size, start); detail::lsp_array_base& local = node->state(); local.set(node); - void* start = detail::sp_array_start(node); result.release(); return local_shared_ptr(detail::lsp_internal_constructor_tag(), - static_cast(start), &local); + reinterpret_cast(start), &local); } template inline typename detail::lsp_if_size_array::type allocate_local_shared_noinit(const A& allocator) { - typedef typename detail::sp_array_element::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 }; + typedef typename detail::sp_array_element::type type; + typedef typename detail::sp_array_scalar::type scalar; + 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); base* node = result.get(); - ::new(static_cast(node)) base(detail::sp_default(), - allocator, size); + scalar* start = detail::sp_array_start(node); + ::new(static_cast(node)) base(detail::sp_default(), allocator, + size, start); detail::lsp_array_base& local = node->state(); local.set(node); - void* start = detail::sp_array_start(node); result.release(); return local_shared_ptr(detail::lsp_internal_constructor_tag(), - static_cast(start), &local); + reinterpret_cast(start), &local); } } /* boost */ diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index 1b3cfcf..98adead 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -353,7 +353,8 @@ class sp_array_state { public: typedef A type; - sp_array_state(const A& allocator, std::size_t size) BOOST_SP_NOEXCEPT + template + sp_array_state(const U& allocator, std::size_t size) BOOST_SP_NOEXCEPT : allocator_(allocator), size_(size) { } @@ -375,7 +376,8 @@ class sp_size_array_state { public: typedef A type; - sp_size_array_state(const A& allocator, std::size_t) BOOST_SP_NOEXCEPT + template + sp_size_array_state(const U& allocator, std::size_t) BOOST_SP_NOEXCEPT : allocator_(allocator) { } A& allocator() BOOST_SP_NOEXCEPT { @@ -429,27 +431,32 @@ struct sp_array_offset { }; template -inline T* -sp_array_start(U* base) BOOST_SP_NOEXCEPT +struct sp_array_storage { + enum { + value = sp_array_alignment::value + }; + typedef typename boost::type_with_alignment::type type; +}; + +template +inline U* +sp_array_start(void* base) BOOST_SP_NOEXCEPT { enum { - size = sp_array_offset::value + size = sp_array_offset::value }; - return reinterpret_cast(reinterpret_cast(base) + size); + return reinterpret_cast(static_cast(base) + size); } template class sp_array_creator { typedef typename A::value_type scalar; - enum { - alignment = sp_array_alignment::value - }; enum { offset = sp_array_offset::value }; - typedef typename boost::type_with_alignment::type type; + typedef typename sp_array_storage::type type; public: template @@ -481,25 +488,23 @@ public: typedef typename allocator::value_type type; template - sp_array_base(const A& other, std::size_t size) + sp_array_base(const A& other, std::size_t size, type* start) : state_(other, size) { - sp_array_construct(state_.allocator(), sp_array_start(this), - state_.size()); + sp_array_construct(state_.allocator(), start, state_.size()); } template sp_array_base(const A& other, std::size_t size, const type* list, - std::size_t count) + std::size_t count, type* start) : state_(other, size) { - sp_array_construct(state_.allocator(), sp_array_start(this), - state_.size(), list, count); + sp_array_construct(state_.allocator(), start, state_.size(), list, + count); } template - sp_array_base(sp_default, const A& other, std::size_t size) + sp_array_base(sp_default, const A& other, std::size_t size, type* start) : state_(other, size) { - sp_array_default(state_.allocator(), sp_array_start(this), - state_.size()); + sp_array_default(state_.allocator(), start, state_.size()); } T& state() BOOST_SP_NOEXCEPT { @@ -507,8 +512,8 @@ public: } virtual void dispose() { - sp_array_destroy(state_.allocator(), sp_array_start(this), - state_.size()); + sp_array_destroy(state_.allocator(), + sp_array_start(this), state_.size()); } virtual void destroy() { @@ -552,10 +557,8 @@ public: return result_; } - T* release() { - T* value = result_; + void release() { result_ = 0; - return value; } private: @@ -579,33 +582,33 @@ allocate_shared(const A& allocator, std::size_t count) typedef detail::sp_array_base base; std::size_t size = count * detail::sp_array_count::value; detail::sp_array_result result(allocator, size); - base* node = result.get(); - ::new(static_cast(node)) base(allocator, size); - void* start = detail::sp_array_start(node); - detail::sp_counted_base* next = result.release(); + detail::sp_counted_base* node = result.get(); + scalar* start = detail::sp_array_start(node); + ::new(static_cast(node)) base(allocator, size, start); + result.release(); return shared_ptr(detail::sp_internal_constructor_tag(), - static_cast(start), detail::shared_count(next)); + reinterpret_cast(start), detail::shared_count(node)); } template inline typename detail::sp_if_size_array::type allocate_shared(const A& allocator) { - typedef typename detail::sp_array_element::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 }; + typedef typename detail::sp_array_element::type type; + typedef typename detail::sp_array_scalar::type scalar; + typedef typename detail::sp_bind_allocator::type other; typedef detail::sp_size_array_state state; typedef detail::sp_array_base base; detail::sp_array_result result(allocator, size); - base* node = result.get(); - ::new(static_cast(node)) base(allocator, size); - void* start = detail::sp_array_start(node); - detail::sp_counted_base* next = result.release(); + detail::sp_counted_base* node = result.get(); + scalar* start = detail::sp_array_start(node); + ::new(static_cast(node)) base(allocator, size, start); + result.release(); return shared_ptr(detail::sp_internal_constructor_tag(), - static_cast(start), detail::shared_count(next)); + reinterpret_cast(start), detail::shared_count(node)); } template @@ -620,14 +623,14 @@ allocate_shared(const A& allocator, std::size_t count, typedef detail::sp_array_base base; std::size_t size = count * detail::sp_array_count::value; detail::sp_array_result result(allocator, size); - base* node = result.get(); + 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); - void* start = detail::sp_array_start(node); - detail::sp_counted_base* next = result.release(); + detail::sp_array_count::value, start); + result.release(); return shared_ptr(detail::sp_internal_constructor_tag(), - static_cast(start), detail::shared_count(next)); + reinterpret_cast(start), detail::shared_count(node)); } template @@ -635,23 +638,23 @@ inline typename detail::sp_if_size_array::type allocate_shared(const A& allocator, const typename detail::sp_array_element::type& value) { - typedef typename detail::sp_array_element::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 }; + typedef typename detail::sp_array_element::type type; + typedef typename detail::sp_array_scalar::type scalar; + typedef typename detail::sp_bind_allocator::type other; typedef detail::sp_size_array_state state; typedef detail::sp_array_base base; detail::sp_array_result result(allocator, size); - base* node = result.get(); + 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); - void* start = detail::sp_array_start(node); - detail::sp_counted_base* next = result.release(); + detail::sp_array_count::value, start); + result.release(); return shared_ptr(detail::sp_internal_constructor_tag(), - static_cast(start), detail::shared_count(next)); + reinterpret_cast(start), detail::shared_count(node)); } template @@ -665,35 +668,35 @@ allocate_shared_noinit(const A& allocator, std::size_t count) typedef detail::sp_array_base base; std::size_t size = count * detail::sp_array_count::value; detail::sp_array_result result(allocator, size); - base* node = result.get(); - ::new(static_cast(node)) base(detail::sp_default(), - allocator, size); - void* start = detail::sp_array_start(node); - detail::sp_counted_base* next = result.release(); + detail::sp_counted_base* node = result.get(); + scalar* start = detail::sp_array_start(node); + ::new(static_cast(node)) base(detail::sp_default(), allocator, + size, start); + result.release(); return shared_ptr(detail::sp_internal_constructor_tag(), - static_cast(start), detail::shared_count(next)); + reinterpret_cast(start), detail::shared_count(node)); } template inline typename detail::sp_if_size_array::type allocate_shared_noinit(const A& allocator) { - typedef typename detail::sp_array_element::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 }; + typedef typename detail::sp_array_element::type type; + typedef typename detail::sp_array_scalar::type scalar; + typedef typename detail::sp_bind_allocator::type other; typedef detail::sp_size_array_state state; typedef detail::sp_array_base base; detail::sp_array_result result(allocator, size); - base* node = result.get(); - ::new(static_cast(node)) base(detail::sp_default(), - allocator, size); - void* start = detail::sp_array_start(node); - detail::sp_counted_base* next = result.release(); + detail::sp_counted_base* node = result.get(); + scalar* start = detail::sp_array_start(node); + ::new(static_cast(node)) base(detail::sp_default(), allocator, + size, start); + result.release(); return shared_ptr(detail::sp_internal_constructor_tag(), - static_cast(start), detail::shared_count(next)); + reinterpret_cast(start), detail::shared_count(node)); } } /* boost */