You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nvidia-texture-tools/src/nvcore/Ptr.h

421 lines
7.8 KiB
C++

// This code is in the public domain -- castanyo@yahoo.es
#ifndef NV_CORE_PTR_H
#define NV_CORE_PTR_H
#include <nvcore/nvcore.h>
#include <nvcore/Debug.h>
#include <stdio.h> // NULL
namespace nv
{
/** Simple auto pointer template class.
*
* This is very similar to the standard auto_ptr class, but with some
* additional limitations to make its use less error prone:
* - Copy constructor and assignment operator are disabled.
* - reset method is removed.
*
* The semantics of the standard auto_ptr are not clear and change depending
* on the std implementation. For a discussion of the problems of auto_ptr read:
* http://www.awprofessional.com/content/images/020163371X/autoptrupdate\auto_ptr_update.html
*/
template <class T>
class AutoPtr
{
NV_FORBID_COPY(AutoPtr);
NV_FORBID_HEAPALLOC();
public:
/** Ctor. */
explicit AutoPtr( T * p ) {
m_ptr = p;
}
/** Dtor. Deletes owned pointer. */
~AutoPtr() {
delete m_ptr;
m_ptr = NULL;
}
/** Delete owned pointer and assign new one. */
void operator=( T * p ) {
delete m_ptr;
m_ptr = p;
}
/** Member access. */
T * operator -> () const {
nvDebugCheck(m_ptr != NULL);
return m_ptr;
}
/** Get reference. */
T & operator*() const {
nvDebugCheck(m_ptr != NULL);
return *m_ptr;
}
/** Get pointer. */
T * ptr() const { return m_ptr; }
/** Relinquish ownership of the underlying pointer and returns that pointer. */
T * release() {
T * tmp = m_ptr;
m_ptr = NULL;
return tmp;
}
/** Const pointer equal comparation. */
bool operator == (const T * const p) const {
return (m_ptr == p);
}
/** Const pointer nequal comparation. */
bool operator != (const T * const p) const {
return (m_ptr != p);
}
private:
T * m_ptr;
};
#if 0
/** Reference counted base class to be used with Pointer.
*
* The only requirement of the Pointer class is that the RefCounted class implements the
* addRef and release methods.
*/
class RefCounted
{
NV_FORBID_COPY(RefCounted);
public:
/// Ctor.
RefCounted() : m_count(0), m_weak_proxy(NULL)
{
s_total_obj_count++;
}
/// Virtual dtor.
virtual ~RefCounted()
{
nvCheck( m_count == 0 );
nvCheck( s_total_obj_count > 0 );
s_total_obj_count--;
}
/// Increase reference count.
uint addRef() const
{
s_total_ref_count++;
m_count++;
return m_count;
}
/// Decrease reference count and remove when 0.
uint release() const
{
nvCheck( m_count > 0 );
s_total_ref_count--;
m_count--;
if( m_count == 0 ) {
releaseWeakProxy();
delete this;
return 0;
}
return m_count;
}
/// Get weak proxy.
WeakProxy * getWeakProxy() const
{
if (m_weak_proxy == NULL) {
m_weak_proxy = new WeakProxy;
m_weak_proxy->AddRef();
}
return m_weak_proxy;
}
/// Release the weak proxy.
void releaseWeakProxy() const
{
if (m_weak_proxy != NULL) {
m_weak_proxy->NotifyObjectDied();
m_weak_proxy->Release();
m_weak_proxy = NULL;
}
}
/** @name Debug methods: */
//@{
/// Get reference count.
int refCount() const
{
return m_count;
}
/// Get total number of objects.
static int totalObjectCount()
{
return s_total_obj_count;
}
/// Get total number of references.
static int totalReferenceCount()
{
return s_total_ref_count;
}
//@}
private:
NVCORE_API static int s_total_ref_count;
NVCORE_API static int s_total_obj_count;
mutable int m_count;
mutable WeakProxy * weak_proxy;
};
#endif
/// Smart pointer template class.
template <class BaseClass>
class Pointer {
public:
// BaseClass must implement addRef() and release().
typedef Pointer<BaseClass> ThisType;
/// Default ctor.
Pointer() : m_ptr(NULL)
{
}
/** Other type assignment. */
template <class OtherBase>
Pointer( const Pointer<OtherBase> & tc )
{
m_ptr = static_cast<BaseClass *>( tc.ptr() );
if( m_ptr ) {
m_ptr->addRef();
}
}
/** Copy ctor. */
Pointer( const ThisType & bc )
{
m_ptr = bc.ptr();
if( m_ptr ) {
m_ptr->addRef();
}
}
/** Copy cast ctor. Pointer(NULL) is valid. */
explicit Pointer( BaseClass * bc )
{
m_ptr = bc;
if( m_ptr ) {
m_ptr->addRef();
}
}
/** Dtor. */
~Pointer()
{
set(NULL);
}
/** @name Accessors: */
//@{
/** -> operator. */
BaseClass * operator -> () const
{
piCheck( m_ptr != NULL );
return m_ptr;
}
/** * operator. */
BaseClass & operator*() const
{
piCheck( m_ptr != NULL );
return *m_ptr;
}
/** Get pointer. */
BaseClass * ptr() const
{
return m_ptr;
}
//@}
/** @name Mutators: */
//@{
/** Other type assignment. */
template <class OtherBase>
void operator = ( const Pointer<OtherBase> & tc )
{
set( static_cast<BaseClass *>(tc.ptr()) );
}
/** This type assignment. */
void operator = ( const ThisType & bc )
{
set( bc.ptr() );
}
/** Pointer assignment. */
void operator = ( BaseClass * bc )
{
set( bc );
}
//@}
/** @name Comparators: */
//@{
/** Other type equal comparation. */
template <class OtherBase>
bool operator == ( const Pointer<OtherBase> & other ) const
{
return m_ptr == other.ptr();
}
/** This type equal comparation. */
bool operator == ( const ThisType & bc ) const
{
return m_ptr == bc.ptr();
}
/** Const pointer equal comparation. */
bool operator == ( const BaseClass * const bc ) const
{
return m_ptr == bc;
}
/** Other type not equal comparation. */
template <class OtherBase>
bool operator != ( const Pointer<OtherBase> & other ) const
{
return m_ptr != other.ptr();
}
/** Other type not equal comparation. */
bool operator != ( const ThisType & bc ) const
{
return m_ptr != bc.ptr();
}
/** Const pointer not equal comparation. */
bool operator != (const BaseClass * const bc) const
{
return m_ptr != bc;
}
/** This type lower than comparation. */
bool operator < (const ThisType & p) const
{
return m_ptr < p.ptr();
}
//@}
private:
/** Set this pointer. */
void set( BaseClass * p )
{
if( m_ptr != p ) {
if( m_ptr ) m_ptr->release();
if( p ) p->addRef();
m_ptr = p;
}
}
private:
BaseClass * m_ptr;
};
/*
template <class T>
class QSharedDataPointer
{
public:
inline void detach() { if (d && d->ref != 1) detach_helper(); }
inline T &operator*() { detach(); return *d; }
inline const T &operator*() const { return *d; }
inline T *operator->() { detach(); return d; }
inline const T *operator->() const { return d; }
inline operator T *() { detach(); return d; }
inline operator const T *() const { return d; }
inline T *data() { detach(); return d; }
inline const T *data() const { return d; }
inline const T *constData() const { return d; }
inline bool operator==(const QSharedDataPointer<T> &other) const { return d == other.d; }
inline bool operator!=(const QSharedDataPointer<T> &other) const { return d != other.d; }
inline QSharedDataPointer() { d = 0; }
inline ~QSharedDataPointer() { if (d && !d->ref.deref()) delete d; }
explicit QSharedDataPointer(T *data);
inline QSharedDataPointer(const QSharedDataPointer<T> &o) : d(o.d) { if (d) d->ref.ref(); }
inline QSharedDataPointer<T> & operator=(const QSharedDataPointer<T> &o) {
if (o.d != d) {
T *x = o.d;
if (x) x->ref.ref();
x = qAtomicSetPtr(&d, x);
if (x && !x->ref.deref())
delete x;
}
return *this;
}
inline QSharedDataPointer &operator=(T *o) {
if (o != d) {
T *x = o;
if (x) x->ref.ref();
x = qAtomicSetPtr(&d, x);
if (x && !x->ref.deref())
delete x;
}
return *this;
}
inline bool operator!() const { return !d; }
private:
void detach_helper();
T *d;
};
template <class T>
Q_INLINE_TEMPLATE QSharedDataPointer<T>::QSharedDataPointer(T *adata) : d(adata)
{ if (d) d->ref.ref(); }
template <class T>
Q_OUTOFLINE_TEMPLATE void QSharedDataPointer<T>::detach_helper()
{
T *x = new T(*d);
x->ref.ref();
x = qAtomicSetPtr(&d, x);
if (!x->ref.deref())
delete x;
}
*/
} // nv namespace
#endif // NV_CORE_PTR_H