summaryrefslogtreecommitdiff
path: root/indra/llcommon/llmemory.h
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon/llmemory.h')
-rw-r--r--indra/llcommon/llmemory.h149
1 files changed, 149 insertions, 0 deletions
diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h
index 905d05254a..962a4aa5d5 100644
--- a/indra/llcommon/llmemory.h
+++ b/indra/llcommon/llmemory.h
@@ -120,6 +120,7 @@ public:
}
return mRef;
}
+
S32 getNumRefs() const
{
return mRef;
@@ -249,6 +250,154 @@ protected:
Type* mPointer;
};
+//template <class Type>
+//class LLPointerTraits
+//{
+// static Type* null();
+//};
+//
+// Expands LLPointer to return a pointer to a special instance of class Type instead of NULL.
+// This is useful in instances where operations on NULL pointers are semantically safe and/or
+// when error checking occurs at a different granularity or in a different part of the code
+// than when referencing an object via a LLHandle.
+//
+
+template <class Type>
+class LLHandle
+{
+public:
+ LLHandle() :
+ mPointer(sNullFunc())
+ {
+ ref();
+ }
+
+ LLHandle(Type* ptr) :
+ mPointer(nonNull(ptr))
+ {
+ ref();
+ }
+
+ LLHandle(const LLHandle<Type>& ptr) :
+ mPointer(ptr.mPointer)
+ {
+ ref();
+ }
+
+ // support conversion up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
+ template<typename Subclass>
+ LLHandle(const LLPointer<Subclass>& ptr) :
+ mPointer(ptr.get())
+ {
+ ref();
+ }
+
+ ~LLHandle()
+ {
+ unref();
+ }
+
+ Type* get() const { return mPointer; }
+ const Type* operator->() const { return mPointer; }
+ Type* operator->() { return mPointer; }
+ const Type& operator*() const { return *mPointer; }
+ Type& operator*() { return *mPointer; }
+
+ operator BOOL() const { return (mPointer != sNullFunc()); }
+ operator bool() const { return (mPointer != sNullFunc()); }
+ bool operator!() const { return (mPointer == sNullFunc()); }
+ bool isNull() const { return (mPointer == sNullFunc()); }
+ bool notNull() const { return (mPointer != sNullFunc()); }
+
+
+ operator Type*() const { return mPointer; }
+ operator const Type*() const { return mPointer; }
+ bool operator !=(Type* ptr) const { return (mPointer != nonNull(ptr)); }
+ bool operator ==(Type* ptr) const { return (mPointer == nonNull(ptr)); }
+ bool operator ==(const LLHandle<Type>& ptr) const { return (mPointer == ptr.mPointer); }
+ bool operator < (const LLHandle<Type>& ptr) const { return (mPointer < ptr.mPointer); }
+ bool operator > (const LLHandle<Type>& ptr) const { return (mPointer > ptr.mPointer); }
+
+ LLHandle<Type>& operator =(Type* ptr)
+ {
+ if( mPointer != ptr )
+ {
+ unref();
+ mPointer = nonNull(ptr);
+ ref();
+ }
+
+ return *this;
+ }
+
+ LLHandle<Type>& operator =(const LLHandle<Type>& ptr)
+ {
+ if( mPointer != ptr.mPointer )
+ {
+ unref();
+ mPointer = ptr.mPointer;
+ ref();
+ }
+ return *this;
+ }
+
+ // support assignment up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
+ template<typename Subclass>
+ LLHandle<Type>& operator =(const LLHandle<Subclass>& ptr)
+ {
+ if( mPointer != ptr.get() )
+ {
+ unref();
+ mPointer = ptr.get();
+ ref();
+ }
+ return *this;
+ }
+
+public:
+ typedef Type* (*NullFunc)();
+ static const NullFunc sNullFunc;
+
+protected:
+ void ref()
+ {
+ if (mPointer)
+ {
+ mPointer->ref();
+ }
+ }
+
+ void unref()
+ {
+ if (mPointer)
+ {
+ Type *tempp = mPointer;
+ mPointer = sNullFunc();
+ tempp->unref();
+ if (mPointer != sNullFunc())
+ {
+ llwarns << "Unreference did assignment to non-NULL because of destructor" << llendl;
+ unref();
+ }
+ }
+ }
+
+ static Type* nonNull(Type* ptr)
+ {
+ return ptr == NULL ? sNullFunc() : ptr;
+ }
+
+ static Type* defaultNullFunc()
+ {
+ llerrs << "No null value provided for LLHandle" << llendl;
+ return NULL;
+ }
+
+protected:
+
+ Type* mPointer;
+};
+
// LLInitializedPointer is just a pointer with a default constructor that initializes it to NULL
// NOT a smart pointer like LLPointer<>
// Useful for example in std::map<int,LLInitializedPointer<LLFoo> >