35 #ifndef CARTOBASE_SMART_RCPTR_H 
   36 #define CARTOBASE_SMART_RCPTR_H 
   47 #define CARTO_THREADED_RCPTR 
   49 #ifdef CARTO_THREADED_RCPTR 
   50 #ifndef CARTO_NO_BOOST 
   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; }
 
  311   inline explicit const_ref( 
const T *pObject, 
bool externalowner )
 
  316 #if __cplusplus >= 201103L 
  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 )
 
  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 )
 
  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 
  486   ref( std::unique_ptr<U>&& r ) : 
const_ref<T>( std::move(r) ) {}
 
  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 
  527 void 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 );
 
  541 void 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 );
 
  557 const 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 )
 
  580 void 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 );
 
  605 void RCObject::destroy( const_ref<T> *r )
 
  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 );
 
  625 const T *RCObject::release( const_ref<T> *r ) {
 
  627   std::cout << 
"Releasing RCObject (" << r->_ref << 
")" << std::endl;
 
  629   const T * 
const result = r->_ref;
 
  630   if ( r->_pcount && *r->_pcount >= 0 )
 
  638 template <
typename T>
 
  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;
 
Base class for reference counted objects (intrusive)
RCObject(const RCObject &)
RCObject & operator=(const RCObject &)
Constant Ref to an object of class T.
const_ref(const ref< T > &other)
const T & operator*() const
const T * pointer() const
bool operator!=(const ref< T > &other) const
const_ref(const const_ref< R > &other)
const_ref(const T *pObject)
const_ref(std::auto_ptr< U > r)
const_ref(const ref< R > &o)
const_ref(const const_ref< T > &other)
bool operator==(const ref< T > &other) const
const T * operator->() const
const_ref< T > & operator=(const ref< T > &other)
const_ref(const T *pObject, bool externalowner)
rc_ptr_trick merely makes a public access to the reference counter inside a rc_ptr.
Reference-counting pointer.
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(const ref< T > &other)
ref(std::auto_ptr< U > r)
ref(T *pObject, bool externalowner)
ref(const ref< R > &other)
ref< T > & operator=(const ref< T > &other)
A multi-purpose general smart pointer, which can act as either a rc_ptr, a weak_ptr or a weak_shared_...
reference_wrapper< T > ref(T &ref)
Function to create a wrapper holding a reference.