mirror of
https://github.com/boostorg/unordered.git
synced 2025-07-29 19:07:15 +02:00
Add foa-based node containers to node_handle_tests
This commit is contained in:
@ -142,27 +142,57 @@ struct node_handle_base
|
||||
}
|
||||
|
||||
public:
|
||||
constexpr node_handle_base() noexcept = default;
|
||||
constexpr node_handle_base()noexcept=default;
|
||||
|
||||
node_handle_base(node_handle_base&& nh) noexcept
|
||||
{
|
||||
if (!nh.empty()) {
|
||||
if (!nh.empty()){
|
||||
// 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;
|
||||
new(a_)Allocator(std::move(nh.al()));
|
||||
new(x_)element_type(std::move(nh.element()));
|
||||
empty_=false;
|
||||
|
||||
reinterpret_cast<element_type*>(nh.x_)->~element_type();
|
||||
reinterpret_cast<Allocator*>(nh.a_)->~Allocator();
|
||||
nh.empty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
node_handle_base& operator=(node_handle_base&& nh)noexcept
|
||||
{
|
||||
bool const pocma=
|
||||
boost::allocator_propagate_on_container_move_assignment<
|
||||
Allocator>::type::value;
|
||||
|
||||
if(!empty()){
|
||||
type_policy::destroy(al(),reinterpret_cast<element_type*>(x_));
|
||||
reinterpret_cast<element_type*>(x_)->~element_type();
|
||||
if (pocma&&!nh.empty()){al()=std::move(nh.al());}
|
||||
}
|
||||
|
||||
if(!nh.empty()){
|
||||
new(x_)element_type(std::move(nh.element()));
|
||||
if(empty()){new(a_)Allocator(std::move(nh.al()));}
|
||||
empty_=false;
|
||||
|
||||
reinterpret_cast<element_type*>(nh.x_)->~element_type();
|
||||
reinterpret_cast<Allocator*>(nh.a_)->~Allocator();
|
||||
nh.empty_=true;
|
||||
}else if (!empty()){
|
||||
reinterpret_cast<Allocator*>(a_)->~Allocator();
|
||||
empty_=true;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
~node_handle_base()
|
||||
{
|
||||
if(!empty()){
|
||||
type_policy::destroy(al(),reinterpret_cast<element_type*>(x_));
|
||||
reinterpret_cast<element_type*>(x_)->~element_type();
|
||||
reinterpret_cast<Allocator*>(a_)->~Allocator();
|
||||
empty_=true;
|
||||
}
|
||||
@ -171,6 +201,55 @@ struct node_handle_base
|
||||
allocator_type get_allocator()const noexcept{return al();}
|
||||
explicit operator bool()const noexcept{ return !empty();}
|
||||
BOOST_ATTRIBUTE_NODISCARD bool empty()const noexcept{return empty_;}
|
||||
|
||||
void swap(node_handle_base& nh) noexcept(
|
||||
boost::allocator_is_always_equal<Allocator>::type::value||
|
||||
boost::allocator_propagate_on_container_swap<Allocator>::type::value)
|
||||
{
|
||||
using std::swap;
|
||||
|
||||
bool const pocs=
|
||||
boost::allocator_propagate_on_container_swap<Allocator>::type::value;
|
||||
|
||||
if (!empty()&&!nh.empty()){
|
||||
BOOST_ASSERT(pocs || al()==nh.al());
|
||||
|
||||
element().swap(nh.element());
|
||||
|
||||
if(pocs){
|
||||
swap(al(),nh.al());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty()&&nh.empty()){return;}
|
||||
|
||||
if (empty()){
|
||||
new(x_)element_type(std::move(nh.element()));
|
||||
new(a_)Allocator(nh.al());
|
||||
empty_=false;
|
||||
|
||||
reinterpret_cast<element_type*>(nh.x_)->~element_type();
|
||||
reinterpret_cast<Allocator*>(nh.a_)->~Allocator();
|
||||
nh.empty_=true;
|
||||
}else{
|
||||
new(nh.x_)element_type(std::move(element()));
|
||||
new(nh.a_)Allocator(al());
|
||||
nh.empty_=false;
|
||||
|
||||
reinterpret_cast<element_type*>(x_)->~element_type();
|
||||
reinterpret_cast<Allocator*>(a_)->~Allocator();
|
||||
empty_=true;
|
||||
}
|
||||
}
|
||||
|
||||
friend
|
||||
void swap(node_handle_base& lhs,node_handle_base& rhs)
|
||||
noexcept(noexcept(lhs.swap(rhs)))
|
||||
{
|
||||
return lhs.swap(rhs);
|
||||
}
|
||||
};
|
||||
|
||||
static const std::size_t default_bucket_count = 0;
|
||||
|
@ -60,6 +60,10 @@ namespace boost {
|
||||
p = rhs.p;
|
||||
rhs.p = nullptr;
|
||||
}
|
||||
|
||||
void swap(element_type& rhs) noexcept {
|
||||
std::swap(p, rhs.p);
|
||||
}
|
||||
};
|
||||
|
||||
static value_type& value_from(element_type const& x) { return *(x.p); }
|
||||
@ -135,21 +139,23 @@ namespace boost {
|
||||
detail::foa::node_handle_base<NodeMapTypes, Allocator>;
|
||||
|
||||
using base_type::element;
|
||||
using base_type::type_policy;
|
||||
using typename base_type::type_policy;
|
||||
|
||||
template <class Key, class T, class Hash, class Pred, class Alloc>
|
||||
friend class boost::unordered::unordered_node_map;
|
||||
|
||||
public:
|
||||
using base_type::empty;
|
||||
using base_type::swap;
|
||||
|
||||
using key_type = typename NodeMapTypes::key_type;
|
||||
using mapped_type = typename NodeMapTypes::mapped_type;
|
||||
|
||||
public:
|
||||
using base_type::empty;
|
||||
|
||||
constexpr node_map_handle() noexcept = default;
|
||||
node_map_handle(node_map_handle&& nh) noexcept = default;
|
||||
|
||||
node_map_handle& operator=(node_map_handle&&) noexcept = default;
|
||||
|
||||
key_type& key() const
|
||||
{
|
||||
BOOST_ASSERT(!empty());
|
||||
|
@ -56,6 +56,10 @@ namespace boost {
|
||||
p = rhs.p;
|
||||
rhs.p = nullptr;
|
||||
}
|
||||
|
||||
void swap(element_type& rhs) noexcept {
|
||||
std::swap(p, rhs.p);
|
||||
}
|
||||
};
|
||||
|
||||
static value_type& value_from(element_type const& x) { return *x.p; }
|
||||
@ -117,19 +121,20 @@ namespace boost {
|
||||
detail::foa::node_handle_base<NodeSetTypes, Allocator>;
|
||||
|
||||
using base_type::element;
|
||||
using base_type::type_policy;
|
||||
using typename base_type::type_policy;
|
||||
|
||||
template <class Key, class Hash, class Pred, class Alloc>
|
||||
friend class boost::unordered::unordered_node_set;
|
||||
|
||||
public:
|
||||
using value_type = typename NodeSetTypes::value_type;
|
||||
|
||||
public:
|
||||
using base_type::empty;
|
||||
using base_type::swap;
|
||||
|
||||
using value_type = typename NodeSetTypes::value_type;
|
||||
|
||||
constexpr node_set_handle() noexcept = default;
|
||||
node_set_handle(node_set_handle&& nh) noexcept = default;
|
||||
node_set_handle& operator=(node_set_handle&&) noexcept = default;
|
||||
|
||||
value_type& value() const
|
||||
{
|
||||
|
@ -166,23 +166,6 @@ static void 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>
|
||||
bool node_handle_compare(
|
||||
NodeHandle const& nh, typename NodeHandle::value_type const& x)
|
||||
@ -269,20 +252,38 @@ template <typename Container> void node_handle_tests_impl(Container& c)
|
||||
BOOST_TEST(!n4);
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST (node_handle_tests) {
|
||||
boost::unordered_set<int> x1;
|
||||
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 node_handle_tests()
|
||||
{
|
||||
Set<int> x1;
|
||||
x1.emplace(100);
|
||||
x1.emplace(140);
|
||||
x1.emplace(-55);
|
||||
node_handle_tests_impl(x1);
|
||||
|
||||
boost::unordered_map<int, std::string> x2;
|
||||
Map<int, std::string> x2;
|
||||
x2.emplace(10, "ten");
|
||||
x2.emplace(-23, "twenty");
|
||||
x2.emplace(-76, "thirty");
|
||||
node_handle_tests_impl(x2);
|
||||
}
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
|
||||
template <class X> typename X::iterator insert_empty_node(X& x)
|
||||
{
|
||||
typedef typename X::node_type node_type;
|
||||
return x.insert(node_type()).position;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||
typename boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>::iterator
|
||||
insert_empty_node(boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>& c)
|
||||
@ -326,8 +327,10 @@ insert_empty_node(boost::unordered_multiset<T, Hash, KeyEqual, Allocator>& c)
|
||||
return c.insert(node_type());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template <typename Container1, typename Container2>
|
||||
void insert_node_handle_unique(Container1& c1, Container2& c2)
|
||||
static void insert_node_handle_unique(Container1& c1, Container2& c2)
|
||||
{
|
||||
typedef typename Container1::node_type node_type;
|
||||
typedef typename Container1::value_type value_type;
|
||||
@ -368,7 +371,7 @@ void insert_node_handle_unique(Container1& c1, Container2& c2)
|
||||
}
|
||||
|
||||
template <typename Container1, typename Container2>
|
||||
void insert_node_handle_unique2(Container1& c1, Container2& c2)
|
||||
static void insert_node_handle_unique2(Container1& c1, Container2& c2)
|
||||
{
|
||||
typedef typename Container1::node_type node_type;
|
||||
typedef typename Container1::value_type value_type;
|
||||
@ -400,6 +403,130 @@ void insert_node_handle_unique2(Container1& c1, Container2& c2)
|
||||
}
|
||||
}
|
||||
|
||||
struct hash_thing
|
||||
{
|
||||
std::size_t operator()(int x) const
|
||||
{
|
||||
return static_cast<std::size_t>(x * 13 + 5);
|
||||
}
|
||||
};
|
||||
|
||||
#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>();
|
||||
node_handle_tests<boost::unordered_node_map, boost::unordered_node_set>();
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST (insert_node_handle_unique_tests) {
|
||||
{
|
||||
boost::unordered_node_set<int> x1;
|
||||
boost::unordered_node_set<int> x2;
|
||||
x1.emplace(100);
|
||||
x1.emplace(140);
|
||||
x1.emplace(-55);
|
||||
x2.emplace(140);
|
||||
insert_node_handle_unique(x1, x2);
|
||||
BOOST_TEST(x2.size() == 3);
|
||||
}
|
||||
|
||||
{
|
||||
boost::unordered_node_set<int> x1;
|
||||
boost::unordered_node_set<int> x2;
|
||||
x1.emplace(100);
|
||||
x1.emplace(140);
|
||||
x1.emplace(-55);
|
||||
x2.emplace(140);
|
||||
insert_node_handle_unique(x1, x2);
|
||||
BOOST_TEST(x2.size() == 3);
|
||||
}
|
||||
|
||||
{
|
||||
boost::unordered_node_map<int, int, hash_thing> x1;
|
||||
boost::unordered_node_map<int, int> x2;
|
||||
x1.emplace(67, 50);
|
||||
x1.emplace(23, 45);
|
||||
x1.emplace(18, 19);
|
||||
x2.emplace(23, 50);
|
||||
x2.emplace(12, 49);
|
||||
insert_node_handle_unique(x1, x2);
|
||||
BOOST_TEST(x2.size() == 4);
|
||||
}
|
||||
|
||||
{
|
||||
boost::unordered_node_map<int, int, hash_thing> x1;
|
||||
boost::unordered_node_map<int, int> x2;
|
||||
x1.emplace(67, 50);
|
||||
x1.emplace(23, 45);
|
||||
x1.emplace(18, 19);
|
||||
x2.emplace(23, 50);
|
||||
x2.emplace(12, 49);
|
||||
insert_node_handle_unique(x1, x2);
|
||||
BOOST_TEST(x2.size() == 4);
|
||||
}
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST (insert_node_handle_unique_tests2) {
|
||||
{
|
||||
boost::unordered_node_set<int> x1;
|
||||
boost::unordered_node_set<int> x2;
|
||||
x1.emplace(100);
|
||||
x1.emplace(140);
|
||||
x1.emplace(-55);
|
||||
x2.emplace(140);
|
||||
insert_node_handle_unique2(x1, x2);
|
||||
BOOST_TEST(x2.size() == 3);
|
||||
}
|
||||
|
||||
{
|
||||
boost::unordered_node_set<int> x1;
|
||||
boost::unordered_node_set<int> x2;
|
||||
x1.emplace(100);
|
||||
x1.emplace(140);
|
||||
x1.emplace(-55);
|
||||
x2.emplace(140);
|
||||
insert_node_handle_unique2(x1, x2);
|
||||
BOOST_TEST(x2.size() == 3);
|
||||
}
|
||||
|
||||
{
|
||||
boost::unordered_node_map<int, int, hash_thing> x1;
|
||||
boost::unordered_node_map<int, int> x2;
|
||||
x1.emplace(67, 50);
|
||||
x1.emplace(23, 45);
|
||||
x1.emplace(18, 19);
|
||||
x2.emplace(23, 50);
|
||||
x2.emplace(12, 49);
|
||||
insert_node_handle_unique2(x1, x2);
|
||||
BOOST_TEST(x2.size() == 4);
|
||||
}
|
||||
|
||||
{
|
||||
boost::unordered_node_map<int, int, hash_thing> x1;
|
||||
boost::unordered_node_map<int, int> x2;
|
||||
x1.emplace(67, 50);
|
||||
x1.emplace(23, 45);
|
||||
x1.emplace(18, 19);
|
||||
x2.emplace(23, 50);
|
||||
x2.emplace(12, 49);
|
||||
insert_node_handle_unique2(x1, x2);
|
||||
BOOST_TEST(x2.size() == 4);
|
||||
}
|
||||
}
|
||||
|
||||
#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>();
|
||||
node_handle_tests<boost::unordered_map, boost::unordered_set>();
|
||||
}
|
||||
|
||||
template <typename Container1, typename Container2>
|
||||
void insert_node_handle_equiv(Container1& c1, Container2& c2)
|
||||
{
|
||||
@ -427,14 +554,6 @@ void insert_node_handle_equiv(Container1& c1, Container2& c2)
|
||||
}
|
||||
}
|
||||
|
||||
struct hash_thing
|
||||
{
|
||||
std::size_t operator()(int x) const
|
||||
{
|
||||
return static_cast<std::size_t>(x * 13 + 5);
|
||||
}
|
||||
};
|
||||
|
||||
UNORDERED_AUTO_TEST (insert_node_handle_unique_tests) {
|
||||
{
|
||||
boost::unordered_set<int> x1;
|
||||
|
Reference in New Issue
Block a user