HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UI_XPtr.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: UI_XPtr.h (UI Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __UI_XPTR_H_INCLUDED__
12 #define __UI_XPTR_H_INCLUDED__
13 
14 #include <UT/UT_Assert.h>
15 #include <SYS/SYS_Compiler.h>
16 #include <SYS/SYS_Deprecated.h>
17 #include <SYS/SYS_Inline.h>
18 
19 class UI_Look;
20 
21 /// Smart pointer class for holding UI_Look instances.
22 /// Similar to a UT_UniquePtr, it additionally tracks whether its pointer is an
23 /// owner or not.
24 template <typename T>
25 class UI_XPtr
26 {
27 public:
28  using PointerType = T*;
29  using ElementType = T;
31 
33  UI_XPtr() = default;
34 
35  /// Construct via raw pointer with ownership flag
37  UI_XPtr(T *ptr, bool owner);
38 
40  ~UI_XPtr();
41 
42  template <typename U>
44  UI_XPtr(UI_XPtr<U> &&other) noexcept;
45 
46  template <typename U>
48  UI_XPtr&
49  operator=(UI_XPtr<U> &&other) noexcept;
50 
51  UI_XPtr(const ThisType &other) = delete;
52  UI_XPtr& operator=(const ThisType &other) = delete;
53 
54  /// Explicit bool operator to avoid releasing the pointer with the cast
55  /// operator. To do this, we must have both const and non-const versions.
56  /// @{
58  explicit operator bool() const { return myPtr != nullptr; }
60  explicit operator bool() { return myPtr != nullptr; }
61  /// @}
62 
64  bool operator==(const ThisType &other) const
65  { return myPtr == other.myPtr; }
66 
68  bool operator!=(const ThisType &other) const
69  { return !(*this == other); }
70 
72  T &operator*() const { return *myPtr; }
73 
75  T *operator->() const { return myPtr; }
76 
78  T *get() const { return myPtr; }
79 
80  /// Release ownership and return current value
81  /// @note Unlike std::unique_ptr, release() does not reset myPtr
83  T *release() { myIsOwner = false; return myPtr; }
84 
85  /// Reset pointer to nullptr or to another raw pointer value
86  /// @{
88  void reset();
90  void reset(T *ptr, bool owner);
91  /// @}
92 
93  /// Return an unowned reference to the underlying pointer
95  ThisType ref() const
96  {
97  return ThisType(myPtr, false);
98  }
99 
100  /// Determine if this is an owning pointer
102  bool isOwner() const { return myIsOwner; }
103 
104  /// Swap with another instance
105  /// @{
107  void swap(ThisType &b) noexcept
108  {
109  UI_Look* ptr = myPtr;
110  myPtr = b.myPtr;
111  b.myPtr = ptr;
112 
113  bool owner = myIsOwner;
114  myIsOwner = b.myIsOwner;
115  b.myIsOwner = owner;
116  }
118  friend void swap(ThisType &a, ThisType &b) noexcept
119  {
120  a.swap(b);
121  }
122  /// @}
123 
124 private:
125  T *myPtr = nullptr;
126  bool myIsOwner = false;
127 };
128 
129 /// Convenience method to create an UI_LookXPtr compatible subclass instance
130 template <typename T, class... Args>
131 static inline UI_XPtr<T>
132 UImakeLook(Args&&... args)
133 {
134  return UI_XPtr<T>(new T(std::forward<Args>(args)...), true);
135 }
136 
137 /////////////////////////////////////////////////////////////////////////////
138 //
139 // Inline Implementations
140 //
141 
142 template <typename T>
144 UI_XPtr<T>::UI_XPtr(T *ptr, bool owner)
145  : myPtr(ptr)
146  , myIsOwner(owner)
147 {
148  // There should never be an owning ptr for a static look
149  UT_ASSERT(!(owner && ptr->isStatic()));
150 }
151 
152 template <typename T>
155 {
156  if (myIsOwner)
157  delete myPtr;
158 }
159 
160 template <typename T>
161 template <typename U>
164 {
165  // Steal ownership but do not reset 'other'
166  myIsOwner = other.isOwner();
167  myPtr = other.release();
168 }
169 
170 template <typename T>
171 template <typename U>
173 UI_XPtr<T>&
175 {
176  // If 'other' has the same underlying raw pointer as myPtr, we do NOT want
177  // to free prematurely if we had ownership. This is bug in the calling
178  // code. The exception we make here is if both are also non-owners because
179  // then we're likely just assigning shared looks.
180  //
181  // If myIsOwner is true and other.isOwner() false, then this case will
182  // cause us to lose ownership. In this bad situation, we will leak.
183  // Since we don't know if the caller has given ownership to someone else,
184  // we leak instead of potentially crashing with a double free.
185  UT_ASSERT((!myIsOwner && !other.isOwner()) || myPtr != other.get());
186 
187  // Delete old pointer, ensuring that we do not delete ourselves
188  if (myIsOwner && myPtr != other.get())
189  delete myPtr;
190 
191  // Steal ownership but do not reset 'other'
192  myIsOwner = other.isOwner();
193  myPtr = other.release();
194 
195  return *this;
196 }
197 
198 template <typename T>
200 void
202 {
203  if (myIsOwner)
204  delete myPtr;
205  myPtr = nullptr;
206  myIsOwner = false;
207 }
208 
209 template <typename T>
211 void
212 UI_XPtr<T>::reset(T *ptr, bool owner)
213 {
214  if (myIsOwner)
215  delete myPtr;
216  myPtr = ptr;
217  myIsOwner = owner;
218 }
219 
220 #endif // __UI_XPTR_H_INCLUDED__
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1221
SYS_FORCE_INLINE UI_XPtr & operator=(UI_XPtr< U > &&other) noexcept
SYS_FORCE_INLINE T * release()
Definition: UI_XPtr.h:83
SYS_FORCE_INLINE UI_XPtr()=default
SYS_FORCE_INLINE void swap(ThisType &b) noexcept
Definition: UI_XPtr.h:107
GUI_SceneLook ElementType
Definition: UI_XPtr.h:29
GUI_SceneLook * PointerType
Definition: UI_XPtr.h:28
SYS_FORCE_INLINE friend void swap(ThisType &a, ThisType &b) noexcept
Definition: UI_XPtr.h:118
SYS_FORCE_INLINE bool operator!=(const ThisType &other) const
Definition: UI_XPtr.h:68
SYS_NO_DISCARD_RESULT ThisType ref() const
Return an unowned reference to the underlying pointer.
Definition: UI_XPtr.h:95
SYS_FORCE_INLINE T * operator->() const
Definition: UI_XPtr.h:75
SYS_FORCE_INLINE T & operator*() const
Definition: UI_XPtr.h:72
SYS_FORCE_INLINE void reset()
Definition: UI_XPtr.h:201
UI_XPtr< T > ThisType
Definition: UI_XPtr.h:30
SYS_FORCE_INLINE bool operator==(const ThisType &other) const
Definition: UI_XPtr.h:64
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1221
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
#define SYS_NO_DISCARD_RESULT
Definition: SYS_Compiler.h:93
SYS_FORCE_INLINE ~UI_XPtr()
Definition: UI_XPtr.h:154
const void * ptr(const T *p)
Definition: format.h:3603
**If you just want to fire and args
Definition: thread.h:615
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:171
#define const
Definition: zconf.h:214
SYS_FORCE_INLINE bool isOwner() const
Determine if this is an owning pointer.
Definition: UI_XPtr.h:102