Add transparent insert, show we don't need a strong typedef

This commit is contained in:
Christian Mazakas
2023-01-09 15:45:25 -08:00
parent e3c66a5e82
commit bce898165c

View File

@ -39,61 +39,100 @@ namespace boost {
using init_type = Key; using init_type = Key;
using value_type = Key; using value_type = Key;
struct element_type // struct element_type
{ // {
value_type* p; // value_type* p;
}; // };
static value_type& value_from(element_type x) { return *x.p; } // static value_type& value_from(element_type x) { return *x.p; }
using element_type = value_type*;
static value_type& value_from(element_type x) { return *x; }
static Key const& extract(value_type const& key) { return key; } static Key const& extract(value_type const& key) { return key; }
static Key const& extract(element_type k) { return *k.p; } // static Key const& extract(element_type k) { return *k.p; }
// static element_type&& move(element_type& x) { return std::move(x); }
static Key const& extract(element_type k) { return *k; }
static element_type&& move(element_type& x) { return std::move(x); } static element_type&& move(element_type& x) { return std::move(x); }
// template <class A>
// static void construct(A&, element_type* p, element_type&& x)
// {
// p->p = x.p;
// x.p = nullptr;
// }
template <class A> template <class A>
static void construct(A&, element_type* p, element_type&& x) static void construct(A&, element_type* p, element_type&& x)
{ {
p->p = x.p; *p = x;
x.p = nullptr; x = nullptr;
} }
template <class A> // template <class A>
static void construct(A& al, element_type* p, element_type const& copy) // static void construct(A& al, element_type* p, element_type const& copy)
{ // {
p->p = boost::to_address(boost::allocator_allocate(al, 1)); // p->p = boost::to_address(boost::allocator_allocate(al, 1));
try { // try {
boost::allocator_construct(al, p->p, *copy.p); // boost::allocator_construct(al, p->p, *copy.p);
} catch (...) { // } catch (...) {
boost::allocator_deallocate(al, // boost::allocator_deallocate(al,
boost::pointer_traits< // boost::pointer_traits<
typename boost::allocator_pointer<A>::type>::pointer_to(*p->p), // typename boost::allocator_pointer<A>::type>::pointer_to(*p->p),
1); // 1);
throw; // throw;
} // }
} // }
// template <class A, class... Args>
// static void construct(A& al, element_type* p, Args&&... args)
// {
// p->p = boost::to_address(boost::allocator_allocate(al, 1));
// try {
// boost::allocator_construct(al, p->p, std::forward<Args>(args)...);
// } catch (...) {
// boost::allocator_deallocate(al,
// boost::pointer_traits<
// typename boost::allocator_pointer<A>::type>::pointer_to(*p->p),
// 1);
// throw;
// }
// }
template <class A, class... Args> template <class A, class... Args>
static void construct(A& al, element_type* p, Args&&... args) static void construct(A& al, element_type* p, Args&&... args)
{ {
p->p = boost::to_address(boost::allocator_allocate(al, 1)); *p = boost::to_address(boost::allocator_allocate(al, 1));
try { try {
boost::allocator_construct(al, p->p, std::forward<Args>(args)...); boost::allocator_construct(al, *p, std::forward<Args>(args)...);
} catch (...) { } catch (...) {
boost::allocator_deallocate(al, boost::allocator_deallocate(al,
boost::pointer_traits< boost::pointer_traits<
typename boost::allocator_pointer<A>::type>::pointer_to(*p->p), typename boost::allocator_pointer<A>::type>::pointer_to(**p),
1); 1);
throw; throw;
} }
} }
// template <class A> static void destroy(A& al, element_type* p) noexcept
// {
// if (p->p) {
// boost::allocator_destroy(al, p->p);
// boost::allocator_deallocate(al,
// boost::pointer_traits<
// typename boost::allocator_pointer<A>::type>::pointer_to(*p->p),
// 1);
// }
// }
template <class A> static void destroy(A& al, element_type* p) noexcept template <class A> static void destroy(A& al, element_type* p) noexcept
{ {
if (p->p) { if (p) {
boost::allocator_destroy(al, p->p); boost::allocator_destroy(al, *p);
boost::allocator_deallocate(al, boost::allocator_deallocate(al,
boost::pointer_traits< boost::pointer_traits<
typename boost::allocator_pointer<A>::type>::pointer_to(*p->p), typename boost::allocator_pointer<A>::type>::pointer_to(**p),
1); 1);
} }
} }
@ -103,7 +142,7 @@ namespace boost {
template <class Key, class Hash, class KeyEqual, class Allocator> template <class Key, class Hash, class KeyEqual, class Allocator>
class unordered_node_set class unordered_node_set
{ {
using set_types = detail::node_set_types<Key>; using set_types = detail::flat_set_types<Key>;
using table_type = detail::foa::table<set_types, Hash, KeyEqual, using table_type = detail::foa::table<set_types, Hash, KeyEqual,
typename boost::allocator_rebind<Allocator, typename boost::allocator_rebind<Allocator,
@ -294,6 +333,15 @@ namespace boost {
return table_.insert(std::move(value)); return table_.insert(std::move(value));
} }
template <class K>
BOOST_FORCEINLINE typename std::enable_if<
detail::transparent_non_iterable<K, unordered_node_set>::value,
std::pair<iterator, bool> >::type
insert(K&& k)
{
return table_.try_emplace(std::forward<K>(k));
}
BOOST_FORCEINLINE iterator insert(const_iterator, value_type const& value) BOOST_FORCEINLINE iterator insert(const_iterator, value_type const& value)
{ {
return table_.insert(value).first; return table_.insert(value).first;
@ -304,6 +352,15 @@ namespace boost {
return table_.insert(std::move(value)).first; return table_.insert(std::move(value)).first;
} }
template <class K>
BOOST_FORCEINLINE typename std::enable_if<
detail::transparent_non_iterable<K, unordered_node_set>::value,
iterator>::type
insert(const_iterator, K&& k)
{
return table_.try_emplace(std::forward<K>(k)).first;
}
template <class InputIterator> template <class InputIterator>
void insert(InputIterator first, InputIterator last) void insert(InputIterator first, InputIterator last)
{ {