12 #include "allocator_base.hpp"
13 #include "internal/reallocator.hpp"
14 #include "internal/affix_helper.hpp"
18 #pragma warning(disable : 4345)
22 inline namespace v_100 {
44 template <
class Allocator,
typename Prefix,
typename Sufix = affix_helper::no_affix>
49 constexpr Prefix *inner_to_prefix(
const block &b)
const noexcept
51 return static_cast<Prefix *
>(b.
ptr);
54 constexpr Sufix *inner_to_sufix(
const block &b)
const noexcept
56 return reinterpret_cast<Sufix*
>(
static_cast<char*
>(b.
ptr) + b.
length - sufix_size);
59 constexpr
block to_inner_block(
const block &b)
const noexcept
61 return {
static_cast<char *
>(b.
ptr) - prefix_size, b.
length + prefix_size + sufix_size };
64 constexpr
block to_outer_block(
const block &b)
const noexcept
66 return {
static_cast<char *
>(b.
ptr) + prefix_size, b.
length - prefix_size - sufix_size };
73 static constexpr
bool supports_truncated_deallocation = Allocator::supports_truncated_deallocation;
74 static constexpr
unsigned alignment = Allocator::alignment;
76 using allocator = Allocator;
77 using prefix = Prefix;
80 static constexpr
size_t prefix_size =
83 static constexpr
size_t sufix_size =
86 static constexpr
size_t good_size(
size_t n) {
87 return Allocator::good_size(n);
105 return b ?
reinterpret_cast<Prefix *
>(
static_cast<char*
>(b.
ptr) - prefix_size) :
nullptr;
116 return b ? (
reinterpret_cast<Sufix*
>(
static_cast<char *
>(b.
ptr) + b.
length)) :
nullptr;
135 auto innerMem = allocator_.allocate(prefix_size + n + sufix_size);
137 if (prefix_size > 0) {
138 affix_helper::create_affix_in_place<Prefix>(inner_to_prefix(innerMem), *
this);
140 if (sufix_size > 0) {
141 affix_helper::create_affix_in_place<Sufix>(inner_to_sufix(innerMem), *
this);
143 result = to_outer_block(innerMem);
159 if (prefix_size > 0) {
162 if (sufix_size > 0) {
165 auto innerBlock(to_inner_block(b));
166 allocator_.deallocate(innerBlock);
175 template <
typename U = Allocator>
176 typename std::enable_if<traits::has_owns<U>::value,
bool>::type
179 return b && allocator_.owns(to_inner_block(b));
192 if (internal::is_reallocation_handled_default(*
this, b, n)) {
195 auto innerBlock = to_inner_block(b);
202 if (allocator_.reallocate(innerBlock, n + prefix_size + sufix_size)) {
203 oldSufix.unload(inner_to_sufix(innerBlock));
204 b = to_outer_block(innerBlock);
218 template <
typename U = Allocator>
219 typename std::enable_if<traits::has_expand<U>::value,
bool>::type
228 return static_cast<bool>(b);
232 auto innerBlock = to_inner_block(b);
234 if (allocator_.expand(innerBlock, delta)) {
235 if (sufix_size > 0) {
236 new (inner_to_sufix(innerBlock)) Sufix(*
outer_to_sufix(oldBlock));
238 b = to_outer_block(innerBlock);
253 static constexpr T *prefix(Allocator &,
const block &) noexcept
257 static constexpr T *sufix(Allocator &,
const block &) noexcept
263 template <
class A,
typename Prefix,
typename Sufix,
typename T>
276 using namespace v_100;
std::enable_if< traits::has_owns< U >::value, bool >::type owns(const block &b) const noexcept
block allocate(size_t n) noexcept
size_t length
This describes the length of the reserved bytes.
constexpr size_t round_to_alignment(size_t basis, size_t n) noexcept
bool reallocate(block &b, size_t n) noexcept
void * ptr
This points to the start address of the described memory block.
constexpr Sufix * outer_to_sufix(const block &b) const noexcept
std::enable_if< traits::has_expand< U >::value, bool >::type expand(block &b, size_t delta) noexcept
constexpr Prefix * outer_to_prefix(const block &b) const noexcept
void deallocate(block &b) noexcept