forked from boostorg/unordered
Use std::ref instead of copying the function parameter… (#290)
* GHA: revise numerous CI jobs. Fix sanitizer on new kernel
* Use std::ref instead of copying the function parameter in std::initializer_list overloads of insert_{or|and}_[c]visit
* Reimplement detail::is_invocable
* Update docs for std::ref(f) changes
---------
Co-authored-by: sdarwin <samuel.d.darwin@gmail.com>
This commit is contained in:
co-authored by
sdarwin
parent
94ab2f0776
commit
e214ecdbd0
@@ -487,7 +487,7 @@ namespace boost {
|
||||
size_type insert_or_visit(std::initializer_list<value_type> ilist, F f)
|
||||
{
|
||||
BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F)
|
||||
return this->insert_or_visit(ilist.begin(), ilist.end(), f);
|
||||
return this->insert_or_visit(ilist.begin(), ilist.end(), std::ref(f));
|
||||
}
|
||||
|
||||
template <class Ty, class F>
|
||||
@@ -520,7 +520,7 @@ namespace boost {
|
||||
size_type insert_or_cvisit(std::initializer_list<value_type> ilist, F f)
|
||||
{
|
||||
BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F)
|
||||
return this->insert_or_cvisit(ilist.begin(), ilist.end(), f);
|
||||
return this->insert_or_cvisit(ilist.begin(), ilist.end(), std::ref(f));
|
||||
}
|
||||
|
||||
template <class Ty, class F1, class F2>
|
||||
@@ -559,7 +559,8 @@ namespace boost {
|
||||
{
|
||||
BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F1)
|
||||
BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F2)
|
||||
return this->insert_and_visit(ilist.begin(), ilist.end(), f1, f2);
|
||||
return this->insert_and_visit(
|
||||
ilist.begin(), ilist.end(), std::ref(f1), std::ref(f2));
|
||||
}
|
||||
|
||||
template <class Ty, class F1, class F2>
|
||||
@@ -598,7 +599,8 @@ namespace boost {
|
||||
{
|
||||
BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F1)
|
||||
BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F2)
|
||||
return this->insert_and_cvisit(ilist.begin(), ilist.end(), f1, f2);
|
||||
return this->insert_and_cvisit(
|
||||
ilist.begin(), ilist.end(), std::ref(f1), std::ref(f2));
|
||||
}
|
||||
|
||||
template <class... Args> BOOST_FORCEINLINE bool emplace(Args&&... args)
|
||||
|
||||
@@ -478,7 +478,7 @@ namespace boost {
|
||||
size_type insert_or_visit(std::initializer_list<value_type> ilist, F f)
|
||||
{
|
||||
BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F)
|
||||
return this->insert_or_visit(ilist.begin(), ilist.end(), f);
|
||||
return this->insert_or_visit(ilist.begin(), ilist.end(), std::ref(f));
|
||||
}
|
||||
|
||||
template <class F>
|
||||
@@ -520,7 +520,7 @@ namespace boost {
|
||||
size_type insert_or_cvisit(std::initializer_list<value_type> ilist, F f)
|
||||
{
|
||||
BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F)
|
||||
return this->insert_or_cvisit(ilist.begin(), ilist.end(), f);
|
||||
return this->insert_or_cvisit(ilist.begin(), ilist.end(), std::ref(f));
|
||||
}
|
||||
|
||||
template <class F1, class F2>
|
||||
@@ -569,7 +569,8 @@ namespace boost {
|
||||
{
|
||||
BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F1)
|
||||
BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F2)
|
||||
return this->insert_and_visit(ilist.begin(), ilist.end(), f1, f2);
|
||||
return this->insert_and_visit(
|
||||
ilist.begin(), ilist.end(), std::ref(f1), std::ref(f2));
|
||||
}
|
||||
|
||||
template <class F1, class F2>
|
||||
@@ -619,7 +620,8 @@ namespace boost {
|
||||
{
|
||||
BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F1)
|
||||
BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F2)
|
||||
return this->insert_and_cvisit(ilist.begin(), ilist.end(), f1, f2);
|
||||
return this->insert_and_cvisit(
|
||||
ilist.begin(), ilist.end(), std::ref(f1), std::ref(f2));
|
||||
}
|
||||
|
||||
template <class... Args> BOOST_FORCEINLINE bool emplace(Args&&... args)
|
||||
|
||||
@@ -513,7 +513,7 @@ namespace boost {
|
||||
size_type insert_or_visit(std::initializer_list<value_type> ilist, F f)
|
||||
{
|
||||
BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F)
|
||||
return this->insert_or_visit(ilist.begin(), ilist.end(), f);
|
||||
return this->insert_or_visit(ilist.begin(), ilist.end(), std::ref(f));
|
||||
}
|
||||
|
||||
template <class F>
|
||||
@@ -567,7 +567,7 @@ namespace boost {
|
||||
size_type insert_or_cvisit(std::initializer_list<value_type> ilist, F f)
|
||||
{
|
||||
BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F)
|
||||
return this->insert_or_cvisit(ilist.begin(), ilist.end(), f);
|
||||
return this->insert_or_cvisit(ilist.begin(), ilist.end(), std::ref(f));
|
||||
}
|
||||
|
||||
template <class F>
|
||||
@@ -627,7 +627,8 @@ namespace boost {
|
||||
{
|
||||
BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F1)
|
||||
BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F2)
|
||||
return this->insert_and_visit(ilist.begin(), ilist.end(), f1, f2);
|
||||
return this->insert_and_visit(
|
||||
ilist.begin(), ilist.end(), std::ref(f1), std::ref(f2));
|
||||
}
|
||||
|
||||
template <class F1, class F2>
|
||||
@@ -688,7 +689,8 @@ namespace boost {
|
||||
{
|
||||
BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F1)
|
||||
BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F2)
|
||||
return this->insert_and_cvisit(ilist.begin(), ilist.end(), f1, f2);
|
||||
return this->insert_and_cvisit(
|
||||
ilist.begin(), ilist.end(), std::ref(f1), std::ref(f2));
|
||||
}
|
||||
|
||||
template <class F1, class F2>
|
||||
|
||||
@@ -504,7 +504,7 @@ namespace boost {
|
||||
size_type insert_or_visit(std::initializer_list<value_type> ilist, F f)
|
||||
{
|
||||
BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F)
|
||||
return this->insert_or_visit(ilist.begin(), ilist.end(), f);
|
||||
return this->insert_or_visit(ilist.begin(), ilist.end(), std::ref(f));
|
||||
}
|
||||
|
||||
template <class F>
|
||||
@@ -567,7 +567,7 @@ namespace boost {
|
||||
size_type insert_or_cvisit(std::initializer_list<value_type> ilist, F f)
|
||||
{
|
||||
BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F)
|
||||
return this->insert_or_cvisit(ilist.begin(), ilist.end(), f);
|
||||
return this->insert_or_cvisit(ilist.begin(), ilist.end(), std::ref(f));
|
||||
}
|
||||
|
||||
template <class F>
|
||||
@@ -638,7 +638,8 @@ namespace boost {
|
||||
{
|
||||
BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F1)
|
||||
BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F2)
|
||||
return this->insert_and_visit(ilist.begin(), ilist.end(), f1, f2);
|
||||
return this->insert_and_visit(
|
||||
ilist.begin(), ilist.end(), std::ref(f1), std::ref(f2));
|
||||
}
|
||||
|
||||
template <class F1, class F2>
|
||||
@@ -710,7 +711,8 @@ namespace boost {
|
||||
{
|
||||
BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F1)
|
||||
BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F2)
|
||||
return this->insert_and_cvisit(ilist.begin(), ilist.end(), f1, f2);
|
||||
return this->insert_and_cvisit(
|
||||
ilist.begin(), ilist.end(), std::ref(f1), std::ref(f2));
|
||||
}
|
||||
|
||||
template <class F1, class F2>
|
||||
|
||||
@@ -13,10 +13,7 @@
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
#include <boost/unordered/detail/type_traits.hpp>
|
||||
|
||||
#define BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F) \
|
||||
static_assert(boost::unordered::detail::is_invocable<F, value_type&>::value, \
|
||||
@@ -79,13 +76,20 @@
|
||||
namespace boost {
|
||||
namespace unordered {
|
||||
namespace detail {
|
||||
template <class F, class... Args>
|
||||
struct is_invocable
|
||||
: std::is_constructible<std::function<void(Args...)>,
|
||||
std::reference_wrapper<typename std::remove_reference<F>::type> >
|
||||
template <class...> struct is_invocable_helper : std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template <class F, class... Args>
|
||||
struct is_invocable_helper<
|
||||
void_t<decltype(std::declval<F>()(std::declval<Args>()...))>, F,
|
||||
Args...> : std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
template <class F, class... Args>
|
||||
using is_invocable = is_invocable_helper<void, F, Args...>;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace unordered
|
||||
|
||||
Reference in New Issue
Block a user