/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. #include "llerror.h" // *TODO: consider eliminating this
  29. // Expands LLPointer to return a pointer to a special instance of class Type instead of NULL.
  30. // This is useful in instances where operations on NULL pointers are semantically safe and/or
  31. // when error checking occurs at a different granularity or in a different part of the code
  32. // than when referencing an object via a LLSafeHandle.
  33. template <class Type>
  34. class LLSafeHandle
  35. {
  36. public:
  37. LLSafeHandle() :
  38. mPointer(NULL)
  39. {
  40. }
  41. LLSafeHandle(Type* ptr) :
  42. mPointer(NULL)
  43. {
  44. assign(ptr);
  45. }
  46. LLSafeHandle(const LLSafeHandle<Type>& ptr) :
  47. mPointer(NULL)
  48. {
  49. assign(ptr.mPointer);
  50. }
  51. // support conversion up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
  52. template<typename Subclass>
  53. LLSafeHandle(const LLSafeHandle<Subclass>& ptr) :
  54. mPointer(NULL)
  55. {
  56. assign(ptr.get());
  57. }
  58. ~LLSafeHandle()
  59. {
  60. unref();
  61. }
  62. const Type* operator->() const { return nonNull(mPointer); }
  63. Type* operator->() { return nonNull(mPointer); }
  64. Type* get() const { return mPointer; }
  65. void clear() { assign(NULL); }
  66. // we disallow these operations as they expose our null objects to direct manipulation
  67. // and bypass the reference counting semantics
  68. //const Type& operator*() const { return *nonNull(mPointer); }
  69. //Type& operator*() { return *nonNull(mPointer); }
  70. operator BOOL() const { return mPointer != NULL; }
  71. operator bool() const { return mPointer != NULL; }
  72. bool operator!() const { return mPointer == NULL; }
  73. bool isNull() const { return mPointer == NULL; }
  74. bool notNull() const { return mPointer != NULL; }
  75. operator Type*() const { return mPointer; }
  76. operator const Type*() const { return mPointer; }
  77. bool operator !=(Type* ptr) const { return (mPointer != ptr); }
  78. bool operator ==(Type* ptr) const { return (mPointer == ptr); }
  79. bool operator ==(const LLSafeHandle<Type>& ptr) const { return (mPointer == ptr.mPointer); }
  80. bool operator < (const LLSafeHandle<Type>& ptr) const { return (mPointer < ptr.mPointer); }
  81. bool operator > (const LLSafeHandle<Type>& ptr) const { return (mPointer > ptr.mPointer); }
  82. LLSafeHandle<Type>& operator =(Type* ptr)
  83. {
  84. assign(ptr);
  85. return *this;
  86. }
  87. LLSafeHandle<Type>& operator =(const LLSafeHandle<Type>& ptr)
  88. {
  89. assign(ptr.mPointer);
  90. return *this;
  91. }
  92. // support assignment up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
  93. template<typename Subclass>
  94. LLSafeHandle<Type>& operator =(const LLSafeHandle<Subclass>& ptr)
  95. {
  96. assign(ptr.get());
  97. return *this;
  98. }
  99. public:
  100. typedef Type* (*NullFunc)();
  101. static const NullFunc sNullFunc;
  102. protected:
  103. void ref()
  104. {
  105. if (mPointer)
  106. {
  107. mPointer->ref();
  108. }
  109. }
  110. void unref()
  111. {
  112. if (mPointer)
  113. {
  114. Type *tempp = mPointer;
  115. mPointer = NULL;
  116. tempp->unref();
  117. if (mPointer != NULL)
  118. {
  119. llwarns << "Unreference did assignment to non-NULL because of destructor" << llendl;
  120. unref();
  121. }
  122. }
  123. }
  124. void assign(Type* ptr)
  125. {
  126. if( mPointer != ptr )
  127. {
  128. unref();
  129. mPointer = ptr;
  130. ref();
  131. }
  132. }
  133. static Type* nonNull(Type* ptr)
  134. {
  135. return ptr == NULL ? sNullFunc() : ptr;
  136. }
  137. protected:
  138. Type* mPointer;
  139. };
  140. #endif