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:
Daniel James
2012-08-25 21:51:24 +00:00
parent 2e11fd8a86
commit ff31c73970
4 changed files with 43 additions and 211 deletions

View File

@ -1104,76 +1104,6 @@ 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

View File

@ -53,14 +53,16 @@ namespace boost { namespace unordered { namespace detail {
node_allocator& alloc_;
node_pointer node_;
bool constructed_;
bool node_constructed_;
bool value_constructed_;
public:
node_constructor(node_allocator& n) :
alloc_(n),
node_(),
constructed_(false)
node_constructed_(false),
value_constructed_(false)
{
}
@ -71,36 +73,27 @@ namespace boost { namespace unordered { namespace detail {
template <BOOST_UNORDERED_EMPLACE_TEMPLATE>
void construct_value(BOOST_UNORDERED_EMPLACE_ARGS)
{
BOOST_ASSERT(node_ && !constructed_);
boost::unordered::detail::construct_node(alloc_,
boost::addressof(*node_), BOOST_UNORDERED_EMPLACE_FORWARD);
node_->init(static_cast<typename node::link_pointer>(node_));
constructed_ = true;
BOOST_ASSERT(node_ && node_constructed_ && !value_constructed_);
boost::unordered::detail::construct_impl(
node_->value_ptr(), BOOST_UNORDERED_EMPLACE_FORWARD);
value_constructed_ = true;
}
template <typename A0>
void construct_value2(BOOST_FWD_REF(A0) a0)
{
BOOST_ASSERT(node_ && !constructed_);
boost::unordered::detail::construct_node(alloc_,
boost::addressof(*node_),
BOOST_ASSERT(node_ && node_constructed_ && !value_constructed_);
boost::unordered::detail::construct_impl(
node_->value_ptr(),
BOOST_UNORDERED_EMPLACE_ARGS1(boost::forward<A0>(a0)));
constructed_ = true;
node_->init(static_cast<typename node::link_pointer>(node_));
value_constructed_ = true;
}
value_type const& value() const {
BOOST_ASSERT(node_ && constructed_);
BOOST_ASSERT(node_ && node_constructed_ && value_constructed_);
return node_->value();
}
node_pointer get()
{
return node_;
}
// no throw
node_pointer release()
{
@ -118,8 +111,12 @@ namespace boost { namespace unordered { namespace detail {
node_constructor<Alloc>::~node_constructor()
{
if (node_) {
if (constructed_) {
boost::unordered::detail::destroy_node(alloc_,
if (value_constructed_) {
boost::unordered::detail::destroy(node_->value_ptr());
}
if (node_constructed_) {
node_allocator_traits::destroy(alloc_,
boost::addressof(*node_));
}
@ -131,13 +128,24 @@ namespace boost { namespace unordered { namespace detail {
void node_constructor<Alloc>::construct_node()
{
if(!node_) {
constructed_ = false;
node_constructed_ = false;
value_constructed_ = false;
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_) {
boost::unordered::detail::destroy_node(alloc_,
boost::addressof(*node_));
constructed_ = false;
else {
BOOST_ASSERT(node_constructed_);
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 };
};
template <typename LinkPointer>
struct node_base
{
typedef LinkPointer link_pointer;
link_pointer next_;
node_base() : next_() {}
};
}}}
namespace boost { namespace unordered { namespace iterator_detail {
@ -720,14 +718,6 @@ namespace boost { namespace unordered { namespace detail {
node_constructor a(this->node_alloc());
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() +
static_cast<std::ptrdiff_t>(this->bucket_count_))->next_ =
a.release();
@ -772,8 +762,9 @@ namespace boost { namespace unordered { namespace detail {
inline void delete_node(c_iterator n)
{
boost::unordered::detail::destroy_node(
node_alloc(), boost::addressof(*n.node_));
boost::unordered::detail::destroy(n.node_->value_ptr());
node_allocator_traits::destroy(node_alloc(),
boost::addressof(*n.node_));
node_allocator_traits::deallocate(node_alloc(), n.node_, 1);
--size_;
}
@ -795,8 +786,7 @@ namespace boost { namespace unordered { namespace detail {
inline void delete_extra_node(bucket_pointer) {}
inline void delete_extra_node(node_pointer n) {
node_allocator_traits::destroy(node_alloc(),
static_cast<typename node::node_base*>(boost::addressof(*n)));
node_allocator_traits::destroy(node_alloc(), boost::addressof(*n));
node_allocator_traits::deallocate(node_alloc(), n, 1);
}

View File

@ -22,44 +22,20 @@ namespace boost { namespace unordered { namespace detail {
template <typename A, typename T>
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>
{
typedef typename ::boost::unordered::detail::rebind_wrap<
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_;
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() :
node_base(),
next_(),
group_prev_(),
hash_(0)
{}
#endif
void init(link_pointer self)
{
@ -76,37 +52,16 @@ namespace boost { namespace unordered { namespace detail {
boost::unordered::detail::ptr_bucket
{
typedef boost::unordered::detail::ptr_bucket bucket_base;
typedef bucket_base node_base;
typedef ptr_bucket* link_pointer;
link_pointer group_prev_;
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() :
bucket_base(),
group_prev_(0),
hash_(0)
{}
#endif
void init(link_pointer self)
{

View File

@ -24,41 +24,18 @@ namespace boost { namespace unordered { namespace detail {
template <typename A, typename T>
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>
{
typedef typename ::boost::unordered::detail::rebind_wrap<
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_;
#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() :
node_base(),
next_(),
hash_(0)
{}
#endif
void init(link_pointer)
{
@ -74,34 +51,14 @@ namespace boost { namespace unordered { namespace detail {
boost::unordered::detail::ptr_bucket
{
typedef boost::unordered::detail::ptr_bucket bucket_base;
typedef bucket_base node_base;
typedef ptr_bucket* link_pointer;
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() :
bucket_base(),
hash_(0)
{}
#endif
void init(link_pointer)
{