3#include "../utility/aligned_malloc.h"
4#include "../utility/alignment.h"
5#include "../utility/empty_base.h"
6#include "../utility/meta.h"
7#include "../utility/source_location.h"
41 template<
typename Alloc,
template<
typename>
typename Atomic>
50 Atomic<detail::get_size_type_t<Alloc>> UseCount;
52 template<
typename... Args,
53 typename = std::enable_if_t<
54 std::is_constructible_v<Alloc, Args...>>>
55 block(Args&&... alloc)
56 noexcept(std::is_nothrow_constructible_v<Alloc, Args...>) :
57 Allocator(std::forward<Args>(alloc)...),
64 template<
typename A = Alloc>
66 noexcept(std::is_nothrow_default_constructible_v<block>) :
67 m_Block(detail::aligned_new<block>(detail::ALIGNMENT)) {}
72 template<
typename... Args,
73 typename = std::enable_if_t<
74 std::is_constructible_v<Alloc, Args...>>>
76 noexcept(std::is_nothrow_constructible_v<block, Args...>) :
77 m_Block(detail::aligned_new<block>(detail::ALIGNMENT, std::forward<Args>(alloc)...)) {}
80 m_Block(other.m_Block)
86 m_Block(other.m_Block)
88 other.m_Block =
nullptr;
97 noexcept(
noexcept(decrement()))
101 m_Block = rhs.m_Block;
109 noexcept(
noexcept(decrement()))
113 m_Block = rhs.m_Block;
115 rhs.m_Block =
nullptr;
123 return m_Block == rhs.m_Block && m_Block->Allocator == rhs.m_Block->Allocator;
129 return m_Block != rhs.m_Block || m_Block->Allocator != rhs.m_Block->Allocator;
132#pragma region Allocation
134 noexcept(detail::has_nothrow_allocate_v<Alloc>)
142 m_Block->Allocator.deallocate(p, n);
146#pragma region Construction
147 template<
typename T,
typename... Args>
152 m_Block->Allocator.construct(p, std::forward<Args>(args)...);
156 typename std::enable_if<detail::has_destroy_v<Alloc, T*>,
void>::type
160 m_Block->Allocator.destroy(p);
164#pragma region Utility
165 template<
typename A = Alloc>
166 typename std::enable_if<detail::has_max_size_v<A>,
size_type>::type
168 noexcept(detail::has_nothrow_max_size_v<A>)
170 return m_Block->Allocator.max_size();
173 template<
typename A = Alloc>
174 typename std::enable_if<detail::has_owns_v<A>,
bool>::type
178 return m_Block->Allocator.owns(p);
184 return m_Block->Allocator;
189 return m_Block->Allocator;
193 void increment() noexcept
195 if (!m_Block)
return;
197 m_Block->UseCount.fetch_add(1, std::memory_order_acq_rel);
201 noexcept(std::is_nothrow_destructible_v<Alloc>)
203 if (!m_Block)
return;
205 if (m_Block->UseCount.fetch_sub(1, std::memory_order_acq_rel) == 1)
notomic() noexcept=default
T fetch_add(T add, std::memory_order) noexcept
Definition shared.h:27
notomic(const notomic &)=delete
T fetch_sub(T add, std::memory_order) noexcept
Definition shared.h:32
notomic(notomic &&)=delete
shared() noexcept(std::is_nothrow_default_constructible_v< block >)
Definition shared.h:65
bool operator!=(const shared &rhs) const noexcept(detail::has_nothrow_not_equal_v< Alloc >)
Definition shared.h:126
shared(shared &&other) noexcept
Definition shared.h:85
shared & operator=(const shared &rhs) noexcept(noexcept(decrement()))
Definition shared.h:96
std::enable_if< detail::has_construct_v< Alloc, T *, Args... >, void >::type construct(T *p, Args &&... args) noexcept(detail::has_nothrow_construct_v< Alloc, T *, Args... >)
Definition shared.h:149
std::enable_if< detail::has_max_size_v< A >, size_type >::type max_size() const noexcept(detail::has_nothrow_max_size_v< A >)
Definition shared.h:167
std::enable_if< detail::has_owns_v< A >, bool >::type owns(void *p) const noexcept(detail::has_nothrow_owns_v< A >)
Definition shared.h:175
~shared()
Definition shared.h:91
bool operator==(const shared &rhs) const noexcept(detail::has_nothrow_equal_v< Alloc >)
Definition shared.h:120
const Alloc & get_allocator() const noexcept
Definition shared.h:187
void deallocate(void *p, size_t n) noexcept(detail::has_nothrow_deallocate_v< Alloc >)
Definition shared.h:139
shared(const shared &other) noexcept
Definition shared.h:79
shared & operator=(shared &&rhs) noexcept(noexcept(decrement()))
Definition shared.h:108
void * allocate(size_t n, const source_location source=KTL_SOURCE()) noexcept(detail::has_nothrow_allocate_v< Alloc >)
Definition shared.h:133
std::enable_if< detail::has_destroy_v< Alloc, T * >, void >::type destroy(T *p) noexcept(detail::has_nothrow_destroy_v< Alloc, T * >)
Definition shared.h:157
detail::get_size_type_t< Alloc > size_type
Definition shared.h:62
Alloc & get_allocator() noexcept
Definition shared.h:182
shared(Args &&... alloc) noexcept(std::is_nothrow_constructible_v< block, Args... >)
Constructor for forwarding any arguments to the underlying allocator.
Definition shared.h:75
#define KTL_EMPTY_BASE
Definition empty_base.h:6
typename get_size_type< Alloc, void >::type get_size_type_t
Definition meta.h:33
constexpr bool has_nothrow_construct_v
Definition meta.h:123
constexpr bool has_construct_v
Definition meta.h:53
void * allocate(Alloc &alloc, size_t n, const source_location source) noexcept(false)
Definition meta.h:161
void aligned_delete(T *p) noexcept(noexcept(p->~T()))
Definition aligned_malloc.h:99
constexpr bool has_no_value_type_v
Definition meta.h:17
Definition cascading.h:16
#define KTL_SOURCE()
Definition source_location.h:11
Definition source_location.h:19