From 4ed301df974e9d6c2ef741116fbb47ddcc9af9b5 Mon Sep 17 00:00:00 2001 From: joaquintides Date: Mon, 13 Mar 2023 17:50:03 +0100 Subject: [PATCH] refactored insert_type creation in emplace --- include/boost/unordered/detail/foa/core.hpp | 55 ++++++++++++++------ include/boost/unordered/detail/foa/table.hpp | 22 ++------ 2 files changed, 42 insertions(+), 35 deletions(-) diff --git a/include/boost/unordered/detail/foa/core.hpp b/include/boost/unordered/detail/foa/core.hpp index e6e3fd1c..cf4fe168 100644 --- a/include/boost/unordered/detail/foa/core.hpp +++ b/include/boost/unordered/detail/foa/core.hpp @@ -1049,14 +1049,45 @@ struct table_locator struct try_emplace_args_t{}; -template -union uninitialized_storage +template +class alloc_cted_insert_type { - T t_; - uninitialized_storage(){} - ~uninitialized_storage(){} + using emplace_type=typename std::conditional< + std::is_constructible::value, + typename TypePolicy::init_type, + typename TypePolicy::value_type + >::type; + + using insert_type=typename std::conditional< + std::is_constructible::value, + emplace_type,typename TypePolicy::element_type + >::type; + + Allocator al; + alignas(insert_type) unsigned char storage[sizeof(insert_type)]; + +public: + alloc_cted_insert_type(const Allocator& al_,Args&&... args):al{al_} + { + TypePolicy::construct(al,data(),std::forward(args)...); + } + + ~alloc_cted_insert_type() + { + TypePolicy::destroy(al,data()); + } + + insert_type* data(){return reinterpret_cast(&storage);} + insert_type& value(){return *data();} }; +template +alloc_cted_insert_type +alloc_make_insert_type(const Allocator& al,Args&&... args) +{ + return {al,std::forward(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: @@ -1421,14 +1452,6 @@ public: table_core& x; }; - template - struct destroy_on_exit - { - Allocator &a; - T *p; - ~destroy_on_exit(){type_policy::destroy(a,p);}; - }; - Hash& h(){return hash_base::get();} const Hash& h()const{return hash_base::get();} Pred& pred(){return pred_base::get();} @@ -1752,10 +1775,10 @@ private: * that average probe length won't increase unboundedly in repeated * insert/erase cycles (drift). */ - auto ov=group_type::maybe_caused_overflow(pc); - ml-=ov; + bool ofw=group_type::maybe_caused_overflow(pc); group_type::reset(pc); - available+=!ov; + ml-=ofw; + available+=!ofw; } void recover_slot(group_type* pg,std::size_t pos) diff --git a/include/boost/unordered/detail/foa/table.hpp b/include/boost/unordered/detail/foa/table.hpp index 96006dcc..5012906f 100644 --- a/include/boost/unordered/detail/foa/table.hpp +++ b/include/boost/unordered/detail/foa/table.hpp @@ -297,25 +297,9 @@ public: template BOOST_FORCEINLINE std::pair emplace(Args&&... args) { - using emplace_type=typename std::conditional< - std::is_constructible::value, - init_type, - value_type - >::type; - - using insert_type=typename std::conditional< - std::is_constructible< - value_type,emplace_type>::value, - emplace_type,element_type - >::type; - - uninitialized_storage s; - auto *p=std::addressof(s.t_); - - type_policy::construct(this->al(),p,std::forward(args)...); - - typename super::template destroy_on_exit guard{this->al(),p}; - return emplace_impl(type_policy::move(*p)); + auto x=alloc_make_insert_type( + this->al(),std::forward(args)...); + return emplace_impl(type_policy::move(x.value())); } template