6 #ifndef METALL_CONTAINER_FALLBACK_ALLOCATOR_HPP
7 #define METALL_CONTAINER_FALLBACK_ALLOCATOR_HPP
11 #include <type_traits>
20 template <
typename StatefulAllocator>
23 static_assert(!std::is_constructible<StatefulAllocator>::value,
24 "The stateful allocator must not be default constructible");
28 using other_stateful_allocator_type =
typename std::allocator_traits<
29 StatefulAllocator>::template rebind_alloc<T>;
36 typename std::remove_reference<StatefulAllocator>::type>::type;
38 using value_type =
typename stateful_allocator_type::value_type;
39 using pointer =
typename stateful_allocator_type::pointer;
41 using void_pointer =
typename stateful_allocator_type::void_pointer;
43 typename stateful_allocator_type::const_void_pointer;
45 using size_type =
typename stateful_allocator_type::size_type;
48 template <
typename T2>
65 typename stateful_allocator_type2,
67 stateful_allocator_type2>::value,
71 allocator_instance) noexcept
72 : m_stateful_allocator(allocator_instance.get_stateful_allocator()) {}
77 typename stateful_allocator_type2,
79 stateful_allocator_type2>::value,
82 stateful_allocator_type2 allocator_instance) noexcept
83 : m_stateful_allocator(allocator_instance) {}
100 typename stateful_allocator_type2,
102 stateful_allocator_type2>::value,
107 m_stateful_allocator = other.stateful_allocator();
113 typename stateful_allocator_type2,
115 stateful_allocator_type2>::value,
118 const stateful_allocator_type2 &allocator_instance) noexcept {
119 m_stateful_allocator = allocator_instance;
130 typename stateful_allocator_type2,
132 stateful_allocator_type2>::value,
136 m_stateful_allocator = std::move(other.stateful_allocator());
142 typename stateful_allocator_type2,
144 stateful_allocator_type2>::value,
147 stateful_allocator_type2 &&allocator_instance) noexcept {
148 m_stateful_allocator = std::move(allocator_instance);
156 if (priv_stateful_allocator_available()) {
157 return m_stateful_allocator.allocate(n);
159 return priv_fallback_allocate(n);
166 if (priv_stateful_allocator_available()) {
167 m_stateful_allocator.deallocate(ptr, size);
169 priv_fallback_deallocate(ptr);
176 return m_stateful_allocator.max_size();
183 template <
class... Args>
185 if (priv_stateful_allocator_available()) {
186 m_stateful_allocator.construct(ptr, std::forward<Args>(args)...);
188 priv_fallback_construct(ptr, std::forward<Args>(args)...);
195 if (priv_stateful_allocator_available()) {
196 m_stateful_allocator.destroy(ptr);
198 priv_fallback_destroy(ptr);
209 return m_stateful_allocator;
215 return priv_stateful_allocator_available();
222 auto priv_stateful_allocator_available()
const {
223 return !!(m_stateful_allocator.get_pointer_to_manager_kernel());
228 throw std::bad_array_new_length();
231 void *
const addr = std::malloc(n *
sizeof(
value_type));
233 throw std::bad_alloc();
239 void priv_fallback_deallocate(
pointer ptr)
const {
240 std::free(to_raw_pointer(ptr));
243 void priv_fallback_destroy(
pointer ptr)
const { (*ptr).~value_type(); }
245 template <
class... arg_types>
246 void priv_fallback_construct(
const pointer &ptr, arg_types &&...args)
const {
247 ::new ((
void *)to_raw_pointer(ptr))
257 template <
typename stateful_allocator_type>
265 template <
typename stateful_allocator_type>
269 return !(rhd == lhd);