Add foa-based node containers to node_handle_tests

This commit is contained in:
Christian Mazakas
2023-02-08 15:08:51 -08:00
parent 9636875596
commit b96dd2184f
4 changed files with 252 additions and 43 deletions
+84 -5
View File
@@ -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;
+10 -4
View File
@@ -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
{