forked from boostorg/unordered
Unordered: Use std::allocator_trait's variadic construct.
[SVN r78349]
This commit is contained in:
@ -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
|
||||
# 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
|
||||
|
||||
// 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
|
||||
# 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 @@ namespace boost { namespace unordered { namespace detail {
|
||||
#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 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
#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 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// 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 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
#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 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
#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 @@ namespace boost { namespace unordered { namespace detail {
|
||||
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 @@ namespace boost { namespace unordered { namespace detail {
|
||||
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 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
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,34 @@ namespace boost { namespace unordered { namespace detail {
|
||||
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
|
||||
@ -459,6 +489,48 @@ namespace boost { namespace unordered { namespace detail {
|
||||
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
|
||||
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);
|
||||
}
|
||||
|
||||
#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);
|
||||
@ -488,6 +560,41 @@ namespace boost { namespace unordered { namespace detail {
|
||||
#undef BOOST_UNORDERED_DEFAULT_TYPE_TMPLT
|
||||
#undef BOOST_UNORDERED_DEFAULT_TYPE
|
||||
|
||||
#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
|
||||
|
@ -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 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
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 @@ namespace boost { namespace unordered { namespace detail {
|
||||
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 @@ namespace boost { namespace unordered { namespace detail {
|
||||
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 @@ namespace boost { namespace unordered { namespace detail {
|
||||
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 @@ 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 {
|
||||
@ -718,6 +724,14 @@ 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();
|
||||
@ -762,9 +776,8 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
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 @@ 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(), 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);
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
@ -45,6 +49,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
|
||||
//
|
||||
|
@ -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 @@ 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>
|
||||
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 @@ 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>
|
||||
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)
|
||||
{
|
||||
|
@ -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 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
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 @@ 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>
|
||||
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)
|
||||
{
|
||||
|
Reference in New Issue
Block a user