corelib/src/Pointers.cc

104 lines
2.1 KiB
C++
Raw Permalink Normal View History

/******************************************************************************/
/* POINTERS *******************************************************************/
/******************************************************************************/
#include <ebcl/Alloc.hh>
#include <ebcl/Config.hh>
#include <ebcl/Pointers.hh>
using namespace ebcl;
/*= 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_ ) ,
EBCL_CFG_SHAREDPTR_REFPOOL_SIZE ,
EBCL_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;
}