diff --git a/include/boost/unordered/concurrent_flat_map.hpp b/include/boost/unordered/concurrent_flat_map.hpp index aad729f5..fdaead75 100644 --- a/include/boost/unordered/concurrent_flat_map.hpp +++ b/include/boost/unordered/concurrent_flat_map.hpp @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -67,7 +68,6 @@ namespace boost { namespace unordered { namespace detail { - template struct is_invocable : std::is_constructible, @@ -75,60 +75,6 @@ namespace boost { { }; - template struct concurrent_map_types - { - using key_type = Key; - using raw_key_type = typename std::remove_const::type; - using raw_mapped_type = typename std::remove_const::type; - - using init_type = std::pair; - using moved_type = std::pair; - using value_type = std::pair; - - using element_type = value_type; - - static value_type& value_from(element_type& x) { return x; } - - template - static raw_key_type const& extract(std::pair const& kv) - { - return kv.first; - } - - static moved_type move(init_type& x) - { - return {std::move(x.first), std::move(x.second)}; - } - - static moved_type move(element_type& x) - { - // TODO: we probably need to launder here - return {std::move(const_cast(x.first)), - std::move(const_cast(x.second))}; - } - - template - static void construct(A& al, init_type* p, Args&&... args) - { - boost::allocator_construct(al, p, std::forward(args)...); - } - - template - static void construct(A& al, value_type* p, Args&&... args) - { - boost::allocator_construct(al, p, std::forward(args)...); - } - - template static void destroy(A& al, init_type* p) noexcept - { - boost::allocator_destroy(al, p); - } - - template static void destroy(A& al, value_type* p) noexcept - { - boost::allocator_destroy(al, p); - } - }; } // namespace detail template @@ -139,7 +85,7 @@ namespace boost { class Allocator2> friend class concurrent_flat_map; - using type_policy = detail::concurrent_map_types; + using type_policy = detail::foa::flat_map_types; detail::foa::concurrent_table table_; diff --git a/include/boost/unordered/detail/foa/flat_map_types.hpp b/include/boost/unordered/detail/foa/flat_map_types.hpp new file mode 100644 index 00000000..8a4d25f2 --- /dev/null +++ b/include/boost/unordered/detail/foa/flat_map_types.hpp @@ -0,0 +1,73 @@ +// Copyright (C) 2023 Christian Mazakas +// 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) + +#ifndef BOOST_UNORDERED_DETAIL_FOA_FLAT_MAP_TYPES_HPP +#define BOOST_UNORDERED_DETAIL_FOA_FLAT_MAP_TYPES_HPP + +#include + +namespace boost { + namespace unordered { + namespace detail { + namespace foa { + template struct flat_map_types + { + using key_type = Key; + using raw_key_type = typename std::remove_const::type; + using raw_mapped_type = typename std::remove_const::type; + + using init_type = std::pair; + using moved_type = std::pair; + using value_type = std::pair; + + using element_type = value_type; + + static value_type& value_from(element_type& x) { return x; } + + template + static raw_key_type const& extract(std::pair const& kv) + { + return kv.first; + } + + static moved_type move(init_type& x) + { + return {std::move(x.first), std::move(x.second)}; + } + + static moved_type move(element_type& x) + { + // TODO: we probably need to launder here + return {std::move(const_cast(x.first)), + std::move(const_cast(x.second))}; + } + + template + static void construct(A& al, init_type* p, Args&&... args) + { + boost::allocator_construct(al, p, std::forward(args)...); + } + + template + static void construct(A& al, value_type* p, Args&&... args) + { + boost::allocator_construct(al, p, std::forward(args)...); + } + + template static void destroy(A& al, init_type* p) noexcept + { + boost::allocator_destroy(al, p); + } + + template static void destroy(A& al, value_type* p) noexcept + { + boost::allocator_destroy(al, p); + } + }; + } // namespace foa + } // namespace detail + } // namespace unordered +} // namespace boost + +#endif // BOOST_UNORDERED_DETAIL_FOA_FLAT_MAP_TYPES_HPP diff --git a/include/boost/unordered/detail/foa/flat_set_types.hpp b/include/boost/unordered/detail/foa/flat_set_types.hpp new file mode 100644 index 00000000..493cb4fe --- /dev/null +++ b/include/boost/unordered/detail/foa/flat_set_types.hpp @@ -0,0 +1,44 @@ +// Copyright (C) 2023 Christian Mazakas +// 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) + +#ifndef BOOST_UNORDERED_DETAIL_FOA_FLAT_SET_TYPES_HPP +#define BOOST_UNORDERED_DETAIL_FOA_FLAT_SET_TYPES_HPP + +#include + +namespace boost { + namespace unordered { + namespace detail { + namespace foa { + template struct flat_set_types + { + using key_type = Key; + using init_type = Key; + using value_type = Key; + + static Key const& extract(value_type const& key) { return key; } + + using element_type = value_type; + + static Key& value_from(element_type& x) { return x; } + + static element_type&& move(element_type& x) { return std::move(x); } + + template + static void construct(A& al, value_type* p, Args&&... args) + { + boost::allocator_construct(al, p, std::forward(args)...); + } + + template static void destroy(A& al, value_type* p) noexcept + { + boost::allocator_destroy(al, p); + } + }; + } // namespace foa + } // namespace detail + } // namespace unordered +} // namespace boost + +#endif // BOOST_UNORDERED_DETAIL_FOA_FLAT_SET_TYPES_HPP diff --git a/include/boost/unordered/detail/foa/node_map_types.hpp b/include/boost/unordered/detail/foa/node_map_types.hpp new file mode 100644 index 00000000..0853dfe9 --- /dev/null +++ b/include/boost/unordered/detail/foa/node_map_types.hpp @@ -0,0 +1,131 @@ +// Copyright (C) 2023 Christian Mazakas +// 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) + +#ifndef BOOST_UNORDERED_DETAIL_FOA_NODE_MAP_TYPES_HPP +#define BOOST_UNORDERED_DETAIL_FOA_NODE_MAP_TYPES_HPP + +#include +#include + +namespace boost { + namespace unordered { + namespace detail { + namespace foa { + template struct node_map_types + { + using key_type = Key; + using mapped_type = T; + using raw_key_type = typename std::remove_const::type; + using raw_mapped_type = typename std::remove_const::type; + + using init_type = std::pair; + using value_type = std::pair; + using moved_type = std::pair; + + using element_type = foa::element_type; + + static value_type& value_from(element_type const& x) + { + return *(x.p); + } + + template + static raw_key_type const& extract(std::pair const& kv) + { + return kv.first; + } + + static raw_key_type const& extract(element_type const& kv) + { + return kv.p->first; + } + + static element_type&& move(element_type& x) { return std::move(x); } + static moved_type move(init_type& x) + { + return {std::move(x.first), std::move(x.second)}; + } + + static moved_type move(value_type& x) + { + return {std::move(const_cast(x.first)), + std::move(const_cast(x.second))}; + } + + template + static void construct(A&, element_type* p, element_type&& x) noexcept + { + p->p = x.p; + x.p = nullptr; + } + + template + static void construct( + A& al, element_type* p, element_type const& copy) + { + construct(al, p, *copy.p); + } + + template + static void construct(A& al, init_type* p, Args&&... args) + { + boost::allocator_construct(al, p, std::forward(args)...); + } + + template + static void construct(A& al, value_type* p, Args&&... args) + { + boost::allocator_construct(al, p, std::forward(args)...); + } + + template + static void construct(A& al, element_type* p, Args&&... args) + { + p->p = boost::to_address(boost::allocator_allocate(al, 1)); + BOOST_TRY + { + boost::allocator_construct(al, p->p, std::forward(args)...); + } + BOOST_CATCH(...) + { + using pointer_type = typename boost::allocator_pointer::type; + using pointer_traits = boost::pointer_traits; + + boost::allocator_deallocate( + al, pointer_traits::pointer_to(*(p->p)), 1); + BOOST_RETHROW + } + BOOST_CATCH_END + } + + template static void destroy(A& al, value_type* p) noexcept + { + boost::allocator_destroy(al, p); + } + + template static void destroy(A& al, init_type* p) noexcept + { + boost::allocator_destroy(al, p); + } + + template + static void destroy(A& al, element_type* p) noexcept + { + if (p->p) { + using pointer_type = typename boost::allocator_pointer::type; + using pointer_traits = boost::pointer_traits; + + destroy(al, p->p); + boost::allocator_deallocate( + al, pointer_traits::pointer_to(*(p->p)), 1); + } + } + }; + + } // namespace foa + } // namespace detail + } // namespace unordered +} // namespace boost + +#endif // BOOST_UNORDERED_DETAIL_FOA_NODE_MAP_TYPES_HPP diff --git a/include/boost/unordered/detail/foa/node_set_types.hpp b/include/boost/unordered/detail/foa/node_set_types.hpp new file mode 100644 index 00000000..68c20986 --- /dev/null +++ b/include/boost/unordered/detail/foa/node_set_types.hpp @@ -0,0 +1,94 @@ +// Copyright (C) 2023 Christian Mazakas +// 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) + +#ifndef BOOST_UNORDERED_DETAIL_FOA_NODE_SET_TYPES_HPP +#define BOOST_UNORDERED_DETAIL_FOA_NODE_SET_TYPES_HPP + +#include +#include + +namespace boost { + namespace unordered { + namespace detail { + namespace foa { + + template struct node_set_types + { + using key_type = Key; + using init_type = Key; + using value_type = Key; + + static Key const& extract(value_type const& key) { return key; } + + using element_type = foa::element_type; + + static value_type& value_from(element_type const& x) { return *x.p; } + static Key const& extract(element_type const& k) { return *k.p; } + static element_type&& move(element_type& x) { return std::move(x); } + static value_type&& move(value_type& x) { return std::move(x); } + + template + static void construct( + A& al, element_type* p, element_type const& copy) + { + construct(al, p, *copy.p); + } + + template + static void construct( + Allocator&, element_type* p, element_type&& x) noexcept + { + p->p = x.p; + x.p = nullptr; + } + + template + static void construct(A& al, value_type* p, Args&&... args) + { + boost::allocator_construct(al, p, std::forward(args)...); + } + + template + static void construct(A& al, element_type* p, Args&&... args) + { + p->p = boost::to_address(boost::allocator_allocate(al, 1)); + BOOST_TRY + { + boost::allocator_construct(al, p->p, std::forward(args)...); + } + BOOST_CATCH(...) + { + boost::allocator_deallocate(al, + boost::pointer_traits::type>::pointer_to(*p->p), + 1); + BOOST_RETHROW + } + BOOST_CATCH_END + } + + template static void destroy(A& al, value_type* p) noexcept + { + boost::allocator_destroy(al, p); + } + + template + static void destroy(A& al, element_type* p) noexcept + { + if (p->p) { + destroy(al, p->p); + boost::allocator_deallocate(al, + boost::pointer_traits::type>::pointer_to(*(p->p)), + 1); + } + } + }; + + } // namespace foa + } // namespace detail + } // namespace unordered +} // namespace boost + +#endif // BOOST_UNORDERED_DETAIL_FOA_NODE_SET_TYPES_HPP diff --git a/include/boost/unordered/unordered_flat_map.hpp b/include/boost/unordered/unordered_flat_map.hpp index 9597d26f..1012798f 100644 --- a/include/boost/unordered/unordered_flat_map.hpp +++ b/include/boost/unordered/unordered_flat_map.hpp @@ -10,6 +10,7 @@ #pragma once #endif +#include #include #include #include @@ -32,67 +33,10 @@ namespace boost { #pragma warning(disable : 4714) /* marked as __forceinline not inlined */ #endif - namespace detail { - template struct flat_map_types - { - using key_type = Key; - using raw_key_type = typename std::remove_const::type; - using raw_mapped_type = typename std::remove_const::type; - - using init_type = std::pair; - using moved_type = std::pair; - using value_type = std::pair; - - using element_type = value_type; - - static value_type& value_from(element_type& x) { return x; } - - template - static raw_key_type const& extract(std::pair const& kv) - { - return kv.first; - } - - static moved_type move(init_type& x) - { - return {std::move(x.first), std::move(x.second)}; - } - - static moved_type move(element_type& x) - { - // TODO: we probably need to launder here - return {std::move(const_cast(x.first)), - std::move(const_cast(x.second))}; - } - - template - static void construct(A& al, init_type* p, Args&&... args) - { - boost::allocator_construct(al, p, std::forward(args)...); - } - - template - static void construct(A& al, value_type* p, Args&&... args) - { - boost::allocator_construct(al, p, std::forward(args)...); - } - - template static void destroy(A& al, init_type* p) noexcept - { - boost::allocator_destroy(al, p); - } - - template static void destroy(A& al, value_type* p) noexcept - { - boost::allocator_destroy(al, p); - } - }; - } // namespace detail - template class unordered_flat_map { - using map_types = detail::flat_map_types; + using map_types = detail::foa::flat_map_types; using table_type = detail::foa::table - bool friend operator==( - unordered_flat_map const& lhs, + bool friend operator==(unordered_flat_map const& lhs, unordered_flat_map const& rhs); template diff --git a/include/boost/unordered/unordered_flat_set.hpp b/include/boost/unordered/unordered_flat_set.hpp index d81e1082..fc3b5f1b 100644 --- a/include/boost/unordered/unordered_flat_set.hpp +++ b/include/boost/unordered/unordered_flat_set.hpp @@ -10,6 +10,7 @@ #pragma once #endif +#include #include #include #include @@ -30,38 +31,10 @@ namespace boost { #pragma warning(disable : 4714) /* marked as __forceinline not inlined */ #endif - namespace detail { - template struct flat_set_types - { - using key_type = Key; - using init_type = Key; - using value_type = Key; - - static Key const& extract(value_type const& key) { return key; } - - using element_type = value_type; - - static Key& value_from(element_type& x) { return x; } - - static element_type&& move(element_type& x) { return std::move(x); } - - template - static void construct(A& al, value_type* p, Args&&... args) - { - boost::allocator_construct(al, p, std::forward(args)...); - } - - template static void destroy(A& al, value_type* p) noexcept - { - boost::allocator_destroy(al, p); - } - }; - } // namespace detail - template class unordered_flat_set { - using set_types = detail::flat_set_types; + using set_types = detail::foa::flat_set_types; using table_type = detail::foa::table - bool friend operator==( - unordered_flat_set const& lhs, + bool friend operator==(unordered_flat_set const& lhs, unordered_flat_set const& rhs); template diff --git a/include/boost/unordered/unordered_node_map.hpp b/include/boost/unordered/unordered_node_map.hpp index 33e3c7c7..f0ce0974 100644 --- a/include/boost/unordered/unordered_node_map.hpp +++ b/include/boost/unordered/unordered_node_map.hpp @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -35,112 +36,6 @@ namespace boost { #endif namespace detail { - template struct node_map_types - { - using key_type = Key; - using mapped_type = T; - using raw_key_type = typename std::remove_const::type; - using raw_mapped_type = typename std::remove_const::type; - - using init_type = std::pair; - using value_type = std::pair; - using moved_type = std::pair; - - using element_type=foa::element_type; - - static value_type& value_from(element_type const& x) { return *(x.p); } - - template - static raw_key_type const& extract(std::pair const& kv) - { - return kv.first; - } - - static raw_key_type const& extract(element_type const& kv) - { - return kv.p->first; - } - - static element_type&& move(element_type& x) { return std::move(x); } - static moved_type move(init_type& x) - { - return {std::move(x.first), std::move(x.second)}; - } - - static moved_type move(value_type& x) - { - return {std::move(const_cast(x.first)), - std::move(const_cast(x.second))}; - } - - template - static void construct(A&, element_type* p, element_type&& x) noexcept - { - p->p = x.p; - x.p = nullptr; - } - - template - static void construct(A& al, element_type* p, element_type const& copy) - { - construct(al, p, *copy.p); - } - - template - static void construct(A& al, init_type* p, Args&&... args) - { - boost::allocator_construct(al, p, std::forward(args)...); - } - - template - static void construct(A& al, value_type* p, Args&&... args) - { - boost::allocator_construct(al, p, std::forward(args)...); - } - - template - static void construct(A& al, element_type* p, Args&&... args) - { - p->p = boost::to_address(boost::allocator_allocate(al, 1)); - BOOST_TRY - { - boost::allocator_construct(al, p->p, std::forward(args)...); - } - BOOST_CATCH(...) - { - using pointer_type = typename boost::allocator_pointer::type; - using pointer_traits = boost::pointer_traits; - - boost::allocator_deallocate( - al, pointer_traits::pointer_to(*(p->p)), 1); - BOOST_RETHROW - } - BOOST_CATCH_END - } - - template static void destroy(A& al, value_type* p) noexcept - { - boost::allocator_destroy(al, p); - } - - template static void destroy(A& al, init_type* p) noexcept - { - boost::allocator_destroy(al, p); - } - - template static void destroy(A& al, element_type* p) noexcept - { - if (p->p) { - using pointer_type = typename boost::allocator_pointer::type; - using pointer_traits = boost::pointer_traits; - - destroy(al, p->p); - boost::allocator_deallocate( - al, pointer_traits::pointer_to(*(p->p)), 1); - } - } - }; - template struct node_map_handle : public detail::foa::node_handle_base @@ -179,7 +74,7 @@ namespace boost { template class unordered_node_map { - using map_types = detail::node_map_types; + using map_types = detail::foa::node_map_types; using table_type = detail::foa::table - bool friend operator==( - unordered_node_map const& lhs, + bool friend operator==(unordered_node_map const& lhs, unordered_node_map const& rhs); template diff --git a/include/boost/unordered/unordered_node_set.hpp b/include/boost/unordered/unordered_node_set.hpp index 87d8677f..68be4a6e 100644 --- a/include/boost/unordered/unordered_node_set.hpp +++ b/include/boost/unordered/unordered_node_set.hpp @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -34,77 +35,6 @@ namespace boost { #endif namespace detail { - template struct node_set_types - { - using key_type = Key; - using init_type = Key; - using value_type = Key; - - static Key const& extract(value_type const& key) { return key; } - - using element_type=foa::element_type; - - static value_type& value_from(element_type const& x) { return *x.p; } - static Key const& extract(element_type const& k) { return *k.p; } - static element_type&& move(element_type& x) { return std::move(x); } - static value_type&& move(value_type& x) { return std::move(x); } - - template - static void construct(A& al, element_type* p, element_type const& copy) - { - construct(al, p, *copy.p); - } - - template - static void construct( - Allocator&, element_type* p, element_type&& x) noexcept - { - p->p = x.p; - x.p = nullptr; - } - - template - static void construct(A& al, value_type* p, Args&&... args) - { - boost::allocator_construct(al, p, std::forward(args)...); - } - - template - static void construct(A& al, element_type* p, Args&&... args) - { - p->p = boost::to_address(boost::allocator_allocate(al, 1)); - BOOST_TRY - { - boost::allocator_construct(al, p->p, std::forward(args)...); - } - BOOST_CATCH(...) - { - boost::allocator_deallocate(al, - boost::pointer_traits< - typename boost::allocator_pointer::type>::pointer_to(*p->p), - 1); - BOOST_RETHROW - } - BOOST_CATCH_END - } - - template static void destroy(A& al, value_type* p) noexcept - { - boost::allocator_destroy(al, p); - } - - template static void destroy(A& al, element_type* p) noexcept - { - if (p->p) { - destroy(al, p->p); - boost::allocator_deallocate(al, - boost::pointer_traits::type>::pointer_to(*(p->p)), - 1); - } - } - }; - template struct node_set_handle : public detail::foa::node_handle_base @@ -135,7 +65,7 @@ namespace boost { template class unordered_node_set { - using set_types = detail::node_set_types; + using set_types = detail::foa::node_set_types; using table_type = detail::foa::table - bool friend operator==( - unordered_node_set const& lhs, + bool friend operator==(unordered_node_set const& lhs, unordered_node_set const& rhs); template