10#ifndef MSGPACK_CPP11_ZONE_HPP
11#define MSGPACK_CPP11_ZONE_HPP
32 finalizer(
void (*func)(
void*),
void* data):m_func(func), m_data(data) {}
33 void operator()() { m_func(m_data); }
34 void (*m_func)(
void*);
37 struct finalizer_array {
40 finalizer* fin = m_tail;
41 for(; fin != m_array; --fin) (*(fin-1))();
51 void push(
void (*func)(
void* data),
void* data)
53 finalizer* fin = m_tail;
56 push_expand(func, data);
65 void push_expand(
void (*func)(
void*),
void* data) {
66 const size_t nused =
static_cast<size_t>(m_end - m_array);
69 nnext = (
sizeof(finalizer) < 72/2) ?
70 72 /
sizeof(finalizer) : 8;
75 static_cast<finalizer*
>(::realloc(m_array,
sizeof(finalizer) * nnext));
77 throw std::bad_alloc();
82 new (m_tail) finalizer(func, data);
86 finalizer_array(finalizer_array&& other) noexcept
87 :m_tail(other.m_tail), m_end(other.m_end), m_array(other.m_array)
93 finalizer_array& operator=(finalizer_array&& other)
noexcept
95 this->~finalizer_array();
96 new (
this) finalizer_array(std::move(other));
105 finalizer_array(
const finalizer_array&);
106 finalizer_array& operator=(
const finalizer_array&);
112 chunk_list(
size_t chunk_size)
114 chunk* c =
static_cast<chunk*
>(::malloc(
sizeof(chunk) + chunk_size));
116 throw std::bad_alloc();
121 m_ptr =
reinterpret_cast<char*
>(c) +
sizeof(chunk);
128 chunk* n = c->m_next;
133 void clear(
size_t chunk_size)
137 chunk* n = c->m_next;
148 m_ptr =
reinterpret_cast<char*
>(m_head) +
sizeof(chunk);
150 chunk_list(chunk_list&& other) noexcept
151 :m_free(other.m_free), m_ptr(other.m_ptr), m_head(other.m_head)
155 chunk_list& operator=(chunk_list&& other)
noexcept
158 new (
this) chunk_list(std::move(other));
166 chunk_list(
const chunk_list&);
167 chunk_list& operator=(
const chunk_list&);
170 chunk_list m_chunk_list;
171 finalizer_array m_finalizer_array;
182 template <
typename T>
189 static void*
operator new(std::size_t size)
191 void* p = ::malloc(size);
192 if (!p)
throw std::bad_alloc();
195 static void operator delete(
void *p)
noexcept
199 static void*
operator new(std::size_t ,
void* mem)
noexcept
203 static void operator delete(
void * ,
void* )
noexcept
207 template <
typename T,
typename... Args>
216 void undo_allocate(
size_t size);
218 template <
typename T>
219 static void object_destruct(
void* obj);
221 template <
typename T>
222 static void object_delete(
void* obj);
224 static char* get_aligned(
char* ptr,
size_t align);
226 char* allocate_expand(
size_t size);
229inline zone::zone(
size_t chunk_size):m_chunk_size(chunk_size), m_chunk_list(m_chunk_size)
233inline char* zone::get_aligned(
char* ptr,
size_t align)
237 reinterpret_cast<char*
>(
238 reinterpret_cast<uintptr_t
>(ptr + (align - 1)) & ~static_cast<uintptr_t>(align - 1)
244 char* aligned = get_aligned(m_chunk_list.m_ptr, align);
245 size_t adjusted_size =
size +
static_cast<size_t>(aligned - m_chunk_list.m_ptr);
246 if (m_chunk_list.m_free < adjusted_size) {
247 size_t enough_size =
size + align - 1;
248 char* ptr = allocate_expand(enough_size);
249 aligned = get_aligned(ptr, align);
250 adjusted_size =
size +
static_cast<size_t>(aligned - m_chunk_list.m_ptr);
252 m_chunk_list.m_free -= adjusted_size;
253 m_chunk_list.m_ptr += adjusted_size;
259 char* ptr = m_chunk_list.m_ptr;
260 if(m_chunk_list.m_free < size) {
261 ptr = allocate_expand(size);
263 m_chunk_list.m_free -=
size;
264 m_chunk_list.m_ptr +=
size;
269inline char* zone::allocate_expand(
size_t size)
271 chunk_list*
const cl = &m_chunk_list;
273 size_t sz = m_chunk_size;
276 size_t tmp_sz = sz * 2;
284 chunk* c =
static_cast<chunk*
>(::malloc(
sizeof(chunk) + sz));
285 if (!c)
throw std::bad_alloc();
287 char* ptr =
reinterpret_cast<char*
>(c) +
sizeof(chunk);
289 c->m_next = cl->m_head;
299 m_finalizer_array.push(func, data);
305 m_finalizer_array.push(&zone::object_delete<T>, obj.release());
310 m_finalizer_array.clear();
311 m_chunk_list.clear(m_chunk_size);
320void zone::object_delete(
void* obj)
322 delete static_cast<T*
>(obj);
326void zone::object_destruct(
void* obj)
328 static_cast<T*
>(obj)->~T();
331inline void zone::undo_allocate(
size_t size)
333 m_chunk_list.m_ptr -=
size;
334 m_chunk_list.m_free +=
size;
338template <
typename T,
typename... Args>
343 m_finalizer_array.push(&zone::object_destruct<T>, x);
345 undo_allocate(
sizeof(T));
349 return new (x) T(args...);
351 --m_finalizer_array.m_tail;
352 undo_allocate(
sizeof(T));
360 return (size + align - 1) / align * align;
#define MSGPACK_ASSERT
Definition assert.hpp:22
Definition cpp03_zone.hpp:30
zone(const zone &)=delete
zone & operator=(zone &&)=default
T * allocate(Args... args)
Definition cpp11_zone.hpp:339
void * allocate_no_align(size_t size)
void push_finalizer(msgpack::unique_ptr< T > obj)
void clear()
Definition cpp03_zone.hpp:321
void * allocate_align(size_t size, size_t align=MSGPACK_ZONE_ALIGN)
zone & operator=(const zone &)=delete
void push_finalizer(void(*func)(void *), void *data)
zone(size_t chunk_size=MSGPACK_ZONE_CHUNK_SIZE)
std::size_t size(T const &t)
Definition size_equal_only.hpp:24
Definition adaptor_base.hpp:15
std::size_t aligned_size(std::size_t size, std::size_t align)
Definition cpp03_zone.hpp:353
#define MSGPACK_NULLPTR
Definition cpp_config_decl.hpp:85
#define MSGPACK_ZONE_ALIGNOF(type)
Definition cpp03_zone_decl.hpp:30
#define MSGPACK_ZONE_ALIGN
Definition cpp03_zone_decl.hpp:24
#define MSGPACK_ZONE_CHUNK_SIZE
Definition cpp03_zone_decl.hpp:20
#define MSGPACK_API_VERSION_NAMESPACE(ns)
Definition versioning.hpp:66