Minor refactoring in allocate_shared implementations

This commit is contained in:
Glen Fernandes
2017-06-29 22:07:42 -04:00
parent 864a0c80dd
commit e4ba116d7e
2 changed files with 102 additions and 97 deletions

View File

@ -34,7 +34,7 @@ class lsp_array_base
: public local_counted_base { : public local_counted_base {
public: public:
void set(sp_counted_base* base) BOOST_SP_NOEXCEPT { void set(sp_counted_base* base) BOOST_SP_NOEXCEPT {
shared_count(base).swap(count_); count_ = shared_count(base);
} }
virtual void local_cb_destroy() BOOST_SP_NOEXCEPT { virtual void local_cb_destroy() BOOST_SP_NOEXCEPT {
@ -55,7 +55,8 @@ class lsp_array_state
public: public:
typedef A type; typedef A type;
lsp_array_state(const A& allocator, std::size_t size) BOOST_SP_NOEXCEPT template<class U>
lsp_array_state(const U& allocator, std::size_t size) BOOST_SP_NOEXCEPT
: allocator_(allocator), : allocator_(allocator),
size_(size) { } size_(size) { }
@ -78,7 +79,8 @@ class lsp_size_array_state
public: public:
typedef A type; typedef A type;
lsp_size_array_state(const A& allocator, std::size_t) BOOST_SP_NOEXCEPT template<class U>
lsp_size_array_state(const U& allocator, std::size_t) BOOST_SP_NOEXCEPT
: allocator_(allocator) { } : allocator_(allocator) { }
A& allocator() BOOST_SP_NOEXCEPT { A& allocator() BOOST_SP_NOEXCEPT {
@ -107,36 +109,36 @@ allocate_local_shared(const A& allocator, std::size_t count)
std::size_t size = count * detail::sp_array_count<type>::value; std::size_t size = count * detail::sp_array_count<type>::value;
detail::sp_array_result<other, base> result(allocator, size); detail::sp_array_result<other, base> result(allocator, size);
base* node = result.get(); base* node = result.get();
::new(static_cast<void*>(node)) base(allocator, size); scalar* start = detail::sp_array_start<base, scalar>(node);
::new(static_cast<void*>(node)) base(allocator, size, start);
detail::lsp_array_base& local = node->state(); detail::lsp_array_base& local = node->state();
local.set(node); local.set(node);
void* start = detail::sp_array_start<scalar>(node);
result.release(); result.release();
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
static_cast<type*>(start), &local); reinterpret_cast<type*>(start), &local);
} }
template<class T, class A> template<class T, class A>
inline typename detail::lsp_if_size_array<T>::type inline typename detail::lsp_if_size_array<T>::type
allocate_local_shared(const A& allocator) allocate_local_shared(const A& allocator)
{ {
typedef typename detail::sp_array_element<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
enum { enum {
size = detail::sp_array_count<T>::value size = detail::sp_array_count<T>::value
}; };
typedef typename detail::sp_array_element<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
typedef detail::lsp_size_array_state<other, size> state; typedef detail::lsp_size_array_state<other, size> state;
typedef detail::sp_array_base<state> base; typedef detail::sp_array_base<state> base;
detail::sp_array_result<other, base> result(allocator, size); detail::sp_array_result<other, base> result(allocator, size);
base* node = result.get(); base* node = result.get();
::new(static_cast<void*>(node)) base(allocator, size); scalar* start = detail::sp_array_start<base, scalar>(node);
::new(static_cast<void*>(node)) base(allocator, size, start);
detail::lsp_array_base& local = node->state(); detail::lsp_array_base& local = node->state();
local.set(node); local.set(node);
void* start = detail::sp_array_start<scalar>(node);
result.release(); result.release();
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
static_cast<type*>(start), &local); reinterpret_cast<type*>(start), &local);
} }
template<class T, class A> template<class T, class A>
@ -152,15 +154,15 @@ allocate_local_shared(const A& allocator, std::size_t count,
std::size_t size = count * detail::sp_array_count<type>::value; std::size_t size = count * detail::sp_array_count<type>::value;
detail::sp_array_result<other, base> result(allocator, size); detail::sp_array_result<other, base> result(allocator, size);
base* node = result.get(); base* node = result.get();
scalar* start = detail::sp_array_start<base, scalar>(node);
::new(static_cast<void*>(node)) base(allocator, size, ::new(static_cast<void*>(node)) base(allocator, size,
reinterpret_cast<const scalar*>(&value), reinterpret_cast<const scalar*>(&value),
detail::sp_array_count<type>::value); detail::sp_array_count<type>::value, start);
detail::lsp_array_base& local = node->state(); detail::lsp_array_base& local = node->state();
local.set(node); local.set(node);
void* start = detail::sp_array_start<scalar>(node);
result.release(); result.release();
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
static_cast<type*>(start), &local); reinterpret_cast<type*>(start), &local);
} }
template<class T, class A> template<class T, class A>
@ -168,25 +170,25 @@ inline typename detail::lsp_if_size_array<T>::type
allocate_local_shared(const A& allocator, allocate_local_shared(const A& allocator,
const typename detail::sp_array_element<T>::type& value) const typename detail::sp_array_element<T>::type& value)
{ {
typedef typename detail::sp_array_element<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
enum { enum {
size = detail::sp_array_count<T>::value size = detail::sp_array_count<T>::value
}; };
typedef typename detail::sp_array_element<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
typedef detail::lsp_size_array_state<other, size> state; typedef detail::lsp_size_array_state<other, size> state;
typedef detail::sp_array_base<state> base; typedef detail::sp_array_base<state> base;
detail::sp_array_result<other, base> result(allocator, size); detail::sp_array_result<other, base> result(allocator, size);
base* node = result.get(); base* node = result.get();
scalar* start = detail::sp_array_start<base, scalar>(node);
::new(static_cast<void*>(node)) base(allocator, size, ::new(static_cast<void*>(node)) base(allocator, size,
reinterpret_cast<const scalar*>(&value), reinterpret_cast<const scalar*>(&value),
detail::sp_array_count<type>::value); detail::sp_array_count<type>::value, start);
detail::lsp_array_base& local = node->state(); detail::lsp_array_base& local = node->state();
local.set(node); local.set(node);
void* start = detail::sp_array_start<scalar>(node);
result.release(); result.release();
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
static_cast<type*>(start), &local); reinterpret_cast<type*>(start), &local);
} }
template<class T, class A> template<class T, class A>
@ -201,38 +203,38 @@ allocate_local_shared_noinit(const A& allocator, std::size_t count)
std::size_t size = count * detail::sp_array_count<type>::value; std::size_t size = count * detail::sp_array_count<type>::value;
detail::sp_array_result<other, base> result(allocator, size); detail::sp_array_result<other, base> result(allocator, size);
base* node = result.get(); base* node = result.get();
::new(static_cast<void*>(node)) base(detail::sp_default(), scalar* start = detail::sp_array_start<base, scalar>(node);
allocator, size); ::new(static_cast<void*>(node)) base(detail::sp_default(), allocator,
size, start);
detail::lsp_array_base& local = node->state(); detail::lsp_array_base& local = node->state();
local.set(node); local.set(node);
void* start = detail::sp_array_start<scalar>(node);
result.release(); result.release();
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
static_cast<type*>(start), &local); reinterpret_cast<type*>(start), &local);
} }
template<class T, class A> template<class T, class A>
inline typename detail::lsp_if_size_array<T>::type inline typename detail::lsp_if_size_array<T>::type
allocate_local_shared_noinit(const A& allocator) allocate_local_shared_noinit(const A& allocator)
{ {
typedef typename detail::sp_array_element<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
enum { enum {
size = detail::sp_array_count<T>::value size = detail::sp_array_count<T>::value
}; };
typedef typename detail::sp_array_element<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
typedef detail::lsp_size_array_state<other, size> state; typedef detail::lsp_size_array_state<other, size> state;
typedef detail::sp_array_base<state, false> base; typedef detail::sp_array_base<state, false> base;
detail::sp_array_result<other, base> result(allocator, size); detail::sp_array_result<other, base> result(allocator, size);
base* node = result.get(); base* node = result.get();
::new(static_cast<void*>(node)) base(detail::sp_default(), scalar* start = detail::sp_array_start<base, scalar>(node);
allocator, size); ::new(static_cast<void*>(node)) base(detail::sp_default(), allocator,
size, start);
detail::lsp_array_base& local = node->state(); detail::lsp_array_base& local = node->state();
local.set(node); local.set(node);
void* start = detail::sp_array_start<scalar>(node);
result.release(); result.release();
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
static_cast<type*>(start), &local); reinterpret_cast<type*>(start), &local);
} }
} /* boost */ } /* boost */

View File

@ -353,7 +353,8 @@ class sp_array_state {
public: public:
typedef A type; typedef A type;
sp_array_state(const A& allocator, std::size_t size) BOOST_SP_NOEXCEPT template<class U>
sp_array_state(const U& allocator, std::size_t size) BOOST_SP_NOEXCEPT
: allocator_(allocator), : allocator_(allocator),
size_(size) { } size_(size) { }
@ -375,7 +376,8 @@ class sp_size_array_state {
public: public:
typedef A type; typedef A type;
sp_size_array_state(const A& allocator, std::size_t) BOOST_SP_NOEXCEPT template<class U>
sp_size_array_state(const U& allocator, std::size_t) BOOST_SP_NOEXCEPT
: allocator_(allocator) { } : allocator_(allocator) { }
A& allocator() BOOST_SP_NOEXCEPT { A& allocator() BOOST_SP_NOEXCEPT {
@ -429,27 +431,32 @@ struct sp_array_offset {
}; };
template<class T, class U> template<class T, class U>
inline T* struct sp_array_storage {
sp_array_start(U* base) BOOST_SP_NOEXCEPT enum {
value = sp_array_alignment<T, U>::value
};
typedef typename boost::type_with_alignment<value>::type type;
};
template<class T, class U>
inline U*
sp_array_start(void* base) BOOST_SP_NOEXCEPT
{ {
enum { enum {
size = sp_array_offset<U, T>::value size = sp_array_offset<T, U>::value
}; };
return reinterpret_cast<T*>(reinterpret_cast<char*>(base) + size); return reinterpret_cast<U*>(static_cast<char*>(base) + size);
} }
template<class A, class T> template<class A, class T>
class sp_array_creator { class sp_array_creator {
typedef typename A::value_type scalar; typedef typename A::value_type scalar;
enum {
alignment = sp_array_alignment<T, scalar>::value
};
enum { enum {
offset = sp_array_offset<T, scalar>::value offset = sp_array_offset<T, scalar>::value
}; };
typedef typename boost::type_with_alignment<alignment>::type type; typedef typename sp_array_storage<T, scalar>::type type;
public: public:
template<class U> template<class U>
@ -481,25 +488,23 @@ public:
typedef typename allocator::value_type type; typedef typename allocator::value_type type;
template<class A> template<class A>
sp_array_base(const A& other, std::size_t size) sp_array_base(const A& other, std::size_t size, type* start)
: state_(other, size) { : state_(other, size) {
sp_array_construct<E>(state_.allocator(), sp_array_start<type>(this), sp_array_construct<E>(state_.allocator(), start, state_.size());
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) std::size_t count, type* start)
: state_(other, size) { : state_(other, size) {
sp_array_construct<E>(state_.allocator(), sp_array_start<type>(this), sp_array_construct<E>(state_.allocator(), start, state_.size(), list,
state_.size(), list, count); count);
} }
template<class A> template<class A>
sp_array_base(sp_default, const A& other, std::size_t size) sp_array_base(sp_default, const A& other, std::size_t size, type* start)
: state_(other, size) { : state_(other, size) {
sp_array_default(state_.allocator(), sp_array_start<type>(this), sp_array_default(state_.allocator(), start, state_.size());
state_.size());
} }
T& state() BOOST_SP_NOEXCEPT { T& state() BOOST_SP_NOEXCEPT {
@ -507,8 +512,8 @@ public:
} }
virtual void dispose() { virtual void dispose() {
sp_array_destroy<E>(state_.allocator(), sp_array_start<type>(this), sp_array_destroy<E>(state_.allocator(),
state_.size()); sp_array_start<sp_array_base, type>(this), state_.size());
} }
virtual void destroy() { virtual void destroy() {
@ -552,10 +557,8 @@ public:
return result_; return result_;
} }
T* release() { void release() {
T* value = result_;
result_ = 0; result_ = 0;
return value;
} }
private: private:
@ -579,33 +582,33 @@ allocate_shared(const A& allocator, std::size_t count)
typedef detail::sp_array_base<state> base; typedef detail::sp_array_base<state> base;
std::size_t size = count * detail::sp_array_count<type>::value; std::size_t size = count * detail::sp_array_count<type>::value;
detail::sp_array_result<other, base> result(allocator, size); detail::sp_array_result<other, base> result(allocator, size);
base* node = result.get(); detail::sp_counted_base* node = result.get();
::new(static_cast<void*>(node)) base(allocator, size); scalar* start = detail::sp_array_start<base, scalar>(node);
void* start = detail::sp_array_start<scalar>(node); ::new(static_cast<void*>(node)) base(allocator, size, start);
detail::sp_counted_base* next = result.release(); result.release();
return shared_ptr<T>(detail::sp_internal_constructor_tag(), return shared_ptr<T>(detail::sp_internal_constructor_tag(),
static_cast<type*>(start), detail::shared_count(next)); reinterpret_cast<type*>(start), detail::shared_count(node));
} }
template<class T, class A> template<class T, class A>
inline typename detail::sp_if_size_array<T>::type inline typename detail::sp_if_size_array<T>::type
allocate_shared(const A& allocator) allocate_shared(const A& allocator)
{ {
typedef typename detail::sp_array_element<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
enum { enum {
size = detail::sp_array_count<T>::value size = detail::sp_array_count<T>::value
}; };
typedef typename detail::sp_array_element<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
typedef detail::sp_size_array_state<other, size> state; typedef detail::sp_size_array_state<other, size> state;
typedef detail::sp_array_base<state> base; typedef detail::sp_array_base<state> base;
detail::sp_array_result<other, base> result(allocator, size); detail::sp_array_result<other, base> result(allocator, size);
base* node = result.get(); detail::sp_counted_base* node = result.get();
::new(static_cast<void*>(node)) base(allocator, size); scalar* start = detail::sp_array_start<base, scalar>(node);
void* start = detail::sp_array_start<scalar>(node); ::new(static_cast<void*>(node)) base(allocator, size, start);
detail::sp_counted_base* next = result.release(); result.release();
return shared_ptr<T>(detail::sp_internal_constructor_tag(), return shared_ptr<T>(detail::sp_internal_constructor_tag(),
static_cast<type*>(start), detail::shared_count(next)); reinterpret_cast<type*>(start), detail::shared_count(node));
} }
template<class T, class A> template<class T, class A>
@ -620,14 +623,14 @@ allocate_shared(const A& allocator, std::size_t count,
typedef detail::sp_array_base<state> base; typedef detail::sp_array_base<state> base;
std::size_t size = count * detail::sp_array_count<type>::value; std::size_t size = count * detail::sp_array_count<type>::value;
detail::sp_array_result<other, base> result(allocator, size); detail::sp_array_result<other, base> result(allocator, size);
base* node = result.get(); detail::sp_counted_base* node = result.get();
scalar* start = detail::sp_array_start<base, scalar>(node);
::new(static_cast<void*>(node)) base(allocator, size, ::new(static_cast<void*>(node)) base(allocator, size,
reinterpret_cast<const scalar*>(&value), reinterpret_cast<const scalar*>(&value),
detail::sp_array_count<type>::value); detail::sp_array_count<type>::value, start);
void* start = detail::sp_array_start<scalar>(node); result.release();
detail::sp_counted_base* next = result.release();
return shared_ptr<T>(detail::sp_internal_constructor_tag(), return shared_ptr<T>(detail::sp_internal_constructor_tag(),
static_cast<type*>(start), detail::shared_count(next)); reinterpret_cast<type*>(start), detail::shared_count(node));
} }
template<class T, class A> template<class T, class A>
@ -635,23 +638,23 @@ inline typename detail::sp_if_size_array<T>::type
allocate_shared(const A& allocator, allocate_shared(const A& allocator,
const typename detail::sp_array_element<T>::type& value) const typename detail::sp_array_element<T>::type& value)
{ {
typedef typename detail::sp_array_element<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
enum { enum {
size = detail::sp_array_count<T>::value size = detail::sp_array_count<T>::value
}; };
typedef typename detail::sp_array_element<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
typedef detail::sp_size_array_state<other, size> state; typedef detail::sp_size_array_state<other, size> state;
typedef detail::sp_array_base<state> base; typedef detail::sp_array_base<state> base;
detail::sp_array_result<other, base> result(allocator, size); detail::sp_array_result<other, base> result(allocator, size);
base* node = result.get(); detail::sp_counted_base* node = result.get();
scalar* start = detail::sp_array_start<base, scalar>(node);
::new(static_cast<void*>(node)) base(allocator, size, ::new(static_cast<void*>(node)) base(allocator, size,
reinterpret_cast<const scalar*>(&value), reinterpret_cast<const scalar*>(&value),
detail::sp_array_count<type>::value); detail::sp_array_count<type>::value, start);
void* start = detail::sp_array_start<scalar>(node); result.release();
detail::sp_counted_base* next = result.release();
return shared_ptr<T>(detail::sp_internal_constructor_tag(), return shared_ptr<T>(detail::sp_internal_constructor_tag(),
static_cast<type*>(start), detail::shared_count(next)); reinterpret_cast<type*>(start), detail::shared_count(node));
} }
template<class T, class A> template<class T, class A>
@ -665,35 +668,35 @@ allocate_shared_noinit(const A& allocator, std::size_t count)
typedef detail::sp_array_base<state, false> base; typedef detail::sp_array_base<state, false> base;
std::size_t size = count * detail::sp_array_count<type>::value; std::size_t size = count * detail::sp_array_count<type>::value;
detail::sp_array_result<other, base> result(allocator, size); detail::sp_array_result<other, base> result(allocator, size);
base* node = result.get(); detail::sp_counted_base* node = result.get();
::new(static_cast<void*>(node)) base(detail::sp_default(), scalar* start = detail::sp_array_start<base, scalar>(node);
allocator, size); ::new(static_cast<void*>(node)) base(detail::sp_default(), allocator,
void* start = detail::sp_array_start<scalar>(node); size, start);
detail::sp_counted_base* next = result.release(); result.release();
return shared_ptr<T>(detail::sp_internal_constructor_tag(), return shared_ptr<T>(detail::sp_internal_constructor_tag(),
static_cast<type*>(start), detail::shared_count(next)); reinterpret_cast<type*>(start), detail::shared_count(node));
} }
template<class T, class A> template<class T, class A>
inline typename detail::sp_if_size_array<T>::type inline typename detail::sp_if_size_array<T>::type
allocate_shared_noinit(const A& allocator) allocate_shared_noinit(const A& allocator)
{ {
typedef typename detail::sp_array_element<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
enum { enum {
size = detail::sp_array_count<T>::value size = detail::sp_array_count<T>::value
}; };
typedef typename detail::sp_array_element<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
typedef detail::sp_size_array_state<other, size> state; typedef detail::sp_size_array_state<other, size> state;
typedef detail::sp_array_base<state, false> base; typedef detail::sp_array_base<state, false> base;
detail::sp_array_result<other, base> result(allocator, size); detail::sp_array_result<other, base> result(allocator, size);
base* node = result.get(); detail::sp_counted_base* node = result.get();
::new(static_cast<void*>(node)) base(detail::sp_default(), scalar* start = detail::sp_array_start<base, scalar>(node);
allocator, size); ::new(static_cast<void*>(node)) base(detail::sp_default(), allocator,
void* start = detail::sp_array_start<scalar>(node); size, start);
detail::sp_counted_base* next = result.release(); result.release();
return shared_ptr<T>(detail::sp_internal_constructor_tag(), return shared_ptr<T>(detail::sp_internal_constructor_tag(),
static_cast<type*>(start), detail::shared_count(next)); reinterpret_cast<type*>(start), detail::shared_count(node));
} }
} /* boost */ } /* boost */