HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_IntrusivePtr.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: UT_IntrusivePtr.h (UT Library, C++)
7  *
8  * COMMENTS: A wrapper around hboost::intrusive_ptr.
9  *
10  */
11 
12 #ifndef __UT_INTRUSIVEPTR_H_INCLUDED__
13 #define __UT_INTRUSIVEPTR_H_INCLUDED__
14 
15 #include <SYS/SYS_AtomicInt.h>
16 #include <SYS/SYS_Inline.h>
17 #include <SYS/SYS_Types.h>
18 #include <memory> // For std::default_delete
19 #include <hboost/intrusive_ptr.hpp>
20 
21 /// @brief Wrapper around hboost::intrusive_ptr
22 ///
23 /// An intrusive pointer assumes that the referenced object implements
24 /// reference counting on itself. The reference counting is implemented using
25 /// the methods @c intrusive_ptr_add_ref() and @c intrusive_ptr_release().
26 ///
27 /// For simple usages, simply derive from UT_IntrusiveRefCounter.
28 ///
29 /// Here's a roll your own example: @code
30 /// class Foo {
31 /// public:
32 /// Foo() : myCount(0) {}
33 /// ~Foo() {}
34 /// void incref()
35 /// {
36 /// myCount.add(1);
37 /// }
38 /// void decref()
39 /// {
40 /// if (myCount.add(-1) == 0)
41 /// delete this;
42 /// }
43 /// SYS_AtomicInt32 myCount;
44 /// };
45 /// static inline void intrusive_ptr_add_ref(Foo *o) { o->incref(); }
46 /// static inline void intrusive_ptr_release(Foo *o) { o->decref(); }
47 ///
48 /// typedef UT_IntrusivePtr<Foo> FooHandle;
49 /// @endcode
50 /// @see UT_SharedPtr
51 template<class T>
52 class UT_IntrusivePtr : public hboost::intrusive_ptr<T>
53 {
54 public:
57  : hboost::intrusive_ptr<T>(nullptr, true) {}
58 
59  // NOTE: This should really be explicit, but there are so many
60  // places currently implicitly casting to UT_IntrusivePtr that
61  // it could take quite a while to fix.
63  /*explicit*/ UT_IntrusivePtr(T *p)
64  : hboost::intrusive_ptr<T>(p, true) {}
65 
67  UT_IntrusivePtr(T *p, bool add_ref)
68  : hboost::intrusive_ptr<T>(p, add_ref) {}
69 
72  : hboost::intrusive_ptr<T>(p) {}
73 
74  template <typename Y>
77  : hboost::intrusive_ptr<T>(p) {}
78 
81  : hboost::intrusive_ptr<T>(std::move(p)) {}
82 
85  {
86  hboost::intrusive_ptr<T>::operator=(that);
87  return *this;
88  }
89 
90  template <typename Y>
93  {
94  hboost::intrusive_ptr<T>::operator=(that);
95  return *this;
96  }
97 
100  {
101  hboost::intrusive_ptr<T>::operator=(std::move(that));
102  return *this;
103  }
104 };
105 
106 /// Thread-safe policy for UT_IntrusiveRefCounter
108 {
110 
112  static uint32 load(const type& counter) { return counter.relaxedLoad();}
114  static void increment(type& counter) { (void) counter.add(1); }
116  static uint32 decrement(type& counter) { return counter.add(-1); }
117 };
118 
119 /// NOT Thread-safe policy for UT_IntrusiveRefCounter
121 {
122  typedef uint32 type;
123 
125  static uint32 load(const type& counter) { return counter; }
127  static void increment(type& counter) { ++counter; }
129  static uint32 decrement(type& counter) { return (--counter); }
130 };
131 
132 // Forward declarations for friends.
133 template <
134  typename DerivedT,
135  typename Deleter = std::default_delete<DerivedT>,
136  typename CounterPolicyT = UT_IntrusiveThreadSafeCounterPolicy
137 >
139 
140 template <typename DerivedT, typename Deleter, typename CounterPolicyT>
143 
144 template <typename DerivedT, typename Deleter, typename CounterPolicyT>
147 
148 /// @brief A reference counter base class for use with UT_IntrusivePtr
149 ///
150 /// This base class can be used with user-defined classes to add support for
151 /// @c UT_IntrusivePtr. The class contains a reference counter defined by the
152 /// @c CounterPolicyT. Upon releasing the last @c UT_IntrusivePtr referencing
153 /// the object derived from the @c UT_IntrusiveRefCounter class, operator
154 /// @c delete is automatically called on the pointer to the object.
155 ///
156 /// The other template parameter, @c DerivedT, is the user's class that
157 /// derives from @c UT_IntrusiveRefCounter.
158 ///
159 /// Example: @code
160 /// class MyClass : public UT_IntrusiveRefCounter<MyClass>
161 /// { ... };
162 /// typedef UT_IntrusivePtr<MyClass> MyClassPtr;
163 /// @endcode
164 template <
165  typename DerivedT,
166  typename Deleter,
167  typename CounterPolicyT
168 >
170 {
171 public:
172  /// Default constructor: Sets counter to 0.
175  : myRefCount(0)
176  {
177  }
178  /// Copy constructor: Sets counter to 0.
181  : myRefCount(0)
182  {
183  }
184  /// Assignment operator: Does not modify counter.
186  {
187  return *this;
188  }
189  /// Return current counter
192  {
193  return CounterPolicyT::load(myRefCount);
194  }
195 
196 protected:
197  /// Destructor: Only derived classes can destruct this.
200  {
201  }
202 
203 private:
204  mutable typename CounterPolicyT::type myRefCount;
205 
206  friend void intrusive_ptr_add_ref<DerivedT,Deleter,CounterPolicyT>(
208  friend void intrusive_ptr_release<DerivedT,Deleter,CounterPolicyT>(
210 };
211 
212 template <typename DerivedT, typename Deleter, typename CounterPolicyT>
213 SYS_FORCE_INLINE void
216 {
217  CounterPolicyT::increment(p->myRefCount);
218 }
219 template <typename DerivedT, typename Deleter, typename CounterPolicyT>
220 SYS_FORCE_INLINE void
222 {
223  if (CounterPolicyT::decrement(p->myRefCount) == 0)
224  {
225  Deleter d;
226  d(SYSconst_cast(static_cast<const DerivedT *>(p)));
227  }
228 }
229 
230 // For UT::ArraySet.
231 namespace UT
232 {
233 template <typename T>
234 struct DefaultClearer;
235 
236 template <typename T>
238 {
239  static void clear(UT_IntrusivePtr<T> &v)
240  { v = UT_IntrusivePtr<T>(); }
241  static bool isClear(const UT_IntrusivePtr<T> &v)
242  { return v.get() == nullptr; }
244  { new ((void *)p) UT_IntrusivePtr<T>(nullptr); }
245  static const bool clearNeedsDestruction = false;
246 };
247 } // namespace UT
248 
249 #endif // __UT_INTRUSIVEPTR_H_INCLUDED__
SYS_FORCE_INLINE UT_IntrusivePtr(T *p, bool add_ref)
SYS_FORCE_INLINE uint32 use_count() const
Return current counter.
const GLdouble * v
Definition: glcorearb.h:836
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
SYS_FORCE_INLINE UT_IntrusivePtr(T *p)
static SYS_FORCE_INLINE uint32 decrement(type &counter)
SYS_FORCE_INLINE T * SYSconst_cast(const T *foo)
Definition: SYS_Types.h:127
SYS_FORCE_INLINE UT_IntrusivePtr(const UT_IntrusivePtr< Y > &p)
A reference counter base class for use with UT_IntrusivePtr.
UT_IntrusiveRefCounter & operator=(const UT_IntrusiveRefCounter &)
Assignment operator: Does not modify counter.
NOT Thread-safe policy for UT_IntrusiveRefCounter.
static bool isClear(const UT_IntrusivePtr< T > &v)
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
SYS_FORCE_INLINE UT_IntrusivePtr< T > & operator=(UT_IntrusivePtr< T > &&that)
static SYS_FORCE_INLINE uint32 load(const type &counter)
SYS_FORCE_INLINE UT_IntrusivePtr< T > & operator=(const UT_IntrusivePtr< T > &that)
Wrapper around hboost::intrusive_ptr.
SYS_FORCE_INLINE UT_IntrusivePtr(const UT_IntrusivePtr< T > &p)
static void clearConstruct(UT_IntrusivePtr< T > *p)
void intrusive_ptr_add_ref(const UT_IntrusiveRefCounter< DerivedT, Deleter, CounterPolicyT > *p)
SYS_FORCE_INLINE UT_IntrusiveRefCounter(const UT_IntrusiveRefCounter &)
Copy constructor: Sets counter to 0.
static void clear(UT_IntrusivePtr< T > &v)
SYS_FORCE_INLINE UT_IntrusivePtr(UT_IntrusivePtr< T > &&p)
SYS_FORCE_INLINE UT_IntrusivePtr()
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:107
T add(T val)
Atomically adds val to myValue, returning the new value of myValue.
static SYS_FORCE_INLINE void increment(type &counter)
SYS_FORCE_INLINE ~UT_IntrusiveRefCounter()
Destructor: Only derived classes can destruct this.
SYS_FORCE_INLINE UT_IntrusivePtr< T > & operator=(const UT_IntrusivePtr< Y > &that)
static SYS_FORCE_INLINE uint32 decrement(type &counter)
void intrusive_ptr_release(const UT_IntrusiveRefCounter< DerivedT, Deleter, CounterPolicyT > *p)
SYS_FORCE_INLINE T relaxedLoad() const
Definition: SYS_AtomicInt.h:60
Thread-safe policy for UT_IntrusiveRefCounter.
static SYS_FORCE_INLINE void increment(type &counter)
static SYS_FORCE_INLINE uint32 load(const type &counter)
unsigned int uint32
Definition: SYS_Types.h:36
SYS_FORCE_INLINE UT_IntrusiveRefCounter()
Default constructor: Sets counter to 0.