b38b0825ee
- C3d aggiornamento delle librerie ( 114902).
215 lines
7.1 KiB
C++
215 lines
7.1 KiB
C++
////////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
\file
|
|
\brief \ru Автоматический указатель на объекты, не имеющие счетчиков ссылок.
|
|
\en Smart pointer to objects without reference counters. \~
|
|
|
|
*/
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifndef __TEMPL_DPTR_H
|
|
#define __TEMPL_DPTR_H
|
|
|
|
#include <math_define.h>
|
|
#include <system_types.h>
|
|
|
|
//------------------------------------------------------------------------------
|
|
/** \brief \ru Автоматический указатель.
|
|
\en Smart pointer. \~
|
|
\details \ru Автоматический указатель на объекты, не имеющие счетчиков ссылок. \n
|
|
\en Smart pointer to objects without reference counters. \n \~
|
|
\ingroup Base_Tools_SmartPointers
|
|
*/
|
|
// ---
|
|
template <class T>
|
|
class DPtr {
|
|
public:
|
|
/// \ru Конструктор по умолчанию. \en Default constructor.
|
|
DPtr() : m_Ptr ( nullptr ), m_Owner( nullptr ) {}
|
|
/// \ru Конструктор по указателю на объект. \en Constructor by pointer to an object.
|
|
/*explicit*/ DPtr( T * obj );
|
|
/// \ru Конструктор по автоматическому указателю на объект. \en Constructor by smart pointer to an object.
|
|
DPtr( const DPtr<T> & );
|
|
/// \ru Деструктор. \en Destructor.
|
|
~DPtr() { reset(); }
|
|
|
|
public:
|
|
/// \ru Оператор доступа. \en An access operator.
|
|
operator T* ( void ) const { return m_Ptr; }
|
|
/// \ru Оператор доступа. \en An access operator.
|
|
T & operator * ( void ) const { return *m_Ptr; } // SKIP_SA
|
|
/// \ru Оператор доступа. \en An access operator.
|
|
T * operator -> ( void ) const { return m_Ptr; }
|
|
/// \ru Оператор присваивания. \en The assignment operator.
|
|
DPtr<T> & operator = ( T * );
|
|
/// \ru Оператор присваивания. \en The assignment operator.
|
|
DPtr<T> & operator = ( const DPtr<T> & src );
|
|
|
|
public:
|
|
/// \ru Функция освобождения объекта. \en A function of release an object.
|
|
DPtr<T> & reset();
|
|
/// \ru Выдать указать. \en Get pointer.
|
|
const T * get() const { return m_Ptr; }
|
|
/// \ru Выдать указать. \en Get pointer.
|
|
T * get() { return m_Ptr; }
|
|
/// \ru Выдать количество владеющих экземпляров DPtr. \en Get the number of DPtr objects that share ownership.
|
|
refcount_t use_count() const { return m_Owner ? m_Owner->use_count() : 0; }
|
|
|
|
/// \ru Конструктор перемещения. \en Moving constructor.
|
|
DPtr( DPtr<T> && src ) : m_Ptr( src.m_Ptr ), m_Owner( src.m_Owner )
|
|
{
|
|
src.m_Ptr = nullptr;
|
|
src.m_Owner = nullptr;
|
|
}
|
|
/// \ru Оператор перемещения. \en Moving operator.
|
|
DPtr<T> & operator = ( DPtr<T> && src )
|
|
{
|
|
std::swap( m_Ptr, src.m_Ptr );
|
|
std::swap( m_Owner, src.m_Owner );
|
|
return *this;
|
|
}
|
|
|
|
private:
|
|
/// \ru Счетчик ссылок на объект. \en A counter of references to an object.
|
|
struct Owner // Поведение аналогично MtRefItem.
|
|
{
|
|
Owner( T * obj )
|
|
: m_Ptr( obj )
|
|
, useCount( 0 )
|
|
{
|
|
PRECONDITION( obj != nullptr );
|
|
}
|
|
void AddRef() const { ++useCount; }
|
|
void Release() const
|
|
{
|
|
PRECONDITION( useCount > 0 );
|
|
if ( --useCount == 0 )
|
|
{
|
|
delete this;
|
|
}
|
|
}
|
|
const T * get() const { return m_Ptr; }
|
|
T * get() { return m_Ptr; }
|
|
refcount_t use_count() const { return useCount; }
|
|
OBVIOUS_PRIVATE_COPY( Owner );
|
|
|
|
private:
|
|
T * m_Ptr;
|
|
mutable refcount_t useCount;
|
|
~Owner() { PRECONDITION( useCount == 0 ); delete m_Ptr; } // Destructor should be private.
|
|
};
|
|
|
|
private:
|
|
T * m_Ptr; ///< \ru Указатель на объект. \en A pointer to an object.
|
|
Owner * m_Owner; ///< \ru Счетчик ссылок на объект. \en A counter of references to an object.
|
|
};
|
|
|
|
//-------------------------------------------------------------------------------
|
|
// \ru Конструктор по указателю на объект. \en Constructor by pointer to an object.
|
|
// ---
|
|
template <class T>
|
|
DPtr<T>::DPtr( T * obj )
|
|
: m_Ptr( obj )
|
|
, m_Owner( nullptr )
|
|
{
|
|
if ( obj != nullptr )
|
|
{
|
|
m_Owner = new Owner( obj );
|
|
m_Owner->AddRef();
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
// \ru Конструктор копирования. \en Copy constructor.
|
|
// ---
|
|
template <class T>
|
|
DPtr<T>::DPtr( const DPtr<T> & dptr )
|
|
: m_Ptr( dptr.m_Ptr )
|
|
, m_Owner( dptr.m_Owner )
|
|
{
|
|
if ( m_Owner != nullptr )
|
|
m_Owner->AddRef(); // SKIP_SA
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
// \ru Оператор присваивания. \en Assignment operator.
|
|
// ---
|
|
template <class T>
|
|
DPtr<T> & DPtr<T>::operator = ( T * pObj )
|
|
{
|
|
if ( m_Ptr != pObj )
|
|
{
|
|
reset();
|
|
if ( pObj != nullptr )
|
|
{
|
|
m_Ptr = pObj;
|
|
m_Owner = new Owner( pObj );
|
|
m_Owner->AddRef();
|
|
}
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
// \ru Оператор присваивания. \en Assignment operator.
|
|
// ---
|
|
template <class T>
|
|
DPtr<T> & DPtr<T>::operator = ( const DPtr<T> & dptr )
|
|
{
|
|
if ( m_Ptr != dptr.m_Ptr )
|
|
{
|
|
reset();
|
|
if ( dptr.m_Ptr != nullptr )
|
|
{
|
|
m_Ptr = dptr.m_Ptr;
|
|
m_Owner = dptr.m_Owner;
|
|
m_Owner->AddRef();
|
|
}
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
// \ru Функция освобождения объекта. \en A function of release an object.
|
|
//---
|
|
template <class T>
|
|
DPtr<T> & DPtr<T>::reset()
|
|
{
|
|
if ( m_Ptr == nullptr )
|
|
return *this;
|
|
|
|
m_Ptr = nullptr;
|
|
m_Owner->Release(); // SKIP_SA
|
|
m_Owner = nullptr;
|
|
return *this;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
//
|
|
//---
|
|
template <class T1, class T2>
|
|
bool operator == ( const DPtr<T1> & left, const DPtr<T2> & right ) { return left.get() == right.get(); }
|
|
template <class T1, class T2>
|
|
bool operator != ( const DPtr<T1> & left, const DPtr<T2> & right ) { return left.get() != right.get(); }
|
|
|
|
/*
|
|
//-------------------------------------------------------------------------------
|
|
//
|
|
//---
|
|
template <class T1, class T2>
|
|
bool operator == ( const DPtr<T1> & left, const T2 * right ) { return left.get() == right; }
|
|
template <class T1, class T2>
|
|
bool operator != ( const DPtr<T1> & left, const T2 * right ) { return left.get() != right; }
|
|
//-------------------------------------------------------------------------------
|
|
//
|
|
//---
|
|
template <class T1, class T2>
|
|
bool operator == ( const T1 * left, const DPtr<T2> & right ) { return left == right.get(); }
|
|
template <class T1, class T2>
|
|
bool operator != ( const T1 * left, const DPtr<T2> & right ) { return left != right.get(); }
|
|
*/
|
|
|
|
#endif // __TEMPL_DPTR_H
|