This document is for a version of USD that is under development. See this page for the current release.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
refPtr.h
Go to the documentation of this file.
1//
2// Copyright 2016 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://openusd.org/license.
6//
7#ifndef PXR_BASE_TF_REF_PTR_H
8#define PXR_BASE_TF_REF_PTR_H
9
409
410#include "pxr/pxr.h"
411
413#include "pxr/base/tf/hash.h"
414#include "pxr/base/tf/nullPtr.h"
415#include "pxr/base/tf/refBase.h"
418#include "pxr/base/tf/api.h"
419
420#include "pxr/base/arch/hints.h"
421
422
423#include <typeinfo>
424#include <type_traits>
425#include <cstddef>
426
427PXR_NAMESPACE_OPEN_SCOPE
428
429// Tf_SupportsUniqueChanged is a metafunction that may be specialized to return
430// false for classes (and all derived classes) that *cannot* ever invoke unique
431// changed listeners.
432template <class T>
433struct Tf_SupportsUniqueChanged {
434 static const bool Value = true;
435};
436
437// Remnants are never able to support weak changed listeners.
438class Tf_Remnant;
439template <>
440struct Tf_SupportsUniqueChanged<Tf_Remnant> {
441 static const bool Value = false;
442};
443
444class TfWeakBase;
445
446template <class T> class TfWeakPtr;
447template <template <class> class X, class Y>
448class TfWeakPtrFacade;
449
450// Functions used for tracking. Do not implement these.
451inline void
452Tf_RefPtrTracker_FirstRef(const void*, const TfRefBase *, const void*) { }
453inline void
454Tf_RefPtrTracker_LastRef(const void*, const TfRefBase *, const void*) { }
455inline void
456Tf_RefPtrTracker_New(const void*, const TfRefBase *, const void*) { }
457inline void
458Tf_RefPtrTracker_Delete(const void*, const TfRefBase *, const void*) { }
459inline void
460Tf_RefPtrTracker_Assign(const void*, const TfRefBase *,
461 const TfRefBase *, const void*) { }
462
463// This code is used to increment and decrement ref counts in the common case.
464// It may lock and invoke the unique changed listener, if the reference count
465// becomes unique or non-unique.
466struct Tf_RefPtr_UniqueChangedCounter {
467 static inline void
468 AddRef(TfRefBase const *refBase) {
469 if (ARCH_UNLIKELY(!refBase)) {
470 return;
471 }
472 const auto relaxed = std::memory_order_relaxed;
473 // Read the current count value.
474 std::atomic_int &counter = refBase->_GetRefCount();
475 int prevCount = counter.load(relaxed);
476 if (ARCH_UNLIKELY(prevCount < 0)) {
477 // We need to invoke the unique changed listener if count goes from
478 // -1 -> -2. Try to CAS the value to one more count if it looks
479 // like we won't take it from -1 -> -2. If that works, we're done.
480 // If not, we'll call an out-of-line function that handles the
481 // locking part.
482 if (prevCount != -1 && counter.
483 compare_exchange_weak(prevCount, prevCount-1, relaxed)) {
484 return;
485 }
486 _AddRefMaybeLocked(refBase, prevCount);
487 }
488 else {
489 // Just bump the count.
490 counter.fetch_add(1, relaxed);
491 }
492 }
493
494 static inline bool
495 RemoveRef(TfRefBase const* refBase) {
496 if (ARCH_UNLIKELY(!refBase)) {
497 return false;
498 }
499 const auto relaxed = std::memory_order_relaxed;
500 const auto release = std::memory_order_release;
501 // Read the current count value.
502 std::atomic_int &counter = refBase->_GetRefCount();
503 int prevCount = counter.load(relaxed);
504 if (ARCH_UNLIKELY(prevCount < 0)) {
505 // We need to invoke the unique changed listener if count goes from
506 // -2 -> -1. Try to CAS the value to one less count if it looks
507 // like we won't take it from -2 -> -1. If that works, we're done.
508 // If not, we'll call an out-of-line function that handles the
509 // locking part.
510 if (prevCount != -2 && counter.
511 compare_exchange_weak(prevCount, prevCount+1, release)) {
512 return prevCount == -1;
513 }
514 return _RemoveRefMaybeLocked(refBase, prevCount);
515 }
516 else {
517 // Just drop the count.
518 return counter.fetch_sub(1, release) == 1;
519 }
520 }
521
522 // Increment ptr's count if it is not zero. Return true if done so
523 // successfully, false if its count is zero.
524 TF_API static bool
525 AddRefIfNonzero(TfRefBase const *refBase);
526
527 TF_API static void
528 _AddRefMaybeLocked(TfRefBase const *refBase, int prevCount);
529
530 TF_API static bool
531 _RemoveRefMaybeLocked(TfRefBase const *refBase, int prevCount);
532
533};
534
535// This code is used to increment and decrement ref counts in the case where
536// the object pointed to explicitly does not support unique changed listeners.
537struct Tf_RefPtr_Counter {
538 static inline void
539 AddRef(TfRefBase const *refBase) {
540 if (ARCH_UNLIKELY(!refBase)) {
541 return;
542 }
543 refBase->_GetRefCount().fetch_add(1, std::memory_order_relaxed);
544 }
545
546 static inline bool
547 RemoveRef(TfRefBase const *refBase) {
548 if (ARCH_UNLIKELY(!refBase)) {
549 return false;
550 }
551 return refBase->_GetRefCount()
552 .fetch_sub(1, std::memory_order_release) == 1;
553 }
554
555 // Increment ptr's count if it is not zero. Return true if done so
556 // successfully, false if its count is zero.
557 static inline bool
558 AddRefIfNonzero(TfRefBase const *refBase) {
559 if (ARCH_UNLIKELY(!refBase)) {
560 return false;
561 }
562 auto &counter = refBase->_GetRefCount();
563 int prevCount = counter.load(std::memory_order_relaxed);
564 while (prevCount) {
565 if (counter.compare_exchange_weak(prevCount, prevCount+1)) {
566 return true;
567 }
568 }
569 return false;
570 }
571};
572
573// Helper to post a fatal error when a NULL Tf pointer is dereferenced.
574[[noreturn]]
575TF_API void
576Tf_PostNullSmartPtrDereferenceFatalError(const TfCallContext &, const char *);
577
589template <class T>
590class TfRefPtr {
591 // Select the counter based on whether T supports unique changed listeners.
592 using _Counter = typename std::conditional<
593 Tf_SupportsUniqueChanged<T>::Value &&
594 !std::is_convertible<T*, TfSimpleRefBase*>::value,
595 Tf_RefPtr_UniqueChangedCounter,
596 Tf_RefPtr_Counter>::type;
597
598 static constexpr T *_NullT = nullptr;
599
600public:
602 typedef T DataType;
603
604
605 template <class U> struct Rebind {
606 typedef TfRefPtr<U> Type;
607 };
608
614 TfRefPtr() : _refBase(nullptr) {
615 Tf_RefPtrTracker_New(this, _refBase, _NullT);
616 }
617
624 TfRefPtr(TfRefPtr<T>&& p) : _refBase(p._refBase) {
625 p._refBase = nullptr;
626 Tf_RefPtrTracker_New(this, _refBase, _NullT);
627 Tf_RefPtrTracker_Assign(&p, p._refBase, _refBase, _NullT);
628 }
629
633 TfRefPtr(const TfRefPtr<T>& p) : _refBase(p._refBase) {
634 _AddRef();
635 Tf_RefPtrTracker_New(this, _refBase, _NullT);
636 }
637
641 template <template <class> class X, class U>
642 inline TfRefPtr(const TfWeakPtrFacade<X, U>& p,
643 typename std::enable_if<
644 std::is_convertible<U*, T*>::value
645 >::type * = 0);
646
679#if defined(doxygen)
680 friend inline TfRefPtr TfCreateRefPtr(T*);
681#else
682 template <class U>
683 friend inline TfRefPtr<U> TfCreateRefPtr(U*);
684#endif
685
692 template <class U>
693 explicit TfRefPtr(
694 U* ptr, typename std::enable_if<
695 std::is_convertible<U*, T*>::value>::type * = nullptr) :
696 _refBase(ptr)
697 {
698 _AddRef();
699 Tf_RefPtrTracker_New(this, _refBase, _NullT);
700 }
701
703 TfRefPtr(TfNullPtrType) : _refBase(nullptr)
704 {
705 Tf_RefPtrTracker_New(this, _refBase, _NullT);
706 }
707
709 TfRefPtr(std::nullptr_t) : _refBase(nullptr)
710 {
711 Tf_RefPtrTracker_New(this, _refBase, _NullT);
712 }
713
733 //
734 // It is quite possible for
735 // ptr = TfNullPtr;
736 // to delete the space that ptr actually lives in (this happens
737 // when you use a circular reference to keep an object alive).
738 // To avoid a crash, we have to ensure that deletion of the object
739 // is the last thing done in the assignment; so we use some
740 // local variables to help us out.
741 //
742
743 Tf_RefPtrTracker_Assign(this, p._refBase, _refBase, _NullT);
744
745 const TfRefBase* tmp = _refBase;
746 _refBase = p._refBase;
747
748 p._AddRef(); // first!
749 _RemoveRef(tmp); // second!
750 return *this;
751 }
752
760 // See comment in assignment operator.
761 Tf_RefPtrTracker_Assign(this, p._refBase, _refBase, _NullT);
762 Tf_RefPtrTracker_Assign(&p, nullptr, p._refBase, _NullT);
763
764 const TfRefBase* tmp = _refBase;
765 _refBase = p._refBase;
766 p._refBase = nullptr;
767
768 _RemoveRef(tmp);
769 return *this;
770 }
771
777 Tf_RefPtrTracker_Delete(this, _refBase, _NullT);
778 _RemoveRef(_refBase);
779 }
780
789#if !defined(doxygen)
790 template <class U>
791#endif
792 TfRefPtr(const TfRefPtr<U>& p) : _refBase(p._refBase) {
793 static_assert(std::is_convertible<U*, T*>::value, "");
794 _AddRef();
795 Tf_RefPtrTracker_New(this, _refBase, _NullT);
796 }
797
808#if !defined(doxygen)
809 template <class U>
810#endif
811 TfRefPtr(TfRefPtr<U>&& p) : _refBase(p._refBase) {
812 static_assert(std::is_convertible<U*, T*>::value, "");
813 p._refBase = nullptr;
814 Tf_RefPtrTracker_New(this, _refBase, _NullT);
815 Tf_RefPtrTracker_Assign(&p, p._refBase, _refBase, _NullT);
816 }
817
828#if !defined(doxygen)
829 template <class U>
830#endif
832 static_assert(std::is_convertible<U*, T*>::value, "");
833
834 Tf_RefPtrTracker_Assign(this, p._refBase, _refBase, _NullT);
835 const TfRefBase* tmp = _refBase;
836 _refBase = p._GetData();
837 p._AddRef(); // first!
838 _RemoveRef(tmp); // second!
839 return *this;
840 }
841
853#if !defined(doxygen)
854 template <class U>
855#endif
857 static_assert(std::is_convertible<U*, T*>::value, "");
858
859 Tf_RefPtrTracker_Assign(this, p._refBase, _refBase, _NullT);
860 Tf_RefPtrTracker_Assign(&p, nullptr, p._refBase, _NullT);
861 const TfRefBase* tmp = _refBase;
862 _refBase = p._GetData();
863 p._refBase = nullptr;
864 _RemoveRef(tmp);
865 return *this;
866 }
867
872#if !defined(doxygen)
873 template <class U>
874#endif
875 auto operator==(const TfRefPtr<U>& p) const
876 -> decltype(std::declval<T *>() == std::declval<U *>(), bool()) {
877 return _refBase == p._refBase;
878 }
879
883#if !defined(doxygen)
884 template <class U>
885#endif
886 auto operator!=(const TfRefPtr<U>& p) const
887 -> decltype(std::declval<T *>() != std::declval<U *>(), bool()) {
888 return _refBase != p._refBase;
889 }
890
895#if !defined(doxygen)
896 template <class U>
897#endif
898 auto operator<(const TfRefPtr<U>& p) const
899 -> decltype(std::declval<T *>() < std::declval<U *>(), bool()) {
900 return _refBase < p._refBase;
901 }
902
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#if !defined(doxygen)
912 template <class U>
913#endif
914 auto operator<=(const TfRefPtr<U>& p) const
915 -> decltype(std::declval<T *>() <= std::declval<U *>(), bool()) {
916 return _refBase <= p._refBase;
917 }
918
919#if !defined(doxygen)
920 template <class U>
921#endif
922 auto operator>=(const TfRefPtr<U>& p) const
923 -> decltype(std::declval<T *>() >= std::declval<U *>(), bool()) {
924 return _refBase >= p._refBase;
925 }
926
928 T* operator->() const {
929 if (_refBase) {
930 return static_cast<T*>(const_cast<TfRefBase*>(_refBase));
931 }
932 Tf_PostNullSmartPtrDereferenceFatalError(
933 TF_CALL_CONTEXT, typeid(TfRefPtr).name());
934 }
935
937 T& operator *() const {
938 return *operator->();
939 }
940
941#if !defined(doxygen)
942 using UnspecifiedBoolType = const TfRefBase * (TfRefPtr::*);
943#endif
944
946 operator UnspecifiedBoolType() const {
947 return _refBase ? &TfRefPtr::_refBase : nullptr;
948 }
949
951 bool operator !() const {
952 return _refBase == nullptr;
953 }
954
959 void swap(TfRefPtr &other) {
960 Tf_RefPtrTracker_Assign(this, other._refBase, _refBase, _NullT);
961 Tf_RefPtrTracker_Assign(&other, _refBase, other._refBase, _NullT);
962 std::swap(_refBase, other._refBase);
963 }
964
967 void Reset() {
968 *this = TfNullPtr;
969 }
970
971private:
972 const TfRefBase* _refBase;
973
974 template <class HashState, class U>
975 friend inline void TfHashAppend(HashState &, const TfRefPtr<U>&);
976 template <class U>
977 friend inline size_t hash_value(const TfRefPtr<U>&);
978
979 friend T *get_pointer(TfRefPtr const &p) {
980 return static_cast<T *>(const_cast<TfRefBase *>(p._refBase));
981 }
982
983 // Used to distinguish construction in TfCreateRefPtr.
984 class _CreateRefPtr { };
985
986 // private constructor, used by TfCreateRefPtr()
987 TfRefPtr(T* ptr, _CreateRefPtr /* unused */)
988 : _refBase(ptr)
989 {
990 /* reference count is NOT bumped */
991 Tf_RefPtrTracker_FirstRef(this, _refBase, _NullT);
992 Tf_RefPtrTracker_New(this, _refBase, _NullT);
993 }
994
995 // Hide confusing internals of actual C++ definition (e.g. DataType)
996 // for doxygen output:
997
1013#if defined(doxygen)
1014 // Sanitized for documentation:
1015 template <class D>
1017#else
1018 template <class D, class B>
1021
1022 template <class D, class B>
1025#endif
1026
1043#if defined(doxygen)
1044 // Sanitized for documentation:
1045 template <class D>
1047#else
1048 template <class D, class B>
1050 TfStatic_cast(const TfRefPtr<B>&);
1051
1052#endif
1053
1065#if defined(doxygen)
1066 // Sanitized for documentation:
1067 template <class D>
1069#else
1070 template <class D>
1073#endif
1074
1075 T* _GetData() const {
1076 return static_cast<T*>(const_cast<TfRefBase*>(_refBase));
1077 }
1078
1085
1086 template <class U>
1087 friend const std::type_info& TfTypeid(const TfRefPtr<U>& ptr);
1088
1089 void _AddRef() const {
1090 _Counter::AddRef(_refBase);
1091 }
1092
1093 void _RemoveRef(const TfRefBase* ptr) const {
1094 if (_Counter::RemoveRef(ptr)) {
1095 Tf_RefPtrTracker_LastRef(this, ptr, _NullT);
1096 delete ptr;
1097 }
1098 }
1099
1100#if ! defined(doxygen)
1101 // doxygen is very confused by this. It declares all TfRefPtrs
1102 // to be friends.
1103 template <class U> friend class TfRefPtr;
1104 template <class U> friend class TfWeakPtr;
1105 friend class Tf_Remnant;
1106
1107 template <class U>
1109#endif
1110 friend class TfWeakBase;
1111};
1112
1113#if !defined(doxygen)
1114
1115//
1116// nullptr comparisons
1117//
1118// These are provided to avoid ambiguous overloads due to
1119// TfWeakPtrFacade::Derived comparisons with TfRefPtr.
1120//
1121
1122template <class T>
1123inline bool operator== (const TfRefPtr<T> &p, std::nullptr_t)
1124{
1125 return !p;
1126}
1127template <class T>
1128inline bool operator== (std::nullptr_t, const TfRefPtr<T> &p)
1129{
1130 return !p;
1131}
1132
1133template <class T>
1134inline bool operator!= (const TfRefPtr<T> &p, std::nullptr_t)
1135{
1136 return !(p == nullptr);
1137}
1138template <class T>
1139inline bool operator!= (std::nullptr_t, const TfRefPtr<T> &p)
1140{
1141 return !(nullptr == p);
1142}
1143
1144template <class T>
1145inline bool operator< (const TfRefPtr<T> &p, std::nullptr_t)
1146{
1147 return std::less<const TfRefBase *>()(get_pointer(p), nullptr);
1148}
1149template <class T>
1150inline bool operator< (std::nullptr_t, const TfRefPtr<T> &p)
1151{
1152 return std::less<const TfRefBase *>()(nullptr, get_pointer(p));
1153}
1154
1155template <class T>
1156inline bool operator<= (const TfRefPtr<T> &p, std::nullptr_t)
1157{
1158 return !(nullptr < p);
1159}
1160template <class T>
1161inline bool operator<= (std::nullptr_t, const TfRefPtr<T> &p)
1162{
1163 return !(p < nullptr);
1164}
1165
1166template <class T>
1167inline bool operator> (const TfRefPtr<T> &p, std::nullptr_t)
1168{
1169 return nullptr < p;
1170}
1171template <class T>
1172inline bool operator> (std::nullptr_t, const TfRefPtr<T> &p)
1173{
1174 return p < nullptr;
1175}
1176
1177template <class T>
1178inline bool operator>= (const TfRefPtr<T> &p, std::nullptr_t)
1179{
1180 return !(p < nullptr);
1181}
1182template <class T>
1183inline bool operator>= (std::nullptr_t, const TfRefPtr<T> &p)
1184{
1185 return !(nullptr < p);
1186}
1187
1188
1189template <typename T>
1190inline TfRefPtr<T> TfCreateRefPtr(T* ptr) {
1191 return TfRefPtr<T>(ptr, typename TfRefPtr<T>::_CreateRefPtr());
1192}
1193
1194template <class T>
1195const std::type_info&
1196TfTypeid(const TfRefPtr<T>& ptr)
1197{
1198 if (ARCH_UNLIKELY(!ptr._refBase))
1199 TF_FATAL_ERROR("called TfTypeid on NULL TfRefPtr");
1200
1201 return typeid(*ptr._GetData());
1202}
1203
1204template <class D, class T>
1205inline
1207TfDynamic_cast(const TfRefPtr<T>& ptr)
1208{
1209 typedef TfRefPtr<typename D::DataType> RefPtr;
1210 return RefPtr(dynamic_cast<typename D::DataType*>(ptr._GetData()));
1211}
1212
1213template <class D, class T>
1214inline
1217{
1218 typedef TfRefPtr<typename D::DataType> RefPtr;
1219 return RefPtr(TfSafeDynamic_cast<typename D::DataType*>(ptr._GetData()));
1220}
1221
1222template <class D, class T>
1223inline
1225TfStatic_cast(const TfRefPtr<T>& ptr)
1226{
1227 typedef TfRefPtr<typename D::DataType> RefPtr;
1228 return RefPtr(static_cast<typename D::DataType*>(ptr._GetData()));
1229}
1230
1231template <class T>
1232inline
1234TfConst_cast(const TfRefPtr<const typename T::DataType>& ptr)
1235{
1236 // this ugly cast allows TfConst_cast to work without requiring
1237 // a definition for T.
1238 typedef TfRefPtr<typename T::DataType> NonConstRefPtr;
1239 return *((NonConstRefPtr*)(&ptr));
1240}
1241
1242// Specialization: prevent construction of a TfRefPtr<TfRefBase>.
1243
1244template <>
1245class TfRefPtr<TfRefBase> {
1246private:
1247 TfRefPtr() = delete;
1248};
1249
1250template <>
1251class TfRefPtr<const TfRefBase> {
1252private:
1253 TfRefPtr() = delete;
1254};
1255
1256template <class T>
1257struct TfTypeFunctions<TfRefPtr<T> > {
1258 static T* GetRawPtr(const TfRefPtr<T>& t) {
1259 return t.operator-> ();
1260 }
1261
1262 static TfRefPtr<T> ConstructFromRawPtr(T* ptr) {
1263 return TfRefPtr<T>(ptr);
1264 }
1265
1266 static bool IsNull(const TfRefPtr<T>& t) {
1267 return !t;
1268 }
1269
1270 static void Class_Object_MUST_Be_Passed_By_Address() { }
1271 static void Class_Object_MUST_Not_Be_Const() { }
1272};
1273
1274template <class T>
1275struct TfTypeFunctions<TfRefPtr<const T> > {
1276 static const T* GetRawPtr(const TfRefPtr<const T>& t) {
1277 return t.operator-> ();
1278 }
1279
1280 static TfRefPtr<const T> ConstructFromRawPtr(T* ptr) {
1281 return TfRefPtr<const T>(ptr);
1282 }
1283
1284 static bool IsNull(const TfRefPtr<const T>& t) {
1285 return !t;
1286 }
1287
1288 static void Class_Object_MUST_Be_Passed_By_Address() { }
1289};
1290
1291#endif
1292
1293#if !defined(doxygen)
1294
1295template <class T>
1296inline void
1297swap(TfRefPtr<T>& lhs, TfRefPtr<T>& rhs)
1298{
1299 lhs.swap(rhs);
1300}
1301
1302template <class T>
1303inline size_t
1304hash_value(const TfRefPtr<T>& ptr)
1305{
1306 return TfHash()(ptr);
1307}
1308
1309template <class HashState, class T>
1310inline void
1311TfHashAppend(HashState &h, const TfRefPtr<T> &ptr)
1312{
1313 h.Append(get_pointer(ptr));
1314}
1315
1316#endif // !doxygen
1317
1318#define TF_SUPPORTS_REFPTR(T) std::is_base_of_v<TfRefBase, T>
1319
1320PXR_NAMESPACE_CLOSE_SCOPE
1321
1322#endif // PXR_BASE_TF_REF_PTR_H
A user-extensible hashing mechanism for use with runtime hash tables.
Definition: hash.h:460
Enable a concrete base class for use with TfRefPtr.
Definition: refBase.h:56
Reference-counted smart pointer utility class.
Definition: refPtr.h:590
TfRefPtr< T > & operator=(const TfRefPtr< T > &p)
Assigns pointer to point at p's object, and increments reference count.
Definition: refPtr.h:732
T & operator*() const
Dereferences the stored pointer.
Definition: refPtr.h:937
TfRefPtr< T > & operator=(TfRefPtr< T > &&p)
Moves the pointer managed by p to *this and leaves p pointing at the NULL object.
Definition: refPtr.h:759
auto operator==(const TfRefPtr< U > &p) const -> decltype(std::declval< T * >()==std::declval< U * >(), bool())
Returns true if *this and p point to the same object (or if they both point to NULL).
Definition: refPtr.h:875
friend TfRefPtr< D > TfConst_cast(const TfRefPtr< const D > &)
Allows const casting of a TfRefPtr.
TfRefPtr< T > & operator=(const TfRefPtr< U > &p)
Assigns pointer to point at p's object, and increments reference count.
Definition: refPtr.h:831
void Reset()
Set this pointer to point to no object.
Definition: refPtr.h:967
TfRefPtr(TfRefPtr< T > &&p)
Moves the pointer managed by p to *this.
Definition: refPtr.h:624
friend const std::type_info & TfTypeid(const TfRefPtr< U > &ptr)
Call typeid on the object pointed to by a TfRefPtr.
~TfRefPtr()
Decrements reference count of object being pointed to.
Definition: refPtr.h:776
bool operator!() const
True if the pointer points to NULL.
Definition: refPtr.h:951
void swap(TfRefPtr &other)
Swap this pointer with other.
Definition: refPtr.h:959
TfRefPtr(U *ptr, typename std::enable_if< std::is_convertible< U *, T * >::value >::type *=nullptr)
Initializes to point at *ptr.
Definition: refPtr.h:693
T * operator->() const
Accessor to T's public members.
Definition: refPtr.h:928
friend TfRefPtr TfCreateRefPtr(T *)
Transfer a raw pointer to a reference-counted pointer.
friend TfRefPtr< D > TfStatic_cast(const TfRefPtr< T > &)
Allows static casting of a TfRefPtr.
TfRefPtr(TfNullPtrType)
Implicit conversion from TfNullPtr to TfRefPtr.
Definition: refPtr.h:703
TfRefPtr(const TfRefPtr< T > &p)
Initializes *this to point at p's object.
Definition: refPtr.h:633
TfRefPtr< T > & operator=(TfRefPtr< U > &&p)
Moves the pointer managed by p to *this and leaves p pointing at the NULL object.
Definition: refPtr.h:856
auto operator!=(const TfRefPtr< U > &p) const -> decltype(std::declval< T * >() !=std::declval< U * >(), bool())
Returns true if *this and p do not point to the same object.
Definition: refPtr.h:886
friend TfRefPtr< D > TfDynamic_cast(const TfRefPtr< T > &)
Allows dynamic casting of a TfRefPtr.
TfRefPtr()
Initialize pointer to nullptr.
Definition: refPtr.h:614
TfRefPtr(TfRefPtr< U > &&p)
Moves the pointer managed by p to *this and leaves p pointing at the NULL object.
Definition: refPtr.h:811
TfRefPtr(const TfRefPtr< U > &p)
Initializes to point at p's object, and increments reference count.
Definition: refPtr.h:792
auto operator<(const TfRefPtr< U > &p) const -> decltype(std::declval< T * >()< std::declval< U * >(), bool())
Returns true if the address of the object pointed to by *this compares less than the address of the o...
Definition: refPtr.h:898
TfRefPtr(std::nullptr_t)
Implicit conversion from nullptr to TfRefPtr.
Definition: refPtr.h:709
T DataType
Convenience type accessor to underlying type T for template code.
Definition: refPtr.h:602
Enable a concrete base class for use with TfWeakPtr.
Definition: weakBase.h:124
Pointer storage with deletion detection.
Definition: weakPtr.h:128
Stripped down version of diagnostic.h that doesn't define std::string.
#define TF_FATAL_ERROR(fmt, args)
Issue a fatal error and end the program.
Definition: diagnostic.h:91
Compiler hints.
Safely compare C++ RTTI type structures.
TO TfSafeDynamic_cast(FROM *ptr)
Safely perform a dynamic cast.
Implements assorted functions based on compile-time type information.
Definition: typeFunctions.h:37
size_t hash_value(const TfToken &x)
Overload hash_value for TfToken.
Definition: token.h:437
TfRefPtr< T > TfCreateRefPtrFromProtectedWeakPtr(TfWeakPtr< T > const &p)
Thread-safe creation of a Tf ref pointer from a Tf weak pointer.
Definition: weakPtr.h:260