You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
210 lines
6.8 KiB
210 lines
6.8 KiB
// Copyright 2020 Siemens Digital Industries Software
|
|
// ==================================================
|
|
// Copyright 2014.
|
|
// Siemens Product Lifecycle Management Software Inc.
|
|
// All Rights Reserved.
|
|
// ==================================================
|
|
// Copyright 2020 Siemens Digital Industries Software
|
|
|
|
/**
|
|
@file
|
|
|
|
Template class that stores a pointer to an object. It ensures that object to which it points
|
|
gets destroyed automatically when the instance of this class goes out of scope.
|
|
|
|
This is intended for reference only, not for general customization use.
|
|
*/
|
|
|
|
#ifndef TEAMCENTER_BASE_UTILS_SCOPED_PTR_HXX
|
|
#define TEAMCENTER_BASE_UTILS_SCOPED_PTR_HXX
|
|
|
|
#include <base_utils/libbase_utils_exports.h>
|
|
|
|
namespace Teamcenter
|
|
{
|
|
|
|
/**
|
|
Default deallocator functor for scoped_ptr.
|
|
<br>Use this as template when supplying custom deallocator.
|
|
*/
|
|
template < class T > struct scoped_ptr_default_deallocator
|
|
{
|
|
void operator() (T* bucket) const { delete bucket; }
|
|
};
|
|
|
|
/**
|
|
@brief Template class that stores a pointer to an object and ensures that the object
|
|
gets destroyed automatically when instance of this class goes out of scope.
|
|
|
|
<h2> Things to be aware of when using scoped_ptr.</h2>
|
|
<br>Allocation scheme used: By default, scoped_ptr provides support for object that was allocated using 'operator new'.
|
|
<br>If any other mechanism of allocation is used, then the custom deallocator needs to be supplied.
|
|
Use scoped_ptr_default_deallocator for reference when providing a custom deallocator.
|
|
|
|
<h2> Example. </h2>
|
|
@code
|
|
// example.
|
|
struct Dummy
|
|
{
|
|
int a;
|
|
int b;
|
|
};
|
|
|
|
void allocateDummy( Dummy** ptr )
|
|
{
|
|
*ptr = new Dummy;
|
|
}
|
|
|
|
// does nothing. purpose here is to only use this function's signature
|
|
// as an example.
|
|
void acceptDummyPtr( const Dummy* ptr )
|
|
{
|
|
}
|
|
|
|
// Incorrect usage pattern.
|
|
void incorrectUsage()
|
|
{
|
|
Dummy* dummyPtr = NULL;
|
|
scoped_ptr<Dummy> freeMe( dummyPtr ); // as 'aptr' is NULL, the scoped_ptr owns a pointer with NULL value.
|
|
|
|
allocateDummy( &dummyPtr ); // the scoped_ptr is unaware about this allocation and leads to a memory leak.
|
|
}
|
|
|
|
void recommendedUsage()
|
|
{
|
|
// scoped_ptr can be passed around like a normal pointer.
|
|
// Its best to avoid using two named variables (one for the normal pointer and other scoped_ptr) and
|
|
// use the scoped_ptr just like normal pointer.
|
|
|
|
scoped_ptr< Dummy > sptr;
|
|
allocatedDummy( &sptr );
|
|
|
|
// use like a normal pointer.
|
|
sptr->a = 1;
|
|
|
|
// pass the contained pointer using get() method.
|
|
// Note: conversion is explicit intentianally. Implicit conversion can have some issues.
|
|
acceptDummyPtr( sptr.get() );
|
|
}
|
|
@endcode
|
|
|
|
<h2> scoped_ptr vs. std::auto_ptr </h2>
|
|
<br>Most of the capabilities of scoped_ptr are provided by std::auto_ptr.
|
|
<br>The reason we provided our own class is due to strictness. If an auto_ptr is copied, the source loses the reference. This ensures that only one auto_ptr
|
|
is responsible for the object's lifetime. However, this can lead to subtle issues (say during implicit copying , etc.).
|
|
scoped_ptr is more strict and doesn't allow such copying.
|
|
*/
|
|
template < class T, class F=scoped_ptr_default_deallocator< T > > class scoped_ptr
|
|
{
|
|
public:
|
|
|
|
/**
|
|
Default constructor. It stores the pointer to an object.
|
|
*/
|
|
explicit scoped_ptr( T* b = 0 ) : bucket( b ) {}
|
|
|
|
/**
|
|
Default destructor. It also deletes the object to which it points.
|
|
*/
|
|
virtual ~scoped_ptr() { F f; f( bucket ); } /* */
|
|
|
|
/**
|
|
Deletes the pointer being held currently and then holds the input pointer.
|
|
*/
|
|
scoped_ptr& operator=( T * ptr ) { F f; f( bucket ); bucket = ptr; return *this; }
|
|
|
|
T** operator&() { bucket = 0; return &bucket; }
|
|
T& operator*() const { return *bucket; }
|
|
T* operator->() const { return bucket; }
|
|
|
|
operator T*() const { return bucket; }
|
|
/* */
|
|
|
|
/**
|
|
Returns the pointer to the object.
|
|
*/
|
|
T* get() const { return bucket; }
|
|
|
|
/**
|
|
Safe getter of the string of elements of type T.
|
|
|
|
It returns the memory pointed by this object, or a pointer to a default constructed element
|
|
if the object does not point to any memory.
|
|
<br>This is particularly useful if the object manages memory of a C-string, because it can
|
|
be used for a NULL-safe assignment to a std::string.
|
|
*/
|
|
const T* getString() const { static const T s_empty = T(); return bucket ? bucket : &s_empty; }
|
|
|
|
/**
|
|
Releases the pointer without deleting the object to which it points.
|
|
*/
|
|
T* release() { T* tmp = bucket; bucket = 0; return tmp; }
|
|
|
|
bool operator == (const T* t) const { return bucket == t; }
|
|
bool operator != (const T* t) const { return bucket != t; }
|
|
|
|
bool operator! () const
|
|
{
|
|
return bucket == 0;
|
|
}
|
|
|
|
protected:
|
|
/**
|
|
Contains the pointer to an object.
|
|
*/
|
|
T* bucket;
|
|
|
|
private:
|
|
scoped_ptr( const scoped_ptr& );
|
|
scoped_ptr& operator = ( const scoped_ptr& );
|
|
};
|
|
|
|
/** Frees an unpacked array of strings that have been allocated using Storage Management (SM) memory management. */
|
|
extern BASE_UTILS_API void free_unpacked_SM_string_array ( char ** array );
|
|
|
|
/**
|
|
@brief Deallocator for an SM allocated <i>unpacked</i> array strings.
|
|
|
|
By unpacked array, we mean that an array of pointers, where the pointer points to
|
|
an array allocated separately.
|
|
<br>Both the array of pointers and the character array should be allocated via SM API.
|
|
|
|
@code
|
|
|
|
void allocateStringArray( char*** ptr )
|
|
{
|
|
// this allocates an SM array of pointer
|
|
// and then allocates space for each array.
|
|
}
|
|
|
|
int main()
|
|
{
|
|
// allocate an array of char* using SM.
|
|
// The pointer in the array inturn points to character array allocated using SM.
|
|
char** stringArray;
|
|
allocateStringArray( &stringArray );
|
|
|
|
// Declaring a scoped_smptr with appropriate deallocator will take care of deallocation.
|
|
scoped_ptr< char*, StringArrayFreer > myFreer( stringArray );
|
|
|
|
// Recommended usage : where possible, instead of two named variables use the scoped_ptr in the
|
|
// place of normal pointer.
|
|
scoped_ptr< char*, StringArrayFreer > stringArray2;
|
|
allocateStringArray( &stringArray2 );
|
|
|
|
char tmp = stringArray2[0][0]; // use like a normal array.
|
|
}
|
|
@endcode
|
|
*/
|
|
struct StringArrayFreer
|
|
{
|
|
void operator() ( char** bucket ) { free_unpacked_SM_string_array ( bucket ); };
|
|
void operator() ( const char** bucket ) { free_unpacked_SM_string_array ( (char**) bucket ); };
|
|
};
|
|
|
|
}// end namespace Teamcenter
|
|
|
|
#include <base_utils/libbase_utils_undef.h>
|
|
|
|
#endif // TEAMCENTER_BASE_UTILS_SCOPED_PTR_HXX
|