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>
187 static
void* operator new(std::
size_t size)
189 void* p = ::malloc(size);
190 if (!p)
throw std::bad_alloc();
193 static void operator delete(
void *p) noexcept
197 static void*
operator new(std::size_t ,
void* mem) noexcept
201 static void operator delete(
void * ,
void* ) noexcept
205 template <
typename T,
typename... Args>
211 zone& operator=(
const zone&) =
delete;
214 void undo_allocate(
size_t size);
216 template <
typename T>
217 static void object_destruct(
void* obj);
219 template <
typename T>
220 static void object_delete(
void* obj);
222 static char* get_aligned(
char* ptr,
size_t align);
224 char* allocate_expand(
size_t size);
227 inline zone::zone(
size_t chunk_size) noexcept:m_chunk_size(chunk_size), m_chunk_list(m_chunk_size)
231 inline char* zone::get_aligned(
char* ptr,
size_t align)
234 reinterpret_cast<char*
>(
235 reinterpret_cast<size_t>(
236 (ptr + (align - 1))) / align * align);
241 char* aligned = get_aligned(m_chunk_list.m_ptr, align);
242 size_t adjusted_size = size + (aligned - m_chunk_list.m_ptr);
243 if (m_chunk_list.m_free < adjusted_size) {
244 size_t enough_size = size + align - 1;
245 char* ptr = allocate_expand(enough_size);
246 aligned = get_aligned(ptr, align);
247 adjusted_size = size + (aligned - m_chunk_list.m_ptr);
249 m_chunk_list.m_free -= adjusted_size;
250 m_chunk_list.m_ptr += adjusted_size;
256 char* ptr = m_chunk_list.m_ptr;
257 if(m_chunk_list.m_free < size) {
258 ptr = allocate_expand(size);
260 m_chunk_list.m_free -=
size;
261 m_chunk_list.m_ptr +=
size;
266 inline char* zone::allocate_expand(
size_t size)
268 chunk_list*
const cl = &m_chunk_list;
270 size_t sz = m_chunk_size;
273 size_t tmp_sz = sz * 2;
281 chunk* c =
static_cast<chunk*
>(::malloc(
sizeof(chunk) + sz));
282 if (!c)
throw std::bad_alloc();
284 char* ptr =
reinterpret_cast<char*
>(c) +
sizeof(chunk);
286 c->m_next = cl->m_head;
296 m_finalizer_array.push(func, data);
299 template <
typename T>
302 m_finalizer_array.push(&zone::object_delete<T>, obj.release());
307 m_finalizer_array.clear();
308 m_chunk_list.clear(m_chunk_size);
316 template <
typename T>
317 void zone::object_delete(
void* obj)
319 delete static_cast<T*
>(obj);
322 template <
typename T>
323 void zone::object_destruct(
void* obj)
325 static_cast<T*
>(obj)->~T();
328 inline void zone::undo_allocate(
size_t size)
330 m_chunk_list.m_ptr -=
size;
331 m_chunk_list.m_free +=
size;
335 template <
typename T,
typename... Args>
340 m_finalizer_array.push(&zone::object_destruct<T>, x);
342 undo_allocate(
sizeof(T));
346 return new (x) T(args...);
348 --m_finalizer_array.m_tail;
349 undo_allocate(
sizeof(T));
357 return (size + align - 1) / align * align;
366 #endif // MSGPACK_CPP11_ZONE_HPP void * allocate_align(size_t size, size_t align=MSGPACK_ZONE_ALIGN)
Definition: cpp03_zone.hpp:246
void * allocate_no_align(size_t size)
Definition: cpp03_zone.hpp:261
T * allocate(Args...args)
Definition: cpp11_zone.hpp:336
Definition: adaptor_base.hpp:15
std::size_t aligned_size(std::size_t size, std::size_t align)
Definition: cpp03_zone.hpp:344
Definition: cpp03_zone.hpp:22
Definition: cpp_config_decl.hpp:47
void push_finalizer(void(*func)(void *), void *data)
Definition: cpp03_zone.hpp:301
#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:312
#define MSGPACK_API_VERSION_NAMESPACE(ns)
Definition: versioning.hpp:58
#define MSGPACK_ZONE_CHUNK_SIZE
Definition: cpp03_zone_decl.hpp:20
#define MSGPACK_ZONE_ALIGNOF(type)
Definition: cpp03_zone_decl.hpp:30
void swap(zone &o)
Definition: cpp03_zone.hpp:318
zone(size_t chunk_size=MSGPACK_ZONE_CHUNK_SIZE)
Definition: cpp03_zone.hpp:234
#define MSGPACK_NULLPTR
Definition: cpp_config_decl.hpp:35