obs-studio/build_dependencies/aja/include/ajalibraries/ajabase/common/ajarefptr.h
Ward Nakchbandi b48576284b first commit
2023-03-04 20:33:16 +03:00

218 lines
4.5 KiB
C++

/* SPDX-License-Identifier: MIT */
/**
@file ajarefptr.h
@copyright (C) 2013-2021 AJA Video Systems, Inc. All rights reserved.
@brief Defines the AJARefPtr template class.
**/
#if !defined (__AJAREFPTR__)
#define __AJAREFPTR__
#include "../system/atomic.h"
/**
@brief I am the referent object that maintains the reference count and
the pointer to the underlying object whose lifespan I manage.
@note I am not designed to be used as a superclass, therefore, none of
my methods are virtual.
**/
template <class TRef>
class Referent
{
// Instance Methods
public:
// Constructor
Referent (TRef * ptr);
// Reference Count Management
void AddRef () throw ();
void RemoveRef () throw ();
// Access To Underlying Object
TRef * get () const throw();
// Instance Data
private:
uint32_t m_nCount; // Reference count
TRef * m_pointer; // Pointer to underlying object I refer to
}; // Referent
template <class TRef>
Referent <TRef>::Referent (TRef * ptr)
: m_nCount (1),
m_pointer (ptr)
{
}
template <class TRef>
void Referent <TRef>::AddRef (void) throw ()
{
AJAAtomic::Increment(&m_nCount);
}
template <class TRef>
void Referent <TRef>::RemoveRef (void) throw ()
{
if (m_nCount > 0)
{
if (AJAAtomic::Decrement(&m_nCount) == 0)
{
delete m_pointer;
m_pointer = 0;
delete this;
}
}
}
template <class TRef>
TRef * Referent <TRef>::get (void) const throw ()
{
return m_pointer;
}
/**
@brief I am a reference-counted pointer template class.
I am intended to be a proxy for an underlying object,
whose lifespan is automatically managed by the Referent
template class that I work with.
@note Be sure not to create more than one of me using the same
object pointer or else a double-free will ensue.
**/
template <class TRef>
class AJARefPtr
{
public:
typedef TRef element_type;
// Construction & Destruction
explicit AJARefPtr (TRef * ptr = NULL) throw ();
AJARefPtr (const AJARefPtr<TRef>& obToCopy ) throw ();
~AJARefPtr () throw ();
// Assignment
AJARefPtr<TRef>& operator = (const AJARefPtr<TRef>& inRHS) throw ();
AJARefPtr<TRef>& operator = (TRef * pobRHS) throw ();
// Comparison
bool operator == (const AJARefPtr< TRef > & inRHS) const throw ();
bool operator != (const AJARefPtr< TRef > & inRHS) const throw ();
bool operator < (const AJARefPtr< TRef > & inRHS) const throw ();
// Dereferencing
TRef & operator * () const throw ();
TRef * operator -> () const throw ();
TRef * get () const throw ();
// Testing
operator bool () const throw ();
private:
Referent <element_type> * m_pRef; // My referent
}; // AJARefPtr
template <class TRef>
AJARefPtr <TRef>::AJARefPtr (TRef * ptr) throw () : m_pRef (new Referent <element_type> (ptr))
{
}
template <class TRef>
AJARefPtr <TRef>::AJARefPtr (const AJARefPtr <TRef> & obToCopy) throw () : m_pRef (obToCopy.m_pRef)
{
m_pRef->AddRef ();
}
template <class TRef>
AJARefPtr <TRef> & AJARefPtr <TRef>::operator = (const AJARefPtr <TRef> & inRHS) throw ()
{
if (*this != inRHS)
{
if (m_pRef)
m_pRef->RemoveRef ();
m_pRef = inRHS.m_pRef;
m_pRef->AddRef ();
}
return *this;
}
template <class TRef>
AJARefPtr <TRef> & AJARefPtr <TRef>::operator = (TRef * pobRHS) throw ()
{
if (pobRHS != get ())
{
if (m_pRef)
m_pRef->RemoveRef ();
m_pRef = new Referent <element_type> (pobRHS);
}
return *this;
}
template <class TRef>
AJARefPtr <TRef>::~AJARefPtr () throw ()
{
m_pRef->RemoveRef ();
}
template <class TRef>
bool AJARefPtr <TRef>::operator == (const AJARefPtr <TRef> & inRHS) const throw ()
{
return get() == inRHS.get();
}
template <class TRef>
bool AJARefPtr <TRef>::operator != (const AJARefPtr <TRef> & inRHS) const throw ()
{
return get() != inRHS.get ();
}
template <class TRef>
bool AJARefPtr <TRef>::operator < (const AJARefPtr <TRef> & inRHS) const throw ()
{
return get() < inRHS.get ();
}
template <class TRef>
TRef & AJARefPtr <TRef>::operator * () const throw ()
{
return *(m_pRef->get());
}
template <class TRef>
TRef * AJARefPtr <TRef>::operator -> () const throw ()
{
return m_pRef ? m_pRef->get () : NULL;
}
template <class TRef>
TRef * AJARefPtr <TRef>::get () const throw ()
{
return m_pRef ? m_pRef->get () : NULL;
}
template <class TRef>
AJARefPtr <TRef>::operator bool () const throw ()
{
return m_pRef && m_pRef->get () != 0;
}
#endif // __AJAREFPTR__