PageRenderTime 40ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llcommon/llpointer.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 170 lines | 109 code | 22 blank | 39 comment | 18 complexity | 05aa359c8eb237bb0aa0f2cecd897fcb MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llpointer.h
  3. * @brief A reference-counted pointer for objects derived from LLRefCount
  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 LLPOINTER_H
  27. #define LLPOINTER_H
  28. #include "llerror.h" // *TODO: consider eliminating this
  29. //----------------------------------------------------------------------------
  30. // RefCount objects should generally only be accessed by way of LLPointer<>'s
  31. // NOTE: LLPointer<LLFoo> x = new LLFoo(); MAY NOT BE THREAD SAFE
  32. // if LLFoo::LLFoo() does anything like put itself in an update queue.
  33. // The queue may get accessed before it gets assigned to x.
  34. // The correct implementation is:
  35. // LLPointer<LLFoo> x = new LLFoo; // constructor does not do anything interesting
  36. // x->instantiate(); // does stuff like place x into an update queue
  37. // see llthread.h for LLThreadSafeRefCount
  38. //----------------------------------------------------------------------------
  39. // Note: relies on Type having ref() and unref() methods
  40. template <class Type> class LLPointer
  41. {
  42. public:
  43. LLPointer() :
  44. mPointer(NULL)
  45. {
  46. }
  47. LLPointer(Type* ptr) :
  48. mPointer(ptr)
  49. {
  50. ref();
  51. }
  52. LLPointer(const LLPointer<Type>& ptr) :
  53. mPointer(ptr.mPointer)
  54. {
  55. ref();
  56. }
  57. // support conversion up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
  58. template<typename Subclass>
  59. LLPointer(const LLPointer<Subclass>& ptr) :
  60. mPointer(ptr.get())
  61. {
  62. ref();
  63. }
  64. ~LLPointer()
  65. {
  66. unref();
  67. }
  68. Type* get() const { return mPointer; }
  69. const Type* operator->() const { return mPointer; }
  70. Type* operator->() { return mPointer; }
  71. const Type& operator*() const { return *mPointer; }
  72. Type& operator*() { return *mPointer; }
  73. operator BOOL() const { return (mPointer != NULL); }
  74. operator bool() const { return (mPointer != NULL); }
  75. bool operator!() const { return (mPointer == NULL); }
  76. bool isNull() const { return (mPointer == NULL); }
  77. bool notNull() const { return (mPointer != NULL); }
  78. operator Type*() const { return mPointer; }
  79. bool operator !=(Type* ptr) const { return (mPointer != ptr); }
  80. bool operator ==(Type* ptr) const { return (mPointer == ptr); }
  81. bool operator ==(const LLPointer<Type>& ptr) const { return (mPointer == ptr.mPointer); }
  82. bool operator < (const LLPointer<Type>& ptr) const { return (mPointer < ptr.mPointer); }
  83. bool operator > (const LLPointer<Type>& ptr) const { return (mPointer > ptr.mPointer); }
  84. LLPointer<Type>& operator =(Type* ptr)
  85. {
  86. if( mPointer != ptr )
  87. {
  88. unref();
  89. mPointer = ptr;
  90. ref();
  91. }
  92. return *this;
  93. }
  94. LLPointer<Type>& operator =(const LLPointer<Type>& ptr)
  95. {
  96. if( mPointer != ptr.mPointer )
  97. {
  98. unref();
  99. mPointer = ptr.mPointer;
  100. ref();
  101. }
  102. return *this;
  103. }
  104. // support assignment up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
  105. template<typename Subclass>
  106. LLPointer<Type>& operator =(const LLPointer<Subclass>& ptr)
  107. {
  108. if( mPointer != ptr.get() )
  109. {
  110. unref();
  111. mPointer = ptr.get();
  112. ref();
  113. }
  114. return *this;
  115. }
  116. // Just exchange the pointers, which will not change the reference counts.
  117. static void swap(LLPointer<Type>& a, LLPointer<Type>& b)
  118. {
  119. Type* temp = a.mPointer;
  120. a.mPointer = b.mPointer;
  121. b.mPointer = temp;
  122. }
  123. protected:
  124. void ref()
  125. {
  126. if (mPointer)
  127. {
  128. mPointer->ref();
  129. }
  130. }
  131. void unref()
  132. {
  133. if (mPointer)
  134. {
  135. Type *tempp = mPointer;
  136. mPointer = NULL;
  137. tempp->unref();
  138. if (mPointer != NULL)
  139. {
  140. llwarns << "Unreference did assignment to non-NULL because of destructor" << llendl;
  141. unref();
  142. }
  143. }
  144. }
  145. protected:
  146. Type* mPointer;
  147. };
  148. #endif