// // MessagePack for C++ memory pool // // Copyright (C) 2008-2009 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 "msgpack/object.hpp" #include "msgpack/zone.h" #include #include <% GENERATION_LIMIT = 15 %> 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 push_finalizer(void (*func)(void*), void* data); void clear(); <%0.upto(GENERATION_LIMIT) {|i|%> template , typename A<%=j%><%}%>> T* allocate(<%=(1..i).map{|j|"A#{j} a#{j}"}.join(', ')%>); <%}%> 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::push_finalizer(void (*func)(void*), void* data) { if(!msgpack_zone_push_finalizer(this, func, data)) { throw std::bad_alloc(); } } inline void zone::clear() { msgpack_zone_clear(this); } template void zone::object_destructor(void* obj) { reinterpret_cast(obj)->~T(); } inline void zone::undo_malloc(size_t size) { msgpack_zone_chunk* chunk = base::chunk_array.tail; chunk->ptr -= size; chunk->free += size; } <%0.upto(GENERATION_LIMIT) {|i|%> template , typename A<%=j%><%}%>> T* zone::allocate(<%=(1..i).map{|j|"A#{j} a#{j}"}.join(', ')%>) { 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(<%=(1..i).map{|j|"a#{j}"}.join(', ')%>); } catch (...) { --base::finalizer_array.tail; undo_malloc(sizeof(T)); throw; } } <%}%> } // namespace msgpack #endif /* msgpack/zone.hpp */