diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index a27b99f..aca4920 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -9,152 +9,166 @@ #ifndef BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP #define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP -#include -#include +#include #include -#include namespace boost { - template + 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 typename boost::remove_cv::type T3; - typedef boost::detail::as_allocator A1; - typedef boost::detail::as_deleter D1; - T1* p1 = 0; - T3* p2 = 0; + typedef boost::detail::ms_init_tag R1; + typedef boost::detail::ms_allocator A1; + typedef boost::detail::ms_noop D1; std::size_t n1 = size * boost::detail::array_total::size; - D1 d1(allocator, n1); - A1 a1(allocator, n1, &p2); - boost::shared_ptr s1(p1, d1, a1); - p1 = reinterpret_cast(p2); + T1* p1 = 0; + T2* p2 = 0; + D1 d1; + A1 a1(allocator, size, &p2); + shared_ptr s1(p1, d1, a1); +#if !defined(BOOST_NO_CXX11_ALLOCATOR) boost::detail::as_init(allocator, p2, n1); - D1* d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->set(p2); - return boost::shared_ptr(s1, p1); +#else + boost::detail::ms_init(p2, n1); +#endif + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->set(p2); + p1 = reinterpret_cast(p2); + return shared_ptr(s1, p1); } - template + 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 typename boost::remove_cv::type T3; + typedef boost::detail::ms_init_tag R1; + typedef boost::detail::ms_allocator A1; + typedef boost::detail::ms_noop D1; enum { N = boost::detail::array_total::size }; - typedef boost::detail::as_allocator A1; - typedef boost::detail::as_deleter D1; T1* p1 = 0; - T3* p2 = 0; - D1 d1(allocator); + T2* p2 = 0; + D1 d1; A1 a1(allocator, &p2); - boost::shared_ptr s1(p1, d1, a1); - p1 = reinterpret_cast(p2); + shared_ptr s1(p1, d1, a1); +#if !defined(BOOST_NO_CXX11_ALLOCATOR) boost::detail::as_init(allocator, p2, N); - D1* d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->set(p2); - return boost::shared_ptr(s1, p1); +#else + boost::detail::ms_init(p2, N); +#endif + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->set(p2); + p1 = reinterpret_cast(p2); + return shared_ptr(s1, p1); } - template + 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 typename boost::remove_cv::type T3; - typedef const T2 T4; - typedef boost::detail::as_allocator A1; - typedef boost::detail::as_deleter D1; + typedef const T2 T3; + typedef boost::detail::ms_init_tag R1; + typedef boost::detail::ms_allocator A1; + typedef boost::detail::ms_noop D1; enum { M = boost::detail::array_total::size }; - T1* p1 = 0; - T3* p2 = 0; - T4* p3 = reinterpret_cast(&value); std::size_t n1 = M * size; - D1 d1(allocator, n1); - A1 a1(allocator, n1, &p2); - boost::shared_ptr s1(p1, d1, a1); + T1* p1 = 0; + T2* p2 = 0; + T3* p3 = reinterpret_cast(&value); + D1 d1; + A1 a1(allocator, size, &p2); + shared_ptr s1(p1, d1, a1); +#if !defined(BOOST_NO_CXX11_ALLOCATOR) + boost::detail::as_init(allocator, p2, n1, p3); +#else + boost::detail::ms_init(p2, n1, p3); +#endif + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->set(p2); p1 = reinterpret_cast(p2); - boost::detail::as_init(allocator, p2, n1, p3); - D1* d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->set(p2); - return boost::shared_ptr(s1, p1); + return shared_ptr(s1, p1); } - template + 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 typename boost::remove_cv::type T3; - typedef const T2 T4; + typedef const T2 T3; + typedef boost::detail::ms_init_tag R1; + typedef boost::detail::ms_allocator A1; + typedef boost::detail::ms_noop D1; enum { - M = boost::detail::array_total::size, - N = boost::detail::array_total::size + N = boost::detail::array_total::size, + M = boost::detail::array_total::size }; - typedef boost::detail::as_allocator A1; - typedef boost::detail::as_deleter D1; T1* p1 = 0; - T3* p2 = 0; - T4* p3 = reinterpret_cast(&value); - D1 d1(allocator); + T2* p2 = 0; + T3* p3 = reinterpret_cast(&value); + D1 d1; A1 a1(allocator, &p2); - boost::shared_ptr s1(p1, d1, a1); + shared_ptr s1(p1, d1, a1); +#if !defined(BOOST_NO_CXX11_ALLOCATOR) + boost::detail::as_init(allocator, p2, N, p3); +#else + boost::detail::as_init(p2, N, p3); +#endif + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->set(p2); p1 = reinterpret_cast(p2); - boost::detail::as_init(allocator, p2, N, p3); - D1* d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->set(p2); - return boost::shared_ptr(s1, p1); + return shared_ptr(s1, p1); } - template + 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 typename boost::remove_cv::type T3; - typedef boost::detail::as_allocator A1; - typedef boost::detail::ms_deleter D1; - T1* p1 = 0; - T3* p2 = 0; + typedef boost::detail::ms_noinit_tag R1; + typedef boost::detail::ms_allocator A1; + typedef boost::detail::ms_noop D1; std::size_t n1 = size * boost::detail::array_total::size; - D1 d1(n1); - A1 a1(allocator, n1, &p2); - boost::shared_ptr s1(p1, d1, a1); - p1 = reinterpret_cast(p2); + T1* p1 = 0; + T2* p2 = 0; + D1 d1; + A1 a1(allocator, size, &p2); + shared_ptr s1(p1, d1, a1); boost::detail::ms_noinit(p2, n1); - D1* d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->set(p2); - return boost::shared_ptr(s1, p1); + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->set(p2); + p1 = reinterpret_cast(p2); + return shared_ptr(s1, p1); } - template + 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 typename boost::remove_cv::type T3; + typedef boost::detail::ms_noinit_tag R1; + typedef boost::detail::ms_allocator A1; + typedef boost::detail::ms_noop D1; enum { N = boost::detail::array_total::size }; - typedef boost::detail::as_allocator A1; - typedef boost::detail::ms_deleter D1; T1* p1 = 0; - T3* p2 = 0; + T2* p2 = 0; D1 d1; A1 a1(allocator, &p2); - boost::shared_ptr s1(p1, d1, a1); - p1 = reinterpret_cast(p2); + shared_ptr s1(p1, d1, a1); boost::detail::ms_noinit(p2, N); - D1* d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->set(p2); - return boost::shared_ptr(s1, p1); + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->set(p2); + p1 = reinterpret_cast(p2); + return shared_ptr(s1, p1); } } diff --git a/include/boost/smart_ptr/detail/allocator_pair.hpp b/include/boost/smart_ptr/detail/allocator_pair.hpp deleted file mode 100644 index 8910c90..0000000 --- a/include/boost/smart_ptr/detail/allocator_pair.hpp +++ /dev/null @@ -1,29 +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_ALLOCATOR_PAIR_HPP -#define BOOST_SMART_PTR_DETAIL_ALLOCATOR_PAIR_HPP - -#include - -namespace boost { - namespace detail { - template - struct as_pair - : A { - as_pair(const A& allocator, const T& value) - : A(allocator), - data(value) { - } - - T data; - }; - } -} - -#endif diff --git a/include/boost/smart_ptr/detail/array_allocator.hpp b/include/boost/smart_ptr/detail/array_allocator.hpp index cca57b7..fc55504 100644 --- a/include/boost/smart_ptr/detail/array_allocator.hpp +++ b/include/boost/smart_ptr/detail/array_allocator.hpp @@ -9,8 +9,8 @@ #ifndef BOOST_SMART_PTR_DETAIL_ARRAY_ALLOCATOR_HPP #define BOOST_SMART_PTR_DETAIL_ARRAY_ALLOCATOR_HPP -#include #include +#include #include #if !defined(BOOST_NO_CXX11_ALLOCATOR) #include @@ -18,32 +18,42 @@ namespace boost { namespace detail { - template - struct ms_allocator_base; + template + struct as_size_base; - template - struct ms_allocator_base { - ms_allocator_base(std::size_t size_) - : size(size_ * sizeof(T)) { + template + struct as_size_base + : A { + as_size_base(const A& allocator, std::size_t size_) + : A(allocator), + size(size_ * array_total::size) { } std::size_t size; }; - template - struct ms_allocator_base { + template + struct as_size_base + : A { + as_size_base(const A& allocator) + : A(allocator) { + } + enum { - size = N * sizeof(T) + size = array_total::size }; }; - template - class as_allocator - : ms_allocator_base { - using ms_allocator_base::size; + struct ms_init_tag { }; + struct ms_noinit_tag { }; - template - friend class as_allocator; + template + class ms_allocator + : as_size_base { + using as_size_base::size; + + template + friend class ms_allocator; #if !defined(BOOST_NO_CXX11_ALLOCATOR) typedef typename std::allocator_traits:: @@ -60,7 +70,7 @@ namespace boost { #endif public: - typedef typename array_inner::type type; + typedef typename array_base::type type; #if !defined(BOOST_NO_CXX11_ALLOCATOR) typedef typename YT::value_type value_type; @@ -80,52 +90,62 @@ namespace boost { typedef typename YA::const_reference const_reference; #endif - template + template struct rebind { - typedef as_allocator other; + typedef ms_allocator other; }; - as_allocator(const A& allocator, type** data) - : pair(allocator, data) { + ms_allocator(const A& allocator, type** data_) + : as_size_base(allocator), + data(data_), + object(0) { } - as_allocator(const A& allocator, std::size_t size_, type** data) - : ms_allocator_base(size_), - pair(allocator, data) { + ms_allocator(const A& allocator, std::size_t size_, type** data_) + : as_size_base(allocator, size_), + data(data_), + object(0) { } template - as_allocator(const as_allocator& other) - : ms_allocator_base(other), - pair(other.pair, other.pair.data) { + ms_allocator(const ms_allocator& other) + : as_size_base(other), + data(other.data), + object(other.object) { } pointer address(reference value) const { - return pair.address(value); + YA ya(*this); + return ya.address(value); } const_pointer address(const_reference value) const { - return pair.address(value); + YA ya(*this); + return ya.address(value); } size_type max_size() const { - return pair.max_size(); + YA ya(*this); + return ya.max_size(); } pointer allocate(size_type count, const void* value = 0) { - std::size_t a1 = boost::alignment_of::value; - std::size_t n1 = count * sizeof(value_type) + a1 - 1; - CA ca(pair); + enum { + M = boost::alignment_of::value + }; + std::size_t n1 = count * sizeof(value_type) + M - 1; + std::size_t n2 = size * sizeof(type); + CA ca(*this); #if !defined(BOOST_NO_CXX11_ALLOCATOR) - char* p1 = CT::allocate(ca, size + n1, value); + char* p1 = CT::allocate(ca, n1 + n2, value); #else - char* p1 = ca.allocate(size + n1, value); + char* p1 = ca.allocate(n1 + n2, value); #endif char* p2 = p1 + n1; - while (std::size_t(p2) % a1 != 0) { + while (std::size_t(p2) % M != 0) { p2--; } - *pair.data = reinterpret_cast(p2); + *data = reinterpret_cast(p2); return reinterpret_cast(p1); } @@ -133,7 +153,7 @@ namespace boost { std::size_t a1 = boost::alignment_of::value; std::size_t n1 = count * sizeof(value_type) + a1 - 1; char* p1 = reinterpret_cast(memory); - CA ca(pair); + CA ca(*this); #if !defined(BOOST_NO_CXX11_ALLOCATOR) CT::deallocate(ca, p1, size + n1); #else @@ -141,58 +161,105 @@ namespace boost { #endif } - template + template void construct(U* memory, const_reference value) { + YA ya(*this); #if !defined(BOOST_NO_CXX11_ALLOCATOR) - YT::construct(pair, memory, value); + YT::construct(ya, memory, value); #else - pair.construct(memory, value); + ya.construct(memory, value); #endif } - template + template void destroy(U* memory) { + YA ya(*this); #if !defined(BOOST_NO_CXX11_ALLOCATOR) - YT::destroy(pair, memory); + YT::destroy(ya, memory); #else - pair.destroy(memory); + ya.destroy(memory); #endif } #if !defined(BOOST_NO_CXX11_ALLOCATOR) && \ !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \ !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) - template + template void construct(U* memory, Args&&... args) { - YT::construct(pair, memory, std::forward(args)...); + YA ya(*this); + YT::construct(ya, memory, std::forward(args)...); } #endif - template - bool operator==(const as_allocator& other) const { - return pair == other.pair; + template + bool operator==(const ms_allocator& other) const { + return true; } - template - bool operator!=(const as_allocator& other) const { - return !(*this == other); + template + bool operator!=(const ms_allocator& other) const { + return !(*this == other); + } + + void set(type* memory) { + object = memory; + } + + void operator()() { + if (object) { + R tag; + free(tag); + } } private: - as_pair pair; + void free(ms_init_tag) { +#if !defined(BOOST_NO_CXX11_ALLOCATOR) + const A& a1(*this); + as_destroy(a1, object, size); +#else + ms_destroy(object, size); +#endif + } + + void free(ms_noinit_tag) { + ms_destroy(object, size); + } + + type** data; + type* object; }; - template - class ms_allocator - : ms_allocator_base { - using ms_allocator_base::size; + template + struct ms_size_base; - template + template + struct ms_size_base { + ms_size_base(std::size_t size_) + : size(size_ * array_total::size) { + } + + std::size_t size; + }; + + template + struct ms_size_base { + enum { + size = array_total::size + }; + }; + + template + class ms_allocator + : ms_size_base { + using ms_size_base::size; + + template friend class ms_allocator; public: - typedef typename array_inner::type type; + typedef typename array_base::type type; typedef Y value_type; typedef Y* pointer; typedef const Y* const_pointer; @@ -201,24 +268,27 @@ namespace boost { typedef Y& reference; typedef const Y& const_reference; - template + template struct rebind { - typedef ms_allocator other; + typedef ms_allocator other; }; ms_allocator(type** data_) - : data(data_) { + : data(data_), + object(0) { } ms_allocator(std::size_t size_, type** data_) - : ms_allocator_base(size_), - data(data_) { + : ms_size_base(size_), + data(data_), + object(0) { } template - ms_allocator(const ms_allocator& other) - : ms_allocator_base(other), - data(other.data) { + ms_allocator(const ms_allocator& other) + : ms_size_base(other), + data(other.data), + object(other.object) { } pointer address(reference value) const { @@ -237,11 +307,14 @@ namespace boost { } pointer allocate(size_type count, const void* = 0) { - std::size_t a1 = boost::alignment_of::value; - std::size_t n1 = count * sizeof(value_type) + a1 - 1; - void* p1 = ::operator new(n1 + size); + enum { + M = boost::alignment_of::value + }; + std::size_t n1 = count * sizeof(value_type) + M - 1; + std::size_t n2 = size * sizeof(type); + void* p1 = ::operator new(n1 + n2); char* p2 = static_cast(p1) + n1; - while (std::size_t(p2) % a1 != 0) { + while (std::size_t(p2) % M != 0) { p2--; } *data = reinterpret_cast(p2); @@ -253,13 +326,13 @@ namespace boost { ::operator delete(p1); } - template + template void construct(U* memory, const_reference value) { void* p1 = memory; ::new(p1) U(value); } - template + template void destroy(U* memory) { memory->~U(); } @@ -267,25 +340,42 @@ namespace boost { #if !defined(BOOST_NO_CXX11_ALLOCATOR) && \ !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \ !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) - template + template void construct(U* memory, Args&&... args) { void* p1 = memory; ::new(p1) U(std::forward(args)...); } #endif - template - bool operator==(const ms_allocator&) const { + template + bool operator==(const ms_allocator&) const { return true; } - template - bool operator!=(const ms_allocator& other) const { + template + bool operator!=(const ms_allocator& other) const { return !(*this == other); } + void set(type* memory) { + object = memory; + } + + void operator()() { + if (object) { + ms_destroy(object, size); + } + } + private: type** data; + type* object; + }; + + class ms_noop { + public: + void operator()(const void*) { + } }; } } diff --git a/include/boost/smart_ptr/detail/array_count_impl.hpp b/include/boost/smart_ptr/detail/array_count_impl.hpp new file mode 100644 index 0000000..503947e --- /dev/null +++ b/include/boost/smart_ptr/detail/array_count_impl.hpp @@ -0,0 +1,68 @@ +/* + * 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_noop D; + typedef ms_allocator A; + typedef sp_counted_impl_pda Y; + public: + sp_counted_impl_pda(const P&, const 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_deleter.hpp b/include/boost/smart_ptr/detail/array_deleter.hpp deleted file mode 100644 index ca320dc..0000000 --- a/include/boost/smart_ptr/detail/array_deleter.hpp +++ /dev/null @@ -1,109 +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_DELETER_HPP -#define BOOST_SMART_PTR_DETAIL_ARRAY_DELETER_HPP - -#include -#include -#include - -namespace boost { - namespace detail { - template - struct ms_deleter_base; - - template - struct ms_deleter_base { - ms_deleter_base(std::size_t size_) - : size(size_) { - } - - std::size_t size; - }; - - template - struct ms_deleter_base { - enum { - size = N - }; - }; - - template - class as_deleter - : ms_deleter_base { - using ms_deleter_base::size; - - public: - typedef typename array_inner::type type; - -#if !defined(BOOST_NO_CXX11_ALLOCATOR) - typedef typename std::allocator_traits:: - template rebind_alloc allocator; -#else - typedef typename A:: - template rebind::other allocator; -#endif - - as_deleter(const A& allocator_) - : pair(allocator_, 0) { - } - - as_deleter(const A& allocator_, std::size_t size_) - : ms_deleter_base(size_), - pair(allocator_, 0) { - } - - void set(type* memory) { - pair.data = memory; - } - - void operator()(const void*) { - if (pair.data) { - as_destroy(pair, pair.data, size); - } - } - - private: - as_pair pair; - }; - - template - class ms_deleter - : ms_deleter_base { - using ms_deleter_base::size; - - public: - typedef typename array_inner::type type; - - ms_deleter() - : object(0) { - } - - ms_deleter(std::size_t size_) - : ms_deleter_base(size_), - object(0) { - } - - void set(type* memory) { - object = memory; - } - - void operator()(const void*) { - if (object) { - ms_destroy(object, size); - } - } - - private: - type* object; - }; - } -} - -#endif diff --git a/include/boost/smart_ptr/detail/array_traits.hpp b/include/boost/smart_ptr/detail/array_traits.hpp index e10ef97..819c5ba 100644 --- a/include/boost/smart_ptr/detail/array_traits.hpp +++ b/include/boost/smart_ptr/detail/array_traits.hpp @@ -9,48 +9,48 @@ #ifndef BOOST_SMART_PTR_DETAIL_ARRAY_TRAITS_HPP #define BOOST_SMART_PTR_DETAIL_ARRAY_TRAITS_HPP -#include +#include namespace boost { namespace detail { - template + template struct array_base { - typedef T type; + typedef typename boost::remove_cv::type type; }; - template + template struct array_base { typedef typename array_base::type type; }; - template + template struct array_base { typedef typename array_base::type type; }; - template + template struct array_total { enum { size = 1 }; }; - template + template struct array_total { enum { size = N * array_total::size }; }; - template + template struct array_inner; - template + template struct array_inner { typedef T type; }; - template + template struct array_inner { typedef T type; }; diff --git a/include/boost/smart_ptr/detail/array_utility.hpp b/include/boost/smart_ptr/detail/array_utility.hpp index e4b690c..84029a1 100644 --- a/include/boost/smart_ptr/detail/array_utility.hpp +++ b/include/boost/smart_ptr/detail/array_utility.hpp @@ -21,43 +21,24 @@ namespace boost { typedef boost::true_type ms_is_trivial; typedef boost::false_type ms_no_trivial; - template + template inline void ms_destroy(T*, std::size_t, ms_is_trivial) { } - template + 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 + template inline void ms_destroy(T* memory, std::size_t size) { boost::has_trivial_destructor trivial; ms_destroy(memory, size, trivial); } -#if !defined(BOOST_NO_CXX11_ALLOCATOR) - template - inline void as_destroy(A& allocator, T* memory, - std::size_t size) { - typedef typename std::allocator_traits:: - template rebind_traits TT; - for (std::size_t i = size; i > 0;) { - TT::destroy(allocator, &memory[--i]); - } - } -#else - template - inline void as_destroy(const A&, T* memory, - std::size_t size) { - boost::has_trivial_destructor trivial; - ms_destroy(memory, size, trivial); - } -#endif - - template + 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; @@ -65,7 +46,7 @@ namespace boost { } } - template + template inline void ms_init(T* memory, std::size_t size, ms_no_trivial) { #if !defined(BOOST_NO_EXCEPTIONS) std::size_t i = 0; @@ -86,15 +67,48 @@ namespace boost { #endif } - template + 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 + 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:: @@ -107,8 +121,8 @@ namespace boost { } } - template - inline void as_init(const A& allocator, T* memory, std::size_t size, + 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; @@ -132,42 +146,13 @@ namespace boost { #endif } - template + 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); } -#else - template - inline void as_init(const A&, T* memory, std::size_t size) { - boost::has_trivial_default_constructor trivial; - ms_init(memory, size, trivial); - } -#endif - 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 + template inline void as_init(const A& allocator, T* memory, std::size_t size, const T* list) { typedef typename std::allocator_traits:: @@ -191,35 +176,13 @@ namespace boost { } #endif } -#else - template - inline void as_init(const A&, 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 - } #endif - template + template inline void ms_noinit(T*, std::size_t, ms_is_trivial) { } - template + template inline void ms_noinit(T* memory, std::size_t size, ms_no_trivial) { #if !defined(BOOST_NO_EXCEPTIONS) std::size_t i = 0; @@ -240,7 +203,7 @@ namespace boost { #endif } - template + template inline void ms_noinit(T* memory, std::size_t size) { boost::has_trivial_default_constructor trivial; ms_noinit(memory, size, trivial); diff --git a/include/boost/smart_ptr/detail/sp_if_array.hpp b/include/boost/smart_ptr/detail/sp_if_array.hpp index bbd0f3c..9a2c1e0 100644 --- a/include/boost/smart_ptr/detail/sp_if_array.hpp +++ b/include/boost/smart_ptr/detail/sp_if_array.hpp @@ -13,18 +13,18 @@ namespace boost { namespace detail { - template + template struct sp_if_array; - template + template struct sp_if_array { typedef boost::shared_ptr type; }; - template + template struct sp_if_size_array; - template + template struct sp_if_size_array { typedef boost::shared_ptr type; }; diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index 50763d8..65eb76f 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -9,151 +9,149 @@ #ifndef BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP #define BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP -#include -#include +#include #include -#include namespace boost { - template + 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 typename boost::remove_cv::type T3; - typedef boost::detail::ms_allocator A1; - typedef boost::detail::ms_deleter D1; + typedef boost::detail::ms_init_tag R1; + typedef boost::detail::ms_allocator A1; + typedef boost::detail::ms_noop D1; + std::size_t n1 = size * boost::detail::array_total::size; T1* p1 = 0; - T3* p2 = 0; - std::size_t n1 = size * boost::detail::array_total::size; - D1 d1(n1); + T2* p2 = 0; + D1 d1; A1 a1(n1, &p2); - boost::shared_ptr s1(p1, d1, a1); - p1 = reinterpret_cast(p2); + shared_ptr s1(p1, d1, a1); boost::detail::ms_init(p2, n1); - D1* d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->set(p2); - return boost::shared_ptr(s1, p1); + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->set(p2); + p1 = reinterpret_cast(p2); + return shared_ptr(s1, p1); } - template + 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 typename boost::remove_cv::type T3; + typedef boost::detail::ms_init_tag R1; + typedef boost::detail::ms_allocator A1; + typedef boost::detail::ms_noop D1; enum { N = boost::detail::array_total::size }; - typedef boost::detail::ms_allocator A1; - typedef boost::detail::ms_deleter D1; T1* p1 = 0; - T3* p2 = 0; + T2* p2 = 0; D1 d1; A1 a1(&p2); - boost::shared_ptr s1(p1, d1, a1); + shared_ptr s1(p1, d1, a1); p1 = reinterpret_cast(p2); boost::detail::ms_init(p2, N); - D1* d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->set(p2); - return boost::shared_ptr(s1, p1); + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->set(p2); + return shared_ptr(s1, p1); } - template + 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 typename boost::remove_cv::type T3; - typedef const T2 T4; - typedef boost::detail::ms_allocator A1; - typedef boost::detail::ms_deleter D1; + typedef const T2 T3; + typedef boost::detail::ms_init_tag R1; + typedef boost::detail::ms_allocator A1; + typedef boost::detail::ms_noop D1; enum { M = boost::detail::array_total::size }; - T1* p1 = 0; - T3* p2 = 0; - T4* p3 = reinterpret_cast(&value); std::size_t n1 = M * size; - D1 d1(n1); + T1* p1 = 0; + T2* p2 = 0; + T3* p3 = reinterpret_cast(&value); + D1 d1; A1 a1(n1, &p2); - boost::shared_ptr s1(p1, d1, a1); + shared_ptr s1(p1, d1, a1); + boost::detail::ms_init(p2, n1, p3); + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->set(p2); p1 = reinterpret_cast(p2); - boost::detail::ms_init(p2, n1, p3); - D1* d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->set(p2); - return boost::shared_ptr(s1, p1); + return shared_ptr(s1, p1); } - template + 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 typename boost::remove_cv::type T3; - typedef const T2 T4; + typedef const T2 T3; + typedef boost::detail::ms_init_tag R1; + typedef boost::detail::ms_allocator A1; + typedef boost::detail::ms_noop D1; enum { M = boost::detail::array_total::size, N = boost::detail::array_total::size - }; - typedef boost::detail::ms_allocator A1; - typedef boost::detail::ms_deleter D1; + }; T1* p1 = 0; - T3* p2 = 0; - T4* p3 = reinterpret_cast(&value); + T2* p2 = 0; + T3* p3 = reinterpret_cast(&value); D1 d1; A1 a1(&p2); - boost::shared_ptr s1(p1, d1, a1); + shared_ptr s1(p1, d1, a1); + boost::detail::ms_init(p2, N, p3); + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->set(p2); p1 = reinterpret_cast(p2); - boost::detail::ms_init(p2, N, p3); - D1* d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->set(p2); - return boost::shared_ptr(s1, p1); + return shared_ptr(s1, p1); } - template + 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 typename boost::remove_cv::type T3; - typedef boost::detail::ms_allocator A1; - typedef boost::detail::ms_deleter D1; + typedef boost::detail::ms_noinit_tag R1; + typedef boost::detail::ms_allocator A1; + typedef boost::detail::ms_noop D1; + std::size_t n1 = size * boost::detail::array_total::size; T1* p1 = 0; - T3* p2 = 0; - std::size_t n1 = size * boost::detail::array_total::size; - D1 d1(n1); + T2* p2 = 0; + D1 d1; A1 a1(n1, &p2); - boost::shared_ptr s1(p1, d1, a1); + shared_ptr s1(p1, d1, a1); p1 = reinterpret_cast(p2); boost::detail::ms_noinit(p2, n1); - D1* d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->set(p2); - return boost::shared_ptr(s1, p1); + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->set(p2); + return shared_ptr(s1, p1); } - template + 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 typename boost::remove_cv::type T3; + typedef boost::detail::ms_noinit_tag R1; + typedef boost::detail::ms_allocator A1; + typedef boost::detail::ms_noop D1; enum { N = boost::detail::array_total::size }; - typedef boost::detail::ms_allocator A1; - typedef boost::detail::ms_deleter D1; T1* p1 = 0; - T3* p2 = 0; + T2* p2 = 0; D1 d1; A1 a1(&p2); - boost::shared_ptr s1(p1, d1, a1); + shared_ptr s1(p1, d1, a1); p1 = reinterpret_cast(p2); boost::detail::ms_noinit(p2, N); - D1* d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->set(p2); - return boost::shared_ptr(s1, p1); + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->set(p2); + return shared_ptr(s1, p1); } }