PageRenderTime 25ms CodeModel.GetById 12ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llcommon/llsafehandle.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 162 lines | 105 code | 22 blank | 35 comment | 15 complexity | e6764e641a721797257134582db6a696 MD5 | raw file
  1/** 
  2 * @file llsafehandle.h
  3 * @brief Reference-counted object where Object() is valid, not NULL.
  4 *
  5 * $LicenseInfo:firstyear=2002&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26#ifndef LLSAFEHANDLE_H
 27#define LLSAFEHANDLE_H
 28
 29#include "llerror.h"	// *TODO: consider eliminating this
 30
 31// Expands LLPointer to return a pointer to a special instance of class Type instead of NULL.
 32// This is useful in instances where operations on NULL pointers are semantically safe and/or
 33// when error checking occurs at a different granularity or in a different part of the code
 34// than when referencing an object via a LLSafeHandle.
 35
 36template <class Type> 
 37class LLSafeHandle
 38{
 39public:
 40	LLSafeHandle() :
 41		mPointer(NULL)
 42	{
 43	}
 44
 45	LLSafeHandle(Type* ptr) : 
 46		mPointer(NULL)
 47	{
 48		assign(ptr);
 49	}
 50
 51	LLSafeHandle(const LLSafeHandle<Type>& ptr) : 
 52		mPointer(NULL)
 53	{
 54		assign(ptr.mPointer);
 55	}
 56
 57	// support conversion up the type hierarchy.  See Item 45 in Effective C++, 3rd Ed.
 58	template<typename Subclass>
 59	LLSafeHandle(const LLSafeHandle<Subclass>& ptr) : 
 60		mPointer(NULL)
 61	{
 62		assign(ptr.get());
 63	}
 64
 65	~LLSafeHandle()								
 66	{
 67		unref();
 68	}
 69
 70	const Type*	operator->() const				{ return nonNull(mPointer); }
 71	Type*	operator->()						{ return nonNull(mPointer); }
 72
 73	Type*	get() const							{ return mPointer; }
 74	void	clear()								{ assign(NULL); }
 75	// we disallow these operations as they expose our null objects to direct manipulation
 76	// and bypass the reference counting semantics
 77	//const Type&	operator*() const			{ return *nonNull(mPointer); }
 78	//Type&	operator*()							{ return *nonNull(mPointer); }
 79
 80	operator BOOL()  const						{ return mPointer != NULL; }
 81	operator bool()  const						{ return mPointer != NULL; }
 82	bool operator!() const						{ return mPointer == NULL; }
 83	bool isNull() const							{ return mPointer == NULL; }
 84	bool notNull() const						{ return mPointer != NULL; }
 85
 86
 87	operator Type*()       const				{ return mPointer; }
 88	operator const Type*() const				{ return mPointer; }
 89	bool operator !=(Type* ptr) const           { return (mPointer != ptr); 	}
 90	bool operator ==(Type* ptr) const           { return (mPointer == ptr); 	}
 91	bool operator ==(const LLSafeHandle<Type>& ptr) const           { return (mPointer == ptr.mPointer); 	}
 92	bool operator < (const LLSafeHandle<Type>& ptr) const           { return (mPointer < ptr.mPointer); 	}
 93	bool operator > (const LLSafeHandle<Type>& ptr) const           { return (mPointer > ptr.mPointer); 	}
 94
 95	LLSafeHandle<Type>& operator =(Type* ptr)                   
 96	{ 
 97		assign(ptr);
 98		return *this; 
 99	}
100
101	LLSafeHandle<Type>& operator =(const LLSafeHandle<Type>& ptr)  
102	{ 
103		assign(ptr.mPointer);
104		return *this; 
105	}
106
107	// support assignment up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
108	template<typename Subclass>
109	LLSafeHandle<Type>& operator =(const LLSafeHandle<Subclass>& ptr)  
110	{ 
111		assign(ptr.get());
112		return *this; 
113	}
114
115public:
116	typedef Type* (*NullFunc)();
117	static const NullFunc sNullFunc;
118
119protected:
120	void ref()                             
121	{ 
122		if (mPointer)
123		{
124			mPointer->ref();
125		}
126	}
127
128	void unref()
129	{
130		if (mPointer)
131		{
132			Type *tempp = mPointer;
133			mPointer = NULL;
134			tempp->unref();
135			if (mPointer != NULL)
136			{
137				llwarns << "Unreference did assignment to non-NULL because of destructor" << llendl;
138				unref();
139			}
140		}
141	}
142
143	void assign(Type* ptr)
144	{
145		if( mPointer != ptr )
146		{
147			unref(); 
148			mPointer = ptr; 
149			ref();
150		}
151	}
152
153	static Type* nonNull(Type* ptr)
154	{
155		return ptr == NULL ? sNullFunc() : ptr;
156	}
157
158protected:
159	Type*	mPointer;
160};
161
162#endif