/******************************************************************************/ /* POINTERS *******************************************************************/ /******************************************************************************/ #include #include #include using namespace lw; /*= T_WeakChain_ =============================================================*/ T_WeakChain_::T_WeakChain_( T_Reference_*& ref ) : ref( &ref ) , prev( nullptr ) , next( nullptr ) { } void T_WeakChain_::unchain( ) { if ( prev != nullptr ) { prev->next = next; prev = nullptr; } else if ( (*ref) != nullptr ) { assert( this == (*ref)->weaks_ ); (*ref)->weaks_ = next; } if ( next != nullptr ) { next->prev = prev; next = nullptr; } } void T_WeakChain_::init( ) { if ( (*ref) == nullptr ) { return; } next = (*ref)->weaks_; if ( next != nullptr ) { next->prev = this; } (*ref)->weaks_ = this; } /*= T_Reference_ =============================================================*/ namespace { static T_ThreadedPoolAllocator< sizeof( T_Reference_ ) , alignof( T_Reference_ ) , LW_CFG_SHAREDPTR_REFPOOL_SIZE , LW_CFG_SHAREDPTR_REFPOOL_MAXFREE > ReferenceAllocator_; } void* T_Reference_::operator new( const size_t count ) noexcept { return ReferenceAllocator_.allocate( count ); } void T_Reference_::operator delete( void* const object ) noexcept { return ReferenceAllocator_.free( object ); } /*----------------------------------------------------------------------------*/ T_Reference_::T_Reference_( void* const ptr , F_Destr_ destructor ) : pointer_( ptr ) , destr_( std::move( destructor ) ) , count_( 1 ) , weaks_( nullptr ) { assert( pointer_ != nullptr ); } T_Reference_::~T_Reference_( ) { assert( count_ == 0 ); T_WeakChain_* wr = weaks_; while ( wr != nullptr ) { T_WeakChain_* const next = wr->next; wr->unchain( ); *( wr->ref ) = nullptr; wr = next; } destr_( pointer_ ); } void* T_Reference_::extract( ) { if ( count_ > 1 ) { throw X_TooManyReferences( ); } void* p( pointer_ ); count_ = 0; pointer_ = nullptr; delete this; return p; }