Add more constructor overloads to support future unordered containers.

This commit is contained in:
Ion Gaztañaga
2018-09-15 01:23:23 +02:00
parent 25a109f8d2
commit ffbf76df00

View File

@@ -52,26 +52,49 @@ namespace boost {
namespace container { namespace container {
namespace dtl { namespace dtl {
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(value_compare) BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(key_compare)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(key_equal)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(hasher)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(predicate_type) BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(predicate_type)
template<class Allocator, class ICont> template<class Allocator, class ICont>
struct node_alloc_holder struct node_alloc_holder
: public allocator_traits<Allocator>::template
portable_rebind_alloc<typename ICont::value_type>::type //NodeAlloc
{ {
//If the intrusive container is an associative container, obtain the predicate, which will //If the intrusive container is an associative container, obtain the predicate, which will
//be of type node_compare<>. If not an associative container value_compare will be a "nat" type. //be of type node_compare<>. If not an associative container val_compare will be a "nat" type.
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
( boost::container::dtl:: ( boost::container::dtl::
, ICont, value_compare, dtl::nat) intrusive_value_compare; , ICont, key_compare, dtl::nat) intrusive_val_compare;
//In that case obtain the value predicate from the node predicate via predicate_type //In that case obtain the value predicate from the node predicate via predicate_type
//if intrusive_value_compare is node_compare<>, nat otherwise //if intrusive_val_compare is node_compare<>, nat otherwise
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
( boost::container::dtl:: ( boost::container::dtl::
, intrusive_value_compare , intrusive_val_compare
, predicate_type, dtl::nat) value_compare; , predicate_type, dtl::nat) val_compare;
//If the intrusive container is a hash container, obtain the predicate, which will
//be of type node_compare<>. If not an associative container val_equal will be a "nat" type.
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
(boost::container::dtl::
, ICont, key_equal, dtl::nat2) intrusive_val_equal;
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
(boost::container::dtl::
, ICont, hasher, dtl::nat3) intrusive_val_hasher;
//In that case obtain the value predicate from the node predicate via predicate_type
//if intrusive_val_compare is node_compare<>, nat otherwise
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
(boost::container::dtl::
, intrusive_val_equal
, predicate_type, dtl::nat2) val_equal;
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
(boost::container::dtl::
, intrusive_val_hasher
, predicate_type, dtl::nat3) val_hasher;
typedef allocator_traits<Allocator> allocator_traits_type; typedef allocator_traits<Allocator> allocator_traits_type;
typedef typename allocator_traits_type::value_type value_type; typedef typename allocator_traits_type::value_type val_type;
typedef ICont intrusive_container; typedef ICont intrusive_container;
typedef typename ICont::value_type Node; typedef typename ICont::value_type Node;
typedef typename allocator_traits_type::template typedef typename allocator_traits_type::template
@@ -99,51 +122,91 @@ struct node_alloc_holder
//Constructors for sequence containers //Constructors for sequence containers
node_alloc_holder() node_alloc_holder()
: members_()
{} {}
explicit node_alloc_holder(const ValAlloc &a) explicit node_alloc_holder(const ValAlloc &a)
: members_(a) : NodeAlloc(a)
{} {}
//Constructors for associative containers //Constructors for associative containers
node_alloc_holder(const value_compare &c, const ValAlloc &a) node_alloc_holder(const val_compare &c, const ValAlloc &a)
: members_(a, c) : NodeAlloc(a), m_icont(typename ICont::key_compare(c))
{}
node_alloc_holder(const val_hasher &hf, const val_equal &eql, const ValAlloc &a)
: NodeAlloc(a)
, m_icont(typename ICont::bucket_traits()
, typename ICont::hasher(hf)
, typename ICont::key_equal(eql))
{}
node_alloc_holder(const val_hasher &hf, const ValAlloc &a)
: NodeAlloc(a)
, m_icont(typename ICont::bucket_traits()
, typename ICont::hasher(hf)
, typename ICont::key_equal())
{}
node_alloc_holder(const val_hasher &hf)
: m_icont(typename ICont::bucket_traits()
, typename ICont::hasher(hf)
, typename ICont::key_equal())
{} {}
explicit node_alloc_holder(const node_alloc_holder &x) explicit node_alloc_holder(const node_alloc_holder &x)
: members_(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc())) : NodeAlloc(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()))
{} {}
node_alloc_holder(const node_alloc_holder &x, const value_compare &c) node_alloc_holder(const node_alloc_holder &x, const val_compare &c)
: members_(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()), c) : NodeAlloc(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()))
, m_icont(typename ICont::key_compare(c))
{}
node_alloc_holder(const node_alloc_holder &x, const val_hasher &hf, const val_equal &eql)
: NodeAlloc(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()))
, m_icont( typename ICont::bucket_traits()
, typename ICont::hasher(hf)
, typename ICont::key_equal(eql))
{}
node_alloc_holder(const val_hasher &hf, const val_equal &eql)
: m_icont(typename ICont::bucket_traits()
, typename ICont::hasher(hf)
, typename ICont::key_equal(eql))
{} {}
explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x) explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x)
: members_(boost::move(x.node_alloc())) : NodeAlloc(boost::move(x.node_alloc()))
{ this->icont().swap(x.icont()); } { this->icont().swap(x.icont()); }
explicit node_alloc_holder(const value_compare &c) explicit node_alloc_holder(const val_compare &c)
: members_(c) : m_icont(typename ICont::key_compare(c))
{} {}
//helpers for move assignments //helpers for move assignments
explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x, const value_compare &c) explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x, const val_compare &c)
: members_(boost::move(x.node_alloc()), c) : NodeAlloc(boost::move(x.node_alloc())), m_icont(typename ICont::key_compare(c))
{ this->icont().swap(x.icont()); } { this->icont().swap(x.icont()); }
explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x, const val_hasher &hf, const val_equal &eql)
: NodeAlloc(boost::move(x.node_alloc()))
, m_icont( typename ICont::bucket_traits()
, typename ICont::hasher(hf)
, typename ICont::key_equal(eql))
{ this->icont().swap(x.icont()); }
void copy_assign_alloc(const node_alloc_holder &x) void copy_assign_alloc(const node_alloc_holder &x)
{ {
dtl::bool_<allocator_traits_type::propagate_on_container_copy_assignment::value> flag; dtl::bool_<allocator_traits_type::propagate_on_container_copy_assignment::value> flag;
dtl::assign_alloc( static_cast<NodeAlloc &>(this->members_) dtl::assign_alloc( static_cast<NodeAlloc &>(*this)
, static_cast<const NodeAlloc &>(x.members_), flag); , static_cast<const NodeAlloc &>(x), flag);
} }
void move_assign_alloc( node_alloc_holder &x) void move_assign_alloc( node_alloc_holder &x)
{ {
dtl::bool_<allocator_traits_type::propagate_on_container_move_assignment::value> flag; dtl::bool_<allocator_traits_type::propagate_on_container_move_assignment::value> flag;
dtl::move_alloc( static_cast<NodeAlloc &>(this->members_) dtl::move_alloc( static_cast<NodeAlloc &>(*this)
, static_cast<NodeAlloc &>(x.members_), flag); , static_cast<NodeAlloc &>(x), flag);
} }
~node_alloc_holder() ~node_alloc_holder()
@@ -358,56 +421,25 @@ struct node_alloc_holder
node_alloc_holder &m_holder; node_alloc_holder &m_holder;
}; };
struct members_holder
: public NodeAlloc
{
private:
members_holder(const members_holder&);
members_holder & operator=(const members_holder&);
public:
members_holder()
: NodeAlloc(), m_icont()
{}
template<class ConvertibleToAlloc>
explicit members_holder(BOOST_FWD_REF(ConvertibleToAlloc) c2alloc)
: NodeAlloc(boost::forward<ConvertibleToAlloc>(c2alloc))
, m_icont()
{}
template<class ConvertibleToAlloc>
members_holder(BOOST_FWD_REF(ConvertibleToAlloc) c2alloc, const value_compare &c)
: NodeAlloc(boost::forward<ConvertibleToAlloc>(c2alloc))
, m_icont(typename ICont::key_compare(c))
{}
explicit members_holder(const value_compare &c)
: NodeAlloc()
, m_icont(typename ICont::key_compare(c))
{}
//The intrusive container
ICont m_icont;
};
ICont &non_const_icont() const ICont &non_const_icont() const
{ return const_cast<ICont&>(this->members_.m_icont); } { return const_cast<ICont&>(this->m_icont); }
NodeAlloc &node_alloc() NodeAlloc &node_alloc()
{ return static_cast<NodeAlloc &>(this->members_); } { return static_cast<NodeAlloc &>(*this); }
const NodeAlloc &node_alloc() const const NodeAlloc &node_alloc() const
{ return static_cast<const NodeAlloc &>(this->members_); } { return static_cast<const NodeAlloc &>(*this); }
members_holder members_;
public: public:
ICont &icont() ICont &icont()
{ return this->members_.m_icont; } { return this->m_icont; }
const ICont &icont() const const ICont &icont() const
{ return this->members_.m_icont; } { return this->m_icont; }
private:
//The intrusive container
ICont m_icont;
}; };
} //namespace dtl { } //namespace dtl {