diff --git a/include/noncc/MSVC/1300/SmallObj.h b/include/noncc/MSVC/1300/SmallObj.h index d36be12..55cc0f7 100755 --- a/include/noncc/MSVC/1300/SmallObj.h +++ b/include/noncc/MSVC/1300/SmallObj.h @@ -13,7 +13,8 @@ // without express or implied warranty. //////////////////////////////////////////////////////////////////////////////// -// Last update: Nov 26, 2004 +// $Header$ + #ifndef SMALLOBJ_INC_ #define SMALLOBJ_INC_ @@ -40,14 +41,20 @@ namespace Loki { class FixedAllocator; +//////////////////////////////////////////////////////////////////////////////// +// class SmallObjAllocator +// Manages pool of fixed-size allocators. +//////////////////////////////////////////////////////////////////////////////// + class SmallObjAllocator { - public: + protected: SmallObjAllocator( std::size_t pageSize, std::size_t maxObjectSize, std::size_t objectAlignSize ); ~SmallObjAllocator( void ); + public: void * Allocate( std::size_t size, bool doThrow ); void Deallocate( void * p, std::size_t size ); @@ -57,6 +64,11 @@ namespace Loki inline std::size_t GetAlignment() const { return objectAlignSize_; } private: + /// Copy-constructor is not implemented. + SmallObjAllocator( const SmallObjAllocator & ); + /// Copy-assignment operator is not implemented. + SmallObjAllocator & operator = ( const SmallObjAllocator & ); + Loki::FixedAllocator * pool_; std::size_t maxSmallObjectSize_; @@ -64,6 +76,126 @@ namespace Loki std::size_t objectAlignSize_; }; +//////////////////////////////////////////////////////////////////////////////// +// class AllocatorSingleton +// This template class is derived from SmallObjAllocator in order to pass template +// arguments into SmallObjAllocator, and still have a default constructor for the +// singleton. +//////////////////////////////////////////////////////////////////////////////// + + template + < + template class ThreadingModel, + std::size_t chunkSize, + std::size_t maxSmallObjectSize, + std::size_t objectAlignSize + > + class AllocatorSingleton : public SmallObjAllocator + { + public: + inline AllocatorSingleton() : + SmallObjAllocator( chunkSize, maxSmallObjectSize, objectAlignSize ) + {} + inline ~AllocatorSingleton( void ) {} + + private: + /// Copy-constructor is not implemented. + AllocatorSingleton( const AllocatorSingleton & ); + /// Copy-assignment operator is not implemented. + AllocatorSingleton & operator = ( const AllocatorSingleton & ); + }; + + + +//////////////////////////////////////////////////////////////////////////////// +// class SmallObjectBase +// Base class for small object allocation classes. +//////////////////////////////////////////////////////////////////////////////// + + template + < + template class ThreadingModel, + std::size_t chunkSize, + std::size_t maxSmallObjectSize, + std::size_t objectAlignSize, + template class LifetimePolicy + > + class SmallObjectBase + { + +#if (MAX_SMALL_OBJECT_SIZE != 0) && (DEFAULT_CHUNK_SIZE != 0) && (LOKI_DEFAULT_OBJECT_ALIGNMENT != 0) + + /// Defines type of allocator. + typedef AllocatorSingleton< ThreadingModel, chunkSize, + maxSmallObjectSize, objectAlignSize > MyAllocator; + + /// Defines type for thread-safety locking mechanism. + typedef ThreadingModel< MyAllocator > MyThreadingModel; + + /// Defines singleton made from allocator. + typedef Loki::SingletonHolder< MyAllocator, Loki::CreateStatic, + LifetimePolicy, ThreadingModel > MyAllocatorSingleton; + + public: + + /** Throwing single-object new. + @note The exception specification is commented to prevent warning + from MS compiler. + */ + static void * operator new ( std::size_t size ) // throw ( std::bad_alloc ) + { + typename MyThreadingModel::Lock lock; + (void)lock; // get rid of warning + return MyAllocatorSingleton::Instance().Allocate( size, true ); + } + + /// Non-throwing single-object new. + static void * operator new ( std::size_t size, const std::nothrow_t & ) throw () + { + typename MyThreadingModel::Lock lock; + (void)lock; // get rid of warning + return MyAllocatorSingleton::Instance().Allocate( size, false ); + } + + /// Placement single-object new. + inline static void * operator new ( std::size_t size, void * place ) + { + return ::operator new( size, place ); + } + + /// Single-object delete. + static void operator delete ( void * p, std::size_t size ) throw () + { + typename MyThreadingModel::Lock lock; + (void)lock; // get rid of warning + MyAllocatorSingleton::Instance().Deallocate( p, size ); + } + + /// Non-throwing single-object delete. + static void operator delete ( void * p, std::size_t size, + const std::nothrow_t & ) throw() + { + typename MyThreadingModel::Lock lock; + (void)lock; // get rid of warning + MyAllocatorSingleton::Instance().Deallocate( p, size ); + } + + /// Placement single-object delete. + inline static void operator delete ( void * p, void * place ) + { + ::operator delete ( p, place ); + } + +#endif // #if default template parameters are not zero + + protected: + inline SmallObjectBase( void ) {} + inline SmallObjectBase( const SmallObjectBase & ) {} + inline SmallObjectBase & operator = ( const SmallObjectBase & ) {} + inline ~SmallObjectBase() {} + }; // end class SmallObjectBase + + //////////////////////////////////////////////////////////////////////////////// // class SmallObject // Base class for polymorphic small objects, offers fast allocations & @@ -75,84 +207,50 @@ namespace Loki template class ThreadingModel = DEFAULT_THREADING, std::size_t chunkSize = DEFAULT_CHUNK_SIZE, std::size_t maxSmallObjectSize = MAX_SMALL_OBJECT_SIZE, - std::size_t objectAlignSize = LOKI_DEFAULT_OBJECT_ALIGNMENT + std::size_t objectAlignSize = LOKI_DEFAULT_OBJECT_ALIGNMENT, + template class LifetimePolicy = Loki::NoDestroy > - class SmallObject : public ThreadingModel< - SmallObject< ThreadingModel, chunkSize, maxSmallObjectSize, objectAlignSize > > + class SmallObject : public SmallObjectBase< ThreadingModel, chunkSize, + maxSmallObjectSize, objectAlignSize, LifetimePolicy > { - typedef ThreadingModel< SmallObject > MyThreadingModel; - - struct MySmallObjAllocator : public SmallObjAllocator - { - MySmallObjAllocator() - : SmallObjAllocator( chunkSize, maxSmallObjectSize, objectAlignSize ) - {} - }; - // The typedef below would make things much simpler, - // but MWCW won't like it - // typedef SingletonHolder MyAllocator; - public: - -#if (MAX_SMALL_OBJECT_SIZE != 0) && (DEFAULT_CHUNK_SIZE != 0) && (LOKI_DEFAULT_OBJECT_ALIGNMENT != 0) - - /// Throwing single-object new. - static void * operator new ( std::size_t size ) throw ( std::bad_alloc ) - { - typename MyThreadingModel::Lock lock; - (void)lock; // get rid of warning - return SingletonHolder< MySmallObjAllocator, CreateStatic, - NoDestroy >::Instance().Allocate( size, true ); - } - - /// Non-throwing single-object new. - static void * operator new ( std::size_t size, const std::nothrow_t & ) throw () - { - typename MyThreadingModel::Lock lock; - (void)lock; // get rid of warning - return SingletonHolder< MySmallObjAllocator, CreateStatic, - NoDestroy >::Instance().Allocate( size, false ); - } - - /// Placement single-object new. - static void * operator new ( std::size_t size, void * place ) - { - return ::operator new( size, place ); - } - - /// Single-object delete. - static void operator delete ( void * p, std::size_t size ) throw () - { - typename MyThreadingModel::Lock lock; - (void)lock; // get rid of warning - SingletonHolder< MySmallObjAllocator, CreateStatic, - NoDestroy >::Instance().Deallocate( p, size ); - } - - /// Non-throwing single-object delete. - static void operator delete ( void * p, std::size_t size, - const std::nothrow_t & ) throw() - { - typename MyThreadingModel::Lock lock; - (void)lock; // get rid of warning - SingletonHolder< MySmallObjAllocator, CreateStatic, - NoDestroy >::Instance().Deallocate( p, size ); - } - - /// Placement single-object delete. - static void operator delete ( void * p, void * place ) - { - ::operator delete ( p, place ); - } - -#endif // #if default template parameters are not zero - virtual ~SmallObject() {} + protected: + inline SmallObject( void ) {} + + private: + /// Copy-constructor is not implemented. + SmallObject( const SmallObject & ); + /// Copy-assignment operator is not implemented. + SmallObject & operator = ( const SmallObject & ); }; // end class SmallObject + +//////////////////////////////////////////////////////////////////////////////// +// class SmallValueObject +// Base class for small objects with value semantics - offers fast allocations & +// deallocations. Destructor is non-virtual, inline, and protected. +//////////////////////////////////////////////////////////////////////////////// + + template + < + template class ThreadingModel = DEFAULT_THREADING, + std::size_t chunkSize = DEFAULT_CHUNK_SIZE, + std::size_t maxSmallObjectSize = MAX_SMALL_OBJECT_SIZE, + std::size_t objectAlignSize = LOKI_DEFAULT_OBJECT_ALIGNMENT, + template class LifetimePolicy = Loki::NoDestroy + > + class SmallValueObject : public SmallObjectBase< ThreadingModel, chunkSize, + maxSmallObjectSize, objectAlignSize, LifetimePolicy > + { + protected: + inline SmallValueObject( void ) {} + inline SmallValueObject( const SmallValueObject & ) {} + inline SmallValueObject & operator = ( const SmallValueObject & ) {} + inline ~SmallValueObject() {} + }; // end class SmallValueObject + } // namespace Loki //////////////////////////////////////////////////////////////////////////////// @@ -163,3 +261,7 @@ namespace Loki #endif // SMALLOBJ_INC_ +// $Log$ +// Revision 1.2 2005/07/22 00:22:38 rich_sposato +// Added SmallValueObject, SmallObjectBase, and AllocatorSingleton classes. +//