forked from boostorg/unordered
Unordered: Go back to the old method for constructing nodes.
Reverts much of [78349]. Keeps the variadic construct. [SVN r80219]
This commit is contained in:
@ -1104,76 +1104,6 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
|
|
||||||
namespace boost { namespace unordered { namespace detail {
|
namespace boost { namespace unordered { namespace detail {
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// construct_node/destroy_node
|
|
||||||
//
|
|
||||||
// Construct a node using the best available method.
|
|
||||||
|
|
||||||
#if BOOST_UNORDERED_DETAIL_FULL_CONSTRUCT
|
|
||||||
|
|
||||||
template <typename Alloc, typename T, BOOST_UNORDERED_EMPLACE_TEMPLATE>
|
|
||||||
inline void construct_node(Alloc& a, T* p, BOOST_UNORDERED_EMPLACE_ARGS)
|
|
||||||
{
|
|
||||||
boost::unordered::detail::allocator_traits<Alloc>::construct(
|
|
||||||
a, p, BOOST_UNORDERED_EMPLACE_FORWARD);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Alloc, typename T>
|
|
||||||
inline void destroy_node(Alloc& a, T* p)
|
|
||||||
{
|
|
||||||
boost::unordered::detail::allocator_traits<Alloc>::destroy(a, p);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
template <typename AllocTraits, typename T>
|
|
||||||
struct value_construct
|
|
||||||
{
|
|
||||||
typedef BOOST_DEDUCED_TYPENAME AllocTraits::allocator_type allocator;
|
|
||||||
|
|
||||||
allocator& alloc;
|
|
||||||
T* ptr;
|
|
||||||
|
|
||||||
value_construct(allocator& a, T* p) : alloc(a), ptr(p)
|
|
||||||
{
|
|
||||||
AllocTraits::construct(alloc, ptr, T());
|
|
||||||
}
|
|
||||||
|
|
||||||
void release()
|
|
||||||
{
|
|
||||||
ptr = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
~value_construct()
|
|
||||||
{
|
|
||||||
if (ptr) AllocTraits::destroy(alloc, ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
value_construct(value_construct const&);
|
|
||||||
value_construct& operator=(value_construct const&);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Alloc, typename T, BOOST_UNORDERED_EMPLACE_TEMPLATE>
|
|
||||||
inline void construct_node(Alloc& a, T* p, BOOST_UNORDERED_EMPLACE_ARGS)
|
|
||||||
{
|
|
||||||
value_construct<boost::unordered::detail::allocator_traits<Alloc>, T>
|
|
||||||
construct_guard(a, p);
|
|
||||||
boost::unordered::detail::construct_impl(
|
|
||||||
p->value_ptr(), BOOST_UNORDERED_EMPLACE_FORWARD);
|
|
||||||
construct_guard.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Alloc, typename T>
|
|
||||||
inline void destroy_node(Alloc& a, T* p)
|
|
||||||
{
|
|
||||||
boost::unordered::detail::destroy(p->value_ptr());
|
|
||||||
boost::unordered::detail::allocator_traits<Alloc>::destroy(a, p);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// array_constructor
|
// array_constructor
|
||||||
|
@ -53,14 +53,16 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
|
|
||||||
node_allocator& alloc_;
|
node_allocator& alloc_;
|
||||||
node_pointer node_;
|
node_pointer node_;
|
||||||
bool constructed_;
|
bool node_constructed_;
|
||||||
|
bool value_constructed_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
node_constructor(node_allocator& n) :
|
node_constructor(node_allocator& n) :
|
||||||
alloc_(n),
|
alloc_(n),
|
||||||
node_(),
|
node_(),
|
||||||
constructed_(false)
|
node_constructed_(false),
|
||||||
|
value_constructed_(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,36 +73,27 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
template <BOOST_UNORDERED_EMPLACE_TEMPLATE>
|
template <BOOST_UNORDERED_EMPLACE_TEMPLATE>
|
||||||
void construct_value(BOOST_UNORDERED_EMPLACE_ARGS)
|
void construct_value(BOOST_UNORDERED_EMPLACE_ARGS)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(node_ && !constructed_);
|
BOOST_ASSERT(node_ && node_constructed_ && !value_constructed_);
|
||||||
boost::unordered::detail::construct_node(alloc_,
|
boost::unordered::detail::construct_impl(
|
||||||
boost::addressof(*node_), BOOST_UNORDERED_EMPLACE_FORWARD);
|
node_->value_ptr(), BOOST_UNORDERED_EMPLACE_FORWARD);
|
||||||
node_->init(static_cast<typename node::link_pointer>(node_));
|
value_constructed_ = true;
|
||||||
constructed_ = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename A0>
|
template <typename A0>
|
||||||
void construct_value2(BOOST_FWD_REF(A0) a0)
|
void construct_value2(BOOST_FWD_REF(A0) a0)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(node_ && !constructed_);
|
BOOST_ASSERT(node_ && node_constructed_ && !value_constructed_);
|
||||||
|
boost::unordered::detail::construct_impl(
|
||||||
boost::unordered::detail::construct_node(alloc_,
|
node_->value_ptr(),
|
||||||
boost::addressof(*node_),
|
|
||||||
BOOST_UNORDERED_EMPLACE_ARGS1(boost::forward<A0>(a0)));
|
BOOST_UNORDERED_EMPLACE_ARGS1(boost::forward<A0>(a0)));
|
||||||
|
value_constructed_ = true;
|
||||||
constructed_ = true;
|
|
||||||
node_->init(static_cast<typename node::link_pointer>(node_));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
value_type const& value() const {
|
value_type const& value() const {
|
||||||
BOOST_ASSERT(node_ && constructed_);
|
BOOST_ASSERT(node_ && node_constructed_ && value_constructed_);
|
||||||
return node_->value();
|
return node_->value();
|
||||||
}
|
}
|
||||||
|
|
||||||
node_pointer get()
|
|
||||||
{
|
|
||||||
return node_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// no throw
|
// no throw
|
||||||
node_pointer release()
|
node_pointer release()
|
||||||
{
|
{
|
||||||
@ -118,8 +111,12 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
node_constructor<Alloc>::~node_constructor()
|
node_constructor<Alloc>::~node_constructor()
|
||||||
{
|
{
|
||||||
if (node_) {
|
if (node_) {
|
||||||
if (constructed_) {
|
if (value_constructed_) {
|
||||||
boost::unordered::detail::destroy_node(alloc_,
|
boost::unordered::detail::destroy(node_->value_ptr());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node_constructed_) {
|
||||||
|
node_allocator_traits::destroy(alloc_,
|
||||||
boost::addressof(*node_));
|
boost::addressof(*node_));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,13 +128,24 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
void node_constructor<Alloc>::construct_node()
|
void node_constructor<Alloc>::construct_node()
|
||||||
{
|
{
|
||||||
if(!node_) {
|
if(!node_) {
|
||||||
constructed_ = false;
|
node_constructed_ = false;
|
||||||
|
value_constructed_ = false;
|
||||||
|
|
||||||
node_ = node_allocator_traits::allocate(alloc_, 1);
|
node_ = node_allocator_traits::allocate(alloc_, 1);
|
||||||
|
|
||||||
|
node_allocator_traits::construct(alloc_,
|
||||||
|
boost::addressof(*node_), node());
|
||||||
|
node_->init(static_cast<typename node::link_pointer>(node_));
|
||||||
|
node_constructed_ = true;
|
||||||
}
|
}
|
||||||
else if (constructed_) {
|
else {
|
||||||
boost::unordered::detail::destroy_node(alloc_,
|
BOOST_ASSERT(node_constructed_);
|
||||||
boost::addressof(*node_));
|
|
||||||
constructed_ = false;
|
if (value_constructed_)
|
||||||
|
{
|
||||||
|
boost::unordered::detail::destroy(node_->value_ptr());
|
||||||
|
value_constructed_ = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,16 +183,6 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
|
|
||||||
enum { extra_node = false };
|
enum { extra_node = false };
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename LinkPointer>
|
|
||||||
struct node_base
|
|
||||||
{
|
|
||||||
typedef LinkPointer link_pointer;
|
|
||||||
link_pointer next_;
|
|
||||||
|
|
||||||
node_base() : next_() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
namespace boost { namespace unordered { namespace iterator_detail {
|
namespace boost { namespace unordered { namespace iterator_detail {
|
||||||
@ -720,14 +718,6 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
node_constructor a(this->node_alloc());
|
node_constructor a(this->node_alloc());
|
||||||
a.construct_node();
|
a.construct_node();
|
||||||
|
|
||||||
// Since this node is just to mark the beginning it doesn't
|
|
||||||
// contain a value, so just construct node::node_base
|
|
||||||
// which containers the pointer to the next element.
|
|
||||||
node_allocator_traits::construct(node_alloc(),
|
|
||||||
static_cast<typename node::node_base*>(
|
|
||||||
boost::addressof(*a.get())),
|
|
||||||
typename node::node_base());
|
|
||||||
|
|
||||||
(constructor.get() +
|
(constructor.get() +
|
||||||
static_cast<std::ptrdiff_t>(this->bucket_count_))->next_ =
|
static_cast<std::ptrdiff_t>(this->bucket_count_))->next_ =
|
||||||
a.release();
|
a.release();
|
||||||
@ -772,8 +762,9 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
|
|
||||||
inline void delete_node(c_iterator n)
|
inline void delete_node(c_iterator n)
|
||||||
{
|
{
|
||||||
boost::unordered::detail::destroy_node(
|
boost::unordered::detail::destroy(n.node_->value_ptr());
|
||||||
node_alloc(), boost::addressof(*n.node_));
|
node_allocator_traits::destroy(node_alloc(),
|
||||||
|
boost::addressof(*n.node_));
|
||||||
node_allocator_traits::deallocate(node_alloc(), n.node_, 1);
|
node_allocator_traits::deallocate(node_alloc(), n.node_, 1);
|
||||||
--size_;
|
--size_;
|
||||||
}
|
}
|
||||||
@ -795,8 +786,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
inline void delete_extra_node(bucket_pointer) {}
|
inline void delete_extra_node(bucket_pointer) {}
|
||||||
|
|
||||||
inline void delete_extra_node(node_pointer n) {
|
inline void delete_extra_node(node_pointer n) {
|
||||||
node_allocator_traits::destroy(node_alloc(),
|
node_allocator_traits::destroy(node_alloc(), boost::addressof(*n));
|
||||||
static_cast<typename node::node_base*>(boost::addressof(*n)));
|
|
||||||
node_allocator_traits::deallocate(node_alloc(), n, 1);
|
node_allocator_traits::deallocate(node_alloc(), n, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,44 +22,20 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
|
|
||||||
template <typename A, typename T>
|
template <typename A, typename T>
|
||||||
struct grouped_node :
|
struct grouped_node :
|
||||||
boost::unordered::detail::node_base<
|
|
||||||
typename ::boost::unordered::detail::rebind_wrap<
|
|
||||||
A, grouped_node<A, T> >::type::pointer
|
|
||||||
>,
|
|
||||||
boost::unordered::detail::value_base<T>
|
boost::unordered::detail::value_base<T>
|
||||||
{
|
{
|
||||||
typedef typename ::boost::unordered::detail::rebind_wrap<
|
typedef typename ::boost::unordered::detail::rebind_wrap<
|
||||||
A, grouped_node<A, T> >::type::pointer link_pointer;
|
A, grouped_node<A, T> >::type::pointer link_pointer;
|
||||||
typedef boost::unordered::detail::node_base<link_pointer> node_base;
|
|
||||||
|
|
||||||
|
link_pointer next_;
|
||||||
link_pointer group_prev_;
|
link_pointer group_prev_;
|
||||||
std::size_t hash_;
|
std::size_t hash_;
|
||||||
|
|
||||||
#if BOOST_UNORDERED_DETAIL_FULL_CONSTRUCT
|
|
||||||
template <BOOST_UNORDERED_EMPLACE_TEMPLATE>
|
|
||||||
explicit grouped_node(BOOST_UNORDERED_EMPLACE_ARGS) :
|
|
||||||
node_base(),
|
|
||||||
group_prev_(),
|
|
||||||
hash_(0)
|
|
||||||
{
|
|
||||||
boost::unordered::detail::construct_impl(
|
|
||||||
this->value_ptr(), BOOST_UNORDERED_EMPLACE_FORWARD);
|
|
||||||
}
|
|
||||||
|
|
||||||
~grouped_node() {
|
|
||||||
boost::unordered::detail::destroy(this->value_ptr());
|
|
||||||
}
|
|
||||||
|
|
||||||
grouped_node(grouped_node const&) {
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
grouped_node() :
|
grouped_node() :
|
||||||
node_base(),
|
next_(),
|
||||||
group_prev_(),
|
group_prev_(),
|
||||||
hash_(0)
|
hash_(0)
|
||||||
{}
|
{}
|
||||||
#endif
|
|
||||||
|
|
||||||
void init(link_pointer self)
|
void init(link_pointer self)
|
||||||
{
|
{
|
||||||
@ -76,37 +52,16 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
boost::unordered::detail::ptr_bucket
|
boost::unordered::detail::ptr_bucket
|
||||||
{
|
{
|
||||||
typedef boost::unordered::detail::ptr_bucket bucket_base;
|
typedef boost::unordered::detail::ptr_bucket bucket_base;
|
||||||
typedef bucket_base node_base;
|
|
||||||
typedef ptr_bucket* link_pointer;
|
typedef ptr_bucket* link_pointer;
|
||||||
|
|
||||||
link_pointer group_prev_;
|
link_pointer group_prev_;
|
||||||
std::size_t hash_;
|
std::size_t hash_;
|
||||||
|
|
||||||
#if BOOST_UNORDERED_DETAIL_FULL_CONSTRUCT
|
|
||||||
template <BOOST_UNORDERED_EMPLACE_TEMPLATE>
|
|
||||||
explicit grouped_ptr_node(BOOST_UNORDERED_EMPLACE_ARGS) :
|
|
||||||
bucket_base(),
|
|
||||||
group_prev_(0),
|
|
||||||
hash_(0)
|
|
||||||
{
|
|
||||||
boost::unordered::detail::construct_impl(
|
|
||||||
this->value_ptr(), BOOST_UNORDERED_EMPLACE_FORWARD);
|
|
||||||
}
|
|
||||||
|
|
||||||
~grouped_ptr_node() {
|
|
||||||
boost::unordered::detail::destroy(this->value_ptr());
|
|
||||||
}
|
|
||||||
|
|
||||||
grouped_ptr_node(grouped_ptr_node const&) {
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
grouped_ptr_node() :
|
grouped_ptr_node() :
|
||||||
bucket_base(),
|
bucket_base(),
|
||||||
group_prev_(0),
|
group_prev_(0),
|
||||||
hash_(0)
|
hash_(0)
|
||||||
{}
|
{}
|
||||||
#endif
|
|
||||||
|
|
||||||
void init(link_pointer self)
|
void init(link_pointer self)
|
||||||
{
|
{
|
||||||
|
@ -24,41 +24,18 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
|
|
||||||
template <typename A, typename T>
|
template <typename A, typename T>
|
||||||
struct unique_node :
|
struct unique_node :
|
||||||
boost::unordered::detail::node_base<
|
|
||||||
typename ::boost::unordered::detail::rebind_wrap<
|
|
||||||
A, unique_node<A, T> >::type::pointer
|
|
||||||
>,
|
|
||||||
boost::unordered::detail::value_base<T>
|
boost::unordered::detail::value_base<T>
|
||||||
{
|
{
|
||||||
typedef typename ::boost::unordered::detail::rebind_wrap<
|
typedef typename ::boost::unordered::detail::rebind_wrap<
|
||||||
A, unique_node<A, T> >::type::pointer link_pointer;
|
A, unique_node<A, T> >::type::pointer link_pointer;
|
||||||
typedef boost::unordered::detail::node_base<link_pointer> node_base;
|
|
||||||
|
|
||||||
|
link_pointer next_;
|
||||||
std::size_t hash_;
|
std::size_t hash_;
|
||||||
|
|
||||||
#if BOOST_UNORDERED_DETAIL_FULL_CONSTRUCT
|
|
||||||
template <BOOST_UNORDERED_EMPLACE_TEMPLATE>
|
|
||||||
explicit unique_node(BOOST_UNORDERED_EMPLACE_ARGS) :
|
|
||||||
node_base(),
|
|
||||||
hash_(0)
|
|
||||||
{
|
|
||||||
boost::unordered::detail::construct_impl(
|
|
||||||
this->value_ptr(), BOOST_UNORDERED_EMPLACE_FORWARD);
|
|
||||||
}
|
|
||||||
|
|
||||||
~unique_node() {
|
|
||||||
boost::unordered::detail::destroy(this->value_ptr());
|
|
||||||
}
|
|
||||||
|
|
||||||
unique_node(unique_node const&) {
|
|
||||||
BOOST_ASSERT(false);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
unique_node() :
|
unique_node() :
|
||||||
node_base(),
|
next_(),
|
||||||
hash_(0)
|
hash_(0)
|
||||||
{}
|
{}
|
||||||
#endif
|
|
||||||
|
|
||||||
void init(link_pointer)
|
void init(link_pointer)
|
||||||
{
|
{
|
||||||
@ -74,34 +51,14 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
boost::unordered::detail::ptr_bucket
|
boost::unordered::detail::ptr_bucket
|
||||||
{
|
{
|
||||||
typedef boost::unordered::detail::ptr_bucket bucket_base;
|
typedef boost::unordered::detail::ptr_bucket bucket_base;
|
||||||
typedef bucket_base node_base;
|
|
||||||
typedef ptr_bucket* link_pointer;
|
typedef ptr_bucket* link_pointer;
|
||||||
|
|
||||||
std::size_t hash_;
|
std::size_t hash_;
|
||||||
|
|
||||||
#if BOOST_UNORDERED_DETAIL_FULL_CONSTRUCT
|
|
||||||
template <BOOST_UNORDERED_EMPLACE_TEMPLATE>
|
|
||||||
explicit ptr_node(BOOST_UNORDERED_EMPLACE_ARGS) :
|
|
||||||
bucket_base(),
|
|
||||||
hash_(0)
|
|
||||||
{
|
|
||||||
boost::unordered::detail::construct_impl(
|
|
||||||
this->value_ptr(), BOOST_UNORDERED_EMPLACE_FORWARD);
|
|
||||||
}
|
|
||||||
|
|
||||||
~ptr_node() {
|
|
||||||
boost::unordered::detail::destroy(this->value_ptr());
|
|
||||||
}
|
|
||||||
|
|
||||||
ptr_node(ptr_node const&) {
|
|
||||||
BOOST_ASSERT(false);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
ptr_node() :
|
ptr_node() :
|
||||||
bucket_base(),
|
bucket_base(),
|
||||||
hash_(0)
|
hash_(0)
|
||||||
{}
|
{}
|
||||||
#endif
|
|
||||||
|
|
||||||
void init(link_pointer)
|
void init(link_pointer)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user