10 #ifndef MSGPACK_CPP11_ZONE_HPP 11 #define MSGPACK_CPP11_ZONE_HPP 30 finalizer(
void (*func)(
void*),
void* data):m_func(func), m_data(data) {}
31 void operator()() { m_func(m_data); }
32 void (*m_func)(
void*);
35 struct finalizer_array {
38 finalizer* fin = m_tail;
39 for(; fin != m_array; --fin) (*(fin-1))();
49 void push(
void (*func)(
void* data),
void* data)
51 finalizer* fin = m_tail;
54 push_expand(func, data);
63 void push_expand(
void (*func)(
void*),
void* data) {
64 const size_t nused = m_end - m_array;
67 nnext = (
sizeof(finalizer) < 72/2) ?
68 72 /
sizeof(finalizer) : 8;
73 static_cast<finalizer*
>(::realloc(m_array,
sizeof(finalizer) * nnext));
75 throw std::bad_alloc();
80 new (m_tail) finalizer(func, data);
84 finalizer_array(finalizer_array&& other) noexcept
85 :m_tail(other.m_tail), m_end(other.m_end), m_array(other.m_array)
91 finalizer_array& operator=(finalizer_array&& other) noexcept
93 this->~finalizer_array();
94 new (
this) finalizer_array(
std::move(other));
103 finalizer_array(
const finalizer_array&);
104 finalizer_array& operator=(
const finalizer_array&);
110 chunk_list(
size_t chunk_size)
112 chunk* c =
static_cast<chunk*
>(::malloc(
sizeof(chunk) + chunk_size));
114 throw std::bad_alloc();
119 m_ptr =
reinterpret_cast<char*
>(c) +
sizeof(chunk);
126 chunk* n = c->m_next;
131 void clear(
size_t chunk_size)
135 chunk* n = c->m_next;
146 m_ptr =
reinterpret_cast<char*
>(m_head) +
sizeof(chunk);
148 chunk_list(chunk_list&& other) noexcept
149 :m_free(other.m_free), m_ptr(other.m_ptr), m_head(other.m_head)
153 chunk_list& operator=(chunk_list&& other) noexcept
164 chunk_list(
const chunk_list&);
165 chunk_list& operator=(
const chunk_list&);
168 chunk_list m_chunk_list;
169 finalizer_array m_finalizer_array;
180 template <
typename T>
188 static void*
operator new(std::size_t
size)
190 void* p = ::malloc(
size);
191 if (!p)
throw std::bad_alloc();
194 static void operator delete(
void *p) noexcept
198 static void*
operator new(std::size_t ,
void* mem) noexcept
202 static void operator delete(
void * ,
void* ) noexcept
206 template <
typename T,
typename... Args>
212 zone& operator=(
const zone&) =
delete;
215 void undo_allocate(
size_t size);
217 template <
typename T>
218 static void object_destruct(
void* obj);
220 template <
typename T>
221 static void object_delete(
void* obj);
223 void* allocate_expand(
size_t size);
226 inline zone::zone(
size_t chunk_size) noexcept:m_chunk_size(chunk_size), m_chunk_list(m_chunk_size)
233 reinterpret_cast<char*
>(
234 reinterpret_cast<size_t>(
235 (m_chunk_list.m_ptr + (align - 1))) / align * align);
236 size_t adjusted_size = size + (aligned - m_chunk_list.m_ptr);
237 if(m_chunk_list.m_free >= adjusted_size) {
238 m_chunk_list.m_free -= adjusted_size;
239 m_chunk_list.m_ptr += adjusted_size;
242 return reinterpret_cast<char*
>(
243 reinterpret_cast<size_t>(
244 allocate_expand(size + (align - 1))) / align * align);
249 if(m_chunk_list.m_free < size) {
250 return allocate_expand(size);
253 char* ptr = m_chunk_list.m_ptr;
254 m_chunk_list.m_free -=
size;
255 m_chunk_list.m_ptr +=
size;
260 inline void* zone::allocate_expand(
size_t size)
262 chunk_list*
const cl = &m_chunk_list;
264 size_t sz = m_chunk_size;
267 size_t tmp_sz = sz * 2;
275 chunk* c =
static_cast<chunk*
>(::malloc(
sizeof(chunk) + sz));
276 if (!c)
throw std::bad_alloc();
278 char* ptr =
reinterpret_cast<char*
>(c) +
sizeof(chunk);
280 c->m_next = cl->m_head;
282 cl->m_free = sz -
size;
283 cl->m_ptr = ptr +
size;
290 m_finalizer_array.push(func, data);
293 template <
typename T>
296 m_finalizer_array.push(&zone::object_delete<T>, obj.release());
301 m_finalizer_array.clear();
302 m_chunk_list.clear(m_chunk_size);
310 template <
typename T>
311 void zone::object_delete(
void* obj)
313 delete static_cast<T*
>(obj);
316 template <
typename T>
317 void zone::object_destruct(
void* obj)
319 static_cast<T*
>(obj)->~T();
322 inline void zone::undo_allocate(
size_t size)
324 m_chunk_list.m_ptr -=
size;
325 m_chunk_list.m_free +=
size;
329 template <
typename T,
typename... Args>
334 m_finalizer_array.push(&zone::object_destruct<T>, x);
336 undo_allocate(
sizeof(T));
340 return new (x) T(args...);
342 --m_finalizer_array.m_tail;
343 undo_allocate(
sizeof(T));
351 return (size + align - 1) / align * align;
360 #endif // MSGPACK_CPP11_ZONE_HPP void * allocate_align(size_t size, size_t align=MSGPACK_ZONE_ALIGN)
Definition: cpp03_zone.hpp:236
void * allocate_no_align(size_t size)
Definition: cpp03_zone.hpp:253
Definition: adaptor_base.hpp:15
std::size_t aligned_size(std::size_t size, std::size_t align)
Definition: cpp03_zone.hpp:337
Definition: cpp03_zone.hpp:22
Definition: cpp_config_decl.hpp:47
void push_finalizer(void(*func)(void *), void *data)
Definition: cpp03_zone.hpp:294
#define MSGPACK_ZONE_ALIGN
Definition: cpp03_zone_decl.hpp:24
std::size_t size(T const &t)
Definition: size_equal_only.hpp:24
void clear()
Definition: cpp03_zone.hpp:305
#define MSGPACK_API_VERSION_NAMESPACE(ns)
Definition: versioning.hpp:58
#define MSGPACK_ZONE_CHUNK_SIZE
Definition: cpp03_zone_decl.hpp:20
void swap(zone &o)
Definition: cpp03_zone.hpp:311
T * allocate(Args... args)
Definition: cpp11_zone.hpp:330
zone(size_t chunk_size=MSGPACK_ZONE_CHUNK_SIZE)
Definition: cpp03_zone.hpp:232
#define MSGPACK_NULLPTR
Definition: cpp_config_decl.hpp:35