forked from boostorg/unordered
Insert/emplace with hint.
This commit is contained in:
@@ -321,7 +321,10 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
// Emplace/Insert
|
||||
|
||||
static inline void add_after_node(
|
||||
// Add node 'n' to the group containing 'pos'.
|
||||
// If 'pos' is the first node in group, add to the end of the group,
|
||||
// otherwise add before 'pos'.
|
||||
static inline void add_to_node_group(
|
||||
node_pointer n,
|
||||
node_pointer pos)
|
||||
{
|
||||
@@ -338,7 +341,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
{
|
||||
n->hash_ = key_hash;
|
||||
if (pos.node_) {
|
||||
this->add_after_node(n, pos.node_);
|
||||
this->add_to_node_group(n, pos.node_);
|
||||
if (n->next_) {
|
||||
std::size_t next_bucket = this->hash_to_bucket(
|
||||
static_cast<node_pointer>(n->next_)->hash_);
|
||||
@@ -375,6 +378,24 @@ namespace boost { namespace unordered { namespace detail {
|
||||
return iterator(n);
|
||||
}
|
||||
|
||||
inline iterator add_using_hint(
|
||||
node_pointer n,
|
||||
node_pointer hint)
|
||||
{
|
||||
n->hash_ = hint->hash_;
|
||||
this->add_to_node_group(n, hint);
|
||||
if (n->next_ != hint && n->next_) {
|
||||
std::size_t next_bucket = this->hash_to_bucket(
|
||||
static_cast<node_pointer>(n->next_)->hash_);
|
||||
if (next_bucket != this->hash_to_bucket(n->hash_)) {
|
||||
this->get_bucket(next_bucket)->next_ = n;
|
||||
}
|
||||
}
|
||||
++this->size_;
|
||||
return iterator(n);
|
||||
}
|
||||
|
||||
|
||||
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
# if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
iterator emplace(boost::unordered::detail::emplace_args1<
|
||||
@@ -383,6 +404,13 @@ namespace boost { namespace unordered { namespace detail {
|
||||
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&)
|
||||
@@ -390,6 +418,13 @@ namespace boost { namespace unordered { namespace detail {
|
||||
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
|
||||
|
||||
@@ -401,6 +436,14 @@ namespace boost { namespace unordered { namespace detail {
|
||||
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_value_generic(
|
||||
this->node_alloc(), BOOST_UNORDERED_EMPLACE_FORWARD)));
|
||||
}
|
||||
|
||||
iterator emplace_impl(node_pointer n)
|
||||
{
|
||||
node_tmp a(n, this->node_alloc());
|
||||
@@ -411,6 +454,22 @@ namespace boost { namespace unordered { namespace detail {
|
||||
return this->add_node(a.release(), key_hash, position);
|
||||
}
|
||||
|
||||
iterator emplace_hint_impl(c_iterator hint, node_pointer n)
|
||||
{
|
||||
node_tmp a(n, this->node_alloc());
|
||||
key_type const& k = this->get_key(a.node_->value());
|
||||
if (hint.node_ && this->key_eq()(k, this->get_key(*hint))) {
|
||||
this->reserve_for_insert(this->size_ + 1);
|
||||
return this->add_using_hint(a.release(), hint.node_);
|
||||
}
|
||||
else {
|
||||
std::size_t key_hash = this->hash(k);
|
||||
iterator position = this->find_node(key_hash, k);
|
||||
this->reserve_for_insert(this->size_ + 1);
|
||||
return this->add_node(a.release(), key_hash, position);
|
||||
}
|
||||
}
|
||||
|
||||
void emplace_impl_no_rehash(node_pointer n)
|
||||
{
|
||||
node_tmp a(n, this->node_alloc());
|
||||
|
||||
@@ -316,6 +316,14 @@ namespace boost { namespace unordered { namespace detail {
|
||||
BOOST_ASSERT(false);
|
||||
return emplace_return(this->begin(), false);
|
||||
}
|
||||
|
||||
iterator emplace_hint(c_iterator,
|
||||
boost::unordered::detail::emplace_args1<
|
||||
boost::unordered::detail::please_ignore_this_overload> const&)
|
||||
{
|
||||
BOOST_ASSERT(false);
|
||||
return this->begin();
|
||||
}
|
||||
# else
|
||||
emplace_return emplace(
|
||||
boost::unordered::detail::please_ignore_this_overload const&)
|
||||
@@ -323,6 +331,13 @@ namespace boost { namespace unordered { namespace detail {
|
||||
BOOST_ASSERT(false);
|
||||
return emplace_return(this->begin(), false);
|
||||
}
|
||||
|
||||
iterator emplace_hint(c_iterator,
|
||||
boost::unordered::detail::please_ignore_this_overload const&)
|
||||
{
|
||||
BOOST_ASSERT(false);
|
||||
return this->begin();
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@@ -340,6 +355,21 @@ namespace boost { namespace unordered { namespace detail {
|
||||
#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(
|
||||
@@ -347,8 +377,27 @@ namespace boost { namespace unordered { namespace detail {
|
||||
{
|
||||
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, key_type const& k,
|
||||
BOOST_UNORDERED_EMPLACE_ARGS)
|
||||
{
|
||||
if (hint.node_ && this->key_eq()(k, this->get_key(*hint))) {
|
||||
return iterator(hint.node_);
|
||||
}
|
||||
else {
|
||||
return emplace_impl(k, BOOST_UNORDERED_EMPLACE_FORWARD).first;
|
||||
}
|
||||
}
|
||||
|
||||
template <BOOST_UNORDERED_EMPLACE_TEMPLATE>
|
||||
emplace_return emplace_impl(key_type const& k,
|
||||
BOOST_UNORDERED_EMPLACE_ARGS)
|
||||
@@ -368,11 +417,31 @@ namespace boost { namespace unordered { namespace detail {
|
||||
}
|
||||
}
|
||||
|
||||
template <BOOST_UNORDERED_EMPLACE_TEMPLATE>
|
||||
iterator emplace_hint_impl(c_iterator hint, no_key,
|
||||
BOOST_UNORDERED_EMPLACE_ARGS)
|
||||
{
|
||||
node_tmp b(
|
||||
boost::unordered::detail::func::construct_value_generic(
|
||||
this->node_alloc(), BOOST_UNORDERED_EMPLACE_FORWARD),
|
||||
this->node_alloc());
|
||||
key_type const& k = this->get_key(b.node_->value());
|
||||
if (hint.node_ && this->key_eq()(k, this->get_key(*hint))) {
|
||||
return iterator(hint.node_);
|
||||
}
|
||||
std::size_t key_hash = this->hash(k);
|
||||
iterator pos = this->find_node(key_hash, k);
|
||||
if (pos.node_) {
|
||||
return pos;
|
||||
}
|
||||
else {
|
||||
return this->resize_and_add_node(b.release(), key_hash);
|
||||
}
|
||||
}
|
||||
|
||||
template <BOOST_UNORDERED_EMPLACE_TEMPLATE>
|
||||
emplace_return emplace_impl(no_key, BOOST_UNORDERED_EMPLACE_ARGS)
|
||||
{
|
||||
// Don't have a key, so construct the node first in order
|
||||
// to be able to lookup the position.
|
||||
node_tmp b(
|
||||
boost::unordered::detail::func::construct_value_generic(
|
||||
this->node_alloc(), BOOST_UNORDERED_EMPLACE_FORWARD),
|
||||
|
||||
@@ -240,9 +240,9 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
iterator emplace_hint(const_iterator, BOOST_FWD_REF(Args)... args)
|
||||
iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
return table_.emplace(boost::forward<Args>(args)...).first;
|
||||
return table_.emplace_hint(hint, boost::forward<Args>(args)...);
|
||||
}
|
||||
#else
|
||||
|
||||
@@ -281,12 +281,12 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <typename A0>
|
||||
iterator emplace_hint(const_iterator, BOOST_FWD_REF(A0) a0)
|
||||
iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(A0) a0)
|
||||
{
|
||||
return table_.emplace(
|
||||
return table_.emplace_hint(hint,
|
||||
boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0))
|
||||
).first;
|
||||
);
|
||||
}
|
||||
|
||||
template <typename A0, typename A1>
|
||||
@@ -302,15 +302,15 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <typename A0, typename A1>
|
||||
iterator emplace_hint(const_iterator,
|
||||
iterator emplace_hint(const_iterator hint,
|
||||
BOOST_FWD_REF(A0) a0,
|
||||
BOOST_FWD_REF(A1) a1)
|
||||
{
|
||||
return table_.emplace(
|
||||
return table_.emplace_hint(hint,
|
||||
boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0),
|
||||
boost::forward<A1>(a1))
|
||||
).first;
|
||||
);
|
||||
}
|
||||
|
||||
template <typename A0, typename A1, typename A2>
|
||||
@@ -328,17 +328,17 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <typename A0, typename A1, typename A2>
|
||||
iterator emplace_hint(const_iterator,
|
||||
iterator emplace_hint(const_iterator hint,
|
||||
BOOST_FWD_REF(A0) a0,
|
||||
BOOST_FWD_REF(A1) a1,
|
||||
BOOST_FWD_REF(A2) a2)
|
||||
{
|
||||
return table_.emplace(
|
||||
return table_.emplace_hint(hint,
|
||||
boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0),
|
||||
boost::forward<A1>(a1),
|
||||
boost::forward<A2>(a2))
|
||||
).first;
|
||||
);
|
||||
}
|
||||
|
||||
#define BOOST_UNORDERED_EMPLACE(z, n, _) \
|
||||
@@ -360,15 +360,15 @@ namespace unordered
|
||||
BOOST_PP_ENUM_PARAMS_Z(z, n, typename A) \
|
||||
> \
|
||||
iterator emplace_hint( \
|
||||
const_iterator, \
|
||||
const_iterator hint, \
|
||||
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a) \
|
||||
) \
|
||||
{ \
|
||||
return table_.emplace( \
|
||||
return table_.emplace_hint(hint, \
|
||||
boost::unordered::detail::create_emplace_args( \
|
||||
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, \
|
||||
a) \
|
||||
)).first; \
|
||||
)); \
|
||||
}
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(4, BOOST_UNORDERED_EMPLACE_LIMIT,
|
||||
@@ -724,9 +724,9 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
iterator emplace_hint(const_iterator, BOOST_FWD_REF(Args)... args)
|
||||
iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
return table_.emplace(boost::forward<Args>(args)...);
|
||||
return table_.emplace_hint(hint, boost::forward<Args>(args)...);
|
||||
}
|
||||
#else
|
||||
|
||||
@@ -765,9 +765,9 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <typename A0>
|
||||
iterator emplace_hint(const_iterator, BOOST_FWD_REF(A0) a0)
|
||||
iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(A0) a0)
|
||||
{
|
||||
return table_.emplace(
|
||||
return table_.emplace_hint(hint,
|
||||
boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0))
|
||||
);
|
||||
@@ -786,11 +786,11 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <typename A0, typename A1>
|
||||
iterator emplace_hint(const_iterator,
|
||||
iterator emplace_hint(const_iterator hint,
|
||||
BOOST_FWD_REF(A0) a0,
|
||||
BOOST_FWD_REF(A1) a1)
|
||||
{
|
||||
return table_.emplace(
|
||||
return table_.emplace_hint(hint,
|
||||
boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0),
|
||||
boost::forward<A1>(a1))
|
||||
@@ -812,12 +812,12 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <typename A0, typename A1, typename A2>
|
||||
iterator emplace_hint(const_iterator,
|
||||
iterator emplace_hint(const_iterator hint,
|
||||
BOOST_FWD_REF(A0) a0,
|
||||
BOOST_FWD_REF(A1) a1,
|
||||
BOOST_FWD_REF(A2) a2)
|
||||
{
|
||||
return table_.emplace(
|
||||
return table_.emplace_hint(hint,
|
||||
boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0),
|
||||
boost::forward<A1>(a1),
|
||||
@@ -844,11 +844,11 @@ namespace unordered
|
||||
BOOST_PP_ENUM_PARAMS_Z(z, n, typename A) \
|
||||
> \
|
||||
iterator emplace_hint( \
|
||||
const_iterator, \
|
||||
const_iterator hint, \
|
||||
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a) \
|
||||
) \
|
||||
{ \
|
||||
return table_.emplace( \
|
||||
return table_.emplace_hint(hint, \
|
||||
boost::unordered::detail::create_emplace_args( \
|
||||
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, \
|
||||
a) \
|
||||
|
||||
@@ -237,9 +237,9 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
iterator emplace_hint(const_iterator, BOOST_FWD_REF(Args)... args)
|
||||
iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
return table_.emplace(boost::forward<Args>(args)...).first;
|
||||
return table_.emplace_hint(hint, boost::forward<Args>(args)...);
|
||||
}
|
||||
#else
|
||||
|
||||
@@ -278,12 +278,12 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <typename A0>
|
||||
iterator emplace_hint(const_iterator, BOOST_FWD_REF(A0) a0)
|
||||
iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(A0) a0)
|
||||
{
|
||||
return table_.emplace(
|
||||
return table_.emplace_hint(hint,
|
||||
boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0))
|
||||
).first;
|
||||
);
|
||||
}
|
||||
|
||||
template <typename A0, typename A1>
|
||||
@@ -299,15 +299,15 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <typename A0, typename A1>
|
||||
iterator emplace_hint(const_iterator,
|
||||
iterator emplace_hint(const_iterator hint,
|
||||
BOOST_FWD_REF(A0) a0,
|
||||
BOOST_FWD_REF(A1) a1)
|
||||
{
|
||||
return table_.emplace(
|
||||
return table_.emplace_hint(hint,
|
||||
boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0),
|
||||
boost::forward<A1>(a1))
|
||||
).first;
|
||||
);
|
||||
}
|
||||
|
||||
template <typename A0, typename A1, typename A2>
|
||||
@@ -325,17 +325,17 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <typename A0, typename A1, typename A2>
|
||||
iterator emplace_hint(const_iterator,
|
||||
iterator emplace_hint(const_iterator hint,
|
||||
BOOST_FWD_REF(A0) a0,
|
||||
BOOST_FWD_REF(A1) a1,
|
||||
BOOST_FWD_REF(A2) a2)
|
||||
{
|
||||
return table_.emplace(
|
||||
return table_.emplace_hint(hint,
|
||||
boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0),
|
||||
boost::forward<A1>(a1),
|
||||
boost::forward<A2>(a2))
|
||||
).first;
|
||||
);
|
||||
}
|
||||
|
||||
#define BOOST_UNORDERED_EMPLACE(z, n, _) \
|
||||
@@ -357,15 +357,15 @@ namespace unordered
|
||||
BOOST_PP_ENUM_PARAMS_Z(z, n, typename A) \
|
||||
> \
|
||||
iterator emplace_hint( \
|
||||
const_iterator, \
|
||||
const_iterator hint, \
|
||||
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a) \
|
||||
) \
|
||||
{ \
|
||||
return table_.emplace( \
|
||||
return table_.emplace_hint(hint, \
|
||||
boost::unordered::detail::create_emplace_args( \
|
||||
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, \
|
||||
a) \
|
||||
)).first; \
|
||||
)); \
|
||||
}
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(4, BOOST_UNORDERED_EMPLACE_LIMIT,
|
||||
@@ -707,9 +707,9 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
iterator emplace_hint(const_iterator, BOOST_FWD_REF(Args)... args)
|
||||
iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
return table_.emplace(boost::forward<Args>(args)...);
|
||||
return table_.emplace_hint(hint, boost::forward<Args>(args)...);
|
||||
}
|
||||
#else
|
||||
|
||||
@@ -748,9 +748,9 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <typename A0>
|
||||
iterator emplace_hint(const_iterator, BOOST_FWD_REF(A0) a0)
|
||||
iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(A0) a0)
|
||||
{
|
||||
return table_.emplace(
|
||||
return table_.emplace_hint(hint,
|
||||
boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0))
|
||||
);
|
||||
@@ -769,11 +769,11 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <typename A0, typename A1>
|
||||
iterator emplace_hint(const_iterator,
|
||||
iterator emplace_hint(const_iterator hint,
|
||||
BOOST_FWD_REF(A0) a0,
|
||||
BOOST_FWD_REF(A1) a1)
|
||||
{
|
||||
return table_.emplace(
|
||||
return table_.emplace_hint(hint,
|
||||
boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0),
|
||||
boost::forward<A1>(a1))
|
||||
@@ -795,12 +795,12 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <typename A0, typename A1, typename A2>
|
||||
iterator emplace_hint(const_iterator,
|
||||
iterator emplace_hint(const_iterator hint,
|
||||
BOOST_FWD_REF(A0) a0,
|
||||
BOOST_FWD_REF(A1) a1,
|
||||
BOOST_FWD_REF(A2) a2)
|
||||
{
|
||||
return table_.emplace(
|
||||
return table_.emplace_hint(hint,
|
||||
boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0),
|
||||
boost::forward<A1>(a1),
|
||||
@@ -827,11 +827,11 @@ namespace unordered
|
||||
BOOST_PP_ENUM_PARAMS_Z(z, n, typename A) \
|
||||
> \
|
||||
iterator emplace_hint( \
|
||||
const_iterator, \
|
||||
const_iterator hint, \
|
||||
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a) \
|
||||
) \
|
||||
{ \
|
||||
return table_.emplace( \
|
||||
return table_.emplace_hint(hint, \
|
||||
boost::unordered::detail::create_emplace_args( \
|
||||
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, \
|
||||
a) \
|
||||
|
||||
Reference in New Issue
Block a user