1// Copyright (C) 2023 Christian Mazakas
2// Distributed under the Boost Software License, Version 1.0. (See accompanying
3// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4
5#ifndef BOOST_UNORDERED_DETAIL_FOA_NODE_SET_TYPES_HPP
6#define BOOST_UNORDERED_DETAIL_FOA_NODE_SET_TYPES_HPP
7
8#include <boost/unordered/detail/foa/element_type.hpp>
9
10#include <boost/core/allocator_access.hpp>
11#include <boost/core/no_exceptions_support.hpp>
12#include <boost/core/pointer_traits.hpp>
13
14namespace boost {
15 namespace unordered {
16 namespace detail {
17 namespace foa {
18
19 template <class Key, class VoidPtr> struct node_set_types
20 {
21 using key_type = Key;
22 using init_type = Key;
23 using value_type = Key;
24
25 static Key const& extract(value_type const& key) { return key; }
26
27 using element_type = foa::element_type<value_type, VoidPtr>;
28
29 static value_type& value_from(element_type const& x) { return *x.p; }
30 static Key const& extract(element_type const& k) { return *k.p; }
31 static element_type&& move(element_type& x) { return std::move(x); }
32 static value_type&& move(value_type& x) { return std::move(x); }
33
34 template <class A>
35 static void construct(
36 A& al, element_type* p, element_type const& copy)
37 {
38 construct(al, p, *copy.p);
39 }
40
41 template <typename Allocator>
42 static void construct(
43 Allocator&, element_type* p, element_type&& x) noexcept
44 {
45 p->p = x.p;
46 x.p = nullptr;
47 }
48
49 template <class A, class... Args>
50 static void construct(A& al, value_type* p, Args&&... args)
51 {
52 boost::allocator_construct(al, p, std::forward<Args>(args)...);
53 }
54
55 template <class A, class... Args>
56 static void construct(A& al, element_type* p, Args&&... args)
57 {
58 p->p = boost::allocator_allocate(al, 1);
59 BOOST_TRY
60 {
61 boost::allocator_construct(
62 al, boost::to_address(p->p), std::forward<Args>(args)...);
63 }
64 BOOST_CATCH(...)
65 {
66 boost::allocator_deallocate(al, p->p, 1);
67 BOOST_RETHROW
68 }
69 BOOST_CATCH_END
70 }
71
72 template <class A> static void destroy(A& al, value_type* p) noexcept
73 {
74 boost::allocator_destroy(al, p);
75 }
76
77 template <class A>
78 static void destroy(A& al, element_type* p) noexcept
79 {
80 if (p->p) {
81 destroy(al, boost::to_address(p->p));
82 boost::allocator_deallocate(al, p->p, 1);
83 }
84 }
85 };
86
87 } // namespace foa
88 } // namespace detail
89 } // namespace unordered
90} // namespace boost
91
92#endif // BOOST_UNORDERED_DETAIL_FOA_NODE_SET_TYPES_HPP
93

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