Adding class to wrap small object allocator for STL containers.
git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@837 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
parent
3179302021
commit
b6d6abd191
1 changed files with 147 additions and 0 deletions
147
include/loki/Allocator.h
Normal file
147
include/loki/Allocator.h
Normal file
|
@ -0,0 +1,147 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// The Loki Library
|
||||
// Copyright (c) 2008 by Rich Sposato
|
||||
//
|
||||
// Permission to use, copy, modify, distribute and sell this software for any
|
||||
// purpose is hereby granted without fee, provided that the above copyright
|
||||
// notice appear in all copies and that both that copyright notice and this
|
||||
// permission notice appear in supporting documentation.
|
||||
// The author makes no representations about the
|
||||
// suitability of this software for any purpose. It is provided "as is"
|
||||
// without express or implied warranty.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LOKI_ALLOCATOR_HPP_INCLUDED
|
||||
#define LOKI_ALLOCATOR_HPP_INCLUDED
|
||||
|
||||
// $Id$
|
||||
|
||||
// Requires project to be compiled with loki/src/SmallObj.cpp and loki/src/Singleton.cpp
|
||||
|
||||
#include <loki/SmallObj.h>
|
||||
|
||||
|
||||
namespace Loki
|
||||
{
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** @class LokiAllocator
|
||||
Adapts Loki's Small-Object Allocator for STL container classes.
|
||||
This class provides all the functionality required for STL allocators, but
|
||||
uses Loki's Small-Object Allocator to perform actual memory operations.
|
||||
Implementation comes from a post in Loki forums (by Rasmus Ekman?).
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename Type,
|
||||
typename AllocT = Loki::AllocatorSingleton<>
|
||||
>
|
||||
class LokiAllocator
|
||||
{
|
||||
public:
|
||||
|
||||
typedef ::std::size_t size_type;
|
||||
typedef ::std::ptrdiff_t difference_type;
|
||||
typedef Type * pointer;
|
||||
typedef const Type * const_pointer;
|
||||
typedef Type & reference;
|
||||
typedef const Type & const_reference;
|
||||
typedef Type value_type;
|
||||
|
||||
/// Default constructor does nothing.
|
||||
inline LokiAllocator( void ) throw() { }
|
||||
|
||||
/// Copy constructor does nothing.
|
||||
inline LokiAllocator( const LokiAllocator & ) throw() { }
|
||||
|
||||
/// Type converting allocator constructor does nothing.
|
||||
template < typename Type1 >
|
||||
inline LokiAllocator( const LokiAllocator< Type1 > & ) throw() { }
|
||||
|
||||
/// Destructor does nothing.
|
||||
inline ~LokiAllocator() throw() { }
|
||||
|
||||
/// Convert an allocator<Type> to an allocator <Type1>.
|
||||
template < typename Type1 >
|
||||
struct rebind
|
||||
{
|
||||
typedef LokiAllocator< Type1 > other;
|
||||
};
|
||||
|
||||
/// Return address of reference to mutable element.
|
||||
pointer address( reference elem ) const { return &elem; }
|
||||
|
||||
/// Return address of reference to const element.
|
||||
const_pointer address( const_reference elem ) const { return &elem; }
|
||||
|
||||
/** Allocate an array of count elements. Warning! The true parameter in
|
||||
the call to Allocate means this function can throw exceptions.
|
||||
@param count # of elements in array.
|
||||
@param hint Place where caller thinks allocation should occur.
|
||||
@return Pointer to block of memory.
|
||||
*/
|
||||
pointer allocate( size_type count, const void * hint = 0 )
|
||||
{
|
||||
(void)hint; // Ignore the hint.
|
||||
void * p = AllocT::Instance().Allocate( count * sizeof( Type ), true );
|
||||
return reinterpret_cast< pointer >( p );
|
||||
}
|
||||
|
||||
/// Ask allocator to release memory at pointer with size bytes.
|
||||
void deallocate( pointer p, size_type size )
|
||||
{
|
||||
AllocT::Instance().Deallocate( p, size * sizeof( Type ) );
|
||||
}
|
||||
|
||||
/// Calculate max # of elements allocator can handle.
|
||||
size_type max_size( void ) const throw()
|
||||
{
|
||||
// A good optimizer will see these calculations always produce the same
|
||||
// value and optimize this function away completely.
|
||||
const size_type max_bytes = size_type( -1 );
|
||||
const size_type bytes = max_bytes / sizeof( Type );
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/// Construct an element at the pointer.
|
||||
void construct( pointer p, const Type & value )
|
||||
{
|
||||
// A call to global placement new forces a call to copy constructor.
|
||||
::new( p ) Type( value );
|
||||
}
|
||||
|
||||
/// Destruct the object at pointer.
|
||||
void destroy( pointer p )
|
||||
{
|
||||
p->~Type();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** All equality operators return true since LokiAllocator is basically a
|
||||
monostate design pattern, so all instances of it are identical.
|
||||
*/
|
||||
template < typename Type >
|
||||
inline bool operator == ( const LokiAllocator< Type > &, const LokiAllocator< Type > & )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/** All inequality operators return false since LokiAllocator is basically a
|
||||
monostate design pattern, so all instances of it are identical.
|
||||
*/
|
||||
template < typename Type >
|
||||
inline bool operator != ( const LokiAllocator< Type > & , const LokiAllocator< Type > & )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
} // namespace Loki
|
||||
|
||||
#endif // LOKI_ALLOCATOR_INCLUDED
|
Loading…
Reference in a new issue