6 #ifndef METALL_CONTAINER_FALLBACK_ALLOCATOR_HPP
7 #define METALL_CONTAINER_FALLBACK_ALLOCATOR_HPP
11 #include <type_traits>
20 template <
typename stateful_allocator>
23 static_assert(!std::is_constructible<stateful_allocator>::value,
24 "The stateful allocator must not be default constructible");
28 using other_stateful_allocatorator_type =
typename std::allocator_traits<
29 stateful_allocator>::template rebind_alloc<T>;
36 typename std::remove_reference<stateful_allocator>::type>::type;
38 using value_type =
typename stateful_allocatorator_type::value_type;
39 using pointer =
typename stateful_allocatorator_type::pointer;
40 using const_pointer =
typename stateful_allocatorator_type::const_pointer;
41 using void_pointer =
typename stateful_allocatorator_type::void_pointer;
43 typename stateful_allocatorator_type::const_void_pointer;
45 using size_type =
typename stateful_allocatorator_type::size_type;
48 template <
typename T2>
65 template <
typename stateful_allocatorator_type2,
67 std::is_constructible<stateful_allocator,
68 stateful_allocatorator_type2>::value,
72 allocator_instance) noexcept
73 : m_stateful_allocatorator(allocator_instance.stateful_allocatorator()) {}
77 template <
typename stateful_allocatorator_type2,
79 std::is_constructible<stateful_allocator,
80 stateful_allocatorator_type2>::value,
83 stateful_allocatorator_type2 allocator_instance) noexcept
84 : m_stateful_allocatorator(allocator_instance) {}
100 template <
typename stateful_allocatorator_type2,
102 std::is_constructible<stateful_allocator,
103 stateful_allocatorator_type2>::value,
108 m_stateful_allocatorator = other.stateful_allocatorator();
113 template <
typename stateful_allocatorator_type2,
115 std::is_constructible<stateful_allocator,
116 stateful_allocatorator_type2>::value,
119 const stateful_allocatorator_type2 &allocator_instance) noexcept {
120 m_stateful_allocatorator = allocator_instance;
130 template <
typename stateful_allocatorator_type2,
132 std::is_constructible<stateful_allocator,
133 stateful_allocatorator_type2>::value,
138 m_stateful_allocatorator = std::move(other.stateful_allocatorator());
143 template <
typename stateful_allocatorator_type2,
145 std::is_constructible<stateful_allocator,
146 stateful_allocatorator_type2>::value,
149 stateful_allocatorator_type2 &&allocator_instance) noexcept {
150 m_stateful_allocatorator = std::move(allocator_instance);
158 if (priv_stateful_allocatorator_available()) {
159 return m_stateful_allocatorator.allocate(n);
161 return priv_fallback_allocate(n);
168 if (priv_stateful_allocatorator_available()) {
169 m_stateful_allocatorator.deallocate(ptr, size);
171 priv_fallback_deallocate(ptr);
178 return m_stateful_allocatorator.max_size();
185 template <
class... Args>
187 if (priv_stateful_allocatorator_available()) {
188 m_stateful_allocatorator.construct(ptr, std::forward<Args>(args)...);
190 priv_fallback_construct(ptr, std::forward<Args>(args)...);
197 if (priv_stateful_allocatorator_available()) {
198 m_stateful_allocatorator.destroy(ptr);
200 priv_fallback_destroy(ptr);
206 return m_stateful_allocatorator;
210 return m_stateful_allocatorator;
217 auto priv_stateful_allocatorator_available()
const {
218 return !!(m_stateful_allocatorator.get_pointer_to_manager_kernel());
223 throw std::bad_array_new_length();
226 void *
const addr = std::malloc(n *
sizeof(
value_type));
228 throw std::bad_alloc();
234 void priv_fallback_deallocate(
pointer ptr)
const {
235 std::free(to_raw_pointer(ptr));
238 void priv_fallback_destroy(
pointer ptr)
const { (*ptr).~value_type(); }
240 template <
class... arg_types>
241 void priv_fallback_construct(
const pointer &ptr, arg_types &&...args)
const {
242 ::new ((
void *)to_raw_pointer(ptr))
252 template <
typename stateful_allocatorator_type>
260 template <
typename stateful_allocatorator_type>
264 return !(rhd == lhd);