10 #ifndef MSGPACK_CPP11_ZONE_HPP
11 #define MSGPACK_CPP11_ZONE_HPP
22 #include <boost/assert.hpp>
33 finalizer(
void (*func)(
void*),
void* data):m_func(func), m_data(data) {}
34 void operator()() { m_func(m_data); }
35 void (*m_func)(
void*);
38 struct finalizer_array {
41 finalizer* fin = m_tail;
42 for(; fin != m_array; --fin) (*(fin-1))();
52 void push(
void (*func)(
void* data),
void* data)
54 finalizer* fin = m_tail;
57 push_expand(func, data);
66 void push_expand(
void (*func)(
void*),
void* data) {
67 const size_t nused =
static_cast<size_t>(m_end - m_array);
70 nnext = (
sizeof(finalizer) < 72/2) ?
71 72 /
sizeof(finalizer) : 8;
76 static_cast<finalizer*
>(::realloc(m_array,
sizeof(finalizer) * nnext));
78 throw std::bad_alloc();
83 new (m_tail) finalizer(func, data);
87 finalizer_array(finalizer_array&& other) noexcept
88 :m_tail(other.m_tail), m_end(other.m_end), m_array(other.m_array)
94 finalizer_array& operator=(finalizer_array&& other) noexcept
96 this->~finalizer_array();
97 new (
this) finalizer_array(std::move(other));
106 finalizer_array(
const finalizer_array&);
107 finalizer_array& operator=(
const finalizer_array&);
113 chunk_list(
size_t chunk_size)
115 chunk* c =
static_cast<chunk*
>(::malloc(
sizeof(chunk) + chunk_size));
117 throw std::bad_alloc();
122 m_ptr =
reinterpret_cast<char*
>(c) +
sizeof(chunk);
129 chunk* n = c->m_next;
134 void clear(
size_t chunk_size)
138 chunk* n = c->m_next;
149 m_ptr =
reinterpret_cast<char*
>(m_head) +
sizeof(chunk);
151 chunk_list(chunk_list&& other) noexcept
152 :m_free(other.m_free), m_ptr(other.m_ptr), m_head(other.m_head)
156 chunk_list& operator=(chunk_list&& other) noexcept
159 new (
this) chunk_list(std::move(other));
167 chunk_list(
const chunk_list&);
168 chunk_list& operator=(
const chunk_list&);
171 chunk_list m_chunk_list;
172 finalizer_array m_finalizer_array;
183 template <
typename T>
190 static void*
operator new(std::size_t
size)
192 void* p = ::malloc(
size);
193 if (!p)
throw std::bad_alloc();
196 static void operator delete(
void *p) noexcept
200 static void*
operator new(std::size_t ,
void* mem) noexcept
204 static void operator delete(
void * ,
void* ) noexcept
208 template <
typename T,
typename... Args>
217 void undo_allocate(
size_t size);
219 template <
typename T>
220 static void object_destruct(
void* obj);
222 template <
typename T>
223 static void object_delete(
void* obj);
225 static char* get_aligned(
char* ptr,
size_t align);
227 char* allocate_expand(
size_t size);
230 inline zone::zone(
size_t chunk_size) noexcept:m_chunk_size(chunk_size), m_chunk_list(m_chunk_size)
234 inline char* zone::get_aligned(
char* ptr,
size_t align)
236 BOOST_ASSERT(align != 0 && (align & (align - 1)) == 0);
238 reinterpret_cast<char*
>(
239 reinterpret_cast<uintptr_t
>(ptr + (align - 1)) & ~static_cast<uintptr_t>(align - 1)
245 char* aligned = get_aligned(m_chunk_list.m_ptr, align);
246 size_t adjusted_size =
size +
static_cast<size_t>(aligned - m_chunk_list.m_ptr);
247 if (m_chunk_list.m_free < adjusted_size) {
248 size_t enough_size =
size + align - 1;
249 char* ptr = allocate_expand(enough_size);
250 aligned = get_aligned(ptr, align);
251 adjusted_size =
size +
static_cast<size_t>(aligned - m_chunk_list.m_ptr);
253 m_chunk_list.m_free -= adjusted_size;
254 m_chunk_list.m_ptr += adjusted_size;
260 char* ptr = m_chunk_list.m_ptr;
261 if(m_chunk_list.m_free <
size) {
262 ptr = allocate_expand(
size);
264 m_chunk_list.m_free -=
size;
265 m_chunk_list.m_ptr +=
size;
270 inline char* zone::allocate_expand(
size_t size)
272 chunk_list*
const cl = &m_chunk_list;
274 size_t sz = m_chunk_size;
277 size_t tmp_sz = sz * 2;
285 chunk* c =
static_cast<chunk*
>(::malloc(
sizeof(chunk) + sz));
286 if (!c)
throw std::bad_alloc();
288 char* ptr =
reinterpret_cast<char*
>(c) +
sizeof(chunk);
290 c->m_next = cl->m_head;
300 m_finalizer_array.push(func, data);
303 template <
typename T>
306 m_finalizer_array.push(&zone::object_delete<T>, obj.release());
311 m_finalizer_array.clear();
312 m_chunk_list.clear(m_chunk_size);
320 template <
typename T>
321 void zone::object_delete(
void* obj)
323 delete static_cast<T*
>(obj);
326 template <
typename T>
327 void zone::object_destruct(
void* obj)
329 static_cast<T*
>(obj)->~T();
332 inline void zone::undo_allocate(
size_t size)
334 m_chunk_list.m_ptr -=
size;
335 m_chunk_list.m_free +=
size;
339 template <
typename T,
typename... Args>
344 m_finalizer_array.push(&zone::object_destruct<T>, x);
346 undo_allocate(
sizeof(T));
350 return new (x) T(args...);
352 --m_finalizer_array.m_tail;
353 undo_allocate(
sizeof(T));
361 return (
size + align - 1) / align * align;
Definition: cpp03_zone.hpp:31
zone & operator=(const zone &)=delete
void * allocate_align(size_t size, size_t align=MSGPACK_ZONE_ALIGN)
zone(const zone &)=delete
zone(size_t chunk_size=MSGPACK_ZONE_CHUNK_SIZE) noexcept
T * allocate(Args... args)
Definition: cpp11_zone.hpp:340
void * allocate_no_align(size_t size)
Definition: cpp03_zone.hpp:271
void push_finalizer(msgpack::unique_ptr< T > obj)
void clear()
Definition: cpp03_zone.hpp:322
void * allocate_align(size_t size, size_t align=MSGPACK_ZONE_ALIGN)
Definition: cpp03_zone.hpp:256
void push_finalizer(void(*func)(void *), void *data)
void * allocate_no_align(size_t size)
zone(size_t chunk_size=MSGPACK_ZONE_CHUNK_SIZE)
Definition: cpp03_zone.hpp:243
zone & operator=(zone &&)=default
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:354
#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