Reference counting helpers - Progress, tests
* Assignment copy/move operators * Boolean conversion / ! operator * Content access
This commit is contained in:
parent
f0e46da2f5
commit
ddaa46867d
3 changed files with 419 additions and 12 deletions
include/ebcl
|
@ -41,6 +41,9 @@ class T_ReferenceCountedClass
|
|||
|
||||
protected:
|
||||
T_ReferenceCountedClass( ) noexcept;
|
||||
|
||||
public:
|
||||
uint32_t getReferenceCount( ) const noexcept;
|
||||
};
|
||||
|
||||
// Shortcuts
|
||||
|
@ -72,6 +75,7 @@ class T_RcPtr
|
|||
|
||||
private:
|
||||
T_Target* target_;
|
||||
void setTarget_( T_Target* t ) noexcept;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -80,27 +84,58 @@ class T_RcPtr
|
|||
T_RcPtr( ) noexcept;
|
||||
~T_RcPtr( ) noexcept;
|
||||
|
||||
// Constructor function
|
||||
template< typename... AT >
|
||||
static T_RcPtr< Type > New( AT&& ... arguments );
|
||||
|
||||
void clear( ) noexcept;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Copy constructors
|
||||
// Copy constructors and operators
|
||||
|
||||
T_RcPtr( T_Self const& other ) noexcept;
|
||||
T_Self& operator= ( T_Self const& other ) noexcept;
|
||||
|
||||
template< typename Q , T_EnableForChild< Type , Q > = true >
|
||||
T_RcPtr( T_RcPtr< Q > const& source ) noexcept;
|
||||
template< typename Q , T_EnableForParent< Type , Q > = false >
|
||||
explicit T_RcPtr( T_RcPtr< Q > const& source );
|
||||
|
||||
template< typename Q , T_EnableForChild< Type , Q > = true >
|
||||
T_Self& operator= ( T_RcPtr< Q > const& other ) noexcept;
|
||||
template< typename Q , T_EnableForParent< Type , Q > = false >
|
||||
T_Self& operator= ( T_RcPtr< Q > const& other );
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Move constructors
|
||||
// Move constructors and operators
|
||||
|
||||
template< typename Q , T_EnableForChild< Type , Q > = true >
|
||||
T_RcPtr( T_RcPtr< Q >&& other ) noexcept;
|
||||
|
||||
template< typename Q , T_EnableForParent< Type , Q > = false >
|
||||
explicit T_RcPtr( T_RcPtr< Q >&& other );
|
||||
};
|
||||
|
||||
template< typename Q , T_EnableForChild< Type , Q > = true >
|
||||
T_Self& operator= ( T_RcPtr< Q >&& other ) noexcept;
|
||||
template< typename Q , T_EnableForParent< Type , Q > = false >
|
||||
T_Self& operator= ( T_RcPtr< Q >&& other );
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Boolean conversion
|
||||
|
||||
operator bool ( ) const noexcept;
|
||||
bool operator! ( ) const noexcept;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Content access
|
||||
|
||||
// Access the actual pointer
|
||||
Type * get( ) const noexcept;
|
||||
explicit operator Type* ( ) const noexcept;
|
||||
|
||||
// Access the object; undefined behavior if get() == nullptr.
|
||||
Type* operator -> ( ) const;
|
||||
Type& operator * ( ) const;
|
||||
};
|
||||
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -27,6 +27,12 @@ inline bool T_ReferenceCountedClass< B >::decreaseReferences_( ) noexcept
|
|||
return ( -- referenceCounter_ ) == 0;
|
||||
}
|
||||
|
||||
template< bool B >
|
||||
inline uint32_t T_ReferenceCountedClass< B >::getReferenceCount( ) const noexcept
|
||||
{
|
||||
return uint32_t{ referenceCounter_ };
|
||||
}
|
||||
|
||||
|
||||
/*= T_RcPtr ==================================================================*/
|
||||
|
||||
|
@ -41,6 +47,30 @@ inline T_RcPtr< T >::~T_RcPtr( ) noexcept
|
|||
clear( );
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
template< typename... AT >
|
||||
inline T_RcPtr< T > T_RcPtr< T >::New(
|
||||
AT&& ... arguments )
|
||||
{
|
||||
T* const obj{ new T( std::forward< AT >( arguments ) ... ) };
|
||||
T_RcPtr< T > ptr;
|
||||
ptr.setTarget_( obj );
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
template< typename T >
|
||||
inline void T_RcPtr< T >::setTarget_(
|
||||
T_Target* t ) noexcept
|
||||
{
|
||||
assert( target_ == nullptr );
|
||||
if ( t ) {
|
||||
t->increaseReferences_( );
|
||||
}
|
||||
target_ = t;
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
inline void T_RcPtr< T >::clear( ) noexcept
|
||||
{
|
||||
|
@ -55,11 +85,9 @@ inline void T_RcPtr< T >::clear( ) noexcept
|
|||
template< typename T >
|
||||
inline T_RcPtr< T >::T_RcPtr(
|
||||
T_RcPtr< T > const& other ) noexcept
|
||||
: target_{ other.target_ }
|
||||
: target_{ nullptr }
|
||||
{
|
||||
if ( target_ ) {
|
||||
target_->increaseReferences_( );
|
||||
}
|
||||
setTarget_( other.target_ );
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
|
@ -68,11 +96,9 @@ template<
|
|||
T_EnableForChild< T , Q >
|
||||
> inline T_RcPtr< T >::T_RcPtr(
|
||||
T_RcPtr< Q > const& other ) noexcept
|
||||
: target_{ other.target_ }
|
||||
: target_{ nullptr }
|
||||
{
|
||||
if ( target_ ) {
|
||||
target_->increaseReferences_( );
|
||||
}
|
||||
setTarget_( other.target_ );
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
|
@ -93,6 +119,45 @@ template<
|
|||
}
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
inline T_RcPtr< T >& T_RcPtr< T >::operator= (
|
||||
T_Self const& other ) noexcept
|
||||
{
|
||||
clear( );
|
||||
setTarget_( other.target_ );
|
||||
return *this;
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
template<
|
||||
typename Q ,
|
||||
T_EnableForChild< T , Q >
|
||||
> inline T_RcPtr< T >& T_RcPtr< T >::operator= (
|
||||
T_RcPtr< Q > const& other ) noexcept
|
||||
{
|
||||
clear( );
|
||||
setTarget_( other.target_ );
|
||||
return *this;
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
template<
|
||||
typename Q ,
|
||||
T_EnableForParent< T , Q >
|
||||
> inline T_RcPtr< T >& T_RcPtr< T >::operator= (
|
||||
T_RcPtr< Q > const& other )
|
||||
{
|
||||
clear( );
|
||||
if ( other.target_ ) {
|
||||
T* const nt{ dynamic_cast< T* >( other.target_ ) };
|
||||
if ( nt == nullptr ) {
|
||||
throw std::bad_cast( );
|
||||
}
|
||||
setTarget_( nt );
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
template< typename T >
|
||||
|
@ -124,6 +189,80 @@ template<
|
|||
}
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
template<
|
||||
typename Q ,
|
||||
T_EnableForChild< T , Q >
|
||||
> inline T_RcPtr< T >& T_RcPtr< T >::operator= (
|
||||
T_RcPtr< Q >&& other ) noexcept
|
||||
{
|
||||
clear( );
|
||||
target_ = other.target_;
|
||||
other.target_ = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
template<
|
||||
typename Q ,
|
||||
T_EnableForParent< T , Q >
|
||||
> inline T_RcPtr< T >& T_RcPtr< T >::operator= (
|
||||
T_RcPtr< Q >&& other )
|
||||
{
|
||||
clear( );
|
||||
if ( other.target_ ) {
|
||||
T* const nt{ dynamic_cast< T* >( other.target_ ) };
|
||||
if ( nt == nullptr ) {
|
||||
throw std::bad_cast( );
|
||||
}
|
||||
other.target_ = nullptr;
|
||||
target_ = nt;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
template< typename T >
|
||||
inline T_RcPtr< T >::operator bool ( ) const noexcept
|
||||
{
|
||||
return target_ != nullptr;
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
inline bool T_RcPtr< T >::operator! ( ) const noexcept
|
||||
{
|
||||
return target_ == nullptr;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
template< typename T >
|
||||
inline T_RcPtr< T >::operator T* ( ) const noexcept
|
||||
{
|
||||
return target_;
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
inline T* T_RcPtr< T >::get( ) const noexcept
|
||||
{
|
||||
return target_;
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
inline T* T_RcPtr< T >::operator -> ( ) const
|
||||
{
|
||||
assert( target_ != nullptr );
|
||||
return target_;
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
inline T& T_RcPtr< T >::operator * ( ) const
|
||||
{
|
||||
assert( target_ != nullptr );
|
||||
return *target_;
|
||||
}
|
||||
|
||||
|
||||
} // namespace ebcl
|
||||
#endif // _H_EBCL_INLINE_REFCOUNT
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue