mirror of
https://github.com/boostorg/unordered.git
synced 2025-07-30 03:17:15 +02:00
Add extract/insert semantics to foa-based node set, add more tests
This commit is contained in:
@ -82,6 +82,15 @@
|
|||||||
namespace boost{
|
namespace boost{
|
||||||
namespace unordered{
|
namespace unordered{
|
||||||
namespace detail{
|
namespace detail{
|
||||||
|
|
||||||
|
template <class Iterator,class NodeType>
|
||||||
|
struct insert_return_type
|
||||||
|
{
|
||||||
|
Iterator position;
|
||||||
|
bool inserted;
|
||||||
|
NodeType node;
|
||||||
|
};
|
||||||
|
|
||||||
namespace foa{
|
namespace foa{
|
||||||
|
|
||||||
static const std::size_t default_bucket_count = 0;
|
static const std::size_t default_bucket_count = 0;
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
#include <boost/core/allocator_access.hpp>
|
#include <boost/core/allocator_access.hpp>
|
||||||
#include <boost/functional/hash.hpp>
|
#include <boost/functional/hash.hpp>
|
||||||
#include <boost/optional/optional.hpp>
|
|
||||||
#include <boost/throw_exception.hpp>
|
#include <boost/throw_exception.hpp>
|
||||||
|
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
@ -56,6 +55,11 @@ namespace boost {
|
|||||||
*/
|
*/
|
||||||
element_type() = default;
|
element_type() = default;
|
||||||
element_type(element_type const&) = delete;
|
element_type(element_type const&) = delete;
|
||||||
|
element_type(element_type&& rhs) noexcept
|
||||||
|
{
|
||||||
|
p = rhs.p;
|
||||||
|
rhs.p = nullptr;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static value_type& value_from(element_type const& x) { return *(x.p); }
|
static value_type& value_from(element_type const& x) { return *(x.p); }
|
||||||
@ -122,7 +126,7 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class NodeMapTypes, class Allocator> struct node_handle
|
template <class NodeMapTypes, class Allocator> struct node_map_handle
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
using type_policy = NodeMapTypes;
|
using type_policy = NodeMapTypes;
|
||||||
@ -132,7 +136,6 @@ namespace boost {
|
|||||||
friend class boost::unordered::unordered_node_map;
|
friend class boost::unordered::unordered_node_map;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using value_type = typename NodeMapTypes::value_type;
|
|
||||||
using key_type = typename NodeMapTypes::key_type;
|
using key_type = typename NodeMapTypes::key_type;
|
||||||
using mapped_type = typename NodeMapTypes::mapped_type;
|
using mapped_type = typename NodeMapTypes::mapped_type;
|
||||||
using allocator_type = Allocator;
|
using allocator_type = Allocator;
|
||||||
@ -167,24 +170,22 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr node_handle() noexcept = default;
|
constexpr node_map_handle() noexcept = default;
|
||||||
|
|
||||||
node_handle(node_handle&& nh) noexcept
|
node_map_handle(node_map_handle&& nh) noexcept
|
||||||
{
|
{
|
||||||
// neither of these move constructors are allowed to throw exceptions
|
// neither of these move constructors are allowed to throw exceptions
|
||||||
// so we can get away with rote placement new
|
// so we can get away with rote placement new
|
||||||
//
|
//
|
||||||
new (a) Allocator(std::move(nh.al()));
|
new (a) Allocator(std::move(nh.al()));
|
||||||
type_policy::construct(al(), reinterpret_cast<element_type*>(x),
|
new (x) element_type(std::move(nh.element()));
|
||||||
type_policy::move(nh.element()));
|
|
||||||
|
|
||||||
empty_ = false;
|
empty_ = false;
|
||||||
|
|
||||||
reinterpret_cast<Allocator*>(nh.a)->~Allocator();
|
reinterpret_cast<Allocator*>(nh.a)->~Allocator();
|
||||||
nh.empty_ = true;
|
nh.empty_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
~node_handle()
|
~node_map_handle()
|
||||||
{
|
{
|
||||||
if (!empty()) {
|
if (!empty()) {
|
||||||
type_policy::destroy(al(), reinterpret_cast<element_type*>(x));
|
type_policy::destroy(al(), reinterpret_cast<element_type*>(x));
|
||||||
@ -208,13 +209,6 @@ namespace boost {
|
|||||||
explicit operator bool() const noexcept { return !empty(); }
|
explicit operator bool() const noexcept { return !empty(); }
|
||||||
BOOST_ATTRIBUTE_NODISCARD bool empty() const noexcept { return empty_; }
|
BOOST_ATTRIBUTE_NODISCARD bool empty() const noexcept { return empty_; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Iterator, class NodeType> struct insert_return_type
|
|
||||||
{
|
|
||||||
Iterator position;
|
|
||||||
bool inserted;
|
|
||||||
NodeType node;
|
|
||||||
};
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||||
@ -249,7 +243,9 @@ namespace boost {
|
|||||||
typename boost::allocator_const_pointer<allocator_type>::type;
|
typename boost::allocator_const_pointer<allocator_type>::type;
|
||||||
using iterator = typename table_type::iterator;
|
using iterator = typename table_type::iterator;
|
||||||
using const_iterator = typename table_type::const_iterator;
|
using const_iterator = typename table_type::const_iterator;
|
||||||
using node_type = detail::node_handle<map_types, allocator_type>;
|
using node_type = detail::node_map_handle<map_types,
|
||||||
|
typename boost::allocator_rebind<Allocator,
|
||||||
|
typename map_types::value_type>::type>;
|
||||||
using insert_return_type =
|
using insert_return_type =
|
||||||
detail::insert_return_type<iterator, node_type>;
|
detail::insert_return_type<iterator, node_type>;
|
||||||
|
|
||||||
@ -457,6 +453,18 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iterator insert(const_iterator, node_type&& nh)
|
||||||
|
{
|
||||||
|
if (nh.empty()) {
|
||||||
|
return end();
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_ASSERT(get_allocator() == nh.get_allocator());
|
||||||
|
|
||||||
|
auto itp = table_.emplace_impl(map_types::move(nh.element()));
|
||||||
|
return itp.first;
|
||||||
|
}
|
||||||
|
|
||||||
template <class M>
|
template <class M>
|
||||||
std::pair<iterator, bool> insert_or_assign(key_type const& key, M&& obj)
|
std::pair<iterator, bool> insert_or_assign(key_type const& key, M&& obj)
|
||||||
{
|
{
|
||||||
|
@ -51,6 +51,11 @@ namespace boost {
|
|||||||
*/
|
*/
|
||||||
element_type() = default;
|
element_type() = default;
|
||||||
element_type(element_type const&) = delete;
|
element_type(element_type const&) = delete;
|
||||||
|
element_type(element_type&& rhs) noexcept
|
||||||
|
{
|
||||||
|
p = rhs.p;
|
||||||
|
rhs.p = nullptr;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static value_type& value_from(element_type const& x) { return *x.p; }
|
static value_type& value_from(element_type const& x) { return *x.p; }
|
||||||
@ -102,6 +107,84 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class NodeSetTypes, class Allocator> struct node_set_handle
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
using type_policy = NodeSetTypes;
|
||||||
|
using element_type = typename type_policy::element_type;
|
||||||
|
|
||||||
|
template <class Key, class Hash, class Pred, class Alloc>
|
||||||
|
friend class boost::unordered::unordered_node_set;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using value_type = typename NodeSetTypes::value_type;
|
||||||
|
using allocator_type = Allocator;
|
||||||
|
|
||||||
|
private:
|
||||||
|
alignas(element_type) unsigned char x[sizeof(element_type)];
|
||||||
|
alignas(Allocator) unsigned char a[sizeof(Allocator)];
|
||||||
|
bool empty_;
|
||||||
|
|
||||||
|
element_type& element() noexcept
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(!empty());
|
||||||
|
return *reinterpret_cast<element_type*>(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
element_type const& element() const noexcept
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(!empty());
|
||||||
|
return *reinterpret_cast<element_type const*>(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
Allocator& al() noexcept
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(!empty());
|
||||||
|
return *reinterpret_cast<Allocator*>(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
Allocator const& al() const noexcept
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(!empty());
|
||||||
|
return *reinterpret_cast<Allocator const*>(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
constexpr node_set_handle() noexcept = default;
|
||||||
|
|
||||||
|
node_set_handle(node_set_handle&& nh) noexcept
|
||||||
|
{
|
||||||
|
// neither of these move constructors are allowed to throw exceptions
|
||||||
|
// so we can get away with rote placement new
|
||||||
|
//
|
||||||
|
new (a) Allocator(std::move(nh.al()));
|
||||||
|
new (x) element_type(std::move(nh.element()));
|
||||||
|
empty_ = false;
|
||||||
|
|
||||||
|
reinterpret_cast<Allocator*>(nh.a)->~Allocator();
|
||||||
|
nh.empty_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
~node_set_handle()
|
||||||
|
{
|
||||||
|
if (!empty()) {
|
||||||
|
type_policy::destroy(al(), reinterpret_cast<element_type*>(x));
|
||||||
|
reinterpret_cast<Allocator*>(a)->~Allocator();
|
||||||
|
empty_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
value_type& value() const
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(!empty());
|
||||||
|
return const_cast<value_type&>(type_policy::extract(element()));
|
||||||
|
}
|
||||||
|
|
||||||
|
allocator_type get_allocator() const noexcept { return al(); }
|
||||||
|
explicit operator bool() const noexcept { return !empty(); }
|
||||||
|
BOOST_ATTRIBUTE_NODISCARD bool empty() const noexcept { return empty_; }
|
||||||
|
};
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
template <class Key, class Hash, class KeyEqual, class Allocator>
|
template <class Key, class Hash, class KeyEqual, class Allocator>
|
||||||
@ -135,6 +218,11 @@ namespace boost {
|
|||||||
typename boost::allocator_const_pointer<allocator_type>::type;
|
typename boost::allocator_const_pointer<allocator_type>::type;
|
||||||
using iterator = typename table_type::iterator;
|
using iterator = typename table_type::iterator;
|
||||||
using const_iterator = typename table_type::const_iterator;
|
using const_iterator = typename table_type::const_iterator;
|
||||||
|
using node_type = detail::node_set_handle<set_types,
|
||||||
|
typename boost::allocator_rebind<Allocator,
|
||||||
|
typename set_types::value_type>::type>;
|
||||||
|
using insert_return_type =
|
||||||
|
detail::insert_return_type<iterator, node_type>;
|
||||||
|
|
||||||
unordered_node_set() : unordered_node_set(0) {}
|
unordered_node_set() : unordered_node_set(0) {}
|
||||||
|
|
||||||
@ -339,6 +427,34 @@ namespace boost {
|
|||||||
this->insert(ilist.begin(), ilist.end());
|
this->insert(ilist.begin(), ilist.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
insert_return_type insert(node_type&& nh)
|
||||||
|
{
|
||||||
|
if (nh.empty()) {
|
||||||
|
return {end(), false, node_type{}};
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_ASSERT(get_allocator() == nh.get_allocator());
|
||||||
|
|
||||||
|
auto itp = table_.emplace_impl(set_types::move(nh.element()));
|
||||||
|
if (itp.second) {
|
||||||
|
return {itp.first, true, node_type{}};
|
||||||
|
} else {
|
||||||
|
return {itp.first, false, std::move(nh)};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator insert(const_iterator, node_type&& nh)
|
||||||
|
{
|
||||||
|
if (nh.empty()) {
|
||||||
|
return end();
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_ASSERT(get_allocator() == nh.get_allocator());
|
||||||
|
|
||||||
|
auto itp = table_.emplace_impl(set_types::move(nh.element()));
|
||||||
|
return itp.first;
|
||||||
|
}
|
||||||
|
|
||||||
template <class... Args>
|
template <class... Args>
|
||||||
BOOST_FORCEINLINE std::pair<iterator, bool> emplace(Args&&... args)
|
BOOST_FORCEINLINE std::pair<iterator, bool> emplace(Args&&... args)
|
||||||
{
|
{
|
||||||
@ -383,6 +499,52 @@ namespace boost {
|
|||||||
table_.swap(rhs.table_);
|
table_.swap(rhs.table_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
node_type extract(const_iterator pos)
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(pos != end());
|
||||||
|
node_type nh;
|
||||||
|
table_.extract(
|
||||||
|
pos, reinterpret_cast<typename set_types::element_type*>(nh.x));
|
||||||
|
new (&nh.a) allocator_type(get_allocator());
|
||||||
|
nh.empty_ = false;
|
||||||
|
return nh;
|
||||||
|
}
|
||||||
|
|
||||||
|
node_type extract(key_type const& key)
|
||||||
|
{
|
||||||
|
auto pos = find(key);
|
||||||
|
node_type nh;
|
||||||
|
if (pos != end()) {
|
||||||
|
table_.extract(
|
||||||
|
pos, reinterpret_cast<typename set_types::element_type*>(nh.x));
|
||||||
|
new (&nh.a) allocator_type(get_allocator());
|
||||||
|
nh.empty_ = false;
|
||||||
|
} else {
|
||||||
|
nh.empty_ = true;
|
||||||
|
}
|
||||||
|
return nh;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename std::enable_if<
|
||||||
|
boost::unordered::detail::transparent_non_iterable<K,
|
||||||
|
unordered_node_set>::value,
|
||||||
|
node_type>::type
|
||||||
|
extract(K const& key)
|
||||||
|
{
|
||||||
|
auto pos = find(key);
|
||||||
|
node_type nh;
|
||||||
|
if (pos != end()) {
|
||||||
|
table_.extract(
|
||||||
|
pos, reinterpret_cast<typename set_types::element_type*>(nh.x));
|
||||||
|
new (&nh.a) allocator_type(get_allocator());
|
||||||
|
nh.empty_ = false;
|
||||||
|
} else {
|
||||||
|
nh.empty_ = true;
|
||||||
|
}
|
||||||
|
return nh;
|
||||||
|
}
|
||||||
|
|
||||||
template <class H2, class P2>
|
template <class H2, class P2>
|
||||||
void merge(unordered_node_set<key_type, H2, P2, allocator_type>& source)
|
void merge(unordered_node_set<key_type, H2, P2, allocator_type>& source)
|
||||||
{
|
{
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
|
||||||
#include "../helpers/unordered.hpp"
|
#include "../helpers/unordered.hpp"
|
||||||
|
|
||||||
#include "../helpers/equivalent.hpp"
|
#include "../helpers/equivalent.hpp"
|
||||||
@ -115,12 +114,13 @@ namespace extract_tests {
|
|||||||
|
|
||||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
boost::unordered_node_map<test::object, test::object, test::hash,
|
boost::unordered_node_map<test::object, test::object, test::hash,
|
||||||
test::equal_to,
|
test::equal_to, test::allocator1<test::object> >* test_node_map;
|
||||||
test::allocator1<std::pair<test::object const, test::object> > >*
|
|
||||||
test_node_map;
|
|
||||||
|
|
||||||
UNORDERED_TEST(
|
boost::unordered_node_set<test::object, test::hash, test::equal_to,
|
||||||
extract_tests1, ((test_node_map))((default_generator)(generate_collisions)))
|
test::allocator1<test::object> >* test_node_set;
|
||||||
|
|
||||||
|
UNORDERED_TEST(extract_tests1,
|
||||||
|
((test_node_map)(test_node_set))((default_generator)(generate_collisions)))
|
||||||
#else
|
#else
|
||||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||||
test::allocator1<test::object> >* test_set;
|
test::allocator1<test::object> >* test_set;
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
#include "../helpers/postfix.hpp"
|
#include "../helpers/postfix.hpp"
|
||||||
#include "../helpers/unordered.hpp"
|
|
||||||
#include "../helpers/prefix.hpp"
|
#include "../helpers/prefix.hpp"
|
||||||
|
#include "../helpers/unordered.hpp"
|
||||||
|
|
||||||
#include "../helpers/helpers.hpp"
|
#include "../helpers/helpers.hpp"
|
||||||
#include "../helpers/metafunctions.hpp"
|
#include "../helpers/metafunctions.hpp"
|
||||||
@ -17,42 +17,19 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
template <template <class Key, class T, class Hash = boost::hash<Key>,
|
||||||
UNORDERED_AUTO_TEST (example1_5) {
|
class Pred = std::equal_to<Key>,
|
||||||
typedef boost::unordered_node_map<int, std::string>::insert_return_type
|
class Allocator = std::allocator<std::pair<Key const, T> > >
|
||||||
insert_return_type;
|
class Map>
|
||||||
|
static void example1()
|
||||||
|
{
|
||||||
|
typedef typename Map<int, std::string>::insert_return_type insert_return_type;
|
||||||
|
|
||||||
boost::unordered_node_map<int, std::string> src;
|
Map<int, std::string> src;
|
||||||
src.emplace(1, "one");
|
src.emplace(1, "one");
|
||||||
src.emplace(2, "two");
|
src.emplace(2, "two");
|
||||||
src.emplace(3, "buckle my shoe");
|
src.emplace(3, "buckle my shoe");
|
||||||
boost::unordered_node_map<int, std::string> dst;
|
Map<int, std::string> dst;
|
||||||
dst.emplace(3, "three");
|
|
||||||
|
|
||||||
dst.insert(src.extract(src.find(1)));
|
|
||||||
dst.insert(src.extract(2));
|
|
||||||
insert_return_type r = dst.insert(src.extract(3));
|
|
||||||
|
|
||||||
BOOST_TEST(src.empty());
|
|
||||||
BOOST_TEST(dst.size() == 3);
|
|
||||||
BOOST_TEST(dst[1] == "one");
|
|
||||||
BOOST_TEST(dst[2] == "two");
|
|
||||||
BOOST_TEST(dst[3] == "three");
|
|
||||||
BOOST_TEST(!r.inserted);
|
|
||||||
BOOST_TEST(r.position == dst.find(3));
|
|
||||||
BOOST_TEST(r.node.mapped() == "buckle my shoe");
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (example1) {
|
|
||||||
typedef boost::unordered_map<int, std::string>::insert_return_type
|
|
||||||
insert_return_type;
|
|
||||||
|
|
||||||
boost::unordered_map<int, std::string> src;
|
|
||||||
src.emplace(1, "one");
|
|
||||||
src.emplace(2, "two");
|
|
||||||
src.emplace(3, "buckle my shoe");
|
|
||||||
boost::unordered_map<int, std::string> dst;
|
|
||||||
dst.emplace(3, "three");
|
dst.emplace(3, "three");
|
||||||
|
|
||||||
dst.insert(src.extract(src.find(1)));
|
dst.insert(src.extract(src.find(1)));
|
||||||
@ -69,12 +46,16 @@ UNORDERED_AUTO_TEST (example1) {
|
|||||||
BOOST_TEST(r.node.mapped() == "buckle my shoe");
|
BOOST_TEST(r.node.mapped() == "buckle my shoe");
|
||||||
}
|
}
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (example2) {
|
template <template <class Key, class Hash = boost::hash<Key>,
|
||||||
boost::unordered_set<int> src;
|
class Pred = std::equal_to<Key>, class Allocator = std::allocator<Key> >
|
||||||
|
class Set>
|
||||||
|
static void example2()
|
||||||
|
{
|
||||||
|
Set<int> src;
|
||||||
src.insert(1);
|
src.insert(1);
|
||||||
src.insert(3);
|
src.insert(3);
|
||||||
src.insert(5);
|
src.insert(5);
|
||||||
boost::unordered_set<int> dst;
|
Set<int> dst;
|
||||||
dst.insert(2);
|
dst.insert(2);
|
||||||
dst.insert(4);
|
dst.insert(4);
|
||||||
dst.insert(5);
|
dst.insert(5);
|
||||||
@ -84,14 +65,18 @@ UNORDERED_AUTO_TEST (example2) {
|
|||||||
// dst == {1, 2, 3, 4, 5}
|
// dst == {1, 2, 3, 4, 5}
|
||||||
}
|
}
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (example3) {
|
template <template <class Key, class Hash = boost::hash<Key>,
|
||||||
typedef boost::unordered_set<int>::iterator iterator;
|
class Pred = std::equal_to<Key>, class Allocator = std::allocator<Key> >
|
||||||
|
class Set>
|
||||||
|
static void example3()
|
||||||
|
{
|
||||||
|
typedef typename Set<int>::iterator iterator;
|
||||||
|
|
||||||
boost::unordered_set<int> src;
|
Set<int> src;
|
||||||
src.insert(1);
|
src.insert(1);
|
||||||
src.insert(3);
|
src.insert(3);
|
||||||
src.insert(5);
|
src.insert(5);
|
||||||
boost::unordered_set<int> dst;
|
Set<int> dst;
|
||||||
dst.insert(2);
|
dst.insert(2);
|
||||||
dst.insert(4);
|
dst.insert(4);
|
||||||
dst.insert(5);
|
dst.insert(5);
|
||||||
@ -115,17 +100,26 @@ UNORDERED_AUTO_TEST (example3) {
|
|||||||
BOOST_TEST(it == dst2.end());
|
BOOST_TEST(it == dst2.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (failed_insertion_with_hint) {
|
template <template <class Key, class T, class Hash = boost::hash<Key>,
|
||||||
|
class Pred = std::equal_to<Key>,
|
||||||
|
class Allocator = std::allocator<std::pair<Key const, T> > >
|
||||||
|
class Map,
|
||||||
|
template <class Key, class Hash = boost::hash<Key>,
|
||||||
|
class Pred = std::equal_to<Key>, class Allocator = std::allocator<Key> >
|
||||||
|
class Set>
|
||||||
|
static void failed_insertion_with_hint()
|
||||||
|
{
|
||||||
{
|
{
|
||||||
boost::unordered_set<int> src;
|
Set<int> src;
|
||||||
boost::unordered_set<int> dst;
|
Set<int> dst;
|
||||||
src.emplace(10);
|
src.emplace(10);
|
||||||
src.emplace(20);
|
src.emplace(20);
|
||||||
dst.emplace(10);
|
dst.emplace(10);
|
||||||
dst.emplace(20);
|
dst.emplace(20);
|
||||||
|
|
||||||
boost::unordered_set<int>::node_type nh = src.extract(10);
|
typename Set<int>::node_type nh = src.extract(10);
|
||||||
|
|
||||||
|
std::cout << "performing relevant test now" << std::endl;
|
||||||
BOOST_TEST(dst.insert(dst.find(10), boost::move(nh)) == dst.find(10));
|
BOOST_TEST(dst.insert(dst.find(10), boost::move(nh)) == dst.find(10));
|
||||||
BOOST_TEST(nh);
|
BOOST_TEST(nh);
|
||||||
BOOST_TEST(!nh.empty());
|
BOOST_TEST(!nh.empty());
|
||||||
@ -143,14 +137,14 @@ UNORDERED_AUTO_TEST (failed_insertion_with_hint) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
boost::unordered_map<int, int> src;
|
Map<int, int> src;
|
||||||
boost::unordered_map<int, int> dst;
|
Map<int, int> dst;
|
||||||
src.emplace(10, 30);
|
src.emplace(10, 30);
|
||||||
src.emplace(20, 5);
|
src.emplace(20, 5);
|
||||||
dst.emplace(10, 20);
|
dst.emplace(10, 20);
|
||||||
dst.emplace(20, 2);
|
dst.emplace(20, 2);
|
||||||
|
|
||||||
boost::unordered_map<int, int>::node_type nh = src.extract(10);
|
typename Map<int, int>::node_type nh = src.extract(10);
|
||||||
BOOST_TEST(dst.insert(dst.find(10), boost::move(nh)) == dst.find(10));
|
BOOST_TEST(dst.insert(dst.find(10), boost::move(nh)) == dst.find(10));
|
||||||
BOOST_TEST(nh);
|
BOOST_TEST(nh);
|
||||||
BOOST_TEST(!nh.empty());
|
BOOST_TEST(!nh.empty());
|
||||||
@ -172,6 +166,23 @@ UNORDERED_AUTO_TEST (failed_insertion_with_hint) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
|
||||||
|
UNORDERED_AUTO_TEST (examples) {
|
||||||
|
example1<boost::unordered_node_map>();
|
||||||
|
example2<boost::unordered_node_set>();
|
||||||
|
example3<boost::unordered_node_set>();
|
||||||
|
failed_insertion_with_hint<boost::unordered_node_map,
|
||||||
|
boost::unordered_node_set>();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
UNORDERED_AUTO_TEST (examples) {
|
||||||
|
example1<boost::unordered_map>();
|
||||||
|
example2<boost::unordered_set>();
|
||||||
|
example3<boost::unordered_set>();
|
||||||
|
failed_insertion_with_hint<boost::unordered_map, boost::unordered_set>();
|
||||||
|
}
|
||||||
|
|
||||||
template <typename NodeHandle>
|
template <typename NodeHandle>
|
||||||
bool node_handle_compare(
|
bool node_handle_compare(
|
||||||
NodeHandle const& nh, typename NodeHandle::value_type const& x)
|
NodeHandle const& nh, typename NodeHandle::value_type const& x)
|
||||||
|
Reference in New Issue
Block a user