35#ifndef CARTOBASE_SMART_RCPTR_H
36#define CARTOBASE_SMART_RCPTR_H
47#define CARTO_THREADED_RCPTR
49#ifdef CARTO_THREADED_RCPTR
51#include <boost/version.hpp>
52#if BOOST_VERSION >= 103300 && \
53 ( !defined( linux ) || ( defined( __GNUC__ ) && __GNUC__ >= 4 ) )
54#include <boost/detail/atomic_count.hpp>
55#ifndef BOOST_AC_USE_PTHREADS
56#define CARTO_RCPTR_USE_BOOST
61#ifndef CARTO_RCPTR_USE_BOOST
66#if !defined( CARTO_RCPTR_USE_BOOST ) && !defined( CARTO_RCPTR_USE_ZOOLIB )
67#undef CARTO_THREADED_RCPTR
84#ifndef DOXYGEN_HIDE_INTERNAL_CLASSES
91 template <
class T>
friend class ref;
97 static void construct(
const_ref<T> *,
const T *,
bool externalowner );
107#ifndef DOXYGEN_HIDE_INTERNAL_CLASSES
111 template <
class T>
friend class ref;
119 static void construct(
const_ref<T> *,
const T *,
bool externalowner );
124#ifdef CARTO_THREADED_RCPTR
138 : _refCounter( 0 ) {}
145 long refCounter = _refCounter;
148 std::cerr <<
"RCObject destructor called while " << refCounter
149 <<
" references are still alive on object " <<
this
153 for(
long i=0; i<refCounter; ++i )
156 for(
long i=0; i<-refCounter; ++i )
167#ifndef DOXYGEN_HIDE_INTERNAL_CLASSES
179 template <
class R>
friend class ref;
200 template <
class R>
friend class ref;
212 return ( _pcount ? *_pcount : 0 );
290#ifndef DOXYGEN_HIDE_INTERNAL_CLASSES
295#ifndef DOXYGEN_HIDE_INTERNAL_CLASSES
299 template <
class R>
friend class ref;
304 inline const_ref() { this->_pcount = 0; this->_ref = 0; }
308 RefConstruction<T>::construct(
this, pObject,
false );
311 inline explicit const_ref(
const T *pObject,
bool externalowner )
313 RefConstruction<T>::construct(
this, pObject, externalowner );
316#if __cplusplus >= 201103L
323 RefConstruction<T>::construct(
this, r.release(),
false );
329 RefConstruction<T>::construct(
this, r.release(),
false );
335 std::cout <<
"New ref from other ref (" << other._ref <<
")" << std::endl;
337 if( other._pcount && *other._pcount >= 0 )
339 this->_pcount = other._pcount;
340 this->_ref = other._ref;
345 std::cout <<
"New ref from other ref (" << other._ref <<
")" << std::endl;
347 if( other._pcount && *other._pcount >= 0 )
349 this->_pcount = other._pcount;
350 this->_ref = other._ref;
357 std::cout <<
"New ref from other ref with implicit cast (" << other._ref
360 if( other._pcount && *other._pcount >= 0 )
362 this->_pcount = other._pcount;
363 this->_ref = other._ref;
369 std::cout <<
"New ref from other ref with implicit cast (" << other._ref <<
")" << std::endl;
371 if( other._pcount && *other._pcount >= 0 )
373 this->_pcount = other._pcount;
374 this->_ref = other._ref;
383 inline bool isNull()
const {
return this->_pcount == NULL; }
392 return static_cast<const T *
>( this->_ref );
396 return *
static_cast<const T *
>( this->_ref );
400 return static_cast<const T *
>( this->_ref );
405 return this->_pcount ? *this->_pcount : 0;
429 std::cout <<
"ref (" << this->_ref <<
") = ref (" << other._ref <<
")"
432 if ( this->_ref != other._ref )
434 if( other._pcount && *other._pcount >= 0 )
436 RefConstruction<T>::destroy(
this );
437 this->_pcount = other._pcount;
438 this->_ref = other._ref;
447 std::cout <<
"ref (" << this->_ref <<
") = ref (" << other._ref <<
")"
450 if (
this != &other && this->_ref != other._ref )
452 if( other._pcount && *other._pcount >= 0 )
454 RefConstruction<T>::destroy(
this );
455 this->_pcount = other._pcount;
456 this->_ref = other._ref;
476 std::cout <<
"New empty ref" << std::endl;
481 inline explicit ref( T *pObject,
bool externalowner )
482 :
const_ref<T>( pObject, externalowner ) {}
484#if __cplusplus >= 201103L
500 return const_cast<T *
>( RefConstruction<T>::release(
this ) );
509 return static_cast<T *
>( this->_ref );
513 return *
static_cast<T *
>( this->_ref );
517 return static_cast<T *
>( this->_ref );
525#ifndef DOXYGEN_HIDE_INTERNAL_CLASSES
527void DefaultRefConstruction::construct( const_ref<T> *r,
const T *pObject,
531 std::cout <<
"New ref (" << pObject <<
")" << std::endl;
533 if ( pObject && !externalowner )
535 else r->_pcount = NULL;
536 r->_ref =
const_cast<T *
>( pObject );
541void DefaultRefConstruction::destroy(
const_ref<T> *r ) {
543 std::cout <<
"Deleting ref (" << r->_ref <<
")" << std::endl;
545 if ( r->_pcount && --(*r->_pcount) == 0 )
548 std::cout <<
"Deleting ref object (" << r->_ref <<
")" << std::endl;
551 delete static_cast<T *
>( r->_ref );
557const T *DefaultRefConstruction::release(
const_ref<T> *r ) {
559 std::cout <<
"Releasing ref (" << r->_ref <<
")" << std::endl;
561 const T *
const result = r->_ref;
562 if ( r->_pcount && --(*r->_pcount) == 0 )
580void RCObject::construct(
const_ref<T> *r,
const T * pObject,
584 std::cout <<
"New RCObject (" << pObject <<
")" << std::endl;
588 long x = pObject->_refCounter;
589 if( externalowner && x == 0 )
591 --pObject->_refCounter;
595 ++pObject->_refCounter;
596 r->_pcount = &pObject->_refCounter;
600 r->_ref =
const_cast<T *
>( pObject );
608 std::cout <<
"RCObject::destroy (" << r->_ref <<
")" << std::endl;
610 std::cout <<
" count: " << *r->_pcount << std::endl;
612 std::cout <<
" no counter\n";
614 if( r->_pcount && --(*r->_pcount) == 0 )
617 std::cout <<
"Deleting RCObject object (" << r->_ref <<
")" << std::endl;
619 delete static_cast<T *
>( r->_ref );
627 std::cout <<
"Releasing RCObject (" << r->_ref <<
")" << std::endl;
629 const T *
const result = r->_ref;
630 if ( r->_pcount && *r->_pcount >= 0 )
642#ifndef DOXYGEN_HIDE_INTERNAL_CLASSES
646 void operator delete(
void* );
647 void operator delete[](
void* );
653 inline explicit rc_ptr( T *p,
bool externalowner )
654 :
ref<T>( p, externalowner ) {}
656#if __cplusplus >= 201103L
658 rc_ptr( std::unique_ptr<U>&& r ) :
ref<T>(
std::move(r) ) {}
671#ifndef DOXYGEN_HIDE_INTERNAL_CLASSES
687 template <
class R >
friend class ref;
702 template <
class R >
friend class ref;
717 template <
class R >
friend class ref;
732 template <
class R >
friend class ref;
747 template <
class R >
friend class ref;
762 template <
class R >
friend class ref;
777 template <
class R >
friend class ref;
792 template <
class R >
friend class ref;
807 template <
class R >
friend class ref;
822 template <
class R >
friend class ref;
RCObject(const RCObject &)
RCObject & operator=(const RCObject &)
friend class rc_ptr_trick
friend class DefaultRefConstruction
friend class rc_ptr_trick
Constant Ref to an object of class T.
const_ref(const ref< T > &other)
bool operator!=(const ref< T > &other) const
const T * pointer() const
const_ref(const const_ref< R > &other)
const_ref(const T *pObject)
const_ref(std::auto_ptr< U > r)
friend class DefaultRefConstruction
const_ref(const ref< R > &o)
const_ref(const const_ref< T > &other)
bool operator==(const ref< T > &other) const
const_ref< T > & operator=(const ref< T > &other)
const T * operator->() const
const T & operator*() const
const_ref(const T *pObject, bool externalowner)
bool operator<(const rc_ptr< T > &other) const
rc_ptr(T *p, bool externalowner)
rc_ptr(std::auto_ptr< U > r)
A ref is a const_ref which can reference non constant objects.
ref< T > & operator=(const ref< T > &other)
ref(const ref< T > &other)
ref(std::auto_ptr< U > r)
ref(T *pObject, bool externalowner)
ref(const ref< R > &other)