|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r78349 - trunk/boost/unordered/detail
From: dnljms_at_[hidden]
Date: 2012-05-06 08:29:26
Author: danieljames
Date: 2012-05-06 08:29:24 EDT (Sun, 06 May 2012)
New Revision: 78349
URL: http://svn.boost.org/trac/boost/changeset/78349
Log:
Unordered: Use std::allocator_trait's variadic construct.
Text files modified:
trunk/boost/unordered/detail/allocator_helpers.hpp | 225 +++++++++++++++++++++++++++++----------
trunk/boost/unordered/detail/buckets.hpp | 94 +++++++++-------
trunk/boost/unordered/detail/emplace_args.hpp | 36 ++++++
trunk/boost/unordered/detail/equivalent.hpp | 42 ++++++
trunk/boost/unordered/detail/unique.hpp | 40 ++++++
5 files changed, 332 insertions(+), 105 deletions(-)
Modified: trunk/boost/unordered/detail/allocator_helpers.hpp
==============================================================================
--- trunk/boost/unordered/detail/allocator_helpers.hpp (original)
+++ trunk/boost/unordered/detail/allocator_helpers.hpp 2012-05-06 08:29:24 EDT (Sun, 06 May 2012)
@@ -15,14 +15,7 @@
# pragma once
#endif
-#include <boost/config.hpp>
-#include <boost/detail/select_type.hpp>
-#include <boost/utility/enable_if.hpp>
-#include <boost/preprocessor/cat.hpp>
-#include <boost/preprocessor/enum.hpp>
-#include <boost/limits.hpp>
-#include <boost/type_traits/add_lvalue_reference.hpp>
-#include <boost/pointer_to_other.hpp>
+#include <boost/unordered/detail/emplace_args.hpp>
#include <boost/assert.hpp>
#include <boost/utility/addressof.hpp>
@@ -31,23 +24,29 @@
# if defined(__GXX_EXPERIMENTAL_CXX0X__) && \
(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
# define BOOST_UNORDERED_USE_ALLOCATOR_TRAITS 1
-# elif BOOST_MSVC >= 1700 && defined(_CPPLIB_VER)
-# define BOOST_UNORDERED_USE_ALLOCATOR_TRAITS 1
-# endif
-
-// Use container's allocator_traits for older versions of Visual C++ as I don't
-// test with them.
-# if defined(BOOST_MSVC) && BOOST_MSVC < 1400
-# define BOOST_UNORDERED_USE_ALLOCATOR_TRAITS 2
+# elif defined(BOOST_MSVC)
+# if BOOST_MSVC < 1400
+ // Use container's allocator_traits for older versions of Visual
+ // C++ as I don't test with them.
+# define BOOST_UNORDERED_USE_ALLOCATOR_TRAITS 2
+# elif BOOST_MSVC >= 1700
+# define BOOST_UNORDERED_USE_ALLOCATOR_TRAITS 1
+# endif
# endif
-
#endif
#if !defined(BOOST_UNORDERED_USE_ALLOCATOR_TRAITS)
# define BOOST_UNORDERED_USE_ALLOCATOR_TRAITS 0
#endif
-#if BOOST_UNORDERED_USE_ALLOCATOR_TRAITS == 1
+#if BOOST_UNORDERED_USE_ALLOCATOR_TRAITS == 0
+# include <boost/limits.hpp>
+# include <boost/utility/enable_if.hpp>
+# include <boost/pointer_to_other.hpp>
+# if defined(BOOST_NO_SFINAE_EXPR)
+# include <boost/type_traits/is_same.hpp>
+# endif
+#elif BOOST_UNORDERED_USE_ALLOCATOR_TRAITS == 1
# include <memory>
#elif BOOST_UNORDERED_USE_ALLOCATOR_TRAITS == 2
# include <boost/container/allocator_traits.hpp>
@@ -57,6 +56,7 @@
# include <type_traits>
#endif
+
namespace boost { namespace unordered { namespace detail {
////////////////////////////////////////////////////////////////////////////
@@ -98,43 +98,10 @@
#endif
////////////////////////////////////////////////////////////////////////////
- // Bits and pieces for implementing traits
- //
- // Some of these are also used elsewhere
-
- template <typename T> typename boost::add_lvalue_reference<T>::type make();
- struct choice9 { typedef char (&type)[9]; };
- struct choice8 : choice9 { typedef char (&type)[8]; };
- struct choice7 : choice8 { typedef char (&type)[7]; };
- struct choice6 : choice7 { typedef char (&type)[6]; };
- struct choice5 : choice6 { typedef char (&type)[5]; };
- struct choice4 : choice5 { typedef char (&type)[4]; };
- struct choice3 : choice4 { typedef char (&type)[3]; };
- struct choice2 : choice3 { typedef char (&type)[2]; };
- struct choice1 : choice2 { typedef char (&type)[1]; };
- choice1 choose();
-
- typedef choice1::type yes_type;
- typedef choice2::type no_type;
-
- struct private_type
- {
- private_type const &operator,(int) const;
- };
-
- template <typename T>
- no_type is_private_type(T const&);
- yes_type is_private_type(private_type const&);
-
- struct convert_from_anything {
- template <typename T>
- convert_from_anything(T const&);
- };
+ // Expression test mechanism
#if !defined(BOOST_NO_SFINAE_EXPR)
-# define BOOST_UNORDERED_HAVE_CALL_DETECTION 1
-
template <typename T, unsigned int> struct expr_test;
template <typename T> struct expr_test<T, sizeof(char)> : T {};
template <typename U> static char for_expr_test(U const&);
@@ -165,8 +132,6 @@
#else
-# define BOOST_UNORDERED_HAVE_CALL_DETECTION 0
-
template <typename T> struct identity { typedef T type; };
#define BOOST_UNORDERED_CHECK_MEMBER(count, result, name, member) \
@@ -209,12 +174,11 @@
////////////////////////////////////////////////////////////////////////////
// Allocator traits
- //
- // Uses the standard versions if available.
- // (although untested as I don't have access to a standard version yet)
#if BOOST_UNORDERED_USE_ALLOCATOR_TRAITS == 1
+#define BOOST_UNORDERED_DETAIL_FULL_CONSTRUCT 1
+
template <typename Alloc>
struct allocator_traits : std::allocator_traits<Alloc> {};
@@ -227,6 +191,8 @@
#elif BOOST_UNORDERED_USE_ALLOCATOR_TRAITS == 2
+#define BOOST_UNORDERED_DETAIL_FULL_CONSTRUCT 0
+
template <typename Alloc>
struct allocator_traits :
boost::container::allocator_traits<Alloc> {};
@@ -239,6 +205,13 @@
#else
+#if defined(BOOST_UNORDERED_VARIADIC_MOVE)
+# define BOOST_UNORDERED_DETAIL_FULL_CONSTRUCT 1
+#else
+# define BOOST_UNORDERED_DETAIL_FULL_CONSTRUCT 0
+#endif
+
+
// TODO: Does this match std::allocator_traits<Alloc>::rebind_alloc<T>?
template <typename Alloc, typename T>
struct rebind_wrap
@@ -309,7 +282,7 @@
BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(propagate_on_container_move_assignment);
BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(propagate_on_container_swap);
-#if BOOST_UNORDERED_HAVE_CALL_DETECTION
+#if !defined(BOOST_NO_SFINAE_EXPR)
template <typename T>
BOOST_UNORDERED_HAS_FUNCTION(
select_on_container_copy_construction, U const, (), 0
@@ -320,12 +293,21 @@
max_size, U const, (), 0
);
+# if defined(BOOST_UNORDERED_VARIADIC_MOVE)
+ template <typename T, typename ValueType, typename... Args>
+ BOOST_UNORDERED_HAS_FUNCTION(
+ construct, U, (
+ boost::unordered::detail::make<ValueType*>(),
+ boost::unordered::detail::make<Args const>()...), 2
+ );
+# else
template <typename T, typename ValueType>
BOOST_UNORDERED_HAS_FUNCTION(
construct, U, (
boost::unordered::detail::make<ValueType*>(),
boost::unordered::detail::make<ValueType const>()), 2
);
+# endif
template <typename T, typename ValueType>
BOOST_UNORDERED_HAS_FUNCTION(
@@ -425,7 +407,27 @@
public:
- // Only supporting the basic copy constructor for now.
+#if defined(BOOST_UNORDERED_VARIADIC_MOVE)
+
+ template <typename T, typename... Args>
+ static typename boost::enable_if_c<
+ boost::unordered::detail::has_construct<Alloc, T, Args...>
+ ::value>::type
+ construct(Alloc& a, T* p, Args&&... x)
+ {
+ a.construct(p, boost::forward<Args>(x)...);
+ }
+
+ template <typename T, typename... Args>
+ static typename boost::disable_if_c<
+ boost::unordered::detail::has_construct<Alloc, T, Args...>
+ ::value>::type
+ construct(Alloc&, T* p, Args&&... x)
+ {
+ new ((void*) p) T(boost::forward<Args>(x)...);
+ }
+
+#elif !defined(BOOST_NO_SFINAE_EXPR)
template <typename T>
static typename boost::enable_if_c<
@@ -443,6 +445,52 @@
new ((void*) p) T(x);
}
+#else
+
+ // If we don't have SFINAE expressions, only construct the type
+ // that matches the allocator.
+
+ template <typename T>
+ static typename boost::enable_if_c<
+ boost::unordered::detail::has_construct<Alloc, T>::value &&
+ boost::is_same<T, value_type>::value
+ >::type
+ construct(Alloc& a, T* p, T const& x)
+ {
+ a.construct(p, x);
+ }
+
+ template <typename T>
+ static typename boost::disable_if_c<
+ boost::unordered::detail::has_construct<Alloc, T>::value &&
+ boost::is_same<T, value_type>::value
+ >::type
+ construct(Alloc&, T* p, T const& x)
+ {
+ new ((void*) p) T(x);
+ }
+
+#endif
+
+#if defined(BOOST_UNORDERED_VARIADIC_MOVE)
+ template <typename T>
+ static typename boost::enable_if_c<
+ boost::unordered::detail::has_destroy<Alloc, T>::value>::type
+ destroy(Alloc& a, T* p)
+ {
+ a.destroy(p);
+ }
+
+ template <typename T>
+ static typename boost::disable_if_c<
+ boost::unordered::detail::has_destroy<Alloc, T>::value>::type
+ destroy(Alloc&, T* p)
+ {
+ boost::unordered::detail::destroy(p);
+ }
+
+#elif !defined(BOOST_NO_SFINAE_EXPR)
+
template <typename T>
static typename boost::enable_if_c<
boost::unordered::detail::has_destroy<Alloc, T>::value>::type
@@ -459,6 +507,30 @@
boost::unordered::detail::destroy(p);
}
+#else
+
+ template <typename T>
+ static typename boost::enable_if_c<
+ boost::unordered::detail::has_destroy<Alloc, T>::value &&
+ boost::is_same<T, value_type>::value
+ >::type
+ destroy(Alloc& a, T* p)
+ {
+ a.destroy(p);
+ }
+
+ template <typename T>
+ static typename boost::disable_if_c<
+ boost::unordered::detail::has_destroy<Alloc, T>::value &&
+ boost::is_same<T, value_type>::value
+ >::type
+ destroy(Alloc&, T* p)
+ {
+ boost::unordered::detail::destroy(p);
+ }
+
+#endif
+
static size_type max_size(const Alloc& a)
{
return boost::unordered::detail::call_max_size<size_type>(a);
@@ -490,6 +562,41 @@
#endif
+#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 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, T());
+ try {
+ boost::unordered::detail::construct_impl(
+ p->value_ptr(), BOOST_UNORDERED_EMPLACE_FORWARD);
+ } catch(...) {
+ boost::unordered::detail::allocator_traits<Alloc>::destroy(a, p);
+ throw;
+ }
+ }
+
+ 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
//
// Allocate and construct an array in an exception safe manner, and
Modified: trunk/boost/unordered/detail/buckets.hpp
==============================================================================
--- trunk/boost/unordered/detail/buckets.hpp (original)
+++ trunk/boost/unordered/detail/buckets.hpp 2012-05-06 08:29:24 EDT (Sun, 06 May 2012)
@@ -13,7 +13,6 @@
#include <boost/unordered/detail/util.hpp>
#include <boost/unordered/detail/allocator_helpers.hpp>
-#include <boost/unordered/detail/emplace_args.hpp>
#include <boost/type_traits/aligned_storage.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <boost/swap.hpp>
@@ -54,16 +53,14 @@
node_allocator& alloc_;
node_pointer node_;
- bool node_constructed_;
- bool value_constructed_;
+ bool constructed_;
public:
node_constructor(node_allocator& n) :
alloc_(n),
node_(),
- node_constructed_(false),
- value_constructed_(false)
+ constructed_(false)
{
}
@@ -74,26 +71,40 @@
template <BOOST_UNORDERED_EMPLACE_TEMPLATE>
void construct_value(BOOST_UNORDERED_EMPLACE_ARGS)
{
- BOOST_ASSERT(node_ && node_constructed_ && !value_constructed_);
- boost::unordered::detail::construct_impl(
- node_->value_ptr(), BOOST_UNORDERED_EMPLACE_FORWARD);
- value_constructed_ = true;
+ 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;
}
template <typename A0>
void construct_value2(BOOST_FWD_REF(A0) a0)
{
- BOOST_ASSERT(node_ && node_constructed_ && !value_constructed_);
- boost::unordered::detail::construct_impl2(
- node_->value_ptr(), boost::forward<A0>(a0));
- value_constructed_ = true;
+ BOOST_ASSERT(node_ && !constructed_);
+# if defined(BOOST_UNORDERED_VARIADIC_MOVE)
+ boost::unordered::detail::construct_node(alloc_,
+ boost::addressof(*node_), boost::forward<A0>(a0));
+# else
+ boost::unordered::detail::construct_node(alloc_,
+ boost::addressof(*node_),
+ boost::unordered::detail::create_emplace_args(
+ boost::forward<A0>(a0)));
+# endif
+ constructed_ = true;
+ node_->init(static_cast<typename node::link_pointer>(node_));
}
value_type const& value() const {
- BOOST_ASSERT(node_ && node_constructed_ && value_constructed_);
+ BOOST_ASSERT(node_ && constructed_);
return node_->value();
}
+ node_pointer get()
+ {
+ return node_;
+ }
+
// no throw
node_pointer release()
{
@@ -111,12 +122,8 @@
node_constructor<Alloc>::~node_constructor()
{
if (node_) {
- if (value_constructed_) {
- boost::unordered::detail::destroy(node_->value_ptr());
- }
-
- if (node_constructed_) {
- node_allocator_traits::destroy(alloc_,
+ if (constructed_) {
+ boost::unordered::detail::destroy_node(alloc_,
boost::addressof(*node_));
}
@@ -128,24 +135,13 @@
void node_constructor<Alloc>::construct_node()
{
if(!node_) {
- node_constructed_ = false;
- value_constructed_ = false;
-
+ 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 {
- BOOST_ASSERT(node_constructed_);
-
- if (value_constructed_)
- {
- boost::unordered::detail::destroy(node_->value_ptr());
- value_constructed_ = false;
- }
+ else if (constructed_) {
+ boost::unordered::detail::destroy_node(alloc_,
+ boost::addressof(*node_));
+ constructed_ = false;
}
}
@@ -183,6 +179,16 @@
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 {
@@ -718,6 +724,14 @@
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();
@@ -762,9 +776,8 @@
inline void delete_node(c_iterator n)
{
- boost::unordered::detail::destroy(n.node_->value_ptr());
- node_allocator_traits::destroy(node_alloc(),
- boost::addressof(*n.node_));
+ boost::unordered::detail::destroy_node(
+ node_alloc(), boost::addressof(*n.node_));
node_allocator_traits::deallocate(node_alloc(), n.node_, 1);
--size_;
}
@@ -786,7 +799,8 @@
inline void delete_extra_node(bucket_pointer) {}
inline void delete_extra_node(node_pointer n) {
- node_allocator_traits::destroy(node_alloc(), boost::addressof(*n));
+ node_allocator_traits::destroy(node_alloc(),
+ static_cast<typename node::node_base*>(boost::addressof(*n)));
node_allocator_traits::deallocate(node_alloc(), n, 1);
}
Modified: trunk/boost/unordered/detail/emplace_args.hpp
==============================================================================
--- trunk/boost/unordered/detail/emplace_args.hpp (original)
+++ trunk/boost/unordered/detail/emplace_args.hpp 2012-05-06 08:29:24 EDT (Sun, 06 May 2012)
@@ -12,6 +12,7 @@
# pragma once
#endif
+#include <boost/unordered/detail/fwd.hpp>
#include <boost/move/move.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/inc.hpp>
@@ -21,7 +22,10 @@
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/type_traits/is_class.hpp>
+#include <boost/type_traits/add_lvalue_reference.hpp>
#include <boost/tuple/tuple.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/detail/select_type.hpp>
#include <utility>
#if !defined(BOOST_NO_0X_HDR_TUPLE)
@@ -46,6 +50,38 @@
namespace boost { namespace unordered { namespace detail {
////////////////////////////////////////////////////////////////////////////
+ // Bits and pieces for implementing traits
+
+ template <typename T> typename boost::add_lvalue_reference<T>::type make();
+ struct choice9 { typedef char (&type)[9]; };
+ struct choice8 : choice9 { typedef char (&type)[8]; };
+ struct choice7 : choice8 { typedef char (&type)[7]; };
+ struct choice6 : choice7 { typedef char (&type)[6]; };
+ struct choice5 : choice6 { typedef char (&type)[5]; };
+ struct choice4 : choice5 { typedef char (&type)[4]; };
+ struct choice3 : choice4 { typedef char (&type)[3]; };
+ struct choice2 : choice3 { typedef char (&type)[2]; };
+ struct choice1 : choice2 { typedef char (&type)[1]; };
+ choice1 choose();
+
+ typedef choice1::type yes_type;
+ typedef choice2::type no_type;
+
+ struct private_type
+ {
+ private_type const &operator,(int) const;
+ };
+
+ template <typename T>
+ no_type is_private_type(T const&);
+ yes_type is_private_type(private_type const&);
+
+ struct convert_from_anything {
+ template <typename T>
+ convert_from_anything(T const&);
+ };
+
+ ////////////////////////////////////////////////////////////////////////////
// emplace_args
//
// Either forwarding variadic arguments, or storing the arguments in
Modified: trunk/boost/unordered/detail/equivalent.hpp
==============================================================================
--- trunk/boost/unordered/detail/equivalent.hpp (original)
+++ trunk/boost/unordered/detail/equivalent.hpp 2012-05-06 08:29:24 EDT (Sun, 06 May 2012)
@@ -12,7 +12,6 @@
#endif
#include <boost/unordered/detail/table.hpp>
-#include <boost/unordered/detail/emplace_args.hpp>
#include <boost/unordered/detail/extract_key.hpp>
namespace boost { namespace unordered { namespace detail {
@@ -23,20 +22,40 @@
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>
+ 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());
+ }
+#else
grouped_node() :
- next_(),
+ node_base(),
group_prev_(),
hash_(0)
{}
+#endif
void init(link_pointer self)
{
@@ -50,16 +69,33 @@
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>
+ 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());
+ }
+#else
grouped_ptr_node() :
bucket_base(),
group_prev_(0),
hash_(0)
{}
+#endif
void init(link_pointer self)
{
Modified: trunk/boost/unordered/detail/unique.hpp
==============================================================================
--- trunk/boost/unordered/detail/unique.hpp (original)
+++ trunk/boost/unordered/detail/unique.hpp 2012-05-06 08:29:24 EDT (Sun, 06 May 2012)
@@ -12,7 +12,6 @@
#endif
#include <boost/unordered/detail/table.hpp>
-#include <boost/unordered/detail/emplace_args.hpp>
#include <boost/unordered/detail/extract_key.hpp>
#include <boost/throw_exception.hpp>
#include <stdexcept>
@@ -25,18 +24,37 @@
template <typename A, typename T>
struct node :
+ boost::unordered::detail::node_base<
+ typename ::boost::unordered::detail::rebind_wrap<
+ A, node<A, T> >::type::pointer
+ >,
boost::unordered::detail::value_base<T>
{
typedef typename ::boost::unordered::detail::rebind_wrap<
A, 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>
+ node(BOOST_UNORDERED_EMPLACE_ARGS) :
+ node_base(),
+ hash_(0)
+ {
+ boost::unordered::detail::construct_impl(
+ this->value_ptr(), BOOST_UNORDERED_EMPLACE_FORWARD);
+ }
+
+ ~node() {
+ boost::unordered::detail::destroy(this->value_ptr());
+ }
+#else
node() :
- next_(),
+ node_base(),
hash_(0)
{}
+#endif
void init(link_pointer)
{
@@ -49,14 +67,30 @@
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>
+ 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());
+ }
+#else
ptr_node() :
bucket_base(),
hash_(0)
{}
+#endif
void init(link_pointer)
{
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk