forked from boostorg/smart_ptr
Move construct and destroy utilities to common header
This commit is contained in:
@ -9,6 +9,7 @@ Distributed under the Boost Software License, Version 1.0.
|
|||||||
#define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
|
#define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
|
||||||
|
|
||||||
#include <boost/core/noinit_adaptor.hpp>
|
#include <boost/core/noinit_adaptor.hpp>
|
||||||
|
#include <boost/smart_ptr/detail/sp_construct.hpp>
|
||||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||||
#include <boost/type_traits/alignment_of.hpp>
|
#include <boost/type_traits/alignment_of.hpp>
|
||||||
#include <boost/type_traits/enable_if.hpp>
|
#include <boost/type_traits/enable_if.hpp>
|
||||||
@ -68,111 +69,6 @@ sp_objects(std::size_t size) BOOST_SP_NOEXCEPT
|
|||||||
return (size + sizeof(T) - 1) / sizeof(T);
|
return (size + sizeof(T) - 1) / sizeof(T);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
|
||||||
template<class A, class T>
|
|
||||||
inline void
|
|
||||||
sp_array_destroy(A& allocator, T* ptr, std::size_t size)
|
|
||||||
{
|
|
||||||
while (size > 0) {
|
|
||||||
std::allocator_traits<A>::destroy(allocator, ptr + --size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
template<class A, class T>
|
|
||||||
inline void
|
|
||||||
sp_array_destroy(A&, T* ptr, std::size_t size)
|
|
||||||
{
|
|
||||||
while (size > 0) {
|
|
||||||
ptr[--size].~T();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<class A, class T>
|
|
||||||
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<class A, class T>
|
|
||||||
inline void
|
|
||||||
sp_array_construct(A& allocator, T* ptr, std::size_t size)
|
|
||||||
{
|
|
||||||
sp_destroyer<A, T> hold(allocator, ptr);
|
|
||||||
for (std::size_t& i = hold.size(); i < size; ++i) {
|
|
||||||
std::allocator_traits<A>::construct(allocator, ptr + i);
|
|
||||||
}
|
|
||||||
hold.size() = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class A, class T>
|
|
||||||
inline void
|
|
||||||
sp_array_construct(A& allocator, T* ptr, std::size_t size, const T* list,
|
|
||||||
std::size_t count)
|
|
||||||
{
|
|
||||||
sp_destroyer<A, T> hold(allocator, ptr);
|
|
||||||
for (std::size_t& i = hold.size(); i < size; ++i) {
|
|
||||||
std::allocator_traits<A>::construct(allocator, ptr + i,
|
|
||||||
list[i % count]);
|
|
||||||
}
|
|
||||||
hold.size() = 0;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
template<class A, class T>
|
|
||||||
inline void
|
|
||||||
sp_array_construct(A& none, T* ptr, std::size_t size)
|
|
||||||
{
|
|
||||||
sp_destroyer<A, T> hold(none, ptr);
|
|
||||||
for (std::size_t& i = hold.size(); i < size; ++i) {
|
|
||||||
::new(static_cast<void*>(ptr + i)) T();
|
|
||||||
}
|
|
||||||
hold.size() = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class A, class T>
|
|
||||||
inline void
|
|
||||||
sp_array_construct(boost::noinit_adaptor<A>& none, T* ptr, std::size_t size)
|
|
||||||
{
|
|
||||||
sp_destroyer<boost::noinit_adaptor<A>, T> hold(none, ptr);
|
|
||||||
for (std::size_t& i = hold.size(); i < size; ++i) {
|
|
||||||
::new(static_cast<void*>(ptr + i)) T;
|
|
||||||
}
|
|
||||||
hold.size() = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class A, class T>
|
|
||||||
inline void
|
|
||||||
sp_array_construct(A& none, T* ptr, std::size_t size, const T* list,
|
|
||||||
std::size_t count)
|
|
||||||
{
|
|
||||||
sp_destroyer<A, T> hold(none, ptr);
|
|
||||||
for (std::size_t& i = hold.size(); i < size; ++i) {
|
|
||||||
::new(static_cast<void*>(ptr + i)) T(list[i % count]);
|
|
||||||
}
|
|
||||||
hold.size() = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<class A>
|
template<class A>
|
||||||
class sp_array_state {
|
class sp_array_state {
|
||||||
public:
|
public:
|
||||||
@ -290,15 +186,14 @@ public:
|
|||||||
template<class A>
|
template<class A>
|
||||||
sp_array_base(const A& other, std::size_t size, type* start)
|
sp_array_base(const A& other, std::size_t size, type* start)
|
||||||
: state_(other, size) {
|
: state_(other, size) {
|
||||||
sp_array_construct(state_.allocator(), start, state_.size());
|
sp_construct_n(state_.allocator(), start, state_.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class A>
|
template<class A>
|
||||||
sp_array_base(const A& other, std::size_t size, const type* list,
|
sp_array_base(const A& other, std::size_t size, const type* list,
|
||||||
std::size_t count, type* start)
|
std::size_t count, type* start)
|
||||||
: state_(other, size) {
|
: state_(other, size) {
|
||||||
sp_array_construct(state_.allocator(), start, state_.size(), list,
|
sp_construct_n(state_.allocator(), start, state_.size(), list, count);
|
||||||
count);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
T& state() BOOST_SP_NOEXCEPT {
|
T& state() BOOST_SP_NOEXCEPT {
|
||||||
@ -306,7 +201,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void dispose() BOOST_SP_NOEXCEPT {
|
virtual void dispose() BOOST_SP_NOEXCEPT {
|
||||||
sp_array_destroy(state_.allocator(),
|
sp_destroy_n(state_.allocator(),
|
||||||
sp_array_start<sp_array_base, type>(this), state_.size());
|
sp_array_start<sp_array_base, type>(this), state_.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
207
include/boost/smart_ptr/detail/sp_construct.hpp
Normal file
207
include/boost/smart_ptr/detail/sp_construct.hpp
Normal file
@ -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 <boost/core/noinit_adaptor.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||||
|
template<class A, class T>
|
||||||
|
inline void
|
||||||
|
sp_destroy(A& a, T* p)
|
||||||
|
{
|
||||||
|
std::allocator_traits<A>::destroy(a, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class A, class T>
|
||||||
|
inline void
|
||||||
|
sp_destroy_n(A& a, T* p, std::size_t n)
|
||||||
|
{
|
||||||
|
while (n > 0) {
|
||||||
|
std::allocator_traits<A>::destroy(a, p + --n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
template<class A, class T>
|
||||||
|
inline void
|
||||||
|
sp_destroy(A&, T* p)
|
||||||
|
{
|
||||||
|
p->~T();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class A, class T>
|
||||||
|
inline void
|
||||||
|
sp_destroy_n(A&, T* p, std::size_t n)
|
||||||
|
{
|
||||||
|
while (n > 0) {
|
||||||
|
p[--n].~T();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<class A, class T>
|
||||||
|
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<class A, class T>
|
||||||
|
inline void
|
||||||
|
sp_construct(A& a, T* p)
|
||||||
|
{
|
||||||
|
std::allocator_traits<A>::construct(a, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||||
|
template<class A, class T, class U, class... V>
|
||||||
|
inline void
|
||||||
|
sp_construct(A& a, T* p, U&& u, V&&... v)
|
||||||
|
{
|
||||||
|
std::allocator_traits<A>::construct(a, p, std::forward<U>(u),
|
||||||
|
std::forward<V>(v)...);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
template<class A, class T, class U>
|
||||||
|
inline void
|
||||||
|
sp_construct(A& a, T* p, U&& u)
|
||||||
|
{
|
||||||
|
std::allocator_traits<A>::construct(a, p, std::forward<U>(u));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
template<class A, class T, class U>
|
||||||
|
inline void
|
||||||
|
sp_construct(A& a, T* p, const U& u)
|
||||||
|
{
|
||||||
|
std::allocator_traits<A>::construct(a, p, u);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<class A, class T>
|
||||||
|
inline void
|
||||||
|
sp_construct_n(A& a, T* p, std::size_t n)
|
||||||
|
{
|
||||||
|
sp_destroyer<A, T> hold(a, p);
|
||||||
|
for (std::size_t& i = hold.size(); i < n; ++i) {
|
||||||
|
std::allocator_traits<A>::construct(a, p + i);
|
||||||
|
}
|
||||||
|
hold.size() = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class A, class T>
|
||||||
|
inline void
|
||||||
|
sp_construct_n(A& a, T* p, std::size_t n, const T* l, std::size_t m)
|
||||||
|
{
|
||||||
|
sp_destroyer<A, T> hold(a, p);
|
||||||
|
for (std::size_t& i = hold.size(); i < n; ++i) {
|
||||||
|
std::allocator_traits<A>::construct(a, p + i, l[i % m]);
|
||||||
|
}
|
||||||
|
hold.size() = 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
template<class A, class T>
|
||||||
|
inline void
|
||||||
|
sp_construct(A&, T* p)
|
||||||
|
{
|
||||||
|
::new(static_cast<void*>(p)) T();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class A, class T>
|
||||||
|
inline void
|
||||||
|
sp_construct(boost::noinit_adaptor<A>&, T* p)
|
||||||
|
{
|
||||||
|
::new(static_cast<void*>(p)) T;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||||
|
template<class A, class T, class U, class... V>
|
||||||
|
inline void
|
||||||
|
sp_construct(A&, T* p, U&& u, V&&... v)
|
||||||
|
{
|
||||||
|
::new(static_cast<void*>(p)) T(std::forward<U>(u), std::forward<V>(v)...);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
template<class A, class T, class U>
|
||||||
|
inline void
|
||||||
|
sp_construct(A&, T* p, U&& u)
|
||||||
|
{
|
||||||
|
::new(static_cast<void*>(p)) T(std::forward<U>(u));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
template<class A, class T, class U>
|
||||||
|
inline void
|
||||||
|
sp_construct(A&, T* p, const U& u)
|
||||||
|
{
|
||||||
|
::new(static_cast<void*>(p)) T(u);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<class A, class T>
|
||||||
|
inline void
|
||||||
|
sp_construct_n(A& a, T* p, std::size_t n)
|
||||||
|
{
|
||||||
|
sp_destroyer<A, T> hold(a, p);
|
||||||
|
for (std::size_t& i = hold.size(); i < n; ++i) {
|
||||||
|
::new(static_cast<void*>(p + i)) T();
|
||||||
|
}
|
||||||
|
hold.size() = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class A, class T>
|
||||||
|
inline void
|
||||||
|
sp_construct_n(boost::noinit_adaptor<A>& a, T* p, std::size_t n)
|
||||||
|
{
|
||||||
|
sp_destroyer<boost::noinit_adaptor<A>, T> hold(a, p);
|
||||||
|
for (std::size_t& i = hold.size(); i < n; ++i) {
|
||||||
|
::new(static_cast<void*>(p + i)) T;
|
||||||
|
}
|
||||||
|
hold.size() = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class A, class T>
|
||||||
|
inline void
|
||||||
|
sp_construct_n(A& a, T* p, std::size_t n, const T* l, std::size_t m)
|
||||||
|
{
|
||||||
|
sp_destroyer<A, T> hold(a, p);
|
||||||
|
for (std::size_t& i = hold.size(); i < n; ++i) {
|
||||||
|
::new(static_cast<void*>(p + i)) T(l[i % m]);
|
||||||
|
}
|
||||||
|
hold.size() = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} /* detail */
|
||||||
|
} /* boost */
|
||||||
|
|
||||||
|
#endif
|
Reference in New Issue
Block a user