diff --git a/include/boost/unordered/detail/foa.hpp b/include/boost/unordered/detail/foa.hpp index 8b8cfa2e..2441b400 100644 --- a/include/boost/unordered/detail/foa.hpp +++ b/include/boost/unordered/detail/foa.hpp @@ -1060,6 +1060,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: * @@ -1353,12 +1355,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 @@ -1547,6 +1547,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); @@ -1668,12 +1699,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