410 lines
14 KiB
C++
410 lines
14 KiB
C++
// ____ ______ __
|
|
// / __ \ / ____// /
|
|
// / /_/ // / / /
|
|
// / ____// /___ / /___ PixInsight Class Library
|
|
// /_/ \____//_____/ PCL 2.4.23
|
|
// ----------------------------------------------------------------------------
|
|
// pcl/Allocator.h - Released 2022-03-12T18:59:29Z
|
|
// ----------------------------------------------------------------------------
|
|
// This file is part of the PixInsight Class Library (PCL).
|
|
// PCL is a multiplatform C++ framework for development of PixInsight modules.
|
|
//
|
|
// Copyright (c) 2003-2022 Pleiades Astrophoto S.L. All Rights Reserved.
|
|
//
|
|
// Redistribution and use in both source and binary forms, with or without
|
|
// modification, is permitted provided that the following conditions are met:
|
|
//
|
|
// 1. All redistributions of source code must retain the above copyright
|
|
// notice, this list of conditions and the following disclaimer.
|
|
//
|
|
// 2. All redistributions in binary form must reproduce the above copyright
|
|
// notice, this list of conditions and the following disclaimer in the
|
|
// documentation and/or other materials provided with the distribution.
|
|
//
|
|
// 3. Neither the names "PixInsight" and "Pleiades Astrophoto", nor the names
|
|
// of their contributors, may be used to endorse or promote products derived
|
|
// from this software without specific prior written permission. For written
|
|
// permission, please contact info@pixinsight.com.
|
|
//
|
|
// 4. All products derived from this software, in any form whatsoever, must
|
|
// reproduce the following acknowledgment in the end-user documentation
|
|
// and/or other materials provided with the product:
|
|
//
|
|
// "This product is based on software from the PixInsight project, developed
|
|
// by Pleiades Astrophoto and its contributors (https://pixinsight.com/)."
|
|
//
|
|
// Alternatively, if that is where third-party acknowledgments normally
|
|
// appear, this acknowledgment must be reproduced in the product itself.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY PLEIADES ASTROPHOTO AND ITS CONTRIBUTORS
|
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PLEIADES ASTROPHOTO OR ITS
|
|
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
// EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, BUSINESS
|
|
// INTERRUPTION; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; AND LOSS OF USE,
|
|
// DATA OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
// POSSIBILITY OF SUCH DAMAGE.
|
|
// ----------------------------------------------------------------------------
|
|
|
|
#ifndef __PCL_Allocator_h
|
|
#define __PCL_Allocator_h
|
|
|
|
/// \file pcl/Allocator.h
|
|
|
|
#include <pcl/Defs.h>
|
|
#include <pcl/Diagnostics.h>
|
|
|
|
#include <pcl/Relational.h>
|
|
#include <pcl/Utility.h>
|
|
|
|
namespace pcl
|
|
{
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \class Allocator
|
|
* \brief Provides memory allocation for PCL containers.
|
|
*
|
|
* %Allocator inherits directly from its template argument A, which
|
|
* corresponds to a <em>block allocator</em> class. A block allocator is
|
|
* responsible for allocation and deallocation of untyped blocks of contiguous
|
|
* memory. %Allocator inherits block allocation capabilities and specializes
|
|
* them for allocation of a particular type T.
|
|
*
|
|
* The type T must have default and copy construction semantics.
|
|
*
|
|
* Besides the default and copy constructors, the block allocator class A must
|
|
* define the following member functions:
|
|
*
|
|
* \code
|
|
* size_type A::MaxSize() const
|
|
* \endcode
|
|
*
|
|
* Returns the maximum size in bytes that the block allocator is able to
|
|
* allocate as a contiguous memory block.
|
|
*
|
|
* \code
|
|
* size_type A::BlockSize( size_type n ) const
|
|
* \endcode
|
|
*
|
|
* Returns the size in bytes of an <em>allocation block</em> suitable to store
|
|
* at least \a n contiguous bytes. %Allocator uses this block size to reserve
|
|
* memory in chunks of optimized length. This greatly improves efficiency of
|
|
* containers because it minimizes the frequency of allocation/deallocation
|
|
* operations.
|
|
*
|
|
* \code
|
|
* size_type A::ReallocatedBlockSize( size_type currentSize, size_type newSize ) const
|
|
* \endcode
|
|
*
|
|
* Returns the size in bytes of a reallocated block. \a currentSize is the
|
|
* current size in bytes of the block being reallocated, and \a newSize is the
|
|
* requested block size. This function is similar to A::BlockSize(), but it is
|
|
* called for reallocation of already existing data blocks, for example before
|
|
* deleting a subset of container elements.
|
|
*
|
|
* \code
|
|
* void* AllocateBlock( size_type sz )
|
|
* \endcode
|
|
*
|
|
* Custom allocation routine. Allocates a contiguous memory block of length
|
|
* \a sz in bytes, and returns the address of the first byte in the newly
|
|
* allocated block.
|
|
*
|
|
* \code
|
|
* void DeallocateBlock( void* p )
|
|
* \endcode
|
|
*
|
|
* Custom deallocation routine. Deallocates a contiguous block of memory that
|
|
* has been previously allocated by any allocator of class A.
|
|
*
|
|
* StandardAllocator is an example of a block allocator that uses the standard
|
|
* \c new and \c delete operators.
|
|
*
|
|
* \sa StandardAllocator
|
|
*/
|
|
template <class T, class A>
|
|
class PCL_CLASS Allocator : public A
|
|
{
|
|
public:
|
|
|
|
/*!
|
|
* Default constructor.
|
|
*/
|
|
Allocator() = default;
|
|
|
|
/*!
|
|
* Copy constructor.
|
|
*/
|
|
Allocator( const Allocator<T,A>& ) = default;
|
|
|
|
/*!
|
|
* Constructs an %Allocator instance as a copy of other block allocator.
|
|
*/
|
|
Allocator( const A& a )
|
|
: A( a )
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* Allocates a contiguous block of memory, sufficient to store at least \a n
|
|
* instance of class T. Optionally, allocates the necessary space for \a n
|
|
* objects plus \a extra additional bytes.
|
|
*
|
|
* Returns the starting address of the allocated block.
|
|
*
|
|
* \note This member function <em>does not construct</em> any T instance;
|
|
* it only allocates the required memory to store \a n instances of T.
|
|
*/
|
|
T* Allocate( size_type n, size_type extra = 0 )
|
|
{
|
|
PCL_PRECONDITION( n+extra > 0 )
|
|
return (T*)this->AllocateBlock( n*sizeof( T )+extra );
|
|
//return (T*)new ( *this ) uint8[ n*sizeof( T )+extra ];
|
|
}
|
|
|
|
/*!
|
|
* Deallocates a block of memory.
|
|
*
|
|
* \note This member function <em>does not destruct</em> any T instance; it
|
|
* only deallocates a previously allocated block where an unspecified number
|
|
* of T instances might be stored (either constructed or not).
|
|
*/
|
|
void Deallocate( T* p )
|
|
{
|
|
PCL_PRECONDITION( p != nullptr )
|
|
this->DeallocateBlock( (void*)p );
|
|
//this->operator delete( (void*)p );
|
|
}
|
|
|
|
/*!
|
|
* Returns the maximum number of instances of class T that this allocator
|
|
* can allocate.
|
|
*/
|
|
size_type MaxLength() const
|
|
{
|
|
return A::MaxSize()/sizeof( T );
|
|
}
|
|
|
|
/*!
|
|
* Returns the length of a newly allocated data block.
|
|
*
|
|
* Given a number \a n of T instances, returns the corresponding <em>paged
|
|
* length</em> for this allocator. The paged length is the actual number of
|
|
* T instances that would be allocated instead of \a n, which depends on the
|
|
* block allocation policy implemented by the block allocator class.
|
|
*
|
|
* The value returned by this member function is always greater than or
|
|
* equal to \a n.
|
|
*
|
|
* \sa ShrunkLength()
|
|
*/
|
|
size_type PagedLength( size_type n ) const
|
|
{
|
|
return A::BlockSize( n*sizeof( T ) )/sizeof( T );
|
|
}
|
|
|
|
/*!
|
|
* Returns the length of a reallocated data block.
|
|
*
|
|
* \param currentLength The current length of an allocated data block.
|
|
*
|
|
* \param newLength The new length of the reallocated data block.
|
|
*
|
|
* The returned length is the actual number of T instances that would be
|
|
* allocated instead of \a newLength, which depends on the block allocation
|
|
* policy implemented by the block allocator class.
|
|
*
|
|
* The value returned by this member function is always greater than or
|
|
* equal to \a n.
|
|
*
|
|
* \sa PagedLength()
|
|
*/
|
|
size_type ReallocatedLength( size_type currentLength, size_type newLength ) const
|
|
{
|
|
return A::ReallocatedBlockSize( currentLength*sizeof( T ), newLength*sizeof( T ) )/sizeof( T );
|
|
}
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*!
|
|
* \defgroup object_construction_destruction Construction and \
|
|
* Destruction of Objects with Explicit Allocation
|
|
*/
|
|
|
|
/*!
|
|
* Constructs an object with storage at address \a p and allocator \a a. This
|
|
* function invokes the default constructor of class T for the object stored at
|
|
* \a p.
|
|
* \sa Allocator
|
|
* \ingroup object_construction_destruction
|
|
*/
|
|
template <class T, class A> inline void Construct( T* p, A& a )
|
|
{
|
|
PCL_PRECONDITION( p != nullptr )
|
|
new( (void*)p, a )T();
|
|
}
|
|
|
|
/*!
|
|
* Constructs an object with storage at address \a p, initial value \a v, and
|
|
* allocator \a a. This function invokes the copy constructor of class T, with
|
|
* argument \a v, for the object stored at \a p.
|
|
* \sa Allocator
|
|
* \ingroup object_construction_destruction
|
|
*/
|
|
template <class T, class T1, class A> inline void Construct( T* p, const T1& v, A& a )
|
|
{
|
|
PCL_PRECONDITION( p != nullptr )
|
|
new( (void*)p, a )T( v );
|
|
}
|
|
|
|
#ifdef _MSC_VER
|
|
# pragma warning( push )
|
|
# pragma warning( disable : 4100 ) // unreferenced formal parameter
|
|
#endif // (VC++ limitation !?)
|
|
|
|
/*!
|
|
* Destroys an object stored at address \a p. Invokes the destructor of
|
|
* class T for the object stored at \a p.
|
|
* \sa Allocator
|
|
* \ingroup object_construction_destruction
|
|
*/
|
|
template <class T> inline void Destroy( T* p )
|
|
{
|
|
PCL_PRECONDITION( p != nullptr )
|
|
p->~T();
|
|
}
|
|
|
|
/*!
|
|
* Destroys a contiguous sequence of objects. Invokes the destructor of class
|
|
* T for each object in the range [p,q).
|
|
* \sa Allocator
|
|
* \ingroup object_construction_destruction
|
|
*/
|
|
template <class T> inline void Destroy( T* p, T* q )
|
|
{
|
|
PCL_PRECONDITION( p != nullptr && q != nullptr )
|
|
for ( ; p < q; ++p )
|
|
p->~T();
|
|
}
|
|
|
|
#ifdef _MSC_VER
|
|
# pragma warning( pop )
|
|
#endif
|
|
|
|
inline void Destroy( void* ) {}
|
|
inline void Destroy( void*, void* ) {}
|
|
|
|
inline void Destroy( bool* ) {}
|
|
inline void Destroy( bool*, bool* ) {}
|
|
|
|
inline void Destroy( signed char* ) {}
|
|
inline void Destroy( signed char*, signed char* ) {}
|
|
|
|
inline void Destroy( unsigned char* ) {}
|
|
inline void Destroy( unsigned char*, unsigned char* ) {}
|
|
|
|
inline void Destroy( wchar_t* ) {}
|
|
inline void Destroy( wchar_t*, wchar_t* ) {}
|
|
|
|
inline void Destroy( char16_t* ) {}
|
|
inline void Destroy( char16_t*, char16_t* ) {}
|
|
|
|
inline void Destroy( char32_t* ) {}
|
|
inline void Destroy( char32_t*, char32_t* ) {}
|
|
|
|
inline void Destroy( signed int* ) {}
|
|
inline void Destroy( signed int*, signed int* ) {}
|
|
|
|
inline void Destroy( unsigned int* ) {}
|
|
inline void Destroy( unsigned int*, unsigned int* ) {}
|
|
|
|
inline void Destroy( signed short* ) {}
|
|
inline void Destroy( signed short*, signed short* ) {}
|
|
|
|
inline void Destroy( unsigned short* ) {}
|
|
inline void Destroy( unsigned short*, unsigned short* ) {}
|
|
|
|
inline void Destroy( signed long* ) {}
|
|
inline void Destroy( signed long*, signed long* ) {}
|
|
|
|
inline void Destroy( unsigned long* ) {}
|
|
inline void Destroy( unsigned long*, unsigned long* ) {}
|
|
|
|
inline void Destroy( signed long long* ) {}
|
|
inline void Destroy( signed long long*, signed long long* ) {}
|
|
|
|
inline void Destroy( unsigned long long* ) {}
|
|
inline void Destroy( unsigned long long*, unsigned long long* ) {}
|
|
|
|
inline void Destroy( float* ) {}
|
|
inline void Destroy( float*, float* ) {}
|
|
|
|
inline void Destroy( double* ) {}
|
|
inline void Destroy( double*, double* ) {}
|
|
|
|
inline void Destroy( long double* ) {}
|
|
inline void Destroy( long double*, long double* ) {}
|
|
|
|
inline void Destroy( void** ) {}
|
|
inline void Destroy( void**, void** ) {}
|
|
|
|
inline void Destroy( bool** ) {}
|
|
inline void Destroy( bool**, bool** ) {}
|
|
|
|
inline void Destroy( signed char** ) {}
|
|
inline void Destroy( signed char**, signed char** ) {}
|
|
|
|
inline void Destroy( unsigned char** ) {}
|
|
inline void Destroy( unsigned char**, unsigned char** ) {}
|
|
|
|
inline void Destroy( wchar_t** ) {}
|
|
inline void Destroy( wchar_t**, wchar_t** ) {}
|
|
|
|
inline void Destroy( signed int** ) {}
|
|
inline void Destroy( signed int**, signed int** ) {}
|
|
|
|
inline void Destroy( unsigned int** ) {}
|
|
inline void Destroy( unsigned int**, unsigned int** ) {}
|
|
|
|
inline void Destroy( signed short** ) {}
|
|
inline void Destroy( signed short**, signed short** ) {}
|
|
|
|
inline void Destroy( unsigned short** ) {}
|
|
inline void Destroy( unsigned short**, unsigned short** ) {}
|
|
|
|
inline void Destroy( signed long** ) {}
|
|
inline void Destroy( signed long**, signed long** ) {}
|
|
|
|
inline void Destroy( unsigned long** ) {}
|
|
inline void Destroy( unsigned long**, unsigned long** ) {}
|
|
|
|
inline void Destroy( signed long long** ) {}
|
|
inline void Destroy( signed long long**, signed long long** ) {}
|
|
|
|
inline void Destroy( unsigned long long** ) {}
|
|
inline void Destroy( unsigned long long**, unsigned long long** ) {}
|
|
|
|
inline void Destroy( float** ) {}
|
|
inline void Destroy( float**, float** ) {}
|
|
|
|
inline void Destroy( double** ) {}
|
|
inline void Destroy( double**, double** ) {}
|
|
|
|
inline void Destroy( long double** ) {}
|
|
inline void Destroy( long double**, long double** ) {}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
} // pcl
|
|
|
|
#endif // __PCL_Allocator_h
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// EOF pcl/Allocator.h - Released 2022-03-12T18:59:29Z
|