forked from boostorg/unordered
Implement try_emplace
This commit is contained in:
@ -1721,6 +1721,35 @@ construct_node_pair(Alloc& alloc, BOOST_FWD_REF(Key) k, BOOST_FWD_REF(Mapped) m)
|
||||
BOOST_CATCH_END
|
||||
return a.release();
|
||||
}
|
||||
|
||||
template <typename Alloc, typename Key, BOOST_UNORDERED_EMPLACE_TEMPLATE>
|
||||
inline typename boost::unordered::detail::allocator_traits<Alloc>::pointer
|
||||
construct_node_pair_from_args(
|
||||
Alloc& alloc, BOOST_FWD_REF(Key) k, BOOST_UNORDERED_EMPLACE_ARGS)
|
||||
{
|
||||
node_constructor<Alloc> a(alloc);
|
||||
a.create_node();
|
||||
boost::unordered::detail::func::call_construct(
|
||||
alloc, boost::unordered::detail::func::const_cast_pointer(
|
||||
boost::addressof(a.node_->value_ptr()->first)),
|
||||
boost::forward<Key>(k));
|
||||
BOOST_TRY
|
||||
{
|
||||
boost::unordered::detail::func::construct_from_args(
|
||||
alloc, boost::unordered::detail::func::const_cast_pointer(
|
||||
boost::addressof(a.node_->value_ptr()->second)),
|
||||
BOOST_UNORDERED_EMPLACE_FORWARD);
|
||||
}
|
||||
BOOST_CATCH(...)
|
||||
{
|
||||
boost::unordered::detail::func::call_destroy(
|
||||
alloc, boost::unordered::detail::func::const_cast_pointer(
|
||||
boost::addressof(a.node_->value_ptr()->first)));
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
return a.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3547,22 +3576,6 @@ struct table_impl : boost::unordered::detail::table<Types>
|
||||
return this->add_node(b.release(), key_hash);
|
||||
}
|
||||
|
||||
value_type& operator[](const_key_type& k)
|
||||
{
|
||||
std::size_t key_hash = this->hash(k);
|
||||
node_pointer pos = this->find_node(key_hash, k);
|
||||
if (pos) {
|
||||
return pos->value();
|
||||
} else {
|
||||
return this
|
||||
->resize_and_add_node(
|
||||
boost::unordered::detail::func::construct_node_pair(
|
||||
this->node_alloc(), k),
|
||||
key_hash)
|
||||
->value();
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
emplace_return emplace(boost::unordered::detail::emplace_args1<
|
||||
@ -3704,6 +3717,64 @@ struct table_impl : boost::unordered::detail::table<Types>
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Key>
|
||||
emplace_return try_emplace_impl(BOOST_FWD_REF(Key) k)
|
||||
{
|
||||
std::size_t key_hash = this->hash(k);
|
||||
node_pointer pos = this->find_node(key_hash, k);
|
||||
if (pos) {
|
||||
return emplace_return(iterator(pos), false);
|
||||
} else {
|
||||
return emplace_return(
|
||||
iterator(this->resize_and_add_node(
|
||||
boost::unordered::detail::func::construct_node_pair(
|
||||
this->node_alloc(), boost::forward<Key>(k)),
|
||||
key_hash)),
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Key>
|
||||
iterator try_emplace_hint_impl(c_iterator hint, BOOST_FWD_REF(Key) k)
|
||||
{
|
||||
if (hint.node_ && this->key_eq()(hint->first, k)) {
|
||||
return iterator(hint.node_);
|
||||
} else {
|
||||
return try_emplace_impl(k).first;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Key, BOOST_UNORDERED_EMPLACE_TEMPLATE>
|
||||
emplace_return try_emplace_impl(
|
||||
BOOST_FWD_REF(Key) k, BOOST_UNORDERED_EMPLACE_ARGS)
|
||||
{
|
||||
std::size_t key_hash = this->hash(k);
|
||||
node_pointer pos = this->find_node(key_hash, k);
|
||||
if (pos) {
|
||||
return emplace_return(iterator(pos), false);
|
||||
} else {
|
||||
return emplace_return(
|
||||
iterator(this->resize_and_add_node(
|
||||
boost::unordered::detail::func::
|
||||
construct_node_pair_from_args(this->node_alloc(),
|
||||
boost::forward<Key>(k),
|
||||
BOOST_UNORDERED_EMPLACE_FORWARD),
|
||||
key_hash)),
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Key, BOOST_UNORDERED_EMPLACE_TEMPLATE>
|
||||
iterator try_emplace_hint_impl(
|
||||
c_iterator hint, BOOST_FWD_REF(Key) k, BOOST_UNORDERED_EMPLACE_ARGS)
|
||||
{
|
||||
if (hint.node_ && this->key_eq()(hint->first, k)) {
|
||||
return iterator(hint.node_);
|
||||
} else {
|
||||
return try_emplace_impl(k, BOOST_UNORDERED_EMPLACE_FORWARD).first;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Key, typename M>
|
||||
emplace_return insert_or_assign_impl(
|
||||
BOOST_FWD_REF(Key) k, BOOST_FWD_REF(M) obj)
|
||||
|
@ -220,6 +220,37 @@ template <class K, class T, class H, class P, class A> class unordered_map
|
||||
{
|
||||
return table_.emplace_hint(hint, boost::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
std::pair<iterator, bool> try_emplace(
|
||||
key_type const& k, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
return table_.try_emplace_impl(k, boost::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
iterator try_emplace(
|
||||
const_iterator hint, key_type const& k, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
return table_.try_emplace_hint_impl(
|
||||
hint, k, boost::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
std::pair<iterator, bool> try_emplace(
|
||||
BOOST_RV_REF(key_type) k, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
return table_.try_emplace_impl(
|
||||
boost::move(k), boost::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
iterator try_emplace(const_iterator hint, BOOST_RV_REF(key_type) k,
|
||||
BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
return table_.try_emplace_hint_impl(
|
||||
hint, boost::move(k), boost::forward<Args>(args)...);
|
||||
}
|
||||
#else
|
||||
|
||||
#if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100))
|
||||
@ -246,6 +277,18 @@ template <class K, class T, class H, class P, class A> class unordered_map
|
||||
|
||||
#endif
|
||||
|
||||
template <typename Key>
|
||||
std::pair<iterator, bool> try_emplace(BOOST_FWD_REF(Key) k)
|
||||
{
|
||||
return table_.try_emplace_impl(boost::forward<Key>(k));
|
||||
}
|
||||
|
||||
template <typename Key>
|
||||
iterator try_emplace(const_iterator hint, BOOST_FWD_REF(Key) k)
|
||||
{
|
||||
return table_.try_emplace_hint_impl(hint, boost::forward<Key>(k));
|
||||
}
|
||||
|
||||
template <typename A0>
|
||||
std::pair<iterator, bool> emplace(BOOST_FWD_REF(A0) a0)
|
||||
{
|
||||
@ -261,6 +304,39 @@ template <class K, class T, class H, class P, class A> class unordered_map
|
||||
boost::forward<A0>(a0)));
|
||||
}
|
||||
|
||||
template <typename A0>
|
||||
std::pair<iterator, bool> try_emplace(
|
||||
key_type const& k, BOOST_FWD_REF(A0) a0)
|
||||
{
|
||||
return table_.try_emplace_impl(
|
||||
k, boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0)));
|
||||
}
|
||||
|
||||
template <typename A0>
|
||||
iterator try_emplace(
|
||||
const_iterator hint, key_type const& k, BOOST_FWD_REF(A0) a0)
|
||||
{
|
||||
return table_.try_emplace_hint_impl(
|
||||
hint, k, boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0)));
|
||||
}
|
||||
|
||||
template <typename A0>
|
||||
std::pair<iterator, bool> try_emplace(
|
||||
BOOST_RV_REF(key_type) k, BOOST_FWD_REF(A0) a0)
|
||||
{
|
||||
return table_.try_emplace_impl(boost::move(k), boost::forward<A0>(a0));
|
||||
}
|
||||
|
||||
template <typename A0>
|
||||
iterator try_emplace(
|
||||
const_iterator hint, BOOST_RV_REF(key_type) k, BOOST_FWD_REF(A0) a0)
|
||||
{
|
||||
return table_.try_emplace_hint_impl(
|
||||
hint, boost::move(k), boost::forward<A0>(a0));
|
||||
}
|
||||
|
||||
template <typename A0, typename A1>
|
||||
std::pair<iterator, bool> emplace(
|
||||
BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1)
|
||||
@ -278,6 +354,44 @@ template <class K, class T, class H, class P, class A> class unordered_map
|
||||
boost::forward<A0>(a0), boost::forward<A1>(a1)));
|
||||
}
|
||||
|
||||
template <typename A0, typename A1>
|
||||
std::pair<iterator, bool> try_emplace(
|
||||
key_type const& k, BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1)
|
||||
{
|
||||
return table_.try_emplace_impl(
|
||||
k, boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0), boost::forward<A1>(a1)));
|
||||
}
|
||||
|
||||
template <typename A0, typename A1>
|
||||
iterator try_emplace(const_iterator hint, key_type const& k,
|
||||
BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1)
|
||||
{
|
||||
return table_.try_emplace_hint_impl(
|
||||
hint, k, boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0), boost::forward<A1>(a1)));
|
||||
}
|
||||
|
||||
template <typename A0, typename A1>
|
||||
std::pair<iterator, bool> try_emplace(
|
||||
BOOST_RV_REF(key_type) k, BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1)
|
||||
{
|
||||
return table_.try_emplace_impl(
|
||||
boost::move(k),
|
||||
boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0), boost::forward<A1>(a1)));
|
||||
}
|
||||
|
||||
template <typename A0, typename A1>
|
||||
iterator try_emplace(const_iterator hint, BOOST_RV_REF(key_type) k,
|
||||
BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1)
|
||||
{
|
||||
return table_.try_emplace_hint_impl(
|
||||
hint, boost::move(k),
|
||||
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)
|
||||
@ -297,6 +411,49 @@ template <class K, class T, class H, class P, class A> class unordered_map
|
||||
boost::forward<A2>(a2)));
|
||||
}
|
||||
|
||||
template <typename A0, typename A1, typename A2>
|
||||
std::pair<iterator, bool> try_emplace(key_type const& k,
|
||||
BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2)
|
||||
{
|
||||
return table_.try_emplace_impl(
|
||||
k, boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0), boost::forward<A1>(a1),
|
||||
boost::forward<A2>(a2)));
|
||||
}
|
||||
|
||||
template <typename A0, typename A1, typename A2>
|
||||
iterator try_emplace(const_iterator hint, key_type const& k,
|
||||
BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2)
|
||||
{
|
||||
return table_
|
||||
.try_emplace_impl_(
|
||||
hint, k, boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0), boost::forward<A1>(a1),
|
||||
boost::forward<A2>(a2)))
|
||||
.first;
|
||||
}
|
||||
|
||||
template <typename A0, typename A1, typename A2>
|
||||
std::pair<iterator, bool> try_emplace(BOOST_RV_REF(key_type) k,
|
||||
BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2)
|
||||
{
|
||||
return table_.try_emplace_impl(
|
||||
boost::move(k), boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0), boost::forward<A1>(a1),
|
||||
boost::forward<A2>(a2)));
|
||||
}
|
||||
|
||||
template <typename A0, typename A1, typename A2>
|
||||
iterator try_emplace(const_iterator hint, BOOST_RV_REF(key_type) k,
|
||||
BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2)
|
||||
{
|
||||
return table_.try_emplace_hint_impl(
|
||||
hint, boost::move(k),
|
||||
boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0), boost::forward<A1>(a1),
|
||||
boost::forward<A2>(a2)));
|
||||
}
|
||||
|
||||
#define BOOST_UNORDERED_EMPLACE(z, n, _) \
|
||||
template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)> \
|
||||
std::pair<iterator, bool> emplace( \
|
||||
@ -313,6 +470,42 @@ template <class K, class T, class H, class P, class A> class unordered_map
|
||||
return table_.emplace_hint( \
|
||||
hint, 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)> \
|
||||
std::pair<iterator, bool> try_emplace( \
|
||||
key_type const& k, BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a)) \
|
||||
{ \
|
||||
return table_.try_emplace_impl( \
|
||||
k, 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 try_emplace(const_iterator hint, key_type const& k, \
|
||||
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a)) \
|
||||
{ \
|
||||
return table_.try_emplace_hint_impl(hint, k, \
|
||||
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)> \
|
||||
std::pair<iterator, bool> try_emplace(BOOST_RV_REF(key_type) k, \
|
||||
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a)) \
|
||||
{ \
|
||||
return table_.try_emplace_impl(boost::move(k), \
|
||||
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 try_emplace(const_iterator hint, BOOST_RV_REF(key_type) k, \
|
||||
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a)) \
|
||||
{ \
|
||||
return table_.try_emplace_hint_impl(hint, boost::move(k), \
|
||||
boost::unordered::detail::create_emplace_args(BOOST_PP_ENUM_##z( \
|
||||
n, BOOST_UNORDERED_CALL_FORWARD, a))); \
|
||||
}
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(
|
||||
@ -1114,7 +1307,7 @@ 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>::operator[](const key_type& k)
|
||||
{
|
||||
return table_[k].second;
|
||||
return table_.try_emplace_impl(k).first->second;
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
|
@ -309,10 +309,21 @@ void unordered_map_functions(X&, Key const& k, T const& v)
|
||||
X a;
|
||||
test::check_return_type<mapped_type>::equals_ref(a[k]);
|
||||
test::check_return_type<mapped_type>::equals_ref(a.at(k));
|
||||
test::check_return_type<std::pair<iterator, bool> >::equals(
|
||||
a.try_emplace(k, v));
|
||||
test::check_return_type<std::pair<iterator, bool> >::equals(
|
||||
a.try_emplace(rvalue(k), v));
|
||||
test::check_return_type<iterator>::equals(a.try_emplace(a.begin(), k, v));
|
||||
test::check_return_type<iterator>::equals(
|
||||
a.try_emplace(a.begin(), rvalue(k), v));
|
||||
test::check_return_type<std::pair<iterator, bool> >::equals(
|
||||
a.insert_or_assign(k, v));
|
||||
test::check_return_type<std::pair<iterator, bool> >::equals(
|
||||
a.insert_or_assign(rvalue(k), v));
|
||||
test::check_return_type<iterator>::equals(
|
||||
a.insert_or_assign(a.begin(), k, v));
|
||||
test::check_return_type<iterator>::equals(
|
||||
a.insert_or_assign(a.begin(), rvalue(k), v));
|
||||
|
||||
X const b = a;
|
||||
test::check_return_type<mapped_type const>::equals_ref(b.at(k));
|
||||
|
@ -465,6 +465,55 @@ UNORDERED_AUTO_TEST(emplace_multimap)
|
||||
BOOST_TEST_EQ(check_.instances(), 20);
|
||||
BOOST_TEST_EQ(check_.constructions(), 20);
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(try_emplace)
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
typedef boost::unordered_map<int, emplace_value> container;
|
||||
typedef container::iterator iterator;
|
||||
typedef std::pair<iterator, bool> return_type;
|
||||
container x(10);
|
||||
return_type r1, r2, r3;
|
||||
|
||||
int k1 = 3;
|
||||
emplace_value m1(414, "grr");
|
||||
r1 = x.try_emplace(3, 414, "grr");
|
||||
BOOST_TEST(r1.second);
|
||||
BOOST_TEST(r1.first->first == k1);
|
||||
BOOST_TEST(r1.first->second == m1);
|
||||
BOOST_TEST_EQ(x.size(), 1u);
|
||||
BOOST_TEST_EQ(check_.instances(), 2);
|
||||
BOOST_TEST_EQ(check_.constructions(), 2);
|
||||
|
||||
int k2 = 10;
|
||||
emplace_value m2(25, "", 'z');
|
||||
r2 = x.try_emplace(10, 25, std::string(""), 'z');
|
||||
BOOST_TEST(r2.second);
|
||||
BOOST_TEST(r2.first->first == k2);
|
||||
BOOST_TEST(r2.first->second == m2);
|
||||
BOOST_TEST_EQ(x.size(), 2u);
|
||||
BOOST_TEST_EQ(check_.instances(), 4);
|
||||
BOOST_TEST_EQ(check_.constructions(), 4);
|
||||
|
||||
BOOST_TEST(x.find(k1)->second == m1);
|
||||
BOOST_TEST(x.find(k2)->second == m2);
|
||||
|
||||
r3 = x.try_emplace(k2, 68, "jfeoj", 'p', 49309, 2323);
|
||||
BOOST_TEST(!r3.second);
|
||||
BOOST_TEST(r3.first == r2.first);
|
||||
BOOST_TEST(r3.first->second == m2);
|
||||
BOOST_TEST_EQ(x.size(), 2u);
|
||||
BOOST_TEST_EQ(check_.instances(), 4);
|
||||
BOOST_TEST_EQ(check_.constructions(), 4);
|
||||
|
||||
BOOST_TEST(r2.first == x.try_emplace(r2.first, k2, 808709, "what"));
|
||||
BOOST_TEST(
|
||||
r2.first ==
|
||||
x.try_emplace(r2.first, k2, 10, "xxx", 'a', 4, 5, 6, 7, 8, 9, 10));
|
||||
BOOST_TEST(r2.first->second == m2);
|
||||
BOOST_TEST_EQ(x.size(), 2u);
|
||||
}
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
@ -637,6 +637,171 @@ template <class X> void map_tests2(X*, test::random_generator generator)
|
||||
}
|
||||
}
|
||||
|
||||
template <class X> void try_emplace_tests(X*, test::random_generator generator)
|
||||
{
|
||||
std::cerr << "try_emplace(key, value)\n";
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
|
||||
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
X x;
|
||||
test::ordered<X> tracker = test::create_ordered(x);
|
||||
|
||||
test::random_values<X> v(1000, generator);
|
||||
for (BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it =
|
||||
v.begin();
|
||||
it != v.end(); ++it) {
|
||||
BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count =
|
||||
x.bucket_count();
|
||||
float b = x.max_load_factor();
|
||||
|
||||
iterator pos = x.find(it->first);
|
||||
bool found = pos != x.end();
|
||||
|
||||
std::pair<typename X::iterator, bool> r =
|
||||
x.try_emplace(it->first, it->second);
|
||||
if (found) {
|
||||
BOOST_TEST(pos == r.first);
|
||||
BOOST_TEST(!r.second);
|
||||
} else {
|
||||
BOOST_TEST(r.second);
|
||||
}
|
||||
BOOST_TEST_EQ(r.first->first, it->first);
|
||||
BOOST_TEST_EQ(r.first->second, it->second);
|
||||
|
||||
tracker.insert(*it);
|
||||
tracker.compare_key(x, *it);
|
||||
|
||||
if (static_cast<double>(x.size()) <
|
||||
b * static_cast<double>(old_bucket_count))
|
||||
BOOST_TEST(x.bucket_count() == old_bucket_count);
|
||||
}
|
||||
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
std::cerr << "try_emplace(begin(), key, value)\n";
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
|
||||
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
X x;
|
||||
test::ordered<X> tracker = test::create_ordered(x);
|
||||
|
||||
test::random_values<X> v(1000, generator);
|
||||
for (BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it =
|
||||
v.begin();
|
||||
it != v.end(); ++it) {
|
||||
BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count =
|
||||
x.bucket_count();
|
||||
float b = x.max_load_factor();
|
||||
|
||||
iterator pos = x.find(it->first);
|
||||
bool found = pos != x.end();
|
||||
|
||||
typename X::iterator r =
|
||||
x.try_emplace(r.begin(), it->first, it->second);
|
||||
if (found) {
|
||||
BOOST_TEST(pos == r);
|
||||
}
|
||||
BOOST_TEST_EQ(r->first, it->first);
|
||||
BOOST_TEST_EQ(r->second, it->second);
|
||||
|
||||
tracker.insert(*it);
|
||||
tracker.compare_key(x, *it);
|
||||
|
||||
if (static_cast<double>(x.size()) <
|
||||
b * static_cast<double>(old_bucket_count))
|
||||
BOOST_TEST(x.bucket_count() == old_bucket_count);
|
||||
}
|
||||
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
std::cerr << "try_emplace(end(), key, value)\n";
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
|
||||
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
X x;
|
||||
test::ordered<X> tracker = test::create_ordered(x);
|
||||
|
||||
test::random_values<X> v(1000, generator);
|
||||
for (BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it =
|
||||
v.begin();
|
||||
it != v.end(); ++it) {
|
||||
BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count =
|
||||
x.bucket_count();
|
||||
float b = x.max_load_factor();
|
||||
|
||||
iterator pos = x.find(it->first);
|
||||
bool found = pos != x.end();
|
||||
|
||||
typename X::iterator r =
|
||||
x.try_emplace(r.end(), it->first, it->second);
|
||||
if (found) {
|
||||
BOOST_TEST(pos == r);
|
||||
}
|
||||
BOOST_TEST_EQ(r->first, it->first);
|
||||
BOOST_TEST_EQ(r->second, it->second);
|
||||
|
||||
tracker.insert(*it);
|
||||
tracker.compare_key(x, *it);
|
||||
|
||||
if (static_cast<double>(x.size()) <
|
||||
b * static_cast<double>(old_bucket_count))
|
||||
BOOST_TEST(x.bucket_count() == old_bucket_count);
|
||||
}
|
||||
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
std::cerr << "try_emplace(pos, key, value)\n";
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
|
||||
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
X x;
|
||||
test::ordered<X> tracker = test::create_ordered(x);
|
||||
|
||||
test::random_values<X> v(1000, generator);
|
||||
for (BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it =
|
||||
v.begin();
|
||||
it != v.end(); ++it) {
|
||||
BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count =
|
||||
x.bucket_count();
|
||||
float b = x.max_load_factor();
|
||||
|
||||
iterator pos = x.find(it->first);
|
||||
bool found = pos != x.end();
|
||||
|
||||
typename X::iterator r = x.try_emplace(pos, it->first, it->second);
|
||||
if (found) {
|
||||
BOOST_TEST(pos == r);
|
||||
}
|
||||
BOOST_TEST_EQ(r->first, it->first);
|
||||
BOOST_TEST_EQ(r->second, it->second);
|
||||
|
||||
tracker.insert(*it);
|
||||
tracker.compare_key(x, *it);
|
||||
|
||||
if (static_cast<double>(x.size()) <
|
||||
b * static_cast<double>(old_bucket_count))
|
||||
BOOST_TEST(x.bucket_count() == old_bucket_count);
|
||||
}
|
||||
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
}
|
||||
|
||||
// Some tests for when the range's value type doesn't match the container's
|
||||
// value type.
|
||||
|
||||
@ -876,6 +1041,10 @@ UNORDERED_AUTO_TEST(map_emplace_test)
|
||||
x.emplace(2, 3);
|
||||
BOOST_TEST(
|
||||
x.find(2) != x.end() && x.find(2)->second == overloaded_constructor(3));
|
||||
|
||||
x.try_emplace(5);
|
||||
BOOST_TEST(
|
||||
x.find(5) != x.end() && x.find(5)->second == overloaded_constructor());
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(set_emplace_test)
|
||||
@ -954,6 +1123,23 @@ UNORDERED_AUTO_TEST(map_emplace_test2)
|
||||
BOOST_TEST(x.find(overloaded_constructor(9, 3, 1)) != x.end() &&
|
||||
x.find(overloaded_constructor(9, 3, 1))->second ==
|
||||
overloaded_constructor(10));
|
||||
|
||||
x.clear();
|
||||
|
||||
x.try_emplace(overloaded_constructor());
|
||||
BOOST_TEST(
|
||||
x.find(overloaded_constructor()) != x.end() &&
|
||||
x.find(overloaded_constructor())->second == overloaded_constructor());
|
||||
|
||||
x.try_emplace(1);
|
||||
BOOST_TEST(
|
||||
x.find(overloaded_constructor(1)) != x.end() &&
|
||||
x.find(overloaded_constructor(1))->second == overloaded_constructor());
|
||||
|
||||
x.try_emplace(overloaded_constructor(2, 3), 4, 5, 6);
|
||||
BOOST_TEST(x.find(overloaded_constructor(2, 3)) != x.end() &&
|
||||
x.find(overloaded_constructor(2, 3))->second ==
|
||||
overloaded_constructor(4, 5, 6));
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(set_emplace_test2)
|
||||
|
Reference in New Issue
Block a user