3 #include "../utility/empty_base.h"
4 #include "../utility/meta.h"
18 template<
typename T,
typename Alloc>
22 static_assert(detail::has_no_value_type_v<Alloc>,
"Building on top of typed allocators is not allowed. Use allocators without a type");
23 static_assert(!std::is_const_v<T>,
"Using an allocator of const T is ill-formed");
24 static_assert(!std::is_copy_constructible_v<Alloc> || std::is_nothrow_copy_constructible_v<Alloc>,
"Using a throwing copy constructor is ill-formed");
25 static_assert(!std::is_move_constructible_v<Alloc> || std::is_nothrow_move_constructible_v<Alloc>,
"Using a throwing move constructor is ill-formed");
26 static_assert(!std::is_copy_assignable_v<Alloc> || std::is_nothrow_copy_assignable_v<Alloc>,
"Using throwing copy assignment is ill-formed");
27 static_assert(!std::is_move_assignable_v<Alloc> || std::is_nothrow_move_assignable_v<Alloc>,
"Using throwing move assignment is ill-formed");
29 template<
typename U,
typename A>
52 template<
typename... Args,
53 typename = std::enable_if_t<
54 std::is_constructible_v<Alloc, Args...>>>
56 noexcept(std::is_nothrow_constructible_v<T, Args...>) :
57 m_Alloc(std::forward<Args>(alloc)...) {}
65 noexcept(std::is_nothrow_copy_constructible_v<Alloc>) :
66 m_Alloc(other.m_Alloc) {}
71 m_Alloc(other.m_Alloc) {}
78 m_Alloc(other.m_Alloc) {}
85 noexcept(std::is_nothrow_copy_assignable_v<Alloc>)
87 m_Alloc = rhs.m_Alloc;
92 #pragma region Allocation
99 noexcept(noexcept(m_Alloc.allocate(n)))
110 noexcept(noexcept(m_Alloc.deallocate(p, n)))
112 m_Alloc.deallocate(p,
sizeof(
value_type) * n);
116 #pragma region Construction
124 template<
typename... Args>
127 noexcept(detail::has_nothrow_construct_v<Alloc, value_type*, Args...>)
129 m_Alloc.construct(p, std::forward<Args>(args)...);
137 template<
typename A = Alloc>
138 typename std::enable_if<detail::has_destroy_v<A, value_type*>,
void>::type
140 noexcept(detail::has_nothrow_destroy_v<Alloc, value_type*>)
146 #pragma region Utility
152 template<
typename A = Alloc>
153 typename std::enable_if<detail::has_max_size_v<A>,
size_type>::type
157 return m_Alloc.max_size() /
sizeof(T);
166 template<
typename A = Alloc>
167 typename std::enable_if<detail::has_owns_v<A>,
bool>::type
169 noexcept(detail::has_nothrow_owns_v<A>)
171 return m_Alloc.owns(p);
197 template<
typename T,
typename U,
typename Alloc>
199 noexcept(detail::has_nothrow_equal_v<Alloc>)
201 return lhs.get_allocator() == rhs.get_allocator();
204 template<
typename T,
typename U,
typename Alloc>
206 noexcept(detail::has_nothrow_not_equal_v<Alloc>)
208 return lhs.get_allocator() != rhs.get_allocator();
Wrapper class for making an untyped allocator into a typed allocator.
Definition: type_allocator.h:20
type_allocator(type_allocator &&other) noexcept(std::is_nothrow_copy_constructible_v< Alloc >)
Definition: type_allocator.h:64
type_allocator & operator=(const type_allocator &)=default
detail::get_size_type_t< Alloc > size_type
Definition: type_allocator.h:34
type_allocator(type_allocator< U, Alloc > &&other) noexcept(std::is_nothrow_constructible_v< Alloc, type_allocator< U, Alloc > && >)
Definition: type_allocator.h:76
type_allocator & operator=(type_allocator &&rhs) noexcept(std::is_nothrow_copy_assignable_v< Alloc >)
Definition: type_allocator.h:84
std::false_type is_always_equal
Definition: type_allocator.h:35
std::enable_if< detail::has_construct_v< Alloc, value_type *, Args... >, void >::type construct(value_type *p, Args &&... args) noexcept(detail::has_nothrow_construct_v< Alloc, value_type *, Args... >)
Constructs an object of T with the given ...args at the given location.
Definition: type_allocator.h:126
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 of objects can be.
Definition: type_allocator.h:154
value_type * allocate(size_t n) noexcept(noexcept(m_Alloc.allocate(n)))
Attempts to allocate a chunk of memory defined by n.
Definition: type_allocator.h:98
std::enable_if< detail::has_owns_v< A >, bool >::type owns(value_type *p) const noexcept(detail::has_nothrow_owns_v< A >)
Returns whether or not the allocator owns the given location in memory.
Definition: type_allocator.h:168
type_allocator()=default
Default constructor.
Alloc & get_allocator() noexcept
Returns a reference to the underlying allocator.
Definition: type_allocator.h:179
std::enable_if< detail::has_destroy_v< A, value_type * >, void >::type destroy(value_type *p) noexcept(detail::has_nothrow_destroy_v< Alloc, value_type * >)
Destructs an object of T at the given location.
Definition: type_allocator.h:139
void deallocate(value_type *p, size_t n) noexcept(noexcept(m_Alloc.deallocate(p, n)))
Attempts to deallocate the memory at location p.
Definition: type_allocator.h:109
type_allocator(const type_allocator< U, Alloc > &other) noexcept(std::is_nothrow_constructible_v< Alloc, const type_allocator< U, Alloc > & >)
Definition: type_allocator.h:69
type_allocator(const type_allocator &)=default
const Alloc & get_allocator() const noexcept
Returns a const reference to the underlying allocator.
Definition: type_allocator.h:188
T value_type
Definition: type_allocator.h:33
type_allocator(Args &&... alloc) noexcept(std::is_nothrow_constructible_v< T, Args... >)
Constructor for forwarding any arguments to the underlying allocator.
Definition: type_allocator.h:55
#define KTL_EMPTY_BASE
Definition: empty_base.h:6
constexpr bool has_construct_v
Definition: meta.h:41
typename get_size_type< Alloc, void >::type get_size_type_t
Definition: meta.h:31
constexpr bool has_nothrow_max_size_v
Definition: meta.h:122
Definition: cascading.h:15
bool operator!=(const type_allocator< T, Alloc > &lhs, const type_allocator< U, Alloc > &rhs) noexcept(detail::has_nothrow_not_equal_v< Alloc >)
Definition: type_allocator.h:205
bool operator==(const type_allocator< T, Alloc > &lhs, const type_allocator< U, Alloc > &rhs) noexcept(detail::has_nothrow_equal_v< Alloc >)
Definition: type_allocator.h:198
Definition: type_allocator.h:39
type_allocator< U, Alloc > other
Definition: type_allocator.h:40