// ____ ______ __ // / __ \ / ____// / // / /_/ // / / / // / ____// /___ / /___ 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 #include #include #include namespace pcl { // ---------------------------------------------------------------------------- /*! * \class Allocator * \brief Provides memory allocation for PCL containers. * * %Allocator inherits directly from its template argument A, which * corresponds to a block allocator 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 allocation block 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 PCL_CLASS Allocator : public A { public: /*! * Default constructor. */ Allocator() = default; /*! * Copy constructor. */ Allocator( const Allocator& ) = 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 does not construct 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 does not destruct 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 paged * length 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 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 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 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 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