diff --git a/include/boost/unordered/concurrent_flat_map.hpp b/include/boost/unordered/concurrent_flat_map.hpp index 2bea917e..40c2fcae 100644 --- a/include/boost/unordered/concurrent_flat_map.hpp +++ b/include/boost/unordered/concurrent_flat_map.hpp @@ -362,18 +362,20 @@ namespace boost { return table_.emplace(std::forward(args)...); } - template - bool emplace_or_visit(F f, Args&&... args) + template + bool emplace_or_visit(Arg&& arg, Args&&... args) { - BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F) - return table_.emplace_or_visit(f, std::forward(args)...); + //BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F) + return table_.emplace_or_visit( + std::forward(arg), std::forward(args)...); } - template - bool emplace_or_cvisit(F f, Args&&... args) + template + bool emplace_or_cvisit(Arg&& arg, Args&&... args) { - BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) - return table_.emplace_or_cvisit(f, std::forward(args)...); + //BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) + return table_.emplace_or_cvisit( + std::forward(arg), std::forward(args)...); } template @@ -396,50 +398,52 @@ namespace boost { std::forward(k), std::forward(args)...); } - template - bool try_emplace_or_visit(key_type const& k, F f, Args&&... args) + template + bool try_emplace_or_visit(key_type const& k, Arg&& arg, Args&&... args) { - BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F) - return table_.try_emplace_or_visit(k, f, std::forward(args)...); - } - - template - bool try_emplace_or_cvisit(key_type const& k, F f, Args&&... args) - { - BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) - return table_.try_emplace_or_cvisit(k, f, std::forward(args)...); - } - - template - bool try_emplace_or_visit(key_type&& k, F f, Args&&... args) - { - BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F) + //BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F) return table_.try_emplace_or_visit( - std::move(k), f, std::forward(args)...); + k, std::forward(arg), std::forward(args)...); } - template - bool try_emplace_or_cvisit(key_type&& k, F f, Args&&... args) + template + bool try_emplace_or_cvisit(key_type const& k, Arg&& arg, Args&&... args) { - BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) + //BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) return table_.try_emplace_or_cvisit( - std::move(k), f, std::forward(args)...); + k, std::forward(arg), std::forward(args)...); } - template - bool try_emplace_or_visit(K&& k, F f, Args&&... args) + template + bool try_emplace_or_visit(key_type&& k, Arg&& arg, Args&&... args) { - BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F) + //BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F) return table_.try_emplace_or_visit( - std::forward(k), f, std::forward(args)...); + std::move(k), std::forward(arg), std::forward(args)...); } - template - bool try_emplace_or_cvisit(K&& k, F f, Args&&... args) + template + bool try_emplace_or_cvisit(key_type&& k, Arg&& arg, Args&&... args) { - BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) + //BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) return table_.try_emplace_or_cvisit( - std::forward(k), f, std::forward(args)...); + std::move(k), std::forward(arg), std::forward(args)...); + } + + template + bool try_emplace_or_visit(K&& k, Arg&& arg, Args&&... args) + { + //BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F) + return table_.try_emplace_or_visit( + std::forward(k), std::forward(arg), std::forward(args)...); + } + + template + bool try_emplace_or_cvisit(K&& k, Arg&& arg, Args&&... args) + { + //BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) + return table_.try_emplace_or_cvisit( + std::forward(k), std::forward(arg), std::forward(args)...); } size_type erase(key_type const& k) { return table_.erase(k); } diff --git a/include/boost/unordered/detail/foa/concurrent_table.hpp b/include/boost/unordered/detail/foa/concurrent_table.hpp index 2461bbad..4517ae5c 100644 --- a/include/boost/unordered/detail/foa/concurrent_table.hpp +++ b/include/boost/unordered/detail/foa/concurrent_table.hpp @@ -17,13 +17,16 @@ #include #include #include +#include #include #include +#include #include #include #include #include #include +#include #include #if !defined(BOOST_UNORDERED_DISABLE_PARALLEL_ALGORITHMS) @@ -445,34 +448,34 @@ public: try_emplace_args_t{},std::forward(x),std::forward(args)...); } - template - BOOST_FORCEINLINE bool try_emplace_or_visit(Key&& x,F&& f,Args&&... args) + template + BOOST_FORCEINLINE bool try_emplace_or_visit(Key&& x,Args&&... args) { - return emplace_or_visit_impl( - group_exclusive{},std::forward(f), + return emplace_or_visit_flast( + group_exclusive{}, try_emplace_args_t{},std::forward(x),std::forward(args)...); } - template - BOOST_FORCEINLINE bool try_emplace_or_cvisit(Key&& x,F&& f,Args&&... args) + template + BOOST_FORCEINLINE bool try_emplace_or_cvisit(Key&& x,Args&&... args) { - return emplace_or_visit_impl( - group_shared{},std::forward(f), + return emplace_or_visit_flast( + group_shared{}, try_emplace_args_t{},std::forward(x),std::forward(args)...); } - template - BOOST_FORCEINLINE bool emplace_or_visit(F&& f,Args&&... args) + template + BOOST_FORCEINLINE bool emplace_or_visit(Args&&... args) { - return construct_and_emplace_or_visit( - group_exclusive{},std::forward(f),std::forward(args)...); + return construct_and_emplace_or_visit_flast( + group_exclusive{},std::forward(args)...); } - template - BOOST_FORCEINLINE bool emplace_or_cvisit(F&& f,Args&&... args) + template + BOOST_FORCEINLINE bool emplace_or_cvisit(Args&&... args) { - return construct_and_emplace_or_visit( - group_shared{},std::forward(f),std::forward(args)...); + return construct_and_emplace_or_visit_flast( + group_shared{},std::forward(args)...); } template @@ -880,6 +883,30 @@ private: group_shared{},[](const value_type&){},std::forward(args)...); } + struct call_construct_and_emplace_or_visit + { + template + BOOST_FORCEINLINE bool operator()( + concurrent_table* this_,Args&&... args)const + { + return this_->construct_and_emplace_or_visit( + std::forward(args)...); + } + }; + + template + BOOST_FORCEINLINE bool construct_and_emplace_or_visit_flast( + GroupAccessMode access_mode,Args&&... args) + { + return mp11::tuple_apply( + call_construct_and_emplace_or_visit{}, + std::tuple_cat( + std::make_tuple(this,access_mode), + tuple_rotate_right(std::forward_as_tuple(std::forward(args)...)) + ) + ); + } + template BOOST_FORCEINLINE bool construct_and_emplace_or_visit( GroupAccessMode access_mode,F&& f,Args&&... args) @@ -914,6 +941,29 @@ private: access_mode,std::forward(f),std::forward(args)...); } + struct call_emplace_or_visit_impl + { + template + BOOST_FORCEINLINE bool operator()( + concurrent_table* this_,Args&&... args)const + { + return this_->emplace_or_visit_impl(std::forward(args)...); + } + }; + + template + BOOST_FORCEINLINE bool emplace_or_visit_flast( + GroupAccessMode access_mode,Args&&... args) + { + return mp11::tuple_apply( + call_emplace_or_visit_impl{}, + std::tuple_cat( + std::make_tuple(this,access_mode), + tuple_rotate_right(std::forward_as_tuple(std::forward(args)...)) + ) + ); + } + template BOOST_FORCEINLINE bool emplace_or_visit_impl( GroupAccessMode access_mode,F&& f,Args&&... args) diff --git a/include/boost/unordered/detail/foa/tuple_rotate_right.hpp b/include/boost/unordered/detail/foa/tuple_rotate_right.hpp new file mode 100644 index 00000000..c63a7fb5 --- /dev/null +++ b/include/boost/unordered/detail/foa/tuple_rotate_right.hpp @@ -0,0 +1,47 @@ +/* Copyright 2023 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See https://www.boost.org/libs/unordered for library home page. + */ + +#ifndef BOOST_UNORDERED_DETAIL_FOA_TUPLE_ROTATE_RIGHT_HPP +#define BOOST_UNORDERED_DETAIL_FOA_TUPLE_ROTATE_RIGHT_HPP + +#include +#include +#include + +namespace boost{ +namespace unordered{ +namespace detail{ +namespace foa{ + +template +auto tuple_rotate_right_aux(mp11::index_sequence,Tuple&& x) + ->std::tuple(std::forward(x)))... + > +{ + return { + std::get<(Is+sizeof...(Is)-1)%sizeof...(Is)>(std::forward(x))...}; +} + +template +auto tuple_rotate_right(Tuple&& x) + ->decltype(tuple_rotate_right_aux( + mp11::make_index_sequence::value>{}, + std::forward(x))) +{ + return tuple_rotate_right_aux( + mp11::make_index_sequence::value>{}, + std::forward(x)); +} + +} /* namespace foa */ +} /* namespace detail */ +} /* namespace unordered */ +} /* namespace boost */ + +#endif