From d593061b150bec1a3e289b4ad9725519e7009bbe Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Thu, 2 May 2019 08:30:34 -0400 Subject: [PATCH] Move construct and destroy utilities to common header --- .../boost/smart_ptr/allocate_shared_array.hpp | 113 +--------- .../boost/smart_ptr/detail/sp_construct.hpp | 207 ++++++++++++++++++ 2 files changed, 211 insertions(+), 109 deletions(-) create mode 100644 include/boost/smart_ptr/detail/sp_construct.hpp diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index 5022bf2..23d5046 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -9,6 +9,7 @@ Distributed under the Boost Software License, Version 1.0. #define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP #include +#include #include #include #include @@ -68,111 +69,6 @@ sp_objects(std::size_t size) BOOST_SP_NOEXCEPT return (size + sizeof(T) - 1) / sizeof(T); } -#if !defined(BOOST_NO_CXX11_ALLOCATOR) -template -inline void -sp_array_destroy(A& allocator, T* ptr, std::size_t size) -{ - while (size > 0) { - std::allocator_traits::destroy(allocator, ptr + --size); - } -} -#else -template -inline void -sp_array_destroy(A&, T* ptr, std::size_t size) -{ - while (size > 0) { - ptr[--size].~T(); - } -} -#endif - -template -class sp_destroyer { -public: - sp_destroyer(A& allocator, T* ptr) BOOST_SP_NOEXCEPT - : allocator_(allocator), - ptr_(ptr), - size_(0) { } - - ~sp_destroyer() { - sp_array_destroy(allocator_, ptr_, size_); - } - - std::size_t& size() BOOST_SP_NOEXCEPT { - return size_; - } - -private: - sp_destroyer(const sp_destroyer&); - sp_destroyer& operator=(const sp_destroyer&); - - A& allocator_; - T* ptr_; - std::size_t size_; -}; - -#if !defined(BOOST_NO_CXX11_ALLOCATOR) -template -inline void -sp_array_construct(A& allocator, T* ptr, std::size_t size) -{ - sp_destroyer hold(allocator, ptr); - for (std::size_t& i = hold.size(); i < size; ++i) { - std::allocator_traits::construct(allocator, ptr + i); - } - hold.size() = 0; -} - -template -inline void -sp_array_construct(A& allocator, T* ptr, std::size_t size, const T* list, - std::size_t count) -{ - sp_destroyer hold(allocator, ptr); - for (std::size_t& i = hold.size(); i < size; ++i) { - std::allocator_traits::construct(allocator, ptr + i, - list[i % count]); - } - hold.size() = 0; -} -#else -template -inline void -sp_array_construct(A& none, T* ptr, std::size_t size) -{ - sp_destroyer hold(none, ptr); - for (std::size_t& i = hold.size(); i < size; ++i) { - ::new(static_cast(ptr + i)) T(); - } - hold.size() = 0; -} - -template -inline void -sp_array_construct(boost::noinit_adaptor& none, T* ptr, std::size_t size) -{ - sp_destroyer, T> hold(none, ptr); - for (std::size_t& i = hold.size(); i < size; ++i) { - ::new(static_cast(ptr + i)) T; - } - hold.size() = 0; -} - -template -inline void -sp_array_construct(A& none, T* ptr, std::size_t size, const T* list, - std::size_t count) -{ - sp_destroyer hold(none, ptr); - for (std::size_t& i = hold.size(); i < size; ++i) { - ::new(static_cast(ptr + i)) T(list[i % count]); - } - hold.size() = 0; -} -#endif - template class sp_array_state { public: @@ -290,15 +186,14 @@ public: template sp_array_base(const A& other, std::size_t size, type* start) : state_(other, size) { - sp_array_construct(state_.allocator(), start, state_.size()); + sp_construct_n(state_.allocator(), start, state_.size()); } template sp_array_base(const A& other, std::size_t size, const type* list, std::size_t count, type* start) : state_(other, size) { - sp_array_construct(state_.allocator(), start, state_.size(), list, - count); + sp_construct_n(state_.allocator(), start, state_.size(), list, count); } T& state() BOOST_SP_NOEXCEPT { @@ -306,7 +201,7 @@ public: } virtual void dispose() BOOST_SP_NOEXCEPT { - sp_array_destroy(state_.allocator(), + sp_destroy_n(state_.allocator(), sp_array_start(this), state_.size()); } diff --git a/include/boost/smart_ptr/detail/sp_construct.hpp b/include/boost/smart_ptr/detail/sp_construct.hpp new file mode 100644 index 0000000..51451fe --- /dev/null +++ b/include/boost/smart_ptr/detail/sp_construct.hpp @@ -0,0 +1,207 @@ +/* +Copyright 2012-2019 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_DETAIL_SP_CONSTRUCT_HPP +#define BOOST_SMART_PTR_DETAIL_SP_CONSTRUCT_HPP + +#include + +namespace boost { +namespace detail { + +#if !defined(BOOST_NO_CXX11_ALLOCATOR) +template +inline void +sp_destroy(A& a, T* p) +{ + std::allocator_traits::destroy(a, p); +} + +template +inline void +sp_destroy_n(A& a, T* p, std::size_t n) +{ + while (n > 0) { + std::allocator_traits::destroy(a, p + --n); + } +} +#else +template +inline void +sp_destroy(A&, T* p) +{ + p->~T(); +} + +template +inline void +sp_destroy_n(A&, T* p, std::size_t n) +{ + while (n > 0) { + p[--n].~T(); + } +} +#endif + +template +class sp_destroyer { +public: + sp_destroyer(A& a, T* p) BOOST_SP_NOEXCEPT + : a_(a), + p_(p), + n_(0) { } + + ~sp_destroyer() { + sp_destroy_n(a_, p_, n_); + } + + std::size_t& size() BOOST_SP_NOEXCEPT { + return n_; + } + +private: + sp_destroyer(const sp_destroyer&); + sp_destroyer& operator=(const sp_destroyer&); + + A& a_; + T* p_; + std::size_t n_; +}; + +#if !defined(BOOST_NO_CXX11_ALLOCATOR) +template +inline void +sp_construct(A& a, T* p) +{ + std::allocator_traits::construct(a, p); +} + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +template +inline void +sp_construct(A& a, T* p, U&& u, V&&... v) +{ + std::allocator_traits::construct(a, p, std::forward(u), + std::forward(v)...); +} +#else +template +inline void +sp_construct(A& a, T* p, U&& u) +{ + std::allocator_traits::construct(a, p, std::forward(u)); +} +#endif +#else +template +inline void +sp_construct(A& a, T* p, const U& u) +{ + std::allocator_traits::construct(a, p, u); +} +#endif + +template +inline void +sp_construct_n(A& a, T* p, std::size_t n) +{ + sp_destroyer hold(a, p); + for (std::size_t& i = hold.size(); i < n; ++i) { + std::allocator_traits::construct(a, p + i); + } + hold.size() = 0; +} + +template +inline void +sp_construct_n(A& a, T* p, std::size_t n, const T* l, std::size_t m) +{ + sp_destroyer hold(a, p); + for (std::size_t& i = hold.size(); i < n; ++i) { + std::allocator_traits::construct(a, p + i, l[i % m]); + } + hold.size() = 0; +} +#else +template +inline void +sp_construct(A&, T* p) +{ + ::new(static_cast(p)) T(); +} + +template +inline void +sp_construct(boost::noinit_adaptor&, T* p) +{ + ::new(static_cast(p)) T; +} + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +template +inline void +sp_construct(A&, T* p, U&& u, V&&... v) +{ + ::new(static_cast(p)) T(std::forward(u), std::forward(v)...); +} +#else +template +inline void +sp_construct(A&, T* p, U&& u) +{ + ::new(static_cast(p)) T(std::forward(u)); +} +#endif +#else +template +inline void +sp_construct(A&, T* p, const U& u) +{ + ::new(static_cast(p)) T(u); +} +#endif + +template +inline void +sp_construct_n(A& a, T* p, std::size_t n) +{ + sp_destroyer hold(a, p); + for (std::size_t& i = hold.size(); i < n; ++i) { + ::new(static_cast(p + i)) T(); + } + hold.size() = 0; +} + +template +inline void +sp_construct_n(boost::noinit_adaptor& a, T* p, std::size_t n) +{ + sp_destroyer, T> hold(a, p); + for (std::size_t& i = hold.size(); i < n; ++i) { + ::new(static_cast(p + i)) T; + } + hold.size() = 0; +} + +template +inline void +sp_construct_n(A& a, T* p, std::size_t n, const T* l, std::size_t m) +{ + sp_destroyer hold(a, p); + for (std::size_t& i = hold.size(); i < n; ++i) { + ::new(static_cast(p + i)) T(l[i % m]); + } + hold.size() = 0; +} +#endif + +} /* detail */ +} /* boost */ + +#endif