24 #ifndef PXR_BASE_TF_REF_PTR_H
25 #define PXR_BASE_TF_REF_PTR_H
441 #include <type_traits>
464 template <
template <
class>
class X,
class Y>
483 const auto relaxed = std::memory_order_relaxed;
486 int prevCount = counter.load(relaxed);
493 if (prevCount != -1 && counter.
494 compare_exchange_weak(prevCount, prevCount-1, relaxed)) {
501 counter.fetch_add(1, relaxed);
510 const auto relaxed = std::memory_order_relaxed;
511 const auto release = std::memory_order_release;
514 int prevCount = counter.load(relaxed);
521 if (prevCount != -2 && counter.
522 compare_exchange_weak(prevCount, prevCount+1, release)) {
523 return prevCount == -1;
529 return counter.fetch_sub(1, release) == 1;
554 refBase->_GetRefCount().fetch_add(1, std::memory_order_relaxed);
562 return refBase->_GetRefCount()
563 .fetch_sub(1, std::memory_order_release) == 1;
573 auto &counter = refBase->_GetRefCount();
574 int prevCount = counter.load(std::memory_order_relaxed);
576 if (counter.compare_exchange_weak(prevCount, prevCount+1)) {
603 using _Counter =
typename std::conditional<
634 p._refBase =
nullptr;
637 _GetObjectForTracking());
651 template <
template <
class>
class X,
class U>
653 typename std::enable_if<
704 U*
ptr,
typename std::enable_if<
754 _GetObjectForTracking());
757 _refBase = p._refBase;
773 _GetObjectForTracking());
775 p._GetObjectForTracking());
778 _refBase = p._refBase;
779 p._refBase =
nullptr;
791 _RemoveRef(_refBase);
802 #if !defined(doxygen)
821 #if !defined(doxygen)
826 p._refBase =
nullptr;
829 _GetObjectForTracking());
842 #if !defined(doxygen)
849 reinterpret_cast<T*>(p._GetObjectForTracking()),
850 _GetObjectForTracking());
852 _refBase = p._GetData();
869 #if !defined(doxygen)
876 reinterpret_cast<T*>(p._GetObjectForTracking()),
877 _GetObjectForTracking());
880 reinterpret_cast<T*>(p._GetObjectForTracking()));
882 _refBase = p._GetData();
883 p._refBase =
nullptr;
892 #if !defined(doxygen)
896 -> decltype(std::declval<T *>() == std::declval<U *>(),
bool()) {
897 return _refBase == p._refBase;
903 #if !defined(doxygen)
907 -> decltype(std::declval<T *>() != std::declval<U *>(),
bool()) {
908 return _refBase != p._refBase;
915 #if !defined(doxygen)
918 auto operator<(const TfRefPtr<U>& p)
const
919 -> decltype(std::declval<T *>() < std::declval<U *>(),
bool()) {
920 return _refBase < p._refBase;
923 #if !defined(doxygen)
927 -> decltype(std::declval<T *>() > std::declval<U *>(),
bool()) {
928 return _refBase > p._refBase;
931 #if !defined(doxygen)
934 auto operator<=(const TfRefPtr<U>& p)
const
935 -> decltype(std::declval<T *>() <= std::declval<U *>(),
bool()) {
936 return _refBase <= p._refBase;
939 #if !defined(doxygen)
943 -> decltype(std::declval<T *>() >= std::declval<U *>(),
bool()) {
944 return _refBase >= p._refBase;
950 return static_cast<T*
>(
const_cast<TfRefBase*
>(_refBase));
961 #if !defined(doxygen)
967 return _refBase ? &TfRefPtr::_refBase :
nullptr;
972 return _refBase ==
nullptr;
981 _GetObjectForTracking());
983 other._GetObjectForTracking());
996 template <
class HashState,
class U>
1002 return static_cast<T *
>(
const_cast<TfRefBase *
>(p._refBase));
1006 class _CreateRefPtr { };
1035 #if defined(doxygen)
1040 template <
class D,
class B>
1044 template <
class D,
class B>
1065 #if defined(doxygen)
1070 template <
class D,
class B>
1087 #if defined(doxygen)
1097 T* _GetData()
const {
1098 return static_cast<T*
>(
const_cast<TfRefBase*
>(_refBase));
1107 T* _GetObjectForTracking()
const {
1108 return reinterpret_cast<T*
>(
const_cast<TfRefBase*
>(_refBase));
1121 void _AddRef()
const {
1122 _Counter::AddRef(_refBase);
1125 void _RemoveRef(
const TfRefBase* ptr)
const {
1126 if (_Counter::RemoveRef(ptr)) {
1128 reinterpret_cast<T*>(const_cast<TfRefBase*>(ptr)));
1133 #if ! defined(doxygen)
1146 #if !defined(doxygen)
1169 return !(p ==
nullptr);
1174 return !(
nullptr == p);
1178 inline bool operator< (const TfRefPtr<T> &p, std::nullptr_t)
1180 return std::less<const TfRefBase *>()(
get_pointer(p),
nullptr);
1183 inline bool operator< (std::nullptr_t, const TfRefPtr<T> &p)
1185 return std::less<const TfRefBase *>()(
nullptr,
get_pointer(p));
1189 inline bool operator<= (const TfRefPtr<T> &p, std::nullptr_t)
1191 return !(
nullptr < p);
1194 inline bool operator<= (std::nullptr_t, const TfRefPtr<T> &p)
1196 return !(p <
nullptr);
1213 return !(p <
nullptr);
1218 return !(
nullptr < p);
1222 template <
typename T>
1228 const std::type_info&
1234 return typeid(*ptr._GetData());
1237 template <
class D,
class T>
1243 return RefPtr(dynamic_cast<typename D::DataType*>(ptr._GetData()));
1246 template <
class D,
class T>
1252 return RefPtr(TfSafeDynamic_cast<typename D::DataType*>(ptr._GetData()));
1255 template <
class D,
class T>
1261 return RefPtr(static_cast<typename D::DataType*>(ptr._GetData()));
1272 return *((NonConstRefPtr*)(&ptr));
1292 return t.operator-> ();
1310 return t.operator-> ();
1326 #if !defined(doxygen)
1339 template<
typename T>
1358 template <
class HashState,
class T>
1367 #define TF_SUPPORTS_REFPTR(T) std::is_base_of_v<TfRefBase, T>
1371 #endif // PXR_BASE_TF_REF_PTR_H
void swap(ArAssetInfo &lhs, ArAssetInfo &rhs)
static void Class_Object_MUST_Be_Passed_By_Address()
auto operator==(const TfRefPtr< U > &p) const -> decltype(std::declval< T * >()==std::declval< U * >(), bool())
static TF_API bool _RemoveRefMaybeLocked(TfRefBase const *refBase, int prevCount)
TfRefPtr< T > TfCreateRefPtr(T *ptr)
PXR_NAMESPACE_OPEN_SCOPE size_t hash_value(const TfRefPtr< T > &ptr)
TfRefPtr< typename T::DataType > TfConst_cast(const TfRefPtr< const typename T::DataType > &ptr)
static TfRefPtr< const T > ConstructFromRawPtr(T *ptr)
friend size_t hash_value(const TfRefPtr< U > &)
TfRefPtr(TfNullPtrType)
Implicit conversion from TfNullPtr to TfRefPtr.
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)
auto operator>=(const TfRefPtr< U > &p) const -> decltype(std::declval< T * >() >=std::declval< U * >(), bool())
GLsizei const GLfloat * value
const TfRefBase *(TfRefPtr::*) UnspecifiedBoolType
static bool IsNull(const TfRefPtr< T > &t)
TF_API const TfNullPtrType TfNullPtr
auto operator>(const TfRefPtr< U > &p) const -> decltype(std::declval< T * >() > std::declval< U * >(), bool())
static void Class_Object_MUST_Be_Passed_By_Address()
void Tf_RefPtrTracker_LastRef(const void *, const void *)
friend T * get_pointer(TfRefPtr const &p)
friend TfRefPtr< U > TfCreateRefPtr(U *)
static void AddRef(TfRefBase const *refBase)
TfRefPtr< T > & operator=(const TfRefPtr< T > &p)
Y * get_pointer(TfWeakPtrFacade< X, Y > const &p)
bool operator!() const
True if the pointer points to NULL.
friend TfRefPtr< typename D::DataType > TfSafeDynamic_cast(const TfRefPtr< B > &)
void Tf_RefPtrTracker_Delete(const void *, const void *)
TfRefPtr(U *ptr, typename std::enable_if< std::is_convertible< U *, T * >::value >::type *=nullptr)
T & operator*() const
Dereferences the stored pointer.
static bool RemoveRef(TfRefBase const *refBase)
TfRefPtr< typename D::DataType > TfDynamic_cast(const TfRefPtr< T > &ptr)
TF_API void Tf_PostNullSmartPtrDereferenceFatalError(const TfCallContext &, const char *)
static void AddRef(TfRefBase const *refBase)
TfRefPtr(const TfRefPtr< T > &p)
T * get_pointer(PXR_NS::TfRefPtr< T > const &p)
static const T * GetRawPtr(const TfRefPtr< const T > &t)
TfRefPtr(TfRefPtr< U > &&p)
A generic, discriminated value, whose type may be queried dynamically.
static bool RemoveRef(TfRefBase const *refBase)
auto operator!=(const TfRefPtr< U > &p) const -> decltype(std::declval< T * >()!=std::declval< U * >(), bool())
TfRefPtr< T > & operator=(TfRefPtr< U > &&p)
static TF_API void _AddRefMaybeLocked(TfRefBase const *refBase, int prevCount)
static T * GetRawPtr(const TfRefPtr< T > &t)
bool operator!=(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Inequality operator, does exact floating point comparisons.
const std::type_info & TfTypeid(const TfRefPtr< T > &ptr)
friend const std::type_info & TfTypeid(const TfRefPtr< U > &ptr)
static bool AddRefIfNonzero(TfRefBase const *refBase)
TfRefPtr< typename D::DataType > TfSafeDynamic_cast(const TfRefPtr< T > &ptr)
TfRefPtr< typename D::DataType > TfStatic_cast(const TfRefPtr< T > &ptr)
TfRefPtr(TfRefPtr< T > &&p)
void Tf_RefPtrTracker_New(const void *, const void *)
friend TfRefPtr< typename D::DataType > TfDynamic_cast(const TfRefPtr< B > &)
bool operator>(const TfRefPtr< T > &p, std::nullptr_t)
GLfloat GLfloat GLfloat GLfloat h
static TF_API bool AddRefIfNonzero(TfRefBase const *refBase)
TfRefPtr(std::nullptr_t)
Implicit conversion from nullptr to TfRefPtr.
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
TfRefPtr< T > & operator=(TfRefPtr< T > &&p)
static bool IsNull(const TfRefPtr< const T > &t)
void Tf_RefPtrTracker_FirstRef(const void *, const void *)
#define PXR_NAMESPACE_CLOSE_SCOPE
static TfRefPtr< T > ConstructFromRawPtr(T *ptr)
friend void TfHashAppend(HashState &, const TfRefPtr< U > &)
void TfHashAppend(HashState &h, const TfRefPtr< T > &ptr)
T DataType
Convenience type accessor to underlying type T for template code.
friend TfRefPtr< typename D::DataType > TfStatic_cast(const TfRefPtr< B > &)
bool operator>=(const TfRefPtr< T > &p, std::nullptr_t)
TfRefPtr(const TfRefPtr< U > &p)
friend TfRefPtr< U > TfCreateRefPtrFromProtectedWeakPtr(TfWeakPtr< U > const &)
void Tf_RefPtrTracker_Assign(const void *, const void *, const void *)
TfRefPtr< T > & operator=(const TfRefPtr< U > &p)
static void Class_Object_MUST_Not_Be_Const()
T * operator->() const
Accessor to T's public members.
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.
void swap(TfRefPtr &other)