3 #include "../utility/aligned_malloc.h"
4 #include "../utility/alignment.h"
5 #include "../utility/assert.h"
6 #include "../utility/empty_base.h"
7 #include "../utility/meta.h"
12 #include <type_traits>
26 template<
typename Alloc>
30 static_assert(detail::has_no_value_type_v<Alloc>,
"Building on top of typed allocators is not allowed. Use allocators without a type");
31 static_assert(detail::has_owns_v<Alloc>,
"The allocator is required to have an 'owns(void*)' method");
51 noexcept(std::is_nothrow_move_constructible_v<node>) :
52 m_Node(std::move(other.m_Node))
54 other.m_Node =
nullptr;
65 noexcept(std::is_nothrow_move_assignable_v<node>)
69 m_Node = std::move(rhs.m_Node);
78 return m_Node == rhs.m_Node;
83 return m_Node != rhs.m_Node;
86 #pragma region Allocation
94 std::is_nothrow_default_constructible_v<node> &&
95 detail::has_nothrow_allocate_v<Alloc> &&
96 (!detail::has_max_size_v<Alloc> || detail::has_nothrow_max_size_v<Alloc>))
102 if constexpr (detail::has_max_size_v<Alloc>)
104 if (n > m_Node->Allocator.max_size())
108 void* p = m_Node->Allocator.allocate(n);
118 p = m_Node->Allocator.allocate(n);
122 m_Node->Allocations++;
134 std::is_nothrow_destructible_v<node> &&
135 detail::has_nothrow_owns_v<Alloc> &&
136 detail::has_nothrow_deallocate_v<Alloc>)
140 node* prev =
nullptr;
144 if (next->Allocator.owns(p))
146 next->Allocator.deallocate(p, n);
150 if (--next->Allocations == 0 && prev)
152 prev->Next = next->Next;
166 #pragma region Construction
174 template<
typename T,
typename... Args>
177 detail::has_nothrow_owns_v<Alloc> &&
178 detail::has_nothrow_construct_v<Alloc, T*, Args...>)
183 if (next->Allocator.owns(p))
185 next->Allocator.construct(p, std::forward<Args>(args)...);
195 ::new(p) T(std::forward<Args>(args)...);
204 typename std::enable_if<detail::has_destroy_v<Alloc, T*>,
void>::type
206 detail::has_nothrow_owns_v<Alloc> &&
207 detail::has_nothrow_destroy_v<Alloc, T*>)
212 if (next->Allocator.owns(p))
214 next->Allocator.destroy(p);
228 #pragma region Utility
234 template<
typename A = Alloc>
235 typename std::enable_if<detail::has_max_size_v<A>,
size_type>::type
239 return m_Node->Allocator.max_size();
248 noexcept(detail::has_nothrow_owns_v<Alloc>)
253 if (next->Allocator.owns(p))
265 noexcept(std::is_nothrow_destructible_v<node>)
275 node* current = next;
277 next = current->Next;
#define KTL_ASSERT(x)
Definition: assert.h:17
An allocator which owns multiple instances of a given sub allocator. When allocating it will attempt ...
Definition: cascading.h:28
void deallocate(void *p, size_type n) noexcept(std::is_nothrow_destructible_v< node > &&detail::has_nothrow_owns_v< Alloc > &&detail::has_nothrow_deallocate_v< Alloc >)
Attempts to deallocate the memory at location p.
Definition: cascading.h:133
std::enable_if< detail::has_destroy_v< Alloc, T * >, void >::type destroy(T *p) noexcept(detail::has_nothrow_owns_v< Alloc > &&detail::has_nothrow_destroy_v< Alloc, T * >)
Destructs an object of T at the given location.
Definition: cascading.h:205
bool operator==(const cascading &rhs) const noexcept
Definition: cascading.h:76
cascading & operator=(cascading &&rhs) noexcept(std::is_nothrow_move_assignable_v< node >)
Definition: cascading.h:64
cascading & operator=(const cascading &)=delete
cascading(const cascading &)=delete
std::enable_if< detail::has_construct_v< Alloc, T *, Args... >, void >::type construct(T *p, Args &&... args) noexcept(detail::has_nothrow_owns_v< Alloc > &&detail::has_nothrow_construct_v< Alloc, T *, Args... >)
Constructs an object of T with the given ...args at the given location.
Definition: cascading.h:176
std::enable_if< detail::has_max_size_v< A >, size_type >::type max_size() const noexcept(detail::has_nothrow_max_size_v< A >)
Returns the maximum size that an allocation can be.
Definition: cascading.h:236
bool owns(void *p) const noexcept(detail::has_nothrow_owns_v< Alloc >)
Returns whether or not the allocator owns the given location in memory.
Definition: cascading.h:247
detail::get_size_type_t< Alloc > size_type
Definition: cascading.h:30
cascading() noexcept
Definition: cascading.h:45
~cascading()
Definition: cascading.h:57
bool operator!=(const cascading &rhs) const noexcept
Definition: cascading.h:81
void * allocate(size_type n) noexcept(std::is_nothrow_default_constructible_v< node > &&detail::has_nothrow_allocate_v< Alloc > &&(!detail::has_max_size_v< Alloc >||detail::has_nothrow_max_size_v< Alloc >))
Attempts to allocate a chunk of memory defined by n.
Definition: cascading.h:93
cascading(cascading &&other) noexcept(std::is_nothrow_move_constructible_v< node >)
Definition: cascading.h:50
#define KTL_EMPTY_BASE
Definition: empty_base.h:6
constexpr bool has_construct_v
Definition: meta.h:41
void aligned_delete(T *p) noexcept(noexcept(p->~T()))
Definition: aligned_malloc.h:99
typename get_size_type< Alloc, void >::type get_size_type_t
Definition: meta.h:31
constexpr size_t ALIGNMENT
Definition: alignment.h:7
constexpr bool has_nothrow_max_size_v
Definition: meta.h:122
Definition: cascading.h:15