855 lines
19 KiB
C++
855 lines
19 KiB
C++
|
/******************************************************************************/
|
||
|
/* POINTERS - INLINE CODE *****************************************************/
|
||
|
/******************************************************************************/
|
||
|
|
||
|
#ifndef _H_LW_LIB_INLINE_POINTERS
|
||
|
#define _H_LW_LIB_INLINE_POINTERS
|
||
|
#include <lw/lib/Pointers.hh>
|
||
|
namespace lw {
|
||
|
|
||
|
|
||
|
/*= T_OwnPtr =================================================================*/
|
||
|
|
||
|
template< typename T >
|
||
|
inline T_OwnPtr< T >::T_OwnPtr( T* p ) noexcept
|
||
|
: p_( p )
|
||
|
{ }
|
||
|
|
||
|
template< typename T >
|
||
|
inline T_OwnPtr< T >::T_OwnPtr( )
|
||
|
: T_OwnPtr( nullptr )
|
||
|
{ }
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
template< typename T >
|
||
|
template<
|
||
|
typename Q ,
|
||
|
T_EnableForChild< T , Q >
|
||
|
> inline T_OwnPtr< T >::T_OwnPtr( T_OwnPtr< Q >&& source ) noexcept
|
||
|
: p_( nullptr )
|
||
|
{
|
||
|
T* temp( source.p_ );
|
||
|
source.p_ = nullptr;
|
||
|
p_ = temp;
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
template<
|
||
|
typename Q ,
|
||
|
T_EnableForParent< T , Q >
|
||
|
> inline T_OwnPtr< T >::T_OwnPtr( T_OwnPtr< Q >&& source )
|
||
|
: p_( nullptr )
|
||
|
{
|
||
|
T* temp( dynamic_cast< T* >( source.p_ ) );
|
||
|
if ( source.p_ && !temp ) {
|
||
|
throw std::bad_cast( );
|
||
|
}
|
||
|
source.p_ = nullptr;
|
||
|
p_ = temp;
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
template<
|
||
|
typename Q ,
|
||
|
T_EnableForChild< T , Q >
|
||
|
> inline T_OwnPtr< T >& T_OwnPtr< T >::operator= ( T_OwnPtr< Q >&& source ) noexcept
|
||
|
{
|
||
|
T* temp( source.p_ );
|
||
|
clear( );
|
||
|
source.p_ = nullptr;
|
||
|
p_ = temp;
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
template<
|
||
|
typename Q ,
|
||
|
T_EnableForParent< T , Q >
|
||
|
> inline T_OwnPtr< T >& T_OwnPtr< T >::operator= (
|
||
|
T_OwnPtr< Q >&& source )
|
||
|
{
|
||
|
T* temp( dynamic_cast< T* >( source.p_ ) );
|
||
|
if ( source.p_ && !temp ) {
|
||
|
throw std::bad_cast( );
|
||
|
}
|
||
|
clear( );
|
||
|
source.p_ = nullptr;
|
||
|
p_ = temp;
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
template< typename T >
|
||
|
inline T_OwnPtr< T >::~T_OwnPtr( )
|
||
|
{
|
||
|
clear( );
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
template< typename T >
|
||
|
inline void swap( T_OwnPtr< T >& lhs , T_OwnPtr< T >& rhs ) noexcept
|
||
|
{
|
||
|
std::swap( lhs.p_ , rhs.p_ );
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
template< typename T >
|
||
|
inline void T_OwnPtr< T >::clear( )
|
||
|
{
|
||
|
T* ptr( nullptr );
|
||
|
std::swap( p_ , ptr );
|
||
|
delete ptr;
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
template< typename T >
|
||
|
inline bool T_OwnPtr< T >::operator== ( const T* p ) const
|
||
|
{
|
||
|
return p == p_;
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
inline bool T_OwnPtr< T >::operator!= ( const T* p ) const
|
||
|
{
|
||
|
return p != p_;
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
inline T_OwnPtr< T >::operator bool ( ) const
|
||
|
{
|
||
|
return p_ != nullptr;
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
inline bool T_OwnPtr< T >::operator! ( ) const
|
||
|
{
|
||
|
return p_ == nullptr;
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
template< typename T >
|
||
|
inline T* T_OwnPtr< T >::get( ) const
|
||
|
{
|
||
|
return p_;
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
inline T* T_OwnPtr< T >::operator-> ( ) const
|
||
|
{
|
||
|
assert( p_ != nullptr );
|
||
|
return p_;
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
inline T& T_OwnPtr< T >::operator* ( ) const
|
||
|
{
|
||
|
assert( p_ != nullptr );
|
||
|
return *p_;
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
template< typename T >
|
||
|
inline T_SharedPtr< T > T_OwnPtr< T >::makeShared( )
|
||
|
{
|
||
|
T* temp( nullptr );
|
||
|
std::swap( p_ , temp );
|
||
|
return T_SharedPtr< T >( temp );
|
||
|
}
|
||
|
|
||
|
|
||
|
/*= NewOwned / OwnRawPointer =================================================*/
|
||
|
|
||
|
template<
|
||
|
typename Type ,
|
||
|
typename... ArgTypes
|
||
|
>
|
||
|
inline T_OwnPtr< Type > NewOwned( ArgTypes&& ... arguments )
|
||
|
{
|
||
|
return T_OwnPtr< Type >( new Type( std::forward< ArgTypes >( arguments ) ... ) );
|
||
|
}
|
||
|
|
||
|
template< typename Type >
|
||
|
inline T_OwnPtr< Type > OwnRawPointer( Type*& pointer ) noexcept
|
||
|
{
|
||
|
assert( pointer != nullptr );
|
||
|
T_OwnPtr< Type > p( pointer );
|
||
|
pointer = nullptr;
|
||
|
return p;
|
||
|
}
|
||
|
|
||
|
template<
|
||
|
typename Type , typename Other ,
|
||
|
T_EnableForChild< Type , Other >
|
||
|
> inline T_OwnPtr< Type > OwnRawPointer( Other*& pointer ) noexcept
|
||
|
{
|
||
|
assert( pointer != nullptr );
|
||
|
T_OwnPtr< Type > p( pointer );
|
||
|
pointer = nullptr;
|
||
|
return p;
|
||
|
}
|
||
|
|
||
|
template<
|
||
|
typename Type , typename Other ,
|
||
|
T_EnableForParent< Type , Other >
|
||
|
> inline T_OwnPtr< Type > OwnRawPointer( Other*& pointer )
|
||
|
{
|
||
|
assert( pointer != nullptr );
|
||
|
Type* temp( dynamic_cast< Type* >( pointer ) );
|
||
|
if ( temp == nullptr ) {
|
||
|
throw std::bad_cast( );
|
||
|
}
|
||
|
T_OwnPtr< Type > p( temp );
|
||
|
pointer = nullptr;
|
||
|
return p;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*= T_Reference_ =============================================================*/
|
||
|
|
||
|
// Reference counter for shared pointers
|
||
|
class T_Reference_
|
||
|
{
|
||
|
private:
|
||
|
typedef std::function< void ( void* ) > F_Destr_;
|
||
|
|
||
|
friend struct T_WeakChain_;
|
||
|
|
||
|
void* pointer_;
|
||
|
F_Destr_ destr_;
|
||
|
uint32_t count_;
|
||
|
T_WeakChain_* weaks_;
|
||
|
|
||
|
public:
|
||
|
/* References are pooled */
|
||
|
void* operator new( size_t count ) noexcept;
|
||
|
void operator delete( void* object ) noexcept;
|
||
|
|
||
|
T_Reference_( ) = delete;
|
||
|
T_Reference_( T_Reference_ const& ) = delete;
|
||
|
T_Reference_( T_Reference_&& ) = delete;
|
||
|
|
||
|
T_Reference_( void* ptr , F_Destr_ destructor );
|
||
|
|
||
|
~T_Reference_( );
|
||
|
|
||
|
void* pointer( ) const;
|
||
|
T_Reference_ * increase( );
|
||
|
void decrease( );
|
||
|
void* extract( );
|
||
|
};
|
||
|
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
inline void* T_Reference_::pointer( ) const
|
||
|
{
|
||
|
return pointer_;
|
||
|
}
|
||
|
|
||
|
inline T_Reference_* T_Reference_::increase( )
|
||
|
{
|
||
|
assert( count_ > 0 );
|
||
|
count_ ++;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
inline void T_Reference_::decrease( )
|
||
|
{
|
||
|
assert( count_ > 0 );
|
||
|
count_ --;
|
||
|
if ( count_ == 0 ) {
|
||
|
delete this;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/*= T_BasePtr_ ===============================================================*/
|
||
|
|
||
|
template< typename T >
|
||
|
inline T_BasePtr_< T >::T_BasePtr_( T_Reference_* ref ) noexcept
|
||
|
: ref_( ref )
|
||
|
{ }
|
||
|
|
||
|
template< typename T >
|
||
|
inline T_BasePtr_< T >::operator bool ( ) const
|
||
|
{
|
||
|
return ref_ != nullptr;
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
inline bool T_BasePtr_< T >::operator! ( ) const
|
||
|
{
|
||
|
return ref_ == nullptr;
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
inline T* T_BasePtr_< T >::operator-> ( ) const
|
||
|
{
|
||
|
assert( ref_ != nullptr );
|
||
|
return reinterpret_cast< T* >( ref_->pointer( ) );
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
inline T_BasePtr_< T >::operator T* ( ) const
|
||
|
{
|
||
|
return ref_ == nullptr
|
||
|
? nullptr
|
||
|
: reinterpret_cast< T* >( ref_->pointer( ) );
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
inline T& T_BasePtr_< T >::operator* ( ) const
|
||
|
{
|
||
|
assert( ref_ != nullptr );
|
||
|
return *reinterpret_cast< T* >( ref_->pointer( ) );
|
||
|
}
|
||
|
|
||
|
|
||
|
/*= X_TooManyReferences ======================================================*/
|
||
|
|
||
|
inline X_TooManyReferences::X_TooManyReferences( )
|
||
|
: std::runtime_error( "too many references" )
|
||
|
{ }
|
||
|
|
||
|
/*= T_SharedPtr ==============================================================*/
|
||
|
|
||
|
template< typename T >
|
||
|
inline T_Reference_* T_SharedPtr< T >::setRef( T_Reference_* from )
|
||
|
{
|
||
|
if ( from == nullptr ) {
|
||
|
return nullptr;
|
||
|
}
|
||
|
return from->increase( );
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
inline void T_SharedPtr< T >::clearRef( )
|
||
|
{
|
||
|
if ( ref_ != nullptr ) {
|
||
|
ref_->decrease( );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
template< typename T >
|
||
|
inline T_SharedPtr< T >::T_SharedPtr( T* ptr )
|
||
|
: T_Base_( new T_Reference_( ptr ,
|
||
|
[]( void* p ) {
|
||
|
delete reinterpret_cast< T* >( p );
|
||
|
} ) )
|
||
|
{ }
|
||
|
|
||
|
template< typename T >
|
||
|
inline T_SharedPtr< T >::T_SharedPtr( ) noexcept
|
||
|
: T_Base_( nullptr )
|
||
|
{ }
|
||
|
|
||
|
template< typename T >
|
||
|
inline T_SharedPtr< T >::~T_SharedPtr( )
|
||
|
{
|
||
|
clearRef( );
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
template< typename T >
|
||
|
inline T_SharedPtr< T >::T_SharedPtr( T_Self_ const& source )
|
||
|
: T_Base_( setRef( source.ref_ ) )
|
||
|
{ }
|
||
|
|
||
|
template< typename T >
|
||
|
template<
|
||
|
typename Q ,
|
||
|
T_EnableForChild< T , Q >
|
||
|
> inline T_SharedPtr< T >::T_SharedPtr( T_SharedPtr< Q > const& other )
|
||
|
: T_Base_( setRef( other.ref_ ) )
|
||
|
{ }
|
||
|
|
||
|
template< typename T >
|
||
|
template<
|
||
|
typename Q ,
|
||
|
T_EnableForParent< T , Q >
|
||
|
> inline T_SharedPtr< T >::T_SharedPtr( T_SharedPtr< Q > const& other )
|
||
|
: T_Base_( nullptr )
|
||
|
{
|
||
|
Q* const p( other );
|
||
|
if ( p != nullptr && dynamic_cast< T* >( p ) == nullptr ) {
|
||
|
throw std::bad_cast( );
|
||
|
}
|
||
|
ref_ = setRef( other.ref_ );
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
template< typename T >
|
||
|
template<
|
||
|
typename Q ,
|
||
|
T_EnableForChild< T , Q >
|
||
|
> inline T_SharedPtr< T >::T_SharedPtr( T_SharedPtr< Q >&& other ) noexcept
|
||
|
: T_Base_( other.ref_ )
|
||
|
{
|
||
|
other.ref_ = nullptr;
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
template<
|
||
|
typename Q ,
|
||
|
T_EnableForParent< T , Q >
|
||
|
> inline T_SharedPtr< T >::T_SharedPtr( T_SharedPtr< Q >&& other )
|
||
|
: T_Base_( nullptr )
|
||
|
{
|
||
|
Q* const p( other );
|
||
|
if ( p != nullptr && dynamic_cast< T* >( p ) == nullptr ) {
|
||
|
throw std::bad_cast( );
|
||
|
}
|
||
|
using std::swap;
|
||
|
swap( ref_ , other.ref_ );
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
template< typename T >
|
||
|
inline T_SharedPtr< T >& T_SharedPtr< T >::operator= ( T_SharedPtr< T > const& other )
|
||
|
{
|
||
|
if ( &other != this && other.ref_ != ref_ ) {
|
||
|
clearRef( );
|
||
|
ref_ = setRef( other.ref_ );
|
||
|
}
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
template<
|
||
|
typename Q ,
|
||
|
T_EnableForChild< T , Q >
|
||
|
> inline T_SharedPtr< T >& T_SharedPtr< T >::operator= ( T_SharedPtr< Q > const& other )
|
||
|
{
|
||
|
if ( other.ref_ != ref_ ) {
|
||
|
clearRef( );
|
||
|
ref_ = setRef( other.ref_ );
|
||
|
}
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
template<
|
||
|
typename Q ,
|
||
|
T_EnableForParent< T , Q >
|
||
|
> inline T_SharedPtr< T >& T_SharedPtr< T >::operator= ( T_SharedPtr< Q > const& other )
|
||
|
{
|
||
|
if ( other.ref_ != ref_ ) {
|
||
|
Q* const p( other );
|
||
|
if ( p != nullptr && dynamic_cast< T* >( p ) == nullptr ) {
|
||
|
throw std::bad_cast( );
|
||
|
}
|
||
|
clearRef( );
|
||
|
ref_ = setRef( other.ref_ );
|
||
|
}
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
template< typename T >
|
||
|
template<
|
||
|
typename Q ,
|
||
|
T_EnableForChild< T , Q >
|
||
|
> inline T_SharedPtr< T >& T_SharedPtr< T >::operator= ( T_SharedPtr< Q >&& other ) noexcept
|
||
|
{
|
||
|
if ( other.ref_ != ref_ ) {
|
||
|
clearRef( );
|
||
|
ref_ = nullptr;
|
||
|
std::swap( ref_ , other.ref_ );
|
||
|
}
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
template<
|
||
|
typename Q ,
|
||
|
T_EnableForParent< T , Q >
|
||
|
> inline T_SharedPtr< T >& T_SharedPtr< T >::operator= ( T_SharedPtr< Q >&& other )
|
||
|
{
|
||
|
if ( other.ref_ != ref_ ) {
|
||
|
Q* const p( other );
|
||
|
if ( p != nullptr && dynamic_cast< T* >( p ) == nullptr ) {
|
||
|
throw std::bad_cast( );
|
||
|
}
|
||
|
clearRef( );
|
||
|
ref_ = nullptr;
|
||
|
std::swap( ref_ , other.ref_ );
|
||
|
}
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
template< typename T >
|
||
|
inline void swap( T_SharedPtr< T >& lhs , T_SharedPtr< T >& rhs ) noexcept
|
||
|
{
|
||
|
std::swap( lhs.ref_ , rhs.ref_ );
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
template< typename T >
|
||
|
inline bool T_SharedPtr< T >::operator== ( T_SharedPtr< T > const& other ) const
|
||
|
{
|
||
|
return other.ref_ == ref_;
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
inline bool T_SharedPtr< T >::operator!= ( T_SharedPtr< T > const& other ) const
|
||
|
{
|
||
|
return other.ref_ != ref_;
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
inline bool T_SharedPtr< T >::operator== ( T_WeakPtr< T > const& other ) const
|
||
|
{
|
||
|
return other.ref_ == ref_;
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
inline bool T_SharedPtr< T >::operator!= ( T_WeakPtr< T > const& other ) const
|
||
|
{
|
||
|
return other.ref_ != ref_;
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
inline void T_SharedPtr< T >::clear( )
|
||
|
{
|
||
|
clearRef( );
|
||
|
ref_ = nullptr;
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
T_OwnPtr< T > T_SharedPtr< T >::makeOwned( )
|
||
|
{
|
||
|
if ( ref_ == nullptr ) {
|
||
|
return T_OwnPtr< T >( );
|
||
|
}
|
||
|
void* const p( ref_->extract( ) );
|
||
|
ref_ = nullptr;
|
||
|
return T_OwnPtr< T >( reinterpret_cast< T* >( p ) );
|
||
|
}
|
||
|
|
||
|
|
||
|
/*= T_WeakPtr ================================================================*/
|
||
|
|
||
|
template< typename T >
|
||
|
inline T_WeakPtr< T >::T_WeakPtr( T_Reference_* ref )
|
||
|
: T_BasePtr_< T >( ref ) , chain_( ref_ )
|
||
|
{
|
||
|
chain_.init( );
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
inline T_WeakPtr< T >::T_WeakPtr( )
|
||
|
: T_WeakPtr( nullptr )
|
||
|
{ }
|
||
|
|
||
|
template< typename T >
|
||
|
inline T_WeakPtr< T >::~T_WeakPtr( )
|
||
|
{
|
||
|
chain_.unchain( );
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
template< typename T >
|
||
|
inline T_WeakPtr< T >::T_WeakPtr( T_WeakPtr< T > const& other )
|
||
|
: T_WeakPtr( other.ref_ )
|
||
|
{ }
|
||
|
|
||
|
template< typename T >
|
||
|
template< typename Q , T_EnableForChild< T , Q > >
|
||
|
inline T_WeakPtr< T >::T_WeakPtr( T_WeakPtr< Q > const& other )
|
||
|
: T_WeakPtr( other.ref_ )
|
||
|
{ }
|
||
|
|
||
|
template< typename T >
|
||
|
template< typename Q , T_EnableForParent< T , Q > >
|
||
|
inline T_WeakPtr< T >::T_WeakPtr( T_WeakPtr< Q > const& other )
|
||
|
: T_WeakPtr( )
|
||
|
{
|
||
|
Q* const p( other );
|
||
|
if ( p != nullptr && dynamic_cast< T* >( p ) == nullptr ) {
|
||
|
throw std::bad_cast( );
|
||
|
}
|
||
|
ref_ = other.ref_;
|
||
|
chain_.init( );
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
template< typename T >
|
||
|
template< typename Q , T_EnableForChild< T , Q > >
|
||
|
inline T_WeakPtr< T >::T_WeakPtr( T_WeakPtr< Q >&& other ) noexcept
|
||
|
: T_WeakPtr( nullptr )
|
||
|
{
|
||
|
other.chain_.unchain( );
|
||
|
ref_ = other.ref_;
|
||
|
other.ref_ = nullptr;
|
||
|
chain_.init( );
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
template< typename Q , T_EnableForParent< T , Q > >
|
||
|
inline T_WeakPtr< T >::T_WeakPtr( T_WeakPtr< Q >&& other )
|
||
|
: T_WeakPtr( nullptr )
|
||
|
{
|
||
|
Q* const p( other );
|
||
|
if ( p != nullptr && dynamic_cast< T* >( p ) == nullptr ) {
|
||
|
throw std::bad_cast( );
|
||
|
}
|
||
|
other.chain_.unchain( );
|
||
|
ref_ = other.ref_;
|
||
|
other.ref_ = nullptr;
|
||
|
chain_.init( );
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
template< typename T >
|
||
|
inline T_WeakPtr< T >::T_WeakPtr( T_SharedPtr< T > const& shared )
|
||
|
: T_WeakPtr( shared.ref_ )
|
||
|
{ }
|
||
|
|
||
|
template< typename T >
|
||
|
template< typename Q , T_EnableForChild< T , Q > >
|
||
|
inline T_WeakPtr< T >::T_WeakPtr( T_SharedPtr< Q > const& shared )
|
||
|
: T_WeakPtr( shared.ref_ )
|
||
|
{ }
|
||
|
|
||
|
template< typename T >
|
||
|
template< typename Q , T_EnableForParent< T , Q > >
|
||
|
inline T_WeakPtr< T >::T_WeakPtr( T_SharedPtr< Q > const& shared )
|
||
|
: T_WeakPtr( nullptr )
|
||
|
{
|
||
|
Q* const p( shared );
|
||
|
if ( p != nullptr && dynamic_cast< T* >( p ) == nullptr ) {
|
||
|
throw std::bad_cast( );
|
||
|
}
|
||
|
ref_ = shared.ref_;
|
||
|
chain_.init( );
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
template< typename T >
|
||
|
inline void swap( T_WeakPtr< T >& lhs , T_WeakPtr< T >& rhs )
|
||
|
{
|
||
|
if ( lhs.ref_ != rhs.ref_ ) {
|
||
|
lhs.chain_.unchain( );
|
||
|
rhs.chain_.unchain( );
|
||
|
std::swap( lhs.ref_ , rhs.ref_ );
|
||
|
lhs.chain_.init( );
|
||
|
rhs.chain_.init( );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
template< typename T >
|
||
|
inline T_WeakPtr< T >& T_WeakPtr< T >::operator= ( T_WeakPtr< T > const& other )
|
||
|
{
|
||
|
chain_.unchain( );
|
||
|
ref_ = other.ref_;
|
||
|
chain_.init( );
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
template< typename Q , T_EnableForChild< T , Q > >
|
||
|
inline T_WeakPtr< T >& T_WeakPtr< T >::operator= ( T_WeakPtr< Q > const& other )
|
||
|
{
|
||
|
chain_.unchain( );
|
||
|
ref_ = other.ref_;
|
||
|
chain_.init( );
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
template< typename Q , T_EnableForParent< T , Q > >
|
||
|
inline T_WeakPtr< T >& T_WeakPtr< T >::operator= ( T_WeakPtr< Q > const& other )
|
||
|
{
|
||
|
Q* const p( other );
|
||
|
if ( p != nullptr && dynamic_cast< T* >( p ) == nullptr ) {
|
||
|
throw std::bad_cast( );
|
||
|
}
|
||
|
chain_.unchain( );
|
||
|
ref_ = other.ref_;
|
||
|
chain_.init( );
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
template< typename T >
|
||
|
template< typename Q , T_EnableForChild< T , Q > >
|
||
|
inline T_WeakPtr< T >& T_WeakPtr< T >::operator= ( T_WeakPtr< Q >&& other )
|
||
|
{
|
||
|
ref_ = nullptr;
|
||
|
chain_.unchain( );
|
||
|
if ( other.ref_ ) {
|
||
|
other.chain_.unchain( );
|
||
|
ref_ = other.ref_;
|
||
|
other.ref_ = nullptr;
|
||
|
chain_.init( );
|
||
|
other.chain_.init( );
|
||
|
}
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
template< typename Q , T_EnableForParent< T , Q > >
|
||
|
inline T_WeakPtr< T >& T_WeakPtr< T >::operator= ( T_WeakPtr< Q >&& other )
|
||
|
{
|
||
|
Q* const p( other );
|
||
|
if ( p != nullptr && dynamic_cast< T* >( p ) == nullptr ) {
|
||
|
throw std::bad_cast( );
|
||
|
}
|
||
|
ref_ = nullptr;
|
||
|
chain_.unchain( );
|
||
|
if ( other.ref_ ) {
|
||
|
other.chain_.unchain( );
|
||
|
ref_ = other.ref_;
|
||
|
other.ref_ = nullptr;
|
||
|
chain_.init( );
|
||
|
other.chain_.init( );
|
||
|
}
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
template< typename T >
|
||
|
inline T_WeakPtr< T >& T_WeakPtr< T >::operator= ( T_SharedPtr< T > const& shared )
|
||
|
{
|
||
|
chain_.unchain( );
|
||
|
ref_ = shared.ref_;
|
||
|
chain_.init( );
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
template< typename Q , T_EnableForChild< T , Q > >
|
||
|
inline T_WeakPtr< T >& T_WeakPtr< T >::operator= ( T_SharedPtr< Q > const& shared )
|
||
|
{
|
||
|
chain_.unchain( );
|
||
|
ref_ = shared.ref_;
|
||
|
chain_.init( );
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
template< typename Q , T_EnableForParent< T , Q > >
|
||
|
inline T_WeakPtr< T >& T_WeakPtr< T >::operator= ( T_SharedPtr< Q > const& shared )
|
||
|
{
|
||
|
Q* const p( shared );
|
||
|
if ( p != nullptr && dynamic_cast< T* >( p ) == nullptr ) {
|
||
|
throw std::bad_cast( );
|
||
|
}
|
||
|
chain_.unchain( );
|
||
|
ref_ = shared.ref_;
|
||
|
chain_.init( );
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
template< typename T >
|
||
|
inline bool T_WeakPtr< T >::operator== ( T_WeakPtr< T > const& other ) const
|
||
|
{
|
||
|
return other.ref_ == ref_;
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
inline bool T_WeakPtr< T >::operator!= ( T_WeakPtr< T > const& other ) const
|
||
|
{
|
||
|
return other.ref_ != ref_;
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
inline bool T_WeakPtr< T >::operator== ( T_SharedPtr< T > const& other ) const
|
||
|
{
|
||
|
return other.ref_ == ref_;
|
||
|
}
|
||
|
|
||
|
template< typename T >
|
||
|
inline bool T_WeakPtr< T >::operator!= ( T_SharedPtr< T > const& other ) const
|
||
|
{
|
||
|
return other.ref_ != ref_;
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
template< typename T >
|
||
|
inline void T_WeakPtr< T >::clear( )
|
||
|
{
|
||
|
chain_.unchain( );
|
||
|
ref_ = nullptr;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*= NewShared ================================================================*/
|
||
|
|
||
|
template<
|
||
|
typename Type ,
|
||
|
typename... ArgTypes
|
||
|
> inline T_SharedPtr< Type > NewShared( ArgTypes&& ... arguments )
|
||
|
{
|
||
|
return T_SharedPtr< Type >( new Type( std::forward< ArgTypes >( arguments ) ... ) );
|
||
|
}
|
||
|
|
||
|
template< typename Type >
|
||
|
T_SharedPtr< Type > ShareRawPointer(
|
||
|
Type*& pointer ) noexcept
|
||
|
{
|
||
|
assert( pointer != nullptr );
|
||
|
T_SharedPtr< Type > p( pointer );
|
||
|
pointer = nullptr;
|
||
|
return p;
|
||
|
}
|
||
|
|
||
|
template<
|
||
|
typename Type , typename Other ,
|
||
|
T_EnableForChild< Type , Other >
|
||
|
> inline T_SharedPtr< Type > ShareRawPointer(
|
||
|
Other*& pointer ) noexcept
|
||
|
{
|
||
|
assert( pointer != nullptr );
|
||
|
T_SharedPtr< Type > p( pointer );
|
||
|
pointer = nullptr;
|
||
|
return p;
|
||
|
}
|
||
|
|
||
|
template<
|
||
|
typename Type , typename Other ,
|
||
|
T_EnableForParent< Type , Other >
|
||
|
> inline T_SharedPtr< Type > ShareRawPointer(
|
||
|
Other*& pointer )
|
||
|
{
|
||
|
assert( pointer != nullptr );
|
||
|
Type* temp( dynamic_cast< Type* >( pointer ) );
|
||
|
if ( temp == nullptr ) {
|
||
|
throw std::bad_cast( );
|
||
|
}
|
||
|
T_SharedPtr< Type > p( temp );
|
||
|
pointer = nullptr;
|
||
|
return p;
|
||
|
}
|
||
|
|
||
|
|
||
|
} // namespace
|
||
|
#endif // _H_LW_LIB_INLINE_POINTERS
|