Generalize alloc_cted_insert_type into allocator_constructed and remove the factory function alloc_make_insert_type()

This commit is contained in:
Braden Ganetsky
2024-02-10 11:46:06 -06:00
parent bd5c9fc740
commit 4fbe450a65
4 changed files with 66 additions and 20 deletions

View File

@ -0,0 +1,59 @@
/* Copyright 2024 Braden Ganetsky.
* 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)
*
* See https://www.boost.org/libs/unordered for library home page.
*/
#ifndef BOOST_UNORDERED_DETAIL_ALLOCATOR_CONSTRUCTED_HPP
#define BOOST_UNORDERED_DETAIL_ALLOCATOR_CONSTRUCTED_HPP
#include <boost/core/allocator_traits.hpp>
#include <boost/unordered/detail/opt_storage.hpp>
namespace boost {
namespace unordered {
namespace detail {
struct allocator_policy
{
template <class Allocator, class T, class... Args>
static void construct(Allocator& a, T* p, Args&&... args)
{
boost::allocator_construct(a, p, std::forward<Args>(args)...);
}
template <class Allocator, class T>
static void destroy(Allocator& a, T* p)
{
boost::allocator_destroy(a, p);
}
};
/* constructs a stack-based object with the given policy and allocator */
template <class Allocator, class T, class Policy = allocator_policy>
class allocator_constructed
{
opt_storage<T> storage;
Allocator alloc;
public:
template <class... Args>
allocator_constructed(Allocator const& alloc_, Args&&... args)
: alloc(alloc_)
{
Policy::construct(
alloc, storage.address(), std::forward<Args>(args)...);
}
~allocator_constructed() { Policy::destroy(alloc, storage.address()); }
T& value() { return *storage.address(); }
};
} /* namespace detail */
} /* namespace unordered */
} /* namespace boost */
#endif

View File

@ -1320,7 +1320,7 @@ private:
{
auto lck=shared_access();
auto x=alloc_make_insert_type<type_policy>(
alloc_cted_insert_type<type_policy,Allocator,Args...> x(
this->al(),std::forward<Args>(args)...);
int res=unprotected_norehash_emplace_or_visit(
access_mode,std::forward<F>(f),type_policy::move(x.value()));

View File

@ -22,6 +22,7 @@
#include <boost/core/pointer_traits.hpp>
#include <boost/cstdint.hpp>
#include <boost/predef.h>
#include <boost/unordered/detail/allocator_constructed.hpp>
#include <boost/unordered/detail/narrow_cast.hpp>
#include <boost/unordered/detail/mulx.hpp>
#include <boost/unordered/detail/static_assert.hpp>
@ -1220,31 +1221,17 @@ class alloc_cted_insert_type
emplace_type,typename TypePolicy::element_type
>::type;
alignas(insert_type) unsigned char storage[sizeof(insert_type)];
Allocator al;
using alloc_cted = allocator_constructed<Allocator, insert_type, TypePolicy>;
alloc_cted val;
public:
alloc_cted_insert_type(const Allocator& al_,Args&&... args):al{al_}
alloc_cted_insert_type(const Allocator& al_,Args&&... args):val{al_,std::forward<Args>(args)...}
{
TypePolicy::construct(al,data(),std::forward<Args>(args)...);
}
~alloc_cted_insert_type()
{
TypePolicy::destroy(al,data());
}
insert_type* data(){return reinterpret_cast<insert_type*>(&storage);}
insert_type& value(){return *data();}
insert_type& value(){return val.value();}
};
template<typename TypePolicy,typename Allocator,typename... Args>
alloc_cted_insert_type<TypePolicy,Allocator,Args...>
alloc_make_insert_type(const Allocator& al,Args&&... args)
{
return {al,std::forward<Args>(args)...};
}
/* table_core. The TypePolicy template parameter is used to generate
* instantiations suitable for either maps or sets, and introduces non-standard
* init_type and element_type:

View File

@ -401,7 +401,7 @@ public:
template<typename... Args>
BOOST_FORCEINLINE std::pair<iterator,bool> emplace(Args&&... args)
{
auto x=alloc_make_insert_type<type_policy>(
alloc_cted_insert_type<type_policy,Allocator,Args...> x(
this->al(),std::forward<Args>(args)...);
return emplace_impl(type_policy::move(x.value()));
}