1// Copyright (C) 2023 Christian Mazakas
2// Copyright (C) 2024 Braden Ganetsky
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6#ifndef BOOST_UNORDERED_DETAIL_FOA_NODE_MAP_TYPES_HPP
7#define BOOST_UNORDERED_DETAIL_FOA_NODE_MAP_TYPES_HPP
8
9#include <boost/unordered/detail/foa/element_type.hpp>
10
11#include <boost/core/allocator_access.hpp>
12#include <boost/core/no_exceptions_support.hpp>
13#include <boost/core/pointer_traits.hpp>
14
15namespace boost {
16 namespace unordered {
17 namespace detail {
18 namespace foa {
19 template <class Key, class T, class VoidPtr> struct node_map_types
20 {
21 using key_type = Key;
22 using mapped_type = T;
23 using raw_key_type = typename std::remove_const<Key>::type;
24 using raw_mapped_type = typename std::remove_const<T>::type;
25
26 using init_type = std::pair<raw_key_type, raw_mapped_type>;
27 using value_type = std::pair<Key const, T>;
28 using moved_type = std::pair<raw_key_type&&, raw_mapped_type&&>;
29
30 using element_type = foa::element_type<value_type, VoidPtr>;
31
32 static value_type& value_from(element_type const& x)
33 {
34 return *(x.p);
35 }
36
37 template <class K, class V>
38 static raw_key_type const& extract(std::pair<K, V> const& kv)
39 {
40 return kv.first;
41 }
42
43 static raw_key_type const& extract(element_type const& kv)
44 {
45 return kv.p->first;
46 }
47
48 static element_type&& move(element_type& x) { return std::move(x); }
49 static moved_type move(init_type& x)
50 {
51 return {std::move(x.first), std::move(x.second)};
52 }
53
54 static moved_type move(value_type& x)
55 {
56 return {std::move(const_cast<raw_key_type&>(x.first)),
57 std::move(const_cast<raw_mapped_type&>(x.second))};
58 }
59
60 template <class A>
61 static void construct(A&, element_type* p, element_type&& x) noexcept
62 {
63 p->p = x.p;
64 x.p = nullptr;
65 }
66
67 template <class A>
68 static void construct(
69 A& al, element_type* p, element_type const& copy)
70 {
71 construct(al, p, *copy.p);
72 }
73
74 template <class A, class... Args>
75 static void construct(A& al, init_type* p, Args&&... args)
76 {
77 boost::allocator_construct(al, p, std::forward<Args>(args)...);
78 }
79
80 template <class A, class... Args>
81 static void construct(A& al, value_type* p, Args&&... args)
82 {
83 boost::allocator_construct(al, p, std::forward<Args>(args)...);
84 }
85
86 template <class A, class... Args>
87 static void construct(A& al, key_type* p, Args&&... args)
88 {
89 boost::allocator_construct(al, p, std::forward<Args>(args)...);
90 }
91
92 template <class A, class... Args>
93 static void construct(A& al, element_type* p, Args&&... args)
94 {
95 p->p = boost::allocator_allocate(al, 1);
96 BOOST_TRY
97 {
98 boost::allocator_construct(
99 al, boost::to_address(p->p), std::forward<Args>(args)...);
100 }
101 BOOST_CATCH(...)
102 {
103 boost::allocator_deallocate(al, p->p, 1);
104 BOOST_RETHROW
105 }
106 BOOST_CATCH_END
107 }
108
109 template <class A> static void destroy(A& al, value_type* p) noexcept
110 {
111 boost::allocator_destroy(al, p);
112 }
113
114 template <class A> static void destroy(A& al, init_type* p) noexcept
115 {
116 boost::allocator_destroy(al, p);
117 }
118
119 template <class A> static void destroy(A& al, key_type* p) noexcept
120 {
121 boost::allocator_destroy(al, p);
122 }
123
124 template <class A>
125 static void destroy(A& al, element_type* p) noexcept
126 {
127 if (p->p) {
128 destroy(al, boost::to_address(p->p));
129 boost::allocator_deallocate(al, p->p, 1);
130 }
131 }
132 };
133
134 } // namespace foa
135 } // namespace detail
136 } // namespace unordered
137} // namespace boost
138
139#endif // BOOST_UNORDERED_DETAIL_FOA_NODE_MAP_TYPES_HPP
140

source code of boost/libs/unordered/include/boost/unordered/detail/foa/node_map_types.hpp