// // MessagePack for C++ memory pool // // Copyright (C) 2008-2010 FURUHASHI Sadayuki // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #ifndef MSGPACK_ZONE_HPP__ #define MSGPACK_ZONE_HPP__ #include "zone.h" #include #include #include namespace msgpack { class zone : public msgpack_zone { public: zone(size_t chunk_size = MSGPACK_ZONE_CHUNK_SIZE); ~zone(); public: void* malloc(size_t size); void* malloc_no_align(size_t size); void push_finalizer(void (*func)(void*), void* data); template void push_finalizer(std::auto_ptr obj); void clear(); void swap(zone& o); static void* operator new(std::size_t size) throw(std::bad_alloc) { void* p = ::malloc(size); if (!p) throw std::bad_alloc(); return p; } static void operator delete(void *p) throw() { ::free(p); } template T* allocate(); template T* allocate(A1 a1); template T* allocate(A1 a1, A2 a2); template T* allocate(A1 a1, A2 a2, A3 a3); template T* allocate(A1 a1, A2 a2, A3 a3, A4 a4); template T* allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5); template T* allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6); template T* allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7); template T* allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8); template T* allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9); template T* allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10); template T* allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11); template T* allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12); template T* allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13); template T* allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13, A14 a14); template T* allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13, A14 a14, A15 a15); private: void undo_malloc(size_t size); template static void object_destructor(void* obj); typedef msgpack_zone base; private: zone(const zone&); }; inline zone::zone(size_t chunk_size) { msgpack_zone_init(this, chunk_size); } inline zone::~zone() { msgpack_zone_destroy(this); } inline void* zone::malloc(size_t size) { void* ptr = msgpack_zone_malloc(this, size); if(!ptr) { throw std::bad_alloc(); } return ptr; } inline void* zone::malloc_no_align(size_t size) { void* ptr = msgpack_zone_malloc_no_align(this, size); if(!ptr) { throw std::bad_alloc(); } return ptr; } inline void zone::push_finalizer(void (*func)(void*), void* data) { if(!msgpack_zone_push_finalizer(this, func, data)) { throw std::bad_alloc(); } } template inline void zone::push_finalizer(std::auto_ptr obj) { if(!msgpack_zone_push_finalizer(this, &zone::object_destructor, obj.get())) { throw std::bad_alloc(); } obj.release(); } inline void zone::clear() { msgpack_zone_clear(this); } inline void zone::swap(zone& o) { msgpack_zone_swap(this, &o); } template void zone::object_destructor(void* obj) { reinterpret_cast(obj)->~T(); } inline void zone::undo_malloc(size_t size) { base::chunk_list.ptr -= size; base::chunk_list.free += size; } template T* zone::allocate() { void* x = malloc(sizeof(T)); if(!msgpack_zone_push_finalizer(this, &zone::object_destructor, x)) { undo_malloc(sizeof(T)); throw std::bad_alloc(); } try { return new (x) T(); } catch (...) { --base::finalizer_array.tail; undo_malloc(sizeof(T)); throw; } } template T* zone::allocate(A1 a1) { void* x = malloc(sizeof(T)); if(!msgpack_zone_push_finalizer(this, &zone::object_destructor, x)) { undo_malloc(sizeof(T)); throw std::bad_alloc(); } try { return new (x) T(a1); } catch (...) { --base::finalizer_array.tail; undo_malloc(sizeof(T)); throw; } } template T* zone::allocate(A1 a1, A2 a2) { void* x = malloc(sizeof(T)); if(!msgpack_zone_push_finalizer(this, &zone::object_destructor, x)) { undo_malloc(sizeof(T)); throw std::bad_alloc(); } try { return new (x) T(a1, a2); } catch (...) { --base::finalizer_array.tail; undo_malloc(sizeof(T)); throw; } } template T* zone::allocate(A1 a1, A2 a2, A3 a3) { void* x = malloc(sizeof(T)); if(!msgpack_zone_push_finalizer(this, &zone::object_destructor, x)) { undo_malloc(sizeof(T)); throw std::bad_alloc(); } try { return new (x) T(a1, a2, a3); } catch (...) { --base::finalizer_array.tail; undo_malloc(sizeof(T)); throw; } } template T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4) { void* x = malloc(sizeof(T)); if(!msgpack_zone_push_finalizer(this, &zone::object_destructor, x)) { undo_malloc(sizeof(T)); throw std::bad_alloc(); } try { return new (x) T(a1, a2, a3, a4); } catch (...) { --base::finalizer_array.tail; undo_malloc(sizeof(T)); throw; } } template T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { void* x = malloc(sizeof(T)); if(!msgpack_zone_push_finalizer(this, &zone::object_destructor, x)) { undo_malloc(sizeof(T)); throw std::bad_alloc(); } try { return new (x) T(a1, a2, a3, a4, a5); } catch (...) { --base::finalizer_array.tail; undo_malloc(sizeof(T)); throw; } } template T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) { void* x = malloc(sizeof(T)); if(!msgpack_zone_push_finalizer(this, &zone::object_destructor, x)) { undo_malloc(sizeof(T)); throw std::bad_alloc(); } try { return new (x) T(a1, a2, a3, a4, a5, a6); } catch (...) { --base::finalizer_array.tail; undo_malloc(sizeof(T)); throw; } } template T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) { void* x = malloc(sizeof(T)); if(!msgpack_zone_push_finalizer(this, &zone::object_destructor, x)) { undo_malloc(sizeof(T)); throw std::bad_alloc(); } try { return new (x) T(a1, a2, a3, a4, a5, a6, a7); } catch (...) { --base::finalizer_array.tail; undo_malloc(sizeof(T)); throw; } } template T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) { void* x = malloc(sizeof(T)); if(!msgpack_zone_push_finalizer(this, &zone::object_destructor, x)) { undo_malloc(sizeof(T)); throw std::bad_alloc(); } try { return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8); } catch (...) { --base::finalizer_array.tail; undo_malloc(sizeof(T)); throw; } } template T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) { void* x = malloc(sizeof(T)); if(!msgpack_zone_push_finalizer(this, &zone::object_destructor, x)) { undo_malloc(sizeof(T)); throw std::bad_alloc(); } try { return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9); } catch (...) { --base::finalizer_array.tail; undo_malloc(sizeof(T)); throw; } } template T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) { void* x = malloc(sizeof(T)); if(!msgpack_zone_push_finalizer(this, &zone::object_destructor, x)) { undo_malloc(sizeof(T)); throw std::bad_alloc(); } try { return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); } catch (...) { --base::finalizer_array.tail; undo_malloc(sizeof(T)); throw; } } template T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11) { void* x = malloc(sizeof(T)); if(!msgpack_zone_push_finalizer(this, &zone::object_destructor, x)) { undo_malloc(sizeof(T)); throw std::bad_alloc(); } try { return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); } catch (...) { --base::finalizer_array.tail; undo_malloc(sizeof(T)); throw; } } template T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12) { void* x = malloc(sizeof(T)); if(!msgpack_zone_push_finalizer(this, &zone::object_destructor, x)) { undo_malloc(sizeof(T)); throw std::bad_alloc(); } try { return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); } catch (...) { --base::finalizer_array.tail; undo_malloc(sizeof(T)); throw; } } template T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13) { void* x = malloc(sizeof(T)); if(!msgpack_zone_push_finalizer(this, &zone::object_destructor, x)) { undo_malloc(sizeof(T)); throw std::bad_alloc(); } try { return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); } catch (...) { --base::finalizer_array.tail; undo_malloc(sizeof(T)); throw; } } template T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13, A14 a14) { void* x = malloc(sizeof(T)); if(!msgpack_zone_push_finalizer(this, &zone::object_destructor, x)) { undo_malloc(sizeof(T)); throw std::bad_alloc(); } try { return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); } catch (...) { --base::finalizer_array.tail; undo_malloc(sizeof(T)); throw; } } template T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13, A14 a14, A15 a15) { void* x = malloc(sizeof(T)); if(!msgpack_zone_push_finalizer(this, &zone::object_destructor, x)) { undo_malloc(sizeof(T)); throw std::bad_alloc(); } try { return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); } catch (...) { --base::finalizer_array.tail; undo_malloc(sizeof(T)); throw; } } } // namespace msgpack #endif /* msgpack/zone.hpp */