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
1302PXR_NAMESPACE_CLOSE_SCOPE
1303
1304namespace boost {
1305
1306template<typename T>
1307T *
1308get_pointer(PXR_NS::TfRefPtr<T> const& p)
1309{
1310 return get_pointer(p);
1311}
1312
1313} // end namespace boost
1314
1315PXR_NAMESPACE_OPEN_SCOPE
1316
1317// Extend boost::hash to support TfRefPtr.
1318template <class T>
1319inline size_t
1320hash_value(const TfRefPtr<T>& ptr)
1321{
1322 return TfHash()(ptr);
1323}
1324
1325template <class HashState, class T>
1326inline void
1327TfHashAppend(HashState &h, const TfRefPtr<T> &ptr)
1328{
1329 h.Append(get_pointer(ptr));
1330}
1331
1332#endif // !doxygen
1333
1334#define TF_SUPPORTS_REFPTR(T) std::is_base_of_v<TfRefBase, T>
1335
1336PXR_NAMESPACE_CLOSE_SCOPE
1337
1338#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