From 5eda445db0f8ed53f29cedbf4945e2ac555bc940 Mon Sep 17 00:00:00 2001 From: joaquintides Date: Sun, 11 Dec 2022 18:49:21 +0100 Subject: [PATCH] optimized try_emplace and extended it for future use in boost::unordered_flat_set heterogeneous insert --- include/boost/unordered/detail/foa.hpp | 48 +++++++++++++++++++++----- 1 file changed, 39 insertions(+), 9 deletions(-) diff --git a/include/boost/unordered/detail/foa.hpp b/include/boost/unordered/detail/foa.hpp index 734493c2..0ef15ef1 100644 --- a/include/boost/unordered/detail/foa.hpp +++ b/include/boost/unordered/detail/foa.hpp @@ -1023,6 +1023,8 @@ inline void prefetch(const void* p) #endif } +struct try_emplace_args_t{}; + #if defined(BOOST_GCC) /* GCC's -Wshadow triggers at scenarios like this: * @@ -1316,12 +1318,10 @@ public: template BOOST_FORCEINLINE std::pair try_emplace( - Key&& k,Args&&... args) + Key&& x,Args&&... args) { return emplace_impl( - std::piecewise_construct, - std::forward_as_tuple(std::forward(k)), - std::forward_as_tuple(std::forward(args)...)); + try_emplace_args_t{},std::forward(x),std::forward(args)...); } BOOST_FORCEINLINE std::pair @@ -1510,6 +1510,37 @@ private: alloc_traits::construct(al(),p,std::forward(args)...); } + template + void construct_element(value_type* p,try_emplace_args_t,Args&&... args) + { + construct_element_from_try_emplace_args( + p, + std::integral_constant::value>{}, + std::forward(args)...); + } + + template + void construct_element_from_try_emplace_args( + value_type* p,std::false_type,Key&& x,Args&&... args) + { + alloc_traits::construct( + al(),p, + std::piecewise_construct, + std::forward_as_tuple(std::forward(x)), + std::forward_as_tuple(std::forward(args)...)); + } + + /* This overload allows boost::unordered_flat_set to internally use + * try_emplace to implement heterogeneous insert (P2363). + */ + + template + void construct_element_from_try_emplace_args( + value_type* p,std::true_type,Key&& x) + { + alloc_traits::construct(al(),p,std::forward(x)); + } + void destroy_element(value_type* p)noexcept { alloc_traits::destroy(al(),p); @@ -1631,12 +1662,11 @@ private: return type_policy::extract(x); } - template - static inline auto key_from( - std::piecewise_construct_t,const Arg1& k,const Arg2&) - ->decltype(std::get<0>(k)) + template + static inline const Key& key_from( + try_emplace_args_t,const Key& x,const Args&...) { - return std::get<0>(k); + return x; } template