19 template <
class T>
class WeakPtr;
20 template <
class T>
class RefMan;
24 #define mInvalidRefCount (-1)
130 void unRefDontInvalidate();
133 od_int32 count()
const {
return count_.load(); }
137 void clearAllObservers();
138 void addObserver(WeakPtrBase* obj);
139 void removeObserver(WeakPtrBase* obj);
142 Counter(
const Counter& a);
165 void unRefNoDelete()
const;
170 Referenced(
const Referenced&);
171 Referenced& operator =(
const Referenced&);
172 virtual ~Referenced();
176 friend class WeakPtrBase;
177 virtual void refNotify()
const {}
178 virtual void unRefNotify()
const {}
179 virtual void unRefNoDeleteNotify()
const {}
180 virtual void prepareForDelete() {}
182 mutable Counter refcount_;
188 bool refIfReffed()
const;
193 void addObserver(WeakPtrBase* obs);
195 void removeObserver(WeakPtrBase* obs);
197 static bool isSane(
const Referenced*);
203 const od_uint64 magicnumber_ = 0x123456789abcdef;
209 inline void refIfObjIsReffed(
const T* obj )
220 inline void unRefIfObjIsReffed(
const T* obj )
230 template <
class T>
inline void refIfObjIsReffed(
const T& obj )
231 { refIfObjIsReffed( &obj ); }
232 template <
class T>
inline void unRefIfObjIsReffed(
const T& obj )
233 { unRefIfObjIsReffed( &obj ); }
243 operator bool()
const;
244 bool operator!()
const;
246 {
return ptr_==r.ptr_; }
251 void set(Referenced*);
253 friend class Counter;
256 mutable LockType lock_;
269 CleanupBlocker( WeakPtrSetBase& base )
270 : base_( base ) { base_.blockCleanup(); }
272 ~CleanupBlocker() { base_.unblockCleanup(); }
275 WeakPtrSetBase& base_;
285 friend class CleanupBlocker;
287 void unblockCleanup();
303 WeakPtr(RefCount::Referenced* p = 0) {
set(p); }
310 {
set(p.
ptr());
return p; }
312 {
set(p);
return p; }
322 mClass(Basic) WeakPtrSet :
public RefCount::WeakPtrSetBase
328 typedef int idx_type;
329 typedef int size_type;
335 size_type size()
const;
344 mutable LockType lock_;
351 #define mRefCountImplWithDestructor(ClassName, DestructorImpl, delfunc ) \
358 bool refIfReffed() const \
360 if ( !refcount_.refIfReffed() ) \
369 if ( refcount_.unRef() ) \
374 void unRefNoDelete() const \
376 unRefNoDeleteNotify(); \
377 refcount_.unRefDontInvalidate(); \
379 int nrRefs() const { return refcount_.count(); } \
381 virtual void refNotify() const {} \
382 virtual void unRefNotify() const {} \
383 virtual void unRefNoDeleteNotify() const {} \
384 mutable ReferenceCounter refcount_; \
391 #define mRefCountImpl(ClassName) \
392 mRefCountImplWithDestructor(ClassName, virtual ~ClassName(), delete this; )
395 #define mRefCountImplNoDestructor(ClassName) \
396 mRefCountImplWithDestructor(ClassName, virtual ~ClassName() {}, delete this; )
400 inline void refPtr(
const RefCount::Referenced* ptr )
407 inline void unRefPtr(
const RefCount::Referenced* ptr )
414 inline void unRefNoDeletePtr(
const RefCount::Referenced* ptr )
417 ptr->unRefNoDelete();
421 template <
class T>
inline
422 void unRefAndZeroPtr( T*& ptr )
434 template <
class T>
inline
435 void unRefAndZeroPtr(
const T*& ptr )
449 template <
class T>
inline
450 void unRefPtr(
const T* ptr )
458 template <
class T>
inline
459 void unRefNoDeletePtr(
const T* ptr )
462 ptr->unRefNoDelete();
467 template <
class T>
inline
468 void refPtr(
const T* ptr )
483 mClass(Basic) ReferenceCounter
491 inline void unRefDontInvalidate();
494 od_int32 count()
const {
return count_.load(); }
495 inline bool refIfReffed();
505 # define mDeclareCounters od_int32 oldcount = count_.load(), newcount = 0
507 # define mDeclareCounters od_int32 oldcount = count_.load(), newcount;
510 inline void ReferenceCounter::ref()
528 newcount = oldcount+1;
531 }
while ( !count_.setIfValueIs( oldcount, newcount, &oldcount ) );
535 inline bool ReferenceCounter::unRef()
551 else if ( oldcount==1 )
554 newcount = oldcount-1;
556 }
while ( !count_.setIfValueIs(oldcount,newcount, &oldcount ) );
562 inline bool ReferenceCounter::refIfReffed()
577 else if ( !oldcount )
580 newcount = oldcount+1;
582 }
while ( !count_.setIfValueIs( oldcount, newcount, &oldcount ) );
588 inline void ReferenceCounter::unRefDontInvalidate()
605 newcount = oldcount-1;
607 }
while ( !count_.setIfValueIs( oldcount, newcount, &oldcount ) );
610 #undef mDeclareCounters
629 if ( ptr_ && ptr_->tryRef() )
642 template <
class T>
inline
643 bool WeakPtrSet<T>::operator+=(
RefMan<T>& toadd )
645 T* ptr = toadd.
ptr();
646 return WeakPtrSet<T>::operator+=(
WeakPtr<T>(ptr) );
649 template <
class T>
inline
650 bool WeakPtrSet<T>::operator+=(
const WeakPtr<T>& toadd )
654 const bool docleanup = blockcleanup_.setIfValueIs( 0, -1,
nullptr );
655 for (
int idx=ptrs_.size()-1; idx>=0; idx-- )
657 if ( docleanup && !ptrs_[idx] )
658 { ptrs_.removeSingle( idx );
continue; }
660 if ( ptrs_[idx]==toadd )
679 template <
class T>
inline
680 int WeakPtrSet<T>::size()
const
683 const int res = ptrs_.size();
689 template <
class T>
inline
690 RefMan<T> WeakPtrSet<T>::operator[](
int idx )
700 template <
class T>
inline