//////////////////////////////////////////////////////////////////////////////// /** \file \brief \ru Автоматические указатель и ссылка на объекты с подсчетом ссылок. \en Smart pointer and reference to objects with reference counter. \~ */ //////////////////////////////////////////////////////////////////////////////// #ifndef __TEMPL_SPTR_H #define __TEMPL_SPTR_H #include #include //------------------------------------------------------------------------------ /** \brief \ru Отладочная проверка на nullptr. \en Debug check for nullptr. \~ \details \ru Отладочная проверка на nullptr. \n \en Debug check for nullptr. \n \~ \ingroup Base_Tools_SmartPointers */ // --- #define NULL_CHECK PRECONDITION( m_pI != nullptr ); //------------------------------------------------------------------------------ /** \brief \ru Автоматический указатель на объекты с подсчетом ссылок. \en Smart pointer to objects with reference counter. \~ \details \ru Автоматический указатель (smart pointer) на объекты с подсчетом ссылок. Требует от параметра шаблона реализации функций AddRef() и Release(). \n \en Smart pointer to objects with reference counter. It requires Implementation of functions AddRef() and Release() from the template parameter. \n \~ \ingroup Base_Tools_SmartPointers */ // --- template class SPtr { T * m_pI; // \ru Указатель на объект. \en A pointer to an object. public: /// \ru Конструктор. \en Constructor. SPtr () : m_pI( nullptr ) {} /// \ru Конструктор по нулевому указателю. \en Constructor by the null pointer. SPtr( std::nullptr_t ) : m_pI( nullptr ) {} /// \ru Конструктор по указателю. \en Constructor by pointer. explicit SPtr ( T * elem ) { if ( (m_pI = elem) != nullptr ) m_pI->AddRef(); } /// \ru Конструктор копирования. \en Copy constructor. SPtr( const SPtr & ptr ) : m_pI( nullptr ) { assign(ptr.m_pI); } // SKIP_SA /// \ru Конструктор по совместимому указателю \en Constructor by compatible pointer template SPtr( const SPtr<_T> & ptr ) : m_pI( nullptr ) { assign(ptr.get()); } /// \ru Деструктор. \en Destructor. ~SPtr() { reset(); } public: // \ru Перегрузка операторов \en Operators overloading /// \ru Оператор преобразования к типу T* . \en An operator for conversion to the type T*. operator T* ( void ) const { return m_pI; } // SKIP_SA /// \ru Оператор преобразования к совместимому указателю. \en An operator for conversion to a compatible pointer. /* template operator SPtr<_T> () const { return SPtr<_T>( m_pI ); } */ /// \ru Оператор доступа. \en An access operator. T & operator * () const { NULL_CHECK return *m_pI; } // SKIP_SA /// \ru Оператор доступа. \en An access operator. T * operator -> () const { NULL_CHECK return m_pI; } // SKIP_SA /// \ru Оператор присваивания. \en The assignment operator. SPtr & operator = ( T * elem ) { return assign( elem ); } /// \ru Оператор присваивания. \en The assignment operator. SPtr & operator = ( const SPtr & ptr ) { return assign( ptr.get() ); } /// \ru Оператор присваивания для совместимого указателя. \en An assignment operator for a compatible pointer. template SPtr & operator = ( const SPtr<_T> & ptr ) { return assign( ptr.get() ); } /// \ru Оператор проверки на равенство. \en An operator for equality check. template bool operator == ( const SPtr<_T> & ptr ) const { return ( m_pI == ptr.get() ); } /// \ru Оператор проверки на равенство. \en An operator for equality check. template bool operator == ( const _T * elem ) const { return ( m_pI == elem ); } /// \ru Оператор проверки на равенство. \en An operator for equality check. bool operator == ( T * elem ) const { return ( m_pI == elem ); } /// \ru Оператор проверки на неравенство. \en An operator for inequality check. template bool operator != ( const SPtr<_T> & ptr ) const { return ( !(operator == (ptr)) ); } /// \ru Оператор проверки на неравенство. \en An operator for inequality check. template bool operator != ( const _T * elem ) const { return ( !(operator == (elem)) ); } /// \ru Оператор проверки на неравенство. \en An operator for inequality check. bool operator != ( T * elem ) const { return ( !(operator == (elem)) ); } /// \ru Отношение порядка. \en Order relation. template bool operator < ( const _T * elem ) const { return ( m_pI < elem ); } /// \ru Отношение порядка. \en Order relation. template bool operator < ( const SPtr<_T> & elem ) const { return ( m_pI < elem.get() ); } public: /// \ru Функция присваивания указателем. \en A function of assignment by pointer. template SPtr & assign( _T * elem ) { if ( m_pI != elem ) { if ( elem != nullptr ) { elem->AddRef(); } // SKIP_SA if ( m_pI != nullptr ) { m_pI->Release(); } // SKIP_SA m_pI = elem; } return *this; // SKIP_SA } /// \ru Функция присваивания указателем. \en A function of assignment by pointer. template SPtr & assign( const SPtr<_T> & elem ) { return assign( elem.get() ); } /// \ru Функция освобождения объекта. \en A function of release an object. SPtr & assign( std::nullptr_t ) { return reset(); } /// \ru Функция освобождения объекта. \en A function of release an object. SPtr & reset( void ) { if ( m_pI != nullptr ) { m_pI->Release(); m_pI = nullptr; } return *this; } // SKIP_SA /// \ru Функция доступа к элементу данных. \en A function of access to data element. T * get() const { return m_pI; } // SKIP_SA /// \ru Функция отсоединяет объект. \en A function detaches an object. T * detach() { T * obj = m_pI; m_pI = nullptr; if ( obj != nullptr ) obj->DecRef(); return obj; } // SKIP_SA /// \ru Нулевой указатель? \en Is null pointer? bool is_null() const { return nullptr == m_pI; } public: /// \ru Конструктор перемещения. \en Moving constructor. SPtr( SPtr && src ) : m_pI ( src.m_pI ) { src.m_pI = 0; } /// \ru Оператор перемещения. \en Moving operator. SPtr & operator = ( SPtr && src ) { T * tmp = m_pI; m_pI = src.m_pI; src.m_pI = tmp; return *this; } /// \ru Преобразовать к SPtr на другой класс. \en Cast to SPtr to another class. template SPtr static_cast_to() const { return SPtr { static_cast(get()) }; } }; //------------------------------------------------------------------------------ /** \brief \ru Автоматическая ссылка на объекты с подсчетом ссылок. \en Smart reference to objects with reference counter. \~ \details \ru Автоматическая ссылка (smart reference) на объекты с подсчетом ссылок. Фактически тоже самое, что и SPtr, но без возможности равенства nullptr.\n Требует от параметра шаблона реализации функций AddRef() и Release(). \n \en Smart reference to objects with reference counter. Actually it is the same as SPtr but without the possibility of equality to nullptr \n It requires Implementation of functions AddRef() and Release() from the template parameter. \n \~ \ingroup Base_Tools_SmartPointers */ // --- template class SRef { T * m_pI; ///< \ru Указатель на значение \en A pointer to the value public: /// \ru Конструктор по ссылке. \en Constructor by reference. SRef ( T & ref ) : m_pI( & ref ) { m_pI->AddRef(); } /// \ru Конструктор копирования. \en Copy constructor. SRef( const SRef & src ): m_pI( src.m_pI ) { m_pI->AddRef(); } /// \ru Деструктор. \en Destructor. ~SRef( void ) { m_pI->Release(); } public: /// \ru Функция доступа. \en An access function. T & get() const { return *m_pI; } /// \ru Оператор доступа. \en An access operator. operator T & ( void ) const { return *m_pI; } /// \ru Оператор доступа. \en An access operator. T & operator()() const { return *m_pI; } /// \ru Оператор проверки на равенство. \en An operator for equality check. bool operator == ( const SRef & src ) const { return ( m_pI == src.m_pI ); } /// \ru Оператор проверки на равенство. \en An operator for equality check. bool operator == ( T & pObj ) const { return ( m_pI == &pObj ); } /// \ru Оператор проверки на неравенство. \en An operator for inequality check. bool operator != ( const SRef & src ) const { return ( !(operator == (src)) ); } /// \ru Оператор проверки на неравенство. \en An operator for inequality check. bool operator != ( T & pObj ) const { return ( !(operator == (pObj)) ); } /// \ru Оператор присваивания. \en The assignment operator. SRef & operator = ( const SRef & ref ) { return operator =( *ref.m_pI ); } /// \ru Оператор присваивания. \en The assignment operator. SRef & operator = ( T & obj ) { obj.AddRef(); m_pI->Release(); m_pI = &obj; return *this; } }; //------------------------------------------------------------------------------ /** \brief \ru Пара автоматических указателей. \en A pair of smart pointers. \~ \details \ru Пара автоматических указателей. \n Удобно применять там, где требуется передавать в качестве аргумента функции или результата пару указателей на объекты со счетчиком ссылок. Все данные и методы класса намеренно сделаны открытыми. \en A pair of smart pointers. \n It is comfortable to use this when it is required to pass as an argument of a function or a result, a pair of smart pointers to objects with reference counters. All data and methods of the class are purposely made public. \~ \ingroup Base_Tools_SmartPointers */ // --- template struct SPtrPair { SPtr first; ///< \ru Автоматический указатель на первый объект. \en A smart pointer to the first object. SPtr second; ///< \ru Автоматический указатель на второй объект. \en A smart pointer to the second object. /// \ru Конструктор. \en Constructor. SPtrPair(): first(), second() {} /// \ru Конструктор копирования. \en Copy constructor. SPtrPair( const SPtrPair & sPair ) : first(sPair.first), second(sPair.second) {} /// \ru Оператор присваивания. \en The assignment operator. SPtrPair & operator = ( const SPtrPair & sPair ) { first = sPair.first; second = sPair.second; } }; namespace c3d { //------------------------------------------------------------------------------ // \ru Создать объект по параметрам и вернуть автоматический указатель на него. // \en Create an object by parameters and return a smart pointer to it. //--- template inline SPtr make_sptr( Args && ... args ) { return SPtr( new T(std::forward( args )...) ); } } // namespace c3d #endif // __TEMPL_SPTR_H