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.
229 lines
6.1 KiB
229 lines
6.1 KiB
// Copyright 2020 Siemens Digital Industries Software
|
|
// ==================================================
|
|
// Copyright 2017.
|
|
// Siemens Product Lifecycle Management Software Inc.
|
|
// All Rights Reserved.
|
|
// ==================================================
|
|
// Copyright 2020 Siemens Digital Industries Software
|
|
|
|
/**
|
|
@file
|
|
Template class that stores a pointer pointing to memory allocated using SM
|
|
(Storage Management module from libsyss).
|
|
<br>It ensures that memory is freed automatically when an instance of this
|
|
class goes out of scope.
|
|
*/
|
|
|
|
#ifndef TEAMCENTER_BASE_UTILS_SCOPED_SM_PTR_HXX
|
|
#define TEAMCENTER_BASE_UTILS_SCOPED_SM_PTR_HXX
|
|
|
|
#include <cstdlib>
|
|
/* */
|
|
#include <base_utils/Mem.h>
|
|
|
|
namespace Teamcenter
|
|
{
|
|
/**
|
|
The default deallocator function for scoped_smptr.
|
|
<br>Use this as template when supplying custom deallocator.
|
|
*/
|
|
template < class T > struct scoped_smptr_my_deallocator
|
|
{
|
|
void operator() (T* bucket) const { MEM_free(bucket); }
|
|
};
|
|
/**
|
|
@brief Template class that stores a pointer pointing to memory allocated using some SM
|
|
(Storage Management module from NX) allocation API. It ensures that memory is freed automatically
|
|
when the instance of this class goes out of scope.
|
|
|
|
<h2> Things to be aware of when using scoped_smptr</h2>
|
|
Allocation scheme: scoped_smptr <b>requires that memory be allocated via SM </b> (Storage Management module
|
|
from NX) API (e.g. MEM_alloc, etc.). <br>
|
|
2) scoped_smptr cannot be used for a class which uses SM memory via 'operator new' override. <br>
|
|
Though the memory may be freed OK, the destructor wont be called and may lead to issues. <br>
|
|
<br>
|
|
|
|
<h2> Example </h2>
|
|
@code
|
|
// example.
|
|
|
|
// allocate some SM memory
|
|
void allocateSomeSmMemory( int** ptr )
|
|
{
|
|
*ptr = (int*) MEM_alloc( 10 * sizeof( int ) );
|
|
}
|
|
|
|
void fooAcceptsIntPtr( const int* ptr )
|
|
{
|
|
[...]
|
|
}
|
|
|
|
void incorrectUsage()
|
|
{
|
|
int* ptr0 = 0;
|
|
|
|
// scoped_smptr internally stores the value of supplied pointer and uses it for cleanup when it goes out of scope.
|
|
// As the value of 'ptr0' is 0, the value stored internally by 'smptr' is 0.
|
|
scoped_smptr< int > smptr( ptr0 );
|
|
|
|
allocateSomeSmMemory( &ptr0 ); // 'smptr' is not aware about this allocation. This leads to a memory leak!
|
|
}
|
|
|
|
// scoped_ptr can be used just like a normal pointer.
|
|
// It is best to avoid using two named variables (one for the normal pointer and other scoped_smptr) and
|
|
// use the scoped_smptr just like normal pointer.
|
|
void recommendedUsage()
|
|
{
|
|
scoped_smptr< int > smptr;
|
|
allocatedDummy( &smptr );
|
|
|
|
// use like a normal pointer.
|
|
smptr[0] = 1;
|
|
|
|
// pass around like a normal pointer.
|
|
fooAcceptsIntPtr( smptr );
|
|
}
|
|
@endcode
|
|
*/
|
|
|
|
template <class T, class F=scoped_smptr_my_deallocator< T > > class scoped_smptr
|
|
{
|
|
public:
|
|
/**
|
|
Constructor.
|
|
Note that no conversion will be allowed: the pointer needs to be of the specified type (T).
|
|
*/
|
|
explicit scoped_smptr( T* b = 0 ) : bucket( b ) {}
|
|
|
|
/**
|
|
Default destructor. It also deletes the object to which it points.
|
|
*/
|
|
virtual ~scoped_smptr() { F f; f( bucket ); } /* */
|
|
|
|
|
|
/**
|
|
Operator =
|
|
<br>If the scoped pointer was already assigned, the current assignment is removed (memory is freed)
|
|
and replaced with the requested pointed.
|
|
*/
|
|
scoped_smptr & operator=(T * ptr) { F f; f(bucket); bucket = ptr; return *this; }
|
|
|
|
/**
|
|
Operator &
|
|
*/
|
|
T** operator&() { return &bucket; }
|
|
|
|
/**
|
|
Operator *
|
|
*/
|
|
T& operator*() const { return *bucket; }
|
|
|
|
/**
|
|
Operator ->
|
|
*/
|
|
T* operator->() const { return bucket; }
|
|
|
|
/**
|
|
Operator []
|
|
*/
|
|
const T& operator[](std::size_t inx) const { return bucket[inx]; }
|
|
|
|
/**
|
|
Operator []
|
|
*/
|
|
T& operator[](std::size_t inx) { return bucket[inx]; }
|
|
|
|
/**
|
|
Operator []
|
|
*/
|
|
const T& operator[](int inx) const { return bucket[inx]; }
|
|
|
|
/**
|
|
Operator []
|
|
*/
|
|
T& operator[](int inx) { return bucket[inx]; }
|
|
|
|
/**
|
|
Operator []
|
|
*/
|
|
const T& operator[](unsigned int inx) const { return bucket[inx]; }
|
|
|
|
/**
|
|
Operator []
|
|
*/
|
|
T& operator[](unsigned int inx) { return bucket[inx]; }
|
|
|
|
/**
|
|
Operator []
|
|
*/
|
|
const T& operator[](short inx) const { return bucket[inx]; }
|
|
|
|
/**
|
|
Operator []
|
|
*/
|
|
T& operator[](short inx) { return bucket[inx]; }
|
|
|
|
/**
|
|
Operator []
|
|
*/
|
|
const T& operator[](long inx) const { return bucket[inx]; }
|
|
|
|
/**
|
|
Operator []
|
|
*/
|
|
T& operator[](long inx) { return bucket[inx]; }
|
|
|
|
/**
|
|
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; }
|
|
|
|
/**
|
|
Returns the pointed memory.
|
|
*/
|
|
T* get() const { return bucket; }
|
|
|
|
/**
|
|
Returns the memory that has been managed by the smart pointer, and ends it management of this memory.
|
|
*/
|
|
T* release() { T* tmp = bucket; bucket = 0; return tmp; }
|
|
|
|
/** Operator == */
|
|
bool operator == (const T* t) const { return bucket == t; }
|
|
|
|
/** Operator != */
|
|
bool operator != (const T* t) const { return bucket != t; }
|
|
|
|
/** Unary NOT operator */
|
|
bool operator! () const
|
|
{
|
|
return bucket == 0;
|
|
}
|
|
|
|
protected:
|
|
/**
|
|
The managed pointer.
|
|
*/
|
|
T* bucket;
|
|
|
|
private:
|
|
/**
|
|
Prevention of usage of the copy constructor.
|
|
*/
|
|
scoped_smptr( const scoped_smptr& );
|
|
|
|
/**
|
|
Prevention of usage of the operator =
|
|
*/
|
|
scoped_smptr& operator = ( const scoped_smptr& );
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|