// // mp::zone // // Copyright (C) 2008 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 MP_ZONE_IMPL_H__ #define MP_ZONE_IMPL_H__ #include #include namespace mp { inline zone::zone() {} inline zone::~zone() { clear(); } template inline T* zone::allocate() { void* x = ::malloc(sizeof(T)); if(!x) { throw std::bad_alloc(); } return push_object(new (x) T()); } MP_ARGS_BEGIN template inline T* zone::allocate(MP_ARGS_PARAMS) { void* x = ::malloc(sizeof(T)); if(!x) { throw std::bad_alloc(); } return push_object(new (x) T(MP_ARGS_FUNC)); } MP_ARGS_END template inline T* zone::push_object(T* x) { void (*func)(void*) = &zone::finalize_destruct_free; try { push_finalizer(func, reinterpret_cast(x)); } catch (...) { (*func)(x); throw; } return x; } inline void* zone::malloc(size_t sz) { void* p = ::malloc(sz); if(!p) { throw std::bad_alloc(); } void (*func)(void*) = &zone::finalize_free; try { push_finalizer(func, p); } catch (...) { (*func)(p); throw; } return p; } inline void zone::push_finalizer(void (*func)(void*), void* obj) { m_entries.push_back( entry(func, obj) ); } inline void zone::delegate_to(zone& guardian) { entries_t composed(m_entries); composed.insert(composed.end(), guardian.m_entries.begin(), guardian.m_entries.end()); guardian.m_entries.swap(composed); m_entries.clear(); } inline void zone::clear() { for(entries_t::reverse_iterator it(m_entries.rbegin()), it_end(m_entries.rend()); it != it_end; ++it) { it->finalize(); } m_entries.clear(); } inline void zone::finalize_free(void* p) { ::free(p); } template void zone::finalize_destruct_free(void* obj) { reinterpret_cast(obj)->~T(); ::free(obj); } } // namespace mp #endif /* mp/zone_impl.h */