mirror of
https://github.com/boostorg/unordered.git
synced 2026-05-04 19:54:18 +02:00
Optimize emplace() for exactly a value_type or init_type argument (#227)
* Add structs to count special member functions * Add failing emplace tests, that will pass after making the optimization * Optimize emplace() to not allocate when we already have a value_type or init_type * Fix newly failing cfoa tests
This commit is contained in:
@@ -28,6 +28,7 @@
|
||||
#include <boost/unordered/detail/foa/tuple_rotate_right.hpp>
|
||||
#include <boost/unordered/detail/serialization_version.hpp>
|
||||
#include <boost/unordered/detail/static_assert.hpp>
|
||||
#include <boost/unordered/detail/type_traits.hpp>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
@@ -682,6 +683,14 @@ public:
|
||||
return construct_and_emplace(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/* Optimization for value_type and init_type, to avoid constructing twice */
|
||||
template<typename Value>
|
||||
BOOST_FORCEINLINE auto emplace(Value&& x)->typename std::enable_if<
|
||||
detail::is_similar_to_any<Value,value_type,init_type>::value,bool>::type
|
||||
{
|
||||
return emplace_impl(std::forward<Value>(x));
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE bool
|
||||
insert(const init_type& x){return emplace_impl(x);}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <boost/core/serialization.hpp>
|
||||
#include <boost/unordered/detail/foa/core.hpp>
|
||||
#include <boost/unordered/detail/serialize_tracked_address.hpp>
|
||||
#include <boost/unordered/detail/type_traits.hpp>
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
@@ -405,6 +406,16 @@ public:
|
||||
return emplace_impl(type_policy::move(x.value()));
|
||||
}
|
||||
|
||||
/* Optimization for value_type and init_type, to avoid constructing twice */
|
||||
template <typename T>
|
||||
BOOST_FORCEINLINE typename std::enable_if<
|
||||
detail::is_similar_to_any<T, value_type, init_type>::value,
|
||||
std::pair<iterator, bool> >::type
|
||||
emplace(T&& x)
|
||||
{
|
||||
return emplace_impl(std::forward<T>(x));
|
||||
}
|
||||
|
||||
template<typename Key,typename... Args>
|
||||
BOOST_FORCEINLINE std::pair<iterator,bool> try_emplace(
|
||||
Key&& x,Args&&... args)
|
||||
|
||||
@@ -147,6 +147,23 @@ namespace boost {
|
||||
!std::is_convertible<Key, const_iterator>::value;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
using remove_cvref_t =
|
||||
typename std::remove_cv<typename std::remove_reference<T>::type>::type;
|
||||
|
||||
template <class T, class U>
|
||||
using is_similar = std::is_same<remove_cvref_t<T>, remove_cvref_t<U> >;
|
||||
|
||||
template <class, class...> struct is_similar_to_any : std::false_type
|
||||
{
|
||||
};
|
||||
template <class T, class U, class... Us>
|
||||
struct is_similar_to_any<T, U, Us...>
|
||||
: std::conditional<is_similar<T, U>::value, is_similar<T, U>,
|
||||
is_similar_to_any<T, Us...> >::type
|
||||
{
|
||||
};
|
||||
|
||||
#if BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES
|
||||
// https://eel.is/c++draft/container.requirements#container.alloc.reqmts-34
|
||||
// https://eel.is/c++draft/container.requirements#unord.req.general-243
|
||||
|
||||
Reference in New Issue
Block a user