Update foa table to support immovable types in the case of the node-based maps

This commit is contained in:
Christian Mazakas
2023-01-30 13:31:18 -08:00
parent f1aeb3b099
commit b9fcfeb24e

View File

@ -1386,14 +1386,49 @@ 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)
{ {
using emplace_type = typename std::conditional< /* We dispatch based on whether or not the value_type is constructible from
* an rvalue refernce to the deduced emplace_type. We do this specifically
* for the csae of the node-based containers. To this end, we're able to
* avoid allocating a node when a duplicate element is attempted to be
* inserted. For immovable types, we instead dispatch to the routine that
* unconditionally allocates via `type_policy::construct()`.
*/
return emplace_dispatch(
std::is_constructible< std::is_constructible<
init_type, Args... value_type,
>::value, emplace_type<Args...>&&>{},
init_type, std::forward<Args>(args)...);
value_type }
>::type;
return emplace_impl(emplace_type(std::forward<Args>(args)...)); template<typename... Args>
BOOST_FORCEINLINE std::pair<iterator,bool> emplace_dispatch(
std::true_type,Args&&... args
) {
using emplace_type_t = emplace_type<Args...>;
return emplace_impl(emplace_type_t(std::forward<Args>(args)...));
}
template<typename... Args>
BOOST_FORCEINLINE std::pair<iterator,bool> emplace_dispatch(
std::false_type,Args&&... args
) {
struct guard {
table& t;
element_type& x;
bool destroy;
~guard(){
if(destroy) {
type_policy::destroy(t.al(),&x);
}
}
};
element_type x;
type_policy::construct(al(),&x,std::forward<Args>(args)...);
guard g{*this,x,true};
auto itp=emplace_impl(type_policy::move(x));
g.destroy=!itp.second;
return itp;
} }
template<typename Key,typename... Args> template<typename Key,typename... Args>
@ -1562,6 +1597,15 @@ private:
template<typename,typename,typename,typename> friend class table; template<typename,typename,typename,typename> friend class table;
using arrays_type=table_arrays<element_type,group_type,size_policy>; using arrays_type=table_arrays<element_type,group_type,size_policy>;
template<typename... Args>
using emplace_type = typename std::conditional<
std::is_constructible<
init_type,Args...
>::value,
init_type,
value_type
>::type;
struct clear_on_exit struct clear_on_exit
{ {
~clear_on_exit(){x.clear();} ~clear_on_exit(){x.clear();}