/* Copyright (C) 2001-2006, William Joseph. All Rights Reserved. This file is part of GtkRadiant. GtkRadiant is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. GtkRadiant is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GtkRadiant; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #if !defined(INCLUDED_MEMORY_ALLOCATOR_H) #define INCLUDED_MEMORY_ALLOCATOR_H #include #if 0 #define DefaultAllocator std::allocator #else /// \brief An allocator that uses c++ new/delete. /// Compliant with the std::allocator interface. template class DefaultAllocator { public: typedef Type value_type; typedef value_type* pointer; typedef const Type* const_pointer; typedef Type& reference; typedef const Type& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; template struct rebind { typedef DefaultAllocator other; }; DefaultAllocator() { } DefaultAllocator(const DefaultAllocator&) { } template DefaultAllocator(const DefaultAllocator&) { } ~DefaultAllocator() { } pointer address(reference instance) const { return &instance; } const_pointer address(const_reference instance) const { return &instance; } Type* allocate(size_type size, const void* = 0) { return static_cast(::operator new(size * sizeof(Type))); } void deallocate(pointer p, size_type) { ::operator delete(p); } size_type max_size() const { return std::size_t(-1) / sizeof (Type); } void construct(pointer p, const Type& value) { new(p) Type(value); } void destroy(pointer p) { p->~Type(); } }; template inline bool operator==(const DefaultAllocator&, const DefaultAllocator&) { return true; } template inline bool operator==(const DefaultAllocator&, const OtherAllocator&) { return false; } #endif template class NamedAllocator : public DefaultAllocator { typedef DefaultAllocator allocator_type; const char* m_name; public: typedef Type value_type; typedef value_type* pointer; typedef const Type* const_pointer; typedef Type& reference; typedef const Type& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; template struct rebind { typedef NamedAllocator other; }; explicit NamedAllocator(const char* name) : m_name(name) { } NamedAllocator(const NamedAllocator& other) : m_name(other.m_name) { } template NamedAllocator(const NamedAllocator& other) : m_name(other.m_name) { } ~NamedAllocator() { } pointer address(reference instance) const { return allocator_type::address(instance); } const_pointer address(const_reference instance) const { return allocator_type::address(instance); } Type* allocate(size_type size, const void* = 0) { return allocator_type::allocate(size); } void deallocate(pointer p, size_type size) { allocator_type::deallocate(p, size); } size_type max_size() const { return allocator_type::max_size(); } void construct(pointer p, const Type& value) { allocator_type::construct(p, value); } void destroy(pointer p) { allocator_type::destroy(p); } template bool operator==(const NamedAllocator& other) { return true; } // returns true if the allocators are not interchangeable template bool operator!=(const NamedAllocator& other) { return false; } }; #include #include "generic/object.h" template class DefaultConstruct { public: void operator()(Type& t) { constructor(t); } }; template class Construct { const T1& other; public: Construct(const T1& other_) : other(other_) { } void operator()(Type& t) { constructor(t, other); } }; template class Destroy { public: void operator()(Type& t) { destructor(t); } }; template > class New : public Allocator { public: New() { } explicit New(const Allocator& allocator) : Allocator(allocator) { } Type* scalar() { return new(Allocator::allocate(1)) Type(); } template Type* scalar(const T1& t1) { return new(Allocator::allocate(1)) Type(t1); } template Type* scalar(const T1& t1, const T2& t2) { return new(Allocator::allocate(1)) Type(t1, t2); } template Type* scalar(const T1& t1, const T2& t2, const T3& t3) { return new(Allocator::allocate(1)) Type(t1, t2, t3); } template Type* scalar(const T1& t1, const T2& t2, const T3& t3, const T4& t4) { return new(Allocator::allocate(1)) Type(t1, t2, t3, t4); } template Type* scalar(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5) { return new(Allocator::allocate(1)) Type(t1, t2, t3, t4, t5); } Type* vector(std::size_t size) { #if 1 Type* p = Allocator::allocate(size); std::for_each(p, p + size, DefaultConstruct()); return p; #else // this does not work with msvc71 runtime return new(Allocator::allocate(size)) Type[size]; #endif } template Type* vector(std::size_t size, const T1& t1) { Type* p = Allocator::allocate(size); std::for_each(p, p + size, Construct(t1)); return p; } }; template > class Delete : public Allocator { public: Delete() { } explicit Delete(const Allocator& allocator) : Allocator(allocator) { } void scalar(Type* p) { if(p != 0) { p->~Type(); Allocator::deallocate(p, 1); } } void vector(Type* p, std::size_t size) { // '::operator delete' handles null // 'std::allocator::deallocate' requires non-null if(p != 0) { std::for_each(p, p + size, Destroy()); Allocator::deallocate(p, size); } } }; template class NamedNew { public: typedef New > type; }; template class NamedDelete { public: typedef Delete > type; }; #endif