Merge branch 'feature/expand-calls' into develop

Expanding a lot of the call to the implementation methods. While working
on some recent changes, I felt the call chains in error messages were
too long, this reduces that a little. It also should make debugging a
tad easier and I think it makes the methods a little more informative,
as you can see what they're doing without hunting around the
implementation file. Also reduces the number of symbols when compiling,
although I'm not sure if that will make much of a difference.

Does make the code a little long, and duplicated, but I don't think it's
particularly harmful.
This commit is contained in:
Daniel James
2017-04-23 10:09:28 +01:00
3 changed files with 474 additions and 462 deletions

View File

@ -2708,6 +2708,8 @@ struct table : boost::unordered::detail::functions<typename Types::hasher,
////////////////////////////////////////////////////////////////////////
// Data access
static node_pointer get_node(c_iterator it) { return it.node_; }
bucket_allocator const& bucket_alloc() const { return allocators_.first(); }
node_allocator const& node_alloc() const { return allocators_.second(); }
@ -2758,12 +2760,6 @@ struct table : boost::unordered::detail::functions<typename Types::hasher,
return policy::to_bucket(bucket_count_, hash_value);
}
float load_factor() const
{
BOOST_ASSERT(bucket_count_ != 0);
return static_cast<float>(size_) / static_cast<float>(bucket_count_);
}
std::size_t bucket_size(std::size_t index) const
{
node_pointer n = begin(index);
@ -2782,17 +2778,6 @@ struct table : boost::unordered::detail::functions<typename Types::hasher,
////////////////////////////////////////////////////////////////////////
// Load methods
std::size_t max_size() const
{
using namespace std;
// size < mlf_ * count
return boost::unordered::detail::double_to_size(
ceil(static_cast<double>(mlf_) *
static_cast<double>(max_bucket_count()))) -
1;
}
void recalculate_max_load()
{
using namespace std;
@ -2868,26 +2853,6 @@ struct table : boost::unordered::detail::functions<typename Types::hasher,
{
}
////////////////////////////////////////////////////////////////////////
// Initialisation.
void init(table const& x)
{
if (x.size_) {
static_cast<table_impl*>(this)->copy_buckets(x);
}
}
void move_init(table& x)
{
if (node_alloc() == x.node_alloc()) {
move_buckets_from(x);
} else if (x.size_) {
// TODO: Could pick new bucket size?
static_cast<table_impl*>(this)->move_buckets(x);
}
}
////////////////////////////////////////////////////////////////////////
// Clear buckets and Create buckets
//
@ -3078,17 +3043,6 @@ struct table : boost::unordered::detail::functions<typename Types::hasher,
BOOST_ASSERT(!size_);
}
void clear()
{
if (!size_)
return;
clear_buckets();
delete_nodes(get_previous_start(), link_pointer());
BOOST_ASSERT(!size_);
}
void destroy_buckets()
{
bucket_pointer end = get_bucket(bucket_count_ + 1);
@ -3258,13 +3212,6 @@ struct table : boost::unordered::detail::functions<typename Types::hasher,
// Find Node
template <typename Key, typename Hash, typename Pred>
node_pointer generic_find_node(
Key const& k, Hash const& hf, Pred const& eq) const
{
return this->find_node_impl(policy::apply_hash(hf, k), k, eq);
}
node_pointer find_node(std::size_t key_hash, const_key_type& k) const
{
return this->find_node_impl(key_hash, k, this->key_eq());
@ -3393,13 +3340,6 @@ inline void table<Types>::rehash(std::size_t min_buckets)
}
}
template <typename Types>
inline void table<Types>::reserve(std::size_t num_elements)
{
rehash(static_cast<std::size_t>(
std::ceil(static_cast<double>(num_elements) / mlf_)));
}
template <typename Types>
inline void table<Types>::rehash_impl(std::size_t num_buckets)
{
@ -3789,50 +3729,34 @@ struct table_unique : boost::unordered::detail::table<Types>
: table(x, node_allocator_traits::select_on_container_copy_construction(
x.node_alloc()))
{
this->init(x);
if (x.size_) {
this->copy_buckets(x);
}
}
table_unique(table_unique const& x, node_allocator const& a) : table(x, a)
{
this->init(x);
if (x.size_) {
this->copy_buckets(x);
}
}
table_unique(table_unique& x, boost::unordered::detail::move_tag m)
: table(x, m)
{
// The move is done in the base class.
}
table_unique(table_unique& x, node_allocator const& a,
boost::unordered::detail::move_tag m)
: table(x, a, m)
{
this->move_init(x);
}
// Accessors
std::size_t count(const_key_type& k) const
{
return this->find_node(k) ? 1 : 0;
}
value_type& at(const_key_type& k) const
{
if (this->size_) {
node_pointer n = this->find_node(k);
if (n)
return n->value();
if (this->node_alloc() == x.node_alloc()) {
this->move_buckets_from(x);
} else if (x.size_) {
// TODO: Could pick new bucket size?
this->move_buckets(x);
}
boost::throw_exception(
std::out_of_range("Unable to find key in unordered_map."));
}
std::pair<iterator, iterator> equal_range(const_key_type& k) const
{
node_pointer n = this->find_node(k);
return std::make_pair(
iterator(n), iterator(n ? node_algo::next_node(n) : n));
}
// equals
@ -3890,81 +3814,6 @@ struct table_unique : boost::unordered::detail::table<Types>
return this->add_node(b.release(), key_hash);
}
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
emplace_return emplace(boost::unordered::detail::emplace_args1<
boost::unordered::detail::please_ignore_this_overload> const&)
{
BOOST_ASSERT(false);
return emplace_return(iterator(), false);
}
iterator emplace_hint(
c_iterator,
boost::unordered::detail::emplace_args1<
boost::unordered::detail::please_ignore_this_overload> const&)
{
BOOST_ASSERT(false);
return iterator();
}
#else
emplace_return emplace(
boost::unordered::detail::please_ignore_this_overload const&)
{
BOOST_ASSERT(false);
return emplace_return(iterator(), false);
}
iterator emplace_hint(c_iterator,
boost::unordered::detail::please_ignore_this_overload const&)
{
BOOST_ASSERT(false);
return iterator();
}
#endif
#endif
template <BOOST_UNORDERED_EMPLACE_TEMPLATE>
emplace_return emplace(BOOST_UNORDERED_EMPLACE_ARGS)
{
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
return emplace_impl(extractor::extract(BOOST_UNORDERED_EMPLACE_FORWARD),
BOOST_UNORDERED_EMPLACE_FORWARD);
#else
return emplace_impl(extractor::extract(args.a0, args.a1),
BOOST_UNORDERED_EMPLACE_FORWARD);
#endif
}
template <BOOST_UNORDERED_EMPLACE_TEMPLATE>
iterator emplace_hint(c_iterator hint, BOOST_UNORDERED_EMPLACE_ARGS)
{
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
return emplace_hint_impl(hint,
extractor::extract(BOOST_UNORDERED_EMPLACE_FORWARD),
BOOST_UNORDERED_EMPLACE_FORWARD);
#else
return emplace_hint_impl(hint, extractor::extract(args.a0, args.a1),
BOOST_UNORDERED_EMPLACE_FORWARD);
#endif
}
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <typename A0>
emplace_return emplace(
boost::unordered::detail::emplace_args1<A0> const& args)
{
return emplace_impl(extractor::extract(args.a0), args);
}
template <typename A0>
iterator emplace_hint(c_iterator hint,
boost::unordered::detail::emplace_args1<A0> const& args)
{
return emplace_hint_impl(hint, extractor::extract(args.a0), args);
}
#endif
template <BOOST_UNORDERED_EMPLACE_TEMPLATE>
iterator emplace_hint_impl(
c_iterator hint, const_key_type& k, BOOST_UNORDERED_EMPLACE_ARGS)
@ -4188,12 +4037,6 @@ struct table_unique : boost::unordered::detail::table<Types>
// if hash function throws, or inserting > 1 element, basic exception
// safety strong otherwise
template <class InputIt> void insert_range(InputIt i, InputIt j)
{
if (i != j)
return insert_range_impl(extractor::extract(*i), i, j);
}
template <class InputIt>
void insert_range_impl(const_key_type& k, InputIt i, InputIt j)
{
@ -4298,22 +4141,6 @@ struct table_unique : boost::unordered::detail::table<Types>
return 1;
}
iterator erase(c_iterator r)
{
BOOST_ASSERT(r.node_);
node_pointer next = node_algo::next_node(r.node_);
erase_nodes(r.node_, next);
return iterator(next);
}
iterator erase_range(c_iterator r1, c_iterator r2)
{
if (r1 == r2)
return iterator(r2.node_);
erase_nodes(r1.node_, r2.node_);
return iterator(r2.node_);
}
void erase_nodes(node_pointer i, node_pointer j)
{
std::size_t bucket_index = this->hash_to_bucket(i->hash_);
@ -4610,39 +4437,34 @@ struct table_equiv : boost::unordered::detail::table<Types>
: table(x, node_allocator_traits::select_on_container_copy_construction(
x.node_alloc()))
{
this->init(x);
if (x.size_) {
copy_buckets(x);
}
}
table_equiv(table_equiv const& x, node_allocator const& a) : table(x, a)
{
this->init(x);
if (x.size_) {
copy_buckets(x);
}
}
table_equiv(table_equiv& x, boost::unordered::detail::move_tag m)
: table(x, m)
{
// The move is done in the base class.
}
table_equiv(table_equiv& x, node_allocator const& a,
boost::unordered::detail::move_tag m)
: table(x, a, m)
{
this->move_init(x);
}
// Accessors
std::size_t count(const_key_type& k) const
{
node_pointer n = this->find_node(k);
return n ? node_algo::count(n, this) : 0;
}
std::pair<iterator, iterator> equal_range(const_key_type& k) const
{
node_pointer n = this->find_node(k);
return std::make_pair(
iterator(n), iterator(n ? node_algo::next_group(n, this) : n));
if (this->node_alloc() == x.node_alloc()) {
this->move_buckets_from(x);
} else if (x.size_) {
// TODO: Could pick new bucket size?
this->move_buckets(x);
}
}
// Equality
@ -4786,56 +4608,6 @@ struct table_equiv : boost::unordered::detail::table<Types>
return n;
}
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
iterator emplace(boost::unordered::detail::emplace_args1<
boost::unordered::detail::please_ignore_this_overload> const&)
{
BOOST_ASSERT(false);
return iterator();
}
iterator emplace_hint(
c_iterator,
boost::unordered::detail::emplace_args1<
boost::unordered::detail::please_ignore_this_overload> const&)
{
BOOST_ASSERT(false);
return iterator();
}
#else
iterator emplace(
boost::unordered::detail::please_ignore_this_overload const&)
{
BOOST_ASSERT(false);
return iterator();
}
iterator emplace_hint(c_iterator,
boost::unordered::detail::please_ignore_this_overload const&)
{
BOOST_ASSERT(false);
return iterator();
}
#endif
#endif
template <BOOST_UNORDERED_EMPLACE_TEMPLATE>
iterator emplace(BOOST_UNORDERED_EMPLACE_ARGS)
{
return iterator(emplace_impl(
boost::unordered::detail::func::construct_node_from_args(
this->node_alloc(), BOOST_UNORDERED_EMPLACE_FORWARD)));
}
template <BOOST_UNORDERED_EMPLACE_TEMPLATE>
iterator emplace_hint(c_iterator hint, BOOST_UNORDERED_EMPLACE_ARGS)
{
return iterator(emplace_hint_impl(
hint, boost::unordered::detail::func::construct_node_from_args(
this->node_alloc(), BOOST_UNORDERED_EMPLACE_FORWARD)));
}
iterator emplace_impl(node_pointer n)
{
node_tmp a(n, this->node_alloc());
@ -5005,22 +4777,6 @@ struct table_equiv : boost::unordered::detail::table<Types>
return deleted_count;
}
iterator erase(c_iterator r)
{
BOOST_ASSERT(r.node_);
node_pointer next = node_algo::next_node(r.node_);
erase_nodes(r.node_, next);
return iterator(next);
}
iterator erase_range(c_iterator r1, c_iterator r2)
{
if (r1 == r2)
return iterator(r2.node_);
erase_nodes(r1.node_, r2.node_);
return iterator(r2.node_);
}
link_pointer erase_nodes(node_pointer i, node_pointer j)
{
std::size_t bucket_index = this->hash_to_bucket(i->hash_);

View File

@ -55,6 +55,8 @@ template <class K, class T, class H, class P, class A> class unordered_map
typedef boost::unordered::detail::map<A, K, T, H, P> types;
typedef typename types::value_allocator_traits value_allocator_traits;
typedef typename types::table table;
typedef typename table::node_pointer node_pointer;
typedef typename table::link_pointer link_pointer;
public:
typedef typename value_allocator_traits::pointer pointer;
@ -220,7 +222,9 @@ template <class K, class T, class H, class P, class A> class unordered_map
template <class... Args>
std::pair<iterator, bool> emplace(BOOST_FWD_REF(Args)... args)
{
return table_.emplace(boost::forward<Args>(args)...);
return table_.emplace_impl(
table::extractor::extract(boost::forward<Args>(args)...),
boost::forward<Args>(args)...);
}
#else
@ -244,25 +248,33 @@ template <class K, class T, class H, class P, class A> class unordered_map
template <typename A0>
std::pair<iterator, bool> emplace(BOOST_FWD_REF(A0) a0)
{
return table_.emplace(boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0)));
return table_.emplace_impl(
table::extractor::extract(boost::forward<A0>(a0)),
boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0)));
}
template <typename A0, typename A1>
std::pair<iterator, bool> emplace(
BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1)
{
return table_.emplace(boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1)));
return table_.emplace_impl(
table::extractor::extract(
boost::forward<A0>(a0), boost::forward<A1>(a1)),
boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1)));
}
template <typename A0, typename A1, typename A2>
std::pair<iterator, bool> emplace(
BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2)
{
return table_.emplace(boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1),
boost::forward<A2>(a2)));
return table_.emplace_impl(
table::extractor::extract(
boost::forward<A0>(a0), boost::forward<A1>(a1)),
boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1),
boost::forward<A2>(a2)));
}
#endif
@ -272,7 +284,9 @@ template <class K, class T, class H, class P, class A> class unordered_map
template <class... Args>
iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args)
{
return table_.emplace_hint(hint, boost::forward<Args>(args)...);
return table_.emplace_hint_impl(hint,
table::extractor::extract(boost::forward<Args>(args)...),
boost::forward<Args>(args)...);
}
#else
@ -292,28 +306,33 @@ template <class K, class T, class H, class P, class A> class unordered_map
template <typename A0>
iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(A0) a0)
{
return table_.emplace_hint(
hint, boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0)));
return table_.emplace_hint_impl(hint,
table::extractor::extract(boost::forward<A0>(a0)),
boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0)));
}
template <typename A0, typename A1>
iterator emplace_hint(
const_iterator hint, BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1)
{
return table_.emplace_hint(
hint, boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1)));
return table_.emplace_hint_impl(
hint, table::extractor::extract(
boost::forward<A0>(a0), boost::forward<A1>(a1)),
boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1)));
}
template <typename A0, typename A1, typename A2>
iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(A0) a0,
BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2)
{
return table_.emplace_hint(
hint, boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1),
boost::forward<A2>(a2)));
return table_.emplace_hint_impl(
hint, table::extractor::extract(
boost::forward<A0>(a0), boost::forward<A1>(a1)),
boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1),
boost::forward<A2>(a2)));
}
#endif
@ -325,21 +344,32 @@ template <class K, class T, class H, class P, class A> class unordered_map
std::pair<iterator, bool> emplace( \
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a)) \
{ \
return table_.emplace(boost::unordered::detail::create_emplace_args( \
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))); \
return table_.emplace_impl( \
table::extractor::extract( \
boost::forward<A0>(a0), boost::forward<A1>(a1)), \
boost::unordered::detail::create_emplace_args( \
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))); \
} \
\
template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)> \
iterator emplace_hint(const_iterator hint, \
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a)) \
{ \
return table_.emplace_hint( \
hint, boost::unordered::detail::create_emplace_args( \
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))); \
return table_.emplace_hint_impl( \
hint, table::extractor::extract( \
boost::forward<A0>(a0), boost::forward<A1>(a1)), \
boost::unordered::detail::create_emplace_args( \
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))); \
}
BOOST_PP_REPEAT_FROM_TO(
4, BOOST_PP_INC(BOOST_UNORDERED_EMPLACE_LIMIT), BOOST_UNORDERED_EMPLACE, _)
BOOST_UNORDERED_EMPLACE(1, 4, _)
BOOST_UNORDERED_EMPLACE(1, 5, _)
BOOST_UNORDERED_EMPLACE(1, 6, _)
BOOST_UNORDERED_EMPLACE(1, 7, _)
BOOST_UNORDERED_EMPLACE(1, 8, _)
BOOST_UNORDERED_EMPLACE(1, 9, _)
BOOST_PP_REPEAT_FROM_TO(10, BOOST_PP_INC(BOOST_UNORDERED_EMPLACE_LIMIT),
BOOST_UNORDERED_EMPLACE, _)
#undef BOOST_UNORDERED_EMPLACE
@ -625,8 +655,8 @@ template <class K, class T, class H, class P, class A> class unordered_map
n, BOOST_UNORDERED_CALL_FORWARD, a))); \
}
BOOST_PP_REPEAT_FROM_TO(
4, BOOST_PP_INC(BOOST_UNORDERED_EMPLACE_LIMIT), BOOST_UNORDERED_TRY_EMPLACE, _)
BOOST_PP_REPEAT_FROM_TO(4, BOOST_PP_INC(BOOST_UNORDERED_EMPLACE_LIMIT),
BOOST_UNORDERED_TRY_EMPLACE, _)
#undef BOOST_UNORDERED_TRY_EMPLACE
@ -808,6 +838,8 @@ template <class K, class T, class H, class P, class A> class unordered_multimap
typedef boost::unordered::detail::multimap<A, K, T, H, P> types;
typedef typename types::value_allocator_traits value_allocator_traits;
typedef typename types::table table;
typedef typename table::node_pointer node_pointer;
typedef typename table::link_pointer link_pointer;
public:
typedef typename value_allocator_traits::pointer pointer;
@ -972,7 +1004,9 @@ template <class K, class T, class H, class P, class A> class unordered_multimap
template <class... Args> iterator emplace(BOOST_FWD_REF(Args)... args)
{
return table_.emplace(boost::forward<Args>(args)...);
return iterator(table_.emplace_impl(
boost::unordered::detail::func::construct_node_from_args(
table_.node_alloc(), boost::forward<Args>(args)...)));
}
#else
@ -994,24 +1028,33 @@ template <class K, class T, class H, class P, class A> class unordered_multimap
template <typename A0> iterator emplace(BOOST_FWD_REF(A0) a0)
{
return table_.emplace(boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0)));
return iterator(table_.emplace_impl(
boost::unordered::detail::func::construct_node_from_args(
table_.node_alloc(),
boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0)))));
}
template <typename A0, typename A1>
iterator emplace(BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1)
{
return table_.emplace(boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1)));
return iterator(table_.emplace_impl(
boost::unordered::detail::func::construct_node_from_args(
table_.node_alloc(),
boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1)))));
}
template <typename A0, typename A1, typename A2>
iterator emplace(
BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2)
{
return table_.emplace(boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1),
boost::forward<A2>(a2)));
return iterator(table_.emplace_impl(
boost::unordered::detail::func::construct_node_from_args(
table_.node_alloc(),
boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1),
boost::forward<A2>(a2)))));
}
#endif
@ -1021,7 +1064,9 @@ template <class K, class T, class H, class P, class A> class unordered_multimap
template <class... Args>
iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args)
{
return table_.emplace_hint(hint, boost::forward<Args>(args)...);
return iterator(table_.emplace_hint_impl(
hint, boost::unordered::detail::func::construct_node_from_args(
table_.node_alloc(), boost::forward<Args>(args)...)));
}
#else
@ -1041,27 +1086,34 @@ template <class K, class T, class H, class P, class A> class unordered_multimap
template <typename A0>
iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(A0) a0)
{
return table_.emplace_hint(
hint, boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0)));
return iterator(table_.emplace_hint_impl(
hint, boost::unordered::detail::func::construct_node_from_args(
table_.node_alloc(),
boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0)))));
}
template <typename A0, typename A1>
iterator emplace_hint(
const_iterator hint, BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1)
{
return table_.emplace_hint(
hint, boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1)));
return iterator(table_.emplace_hint_impl(
hint, boost::unordered::detail::func::construct_node_from_args(
table_.node_alloc(),
boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1)))));
}
template <typename A0, typename A1, typename A2>
iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(A0) a0,
BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2)
{
return table_.emplace_hint(
hint, boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1),
boost::forward<A2>(a2)));
return iterator(table_.emplace_hint_impl(
hint, boost::unordered::detail::func::construct_node_from_args(
table_.node_alloc(),
boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1),
boost::forward<A2>(a2)))));
}
#endif
@ -1072,21 +1124,33 @@ template <class K, class T, class H, class P, class A> class unordered_multimap
template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)> \
iterator emplace(BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a)) \
{ \
return table_.emplace(boost::unordered::detail::create_emplace_args( \
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))); \
return iterator(table_.emplace_impl( \
boost::unordered::detail::func::construct_node_from_args( \
table_.node_alloc(), \
boost::unordered::detail::create_emplace_args( \
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))))); \
} \
\
template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)> \
iterator emplace_hint(const_iterator hint, \
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a)) \
{ \
return table_.emplace_hint( \
hint, boost::unordered::detail::create_emplace_args( \
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))); \
return iterator(table_.emplace_hint_impl( \
hint, \
boost::unordered::detail::func::construct_node_from_args( \
table_.node_alloc(), \
boost::unordered::detail::create_emplace_args( \
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))))); \
}
BOOST_PP_REPEAT_FROM_TO(
4, BOOST_PP_INC(BOOST_UNORDERED_EMPLACE_LIMIT), BOOST_UNORDERED_EMPLACE, _)
BOOST_UNORDERED_EMPLACE(1, 4, _)
BOOST_UNORDERED_EMPLACE(1, 5, _)
BOOST_UNORDERED_EMPLACE(1, 6, _)
BOOST_UNORDERED_EMPLACE(1, 7, _)
BOOST_UNORDERED_EMPLACE(1, 8, _)
BOOST_UNORDERED_EMPLACE(1, 9, _)
BOOST_PP_REPEAT_FROM_TO(10, BOOST_PP_INC(BOOST_UNORDERED_EMPLACE_LIMIT),
BOOST_UNORDERED_EMPLACE, _)
#undef BOOST_UNORDERED_EMPLACE
@ -1307,7 +1371,7 @@ unordered_map<K, T, H, P, A>::unordered_map(InputIt f, InputIt l, size_type n,
const hasher& hf, const key_equal& eql, const allocator_type& a)
: table_(boost::unordered::detail::initial_size(f, l, n), hf, eql, a)
{
table_.insert_range(f, l);
this->insert(f, l);
}
template <class K, class T, class H, class P, class A>
@ -1347,7 +1411,7 @@ unordered_map<K, T, H, P, A>::unordered_map(
boost::unordered::detail::initial_size(list.begin(), list.end(), n),
hf, eql, a)
{
table_.insert_range(list.begin(), list.end());
this->insert(list.begin(), list.end());
}
#endif
@ -1373,7 +1437,7 @@ unordered_map<K, T, H, P, A>::unordered_map(
: table_(boost::unordered::detail::initial_size(f, l, n), hasher(),
key_equal(), a)
{
table_.insert_range(f, l);
this->insert(f, l);
}
template <class K, class T, class H, class P, class A>
@ -1383,7 +1447,7 @@ unordered_map<K, T, H, P, A>::unordered_map(InputIt f, InputIt l, size_type n,
: table_(
boost::unordered::detail::initial_size(f, l, n), hf, key_equal(), a)
{
table_.insert_range(f, l);
this->insert(f, l);
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
@ -1396,7 +1460,7 @@ unordered_map<K, T, H, P, A>::unordered_map(
boost::unordered::detail::initial_size(list.begin(), list.end(), n),
hasher(), key_equal(), a)
{
table_.insert_range(list.begin(), list.end());
this->insert(list.begin(), list.end());
}
template <class K, class T, class H, class P, class A>
@ -1407,7 +1471,7 @@ unordered_map<K, T, H, P, A>::unordered_map(
boost::unordered::detail::initial_size(list.begin(), list.end(), n),
hf, key_equal(), a)
{
table_.insert_range(list.begin(), list.end());
this->insert(list.begin(), list.end());
}
#endif
@ -1423,8 +1487,8 @@ template <class K, class T, class H, class P, class A>
unordered_map<K, T, H, P, A>& unordered_map<K, T, H, P, A>::operator=(
std::initializer_list<value_type> list)
{
table_.clear();
table_.insert_range(list.begin(), list.end());
this->clear();
this->insert(list.begin(), list.end());
return *this;
}
@ -1435,7 +1499,13 @@ unordered_map<K, T, H, P, A>& unordered_map<K, T, H, P, A>::operator=(
template <class K, class T, class H, class P, class A>
std::size_t unordered_map<K, T, H, P, A>::max_size() const BOOST_NOEXCEPT
{
return table_.max_size();
using namespace std;
// size <= mlf_ * count
return boost::unordered::detail::double_to_size(
ceil(static_cast<double>(table_.mlf_) *
static_cast<double>(table_.max_bucket_count()))) -
1;
}
// modifiers
@ -1444,7 +1514,10 @@ template <class K, class T, class H, class P, class A>
template <class InputIt>
void unordered_map<K, T, H, P, A>::insert(InputIt first, InputIt last)
{
table_.insert_range(first, last);
if (first != last) {
table_.insert_range_impl(
table::extractor::extract(*first), first, last);
}
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
@ -1452,7 +1525,7 @@ template <class K, class T, class H, class P, class A>
void unordered_map<K, T, H, P, A>::insert(
std::initializer_list<value_type> list)
{
table_.insert_range(list.begin(), list.end());
this->insert(list.begin(), list.end());
}
#endif
@ -1460,14 +1533,22 @@ template <class K, class T, class H, class P, class A>
typename unordered_map<K, T, H, P, A>::iterator
unordered_map<K, T, H, P, A>::erase(iterator position)
{
return table_.erase(position);
node_pointer node = table::get_node(position);
BOOST_ASSERT(node);
node_pointer next = table::node_algo::next_node(node);
table_.erase_nodes(node, next);
return iterator(next);
}
template <class K, class T, class H, class P, class A>
typename unordered_map<K, T, H, P, A>::iterator
unordered_map<K, T, H, P, A>::erase(const_iterator position)
{
return table_.erase(position);
node_pointer node = table::get_node(position);
BOOST_ASSERT(node);
node_pointer next = table::node_algo::next_node(node);
table_.erase_nodes(node, next);
return iterator(next);
}
template <class K, class T, class H, class P, class A>
@ -1481,7 +1562,11 @@ template <class K, class T, class H, class P, class A>
typename unordered_map<K, T, H, P, A>::iterator
unordered_map<K, T, H, P, A>::erase(const_iterator first, const_iterator last)
{
return table_.erase_range(first, last);
node_pointer last_node = table::get_node(last);
if (first == last)
return iterator(last_node);
table_.erase_nodes(table::get_node(first), last_node);
return iterator(last_node);
}
template <class K, class T, class H, class P, class A>
@ -1497,7 +1582,10 @@ void unordered_map<K, T, H, P, A>::swap(unordered_map& other)
template <class K, class T, class H, class P, class A>
void unordered_map<K, T, H, P, A>::clear() BOOST_NOEXCEPT
{
table_.clear();
if (table_.size_) {
table_.clear_buckets();
table_.delete_nodes(table_.get_previous_start(), link_pointer());
}
}
template <class K, class T, class H, class P, class A>
@ -1576,7 +1664,8 @@ typename unordered_map<K, T, H, P, A>::iterator
unordered_map<K, T, H, P, A>::find(CompatibleKey const& k,
CompatibleHash const& hash, CompatiblePredicate const& eq)
{
return iterator(table_.generic_find_node(k, hash, eq));
return iterator(
table_.find_node_impl(table::policy::apply_hash(hash, k), k, eq));
}
template <class K, class T, class H, class P, class A>
@ -1585,14 +1674,15 @@ typename unordered_map<K, T, H, P, A>::const_iterator
unordered_map<K, T, H, P, A>::find(CompatibleKey const& k,
CompatibleHash const& hash, CompatiblePredicate const& eq) const
{
return const_iterator(table_.generic_find_node(k, hash, eq));
return const_iterator(
table_.find_node_impl(table::policy::apply_hash(hash, k), k, eq));
}
template <class K, class T, class H, class P, class A>
typename unordered_map<K, T, H, P, A>::size_type
unordered_map<K, T, H, P, A>::count(const key_type& k) const
{
return table_.count(k);
return table_.find_node(k) ? 1 : 0;
}
template <class K, class T, class H, class P, class A>
@ -1600,7 +1690,9 @@ std::pair<typename unordered_map<K, T, H, P, A>::iterator,
typename unordered_map<K, T, H, P, A>::iterator>
unordered_map<K, T, H, P, A>::equal_range(const key_type& k)
{
return table_.equal_range(k);
node_pointer n = table_.find_node(k);
return std::make_pair(
iterator(n), iterator(n ? table::node_algo::next_node(n) : n));
}
template <class K, class T, class H, class P, class A>
@ -1608,7 +1700,9 @@ std::pair<typename unordered_map<K, T, H, P, A>::const_iterator,
typename unordered_map<K, T, H, P, A>::const_iterator>
unordered_map<K, T, H, P, A>::equal_range(const key_type& k) const
{
return table_.equal_range(k);
node_pointer n = table_.find_node(k);
return std::make_pair(const_iterator(n),
const_iterator(n ? table::node_algo::next_node(n) : n));
}
template <class K, class T, class H, class P, class A>
@ -1629,14 +1723,28 @@ template <class K, class T, class H, class P, class A>
typename unordered_map<K, T, H, P, A>::mapped_type&
unordered_map<K, T, H, P, A>::at(const key_type& k)
{
return table_.at(k).second;
if (table_.size_) {
node_pointer n = table_.find_node(k);
if (n)
return n->value().second;
}
boost::throw_exception(
std::out_of_range("Unable to find key in unordered_map."));
}
template <class K, class T, class H, class P, class A>
typename unordered_map<K, T, H, P, A>::mapped_type const&
unordered_map<K, T, H, P, A>::at(const key_type& k) const
{
return table_.at(k).second;
if (table_.size_) {
node_pointer n = table_.find_node(k);
if (n)
return n->value().second;
}
boost::throw_exception(
std::out_of_range("Unable to find key in unordered_map."));
}
template <class K, class T, class H, class P, class A>
@ -1651,7 +1759,9 @@ unordered_map<K, T, H, P, A>::bucket_size(size_type n) const
template <class K, class T, class H, class P, class A>
float unordered_map<K, T, H, P, A>::load_factor() const BOOST_NOEXCEPT
{
return table_.load_factor();
BOOST_ASSERT(table_.bucket_count_ != 0);
return static_cast<float>(table_.size_) /
static_cast<float>(table_.bucket_count_);
}
template <class K, class T, class H, class P, class A>
@ -1669,7 +1779,8 @@ void unordered_map<K, T, H, P, A>::rehash(size_type n)
template <class K, class T, class H, class P, class A>
void unordered_map<K, T, H, P, A>::reserve(size_type n)
{
table_.reserve(n);
table_.rehash(static_cast<std::size_t>(
std::ceil(static_cast<double>(n) / table_.mlf_)));
}
template <class K, class T, class H, class P, class A>
@ -1735,7 +1846,7 @@ unordered_multimap<K, T, H, P, A>::unordered_multimap(InputIt f, InputIt l,
const allocator_type& a)
: table_(boost::unordered::detail::initial_size(f, l, n), hf, eql, a)
{
table_.insert_range(f, l);
this->insert(f, l);
}
template <class K, class T, class H, class P, class A>
@ -1776,7 +1887,7 @@ unordered_multimap<K, T, H, P, A>::unordered_multimap(
boost::unordered::detail::initial_size(list.begin(), list.end(), n),
hf, eql, a)
{
table_.insert_range(list.begin(), list.end());
this->insert(list.begin(), list.end());
}
#endif
@ -1802,7 +1913,7 @@ unordered_multimap<K, T, H, P, A>::unordered_multimap(
: table_(boost::unordered::detail::initial_size(f, l, n), hasher(),
key_equal(), a)
{
table_.insert_range(f, l);
this->insert(f, l);
}
template <class K, class T, class H, class P, class A>
@ -1812,7 +1923,7 @@ unordered_multimap<K, T, H, P, A>::unordered_multimap(InputIt f, InputIt l,
: table_(
boost::unordered::detail::initial_size(f, l, n), hf, key_equal(), a)
{
table_.insert_range(f, l);
this->insert(f, l);
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
@ -1825,7 +1936,7 @@ unordered_multimap<K, T, H, P, A>::unordered_multimap(
boost::unordered::detail::initial_size(list.begin(), list.end(), n),
hasher(), key_equal(), a)
{
table_.insert_range(list.begin(), list.end());
this->insert(list.begin(), list.end());
}
template <class K, class T, class H, class P, class A>
@ -1836,7 +1947,7 @@ unordered_multimap<K, T, H, P, A>::unordered_multimap(
boost::unordered::detail::initial_size(list.begin(), list.end(), n),
hf, key_equal(), a)
{
table_.insert_range(list.begin(), list.end());
this->insert(list.begin(), list.end());
}
#endif
@ -1852,8 +1963,8 @@ template <class K, class T, class H, class P, class A>
unordered_multimap<K, T, H, P, A>& unordered_multimap<K, T, H, P, A>::operator=(
std::initializer_list<value_type> list)
{
table_.clear();
table_.insert_range(list.begin(), list.end());
this->clear();
this->insert(list.begin(), list.end());
return *this;
}
@ -1864,7 +1975,13 @@ unordered_multimap<K, T, H, P, A>& unordered_multimap<K, T, H, P, A>::operator=(
template <class K, class T, class H, class P, class A>
std::size_t unordered_multimap<K, T, H, P, A>::max_size() const BOOST_NOEXCEPT
{
return table_.max_size();
using namespace std;
// size <= mlf_ * count
return boost::unordered::detail::double_to_size(
ceil(static_cast<double>(table_.mlf_) *
static_cast<double>(table_.max_bucket_count()))) -
1;
}
// modifiers
@ -1881,7 +1998,7 @@ template <class K, class T, class H, class P, class A>
void unordered_multimap<K, T, H, P, A>::insert(
std::initializer_list<value_type> list)
{
table_.insert_range(list.begin(), list.end());
this->insert(list.begin(), list.end());
}
#endif
@ -1889,14 +2006,22 @@ template <class K, class T, class H, class P, class A>
typename unordered_multimap<K, T, H, P, A>::iterator
unordered_multimap<K, T, H, P, A>::erase(iterator position)
{
return table_.erase(position);
node_pointer node = table::get_node(position);
BOOST_ASSERT(node);
node_pointer next = table::node_algo::next_node(node);
table_.erase_nodes(node, next);
return iterator(next);
}
template <class K, class T, class H, class P, class A>
typename unordered_multimap<K, T, H, P, A>::iterator
unordered_multimap<K, T, H, P, A>::erase(const_iterator position)
{
return table_.erase(position);
node_pointer node = table::get_node(position);
BOOST_ASSERT(node);
node_pointer next = table::node_algo::next_node(node);
table_.erase_nodes(node, next);
return iterator(next);
}
template <class K, class T, class H, class P, class A>
@ -1911,7 +2036,11 @@ typename unordered_multimap<K, T, H, P, A>::iterator
unordered_multimap<K, T, H, P, A>::erase(
const_iterator first, const_iterator last)
{
return table_.erase_range(first, last);
node_pointer last_node = table::get_node(last);
if (first == last)
return iterator(last_node);
table_.erase_nodes(table::get_node(first), last_node);
return iterator(last_node);
}
template <class K, class T, class H, class P, class A>
@ -1927,7 +2056,10 @@ void unordered_multimap<K, T, H, P, A>::swap(unordered_multimap& other)
template <class K, class T, class H, class P, class A>
void unordered_multimap<K, T, H, P, A>::clear() BOOST_NOEXCEPT
{
table_.clear();
if (table_.size_) {
table_.clear_buckets();
table_.delete_nodes(table_.get_previous_start(), link_pointer());
}
}
// observers
@ -2014,7 +2146,8 @@ typename unordered_multimap<K, T, H, P, A>::iterator
unordered_multimap<K, T, H, P, A>::find(CompatibleKey const& k,
CompatibleHash const& hash, CompatiblePredicate const& eq)
{
return iterator(table_.generic_find_node(k, hash, eq));
return iterator(
table_.find_node_impl(table::policy::apply_hash(hash, k), k, eq));
}
template <class K, class T, class H, class P, class A>
@ -2023,14 +2156,16 @@ typename unordered_multimap<K, T, H, P, A>::const_iterator
unordered_multimap<K, T, H, P, A>::find(CompatibleKey const& k,
CompatibleHash const& hash, CompatiblePredicate const& eq) const
{
return const_iterator(table_.generic_find_node(k, hash, eq));
return const_iterator(
table_.find_node_impl(table::policy::apply_hash(hash, k), k, eq));
}
template <class K, class T, class H, class P, class A>
typename unordered_multimap<K, T, H, P, A>::size_type
unordered_multimap<K, T, H, P, A>::count(const key_type& k) const
{
return table_.count(k);
node_pointer n = table_.find_node(k);
return n ? table::node_algo::count(n, &table_) : 0;
}
template <class K, class T, class H, class P, class A>
@ -2038,7 +2173,9 @@ std::pair<typename unordered_multimap<K, T, H, P, A>::iterator,
typename unordered_multimap<K, T, H, P, A>::iterator>
unordered_multimap<K, T, H, P, A>::equal_range(const key_type& k)
{
return table_.equal_range(k);
node_pointer n = table_.find_node(k);
return std::make_pair(iterator(n),
iterator(n ? table::node_algo::next_group(n, &table_) : n));
}
template <class K, class T, class H, class P, class A>
@ -2046,7 +2183,9 @@ std::pair<typename unordered_multimap<K, T, H, P, A>::const_iterator,
typename unordered_multimap<K, T, H, P, A>::const_iterator>
unordered_multimap<K, T, H, P, A>::equal_range(const key_type& k) const
{
return table_.equal_range(k);
node_pointer n = table_.find_node(k);
return std::make_pair(const_iterator(n),
const_iterator(n ? table::node_algo::next_group(n, &table_) : n));
}
template <class K, class T, class H, class P, class A>
@ -2061,7 +2200,9 @@ unordered_multimap<K, T, H, P, A>::bucket_size(size_type n) const
template <class K, class T, class H, class P, class A>
float unordered_multimap<K, T, H, P, A>::load_factor() const BOOST_NOEXCEPT
{
return table_.load_factor();
BOOST_ASSERT(table_.bucket_count_ != 0);
return static_cast<float>(table_.size_) /
static_cast<float>(table_.bucket_count_);
}
template <class K, class T, class H, class P, class A>
@ -2079,7 +2220,8 @@ void unordered_multimap<K, T, H, P, A>::rehash(size_type n)
template <class K, class T, class H, class P, class A>
void unordered_multimap<K, T, H, P, A>::reserve(size_type n)
{
table_.reserve(n);
table_.rehash(static_cast<std::size_t>(
std::ceil(static_cast<double>(n) / table_.mlf_)));
}
template <class K, class T, class H, class P, class A>

View File

@ -53,6 +53,8 @@ template <class T, class H, class P, class A> class unordered_set
typedef boost::unordered::detail::set<A, T, H, P> types;
typedef typename types::value_allocator_traits value_allocator_traits;
typedef typename types::table table;
typedef typename table::node_pointer node_pointer;
typedef typename table::link_pointer link_pointer;
public:
typedef typename value_allocator_traits::pointer pointer;
@ -218,7 +220,9 @@ template <class T, class H, class P, class A> class unordered_set
template <class... Args>
std::pair<iterator, bool> emplace(BOOST_FWD_REF(Args)... args)
{
return table_.emplace(boost::forward<Args>(args)...);
return table_.emplace_impl(
table::extractor::extract(boost::forward<Args>(args)...),
boost::forward<Args>(args)...);
}
#else
@ -242,25 +246,33 @@ template <class T, class H, class P, class A> class unordered_set
template <typename A0>
std::pair<iterator, bool> emplace(BOOST_FWD_REF(A0) a0)
{
return table_.emplace(boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0)));
return table_.emplace_impl(
table::extractor::extract(boost::forward<A0>(a0)),
boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0)));
}
template <typename A0, typename A1>
std::pair<iterator, bool> emplace(
BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1)
{
return table_.emplace(boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1)));
return table_.emplace_impl(
table::extractor::extract(
boost::forward<A0>(a0), boost::forward<A1>(a1)),
boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1)));
}
template <typename A0, typename A1, typename A2>
std::pair<iterator, bool> emplace(
BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2)
{
return table_.emplace(boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1),
boost::forward<A2>(a2)));
return table_.emplace_impl(
table::extractor::extract(
boost::forward<A0>(a0), boost::forward<A1>(a1)),
boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1),
boost::forward<A2>(a2)));
}
#endif
@ -270,7 +282,9 @@ template <class T, class H, class P, class A> class unordered_set
template <class... Args>
iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args)
{
return table_.emplace_hint(hint, boost::forward<Args>(args)...);
return table_.emplace_hint_impl(hint,
table::extractor::extract(boost::forward<Args>(args)...),
boost::forward<Args>(args)...);
}
#else
@ -290,28 +304,33 @@ template <class T, class H, class P, class A> class unordered_set
template <typename A0>
iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(A0) a0)
{
return table_.emplace_hint(
hint, boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0)));
return table_.emplace_hint_impl(hint,
table::extractor::extract(boost::forward<A0>(a0)),
boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0)));
}
template <typename A0, typename A1>
iterator emplace_hint(
const_iterator hint, BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1)
{
return table_.emplace_hint(
hint, boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1)));
return table_.emplace_hint_impl(
hint, table::extractor::extract(
boost::forward<A0>(a0), boost::forward<A1>(a1)),
boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1)));
}
template <typename A0, typename A1, typename A2>
iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(A0) a0,
BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2)
{
return table_.emplace_hint(
hint, boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1),
boost::forward<A2>(a2)));
return table_.emplace_hint_impl(
hint, table::extractor::extract(
boost::forward<A0>(a0), boost::forward<A1>(a1)),
boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1),
boost::forward<A2>(a2)));
}
#endif
@ -323,20 +342,31 @@ template <class T, class H, class P, class A> class unordered_set
std::pair<iterator, bool> emplace( \
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a)) \
{ \
return table_.emplace(boost::unordered::detail::create_emplace_args( \
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))); \
return table_.emplace_impl( \
table::extractor::extract( \
boost::forward<A0>(a0), boost::forward<A1>(a1)), \
boost::unordered::detail::create_emplace_args( \
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))); \
} \
\
template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)> \
iterator emplace_hint(const_iterator hint, \
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a)) \
{ \
return table_.emplace_hint( \
hint, boost::unordered::detail::create_emplace_args( \
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))); \
return table_.emplace_hint_impl( \
hint, table::extractor::extract( \
boost::forward<A0>(a0), boost::forward<A1>(a1)), \
boost::unordered::detail::create_emplace_args( \
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))); \
}
BOOST_PP_REPEAT_FROM_TO(4, BOOST_PP_INC(BOOST_UNORDERED_EMPLACE_LIMIT),
BOOST_UNORDERED_EMPLACE(1, 4, _)
BOOST_UNORDERED_EMPLACE(1, 5, _)
BOOST_UNORDERED_EMPLACE(1, 6, _)
BOOST_UNORDERED_EMPLACE(1, 7, _)
BOOST_UNORDERED_EMPLACE(1, 8, _)
BOOST_UNORDERED_EMPLACE(1, 9, _)
BOOST_PP_REPEAT_FROM_TO(10, BOOST_PP_INC(BOOST_UNORDERED_EMPLACE_LIMIT),
BOOST_UNORDERED_EMPLACE, _)
#undef BOOST_UNORDERED_EMPLACE
@ -534,6 +564,8 @@ template <class T, class H, class P, class A> class unordered_multiset
typedef boost::unordered::detail::multiset<A, T, H, P> types;
typedef typename types::value_allocator_traits value_allocator_traits;
typedef typename types::table table;
typedef typename table::node_pointer node_pointer;
typedef typename table::link_pointer link_pointer;
public:
typedef typename value_allocator_traits::pointer pointer;
@ -695,9 +727,12 @@ template <class T, class H, class P, class A> class unordered_multiset
// emplace
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <class... Args> iterator emplace(BOOST_FWD_REF(Args)... args)
{
return table_.emplace(boost::forward<Args>(args)...);
return iterator(table_.emplace_impl(
boost::unordered::detail::func::construct_node_from_args(
table_.node_alloc(), boost::forward<Args>(args)...)));
}
#else
@ -719,24 +754,33 @@ template <class T, class H, class P, class A> class unordered_multiset
template <typename A0> iterator emplace(BOOST_FWD_REF(A0) a0)
{
return table_.emplace(boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0)));
return iterator(table_.emplace_impl(
boost::unordered::detail::func::construct_node_from_args(
table_.node_alloc(),
boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0)))));
}
template <typename A0, typename A1>
iterator emplace(BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1)
{
return table_.emplace(boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1)));
return iterator(table_.emplace_impl(
boost::unordered::detail::func::construct_node_from_args(
table_.node_alloc(),
boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1)))));
}
template <typename A0, typename A1, typename A2>
iterator emplace(
BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2)
{
return table_.emplace(boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1),
boost::forward<A2>(a2)));
return iterator(table_.emplace_impl(
boost::unordered::detail::func::construct_node_from_args(
table_.node_alloc(),
boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1),
boost::forward<A2>(a2)))));
}
#endif
@ -746,7 +790,9 @@ template <class T, class H, class P, class A> class unordered_multiset
template <class... Args>
iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args)
{
return table_.emplace_hint(hint, boost::forward<Args>(args)...);
return iterator(table_.emplace_hint_impl(
hint, boost::unordered::detail::func::construct_node_from_args(
table_.node_alloc(), boost::forward<Args>(args)...)));
}
#else
@ -766,28 +812,34 @@ template <class T, class H, class P, class A> class unordered_multiset
template <typename A0>
iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(A0) a0)
{
return table_.emplace_hint(
hint, boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0)));
return iterator(table_.emplace_hint_impl(
hint, boost::unordered::detail::func::construct_node_from_args(
table_.node_alloc(),
boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0)))));
}
template <typename A0, typename A1>
iterator emplace_hint(
const_iterator hint, BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1)
{
return table_.emplace_hint(
hint, boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1)));
return iterator(table_.emplace_hint_impl(
hint, boost::unordered::detail::func::construct_node_from_args(
table_.node_alloc(),
boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1)))));
}
template <typename A0, typename A1, typename A2>
iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(A0) a0,
BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2)
{
return table_.emplace_hint(
hint, boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1),
boost::forward<A2>(a2)));
return iterator(table_.emplace_hint_impl(
hint, boost::unordered::detail::func::construct_node_from_args(
table_.node_alloc(),
boost::unordered::detail::create_emplace_args(
boost::forward<A0>(a0), boost::forward<A1>(a1),
boost::forward<A2>(a2)))));
}
#endif
@ -798,20 +850,32 @@ template <class T, class H, class P, class A> class unordered_multiset
template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)> \
iterator emplace(BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a)) \
{ \
return table_.emplace(boost::unordered::detail::create_emplace_args( \
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))); \
return iterator(table_.emplace_impl( \
boost::unordered::detail::func::construct_node_from_args( \
table_.node_alloc(), \
boost::unordered::detail::create_emplace_args( \
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))))); \
} \
\
template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)> \
iterator emplace_hint(const_iterator hint, \
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a)) \
{ \
return table_.emplace_hint( \
hint, boost::unordered::detail::create_emplace_args( \
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))); \
return iterator(table_.emplace_hint_impl( \
hint, \
boost::unordered::detail::func::construct_node_from_args( \
table_.node_alloc(), \
boost::unordered::detail::create_emplace_args( \
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, a))))); \
}
BOOST_PP_REPEAT_FROM_TO(4, BOOST_PP_INC(BOOST_UNORDERED_EMPLACE_LIMIT),
BOOST_UNORDERED_EMPLACE(1, 4, _)
BOOST_UNORDERED_EMPLACE(1, 5, _)
BOOST_UNORDERED_EMPLACE(1, 6, _)
BOOST_UNORDERED_EMPLACE(1, 7, _)
BOOST_UNORDERED_EMPLACE(1, 8, _)
BOOST_UNORDERED_EMPLACE(1, 9, _)
BOOST_PP_REPEAT_FROM_TO(10, BOOST_PP_INC(BOOST_UNORDERED_EMPLACE_LIMIT),
BOOST_UNORDERED_EMPLACE, _)
#undef BOOST_UNORDERED_EMPLACE
@ -1006,7 +1070,7 @@ unordered_set<T, H, P, A>::unordered_set(InputIt f, InputIt l, size_type n,
const hasher& hf, const key_equal& eql, const allocator_type& a)
: table_(boost::unordered::detail::initial_size(f, l, n), hf, eql, a)
{
table_.insert_range(f, l);
this->insert(f, l);
}
template <class T, class H, class P, class A>
@ -1046,7 +1110,7 @@ unordered_set<T, H, P, A>::unordered_set(std::initializer_list<value_type> list,
boost::unordered::detail::initial_size(list.begin(), list.end(), n),
hf, eql, a)
{
table_.insert_range(list.begin(), list.end());
this->insert(list.begin(), list.end());
}
#endif
@ -1071,7 +1135,7 @@ unordered_set<T, H, P, A>::unordered_set(
: table_(boost::unordered::detail::initial_size(f, l, n), hasher(),
key_equal(), a)
{
table_.insert_range(f, l);
this->insert(f, l);
}
template <class T, class H, class P, class A>
@ -1081,7 +1145,7 @@ unordered_set<T, H, P, A>::unordered_set(InputIt f, InputIt l, size_type n,
: table_(
boost::unordered::detail::initial_size(f, l, n), hf, key_equal(), a)
{
table_.insert_range(f, l);
this->insert(f, l);
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
@ -1093,7 +1157,7 @@ unordered_set<T, H, P, A>::unordered_set(std::initializer_list<value_type> list,
boost::unordered::detail::initial_size(list.begin(), list.end(), n),
hasher(), key_equal(), a)
{
table_.insert_range(list.begin(), list.end());
this->insert(list.begin(), list.end());
}
template <class T, class H, class P, class A>
@ -1103,7 +1167,7 @@ unordered_set<T, H, P, A>::unordered_set(std::initializer_list<value_type> list,
boost::unordered::detail::initial_size(list.begin(), list.end(), n),
hf, key_equal(), a)
{
table_.insert_range(list.begin(), list.end());
this->insert(list.begin(), list.end());
}
#endif
@ -1119,8 +1183,8 @@ template <class T, class H, class P, class A>
unordered_set<T, H, P, A>& unordered_set<T, H, P, A>::operator=(
std::initializer_list<value_type> list)
{
table_.clear();
table_.insert_range(list.begin(), list.end());
this->clear();
this->insert(list.begin(), list.end());
return *this;
}
@ -1131,7 +1195,13 @@ unordered_set<T, H, P, A>& unordered_set<T, H, P, A>::operator=(
template <class T, class H, class P, class A>
std::size_t unordered_set<T, H, P, A>::max_size() const BOOST_NOEXCEPT
{
return table_.max_size();
using namespace std;
// size < mlf_ * count
return boost::unordered::detail::double_to_size(
ceil(static_cast<double>(table_.mlf_) *
static_cast<double>(table_.max_bucket_count()))) -
1;
}
// modifiers
@ -1140,14 +1210,17 @@ template <class T, class H, class P, class A>
template <class InputIt>
void unordered_set<T, H, P, A>::insert(InputIt first, InputIt last)
{
table_.insert_range(first, last);
if (first != last) {
table_.insert_range_impl(
table::extractor::extract(*first), first, last);
}
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
template <class T, class H, class P, class A>
void unordered_set<T, H, P, A>::insert(std::initializer_list<value_type> list)
{
table_.insert_range(list.begin(), list.end());
this->insert(list.begin(), list.end());
}
#endif
@ -1155,7 +1228,11 @@ template <class T, class H, class P, class A>
typename unordered_set<T, H, P, A>::iterator unordered_set<T, H, P, A>::erase(
const_iterator position)
{
return table_.erase(position);
node_pointer node = table::get_node(position);
BOOST_ASSERT(node);
node_pointer next = table::node_algo::next_node(node);
table_.erase_nodes(node, next);
return iterator(next);
}
template <class T, class H, class P, class A>
@ -1169,7 +1246,11 @@ template <class T, class H, class P, class A>
typename unordered_set<T, H, P, A>::iterator unordered_set<T, H, P, A>::erase(
const_iterator first, const_iterator last)
{
return table_.erase_range(first, last);
node_pointer last_node = table::get_node(last);
if (first == last)
return iterator(last_node);
table_.erase_nodes(table::get_node(first), last_node);
return iterator(last_node);
}
template <class T, class H, class P, class A>
@ -1185,13 +1266,10 @@ void unordered_set<T, H, P, A>::swap(unordered_set& other)
template <class T, class H, class P, class A>
void unordered_set<T, H, P, A>::clear() BOOST_NOEXCEPT
{
table_.clear();
}
template <class T, class H, class P, class A>
void unordered_multiset<T, H, P, A>::clear() BOOST_NOEXCEPT
{
table_.clear();
if (table_.size_) {
table_.clear_buckets();
table_.delete_nodes(table_.get_previous_start(), link_pointer());
}
}
// observers
@ -1263,14 +1341,15 @@ typename unordered_set<T, H, P, A>::const_iterator
unordered_set<T, H, P, A>::find(CompatibleKey const& k,
CompatibleHash const& hash, CompatiblePredicate const& eq) const
{
return const_iterator(table_.generic_find_node(k, hash, eq));
return const_iterator(
table_.find_node_impl(table::policy::apply_hash(hash, k), k, eq));
}
template <class T, class H, class P, class A>
typename unordered_set<T, H, P, A>::size_type unordered_set<T, H, P, A>::count(
const key_type& k) const
{
return table_.count(k);
return table_.find_node(k) ? 1 : 0;
}
template <class T, class H, class P, class A>
@ -1278,7 +1357,9 @@ std::pair<typename unordered_set<T, H, P, A>::const_iterator,
typename unordered_set<T, H, P, A>::const_iterator>
unordered_set<T, H, P, A>::equal_range(const key_type& k) const
{
return table_.equal_range(k);
node_pointer n = table_.find_node(k);
return std::make_pair(const_iterator(n),
const_iterator(n ? table::node_algo::next_node(n) : n));
}
template <class T, class H, class P, class A>
@ -1293,7 +1374,9 @@ unordered_set<T, H, P, A>::bucket_size(size_type n) const
template <class T, class H, class P, class A>
float unordered_set<T, H, P, A>::load_factor() const BOOST_NOEXCEPT
{
return table_.load_factor();
BOOST_ASSERT(table_.bucket_count_ != 0);
return static_cast<float>(table_.size_) /
static_cast<float>(table_.bucket_count_);
}
template <class T, class H, class P, class A>
@ -1311,7 +1394,8 @@ void unordered_set<T, H, P, A>::rehash(size_type n)
template <class T, class H, class P, class A>
void unordered_set<T, H, P, A>::reserve(size_type n)
{
table_.reserve(n);
table_.rehash(static_cast<std::size_t>(
std::ceil(static_cast<double>(n) / table_.mlf_)));
}
template <class T, class H, class P, class A>
@ -1376,7 +1460,7 @@ unordered_multiset<T, H, P, A>::unordered_multiset(InputIt f, InputIt l,
const allocator_type& a)
: table_(boost::unordered::detail::initial_size(f, l, n), hf, eql, a)
{
table_.insert_range(f, l);
this->insert(f, l);
}
template <class T, class H, class P, class A>
@ -1417,7 +1501,7 @@ unordered_multiset<T, H, P, A>::unordered_multiset(
boost::unordered::detail::initial_size(list.begin(), list.end(), n),
hf, eql, a)
{
table_.insert_range(list.begin(), list.end());
this->insert(list.begin(), list.end());
}
#endif
@ -1443,7 +1527,7 @@ unordered_multiset<T, H, P, A>::unordered_multiset(
: table_(boost::unordered::detail::initial_size(f, l, n), hasher(),
key_equal(), a)
{
table_.insert_range(f, l);
this->insert(f, l);
}
template <class T, class H, class P, class A>
@ -1453,7 +1537,7 @@ unordered_multiset<T, H, P, A>::unordered_multiset(InputIt f, InputIt l,
: table_(
boost::unordered::detail::initial_size(f, l, n), hf, key_equal(), a)
{
table_.insert_range(f, l);
this->insert(f, l);
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
@ -1466,7 +1550,7 @@ unordered_multiset<T, H, P, A>::unordered_multiset(
boost::unordered::detail::initial_size(list.begin(), list.end(), n),
hasher(), key_equal(), a)
{
table_.insert_range(list.begin(), list.end());
this->insert(list.begin(), list.end());
}
template <class T, class H, class P, class A>
@ -1477,7 +1561,7 @@ unordered_multiset<T, H, P, A>::unordered_multiset(
boost::unordered::detail::initial_size(list.begin(), list.end(), n),
hf, key_equal(), a)
{
table_.insert_range(list.begin(), list.end());
this->insert(list.begin(), list.end());
}
#endif
@ -1493,8 +1577,8 @@ template <class T, class H, class P, class A>
unordered_multiset<T, H, P, A>& unordered_multiset<T, H, P, A>::operator=(
std::initializer_list<value_type> list)
{
table_.clear();
table_.insert_range(list.begin(), list.end());
this->clear();
this->insert(list.begin(), list.end());
return *this;
}
@ -1505,7 +1589,13 @@ unordered_multiset<T, H, P, A>& unordered_multiset<T, H, P, A>::operator=(
template <class T, class H, class P, class A>
std::size_t unordered_multiset<T, H, P, A>::max_size() const BOOST_NOEXCEPT
{
return table_.max_size();
using namespace std;
// size < mlf_ * count
return boost::unordered::detail::double_to_size(
ceil(static_cast<double>(table_.mlf_) *
static_cast<double>(table_.max_bucket_count()))) -
1;
}
// modifiers
@ -1522,7 +1612,7 @@ template <class T, class H, class P, class A>
void unordered_multiset<T, H, P, A>::insert(
std::initializer_list<value_type> list)
{
table_.insert_range(list.begin(), list.end());
this->insert(list.begin(), list.end());
}
#endif
@ -1530,7 +1620,11 @@ template <class T, class H, class P, class A>
typename unordered_multiset<T, H, P, A>::iterator
unordered_multiset<T, H, P, A>::erase(const_iterator position)
{
return table_.erase(position);
node_pointer node = table::get_node(position);
BOOST_ASSERT(node);
node_pointer next = table::node_algo::next_node(node);
table_.erase_nodes(node, next);
return iterator(next);
}
template <class T, class H, class P, class A>
@ -1544,7 +1638,11 @@ template <class T, class H, class P, class A>
typename unordered_multiset<T, H, P, A>::iterator
unordered_multiset<T, H, P, A>::erase(const_iterator first, const_iterator last)
{
return table_.erase_range(first, last);
node_pointer last_node = table::get_node(last);
if (first == last)
return iterator(last_node);
table_.erase_nodes(table::get_node(first), last_node);
return iterator(last_node);
}
template <class T, class H, class P, class A>
@ -1557,6 +1655,15 @@ void unordered_multiset<T, H, P, A>::swap(unordered_multiset& other)
table_.swap(other.table_);
}
template <class T, class H, class P, class A>
void unordered_multiset<T, H, P, A>::clear() BOOST_NOEXCEPT
{
if (table_.size_) {
table_.clear_buckets();
table_.delete_nodes(table_.get_previous_start(), link_pointer());
}
}
// observers
template <class T, class H, class P, class A>
@ -1634,14 +1741,16 @@ typename unordered_multiset<T, H, P, A>::const_iterator
unordered_multiset<T, H, P, A>::find(CompatibleKey const& k,
CompatibleHash const& hash, CompatiblePredicate const& eq) const
{
return const_iterator(table_.generic_find_node(k, hash, eq));
return const_iterator(
table_.find_node_impl(table::policy::apply_hash(hash, k), k, eq));
}
template <class T, class H, class P, class A>
typename unordered_multiset<T, H, P, A>::size_type
unordered_multiset<T, H, P, A>::count(const key_type& k) const
{
return table_.count(k);
node_pointer n = table_.find_node(k);
return n ? table::node_algo::count(n, &table_) : 0;
}
template <class T, class H, class P, class A>
@ -1649,7 +1758,9 @@ std::pair<typename unordered_multiset<T, H, P, A>::const_iterator,
typename unordered_multiset<T, H, P, A>::const_iterator>
unordered_multiset<T, H, P, A>::equal_range(const key_type& k) const
{
return table_.equal_range(k);
node_pointer n = table_.find_node(k);
return std::make_pair(const_iterator(n),
const_iterator(n ? table::node_algo::next_group(n, &table_) : n));
}
template <class T, class H, class P, class A>
@ -1664,7 +1775,9 @@ unordered_multiset<T, H, P, A>::bucket_size(size_type n) const
template <class T, class H, class P, class A>
float unordered_multiset<T, H, P, A>::load_factor() const BOOST_NOEXCEPT
{
return table_.load_factor();
BOOST_ASSERT(table_.bucket_count_ != 0);
return static_cast<float>(table_.size_) /
static_cast<float>(table_.bucket_count_);
}
template <class T, class H, class P, class A>
@ -1682,7 +1795,8 @@ void unordered_multiset<T, H, P, A>::rehash(size_type n)
template <class T, class H, class P, class A>
void unordered_multiset<T, H, P, A>::reserve(size_type n)
{
table_.reserve(n);
table_.rehash(static_cast<std::size_t>(
std::ceil(static_cast<double>(n) / table_.mlf_)));
}
template <class T, class H, class P, class A>