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 );
113#ifndef DOXYGEN_HIDE_INTERNAL_CLASSES
117 template <
class T>
friend class ref;
125 static void construct(
const_ref<T> *,
const T *,
bool externalowner );
130#ifdef CARTO_THREADED_RCPTR
144 : _refCounter( 0 ) {}
151 long refCounter = _refCounter;
154 std::cerr <<
"RCObject destructor called while " << refCounter
155 <<
" references are still alive on object " <<
this
159 for(
long i=0; i<refCounter; ++i )
162 for(
long i=0; i<-refCounter; ++i )
173#ifndef DOXYGEN_HIDE_INTERNAL_CLASSES
185 template <
class R>
friend class ref;
206 template <
class R>
friend class ref;
218 return ( _pcount ? *_pcount : 0 );
296#ifndef DOXYGEN_HIDE_INTERNAL_CLASSES
301#ifndef DOXYGEN_HIDE_INTERNAL_CLASSES
305 template <
class R>
friend class ref;
310 inline const_ref() { this->_pcount = 0; this->_ref = 0; }
314 RefConstruction<T>::construct(
this, pObject,
false );
317 inline explicit const_ref(
const T *pObject,
bool externalowner )
319 RefConstruction<T>::construct(
this, pObject, externalowner );
322#if __cplusplus >= 201103L
329 RefConstruction<T>::construct(
this, r.release(),
false );
335 RefConstruction<T>::construct(
this, r.release(),
false );
341 std::cout <<
"New ref from other ref (" << other._ref <<
")" << std::endl;
343 if( other._pcount && *other._pcount >= 0 )
345 this->_pcount = other._pcount;
346 this->_ref = other._ref;
351 std::cout <<
"New ref from other ref (" << other._ref <<
")" << std::endl;
353 if( other._pcount && *other._pcount >= 0 )
355 this->_pcount = other._pcount;
356 this->_ref = other._ref;
363 std::cout <<
"New ref from other ref with implicit cast (" << other._ref
366 if( other._pcount && *other._pcount >= 0 )
368 this->_pcount = other._pcount;
369 this->_ref = other._ref;
375 std::cout <<
"New ref from other ref with implicit cast (" << other._ref <<
")" << std::endl;
377 if( other._pcount && *other._pcount >= 0 )
379 this->_pcount = other._pcount;
380 this->_ref = other._ref;
389 inline bool isNull()
const {
return this->_pcount == NULL; }
398 return static_cast<const T *
>( this->_ref );
402 return *
static_cast<const T *
>( this->_ref );
406 return static_cast<const T *
>( this->_ref );
411 return this->_pcount ? *this->_pcount : 0;
435 std::cout <<
"ref (" << this->_ref <<
") = ref (" << other._ref <<
")"
438 if ( this->_ref != other._ref )
440 if( other._pcount && *other._pcount >= 0 )
442 RefConstruction<T>::destroy(
this );
443 this->_pcount = other._pcount;
444 this->_ref = other._ref;
453 std::cout <<
"ref (" << this->_ref <<
") = ref (" << other._ref <<
")"
456 if (
this != &other && this->_ref != other._ref )
458 if( other._pcount && *other._pcount >= 0 )
460 RefConstruction<T>::destroy(
this );
461 this->_pcount = other._pcount;
462 this->_ref = other._ref;
482 std::cout <<
"New empty ref" << std::endl;
487 inline explicit ref( T *pObject,
bool externalowner )
488 :
const_ref<T>( pObject, externalowner ) {}
490#if __cplusplus >= 201103L
515 return static_cast<T *
>( this->_ref );
519 return *
static_cast<T *
>( this->_ref );
523 return static_cast<T *
>( this->_ref );
531#ifndef DOXYGEN_HIDE_INTERNAL_CLASSES
533void DefaultRefConstruction::construct( const_ref<T> *r,
const T *pObject,
537 std::cout <<
"New ref (" << pObject <<
")" << std::endl;
539 if ( pObject && !externalowner )
541 else r->_pcount = NULL;
542 r->_ref =
const_cast<T *
>( pObject );
547void DefaultRefConstruction::destroy(
const_ref<T> *r ) {
549 std::cout <<
"Deleting ref (" << r->_ref <<
")" << std::endl;
551 if ( r->_pcount && --(*r->_pcount) == 0 )
554 std::cout <<
"Deleting ref object (" << r->_ref <<
")" << std::endl;
557 delete static_cast<T *
>( r->_ref );
565 std::cout <<
"Releasing ref (" << r->_ref <<
")" << std::endl;
567 const T *
const result = r->_ref;
568 if ( r->_pcount && --(*r->_pcount) == 0 )
586void RCObject::construct(
const_ref<T> *r,
const T * pObject,
590 std::cout <<
"New RCObject (" << pObject <<
")" << std::endl;
594 long x = pObject->_refCounter;
595 if( externalowner && x == 0 )
597 --pObject->_refCounter;
601 ++pObject->_refCounter;
602 r->_pcount = &pObject->_refCounter;
606 r->_ref =
const_cast<T *
>( pObject );
614 std::cout <<
"RCObject::destroy (" << r->_ref <<
")" << std::endl;
616 std::cout <<
" count: " << *r->_pcount << std::endl;
618 std::cout <<
" no counter\n";
620 if( r->_pcount && --(*r->_pcount) == 0 )
623 std::cout <<
"Deleting RCObject object (" << r->_ref <<
")" << std::endl;
625 delete static_cast<T *
>( r->_ref );
633 std::cout <<
"Releasing RCObject (" << r->_ref <<
")" << std::endl;
635 const T *
const result = r->_ref;
636 if ( r->_pcount && *r->_pcount >= 0 )
648#ifndef DOXYGEN_HIDE_INTERNAL_CLASSES
652 void operator delete(
void* );
653 void operator delete[](
void* );
659 inline explicit rc_ptr( T *p,
bool externalowner )
660 :
ref<T>( p, externalowner ) {}
662#if __cplusplus >= 201103L
664 rc_ptr( std::unique_ptr<U>&& r ) :
ref<T>(
std::move(r) ) {}
677#ifndef DOXYGEN_HIDE_INTERNAL_CLASSES
693 template <
class R >
friend class ref;
708 template <
class R >
friend class ref;
723 template <
class R >
friend class ref;
738 template <
class R >
friend class ref;
753 template <
class R >
friend class ref;
768 template <
class R >
friend class ref;
783 template <
class R >
friend class ref;
798 template <
class R >
friend class ref;
813 template <
class R >
friend class ref;
828 template <
class R >
friend class ref;
static const T * release(const_ref< T > *)
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)