10 #ifndef MSGPACK_CPP11_ZONE_HPP 11 #define MSGPACK_CPP11_ZONE_HPP 21 #ifndef MSGPACK_ZONE_CHUNK_SIZE 22 #define MSGPACK_ZONE_CHUNK_SIZE 8192 25 #ifndef MSGPACK_ZONE_ALIGN 26 #define MSGPACK_ZONE_ALIGN sizeof(void*) 38 finalizer(
void (*func)(
void*),
void* data):m_func(func), m_data(data) {}
39 void operator()() { m_func(m_data); }
40 void (*m_func)(
void*);
43 struct finalizer_array {
44 finalizer_array():m_tail(
nullptr), m_end(
nullptr), m_array(
nullptr) {}
46 finalizer* fin = m_tail;
47 for(; fin != m_array; --fin) (*(fin-1))();
57 void push(
void (*func)(
void* data),
void* data)
59 finalizer* fin = m_tail;
62 push_expand(func, data);
71 void push_expand(
void (*func)(
void*),
void* data) {
72 const size_t nused = m_end - m_array;
75 nnext = (
sizeof(finalizer) < 72/2) ?
76 72 /
sizeof(finalizer) : 8;
81 static_cast<finalizer*
>(::realloc(m_array,
sizeof(finalizer) * nnext));
83 throw std::bad_alloc();
88 new (m_tail) finalizer(func, data);
92 finalizer_array(finalizer_array&& other) noexcept
93 :m_tail(other.m_tail), m_end(other.m_end), m_array(other.m_array)
95 other.m_tail =
nullptr;
96 other.m_end =
nullptr;
97 other.m_array =
nullptr;
99 finalizer_array& operator=(finalizer_array&& other) noexcept
101 this->~finalizer_array();
102 new (
this) finalizer_array(
std::move(other));
111 finalizer_array(
const finalizer_array&);
112 finalizer_array& operator=(
const finalizer_array&);
118 chunk_list(
size_t chunk_size)
120 chunk* c =
static_cast<chunk*
>(::malloc(
sizeof(chunk) + chunk_size));
122 throw std::bad_alloc();
127 m_ptr =
reinterpret_cast<char*
>(c) +
sizeof(chunk);
134 chunk* n = c->m_next;
139 void clear(
size_t chunk_size)
143 chunk* n = c->m_next;
152 m_head->m_next =
nullptr;
154 m_ptr =
reinterpret_cast<char*
>(m_head) +
sizeof(chunk);
156 chunk_list(chunk_list&& other) noexcept
157 :m_free(other.m_free), m_ptr(other.m_ptr), m_head(other.m_head)
159 other.m_head =
nullptr;
161 chunk_list& operator=(chunk_list&& other) noexcept
172 chunk_list(
const chunk_list&);
173 chunk_list& operator=(
const chunk_list&);
176 chunk_list m_chunk_list;
177 finalizer_array m_finalizer_array;
188 template <
typename T>
196 static void*
operator new(std::size_t size)
198 void* p = ::malloc(size);
199 if (!p)
throw std::bad_alloc();
202 static void operator delete(
void *p) noexcept
206 static void*
operator new(std::size_t ,
void* mem) noexcept
210 static void operator delete(
void * ,
void* ) noexcept
214 template <
typename T,
typename... Args>
220 zone& operator=(
const zone&) =
delete;
223 void undo_allocate(
size_t size);
225 template <
typename T>
226 static void object_destruct(
void* obj);
228 template <
typename T>
229 static void object_delete(
void* obj);
231 void* allocate_expand(
size_t size);
234 inline zone::zone(
size_t chunk_size) noexcept:m_chunk_size(chunk_size), m_chunk_list(m_chunk_size)
241 reinterpret_cast<char*
>(
242 reinterpret_cast<size_t>(
243 (m_chunk_list.m_ptr + (align - 1))) / align * align);
244 size_t adjusted_size = size + (aligned - m_chunk_list.m_ptr);
245 if(m_chunk_list.m_free >= adjusted_size) {
246 m_chunk_list.m_free -= adjusted_size;
247 m_chunk_list.m_ptr += adjusted_size;
250 return reinterpret_cast<char*
>(
251 reinterpret_cast<size_t>(
252 allocate_expand(size + (align - 1))) / align * align);
257 if(m_chunk_list.m_free < size) {
258 return allocate_expand(size);
261 char* ptr = m_chunk_list.m_ptr;
262 m_chunk_list.m_free -= size;
263 m_chunk_list.m_ptr += size;
268 inline void* zone::allocate_expand(
size_t size)
270 chunk_list*
const cl = &m_chunk_list;
272 size_t sz = m_chunk_size;
275 size_t tmp_sz = sz * 2;
283 chunk* c =
static_cast<chunk*
>(::malloc(
sizeof(chunk) + sz));
284 if (!c)
throw std::bad_alloc();
286 char* ptr =
reinterpret_cast<char*
>(c) +
sizeof(chunk);
288 c->m_next = cl->m_head;
290 cl->m_free = sz - size;
291 cl->m_ptr = ptr + size;
298 m_finalizer_array.push(func, data);
301 template <
typename T>
304 m_finalizer_array.push(&zone::object_delete<T>, obj.release());
309 m_finalizer_array.clear();
310 m_chunk_list.clear(m_chunk_size);
318 template <
typename T>
319 void zone::object_delete(
void* obj)
321 delete static_cast<T*
>(obj);
324 template <
typename T>
325 void zone::object_destruct(
void* obj)
327 static_cast<T*
>(obj)->~T();
330 inline void zone::undo_allocate(
size_t size)
332 m_chunk_list.m_ptr -= size;
333 m_chunk_list.m_free += size;
337 template <
typename T,
typename... Args>
342 m_finalizer_array.push(&zone::object_destruct<T>, x);
344 undo_allocate(
sizeof(T));
348 return new (x) T(args...);
350 --m_finalizer_array.m_tail;
351 undo_allocate(
sizeof(T));
359 return (size + align - 1) / align * align;
368 #endif // MSGPACK_CPP11_ZONE_HPP #define MSGPACK_API_VERSION_NAMESPACE(ns)
Definition: versioning.hpp:58
void * allocate_align(size_t size, size_t align=MSGPACK_ZONE_ALIGN)
Definition: cpp03_zone.hpp:248
void * allocate_no_align(size_t size)
Definition: cpp03_zone.hpp:265
#define MSGPACK_ZONE_ALIGN
Definition: cpp11_zone.hpp:26
#define MSGPACK_ZONE_CHUNK_SIZE
Definition: cpp11_zone.hpp:22
Definition: adaptor_base.hpp:15
Definition: cpp03_zone.hpp:34
Definition: cpp_config.hpp:44
void push_finalizer(void(*func)(void *), void *data)
Definition: cpp03_zone.hpp:306
void clear()
Definition: cpp03_zone.hpp:317
void swap(zone &o)
Definition: cpp03_zone.hpp:323
T * allocate(Args... args)
Definition: cpp11_zone.hpp:338
zone(size_t chunk_size=MSGPACK_ZONE_CHUNK_SIZE)
Definition: cpp03_zone.hpp:244
T & move(T &t)
Definition: cpp_config.hpp:52
std::size_t aligned_size(std::size_t size, std::size_t align=MSGPACK_ZONE_ALIGN)
Definition: cpp03_zone.hpp:349