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)
157 chunk_list& operator=(chunk_list&& other)
noexcept
160 new (
this) chunk_list(std::move(other));
168 chunk_list(
const chunk_list&);
169 chunk_list& operator=(
const chunk_list&);
172 chunk_list m_chunk_list;
173 finalizer_array m_finalizer_array;
184 template <
typename T>
191 static void*
operator new(std::size_t size)
193 void* p = ::malloc(size);
194 if (!p)
throw std::bad_alloc();
197 static void operator delete(
void *p)
noexcept
201 static void*
operator new(std::size_t ,
void* mem)
noexcept
205 static void operator delete(
void * ,
void* )
noexcept
209 template <
typename T,
typename... Args>
214 if (
this != &other) {
219 m_finalizer_array = std::move(other.m_finalizer_array);
220 m_chunk_list = std::move(other.m_chunk_list);
221 m_chunk_size = other.m_chunk_size;
229 void undo_allocate(
size_t size);
231 template <
typename T>
232 static void object_destruct(
void* obj);
234 template <
typename T>
235 static void object_delete(
void* obj);
237 static char* get_aligned(
char* ptr,
size_t align);
239 char* allocate_expand(
size_t size);
242inline zone::zone(
size_t chunk_size):m_chunk_size(chunk_size), m_chunk_list(m_chunk_size)
246inline char* zone::get_aligned(
char* ptr,
size_t align)
250 reinterpret_cast<char*
>(
251 reinterpret_cast<uintptr_t
>(ptr + (align - 1)) & ~static_cast<uintptr_t>(align - 1)
257 char* aligned = get_aligned(m_chunk_list.m_ptr, align);
258 size_t adjusted_size =
size +
static_cast<size_t>(aligned - m_chunk_list.m_ptr);
259 if (m_chunk_list.m_free < adjusted_size) {
260 size_t enough_size =
size + align - 1;
261 char* ptr = allocate_expand(enough_size);
262 aligned = get_aligned(ptr, align);
263 adjusted_size =
size +
static_cast<size_t>(aligned - m_chunk_list.m_ptr);
265 m_chunk_list.m_free -= adjusted_size;
266 m_chunk_list.m_ptr += adjusted_size;
272 char* ptr = m_chunk_list.m_ptr;
273 if(m_chunk_list.m_free < size) {
274 ptr = allocate_expand(size);
276 m_chunk_list.m_free -=
size;
277 m_chunk_list.m_ptr +=
size;
282inline char* zone::allocate_expand(
size_t size)
284 chunk_list*
const cl = &m_chunk_list;
286 size_t sz = m_chunk_size;
289 size_t tmp_sz = sz * 2;
297 if((
sizeof(chunk) + sz) < sz) {
298 throw std::bad_alloc();
301 chunk* c =
static_cast<chunk*
>(::malloc(
sizeof(chunk) + sz));
302 if (!c)
throw std::bad_alloc();
304 char* ptr =
reinterpret_cast<char*
>(c) +
sizeof(chunk);
306 c->m_next = cl->m_head;
316 m_finalizer_array.push(func, data);
322 m_finalizer_array.push(&zone::object_delete<T>, obj.release());
327 m_finalizer_array.clear();
328 m_chunk_list.clear(m_chunk_size);
337void zone::object_delete(
void* obj)
339 delete static_cast<T*
>(obj);
343void zone::object_destruct(
void* obj)
345 static_cast<T*
>(obj)->~T();
348inline void zone::undo_allocate(
size_t size)
350 m_chunk_list.m_ptr -=
size;
351 m_chunk_list.m_free +=
size;
355template <
typename T,
typename... Args>
360 m_finalizer_array.push(&zone::object_destruct<T>, x);
362 undo_allocate(
sizeof(T));
366 return new (x) T(args...);
368 --m_finalizer_array.m_tail;
369 undo_allocate(
sizeof(T));
377 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 &&other)
Definition cpp11_zone.hpp:213
T * allocate(Args... args)
Definition cpp11_zone.hpp:356
void * allocate_no_align(size_t size)
void push_finalizer(msgpack::unique_ptr< T > obj)
void clear()
Definition cpp03_zone.hpp:325
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:365
#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