HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
refPtr.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef PXR_BASE_TF_REF_PTR_H
25 #define PXR_BASE_TF_REF_PTR_H
26 
27 /// \file tf/refPtr.h
28 /// \ingroup group_tf_Memory
29 /// Reference counting.
30 ///
31 /// \anchor refPtr_QuickStart
32 /// <B> Quick Start </B>
33 ///
34 /// Here is how to make a class \c Bunny usable through \c TfRefPtr.
35 ///
36 /// \code
37 /// #include "pxr/base/tf/refPtr.h"
38 /// typedef TfRefPtr<Bunny> BunnyRefPtr;
39 ///
40 /// class Bunny : public TfRefBase {
41 /// public:
42 /// static BunnyRefPtr New() {
43 /// // warning: return new Bunny directly will leak memory!
44 /// return TfCreateRefPtr(new Bunny);
45 /// }
46 /// static BunnyRefPtr New(bool isRabid) {
47 /// return TfCreateRefPtr(new Bunny(isRabid));
48 /// }
49 ///
50 /// ~Bunny();
51 ///
52 /// bool IsHungry();
53 /// private:
54 /// Bunny();
55 /// Bunny(bool);
56 /// };
57 ///
58 /// BunnyRefPtr nice = Bunny::New();
59 /// BunnyRefPtr mean = Bunny::New(true); // this one is rabid
60 ///
61 /// BunnyRefPtr mean2 = mean; // two references to mean rabbit
62 /// mean.Reset(); // one reference to mean rabbit
63 ///
64 /// if (mean2->IsHungry())
65 /// nice.Reset(); // nice bunny gone now...
66 ///
67 /// // this function comes from
68 /// // TfRefBase; meaning is that
69 /// if (mean2->IsUnique()) // mean2 is the last pointer to
70 /// mean2.Reset(); // this bunny...
71 /// \endcode
72 ///
73 /// Pretty much any pointer operation that is legal with regular pointers
74 /// is legal with the \c BunnyRefPtr; continue reading for a more detailed
75 /// description.
76 ///
77 /// Note that by virtue of deriving from \c TfRefBase, the reference
78 /// count can be queried: see \c TfRefBase for details.
79 ///
80 /// \anchor refPtr_DetailedDiscussion
81 /// <B> Detailed Discussion: Overview </B>
82 ///
83 /// Objects created by the \c new operator can easily be a source of
84 /// both memory leaks and dangling pointers. One solution is
85 /// \e reference counting; when an object is created by \c new,
86 /// the number of pointers given the object's address is continually
87 /// tracked in a \e reference \e counter. Then, \c delete is called on
88 /// the object \e only when the object's reference count drops to zero,
89 /// meaning there are no more pointers left pointing to the object.
90 /// Reference counting avoids both dangling pointers and memory leaks.
91 ///
92 /// Access by regular pointers does not perform reference counting, but
93 /// the \c TfRefPtr<T> class implements reference-counted pointer access
94 /// to objects of type \c T, with minimal overhead. The reference counting
95 /// is made thread-safe by use of atomic integers.
96 ///
97 ///
98 /// <B> Basic Use </B>
99 ///
100 /// The use of a \c TfRefPtr is simple. Whenever a \c TfRefPtr is
101 /// made to point at an object, either by initialization or assignment,
102 /// the object being pointed at has its reference count incremented.
103 /// When a \c TfRefPtr with a non-NULL address is reassigned, or
104 /// goes out of scope, the object being pointed to has its reference
105 /// count decremented.
106 ///
107 /// A \c TfRefPtr<T> can access \c T's public members by the
108 /// \c -> operator and can be dereferenced by the "\c *" operator.
109 /// Here is a simple example:
110 /// \code
111 /// #include "pxr/base/tf/refPtr.h"
112 ///
113 /// typedef TfRefPtr<Simple> SimpleRefPtr;
114 ///
115 /// class Simple : public TfRefBase {
116 /// public:
117 /// void Method1();
118 /// int Method2();
119 ///
120 /// static SimpleRefPtr New() {
121 /// return TfCreateRefPtr(new Simple);
122 /// }
123 /// private:
124 /// Simple();
125 /// };
126 ///
127 ///
128 /// SimpleRefPtr p1; // p1 points to NULL
129 /// SimpleRefPtr p2 = Simple::New(); // p2 points to new object A
130 /// SimpleRefPtr p3 = Simple::New(); // p3 points to new object B
131 ///
132 /// p1->Method1(); // runtime error -- p1 is NULL
133 /// p3 = p2; // object B is deleted
134 /// p2->Method1(); // Method1 on object A
135 /// int value = p3->Method2(); // Method2 on object A
136 ///
137 /// p2.Reset(); // only p3 still points at A
138 /// p3 = p1; // object A is deleted
139 ///
140 /// if (...) {
141 /// SimpleRefPtr p4 = Simple::New(); // p4 points to object C
142 /// p4->Method1();
143 /// } // object C destroyed
144 /// \endcode
145 ///
146 /// Note that \c Simple's constructor is private; this ensures that one
147 /// can only get at a \c Simple through \c Simple::New(), which is careful
148 /// to return a \c SimpleRefPtr.
149 ///
150 /// Note that it is often useful to have both const and non-const
151 /// versions of \c TfRefPtr for the same data type. Our convention
152 /// is to use a \c typedef for each of these, with the const version
153 /// beginning with "Const", after any prefix. The const version can be
154 /// used as a parameter to a function in which you want to prevent
155 /// changes to the pointed-to object. For example:
156 /// \code
157 /// typedef TfRefPtr<XySimple> XySimpleRefPtr;
158 /// typedef TfRefPtr<const XySimple> XyConstSimpleRefPtr;
159 ///
160 /// void
161 /// Func1(const XySimpleRefPtr &p)
162 /// {
163 /// p->Modify(); // OK even if Modify() is not a const member
164 /// }
165 ///
166 /// void
167 /// Func2(const XyConstSimpleRefPtr &p)
168 /// {
169 /// p->Query(); // OK only if Query() is a const member
170 /// }
171 /// \endcode
172 ///
173 /// It is always possible to assign a non-const pointer to a const
174 /// pointer variable. In extremely rare cases where you want to do the
175 /// opposite, you can use the \c TfConst_cast function, as in:
176 /// \code
177 /// XyConstSimpleRefPtr p1;
178 /// XySimpleRefPtr p2;
179 ///
180 /// p1 = p2; // OK
181 /// p2 = p1; // Illegal!
182 /// p2 = TfConst_cast<XySimpleRefPtr>(p1); // OK, but discouraged
183 /// \endcode
184 ///
185 /// <B> Comparisons and Tests </B>
186 ///
187 /// Reference-counted pointers of like type can be compared; any \c TfRefPtr
188 /// can be tested to see it is NULL or not:
189 ///
190 /// \code
191 /// TfRefPtr<Elf> elf = Elf::New();
192 /// TfRefPtr<Dwarf> sleepy,
193 /// sneezy = Dwarf::New();
194 ///
195 /// if (!sleepy)
196 /// ... // true: sleepy is NULL
197 ///
198 /// if (sneezy)
199 /// ... // true: sneezy is non-nULL
200 ///
201 /// bool b1 = (sleepy != sneezy),
202 /// b2 = (sleepy == sneezy),
203 /// b3 = (elf == sneezy); // compilation error -- type clash
204 ///
205 /// \endcode
206 ///
207 /// <B> Opaqueness </B>
208 ///
209 /// A \c TfRefPtr can be used as an opaque pointer, just as a regular
210 /// pointer can. For example, without having included the header file
211 /// for a class \c XySimple, the following will still compile:
212 /// \code
213 /// #include "pxr/base/tf/refPtr.h"
214 ///
215 /// class XySimple;
216 ///
217 /// class Complicated {
218 /// public:
219 /// void SetSimple(const TfRefPtr<XySimple>& s) {
220 /// _simplePtr = s;
221 /// }
222 ///
223 /// TfRefPtr<XySimple> GetSimple() {
224 /// return _simplePtr;
225 /// }
226 ///
227 /// void Forget() {
228 /// _simplePtr.Reset();
229 /// }
230 ///
231 /// private:
232 /// TfRefPtr<XySimple> _simplePtr;
233 /// };
234 /// \endcode
235 ///
236 /// Note that the call \c Forget() (or \c SetSimple() for that matter)
237 /// may implicitly cause destruction of an \c XySimple object, if the count
238 /// of the object pointed to by \c _simplePtr drops to zero. Even though
239 /// the definition of \c XySimple is unknown, this compiles and works correctly.
240 ///
241 /// The only time that the definition of \c XySimple is required is when
242 /// putting a raw \c XySimple* into a \c TfRefPtr<XySimple>; note however, that
243 /// this should in fact only be done within the class definition of
244 /// \c XySimple itself.
245 ///
246 /// Other cases that require a definition of \c XySimple are parallel to
247 /// regular raw pointers, such as calling a member function, static or
248 /// dynamic casts (but not const casts) and using the \c TfTypeid
249 /// function. Transferring a \c TfWeakPtr to a \c TfRefPtr also
250 /// requires knowing the definition of \c XySimple.
251 ///
252 /// Sometimes a class may have many typedefs associated with it, having
253 /// to do with \c TfRefPtr or \c TfWeakPtr. If it is useful to use
254 /// the class opaquely, we recommend creating a separate file
255 /// as follows:
256 ///
257 /// \code
258 /// // file: proj/xy/simplePtrDefs.h
259 /// #include "pxr/base/tf/refPtr.h"
260 /// #include "pxr/base/tf/weakPtr.h"
261 ///
262 /// typedef TfRefPtr<class XySimple> XySimpleRefPtr;
263 /// typedef TfRefPtr<const class XySimple> XyConstSimpleRefPtr;
264 ///
265 /// // typedefs for TfWeakPtr<XySimple> would follow,
266 /// // if XySimple derives from TfWeakBase
267 /// \endcode
268 ///
269 /// The definition for \c XySimple would then use the typedefs:
270 ///
271 /// \code
272 /// #include "Proj/Xy/SimpleRefPtrDefs.h"
273 ///
274 /// class XySimple : public TfRefBase {
275 /// public:
276 /// static XySimpleRefPtr New();
277 /// ...
278 /// };
279 ///
280 /// \endcode
281 ///
282 /// The above pattern now allows a consumer of class \c XySimple the option
283 /// to include only \c simplePtrDefs.h, if using the type opaquely suffices,
284 /// or to include \c simple.h, if the class definition is required.
285 ///
286 ///
287 /// <B> Cyclic Dependencies </B>
288 ///
289 /// If you build a tree using \c TfRefPtr, and you only have pointers
290 /// from parent to child, everything is fine: if you "lose" the root of the
291 /// tree, the tree will correctly destroy itself.
292 ///
293 /// But what if children point back to parents? Then a simple parent/child
294 /// pair is stable, because the parent and child point at each other, and
295 /// even if nobody else has a pointer to the parent, the reference count
296 /// of the two nodes remains at one.
297 ///
298 /// The solution to this is to make one of the links (typically from child back
299 /// to parent) use a \c TfWeakPtr. If a class \c T is enabled for both
300 /// "guarding" (see \c TfWeakBase) and reference counting, then a \c TfRefPtr
301 /// can be converted to a \c TfWeakPtr (in this context, a "back pointer")
302 /// and vice versa.
303 ///
304 /// <B> Inheritance </B>
305 ///
306 ///
307 /// Reference-counted pointers obey the same rules with respect to inheritance
308 /// as regular pointers. In particular, if class \c Derived is derived
309 /// from class \c Base, then the following are legal:
310 ///
311 /// \code
312 /// TfRefPtr<Base> bPtr = new Base;
313 /// TfRefPtr<Derived> dPtr = new Derived;
314 ///
315 /// TfRefPtr<Base> b2Ptr = dPtr; // initialization
316 /// b2Ptr = dPtr; // assignment
317 /// b2Ptr == dPtr; // comparison
318 ///
319 /// dPtr = bPtr; // Not legal: compilation error
320 /// \endcode
321 ///
322 /// As the last example shows, initialization or assignment to
323 /// a \c TfRefPtr<Derived> from a \c TfRefPtr<Base> is illegal,
324 /// just as it is illegal to assign a \c Base* to a \c Derived*.
325 /// However, if \c Derived and \c Base are polymorphic
326 /// (i.e. have virtual functions) then the analogue of a \c dynamic_cast<>
327 /// is possible:
328 ///
329 /// \code
330 /// dPtr = TfDynamic_cast<TfRefPtr<Derived> >(bPtr);
331 /// \endcode
332 ///
333 /// Just like a regular \c dynamic_cast<> operation, the \c TfRefPtr
334 /// returned by \c TfDynamic_cast<> points to NULL if the conversion fails,
335 /// so that the operator can also be used to check types:
336 ///
337 /// \code
338 /// if (! TfDynamic_cast<TfRefPtr<T2> >(ptr))
339 /// // complain: ptr is not of type T2
340 /// \endcode
341 ///
342 /// Similarly, one can use the \c TfStatic_cast<> operator to statically
343 /// convert \c TfRefPtrs:
344 ///
345 /// \code
346 /// dPtr = TfStatic_cast<TfRefPtr<Derived> >(bPtr);
347 /// \endcode
348 ///
349 /// This is faster, but not as safe as using \c TfDynamic_cast.
350 ///
351 /// Finally, remember that in \c C++, a \c Derived** is
352 /// not a \c Base**, nor is a \c Derived*& a \c Base*&. This implies
353 /// that
354 ///
355 /// \code
356 /// TfRefPtr<Base>* bPtrPtr = &dPtr; // compilation error
357 /// TfRefPtr<Base>& bPtrRef = dPtr; // compilation error
358 /// const TfRefPtr<Base>&bPtrRef = dPtr; // OK
359 /// \endcode
360 ///
361 /// The last initialization is legal because the compiler implicitly
362 /// converts dPtr into a temporary variable of type \c TfRefPtr<Base>.
363 ///
364 ///
365 /// <B> Thread Safety </B>
366 ///
367 /// One more comment about thread-safety: the above examples are thread-safe
368 /// in the sense that if two or more threads create and destroy their \e own
369 /// \c TfRefPtr objects, the reference counts of the underlying objects are
370 /// always correct; said another way, the reference count it a thread-safe
371 /// quantity.
372 ///
373 /// However, it is never safe for two threads to simultaneously try to alter
374 /// the same \c TfRefPtr object, nor can two threads safely call methods on the
375 /// same underlying object unless that object itself guarantees thread safety.
376 ///
377 /// \anchor refPtr_Tracking
378 /// <B> Tracking References </B>
379 ///
380 /// The \c TfRefPtrTracker singleton can track \c TfRefPtr objects that
381 /// point to particular instances. The macros \c TF_DECLARE_REFBASE_TRACK
382 /// and \c TF_DEFINE_REFBASE_TRACK are used to enable tracking. Tracking
383 /// is enabled at compile time but which instances to track is chosen at
384 /// runtime.
385 ///
386 /// <B> Total Encapsulation </B>
387 /// \anchor refPtr_encapsulation
388 ///
389 /// If you're using \c TfRefPtrs on a type \c T, you probably want
390 /// to completely forbid clients from creating their own objects of
391 /// type \c T, and force them to go through \c TfRefPtrs. Such
392 /// encapsulation is strongly encouraged. Here is the recommended
393 /// technique:
394 ///
395 /// \code
396 ///
397 /// typedef TfRefPtr<class Simple> SimpleRefPtr;
398 ///
399 /// class Simple : public TfRefBase {
400 /// private: // use protected if you plan to derive later
401 /// Simple();
402 /// Simple(<arg-list>);
403 /// public:
404 /// static SimpleRefPtr New() {
405 /// return TfCreateRefPtr(new Simple);
406 /// }
407 ///
408 /// static SimpleRefPtr New(<arg-list>) {
409 /// return TfCreateRefPtr(new Simple(<arg-list>));
410 /// }
411 ///
412 /// ~Simple();
413 /// };
414 /// \endcode
415 ///
416 /// Clients can now only create objects of type \c Simple using a
417 /// \c TfRefPtr:
418 ///
419 /// \code
420 /// Simple s; // compilation error
421 /// SimpleRefPtr sPtr1 = new Simple; // compilation error
422 /// SimpleRefPtr sPtr2 = Simple::New(); // OK
423 /// SimpleRefPtr sPtr3 = Simple::New(<arg-list>); // Ok
424 /// \endcode
425 ///
426 
427 #include "pxr/pxr.h"
428 
430 #include "pxr/base/tf/hash.h"
431 #include "pxr/base/tf/nullPtr.h"
432 #include "pxr/base/tf/refBase.h"
435 #include "pxr/base/tf/api.h"
436 
437 #include "pxr/base/arch/hints.h"
438 
439 
440 #include <typeinfo>
441 #include <type_traits>
442 #include <cstddef>
443 
445 
446 // Tf_SupportsUniqueChanged is a metafunction that may be specialized to return
447 // false for classes (and all derived classes) that *cannot* ever invoke unique
448 // changed listeners.
449 template <class T>
451  static const bool Value = true;
452 };
453 
454 // Remnants are never able to support weak changed listeners.
455 class Tf_Remnant;
456 template <>
458  static const bool Value = false;
459 };
460 
461 class TfWeakBase;
462 
463 template <class T> class TfWeakPtr;
464 template <template <class> class X, class Y>
466 
467 // Functions used for tracking. Do not implement these.
468 inline void Tf_RefPtrTracker_FirstRef(const void*, const void*) { }
469 inline void Tf_RefPtrTracker_LastRef(const void*, const void*) { }
470 inline void Tf_RefPtrTracker_New(const void*, const void*) { }
471 inline void Tf_RefPtrTracker_Delete(const void*, const void*) { }
472 inline void Tf_RefPtrTracker_Assign(const void*, const void*, const void*) { }
473 
474 // This code is used to increment and decrement ref counts in the common case.
475 // It may lock and invoke the unique changed listener, if the reference count
476 // becomes unique or non-unique.
478  static inline void
479  AddRef(TfRefBase const *refBase) {
480  if (ARCH_UNLIKELY(!refBase)) {
481  return;
482  }
483  const auto relaxed = std::memory_order_relaxed;
484  // Read the current count value.
485  std::atomic_int &counter = refBase->_GetRefCount();
486  int prevCount = counter.load(relaxed);
487  if (ARCH_UNLIKELY(prevCount < 0)) {
488  // We need to invoke the unique changed listener if count goes from
489  // -1 -> -2. Try to CAS the value to one more count if it looks
490  // like we won't take it from -1 -> -2. If that works, we're done.
491  // If not, we'll call an out-of-line function that handles the
492  // locking part.
493  if (prevCount != -1 && counter.
494  compare_exchange_weak(prevCount, prevCount-1, relaxed)) {
495  return;
496  }
497  _AddRefMaybeLocked(refBase, prevCount);
498  }
499  else {
500  // Just bump the count.
501  counter.fetch_add(1, relaxed);
502  }
503  }
504 
505  static inline bool
506  RemoveRef(TfRefBase const* refBase) {
507  if (ARCH_UNLIKELY(!refBase)) {
508  return false;
509  }
510  const auto relaxed = std::memory_order_relaxed;
511  const auto release = std::memory_order_release;
512  // Read the current count value.
513  std::atomic_int &counter = refBase->_GetRefCount();
514  int prevCount = counter.load(relaxed);
515  if (ARCH_UNLIKELY(prevCount < 0)) {
516  // We need to invoke the unique changed listener if count goes from
517  // -2 -> -1. Try to CAS the value to one less count if it looks
518  // like we won't take it from -2 -> -1. If that works, we're done.
519  // If not, we'll call an out-of-line function that handles the
520  // locking part.
521  if (prevCount != -2 && counter.
522  compare_exchange_weak(prevCount, prevCount+1, release)) {
523  return prevCount == -1;
524  }
525  return _RemoveRefMaybeLocked(refBase, prevCount);
526  }
527  else {
528  // Just drop the count.
529  return counter.fetch_sub(1, release) == 1;
530  }
531  }
532 
533  // Increment ptr's count if it is not zero. Return true if done so
534  // successfully, false if its count is zero.
535  TF_API static bool
536  AddRefIfNonzero(TfRefBase const *refBase);
537 
538  TF_API static void
539  _AddRefMaybeLocked(TfRefBase const *refBase, int prevCount);
540 
541  TF_API static bool
542  _RemoveRefMaybeLocked(TfRefBase const *refBase, int prevCount);
543 
544 };
545 
546 // This code is used to increment and decrement ref counts in the case where
547 // the object pointed to explicitly does not support unique changed listeners.
549  static inline void
550  AddRef(TfRefBase const *refBase) {
551  if (ARCH_UNLIKELY(!refBase)) {
552  return;
553  }
554  refBase->_GetRefCount().fetch_add(1, std::memory_order_relaxed);
555  }
556 
557  static inline bool
558  RemoveRef(TfRefBase const *refBase) {
559  if (ARCH_UNLIKELY(!refBase)) {
560  return false;
561  }
562  return refBase->_GetRefCount()
563  .fetch_sub(1, std::memory_order_release) == 1;
564  }
565 
566  // Increment ptr's count if it is not zero. Return true if done so
567  // successfully, false if its count is zero.
568  static inline bool
569  AddRefIfNonzero(TfRefBase const *refBase) {
570  if (ARCH_UNLIKELY(!refBase)) {
571  return false;
572  }
573  auto &counter = refBase->_GetRefCount();
574  int prevCount = counter.load(std::memory_order_relaxed);
575  while (prevCount) {
576  if (counter.compare_exchange_weak(prevCount, prevCount+1)) {
577  return true;
578  }
579  }
580  return false;
581  }
582 };
583 
584 // Helper to post a fatal error when a NULL Tf pointer is dereferenced.
585 [[noreturn]]
586 TF_API void
588 
589 /// \class TfRefPtr
590 /// \ingroup group_tf_Memory
591 ///
592 /// Reference-counted smart pointer utility class
593 ///
594 /// The \c TfRefPtr class implements a reference counting on objects
595 /// that inherit from \c TfRefBase.
596 ///
597 /// For more information, see either the \ref refPtr_QuickStart "Quick Start"
598 /// example or read the \ref refPtr_DetailedDiscussion "detailed discussion".
599 ///
600 template <class T>
601 class TfRefPtr {
602  // Select the counter based on whether T supports unique changed listeners.
603  using _Counter = typename std::conditional<
608 
609 public:
610  /// Convenience type accessor to underlying type \c T for template code.
611  typedef T DataType;
612 
613 
614  template <class U> struct Rebind {
615  typedef TfRefPtr<U> Type;
616  };
617 
618  /// Initialize pointer to nullptr.
619  ///
620  /// The default constructor leaves the pointer initialized to point to the
621  /// NULL object. Attempts to use the \c -> operator will cause an abort
622  /// until the pointer is given a value.
623  TfRefPtr() : _refBase(nullptr) {
624  Tf_RefPtrTracker_New(this, _GetObjectForTracking());
625  }
626 
627  /// Moves the pointer managed by \p p to \c *this.
628  ///
629  /// After construction, \c *this will point to the object \p p had
630  /// been pointing at and \p p will be pointing at the NULL object.
631  /// The reference count of the object being pointed at does not
632  /// change.
633  TfRefPtr(TfRefPtr<T>&& p) : _refBase(p._refBase) {
634  p._refBase = nullptr;
635  Tf_RefPtrTracker_New(this, _GetObjectForTracking());
636  Tf_RefPtrTracker_Assign(&p, p._GetObjectForTracking(),
637  _GetObjectForTracking());
638  }
639 
640  /// Initializes \c *this to point at \p p's object.
641  ///
642  /// Increments \p p's object's reference count.
643  TfRefPtr(const TfRefPtr<T>& p) : _refBase(p._refBase) {
644  _AddRef();
645  Tf_RefPtrTracker_New(this, _GetObjectForTracking());
646  }
647 
648  /// Initializes \c *this to point at \p gp's object.
649  ///
650  /// Increments \p gp's object's reference count.
651  template <template <class> class X, class U>
652  inline TfRefPtr(const TfWeakPtrFacade<X, U>& p,
653  typename std::enable_if<
655  >::type * = 0);
656 
657  /// Transfer a raw pointer to a reference-counted pointer.
658  ///
659  /// The \c TfCreateRefPtr() function should only be used from within a
660  /// static \c New() function (or similarly, a \c Clone() function) of a
661  /// reference-counted class. Reference-counted objects have their
662  /// reference count initially set to one to account for the fact that a
663  /// newly created object must always persist at least until its \c New()
664  /// function returns. Therefore, the transfer of the pointer returned by
665  /// \c new into a reference pointer must \e not increase the reference
666  /// count. The transfer of the raw pointer returned by \c new into the
667  /// object returned by \c New() is a "transfer of ownership" and does not
668  /// represent an additional reference to the object.
669  ///
670  /// In summary, this code is wrong, and will return an object that can
671  /// never be destroyed:
672  ///
673  /// \code
674  /// SimpleRefPtr Simple::New() {
675  /// return SimpleRefPtr(new Simple); // legal, but leaks memory: beware!!
676  /// }
677  /// \endcode
678  ///
679  /// The correct form is
680  ///
681  /// \code
682  /// SimpleRefPtr Simple::New() {
683  /// return TfCreateRefPtr(new Simple);
684  /// }
685  /// \endcode
686  ///
687  /// Note also that a function which is essentially like \c New(),
688  /// for example \c Clone(), would also want to use \c TfCreateRefPtr().
689 #if defined(doxygen)
690  friend inline TfRefPtr TfCreateRefPtr(T*);
691 #else
692  template <class U>
693  friend inline TfRefPtr<U> TfCreateRefPtr(U*);
694 #endif
695 
696  /// Initializes to point at \c *ptr.
697  ///
698  /// Increments \c *ptr's reference count. Note that newly constructed
699  /// objects start with a reference count of one. Therefore, you should \e
700  /// NOT use this constructor (either implicitly or explicitly) from within
701  /// a \c New() function. Use \c TfCreateRefPtr() instead.
702  template <class U>
703  explicit TfRefPtr(
704  U* ptr, typename std::enable_if<
706  _refBase(ptr)
707  {
708  _AddRef();
709  Tf_RefPtrTracker_New(this, _GetObjectForTracking());
710  }
711 
712  /// Implicit conversion from \a TfNullPtr to TfRefPtr.
713  TfRefPtr(TfNullPtrType) : _refBase(nullptr)
714  {
715  Tf_RefPtrTracker_New(this, _GetObjectForTracking());
716  }
717 
718  /// Implicit conversion from \a nullptr to TfRefPtr.
719  TfRefPtr(std::nullptr_t) : _refBase(nullptr)
720  {
721  Tf_RefPtrTracker_New(this, _GetObjectForTracking());
722  }
723 
724  /// Assigns pointer to point at \c p's object, and increments reference
725  /// count.
726  ///
727  /// The object (if any) pointed at before the assignment has its
728  /// reference count decremented, while the object newly pointed at
729  /// has its reference count incremented.
730  /// If the object previously pointed to now has nobody left to point at it,
731  /// the object will typically be destroyed at this point.
732  ///
733  /// An assignment
734  /// \code
735  /// ptr = TfNullPtr;
736  /// \endcode
737  ///
738  /// can be used to make \c ptr "forget" where it is pointing; note
739  /// however that this has an important side effect, since it
740  /// decrements the reference count of the object previously pointed
741  /// to by \c ptr, possibly triggering destruction of that object.
743  //
744  // It is quite possible for
745  // ptr = TfNullPtr;
746  // to delete the space that ptr actually lives in (this happens
747  // when you use a circular reference to keep an object alive).
748  // To avoid a crash, we have to ensure that deletion of the object
749  // is the last thing done in the assignment; so we use some
750  // local variables to help us out.
751  //
752 
753  Tf_RefPtrTracker_Assign(this, p._GetObjectForTracking(),
754  _GetObjectForTracking());
755 
756  const TfRefBase* tmp = _refBase;
757  _refBase = p._refBase;
758 
759  p._AddRef(); // first!
760  _RemoveRef(tmp); // second!
761  return *this;
762  }
763 
764  /// Moves the pointer managed by \p p to \c *this and leaves \p p
765  /// pointing at the NULL object.
766  ///
767  /// The object (if any) pointed at before the assignment has its
768  /// reference count decremented, while the reference count of the
769  /// object newly pointed at is not changed.
771  // See comment in assignment operator.
772  Tf_RefPtrTracker_Assign(this, p._GetObjectForTracking(),
773  _GetObjectForTracking());
774  Tf_RefPtrTracker_Assign(&p, nullptr,
775  p._GetObjectForTracking());
776 
777  const TfRefBase* tmp = _refBase;
778  _refBase = p._refBase;
779  p._refBase = nullptr;
780 
781  _RemoveRef(tmp);
782  return *this;
783  }
784 
785  /// Decrements reference count of object being pointed to.
786  ///
787  /// If the reference count of the object (if any) that was just pointed at
788  /// reaches zero, the object will typically be destroyed at this point.
790  Tf_RefPtrTracker_Delete(this, _GetObjectForTracking());
791  _RemoveRef(_refBase);
792  }
793 
794  /// Initializes to point at \c p's object, and increments reference count.
795  ///
796  /// This initialization is legal only if
797  /// \code
798  /// U* uPtr;
799  /// T* tPtr = uPtr;
800  /// \endcode
801  /// is legal.
802 #if !defined(doxygen)
803  template <class U>
804 #endif
805  TfRefPtr(const TfRefPtr<U>& p) : _refBase(p._refBase) {
806  static_assert(std::is_convertible<U*, T*>::value, "");
807  _AddRef();
808  Tf_RefPtrTracker_New(this, _GetObjectForTracking());
809  }
810 
811  /// Moves the pointer managed by \p p to \c *this and leaves \p p
812  /// pointing at the NULL object. The reference count of the object
813  /// being pointed to is not changed.
814  ///
815  /// This initialization is legal only if
816  /// \code
817  /// U* uPtr;
818  /// T* tPtr = uPtr;
819  /// \endcode
820  /// is legal.
821 #if !defined(doxygen)
822  template <class U>
823 #endif
824  TfRefPtr(TfRefPtr<U>&& p) : _refBase(p._refBase) {
825  static_assert(std::is_convertible<U*, T*>::value, "");
826  p._refBase = nullptr;
827  Tf_RefPtrTracker_New(this, _GetObjectForTracking());
828  Tf_RefPtrTracker_Assign(&p, p._GetObjectForTracking(),
829  _GetObjectForTracking());
830  }
831 
832  /// Assigns pointer to point at \c p's object, and increments reference
833  /// count.
834  ///
835  /// This assignment is legal only if
836  /// \code
837  /// U* uPtr;
838  /// T* tPtr;
839  /// tPtr = uPtr;
840  /// \endcode
841  /// is legal.
842 #if !defined(doxygen)
843  template <class U>
844 #endif
846  static_assert(std::is_convertible<U*, T*>::value, "");
847 
849  reinterpret_cast<T*>(p._GetObjectForTracking()),
850  _GetObjectForTracking());
851  const TfRefBase* tmp = _refBase;
852  _refBase = p._GetData();
853  p._AddRef(); // first!
854  _RemoveRef(tmp); // second!
855  return *this;
856  }
857 
858  /// Moves the pointer managed by \p p to \c *this and leaves \p p
859  /// pointing at the NULL object. The reference count of the object
860  /// being pointed to is not changed.
861  ///
862  /// This assignment is legal only if
863  /// \code
864  /// U* uPtr;
865  /// T* tPtr;
866  /// tPtr = uPtr;
867  /// \endcode
868  /// is legal.
869 #if !defined(doxygen)
870  template <class U>
871 #endif
873  static_assert(std::is_convertible<U*, T*>::value, "");
874 
876  reinterpret_cast<T*>(p._GetObjectForTracking()),
877  _GetObjectForTracking());
879  nullptr,
880  reinterpret_cast<T*>(p._GetObjectForTracking()));
881  const TfRefBase* tmp = _refBase;
882  _refBase = p._GetData();
883  p._refBase = nullptr;
884  _RemoveRef(tmp);
885  return *this;
886  }
887 
888  /// Returns true if \c *this and \c p point to the same object (or if they
889  /// both point to NULL).
890  ///
891  /// The comparison is legal only if a \c T* and a \c U* are comparable.
892 #if !defined(doxygen)
893  template <class U>
894 #endif
895  auto operator==(const TfRefPtr<U>& p) const
896  -> decltype(std::declval<T *>() == std::declval<U *>(), bool()) {
897  return _refBase == p._refBase;
898  }
899 
900  /// Returns true if \c *this and \c p do not point to the same object.
901  ///
902  /// The comparison is legal only if a \c T* and a \c U* are comparable.
903 #if !defined(doxygen)
904  template <class U>
905 #endif
906  auto operator!=(const TfRefPtr<U>& p) const
907  -> decltype(std::declval<T *>() != std::declval<U *>(), bool()) {
908  return _refBase != p._refBase;
909  }
910 
911  /// Returns true if the address of the object pointed to by \c *this
912  /// compares less than the address of the object pointed to by \p p.
913  ///
914  /// The comparison is legal only if a \c T* and a \c U* are comparable.
915 #if !defined(doxygen)
916  template <class U>
917 #endif
918  auto operator<(const TfRefPtr<U>& p) const
919  -> decltype(std::declval<T *>() < std::declval<U *>(), bool()) {
920  return _refBase < p._refBase;
921  }
922 
923 #if !defined(doxygen)
924  template <class U>
925 #endif
926  auto operator>(const TfRefPtr<U>& p) const
927  -> decltype(std::declval<T *>() > std::declval<U *>(), bool()) {
928  return _refBase > p._refBase;
929  }
930 
931 #if !defined(doxygen)
932  template <class U>
933 #endif
934  auto operator<=(const TfRefPtr<U>& p) const
935  -> decltype(std::declval<T *>() <= std::declval<U *>(), bool()) {
936  return _refBase <= p._refBase;
937  }
938 
939 #if !defined(doxygen)
940  template <class U>
941 #endif
942  auto operator>=(const TfRefPtr<U>& p) const
943  -> decltype(std::declval<T *>() >= std::declval<U *>(), bool()) {
944  return _refBase >= p._refBase;
945  }
946 
947  /// Accessor to \c T's public members.
948  T* operator->() const {
949  if (_refBase) {
950  return static_cast<T*>(const_cast<TfRefBase*>(_refBase));
951  }
953  TF_CALL_CONTEXT, typeid(TfRefPtr).name());
954  }
955 
956  /// Dereferences the stored pointer.
957  T& operator *() const {
958  return *operator->();
959  }
960 
961 #if !defined(doxygen)
962  using UnspecifiedBoolType = const TfRefBase * (TfRefPtr::*);
963 #endif
964 
965  /// True if the pointer points to an object.
966  operator UnspecifiedBoolType() const {
967  return _refBase ? &TfRefPtr::_refBase : nullptr;
968  }
969 
970  /// True if the pointer points to \c NULL.
971  bool operator !() const {
972  return _refBase == nullptr;
973  }
974 
975  /// Swap this pointer with \a other.
976  /// After this operation, this pointer will point to what \a other
977  /// formerly pointed to, and \a other will point to what this pointer
978  /// formerly pointed to.
979  void swap(TfRefPtr &other) {
980  Tf_RefPtrTracker_Assign(this, other._GetObjectForTracking(),
981  _GetObjectForTracking());
982  Tf_RefPtrTracker_Assign(&other, _GetObjectForTracking(),
983  other._GetObjectForTracking());
984  std::swap(_refBase, other._refBase);
985  }
986 
987  /// Set this pointer to point to no object.
988  /// Equivalent to assignment with TfNullPtr.
989  void Reset() {
990  *this = TfNullPtr;
991  }
992 
993 private:
994  const TfRefBase* _refBase;
995 
996  template <class HashState, class U>
997  friend inline void TfHashAppend(HashState &, const TfRefPtr<U>&);
998  template <class U>
999  friend inline size_t hash_value(const TfRefPtr<U>&);
1000 
1001  friend T *get_pointer(TfRefPtr const &p) {
1002  return static_cast<T *>(const_cast<TfRefBase *>(p._refBase));
1003  }
1004 
1005  // Used to distinguish construction in TfCreateRefPtr.
1006  class _CreateRefPtr { };
1007 
1008  // private constructor, used by TfCreateRefPtr()
1009  TfRefPtr(T* ptr, _CreateRefPtr /* unused */)
1010  : _refBase(ptr)
1011  {
1012  /* reference count is NOT bumped */
1013  Tf_RefPtrTracker_FirstRef(this, _GetObjectForTracking());
1014  Tf_RefPtrTracker_New(this, _GetObjectForTracking());
1015  }
1016 
1017  // Hide confusing internals of actual C++ definition (e.g. DataType)
1018  // for doxygen output:
1019 
1020  /// Allows dynamic casting of a \c TfRefPtr.
1021  ///
1022  /// If it is legal to dynamically cast a \c T* to a \c D* , then
1023  /// the following is also legal:
1024  /// \code
1025  /// TfRefPtr<T> tPtr = ... ;
1026  /// TfRefPtr<D> dPtr;
1027  ///
1028  /// if (!(dPtr = TfDynamic_cast< TfRefPtr<D> >(tPtr)))
1029  /// ...; // cast failed
1030  /// \endcode
1031  /// The runtime performance of this function is exactly the same
1032  /// as a \c dynamic_cast (i.e. one virtual function call). If the pointer
1033  /// being cast is NULL or does not point to an object of the requisite
1034  /// type, the result is a \c TfRefPtr pointing to NULL.
1035 #if defined(doxygen)
1036  // Sanitized for documentation:
1037  template <class D>
1038  friend inline TfRefPtr<D> TfDynamic_cast(const TfRefPtr<T>&);
1039 #else
1040  template <class D, class B>
1042  TfDynamic_cast(const TfRefPtr<B>&);
1043 
1044  template <class D, class B>
1047 #endif
1048 
1049  /// Allows static casting of a \c TfRefPtr.
1050  ///
1051  /// If it is legal to statically cast a \c T* to a \c D* , then
1052  /// the following is also legal:
1053  /// \code
1054  /// TfRefPtr<T> tPtr = ... ;
1055  /// TfRefPtr<D> dPtr;
1056  ///
1057  /// dPtr = TfStatic_cast< TfRefPtr<D> >(tPtr);
1058  /// \endcode
1059  /// The runtime performance of this function is exactly the same
1060  /// as a regular \c TfRefPtr initialization, since the cost of
1061  /// the underlying \c static_cast is zero. Of course, a \c TfDynamic_cast
1062  /// is preferred, assuming the underlying types are polymorphic
1063  /// (i.e. have virtual functions).
1064  ///
1065 #if defined(doxygen)
1066  // Sanitized for documentation:
1067  template <class D>
1068  friend inline TfRefPtr<D> TfStatic_cast(const TfRefPtr<T>&);
1069 #else
1070  template <class D, class B>
1072  TfStatic_cast(const TfRefPtr<B>&);
1073 
1074 #endif
1075 
1076  /// Allows const casting of a \c TfRefPtr.
1077  ///
1078  /// The following is always legal:
1079  /// \code
1080  /// TfRefPtr<const T> cPtr = ...;
1081  /// TfRefPtr<T> tPtr;
1082  ///
1083  /// tPtr = TfConst_cast< TfRefPtr<T> >(cPtr);
1084  /// \endcode
1085  /// As with the C++ \c const_cast operator, use of this function is
1086  /// discouraged.
1087 #if defined(doxygen)
1088  // Sanitized for documentation:
1089  template <class D>
1090  friend inline TfRefPtr<D> TfConst_cast(const TfRefPtr<const D>&);
1091 #else
1092  template <class D>
1095 #endif
1096 
1097  T* _GetData() const {
1098  return static_cast<T*>(const_cast<TfRefBase*>(_refBase));
1099  }
1100 
1101  // This method is only used when calling the hook functions for
1102  // tracking. We reinterpret_cast instead of static_cast so that
1103  // we don't need the definition of T. However, if TfRefBase is
1104  // not the first base class of T then the resulting pointer may
1105  // not point to a T. Nevertheless, it should be consistent to
1106  // all calls to the tracking functions.
1107  T* _GetObjectForTracking() const {
1108  return reinterpret_cast<T*>(const_cast<TfRefBase*>(_refBase));
1109  }
1110 
1111  /// Call \c typeid on the object pointed to by a \c TfRefPtr.
1112  ///
1113  /// If \c ptr is a \c TfRefPtr, \c typeid(ptr) will return
1114  /// type information about the \c TfRefPtr. To access type
1115  /// information about the object pointed to by a \c TfRefPtr,
1116  /// one can use \c TfTypeid.
1117 
1118  template <class U>
1119  friend const std::type_info& TfTypeid(const TfRefPtr<U>& ptr);
1120 
1121  void _AddRef() const {
1122  _Counter::AddRef(_refBase);
1123  }
1124 
1125  void _RemoveRef(const TfRefBase* ptr) const {
1126  if (_Counter::RemoveRef(ptr)) {
1128  reinterpret_cast<T*>(const_cast<TfRefBase*>(ptr)));
1129  delete ptr;
1130  }
1131  }
1132 
1133 #if ! defined(doxygen)
1134  // doxygen is very confused by this. It declares all TfRefPtrs
1135  // to be friends.
1136  template <class U> friend class TfRefPtr;
1137  template <class U> friend class TfWeakPtr;
1138  friend class Tf_Remnant;
1139 
1140  template <class U>
1142 #endif
1143  friend class TfWeakBase;
1144 };
1145 
1146 #if !defined(doxygen)
1147 
1148 //
1149 // nullptr comparisons
1150 //
1151 // These are provided to avoid ambiguous overloads due to
1152 // TfWeakPtrFacade::Derived comparisons with TfRefPtr.
1153 //
1154 
1155 template <class T>
1156 inline bool operator== (const TfRefPtr<T> &p, std::nullptr_t)
1157 {
1158  return !p;
1159 }
1160 template <class T>
1161 inline bool operator== (std::nullptr_t, const TfRefPtr<T> &p)
1162 {
1163  return !p;
1164 }
1165 
1166 template <class T>
1167 inline bool operator!= (const TfRefPtr<T> &p, std::nullptr_t)
1168 {
1169  return !(p == nullptr);
1170 }
1171 template <class T>
1172 inline bool operator!= (std::nullptr_t, const TfRefPtr<T> &p)
1173 {
1174  return !(nullptr == p);
1175 }
1176 
1177 template <class T>
1178 inline bool operator< (const TfRefPtr<T> &p, std::nullptr_t)
1179 {
1180  return std::less<const TfRefBase *>()(get_pointer(p), nullptr);
1181 }
1182 template <class T>
1183 inline bool operator< (std::nullptr_t, const TfRefPtr<T> &p)
1184 {
1185  return std::less<const TfRefBase *>()(nullptr, get_pointer(p));
1186 }
1187 
1188 template <class T>
1189 inline bool operator<= (const TfRefPtr<T> &p, std::nullptr_t)
1190 {
1191  return !(nullptr < p);
1192 }
1193 template <class T>
1194 inline bool operator<= (std::nullptr_t, const TfRefPtr<T> &p)
1195 {
1196  return !(p < nullptr);
1197 }
1198 
1199 template <class T>
1200 inline bool operator> (const TfRefPtr<T> &p, std::nullptr_t)
1201 {
1202  return nullptr < p;
1203 }
1204 template <class T>
1205 inline bool operator> (std::nullptr_t, const TfRefPtr<T> &p)
1206 {
1207  return p < nullptr;
1208 }
1209 
1210 template <class T>
1211 inline bool operator>= (const TfRefPtr<T> &p, std::nullptr_t)
1212 {
1213  return !(p < nullptr);
1214 }
1215 template <class T>
1216 inline bool operator>= (std::nullptr_t, const TfRefPtr<T> &p)
1217 {
1218  return !(nullptr < p);
1219 }
1220 
1221 
1222 template <typename T>
1224  return TfRefPtr<T>(ptr, typename TfRefPtr<T>::_CreateRefPtr());
1225 }
1226 
1227 template <class T>
1228 const std::type_info&
1230 {
1231  if (ARCH_UNLIKELY(!ptr._refBase))
1232  TF_FATAL_ERROR("called TfTypeid on NULL TfRefPtr");
1233 
1234  return typeid(*ptr._GetData());
1235 }
1236 
1237 template <class D, class T>
1238 inline
1241 {
1242  typedef TfRefPtr<typename D::DataType> RefPtr;
1243  return RefPtr(dynamic_cast<typename D::DataType*>(ptr._GetData()));
1244 }
1245 
1246 template <class D, class T>
1247 inline
1250 {
1251  typedef TfRefPtr<typename D::DataType> RefPtr;
1252  return RefPtr(TfSafeDynamic_cast<typename D::DataType*>(ptr._GetData()));
1253 }
1254 
1255 template <class D, class T>
1256 inline
1259 {
1260  typedef TfRefPtr<typename D::DataType> RefPtr;
1261  return RefPtr(static_cast<typename D::DataType*>(ptr._GetData()));
1262 }
1263 
1264 template <class T>
1265 inline
1268 {
1269  // this ugly cast allows TfConst_cast to work without requiring
1270  // a definition for T.
1271  typedef TfRefPtr<typename T::DataType> NonConstRefPtr;
1272  return *((NonConstRefPtr*)(&ptr));
1273 }
1274 
1275 // Specialization: prevent construction of a TfRefPtr<TfRefBase>.
1276 
1277 template <>
1279 private:
1280  TfRefPtr() = delete;
1281 };
1282 
1283 template <>
1284 class TfRefPtr<const TfRefBase> {
1285 private:
1286  TfRefPtr() = delete;
1287 };
1288 
1289 template <class T>
1291  static T* GetRawPtr(const TfRefPtr<T>& t) {
1292  return t.operator-> ();
1293  }
1294 
1296  return TfRefPtr<T>(ptr);
1297  }
1298 
1299  static bool IsNull(const TfRefPtr<T>& t) {
1300  return !t;
1301  }
1302 
1305 };
1306 
1307 template <class T>
1308 struct TfTypeFunctions<TfRefPtr<const T> > {
1309  static const T* GetRawPtr(const TfRefPtr<const T>& t) {
1310  return t.operator-> ();
1311  }
1312 
1314  return TfRefPtr<const T>(ptr);
1315  }
1316 
1317  static bool IsNull(const TfRefPtr<const T>& t) {
1318  return !t;
1319  }
1320 
1322 };
1323 
1324 #endif
1325 
1326 #if !defined(doxygen)
1327 
1328 template <class T>
1329 inline void
1331 {
1332  lhs.swap(rhs);
1333 }
1334 
1336 
1337 namespace hboost {
1338 
1339 template<typename T>
1340 T *
1341 get_pointer(PXR_NS::TfRefPtr<T> const& p)
1342 {
1343  return get_pointer(p);
1344 }
1345 
1346 } // end namespace hboost
1347 
1349 
1350 // Extend hboost::hash to support TfRefPtr.
1351 template <class T>
1352 inline size_t
1354 {
1355  return TfHash()(ptr);
1356 }
1357 
1358 template <class HashState, class T>
1359 inline void
1360 TfHashAppend(HashState &h, const TfRefPtr<T> &ptr)
1361 {
1362  h.Append(get_pointer(ptr));
1363 }
1364 
1365 #endif // !doxygen
1366 
1367 #define TF_SUPPORTS_REFPTR(T) std::is_base_of_v<TfRefBase, T>
1368 
1370 
1371 #endif // PXR_BASE_TF_REF_PTR_H
void swap(ArAssetInfo &lhs, ArAssetInfo &rhs)
Definition: assetInfo.h:74
static void Class_Object_MUST_Be_Passed_By_Address()
Definition: refPtr.h:1303
auto operator==(const TfRefPtr< U > &p) const -> decltype(std::declval< T * >()==std::declval< U * >(), bool())
Definition: refPtr.h:895
static TF_API bool _RemoveRefMaybeLocked(TfRefBase const *refBase, int prevCount)
TfRefPtr< T > TfCreateRefPtr(T *ptr)
Definition: refPtr.h:1223
#define TF_CALL_CONTEXT
Definition: callContext.h:47
PXR_NAMESPACE_OPEN_SCOPE size_t hash_value(const TfRefPtr< T > &ptr)
Definition: refPtr.h:1353
TfRefPtr< typename T::DataType > TfConst_cast(const TfRefPtr< const typename T::DataType > &ptr)
Definition: refPtr.h:1267
static TfRefPtr< const T > ConstructFromRawPtr(T *ptr)
Definition: refPtr.h:1313
#define TF_API
Definition: api.h:40
friend size_t hash_value(const TfRefPtr< U > &)
TfRefPtr(TfNullPtrType)
Implicit conversion from TfNullPtr to TfRefPtr.
Definition: refPtr.h:713
Y
Definition: ImathEuler.h:184
void swap(UT::ArraySet< Key, MULTI, MAX_LOAD_FACTOR_256, Clearer, Hash, KeyEqual > &a, UT::ArraySet< Key, MULTI, MAX_LOAD_FACTOR_256, Clearer, Hash, KeyEqual > &b)
Definition: UT_ArraySet.h:1639
auto operator>=(const TfRefPtr< U > &p) const -> decltype(std::declval< T * >() >=std::declval< U * >(), bool())
Definition: refPtr.h:942
GLsizei const GLfloat * value
Definition: glcorearb.h:824
const TfRefBase *(TfRefPtr::*) UnspecifiedBoolType
Definition: refPtr.h:962
static bool IsNull(const TfRefPtr< T > &t)
Definition: refPtr.h:1299
TF_API const TfNullPtrType TfNullPtr
auto operator>(const TfRefPtr< U > &p) const -> decltype(std::declval< T * >() > std::declval< U * >(), bool())
Definition: refPtr.h:926
X
Definition: ImathEuler.h:183
static void Class_Object_MUST_Be_Passed_By_Address()
Definition: refPtr.h:1321
void Tf_RefPtrTracker_LastRef(const void *, const void *)
Definition: refPtr.h:469
friend T * get_pointer(TfRefPtr const &p)
Definition: refPtr.h:1001
friend TfRefPtr< U > TfCreateRefPtr(U *)
static void AddRef(TfRefBase const *refBase)
Definition: refPtr.h:550
TfRefPtr< T > & operator=(const TfRefPtr< T > &p)
Definition: refPtr.h:742
Y * get_pointer(TfWeakPtrFacade< X, Y > const &p)
Definition: weakPtrFacade.h:83
bool operator!() const
True if the pointer points to NULL.
Definition: refPtr.h:971
friend TfRefPtr< typename D::DataType > TfSafeDynamic_cast(const TfRefPtr< B > &)
void Tf_RefPtrTracker_Delete(const void *, const void *)
Definition: refPtr.h:471
Definition: hash.h:477
TfRefPtr(U *ptr, typename std::enable_if< std::is_convertible< U *, T * >::value >::type *=nullptr)
Definition: refPtr.h:703
T & operator*() const
Dereferences the stored pointer.
Definition: refPtr.h:957
static bool RemoveRef(TfRefBase const *refBase)
Definition: refPtr.h:506
atomic< int > atomic_int
Definition: atomic.h:25
TfRefPtr< typename D::DataType > TfDynamic_cast(const TfRefPtr< T > &ptr)
Definition: refPtr.h:1240
#define ARCH_UNLIKELY(x)
Definition: hints.h:47
TF_API void Tf_PostNullSmartPtrDereferenceFatalError(const TfCallContext &, const char *)
static void AddRef(TfRefBase const *refBase)
Definition: refPtr.h:479
TfRefPtr(const TfRefPtr< T > &p)
Definition: refPtr.h:643
T * get_pointer(PXR_NS::TfRefPtr< T > const &p)
Definition: refPtr.h:1341
static const T * GetRawPtr(const TfRefPtr< const T > &t)
Definition: refPtr.h:1309
TfRefPtr(TfRefPtr< U > &&p)
Definition: refPtr.h:824
A generic, discriminated value, whose type may be queried dynamically.
Definition: Value.h:44
static bool RemoveRef(TfRefBase const *refBase)
Definition: refPtr.h:558
auto operator!=(const TfRefPtr< U > &p) const -> decltype(std::declval< T * >()!=std::declval< U * >(), bool())
Definition: refPtr.h:906
TfRefPtr< T > & operator=(TfRefPtr< U > &&p)
Definition: refPtr.h:872
static TF_API void _AddRefMaybeLocked(TfRefBase const *refBase, int prevCount)
#define TF_FATAL_ERROR
static T * GetRawPtr(const TfRefPtr< T > &t)
Definition: refPtr.h:1291
bool operator!=(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Inequality operator, does exact floating point comparisons.
Definition: Mat3.h:556
const std::type_info & TfTypeid(const TfRefPtr< T > &ptr)
Definition: refPtr.h:1229
friend const std::type_info & TfTypeid(const TfRefPtr< U > &ptr)
static bool AddRefIfNonzero(TfRefBase const *refBase)
Definition: refPtr.h:569
TfRefPtr< typename D::DataType > TfSafeDynamic_cast(const TfRefPtr< T > &ptr)
Definition: refPtr.h:1249
TfRefPtr< typename D::DataType > TfStatic_cast(const TfRefPtr< T > &ptr)
Definition: refPtr.h:1258
TfRefPtr(TfRefPtr< T > &&p)
Definition: refPtr.h:633
void Tf_RefPtrTracker_New(const void *, const void *)
Definition: refPtr.h:470
GLdouble t
Definition: glad.h:2397
friend TfRefPtr< typename D::DataType > TfDynamic_cast(const TfRefPtr< B > &)
bool operator>(const TfRefPtr< T > &p, std::nullptr_t)
Definition: refPtr.h:1200
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
static TF_API bool AddRefIfNonzero(TfRefBase const *refBase)
TfRefPtr(std::nullptr_t)
Implicit conversion from nullptr to TfRefPtr.
Definition: refPtr.h:719
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1432
TfRefPtr< T > & operator=(TfRefPtr< T > &&p)
Definition: refPtr.h:770
static bool IsNull(const TfRefPtr< const T > &t)
Definition: refPtr.h:1317
TfRefPtr()
Definition: refPtr.h:623
void Tf_RefPtrTracker_FirstRef(const void *, const void *)
Definition: refPtr.h:468
auto ptr(T p) -> const void *
Definition: format.h:2448
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
static TfRefPtr< T > ConstructFromRawPtr(T *ptr)
Definition: refPtr.h:1295
friend void TfHashAppend(HashState &, const TfRefPtr< U > &)
void TfHashAppend(HashState &h, const TfRefPtr< T > &ptr)
Definition: refPtr.h:1360
~TfRefPtr()
Definition: refPtr.h:789
T DataType
Convenience type accessor to underlying type T for template code.
Definition: refPtr.h:611
friend TfRefPtr< typename D::DataType > TfStatic_cast(const TfRefPtr< B > &)
bool operator>=(const TfRefPtr< T > &p, std::nullptr_t)
Definition: refPtr.h:1211
TfRefPtr(const TfRefPtr< U > &p)
Definition: refPtr.h:805
friend TfRefPtr< U > TfCreateRefPtrFromProtectedWeakPtr(TfWeakPtr< U > const &)
void Tf_RefPtrTracker_Assign(const void *, const void *, const void *)
Definition: refPtr.h:472
type
Definition: core.h:1059
TfRefPtr< T > & operator=(const TfRefPtr< U > &p)
Definition: refPtr.h:845
static void Class_Object_MUST_Not_Be_Const()
Definition: refPtr.h:1304
T * operator->() const
Accessor to T's public members.
Definition: refPtr.h:948
friend TfRefPtr< typename D::DataType > TfConst_cast(const TfRefPtr< const typename D::DataType > &)
bool operator==(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Equality operator, does exact floating point comparisons.
Definition: Mat3.h:542
void Reset()
Definition: refPtr.h:989
void swap(TfRefPtr &other)
Definition: refPtr.h:979
TfRefPtr< U > Type
Definition: refPtr.h:615