mirror of
https://github.com/boostorg/unordered.git
synced 2025-07-30 11:27:15 +02:00
Generalize alloc_cted_insert_type into allocator_constructed and remove the factory function alloc_make_insert_type()
This commit is contained in:
59
include/boost/unordered/detail/allocator_constructed.hpp
Normal file
59
include/boost/unordered/detail/allocator_constructed.hpp
Normal 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
|
@ -1320,7 +1320,7 @@ private:
|
|||||||
{
|
{
|
||||||
auto lck=shared_access();
|
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)...);
|
this->al(),std::forward<Args>(args)...);
|
||||||
int res=unprotected_norehash_emplace_or_visit(
|
int res=unprotected_norehash_emplace_or_visit(
|
||||||
access_mode,std::forward<F>(f),type_policy::move(x.value()));
|
access_mode,std::forward<F>(f),type_policy::move(x.value()));
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <boost/core/pointer_traits.hpp>
|
#include <boost/core/pointer_traits.hpp>
|
||||||
#include <boost/cstdint.hpp>
|
#include <boost/cstdint.hpp>
|
||||||
#include <boost/predef.h>
|
#include <boost/predef.h>
|
||||||
|
#include <boost/unordered/detail/allocator_constructed.hpp>
|
||||||
#include <boost/unordered/detail/narrow_cast.hpp>
|
#include <boost/unordered/detail/narrow_cast.hpp>
|
||||||
#include <boost/unordered/detail/mulx.hpp>
|
#include <boost/unordered/detail/mulx.hpp>
|
||||||
#include <boost/unordered/detail/static_assert.hpp>
|
#include <boost/unordered/detail/static_assert.hpp>
|
||||||
@ -1220,31 +1221,17 @@ class alloc_cted_insert_type
|
|||||||
emplace_type,typename TypePolicy::element_type
|
emplace_type,typename TypePolicy::element_type
|
||||||
>::type;
|
>::type;
|
||||||
|
|
||||||
alignas(insert_type) unsigned char storage[sizeof(insert_type)];
|
using alloc_cted = allocator_constructed<Allocator, insert_type, TypePolicy>;
|
||||||
Allocator al;
|
alloc_cted val;
|
||||||
|
|
||||||
public:
|
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()
|
insert_type& value(){return val.value();}
|
||||||
{
|
|
||||||
TypePolicy::destroy(al,data());
|
|
||||||
}
|
|
||||||
|
|
||||||
insert_type* data(){return reinterpret_cast<insert_type*>(&storage);}
|
|
||||||
insert_type& value(){return *data();}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
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
|
/* table_core. The TypePolicy template parameter is used to generate
|
||||||
* instantiations suitable for either maps or sets, and introduces non-standard
|
* instantiations suitable for either maps or sets, and introduces non-standard
|
||||||
* init_type and element_type:
|
* init_type and element_type:
|
||||||
|
@ -401,7 +401,7 @@ public:
|
|||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
BOOST_FORCEINLINE std::pair<iterator,bool> emplace(Args&&... 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)...);
|
this->al(),std::forward<Args>(args)...);
|
||||||
return emplace_impl(type_policy::move(x.value()));
|
return emplace_impl(type_policy::move(x.value()));
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user