From 3d279e6c6d668d56db4722618ebc78580c542e71 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Wed, 12 Feb 2014 13:45:28 -0800 Subject: [PATCH] Save additional sizeof(void*) bytes for arrays --- .../boost/smart_ptr/allocate_shared_array.hpp | 54 ++++---- .../smart_ptr/detail/array_allocator.hpp | 120 ++++++++++-------- .../smart_ptr/detail/array_count_impl.hpp | 2 +- include/boost/smart_ptr/make_shared_array.hpp | 42 +++--- 4 files changed, 120 insertions(+), 98 deletions(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index e64047f..c91d4da 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -19,22 +19,23 @@ namespace boost { 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::ms_allocator A1; + 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); + A1 a1(allocator, size); shared_ptr s1(p1, d1, a1); + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->swap(p2); #if !defined(BOOST_NO_CXX11_ALLOCATOR) boost::detail::as_init(allocator, p2, n1); #else boost::detail::ms_init(p2, n1); #endif - A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(p2); p1 = reinterpret_cast(p2); + a2->swap(p2); return shared_ptr(s1, p1); } @@ -44,7 +45,7 @@ namespace boost { 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::ms_allocator A1; + typedef boost::detail::as_allocator A1; typedef boost::detail::ms_in_allocator_tag D1; enum { N = boost::detail::array_total::size @@ -52,16 +53,17 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; D1 d1; - A1 a1(allocator, &p2); + A1 a1(allocator); shared_ptr s1(p1, d1, a1); + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->swap(p2); #if !defined(BOOST_NO_CXX11_ALLOCATOR) boost::detail::as_init(allocator, p2, N); #else boost::detail::ms_init(p2, N); #endif - A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(p2); p1 = reinterpret_cast(p2); + a2->swap(p2); return shared_ptr(s1, p1); } @@ -73,7 +75,7 @@ namespace boost { typedef typename boost::detail::array_base::type T2; typedef const T2 T3; typedef boost::detail::ms_init_tag R1; - typedef boost::detail::ms_allocator A1; + typedef boost::detail::as_allocator A1; typedef boost::detail::ms_in_allocator_tag D1; enum { M = boost::detail::array_total::size @@ -83,16 +85,17 @@ namespace boost { T2* p2 = 0; T3* p3 = reinterpret_cast(&value); D1 d1; - A1 a1(allocator, size, &p2); + A1 a1(allocator, size); shared_ptr s1(p1, d1, a1); + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->swap(p2); #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); + a2->swap(p2); return shared_ptr(s1, p1); } @@ -104,7 +107,7 @@ namespace boost { typedef typename boost::detail::array_base::type T2; typedef const T2 T3; typedef boost::detail::ms_init_tag R1; - typedef boost::detail::ms_allocator A1; + typedef boost::detail::as_allocator A1; typedef boost::detail::ms_in_allocator_tag D1; enum { N = boost::detail::array_total::size, @@ -114,16 +117,17 @@ namespace boost { T2* p2 = 0; T3* p3 = reinterpret_cast(&value); D1 d1; - A1 a1(allocator, &p2); + A1 a1(allocator); shared_ptr s1(p1, d1, a1); + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->swap(p2); #if !defined(BOOST_NO_CXX11_ALLOCATOR) boost::detail::as_init(allocator, p2, N, p3); #else boost::detail::ms_init(p2, N, p3); #endif - A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(p2); p1 = reinterpret_cast(p2); + a2->swap(p2); return shared_ptr(s1, p1); } @@ -133,18 +137,19 @@ namespace boost { 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::ms_allocator A1; + 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); + A1 a1(allocator, size); shared_ptr s1(p1, d1, a1); - boost::detail::ms_noinit(p2, n1); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(p2); + a2->swap(p2); + boost::detail::ms_noinit(p2, n1); p1 = reinterpret_cast(p2); + a2->swap(p2); return shared_ptr(s1, p1); } @@ -154,7 +159,7 @@ namespace boost { 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::ms_allocator A1; + typedef boost::detail::as_allocator A1; typedef boost::detail::ms_in_allocator_tag D1; enum { N = boost::detail::array_total::size @@ -162,12 +167,13 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; D1 d1; - A1 a1(allocator, &p2); + A1 a1(allocator); shared_ptr s1(p1, d1, a1); - boost::detail::ms_noinit(p2, N); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(p2); + a2->swap(p2); + boost::detail::ms_noinit(p2, N); p1 = reinterpret_cast(p2); + a2->swap(p2); return shared_ptr(s1, p1); } } diff --git a/include/boost/smart_ptr/detail/array_allocator.hpp b/include/boost/smart_ptr/detail/array_allocator.hpp index ce918b9..2289084 100644 --- a/include/boost/smart_ptr/detail/array_allocator.hpp +++ b/include/boost/smart_ptr/detail/array_allocator.hpp @@ -12,9 +12,7 @@ #include #include #include -#if !defined(BOOST_NO_CXX11_ALLOCATOR) -#include -#endif +#include namespace boost { namespace detail { @@ -47,13 +45,13 @@ namespace boost { struct ms_init_tag { }; struct ms_noinit_tag { }; - template - class ms_allocator + template + class as_allocator : as_size_base { using as_size_base::size; template - friend class ms_allocator; + friend class as_allocator; #if !defined(BOOST_NO_CXX11_ALLOCATOR) typedef typename std::allocator_traits:: @@ -92,25 +90,36 @@ namespace boost { template struct rebind { - typedef ms_allocator other; + typedef as_allocator other; }; - ms_allocator(const A& allocator, type** data_) + as_allocator(const A& allocator) : as_size_base(allocator), - data(data_), object(0) { } - ms_allocator(const A& allocator, std::size_t size_, type** data_) + as_allocator(const A& allocator, std::size_t size_) : as_size_base(allocator, size_), - data(data_), object(0) { } template - ms_allocator(const ms_allocator& other) + as_allocator(const as_allocator& other, U* memory) + : as_size_base(other) { + enum { + M = boost::alignment_of::value + }; + std::size_t n1 = sizeof(U) + M - 1; + char* p1 = reinterpret_cast(memory) + n1; + while (std::size_t(p1) % M != 0) { + p1--; + } + object = reinterpret_cast(p1); + } + + template + as_allocator(const as_allocator& other) : as_size_base(other), - data(other.data), object(other.object) { } @@ -129,29 +138,26 @@ namespace boost { return ya.max_size(); } - pointer allocate(size_type count, const void* value = 0) { + pointer allocate(size_type, const void* value = 0) { enum { M = boost::alignment_of::value }; - std::size_t n1 = count * sizeof(value_type) + M - 1; + std::size_t n1 = 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, n1 + n2, value); + void* p1 = CT::allocate(ca, n1 + n2, value); #else - char* p1 = ca.allocate(n1 + n2, value); + void* p1 = ca.allocate(n1 + n2, value); #endif - char* p2 = p1 + n1; - while (std::size_t(p2) % M != 0) { - p2--; - } - *data = reinterpret_cast(p2); - return reinterpret_cast(p1); + return static_cast(p1); } - void deallocate(pointer memory, size_type count) { - std::size_t a1 = boost::alignment_of::value; - std::size_t n1 = count * sizeof(value_type) + a1 - 1; + void deallocate(pointer memory, size_type) { + enum { + M = boost::alignment_of::value + }; + std::size_t n1 = sizeof(value_type) + M - 1; char* p1 = reinterpret_cast(memory); CA ca(*this); #if !defined(BOOST_NO_CXX11_ALLOCATOR) @@ -193,17 +199,17 @@ namespace boost { #endif template - bool operator==(const ms_allocator& other) const { + bool operator==(const as_allocator& other) const { return true; } template - bool operator!=(const ms_allocator& other) const { + bool operator!=(const as_allocator& other) const { return !(*this == other); } - void set(type* memory) { - object = memory; + void swap(type*& other) { + std::swap(object, other); } void operator()() { @@ -227,7 +233,6 @@ namespace boost { ms_destroy(object, size); } - type** data; type* object; }; @@ -250,12 +255,12 @@ namespace boost { }; }; - template - class ms_allocator + template + class ms_allocator : ms_size_base { using ms_size_base::size; - template + template friend class ms_allocator; public: @@ -270,24 +275,35 @@ namespace boost { template struct rebind { - typedef ms_allocator other; + typedef ms_allocator other; }; - ms_allocator(type** data_) - : data(data_), - object(0) { + ms_allocator() + : object(0) { } - ms_allocator(std::size_t size_, type** data_) + ms_allocator(std::size_t size_) : ms_size_base(size_), - data(data_), object(0) { } template - ms_allocator(const ms_allocator& other) + ms_allocator(const ms_allocator& other, U* memory) + : ms_size_base(other) { + enum { + M = boost::alignment_of::value + }; + std::size_t n1 = sizeof(U) + M - 1; + char* p1 = reinterpret_cast(memory) + n1; + while (std::size_t(p1) % M != 0) { + p1--; + } + object = reinterpret_cast(p1); + } + + template + ms_allocator(const ms_allocator& other) : ms_size_base(other), - data(other.data), object(other.object) { } @@ -306,19 +322,14 @@ namespace boost { return N; } - pointer allocate(size_type count, const void* = 0) { + pointer allocate(size_type, const void* = 0) { enum { M = boost::alignment_of::value }; - std::size_t n1 = count * sizeof(value_type) + M - 1; + std::size_t n1 = 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) % M != 0) { - p2--; - } - *data = reinterpret_cast(p2); - return reinterpret_cast(p1); + return static_cast(p1); } void deallocate(pointer memory, size_type) { @@ -348,17 +359,17 @@ namespace boost { #endif template - bool operator==(const ms_allocator&) const { + bool operator==(const ms_allocator&) const { return true; } template - bool operator!=(const ms_allocator& other) const { + bool operator!=(const ms_allocator& other) const { return !(*this == other); } - void set(type* memory) { - object = memory; + void swap(type*& other) { + std::swap(object, other); } void operator()() { @@ -368,7 +379,6 @@ namespace boost { } private: - type** data; type* object; }; diff --git a/include/boost/smart_ptr/detail/array_count_impl.hpp b/include/boost/smart_ptr/detail/array_count_impl.hpp index f81954d..da2d9dd 100644 --- a/include/boost/smart_ptr/detail/array_count_impl.hpp +++ b/include/boost/smart_ptr/detail/array_count_impl.hpp @@ -21,7 +21,7 @@ namespace boost { typedef sp_counted_impl_pda Y; public: sp_counted_impl_pda(P, const D&, const A& allocator_) - : allocator(allocator_) { + : allocator(allocator_, this) { } virtual void dispose() { diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index 362c3f8..96a45dc 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -25,12 +25,13 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; D1 d1; - A1 a1(size, &p2); + A1 a1(size); shared_ptr s1(p1, d1, a1); - boost::detail::ms_init(p2, n1); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(p2); + a2->swap(p2); + boost::detail::ms_init(p2, n1); p1 = reinterpret_cast(p2); + a2->swap(p2); return shared_ptr(s1, p1); } @@ -48,12 +49,13 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; D1 d1; - A1 a1(&p2); + A1 a1; shared_ptr s1(p1, d1, a1); - boost::detail::ms_init(p2, N); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(p2); + a2->swap(p2); + boost::detail::ms_init(p2, N); p1 = reinterpret_cast(p2); + a2->swap(p2); return shared_ptr(s1, p1); } @@ -75,12 +77,13 @@ namespace boost { T2* p2 = 0; T3* p3 = reinterpret_cast(&value); D1 d1; - A1 a1(size, &p2); + A1 a1(size); 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); + a2->swap(p2); + boost::detail::ms_init(p2, n1, p3); p1 = reinterpret_cast(p2); + a2->swap(p2); return shared_ptr(s1, p1); } @@ -101,12 +104,13 @@ namespace boost { T2* p2 = 0; T3* p3 = reinterpret_cast(&value); D1 d1; - A1 a1(&p2); + A1 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); + a2->swap(p2); + boost::detail::ms_init(p2, N, p3); p1 = reinterpret_cast(p2); + a2->swap(p2); return shared_ptr(s1, p1); } @@ -122,12 +126,13 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; D1 d1; - A1 a1(size, &p2); + A1 a1(size); shared_ptr s1(p1, d1, a1); - boost::detail::ms_noinit(p2, n1); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(p2); + a2->swap(p2); + boost::detail::ms_noinit(p2, n1); p1 = reinterpret_cast(p2); + a2->swap(p2); return shared_ptr(s1, p1); } @@ -145,12 +150,13 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; D1 d1; - A1 a1(&p2); + A1 a1; shared_ptr s1(p1, d1, a1); - boost::detail::ms_noinit(p2, N); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(p2); + a2->swap(p2); + boost::detail::ms_noinit(p2, N); p1 = reinterpret_cast(p2); + a2->swap(p2); return shared_ptr(s1, p1); } }