diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index 1ae5cc7..75adf27 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -1,181 +1,1006 @@ /* - * Copyright (c) 2012-2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ +Copyright 2012-2017 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ #ifndef BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP #define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP -#include -#include +#include +#include +#include +#include +#include namespace boost { - template - inline typename boost::detail::sp_if_array::type - allocate_shared(const A& allocator, std::size_t size) { - typedef typename boost::detail::array_inner::type T1; - typedef typename boost::detail::array_base::type T2; - typedef boost::detail::ms_init_tag R1; - typedef boost::detail::as_allocator A1; - typedef boost::detail::ms_in_allocator_tag D1; - std::size_t n1 = size * boost::detail::array_total::size; - T1* p1 = 0; - T2* p2 = 0; - D1 d1; - A1 a1(allocator, size, &p2); - shared_ptr s1(p1, d1, a1); - A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(0); +namespace detail { + +template +struct sp_if_array { }; + +template +struct sp_if_array { + typedef boost::shared_ptr type; +}; + +template +struct sp_if_size_array { }; + +template +struct sp_if_size_array { + typedef boost::shared_ptr type; +}; + +template +struct sp_array_element { }; + +template +struct sp_array_element { + typedef T type; +}; + +template +struct sp_array_element { + typedef T type; +}; + +template +struct sp_array_scalar { + typedef T type; +}; + +template +struct sp_array_scalar { + typedef typename sp_array_scalar::type type; +}; + +template +struct sp_array_scalar { + typedef typename sp_array_scalar::type type; +}; + +template +struct sp_array_scalar { + typedef typename sp_array_scalar::type type; +}; + +template +struct sp_array_scalar { + typedef typename sp_array_scalar::type type; +}; + +template +struct sp_array_scalar { + typedef typename sp_array_scalar::type type; +}; + +template +struct sp_array_scalar { + typedef typename sp_array_scalar::type type; +}; + +template +struct sp_array_scalar { + typedef typename sp_array_scalar::type type; +}; + +template +struct sp_array_scalar { + typedef typename sp_array_scalar::type type; +}; + +template +struct sp_array_count { + BOOST_STATIC_CONSTEXPR std::size_t value = 1; +}; + +template +struct sp_array_count { + BOOST_STATIC_CONSTEXPR std::size_t value = N * + sp_array_count::value; +}; + +template +struct sp_array_count { }; + +template +inline D* +sp_get_deleter(const boost::shared_ptr& value) BOOST_NOEXCEPT +{ + return static_cast(value._internal_get_untyped_deleter()); +} + +template +struct sp_array_storage { + union type { + char value[N]; + typename boost::type_with_alignment::type other; + }; +}; + +template +struct sp_max_size { + BOOST_STATIC_CONSTEXPR std::size_t value = N < M ? M : N; +}; + #if !defined(BOOST_NO_CXX11_ALLOCATOR) - boost::detail::as_init(allocator, p2, n1); +template +struct sp_bind_allocator { + typedef typename std::allocator_traits::template + rebind_alloc type; +}; #else - boost::detail::ms_init(p2, n1); +template +struct sp_bind_allocator { + typedef typename A::template rebind::other type; +}; #endif - a2->set(p2); - p1 = reinterpret_cast(p2); - return shared_ptr(s1, p1); - } - template - inline typename boost::detail::sp_if_size_array::type - allocate_shared(const A& allocator) { - typedef typename boost::detail::array_inner::type T1; - typedef typename boost::detail::array_base::type T2; - typedef boost::detail::ms_init_tag R1; - typedef boost::detail::as_allocator A1; - typedef boost::detail::ms_in_allocator_tag D1; - enum { - N = boost::detail::array_total::size - }; - T1* p1 = 0; - T2* p2 = 0; - D1 d1; - A1 a1(allocator, &p2); - shared_ptr s1(p1, d1, a1); - A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(0); -#if !defined(BOOST_NO_CXX11_ALLOCATOR) - boost::detail::as_init(allocator, p2, N); -#else - boost::detail::ms_init(p2, N); -#endif - a2->set(p2); - p1 = reinterpret_cast(p2); - return shared_ptr(s1, p1); - } +template +struct sp_enable { }; - template - inline typename boost::detail::sp_if_array::type - allocate_shared(const A& allocator, std::size_t size, - const typename boost::detail::array_inner::type& value) { - typedef typename boost::detail::array_inner::type T1; - typedef typename boost::detail::array_base::type T2; - typedef const T2 T3; - typedef boost::detail::ms_init_tag R1; - typedef boost::detail::as_allocator A1; - typedef boost::detail::ms_in_allocator_tag D1; - enum { - M = boost::detail::array_total::size - }; - std::size_t n1 = M * size; - T1* p1 = 0; - T2* p2 = 0; - T3* p3 = reinterpret_cast(&value); - D1 d1; - A1 a1(allocator, size, &p2); - shared_ptr s1(p1, d1, a1); - A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(0); -#if !defined(BOOST_NO_CXX11_ALLOCATOR) - boost::detail::as_init(allocator, p2, n1, p3); -#else - boost::detail::ms_init(p2, n1, p3); -#endif - a2->set(p2); - p1 = reinterpret_cast(p2); - return shared_ptr(s1, p1); - } +template<> +struct sp_enable { + typedef void type; +}; - template - inline typename boost::detail::sp_if_size_array::type - allocate_shared(const A& allocator, - const typename boost::detail::array_inner::type& value) { - typedef typename boost::detail::array_inner::type T1; - typedef typename boost::detail::array_base::type T2; - typedef const T2 T3; - typedef boost::detail::ms_init_tag R1; - typedef boost::detail::as_allocator A1; - typedef boost::detail::ms_in_allocator_tag D1; - enum { - N = boost::detail::array_total::size, - M = boost::detail::array_total::size - }; - T1* p1 = 0; - T2* p2 = 0; - T3* p3 = reinterpret_cast(&value); - D1 d1; - A1 a1(allocator, &p2); - shared_ptr s1(p1, d1, a1); - A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(0); -#if !defined(BOOST_NO_CXX11_ALLOCATOR) - boost::detail::as_init(allocator, p2, N, p3); -#else - boost::detail::ms_init(p2, N, p3); -#endif - a2->set(p2); - p1 = reinterpret_cast(p2); - return shared_ptr(s1, p1); - } +template +inline +typename sp_enable::value>::type +sp_array_destroy(T*, std::size_t) BOOST_NOEXCEPT { } - template - inline typename boost::detail::sp_if_array::type - allocate_shared_noinit(const A& allocator, std::size_t size) { - typedef typename boost::detail::array_inner::type T1; - typedef typename boost::detail::array_base::type T2; - typedef boost::detail::ms_noinit_tag R1; - typedef boost::detail::as_allocator A1; - typedef boost::detail::ms_in_allocator_tag D1; - std::size_t n1 = size * boost::detail::array_total::size; - T1* p1 = 0; - T2* p2 = 0; - D1 d1; - A1 a1(allocator, size, &p2); - shared_ptr s1(p1, d1, a1); - A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(0); - boost::detail::ms_noinit(p2, n1); - a2->set(p2); - p1 = reinterpret_cast(p2); - return shared_ptr(s1, p1); - } - - template - inline typename boost::detail::sp_if_size_array::type - allocate_shared_noinit(const A& allocator) { - typedef typename boost::detail::array_inner::type T1; - typedef typename boost::detail::array_base::type T2; - typedef boost::detail::ms_noinit_tag R1; - typedef boost::detail::as_allocator A1; - typedef boost::detail::ms_in_allocator_tag D1; - enum { - N = boost::detail::array_total::size - }; - T1* p1 = 0; - T2* p2 = 0; - D1 d1; - A1 a1(allocator, &p2); - shared_ptr s1(p1, d1, a1); - A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(0); - boost::detail::ms_noinit(p2, N); - a2->set(p2); - p1 = reinterpret_cast(p2); - return shared_ptr(s1, p1); +template +inline +typename sp_enable::value>::type +sp_array_destroy(T* storage, std::size_t size) +{ + while (size > 0) { + storage[--size].~T(); } } +#if !defined(BOOST_NO_CXX11_ALLOCATOR) +template +inline void +sp_array_destroy(A& allocator, T* storage, std::size_t size) +{ + while (size > 0) { + std::allocator_traits::destroy(allocator, &storage[--size]); + } +} +#endif + +#if !defined(BOOST_NO_EXCEPTIONS) +template +inline +typename sp_enable::value || + boost::has_trivial_destructor::value>::type +sp_array_construct(T* storage, std::size_t size) +{ + for (std::size_t i = 0; i < size; ++i) { + ::new(static_cast(storage + i)) T(); + } +} + +template +inline +typename sp_enable::value && + !boost::has_trivial_destructor::value>::type +sp_array_construct(T* storage, std::size_t size) +{ + std::size_t i = 0; + try { + for (; i < size; ++i) { + ::new(static_cast(storage + i)) T(); + } + } catch (...) { + while (i > 0) { + storage[--i].~T(); + } + throw; + } +} + +template +inline void +sp_array_construct(T* storage, std::size_t size, const T* list, + std::size_t count) +{ + std::size_t i = 0; + try { + for (; i < size; ++i) { + ::new(static_cast(storage + i)) T(list[i % count]); + } + } catch (...) { + while (i > 0) { + storage[--i].~T(); + } + throw; + } +} +#else +template +inline void +sp_array_construct(T* storage, std::size_t size) +{ + for (std::size_t i = 0; i < size; ++i) { + ::new(static_cast(storage + i)) T(); + } +} + +template +inline void +sp_array_construct(T* storage, std::size_t size, const T* list, + std::size_t count) +{ + for (std::size_t i = 0; i < size; ++i) { + ::new(static_cast(storage + i)) T(list[i % count]); + } +} +#endif + +#if !defined(BOOST_NO_CXX11_ALLOCATOR) +#if !defined(BOOST_NO_EXCEPTIONS) +template +inline void +sp_array_construct(A& allocator, T* storage, std::size_t size) +{ + std::size_t i = 0; + try { + for (i = 0; i < size; ++i) { + std::allocator_traits::construct(allocator, storage + i); + } + } catch (...) { + sp_array_destroy(allocator, storage, i); + throw; + } +} + +template +inline void +sp_array_construct(A& allocator, T* storage, std::size_t size, + const T* list, std::size_t count) +{ + std::size_t i = 0; + try { + for (i = 0; i < size; ++i) { + std::allocator_traits::construct(allocator, storage + i, + list[i % count]); + } + } catch (...) { + sp_array_destroy(allocator, storage, i); + throw; + } +} +#else +template +inline void +sp_array_construct(A& allocator, T* storage, std::size_t size) +{ + for (std::size_t i = 0; i < size; ++i) { + std::allocator_traits::construct(allocator, storage + i); + } +} + +template +inline void +sp_array_construct(A& allocator, T* storage, std::size_t size, + const T* list, std::size_t count) +{ + for (std::size_t i = 0; i < size; ++i) { + std::allocator_traits::construct(allocator, storage + i, + list[i % count]); + } +} +#endif +#endif + +template +inline +typename sp_enable::value>::type +sp_array_default(T*, std::size_t) BOOST_NOEXCEPT { } + +#if !defined(BOOST_NO_EXCEPTIONS) +template +inline +typename sp_enable::value && + boost::has_trivial_destructor::value>::type +sp_array_default(T* storage, std::size_t size) +{ + for (std::size_t i = 0; i < size; ++i) { + ::new(static_cast(storage + i)) T; + } +} + +template +inline +typename sp_enable::value && + !boost::has_trivial_destructor::value>::type +sp_array_default(T* storage, std::size_t size) +{ + std::size_t i = 0; + try { + for (; i < size; ++i) { + ::new(static_cast(storage + i)) T; + } + } catch (...) { + while (i > 0) { + storage[--i].~T(); + } + throw; + } +} +#else +template +inline +typename sp_enable::value>::type +sp_array_default(T* storage, std::size_t size) +{ + for (std::size_t i = 0; i < size; ++i) { + ::new(static_cast(storage + i)) T; + } +} +#endif + +template +BOOST_CONSTEXPR inline std::size_t +sp_objects(std::size_t size) BOOST_NOEXCEPT +{ + return size / sizeof(T); +} + +template +BOOST_CONSTEXPR inline std::size_t +sp_align(std::size_t size) BOOST_NOEXCEPT +{ + return (sizeof(T) * size + sizeof(U) - 1) & ~(sizeof(U) - 1); +} + +template +class sp_size_array_deleter { +public: + template + static void operator_fn(U) BOOST_NOEXCEPT { } + + sp_size_array_deleter() BOOST_NOEXCEPT + : enabled_(false) { } + + template + sp_size_array_deleter(const A&) BOOST_NOEXCEPT + : enabled_(false) { } + + sp_size_array_deleter(const sp_size_array_deleter&) BOOST_NOEXCEPT + : enabled_(false) { } + + ~sp_size_array_deleter() { + if (enabled_) { + sp_array_destroy(reinterpret_cast(&storage_), N); + } + } + + template + void operator()(U) { + if (enabled_) { + sp_array_destroy(reinterpret_cast(&storage_), N); + enabled_ = false; + } + } + + void* construct() { + sp_array_construct(reinterpret_cast(&storage_), N); + enabled_ = true; + return &storage_; + } + + void* construct(const T* list, std::size_t count) { + sp_array_construct(reinterpret_cast(&storage_), N, + list, count); + enabled_ = true; + return &storage_; + } + + void* construct_default() { + sp_array_default(reinterpret_cast(&storage_), N); + enabled_ = true; + return &storage_; + } + +private: + bool enabled_; + typename sp_array_storage::value>::type storage_; +}; + +#if !defined(BOOST_NO_CXX11_ALLOCATOR) +template +class sp_size_array_destroyer { +public: + template + static void operator_fn(U) BOOST_NOEXCEPT { } + + template + sp_size_array_destroyer(const U& allocator) BOOST_NOEXCEPT + : allocator_(allocator), + enabled_(false) { } + + sp_size_array_destroyer(const sp_size_array_destroyer& other) + BOOST_NOEXCEPT + : allocator_(other.allocator_), + enabled_(false) { } + + ~sp_size_array_destroyer() { + if (enabled_) { + sp_array_destroy(allocator_, + reinterpret_cast(&storage_), N); + } + } + + template + void operator()(U) { + if (enabled_) { + sp_array_destroy(allocator_, + reinterpret_cast(&storage_), N); + enabled_ = false; + } + } + + void* construct() { + sp_array_construct(allocator_, + reinterpret_cast(&storage_), N); + enabled_ = true; + return &storage_; + } + + void* construct(const T* list, std::size_t count) { + sp_array_construct(allocator_, + reinterpret_cast(&storage_), N, list, count); + enabled_ = true; + return &storage_; + } + + const A& allocator() const BOOST_NOEXCEPT { + return allocator_; + } + +private: + typename sp_array_storage::value>::type storage_; + A allocator_; + bool enabled_; +}; +#endif + +template +class sp_array_deleter { +public: + template + static void operator_fn(U) BOOST_NOEXCEPT { } + + sp_array_deleter(std::size_t size) BOOST_NOEXCEPT + : address_(0), + size_(size) { } + + template + sp_array_deleter(const A& allocator) BOOST_NOEXCEPT + : address_(0), + size_(allocator.size()) { } + + template + sp_array_deleter(const A&, std::size_t size) BOOST_NOEXCEPT + : address_(0), + size_(size) { } + + sp_array_deleter(const sp_array_deleter& other) BOOST_NOEXCEPT + : address_(0), + size_(other.size_) { } + + ~sp_array_deleter() { + if (address_) { + sp_array_destroy(static_cast(address_), size_); + } + } + + template + void operator()(U) { + if (address_) { + sp_array_destroy(static_cast(address_), size_); + address_ = 0; + } + } + + void construct(T* address) { + sp_array_construct(address, size_); + address_ = address; + } + + void construct(T* address, const T* list, std::size_t count) { + sp_array_construct(address, size_, list, count); + address_ = address; + } + + void construct_default(T* address) { + sp_array_default(address, size_); + address_ = address; + } + + std::size_t size() const BOOST_NOEXCEPT { + return size_; + } + +private: + void* address_; + std::size_t size_; +}; + +#if !defined(BOOST_NO_CXX11_ALLOCATOR) +template +class sp_array_destroyer { +public: + template + static void operator_fn(U) BOOST_NOEXCEPT { } + + template + sp_array_destroyer(const U& allocator, std::size_t size) + BOOST_NOEXCEPT + : allocator_(allocator), + size_(size), + address_(0) { } + + template + sp_array_destroyer(const U& allocator) BOOST_NOEXCEPT + : allocator_(allocator.allocator()), + size_(allocator.size()), + address_(0) { } + + sp_array_destroyer(const sp_array_destroyer& other) BOOST_NOEXCEPT + : allocator_(other.allocator_), + size_(other.size_), + address_(0) { } + + ~sp_array_destroyer() { + if (address_) { + sp_array_destroy(allocator_, static_cast(address_), + size_); + } + } + + template + void operator()(U) { + if (address_) { + sp_array_destroy(allocator_, static_cast(address_), + size_); + address_ = 0; + } + } + + void construct(T* address) { + sp_array_construct(allocator_, address, size_); + address_ = address; + } + + void construct(T* address, const T* list, std::size_t count) { + sp_array_construct(allocator_, address, size_, list, count); + address_ = address; + } + + const A& allocator() const BOOST_NOEXCEPT { + return allocator_; + } + + std::size_t size() const BOOST_NOEXCEPT { + return size_; + } + +private: + A allocator_; + std::size_t size_; + void* address_; +}; +#endif + +template +class sp_array_allocator { + template + friend class sp_array_allocator; + +public: + typedef typename A::value_type value_type; + +private: + enum { + alignment = sp_max_size::value, + boost::alignment_of::value>::value + }; + + typedef typename boost::type_with_alignment::type type; + typedef typename sp_bind_allocator::type type_allocator; + +public: + template + struct rebind { + typedef sp_array_allocator::type> other; + }; + + sp_array_allocator(const A& allocator, std::size_t size, + void** result) BOOST_NOEXCEPT + : allocator_(allocator), + size_(size), + result_(result) { } + + sp_array_allocator(const A& allocator, std::size_t size) + BOOST_NOEXCEPT + : allocator_(allocator), + size_(size) { } + + template + sp_array_allocator(const sp_array_allocator& other) + BOOST_NOEXCEPT + : allocator_(other.allocator_), + size_(other.size_), + result_(other.result_) { } + + value_type* allocate(std::size_t count, const void* = 0) { + type_allocator allocator(allocator_); + std::size_t head = sp_align(count); + std::size_t tail = sp_align(size_); + std::size_t size = sp_objects(head + tail); + type* address = allocator.allocate(size); + *result_ = address + sp_objects(head); + return reinterpret_cast(address); + } + + void deallocate(value_type* value, std::size_t count) { + type_allocator allocator(allocator_); + std::size_t head = sp_align(count); + std::size_t tail = sp_align(size_); + std::size_t size = sp_objects(head + tail); + allocator.deallocate(reinterpret_cast(value), size); + } + + const A& allocator() const BOOST_NOEXCEPT { + return allocator_; + } + + std::size_t size() const BOOST_NOEXCEPT { + return size_; + } + +private: + A allocator_; + std::size_t size_; + void** result_; +}; + +template +inline bool +operator==(const sp_array_allocator& first, + const sp_array_allocator& second) BOOST_NOEXCEPT +{ + return first.allocator() == second.allocator() && + first.size() == second.size(); +} + +template +inline bool +operator!=(const sp_array_allocator& first, + const sp_array_allocator& second) BOOST_NOEXCEPT +{ + return !(first == second); +} + +#if !defined(BOOST_NO_CXX11_ALLOCATOR) +template +struct sp_select_size_deleter { + typedef sp_size_array_destroyer::type> type; +}; + +template +struct sp_select_size_deleter, T, N> { + typedef sp_size_array_deleter type; +}; + +template +struct sp_select_deleter { + typedef sp_array_destroyer::type> type; +}; + +template +struct sp_select_deleter, T> { + typedef sp_array_deleter type; +}; +#else +template +struct sp_select_size_deleter { + typedef sp_size_array_deleter type; +}; + +template +struct sp_select_deleter { + typedef sp_array_deleter type; +}; +#endif + +template +class sp_counted_impl_pda, A> + : public sp_counted_base { +public: + typedef sp_size_array_deleter deleter_type; + +private: + typedef sp_counted_impl_pda type; + typedef typename sp_bind_allocator::type deallocator; + +public: + sp_counted_impl_pda(P, const deleter_type&, const A& allocator) + : deleter_(allocator), + allocator_(allocator) { } + + sp_counted_impl_pda(P, const A& allocator) + : deleter_(allocator) { } + + void dispose() { + deleter_(0); + } + + void destroy() { + this->~type(); + deallocator allocator(allocator_); + allocator.deallocate(this, 1); + } + + void* get_deleter(const sp_typeinfo&) { + return &reinterpret_cast(deleter_); + } + + void* get_untyped_deleter() { + return &reinterpret_cast(deleter_); + } + +private: + deleter_type deleter_; + A allocator_; +}; + +#if !defined(BOOST_NO_CXX11_ALLOCATOR) +template +class sp_counted_impl_pda, A> + : public sp_counted_base { +public: + typedef sp_size_array_destroyer deleter_type; + +private: + typedef sp_counted_impl_pda type; + typedef typename sp_bind_allocator::type deallocator; + +public: + sp_counted_impl_pda(P, const deleter_type&, const A& allocator) + : deleter_(allocator) { } + + sp_counted_impl_pda(P, const A& allocator) + : deleter_(allocator) { } + + void dispose() { + deleter_(0); + } + + void destroy() { + this->~type(); + deallocator allocator(deleter_.allocator()); + allocator.deallocate(this, 1); + } + + void* get_deleter(const sp_typeinfo&) { + return &reinterpret_cast(deleter_); + } + + void* get_untyped_deleter() { + return &reinterpret_cast(deleter_); + } + +private: + deleter_type deleter_; +}; +#endif + +template +class sp_counted_impl_pda, + sp_array_allocator > + : public sp_counted_base { +public: + typedef sp_array_deleter deleter_type; + typedef sp_array_allocator allocator_type; + +private: + typedef sp_counted_impl_pda type; + typedef sp_array_allocator::type> deallocator; + +public: + sp_counted_impl_pda(P, const deleter_type&, + const allocator_type& allocator) + : deleter_(allocator), + allocator_(allocator.allocator()) { } + + sp_counted_impl_pda(P, const allocator_type& allocator) + : deleter_(allocator), + allocator_(allocator.allocator()) { } + + void dispose() { + deleter_(0); + } + + void destroy() { + this->~type(); + deallocator allocator(allocator_, deleter_.size()); + allocator.deallocate(this, 1); + } + + void* get_deleter(const sp_typeinfo&) { + return &reinterpret_cast(deleter_); + } + + void* get_untyped_deleter() { + return &reinterpret_cast(deleter_); + } + +private: + deleter_type deleter_; + A allocator_; +}; + +#if !defined(BOOST_NO_CXX11_ALLOCATOR) +template +class sp_counted_impl_pda, + sp_array_allocator > + : public sp_counted_base { +public: + typedef sp_array_destroyer deleter_type; + typedef sp_array_allocator allocator_type; + +private: + typedef sp_counted_impl_pda type; + typedef sp_array_allocator::type> deallocator; + +public: + sp_counted_impl_pda(P, const deleter_type&, + const allocator_type& allocator) + : deleter_(allocator) { } + + sp_counted_impl_pda(P, const allocator_type& allocator) + : deleter_(allocator) { } + + void dispose() { + deleter_(0); + } + + void destroy() { + this->~type(); + deallocator allocator(deleter_.allocator(), deleter_.size()); + allocator.deallocate(this, 1); + } + + void* get_deleter(const sp_typeinfo&) { + return &reinterpret_cast(deleter_); + } + + void* get_untyped_deleter() { + return &reinterpret_cast(deleter_); + } + +private: + deleter_type deleter_; +}; +#endif + +} /* detail */ + +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_select_size_deleter::value>::type deleter; + shared_ptr result(static_cast(0), + detail::sp_inplace_tag(), allocator); + deleter* state = detail::sp_get_deleter(result); + void* start = state->construct(); + return shared_ptr(result, static_cast(start)); +} + +template +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_select_size_deleter::value>::type deleter; + shared_ptr result(static_cast(0), + detail::sp_inplace_tag(), allocator); + deleter* state = detail::sp_get_deleter(result); + void* start = state->construct(reinterpret_cast(&value), detail::sp_array_count::value); + return shared_ptr(result, static_cast(start)); +} + +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 detail::sp_size_array_deleter::value> deleter; + shared_ptr result(static_cast(0), + detail::sp_inplace_tag(), allocator); + deleter* state = detail::sp_get_deleter(result); + void* start = state->construct_default(); + return shared_ptr(result, static_cast(start)); +} + +template +inline typename detail::sp_if_array::type +allocate_shared(const A& allocator, std::size_t count) +{ + typedef typename detail::sp_array_element::type type; + typedef typename detail::sp_array_scalar::type scalar; + typedef typename detail::sp_select_deleter::type deleter; + std::size_t size = count * detail::sp_array_count::value; + void* start; + shared_ptr result(static_cast(0), + detail::sp_inplace_tag(), + detail::sp_array_allocator(allocator, size, &start)); + deleter* state = detail::sp_get_deleter(result); + state->construct(static_cast(start)); + return shared_ptr(result, static_cast(start)); +} + +template +inline typename detail::sp_if_array::type +allocate_shared(const A& allocator, std::size_t count, + 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_select_deleter::type deleter; + std::size_t size = count * detail::sp_array_count::value; + void* start; + shared_ptr result(static_cast(0), + detail::sp_inplace_tag(), + detail::sp_array_allocator(allocator, size, &start)); + deleter* state = detail::sp_get_deleter(result); + state->construct(static_cast(start), + reinterpret_cast(&value), + detail::sp_array_count::value); + return shared_ptr(result, static_cast(start)); +} + +template +inline typename detail::sp_if_array::type +allocate_shared_noinit(const A& allocator, std::size_t count) +{ + typedef typename detail::sp_array_element::type type; + typedef typename detail::sp_array_scalar::type scalar; + typedef detail::sp_array_deleter deleter; + std::size_t size = count * detail::sp_array_count::value; + void* start; + shared_ptr result(static_cast(0), + detail::sp_inplace_tag(), + detail::sp_array_allocator(allocator, size, &start)); + deleter* state = detail::sp_get_deleter(result); + state->construct_default(static_cast(start)); + return shared_ptr(result, static_cast(start)); +} + +} /* boost */ + #endif diff --git a/include/boost/smart_ptr/detail/array_allocator.hpp b/include/boost/smart_ptr/detail/array_allocator.hpp deleted file mode 100644 index 7147996..0000000 --- a/include/boost/smart_ptr/detail/array_allocator.hpp +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Copyright (c) 2012-2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ -#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_ALLOCATOR_HPP -#define BOOST_SMART_PTR_DETAIL_ARRAY_ALLOCATOR_HPP - -#include -#include -#include -#include - -namespace boost { - namespace detail { - struct ms_init_tag { }; - struct ms_noinit_tag { }; - - template - struct ms_allocator_state; - - template - struct ms_allocator_state { - typedef typename array_base::type type; - - ms_allocator_state(std::size_t size_, - type** result_) - : size(size_ * array_total::size), - result(result_) { - } - - std::size_t size; - - union { - type** result; - type* object; - }; - }; - - template - struct ms_allocator_state { - typedef typename array_base::type type; - - ms_allocator_state(type** result_) - : result(result_) { - } - - enum { - size = array_total::size - }; - - union { - type** result; - type* object; - }; - }; - - template - class as_allocator - : public A { - template - friend class as_allocator; - -#if !defined(BOOST_NO_CXX11_ALLOCATOR) - typedef std::allocator_traits AT; - typedef typename AT::template rebind_alloc CA; - typedef typename AT::template rebind_traits CT; -#else - typedef typename A::template rebind::other CA; -#endif - - public: - typedef A allocator_type; - -#if !defined(BOOST_NO_CXX11_ALLOCATOR) - typedef typename AT::value_type value_type; - typedef typename AT::pointer pointer; - typedef typename AT::const_pointer const_pointer; - typedef typename AT::void_pointer void_pointer; - typedef typename AT::const_void_pointer const_void_pointer; - typedef typename AT::size_type size_type; - typedef typename AT::difference_type difference_type; -#else - typedef typename A::value_type value_type; - typedef typename A::pointer pointer; - typedef typename A::const_pointer const_pointer; - typedef typename A::size_type size_type; - typedef typename A::difference_type difference_type; - typedef typename A::reference reference; - typedef typename A::const_reference const_reference; - typedef void* void_pointer; - typedef const void* const_void_pointer; -#endif - - template - struct rebind { -#if !defined(BOOST_NO_CXX11_ALLOCATOR) - typedef as_allocator, T, R> other; -#else - typedef as_allocator::other, T, R> other; -#endif - }; - - typedef typename array_base::type type; - - as_allocator(const A& allocator_, type** result) - : A(allocator_), - data(result) { - } - - as_allocator(const A& allocator_, std::size_t size, - type** result) - : A(allocator_), - data(size, result) { - } - - template - as_allocator(const as_allocator& other) - : A(other.allocator()), - data(other.data) { - } - - pointer allocate(size_type count, const_void_pointer = 0) { - enum { - M = boost::alignment_of::value - }; - std::size_t n1 = count * sizeof(value_type); - std::size_t n2 = data.size * sizeof(type); - std::size_t n3 = n2 + M; - CA ca(allocator()); - void* p1 = ca.allocate(n1 + n3); - void* p2 = static_cast(p1) + n1; - (void)boost::alignment::align(M, n2, p2, n3); - *data.result = static_cast(p2); - return static_cast(p1); - } - - void deallocate(pointer memory, size_type count) { - enum { - M = boost::alignment_of::value - }; - std::size_t n1 = count * sizeof(value_type); - std::size_t n2 = data.size * sizeof(type) + M; - char* p1 = reinterpret_cast(memory); - CA ca(allocator()); - ca.deallocate(p1, n1 + n2); - } - - const A& allocator() const { - return static_cast(*this); - } - - A& allocator() { - return static_cast(*this); - } - - void set(type* memory) { - data.object = memory; - } - - void operator()() { - if (data.object) { - R tag; - release(tag); - } - } - - private: - void release(ms_init_tag) { -#if !defined(BOOST_NO_CXX11_ALLOCATOR) - as_destroy(allocator(), data.object, data.size); -#else - ms_destroy(data.object, data.size); -#endif - } - - void release(ms_noinit_tag) { - ms_destroy(data.object, data.size); - } - - ms_allocator_state data; - }; - - template - bool operator==(const as_allocator& a1, - const as_allocator& a2) { - return a1.allocator() == a2.allocator(); - } - - template - bool operator!=(const as_allocator& a1, - const as_allocator& a2) { - return a1.allocator() != a2.allocator(); - } - - template - class ms_allocator; - - template - class ms_allocator { - template - friend class ms_allocator; - - public: - typedef typename array_base::type type; - - typedef Y value_type; - typedef Y* pointer; - typedef const Y* const_pointer; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - typedef Y& reference; - typedef const Y& const_reference; - - template - struct rebind { - typedef ms_allocator other; - }; - - ms_allocator(type** result) - : data(result) { - } - - ms_allocator(std::size_t size, type** result) - : data(size, result) { - } - - template - ms_allocator(const ms_allocator& other) - : data(other.data) { - } - - pointer allocate(size_type count, const void* = 0) { - enum { - M = boost::alignment_of::value - }; - std::size_t n1 = count * sizeof(Y); - std::size_t n2 = data.size * sizeof(type); - std::size_t n3 = n2 + M; - void* p1 = ::operator new(n1 + n3); - void* p2 = static_cast(p1) + n1; - (void)boost::alignment::align(M, n2, p2, n3); - *data.result = static_cast(p2); - return static_cast(p1); - } - - void deallocate(pointer memory, size_type) { - void* p1 = memory; - ::operator delete(p1); - } - -#if defined(BOOST_NO_CXX11_ALLOCATOR) - pointer address(reference value) const { - return &value; - } - - const_pointer address(const_reference value) const { - return &value; - } - - size_type max_size() const { - enum { - N = static_cast(-1) / sizeof(Y) - }; - return N; - } - - void construct(pointer memory, const_reference value) { - void* p1 = memory; - ::new(p1) Y(value); - } - - void destroy(pointer memory) { - (void)memory; - memory->~Y(); - } -#endif - - void set(type* memory) { - data.object = memory; - } - - void operator()() { - if (data.object) { - ms_destroy(data.object, data.size); - } - } - - private: - ms_allocator_state data; - }; - - template - bool operator==(const ms_allocator&, - const ms_allocator&) { - return true; - } - - template - bool operator!=(const ms_allocator&, - const ms_allocator&) { - return false; - } - - class ms_in_allocator_tag { - public: - void operator()(const void*) { - } - }; - } -} - -#endif diff --git a/include/boost/smart_ptr/detail/array_count_impl.hpp b/include/boost/smart_ptr/detail/array_count_impl.hpp deleted file mode 100644 index b7c9617..0000000 --- a/include/boost/smart_ptr/detail/array_count_impl.hpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ -#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_COUNT_IMPL_HPP -#define BOOST_SMART_PTR_DETAIL_ARRAY_COUNT_IMPL_HPP - -#include -#include - -namespace boost { - namespace detail { - template - class sp_counted_impl_pda - : public sp_counted_base { - typedef ms_in_allocator_tag D; - typedef sp_counted_impl_pda Y; - public: - sp_counted_impl_pda(P, D, const A& allocator_) - : allocator(allocator_) { - } - - virtual void dispose() { - allocator(); - } - - virtual void destroy() { -#if !defined(BOOST_NO_CXX11_ALLOCATOR) - typedef typename std::allocator_traits:: - template rebind_alloc YA; - typedef typename std::allocator_traits:: - template rebind_traits YT; -#else - typedef typename A::template rebind::other YA; -#endif - YA a1(allocator); -#if !defined(BOOST_NO_CXX11_ALLOCATOR) - YT::destroy(a1, this); - YT::deallocate(a1, this, 1); -#else - this->~Y(); - a1.deallocate(this, 1); -#endif - } - - virtual void* get_deleter(const sp_typeinfo&) { - return &reinterpret_cast(allocator); - } - - virtual void* get_untyped_deleter() { - return &reinterpret_cast(allocator); - } - - private: - sp_counted_impl_pda(const sp_counted_impl_pda&); - sp_counted_impl_pda& operator=(const sp_counted_impl_pda&); - - A allocator; - }; - } -} - -#endif diff --git a/include/boost/smart_ptr/detail/array_traits.hpp b/include/boost/smart_ptr/detail/array_traits.hpp deleted file mode 100644 index 819c5ba..0000000 --- a/include/boost/smart_ptr/detail/array_traits.hpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2012-2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ -#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_TRAITS_HPP -#define BOOST_SMART_PTR_DETAIL_ARRAY_TRAITS_HPP - -#include - -namespace boost { - namespace detail { - template - struct array_base { - typedef typename boost::remove_cv::type type; - }; - - template - struct array_base { - typedef typename array_base::type type; - }; - - template - struct array_base { - typedef typename array_base::type type; - }; - - template - struct array_total { - enum { - size = 1 - }; - }; - - template - struct array_total { - enum { - size = N * array_total::size - }; - }; - - template - struct array_inner; - - template - struct array_inner { - typedef T type; - }; - - template - struct array_inner { - typedef T type; - }; - } -} - -#endif diff --git a/include/boost/smart_ptr/detail/array_utility.hpp b/include/boost/smart_ptr/detail/array_utility.hpp deleted file mode 100644 index 84029a1..0000000 --- a/include/boost/smart_ptr/detail/array_utility.hpp +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (c) 2012-2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ -#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_UTILITY_HPP -#define BOOST_SMART_PTR_DETAIL_ARRAY_UTILITY_HPP - -#include -#include -#include -#if !defined(BOOST_NO_CXX11_ALLOCATOR) -#include -#endif - -namespace boost { - namespace detail { - typedef boost::true_type ms_is_trivial; - typedef boost::false_type ms_no_trivial; - - template - inline void ms_destroy(T*, std::size_t, ms_is_trivial) { - } - - template - inline void ms_destroy(T* memory, std::size_t size, ms_no_trivial) { - for (std::size_t i = size; i > 0;) { - memory[--i].~T(); - } - } - - template - inline void ms_destroy(T* memory, std::size_t size) { - boost::has_trivial_destructor trivial; - ms_destroy(memory, size, trivial); - } - - template - inline void ms_init(T* memory, std::size_t size, ms_is_trivial) { - for (std::size_t i = 0; i < size; i++) { - void* p1 = memory + i; - ::new(p1) T(); - } - } - - template - inline void ms_init(T* memory, std::size_t size, ms_no_trivial) { -#if !defined(BOOST_NO_EXCEPTIONS) - std::size_t i = 0; - try { - for (; i < size; i++) { - void* p1 = memory + i; - ::new(p1) T(); - } - } catch (...) { - ms_destroy(memory, i); - throw; - } -#else - for (std::size_t i = 0; i < size; i++) { - void* p1 = memory + i; - ::new(p1) T(); - } -#endif - } - - template - inline void ms_init(T* memory, std::size_t size) { - boost::has_trivial_default_constructor trivial; - ms_init(memory, size, trivial); - } - - template - inline void ms_init(T* memory, std::size_t size, const T* list) { -#if !defined(BOOST_NO_EXCEPTIONS) - std::size_t i = 0; - try { - for (; i < size; i++) { - void* p1 = memory + i; - ::new(p1) T(list[i % N]); - } - } catch (...) { - ms_destroy(memory, i); - throw; - } -#else - for (std::size_t i = 0; i < size; i++) { - void* p1 = memory + i; - ::new(p1) T(list[i % N]); - } -#endif - } - -#if !defined(BOOST_NO_CXX11_ALLOCATOR) - template - inline void as_destroy(const A& allocator, T* memory, - std::size_t size) { - typedef typename std::allocator_traits:: - template rebind_alloc TA; - typedef typename std::allocator_traits:: - template rebind_traits TT; - TA a2(allocator); - for (std::size_t i = size; i > 0;) { - TT::destroy(a2, &memory[--i]); - } - } - - template - inline void as_init(const A& allocator, T* memory, std::size_t size, - ms_is_trivial) { - typedef typename std::allocator_traits:: - template rebind_alloc TA; - typedef typename std::allocator_traits:: - template rebind_traits TT; - TA a2(allocator); - for (std::size_t i = 0; i < size; i++) { - TT::construct(a2, memory + i); - } - } - - template - inline void as_init(const A& allocator, T* memory, std::size_t size, - ms_no_trivial) { - typedef typename std::allocator_traits:: - template rebind_alloc TA; - typedef typename std::allocator_traits:: - template rebind_traits TT; - TA a2(allocator); -#if !defined(BOOST_NO_EXCEPTIONS) - std::size_t i = 0; - try { - for (; i < size; i++) { - TT::construct(a2, memory + i); - } - } catch (...) { - as_destroy(a2, memory, i); - throw; - } -#else - for (std::size_t i = 0; i < size; i++) { - TT::construct(a2, memory + i); - } -#endif - } - - template - inline void as_init(const A& allocator, T* memory, std::size_t size) { - boost::has_trivial_default_constructor trivial; - as_init(allocator, memory, size, trivial); - } - - template - inline void as_init(const A& allocator, T* memory, std::size_t size, - const T* list) { - typedef typename std::allocator_traits:: - template rebind_alloc TA; - typedef typename std::allocator_traits:: - template rebind_traits TT; - TA a2(allocator); -#if !defined(BOOST_NO_EXCEPTIONS) - std::size_t i = 0; - try { - for (; i < size; i++) { - TT::construct(a2, memory + i, list[i % N]); - } - } catch (...) { - as_destroy(a2, memory, i); - throw; - } -#else - for (std::size_t i = 0; i < size; i++) { - TT::construct(a2, memory + i, list[i % N]); - } -#endif - } -#endif - - template - inline void ms_noinit(T*, std::size_t, ms_is_trivial) { - } - - template - inline void ms_noinit(T* memory, std::size_t size, ms_no_trivial) { -#if !defined(BOOST_NO_EXCEPTIONS) - std::size_t i = 0; - try { - for (; i < size; i++) { - void* p1 = memory + i; - ::new(p1) T; - } - } catch (...) { - ms_destroy(memory, i); - throw; - } -#else - for (std::size_t i = 0; i < size; i++) { - void* p1 = memory + i; - ::new(p1) T; - } -#endif - } - - template - inline void ms_noinit(T* memory, std::size_t size) { - boost::has_trivial_default_constructor trivial; - ms_noinit(memory, size, trivial); - } - } -} - -#endif diff --git a/include/boost/smart_ptr/detail/sp_if_array.hpp b/include/boost/smart_ptr/detail/sp_if_array.hpp deleted file mode 100644 index 9a2c1e0..0000000 --- a/include/boost/smart_ptr/detail/sp_if_array.hpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2012-2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ -#ifndef BOOST_SMART_PTR_DETAIL_SP_IF_ARRAY_HPP -#define BOOST_SMART_PTR_DETAIL_SP_IF_ARRAY_HPP - -#include - -namespace boost { - namespace detail { - template - struct sp_if_array; - - template - struct sp_if_array { - typedef boost::shared_ptr type; - }; - - template - struct sp_if_size_array; - - template - struct sp_if_size_array { - typedef boost::shared_ptr type; - }; - } -} - -#endif diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index c48f507..2eaf4db 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -1,158 +1,66 @@ /* - * Copyright (c) 2012-2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ +Copyright 2012-2017 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ #ifndef BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP #define BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP -#include -#include +#include namespace boost { - template - inline typename boost::detail::sp_if_array::type - make_shared(std::size_t size) { - typedef typename boost::detail::array_inner::type T1; - typedef typename boost::detail::array_base::type T2; - typedef boost::detail::ms_allocator A1; - typedef boost::detail::ms_in_allocator_tag D1; - std::size_t n1 = size * boost::detail::array_total::size; - T1* p1 = 0; - T2* p2 = 0; - D1 d1; - A1 a1(size, &p2); - shared_ptr s1(p1, d1, a1); - A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(0); - boost::detail::ms_init(p2, n1); - a2->set(p2); - p1 = reinterpret_cast(p2); - return shared_ptr(s1, p1); - } - template - inline typename boost::detail::sp_if_size_array::type - make_shared() { - typedef typename boost::detail::array_inner::type T1; - typedef typename boost::detail::array_base::type T2; - typedef boost::detail::ms_allocator A1; - typedef boost::detail::ms_in_allocator_tag D1; - enum { - N = boost::detail::array_total::size - }; - T1* p1 = 0; - T2* p2 = 0; - D1 d1; - A1 a1(&p2); - shared_ptr s1(p1, d1, a1); - A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(0); - boost::detail::ms_init(p2, N); - a2->set(p2); - p1 = reinterpret_cast(p2); - return shared_ptr(s1, p1); - } - - template - inline typename boost::detail::sp_if_array::type - make_shared(std::size_t size, - const typename boost::detail::array_inner::type& value) { - typedef typename boost::detail::array_inner::type T1; - typedef typename boost::detail::array_base::type T2; - typedef const T2 T3; - typedef boost::detail::ms_allocator A1; - typedef boost::detail::ms_in_allocator_tag D1; - enum { - M = boost::detail::array_total::size - }; - std::size_t n1 = M * size; - T1* p1 = 0; - T2* p2 = 0; - T3* p3 = reinterpret_cast(&value); - D1 d1; - A1 a1(size, &p2); - shared_ptr s1(p1, d1, a1); - A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(0); - boost::detail::ms_init(p2, n1, p3); - a2->set(p2); - p1 = reinterpret_cast(p2); - return shared_ptr(s1, p1); - } - - template - inline typename boost::detail::sp_if_size_array::type - make_shared(const typename boost::detail::array_inner::type& value) { - typedef typename boost::detail::array_inner::type T1; - typedef typename boost::detail::array_base::type T2; - typedef const T2 T3; - typedef boost::detail::ms_allocator A1; - typedef boost::detail::ms_in_allocator_tag D1; - enum { - M = boost::detail::array_total::size, - N = boost::detail::array_total::size - }; - T1* p1 = 0; - T2* p2 = 0; - T3* p3 = reinterpret_cast(&value); - D1 d1; - A1 a1(&p2); - shared_ptr s1(p1, d1, a1); - A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(0); - boost::detail::ms_init(p2, N, p3); - a2->set(p2); - p1 = reinterpret_cast(p2); - return shared_ptr(s1, p1); - } - - template - inline typename boost::detail::sp_if_array::type - make_shared_noinit(std::size_t size) { - typedef typename boost::detail::array_inner::type T1; - typedef typename boost::detail::array_base::type T2; - typedef boost::detail::ms_allocator A1; - typedef boost::detail::ms_in_allocator_tag D1; - std::size_t n1 = size * boost::detail::array_total::size; - T1* p1 = 0; - T2* p2 = 0; - D1 d1; - A1 a1(size, &p2); - shared_ptr s1(p1, d1, a1); - A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(0); - boost::detail::ms_noinit(p2, n1); - a2->set(p2); - p1 = reinterpret_cast(p2); - return shared_ptr(s1, p1); - } - - template - inline typename boost::detail::sp_if_size_array::type - make_shared_noinit() { - typedef typename boost::detail::array_inner::type T1; - typedef typename boost::detail::array_base::type T2; - typedef boost::detail::ms_allocator A1; - typedef boost::detail::ms_in_allocator_tag D1; - enum { - N = boost::detail::array_total::size - }; - T1* p1 = 0; - T2* p2 = 0; - D1 d1; - A1 a1(&p2); - shared_ptr s1(p1, d1, a1); - A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(0); - boost::detail::ms_noinit(p2, N); - a2->set(p2); - p1 = reinterpret_cast(p2); - return shared_ptr(s1, p1); - } +template +inline typename detail::sp_if_size_array::type +make_shared() +{ + return boost::allocate_shared(std::allocator::type>()); } +template +inline typename detail::sp_if_size_array::type +make_shared(const typename detail::sp_array_element::type& value) +{ + return boost::allocate_shared(std::allocator::type>(), value); +} + +template +inline typename detail::sp_if_array::type +make_shared(std::size_t size) +{ + return boost::allocate_shared(std::allocator::type>(), size); +} + +template +inline typename detail::sp_if_array::type +make_shared(std::size_t size, + const typename detail::sp_array_element::type& value) +{ + return boost::allocate_shared(std::allocator::type>(), size, value); +} + +template +inline typename detail::sp_if_size_array::type +make_shared_noinit() +{ + return allocate_shared_noinit(std::allocator::type>()); +} + +template +inline typename detail::sp_if_array::type +make_shared_noinit(std::size_t size) +{ + return allocate_shared_noinit(std::allocator::type>(), size); +} + +} /* boost */ + #endif