diff options
Diffstat (limited to 'indra/llcommon/llpointer.h')
-rw-r--r-- | indra/llcommon/llpointer.h | 85 |
1 files changed, 64 insertions, 21 deletions
diff --git a/indra/llcommon/llpointer.h b/indra/llcommon/llpointer.h index 88c09c8dca..6a3bbeb768 100644 --- a/indra/llcommon/llpointer.h +++ b/indra/llcommon/llpointer.h @@ -97,24 +97,13 @@ public: LLPointer<Type>& operator =(Type* ptr) { - if( mPointer != ptr ) - { - unref(); - mPointer = ptr; - ref(); - } - + assign(ptr); return *this; } LLPointer<Type>& operator =(const LLPointer<Type>& ptr) { - if( mPointer != ptr.mPointer ) - { - unref(); - mPointer = ptr.mPointer; - ref(); - } + assign(ptr); return *this; } @@ -122,12 +111,7 @@ public: template<typename Subclass> LLPointer<Type>& operator =(const LLPointer<Subclass>& ptr) { - if( mPointer != ptr.get() ) - { - unref(); - mPointer = ptr.get(); - ref(); - } + assign(ptr.get()); return *this; } @@ -144,6 +128,16 @@ protected: void ref(); void unref(); #else + + void assign(const LLPointer<Type>& ptr) + { + if( mPointer != ptr.mPointer ) + { + unref(); + mPointer = ptr.mPointer; + ref(); + } + } void ref() { if (mPointer) @@ -156,9 +150,9 @@ protected: { if (mPointer) { - Type *tempp = mPointer; + Type *temp = mPointer; mPointer = NULL; - tempp->unref(); + temp->unref(); if (mPointer != NULL) { llwarns << "Unreference did assignment to non-NULL because of destructor" << llendl; @@ -171,4 +165,53 @@ protected: Type* mPointer; }; +template<typename Type> +class LLCopyOnWritePointer : public LLPointer<Type> +{ +public: + typedef LLPointer<Type> ref_pointer_t; + typedef LLCopyOnWritePointer<Type> self_t; + + LLCopyOnWritePointer() + { + } + + LLCopyOnWritePointer(Type* ptr) + : LLPointer(ptr) + { + } + + Type* write() + { + makeUnique(); + return mPointer; + } + + void makeUnique() + { + if (mPointer && mPointer->getNumRefs() > 1) + { + ref_pointer_t::assign(new Type(*mPointer)); + } + } + + using ref_pointer_t::operator BOOL; + using ref_pointer_t::operator bool; + using ref_pointer_t::operator!; + + using ref_pointer_t::operator !=; + using ref_pointer_t::operator ==; + using LLPointer<Type>::operator =; + + using LLPointer<Type>::operator <; + using LLPointer<Type>::operator >; + + + operator Type*() { return mPointer; } + operator const Type*() const { return mPointer; } + Type* operator->() { return mPointer; } + const Type* operator->() const { return mPointer; } + +}; + #endif |