diff options
Diffstat (limited to 'src/third-party/ArenaAlloc/arenaalloc.h')
-rw-r--r-- | src/third-party/ArenaAlloc/arenaalloc.h | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/src/third-party/ArenaAlloc/arenaalloc.h b/src/third-party/ArenaAlloc/arenaalloc.h new file mode 100644 index 0000000..dfd648d --- /dev/null +++ b/src/third-party/ArenaAlloc/arenaalloc.h @@ -0,0 +1,186 @@ +// -*- c++ -*- +/****************************************************************************** + * arenaalloc.h + * + * Arena allocator based on the example logic provided by Nicolai Josuttis + * and available at http://www.josuttis.com/libbook/examples.html. + * This enhanced work is provided under the terms of the MIT license. + * + *****************************************************************************/ + +#ifndef _ARENA_ALLOC_H +#define _ARENA_ALLOC_H + +#include <limits> +#include <memory> + +#if __cplusplus >= 201103L +#include <type_traits> +#include <utility> +#endif + +// Define macro ARENA_ALLOC_DEBUG to enable some tracing of the allocator +#include "arenaallocimpl.h" + +namespace ArenaAlloc +{ + + struct _newAllocatorImpl + { + // these two functions should be supported by a specialized + // allocator for shared memory or another source of specialized + // memory such as device mapped memory. + void* allocate( size_t numBytes ) { return new char[ numBytes ]; } + void deallocate( void* ptr ) { delete[]( (char*)ptr ); } + }; + + template <class T, + class AllocatorImpl = _newAllocatorImpl, + class MemblockImpl = _memblockimpl<AllocatorImpl> > + class Alloc { + + private: + MemblockImpl* m_impl; + + public: + // type definitions + typedef T value_type; + typedef T* pointer; + typedef const T* const_pointer; + typedef T& reference; + typedef const T& const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + +#if __cplusplus >= 201103L + // when containers are swapped, (i.e. vector.swap) + // swap the allocators also. This was not specified in c++98 + // thus users of this code not using c++11 must + // exercise caution when using the swap algorithm or + // specialized swap member function. Specifically, + // don't swap containers not sharing the same + // allocator internal implementation in c++98. This is ok + // in c++11. + typedef std::true_type propagate_on_container_swap; + + // container moves should move the allocator also. + typedef std::true_type propagate_on_container_move_assignment; +#endif + + // rebind allocator to type U + template <class U> + struct rebind { + typedef Alloc<U,AllocatorImpl,MemblockImpl> other; + }; + + // return address of values + pointer address (reference value) const { + return &value; + } + const_pointer address (const_reference value) const { + return &value; + } + + Alloc( std::size_t defaultSize = 32768, AllocatorImpl allocImpl = AllocatorImpl() ) throw(): + m_impl( MemblockImpl::create( defaultSize, allocImpl ) ) + { + } + + Alloc(const Alloc& src) throw(): + m_impl( src.m_impl ) + { + m_impl->incrementRefCount(); + } + + template <class U> + Alloc (const Alloc<U,AllocatorImpl,MemblockImpl>& src) throw(): + m_impl( 0 ) + { + MemblockImpl::assign( src, m_impl ); + m_impl->incrementRefCount(); + } + + ~Alloc() throw() + { + m_impl->decrementRefCount(); + } + + // return maximum number of elements that can be allocated + size_type max_size () const throw() + { + return std::numeric_limits<std::size_t>::max() / sizeof(T); + } + + // allocate but don't initialize num elements of type T + pointer allocate (size_type num, const void* = 0) + { + return reinterpret_cast<pointer>( m_impl->allocate(num*sizeof(T)) ); + } + + // initialize elements of allocated storage p with value value +#if __cplusplus >= 201103L + + // use c++11 style forwarding to construct the object + template< typename P, typename... Args> + void construct( P* obj, Args&&... args ) + { + ::new((void*) obj ) P( std::forward<Args>( args )... ); + } + + template< typename P > + void destroy( P* obj ) { obj->~P(); } + +#else + void construct (pointer p, const T& value) + { + new((void*)p)T(value); + } + void destroy (pointer p) { p->~T(); } +#endif + + // deallocate storage p of deleted elements + void deallocate (pointer p, size_type num) + { + m_impl->deallocate( p ); + } + + bool equals( const MemblockImpl * impl ) const + { + return impl == m_impl; + } + + bool operator == ( const Alloc& t2 ) const + { + return m_impl == t2.m_impl; + } + + friend MemblockImpl; + + template< typename Other > + bool operator == ( const Alloc< Other, AllocatorImpl, MemblockImpl >& t2 ) + { + return t2.equals( m_impl ); + } + + template< typename Other > + bool operator != ( const Alloc< Other, AllocatorImpl, MemblockImpl >& t2 ) + { + return !t2.equals( m_impl ); + } + + // These are extension functions not required for an stl allocator + size_t getNumAllocations() { return m_impl->getNumAllocations(); } + size_t getNumDeallocations() { return m_impl->getNumDeallocations(); } + size_t getNumBytesAllocated() { return m_impl->getNumBytesAllocated(); } + }; + + template<typename A> + template<typename T> + void _memblockimpl<A>::assign( const Alloc<T,A, _memblockimpl<A> >& src, _memblockimpl<A> *& dest ) + { + dest = const_cast<_memblockimpl<A>* >(src.m_impl); + } + +} + +#endif |