forked from boostorg/smart_ptr
Refactor make_shared for arrays
Refactor implementation to later simplify making an optimization [for the C++11 allocator case] for when sp_counted_impl_pda destruction invokes the allocator's destroy function instead of the type's destructor.
This commit is contained in:
@ -21,16 +21,18 @@ namespace boost {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef typename boost::remove_cv<T2>::type T3;
|
||||
typedef boost::detail::as_allocator<T3[], A> A1;
|
||||
typedef boost::detail::as_deleter<T3[], A> D1;
|
||||
T1* p1 = 0;
|
||||
T3* p2 = 0;
|
||||
std::size_t n1 = size * boost::detail::array_total<T1>::size;
|
||||
boost::detail::as_allocator<T3[], A> a1(allocator, n1, &p2);
|
||||
boost::detail::as_deleter<T3[], A> d1(allocator, n1);
|
||||
D1 d1(allocator, n1);
|
||||
A1 a1(allocator, n1, &p2);
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::as_deleter<T3[], A>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->init(p2);
|
||||
boost::detail::as_init(allocator, p2, n1);
|
||||
D1* d2 = static_cast<D1*>(s1._internal_get_untyped_deleter());
|
||||
d2->set(p2);
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
@ -43,15 +45,17 @@ namespace boost {
|
||||
enum {
|
||||
N = boost::detail::array_total<T>::size
|
||||
};
|
||||
typedef boost::detail::as_allocator<T3[N], A> A1;
|
||||
typedef boost::detail::as_deleter<T3[N], A> D1;
|
||||
T1* p1 = 0;
|
||||
T3* p2 = 0;
|
||||
boost::detail::as_allocator<T3[N], A> a1(allocator, &p2);
|
||||
boost::detail::as_deleter<T3[N], A> d1(allocator);
|
||||
D1 d1(allocator);
|
||||
A1 a1(allocator, &p2);
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::as_deleter<T3[N], A>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->init(p2);
|
||||
boost::detail::as_init(allocator, p2, N);
|
||||
D1* d2 = static_cast<D1*>(s1._internal_get_untyped_deleter());
|
||||
d2->set(p2);
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
@ -63,6 +67,8 @@ namespace boost {
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef typename boost::remove_cv<T2>::type T3;
|
||||
typedef const T2 T4;
|
||||
typedef boost::detail::as_allocator<T3[], A> A1;
|
||||
typedef boost::detail::as_deleter<T3[], A> D1;
|
||||
enum {
|
||||
M = boost::detail::array_total<T1>::size
|
||||
};
|
||||
@ -70,13 +76,13 @@ namespace boost {
|
||||
T3* p2 = 0;
|
||||
T4* p3 = reinterpret_cast<T4*>(&value);
|
||||
std::size_t n1 = M * size;
|
||||
boost::detail::as_allocator<T3[], A> a1(allocator, n1, &p2);
|
||||
boost::detail::as_deleter<T3[], A> d1(allocator, n1);
|
||||
D1 d1(allocator, n1);
|
||||
A1 a1(allocator, n1, &p2);
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::as_deleter<T3[], A>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->template init<M>(p2, p3);
|
||||
boost::detail::as_init<T3, A, M>(allocator, p2, n1, p3);
|
||||
D1* d2 = static_cast<D1*>(s1._internal_get_untyped_deleter());
|
||||
d2->set(p2);
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
@ -90,18 +96,20 @@ namespace boost {
|
||||
typedef const T2 T4;
|
||||
enum {
|
||||
M = boost::detail::array_total<T1>::size,
|
||||
N = boost::detail::array_total<T>::size
|
||||
N = boost::detail::array_total<T>::size
|
||||
};
|
||||
typedef boost::detail::as_allocator<T3[N], A> A1;
|
||||
typedef boost::detail::as_deleter<T3[N], A> D1;
|
||||
T1* p1 = 0;
|
||||
T3* p2 = 0;
|
||||
T4* p3 = reinterpret_cast<T4*>(&value);
|
||||
boost::detail::as_allocator<T3[N], A> a1(allocator, &p2);
|
||||
boost::detail::as_deleter<T3[N], A> d1(allocator);
|
||||
D1 d1(allocator);
|
||||
A1 a1(allocator, &p2);
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::as_deleter<T3[N], A>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->template init<M>(p2, p3);
|
||||
boost::detail::as_init<T3, A, M>(allocator, p2, N, p3);
|
||||
D1* d2 = static_cast<D1*>(s1._internal_get_untyped_deleter());
|
||||
d2->set(p2);
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
@ -111,16 +119,18 @@ namespace boost {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef typename boost::remove_cv<T2>::type T3;
|
||||
typedef boost::detail::as_allocator<T3[], A> A1;
|
||||
typedef boost::detail::ms_deleter<T3[]> D1;
|
||||
T1* p1 = 0;
|
||||
T3* p2 = 0;
|
||||
std::size_t n1 = size * boost::detail::array_total<T1>::size;
|
||||
boost::detail::as_allocator<T3[], A> a1(allocator, n1, &p2);
|
||||
boost::detail::ms_deleter<T3[]> d1(n1);
|
||||
D1 d1(n1);
|
||||
A1 a1(allocator, n1, &p2);
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::ms_deleter<T3[]>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->noinit(p2);
|
||||
boost::detail::ms_noinit(p2, n1);
|
||||
D1* d2 = static_cast<D1*>(s1._internal_get_untyped_deleter());
|
||||
d2->set(p2);
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
@ -133,15 +143,17 @@ namespace boost {
|
||||
enum {
|
||||
N = boost::detail::array_total<T>::size
|
||||
};
|
||||
typedef boost::detail::as_allocator<T3[N], A> A1;
|
||||
typedef boost::detail::ms_deleter<T3[N]> D1;
|
||||
T1* p1 = 0;
|
||||
T3* p2 = 0;
|
||||
boost::detail::as_allocator<T3[N], A> a1(allocator, &p2);
|
||||
boost::detail::ms_deleter<T3[N]> d1;
|
||||
D1 d1;
|
||||
A1 a1(allocator, &p2);
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::ms_deleter<T3[N]>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->noinit(p2);
|
||||
boost::detail::ms_noinit(p2, N);
|
||||
D1* d2 = static_cast<D1*>(s1._internal_get_untyped_deleter());
|
||||
d2->set(p2);
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Glen Joseph Fernandes
|
||||
* 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
|
||||
* 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_AS_PAIR_HPP
|
||||
#define BOOST_SMART_PTR_DETAIL_AS_PAIR_HPP
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_ALLOCATOR_PAIR_HPP
|
||||
#define BOOST_SMART_PTR_DETAIL_ALLOCATOR_PAIR_HPP
|
||||
|
||||
#include <cstddef>
|
||||
|
@ -9,10 +9,10 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_ALLOCATOR_HPP
|
||||
#define BOOST_SMART_PTR_DETAIL_ARRAY_ALLOCATOR_HPP
|
||||
|
||||
#include <boost/smart_ptr/detail/allocator_pair.hpp>
|
||||
#include <boost/smart_ptr/detail/array_traits.hpp>
|
||||
#include <boost/smart_ptr/detail/as_pair.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
#include <memory>
|
||||
#endif
|
||||
|
||||
@ -45,22 +45,20 @@ namespace boost {
|
||||
template<typename T_, typename A_, typename Y_>
|
||||
friend class as_allocator;
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR) && \
|
||||
!defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
typedef typename std::allocator_traits<A>::
|
||||
template rebind_alloc<Y> YA;
|
||||
typedef typename std::allocator_traits<A>::
|
||||
template rebind_alloc<char> CA;
|
||||
typedef typename std::allocator_traits<A>::
|
||||
template rebind_traits<Y> YT;
|
||||
typedef typename std::allocator_traits<A>::
|
||||
template rebind_traits<char> CT;
|
||||
#else
|
||||
typedef typename A::template rebind<Y>::other YA;
|
||||
typedef typename A::template rebind<char>::other CA;
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
typedef std::allocator_traits<YA> YT;
|
||||
typedef std::allocator_traits<CA> CT;
|
||||
#endif
|
||||
|
||||
public:
|
||||
typedef typename array_inner<T>::type type;
|
||||
|
||||
@ -128,7 +126,7 @@ namespace boost {
|
||||
p2--;
|
||||
}
|
||||
*pair.data = reinterpret_cast<type*>(p2);
|
||||
return reinterpret_cast<Y*>(p1);
|
||||
return reinterpret_cast<value_type*>(p1);
|
||||
}
|
||||
|
||||
void deallocate(pointer memory, size_type count) {
|
||||
@ -162,15 +160,12 @@ namespace boost {
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
|
||||
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR) && \
|
||||
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
|
||||
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
template<typename U, typename... Args>
|
||||
void construct(U* memory, Args&&... args) {
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
YT::construct(pair, memory, std::forward<Args>(args)...);
|
||||
#else
|
||||
pair.construct(memory, std::forward<Args>(args)...);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -235,7 +230,10 @@ namespace boost {
|
||||
}
|
||||
|
||||
size_type max_size() const {
|
||||
return static_cast<std::size_t>(-1) / sizeof(Y);
|
||||
enum {
|
||||
N = static_cast<std::size_t>(-1) / sizeof(value_type)
|
||||
};
|
||||
return N;
|
||||
}
|
||||
|
||||
pointer allocate(size_type count, const void* = 0) {
|
||||
@ -247,7 +245,7 @@ namespace boost {
|
||||
p2--;
|
||||
}
|
||||
*data = reinterpret_cast<type*>(p2);
|
||||
return reinterpret_cast<Y*>(p1);
|
||||
return reinterpret_cast<value_type*>(p1);
|
||||
}
|
||||
|
||||
void deallocate(pointer memory, size_type) {
|
||||
@ -266,8 +264,9 @@ namespace boost {
|
||||
memory->~U();
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
|
||||
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR) && \
|
||||
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
|
||||
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
template<typename U, typename... Args>
|
||||
void construct(U* memory, Args&&... args) {
|
||||
void* p1 = memory;
|
||||
|
@ -9,14 +9,9 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_DELETER_HPP
|
||||
#define BOOST_SMART_PTR_DETAIL_ARRAY_DELETER_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/smart_ptr/detail/allocator_pair.hpp>
|
||||
#include <boost/smart_ptr/detail/array_traits.hpp>
|
||||
#include <boost/smart_ptr/detail/as_pair.hpp>
|
||||
#include <boost/type_traits/has_trivial_constructor.hpp>
|
||||
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
#include <memory>
|
||||
#endif
|
||||
#include <boost/smart_ptr/detail/array_utility.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
@ -47,130 +42,35 @@ namespace boost {
|
||||
public:
|
||||
typedef typename array_inner<T>::type type;
|
||||
|
||||
as_deleter(const A& allocator)
|
||||
: pair(allocator, 0) {
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
typedef typename std::allocator_traits<A>::
|
||||
template rebind_alloc<type> allocator;
|
||||
#else
|
||||
typedef typename A::
|
||||
template rebind<type>::other allocator;
|
||||
#endif
|
||||
|
||||
as_deleter(const A& allocator_)
|
||||
: pair(allocator_, 0) {
|
||||
}
|
||||
|
||||
as_deleter(const A& allocator, std::size_t size_)
|
||||
as_deleter(const A& allocator_, std::size_t size_)
|
||||
: ms_deleter_base<T>(size_),
|
||||
pair(allocator, 0) {
|
||||
pair(allocator_, 0) {
|
||||
}
|
||||
|
||||
void init(type* memory) {
|
||||
value_init(memory);
|
||||
pair.data = memory;
|
||||
}
|
||||
|
||||
template<std::size_t N>
|
||||
void init(type* memory, const type* value) {
|
||||
value_init<N>(memory, value);
|
||||
void set(type* memory) {
|
||||
pair.data = memory;
|
||||
}
|
||||
|
||||
void operator()(const void*) {
|
||||
if (pair.data) {
|
||||
destroy(pair.data, size);
|
||||
as_destroy<type, allocator>(pair, pair.data, size);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR) && \
|
||||
!defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
||||
typedef typename std::allocator_traits<A>::
|
||||
template rebind_alloc<type> TA;
|
||||
#else
|
||||
typedef typename A::
|
||||
template rebind<type>::other TA;
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
typedef std::allocator_traits<TA> TT;
|
||||
#endif
|
||||
|
||||
void destroy(type* memory, std::size_t count) {
|
||||
for (std::size_t i = count; i > 0;) {
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
TT::destroy(pair, &memory[--i]);
|
||||
#else
|
||||
memory[--i].~type();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void value_init(type* memory, boost::true_type) {
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
TT::construct(pair, memory + i);
|
||||
#else
|
||||
void* p1 = memory + i;
|
||||
::new(p1) type();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void value_init(type* memory, boost::false_type) {
|
||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||
std::size_t i = 0;
|
||||
try {
|
||||
for (; i < size; i++) {
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
TT::construct(pair, memory + i);
|
||||
#else
|
||||
void* p1 = memory + i;
|
||||
::new(p1) type();
|
||||
#endif
|
||||
}
|
||||
} catch (...) {
|
||||
destroy(memory, i);
|
||||
throw;
|
||||
}
|
||||
#else
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
TT::construct(pair, memory + i);
|
||||
#else
|
||||
void* p1 = memory + i;
|
||||
::new(p1) type();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void value_init(type* memory) {
|
||||
boost::has_trivial_default_constructor<type> tag;
|
||||
value_init(memory, tag);
|
||||
}
|
||||
|
||||
template<std::size_t N>
|
||||
void value_init(type* memory, const type* list) {
|
||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||
std::size_t i = 0;
|
||||
try {
|
||||
for (; i < size; i++) {
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
TT::construct(pair, memory + i, list[i % N]);
|
||||
#else
|
||||
void* p1 = memory + i;
|
||||
::new(p1) type(list[i % N]);
|
||||
#endif
|
||||
}
|
||||
} catch (...) {
|
||||
destroy(memory, i);
|
||||
throw;
|
||||
}
|
||||
#else
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
TT::construct(allocator, memory + i, list[i % N]);
|
||||
#else
|
||||
void* p1 = memory + i;
|
||||
::new(p1) type(list[i % N]);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
as_pair<TA, type*> pair;
|
||||
as_pair<allocator, type*> pair;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
@ -190,124 +90,17 @@ namespace boost {
|
||||
object(0) {
|
||||
}
|
||||
|
||||
void init(type* memory) {
|
||||
value_init(memory);
|
||||
object = memory;
|
||||
}
|
||||
|
||||
template<std::size_t N>
|
||||
void init(type* memory, const type* value) {
|
||||
value_init<N>(memory, value);
|
||||
object = memory;
|
||||
}
|
||||
|
||||
void noinit(type* memory) {
|
||||
default_init(memory);
|
||||
void set(type* memory) {
|
||||
object = memory;
|
||||
}
|
||||
|
||||
void operator()(const void*) {
|
||||
if (object) {
|
||||
destroy(object, size);
|
||||
ms_destroy(object, size);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void destroy(type*, std::size_t, boost::true_type) {
|
||||
}
|
||||
|
||||
void destroy(type* memory, std::size_t count, boost::false_type) {
|
||||
for (std::size_t i = count; i > 0;) {
|
||||
memory[--i].~type();
|
||||
}
|
||||
}
|
||||
|
||||
void destroy(type* memory, std::size_t count) {
|
||||
boost::has_trivial_destructor<type> tag;
|
||||
destroy(memory, count, tag);
|
||||
}
|
||||
|
||||
void value_init(type* memory, boost::true_type) {
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) type();
|
||||
}
|
||||
}
|
||||
|
||||
void value_init(type* memory, boost::false_type) {
|
||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||
std::size_t i = 0;
|
||||
try {
|
||||
for (; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) type();
|
||||
}
|
||||
} catch (...) {
|
||||
destroy(memory, i);
|
||||
throw;
|
||||
}
|
||||
#else
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) type();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void value_init(type* memory) {
|
||||
boost::has_trivial_default_constructor<type> tag;
|
||||
value_init(memory, tag);
|
||||
}
|
||||
|
||||
template<std::size_t N>
|
||||
void value_init(type* memory, const type* list) {
|
||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||
std::size_t i = 0;
|
||||
try {
|
||||
for (; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) type(list[i % N]);
|
||||
}
|
||||
} catch (...) {
|
||||
destroy(memory, i);
|
||||
throw;
|
||||
}
|
||||
#else
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) type(list[i % N]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void default_init(type*, boost::true_type) {
|
||||
}
|
||||
|
||||
void default_init(type* memory, boost::false_type) {
|
||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||
std::size_t i = 0;
|
||||
try {
|
||||
for (; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) type;
|
||||
}
|
||||
} catch (...) {
|
||||
destroy(memory, i);
|
||||
throw;
|
||||
}
|
||||
#else
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) type;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void default_init(type* memory) {
|
||||
boost::has_trivial_default_constructor<type> tag;
|
||||
default_init(memory, tag);
|
||||
}
|
||||
|
||||
type* object;
|
||||
};
|
||||
}
|
||||
|
251
include/boost/smart_ptr/detail/array_utility.hpp
Normal file
251
include/boost/smart_ptr/detail/array_utility.hpp
Normal file
@ -0,0 +1,251 @@
|
||||
/*
|
||||
* 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 <boost/config.hpp>
|
||||
#include <boost/type_traits/has_trivial_constructor.hpp>
|
||||
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
#include <memory>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
typedef boost::true_type ms_is_trivial;
|
||||
typedef boost::false_type ms_no_trivial;
|
||||
|
||||
template<typename T>
|
||||
inline void ms_destroy(T*, std::size_t, ms_is_trivial) {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
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<typename T>
|
||||
inline void ms_destroy(T* memory, std::size_t size) {
|
||||
boost::has_trivial_destructor<T> trivial;
|
||||
ms_destroy(memory, size, trivial);
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
template<typename T, typename A>
|
||||
inline void as_destroy(A& allocator, T* memory,
|
||||
std::size_t size) {
|
||||
typedef typename std::allocator_traits<A>::
|
||||
template rebind_traits<T> TT;
|
||||
for (std::size_t i = size; i > 0;) {
|
||||
TT::destroy(allocator, &memory[--i]);
|
||||
}
|
||||
}
|
||||
#else
|
||||
template<typename T, typename A>
|
||||
inline void as_destroy(const A&, T* memory,
|
||||
std::size_t size) {
|
||||
boost::has_trivial_destructor<T> trivial;
|
||||
ms_destroy(memory, size, trivial);
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
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<typename T>
|
||||
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<typename T>
|
||||
inline void ms_init(T* memory, std::size_t size) {
|
||||
boost::has_trivial_default_constructor<T> trivial;
|
||||
ms_init(memory, size, trivial);
|
||||
}
|
||||
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
template<typename T, typename A>
|
||||
inline void as_init(const A& allocator, T* memory, std::size_t size,
|
||||
ms_is_trivial) {
|
||||
typedef typename std::allocator_traits<A>::
|
||||
template rebind_alloc<T> TA;
|
||||
typedef typename std::allocator_traits<A>::
|
||||
template rebind_traits<T> TT;
|
||||
TA a2(allocator);
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
TT::construct(a2, memory + i);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, typename A>
|
||||
inline void as_init(const A& allocator, T* memory, std::size_t size,
|
||||
ms_no_trivial) {
|
||||
typedef typename std::allocator_traits<A>::
|
||||
template rebind_alloc<T> TA;
|
||||
typedef typename std::allocator_traits<A>::
|
||||
template rebind_traits<T> 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<typename T, typename A>
|
||||
inline void as_init(const A& allocator, T* memory, std::size_t size) {
|
||||
boost::has_trivial_default_constructor<T> trivial;
|
||||
as_init(allocator, memory, size, trivial);
|
||||
}
|
||||
#else
|
||||
template<typename T, typename A>
|
||||
inline void as_init(const A&, T* memory, std::size_t size) {
|
||||
boost::has_trivial_default_constructor<T> trivial;
|
||||
ms_init(memory, size, trivial);
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename T, std::size_t N>
|
||||
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<typename T, typename A, std::size_t N>
|
||||
inline void as_init(const A& allocator, T* memory, std::size_t size,
|
||||
const T* list) {
|
||||
typedef typename std::allocator_traits<A>::
|
||||
template rebind_alloc<T> TA;
|
||||
typedef typename std::allocator_traits<A>::
|
||||
template rebind_traits<T> 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
|
||||
}
|
||||
#else
|
||||
template<typename T, typename A, std::size_t N>
|
||||
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<typename T>
|
||||
inline void ms_noinit(T*, std::size_t, ms_is_trivial) {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
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<typename T>
|
||||
inline void ms_noinit(T* memory, std::size_t size) {
|
||||
boost::has_trivial_default_constructor<T> trivial;
|
||||
ms_noinit(memory, size, trivial);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -21,16 +21,18 @@ namespace boost {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef typename boost::remove_cv<T2>::type T3;
|
||||
typedef boost::detail::ms_allocator<T3[]> A1;
|
||||
typedef boost::detail::ms_deleter<T3[]> D1;
|
||||
T1* p1 = 0;
|
||||
T3* p2 = 0;
|
||||
std::size_t n1 = size * boost::detail::array_total<T1>::size;
|
||||
D1 d1(n1);
|
||||
boost::detail::ms_allocator<T3[]> a1(n1, &p2);
|
||||
boost::detail::ms_deleter<T3[]> d1(n1);
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::ms_deleter<T3[]>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->init(p2);
|
||||
boost::detail::ms_init(p2, n1);
|
||||
D1* d2 = static_cast<D1*>(s1._internal_get_untyped_deleter());
|
||||
d2->set(p2);
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
@ -43,15 +45,17 @@ namespace boost {
|
||||
enum {
|
||||
N = boost::detail::array_total<T>::size
|
||||
};
|
||||
typedef boost::detail::ms_allocator<T3[N]> A1;
|
||||
typedef boost::detail::ms_deleter<T3[N]> D1;
|
||||
T1* p1 = 0;
|
||||
T3* p2 = 0;
|
||||
D1 d1;
|
||||
boost::detail::ms_allocator<T3[N]> a1(&p2);
|
||||
boost::detail::ms_deleter<T3[N]> d1;
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::ms_deleter<T3[N]>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->init(p2);
|
||||
boost::detail::ms_init(p2, N);
|
||||
D1* d2 = static_cast<D1*>(s1._internal_get_untyped_deleter());
|
||||
d2->set(p2);
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
@ -63,6 +67,8 @@ namespace boost {
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef typename boost::remove_cv<T2>::type T3;
|
||||
typedef const T2 T4;
|
||||
typedef boost::detail::ms_allocator<T3[]> A1;
|
||||
typedef boost::detail::ms_deleter<T3[]> D1;
|
||||
enum {
|
||||
M = boost::detail::array_total<T1>::size
|
||||
};
|
||||
@ -70,13 +76,13 @@ namespace boost {
|
||||
T3* p2 = 0;
|
||||
T4* p3 = reinterpret_cast<T4*>(&value);
|
||||
std::size_t n1 = M * size;
|
||||
D1 d1(n1);
|
||||
boost::detail::ms_allocator<T3[]> a1(n1, &p2);
|
||||
boost::detail::ms_deleter<T3[]> d1(n1);
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::ms_deleter<T3[]>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->template init<M>(p2, p3);
|
||||
boost::detail::ms_init<T3, M>(p2, n1, p3);
|
||||
D1* d2 = static_cast<D1*>(s1._internal_get_untyped_deleter());
|
||||
d2->set(p2);
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
@ -91,16 +97,18 @@ namespace boost {
|
||||
M = boost::detail::array_total<T1>::size,
|
||||
N = boost::detail::array_total<T>::size
|
||||
};
|
||||
typedef boost::detail::ms_allocator<T3[N]> A1;
|
||||
typedef boost::detail::ms_deleter<T3[N]> D1;
|
||||
T1* p1 = 0;
|
||||
T3* p2 = 0;
|
||||
T4* p3 = reinterpret_cast<T4*>(&value);
|
||||
D1 d1;
|
||||
boost::detail::ms_allocator<T3[N]> a1(&p2);
|
||||
boost::detail::ms_deleter<T3[N]> d1;
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::ms_deleter<T3[N]>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->template init<M>(p2, p3);
|
||||
boost::detail::ms_init<T3, M>(p2, N, p3);
|
||||
D1* d2 = static_cast<D1*>(s1._internal_get_untyped_deleter());
|
||||
d2->set(p2);
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
@ -110,16 +118,18 @@ namespace boost {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef typename boost::remove_cv<T2>::type T3;
|
||||
typedef boost::detail::ms_allocator<T3[]> A1;
|
||||
typedef boost::detail::ms_deleter<T3[]> D1;
|
||||
T1* p1 = 0;
|
||||
T3* p2 = 0;
|
||||
std::size_t n1 = size * boost::detail::array_total<T1>::size;
|
||||
boost::detail::ms_allocator<T3[]> a1(n1, &p2);
|
||||
boost::detail::ms_deleter<T3[]> d1(n1);
|
||||
D1 d1(n1);
|
||||
A1 a1(n1, &p2);
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::ms_deleter<T3[]>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->noinit(p2);
|
||||
boost::detail::ms_noinit(p2, n1);
|
||||
D1* d2 = static_cast<D1*>(s1._internal_get_untyped_deleter());
|
||||
d2->set(p2);
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
@ -132,15 +142,17 @@ namespace boost {
|
||||
enum {
|
||||
N = boost::detail::array_total<T>::size
|
||||
};
|
||||
typedef boost::detail::ms_allocator<T3[N]> A1;
|
||||
typedef boost::detail::ms_deleter<T3[N]> D1;
|
||||
T1* p1 = 0;
|
||||
T3* p2 = 0;
|
||||
boost::detail::ms_allocator<T3[N]> a1(&p2);
|
||||
boost::detail::ms_deleter<T3[N]> d1;
|
||||
D1 d1;
|
||||
A1 a1(&p2);
|
||||
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||
typedef boost::detail::ms_deleter<T3[N]>* D2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||
d2->noinit(p2);
|
||||
boost::detail::ms_noinit(p2, N);
|
||||
D1* d2 = static_cast<D1*>(s1._internal_get_untyped_deleter());
|
||||
d2->set(p2);
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user