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 58 #endif // BOOST_VERSION 59 #endif // CARTO_NO_BOOST 61 #ifndef CARTO_RCPTR_USE_BOOST 66 #if !defined( CARTO_RCPTR_USE_BOOST ) && !defined( CARTO_RCPTR_USE_ZOOLIB ) 67 #undef CARTO_THREADED_RCPTR 70 #endif // 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 );
102 #endif // DOXYGEN_HIDE_INTERNAL_CLASSES 107 #ifndef DOXYGEN_HIDE_INTERNAL_CLASSES
109 #endif // 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 131 mutable RefCounterType _refCounter;
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 );
215 #endif // DOXYGEN_HIDE_INTERNAL_CLASSES 290 #ifndef DOXYGEN_HIDE_INTERNAL_CLASSES
292 #endif // DOXYGEN_HIDE_INTERNAL_CLASSES 295 #ifndef DOXYGEN_HIDE_INTERNAL_CLASSES 298 #endif // 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; }
385 inline bool operator ==(
const T *pointer )
const {
return this->_ref == pointer; }
387 inline bool operator !=(
const ref<T> &other )
const {
return this->_ref != other._ref; }
388 inline bool operator !=(
const const_ref<T> &other )
const {
return this->_ref != other._ref; }
389 inline bool operator !=(
const T *pointer )
const {
return this->_ref != pointer; }
391 inline const T *operator ->()
const {
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 508 inline T *operator ->()
const {
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 )
570 #endif // DOXYGEN_HIDE_INTERNAL_CLASSES 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 );
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 )
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) ) {}
666 inline T *
get()
const {
return this->pointer(); }
667 inline bool operator <( const rc_ptr<T> &other )
const {
668 return this->pointer() < other.pointer();
671 #ifndef DOXYGEN_HIDE_INTERNAL_CLASSES 672 inline operator insipid*()
const 674 return reinterpret_cast< insipid*
>( this->pointer() );
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 &)
Constant Ref to an object of class T.
const_ref(const ref< T > &other)
const_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_...
ref(T *pObject, bool externalowner)
ref(std::auto_ptr< U > r)
Base class for reference counted objects (intrusive)
const_ref(const T *pObject)
ref(const ref< T > &other)
const T * pointer() const
bool operator==(const carto::block< T, N > &b1, const carto::block< T, N > &b2)
rc_ptr(std::auto_ptr< U > r)
VoxelRGB operator*(const VoxelRGB &aa, const uint8_t &bb)
Reference-counting pointer.
const_ref(const const_ref< R > &other)
rc_ptr_trick merely makes a public access to the reference counter inside a rc_ptr.
A ref is a const_ref which can reference non constant objects.
rc_ptr(T *p, bool externalowner)
ref(const ref< R > &other)
const_ref(const T *pObject, bool externalowner)
const_ref(std::auto_ptr< U > r)
const_ref(const ref< R > &o)
const_ref(const const_ref< T > &other)