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 TF_REFPTR_H
25 #define TF_REFPTR_H
26 
426 
427 #include "pxr/pxr.h"
428 
429 #include "pxr/base/tf/diagnosticLite.h"
430 #include "pxr/base/tf/nullPtr.h"
431 #include "pxr/base/tf/refBase.h"
432 #include "pxr/base/tf/safeTypeCompare.h"
433 #include "pxr/base/tf/typeFunctions.h"
434 #include "pxr/base/tf/api.h"
435 
436 #include "pxr/base/arch/hints.h"
437 
438 #include <boost/functional/hash_fwd.hpp>
439 #include <boost/mpl/if.hpp>
440 #include <boost/type_traits/is_base_of.hpp>
441 #include <boost/type_traits/is_convertible.hpp>
442 #include <boost/type_traits/is_same.hpp>
443 #include <boost/utility/enable_if.hpp>
444 
445 #include <typeinfo>
446 #include <type_traits>
447 #include <cstddef>
448 
449 PXR_NAMESPACE_OPEN_SCOPE
450 
451 // Tf_SupportsUniqueChanged is a metafunction that may be specialized to return
452 // false for classes (and all derived classes) that *cannot* ever invoke unique
453 // changed listeners.
454 template <class T>
455 struct Tf_SupportsUniqueChanged {
456  static const bool Value = true;
457 };
458 
459 // Remnants are never able to support weak changed listeners.
460 class Tf_Remnant;
461 template <>
462 struct Tf_SupportsUniqueChanged<Tf_Remnant> {
463  static const bool Value = false;
464 };
465 
466 class TfHash;
467 class TfWeakBase;
468 
469 template <class T> class TfWeakPtr;
470 template <template <class> class X, class Y>
471 class TfWeakPtrFacade;
472 
473 // Functions used for tracking. Do not implement these.
474 inline void Tf_RefPtrTracker_FirstRef(const void*, const void*) { }
475 inline void Tf_RefPtrTracker_LastRef(const void*, const void*) { }
476 inline void Tf_RefPtrTracker_New(const void*, const void*) { }
477 inline void Tf_RefPtrTracker_Delete(const void*, const void*) { }
478 inline void Tf_RefPtrTracker_Assign(const void*, const void*, const void*) { }
479 
480 // This code is used to increment and decrement ref counts in the common case.
481 // It may lock and invoke the unique changed listener, if the reference count
482 // becomes unique or non-unique.
483 struct Tf_RefPtr_UniqueChangedCounter {
484  static inline int
485  AddRef(TfRefBase const *refBase)
486  {
487  if (refBase) {
488  // Check to see if we need to invoke the unique changed listener.
489  if (refBase->_shouldInvokeUniqueChangedListener)
490  return _AddRef(refBase);
491  else
492  return refBase->GetRefCount()._FetchAndAdd(1);
493  }
494  return 0;
495  }
496 
497  static inline bool
498  RemoveRef(TfRefBase const* refBase) {
499  if (refBase) {
500  // Check to see if we need to invoke the unique changed listener.
501  return refBase->_shouldInvokeUniqueChangedListener ?
502  _RemoveRef(refBase) :
503  refBase->GetRefCount()._DecrementAndTestIfZero();
504  }
505  return false;
506  }
507 
508  // Increment ptr's count if it is not zero. Return true if done so
509  // successfully, false if its count is zero.
510  static inline bool
511  AddRefIfNonzero(TfRefBase const *ptr) {
512  if (!ptr)
513  return false;
514  if (ptr->_shouldInvokeUniqueChangedListener) {
515  return _AddRefIfNonzero(ptr);
516  } else {
517  auto &counter = ptr->GetRefCount()._counter;
518  auto val = counter.load();
519  do {
520  if (val == 0)
521  return false;
522  } while (!counter.compare_exchange_weak(val, val + 1));
523  return true;
524  }
525  }
526 
527  TF_API static bool _RemoveRef(TfRefBase const *refBase);
528 
529  TF_API static int _AddRef(TfRefBase const *refBase);
530 
531  TF_API static bool _AddRefIfNonzero(TfRefBase const *refBase);
532 };
533 
534 // This code is used to increment and decrement ref counts in the case where
535 // the object pointed to explicitly does not support unique changed listeners.
536 struct Tf_RefPtr_Counter {
537  static inline int
538  AddRef(TfRefBase const *refBase) {
539  if (refBase)
540  return refBase->GetRefCount()._FetchAndAdd(1);
541  return 0;
542  }
543 
544  static inline bool
545  RemoveRef(TfRefBase const *ptr) {
546  return (ptr && (ptr->GetRefCount()._DecrementAndTestIfZero()));
547  }
548 
549  // Increment ptr's count if it is not zero. Return true if done so
550  // successfully, false if its count is zero.
551  static inline bool
552  AddRefIfNonzero(TfRefBase const *ptr) {
553  if (!ptr)
554  return false;
555  auto &counter = ptr->GetRefCount()._counter;
556  auto val = counter.load();
557  do {
558  if (val == 0)
559  return false;
560  } while (!counter.compare_exchange_weak(val, val + 1));
561  return true;
562  }
563 };
564 
565 // Helper to post a fatal error when a NULL Tf pointer is dereferenced.
566 [[noreturn]]
567 TF_API void
568 Tf_PostNullSmartPtrDereferenceFatalError(
569  const TfCallContext &, const std::type_info &);
570 
582 template <class T>
583 class TfRefPtr {
584  // Select the counter based on whether T supports unique changed listeners.
585  typedef typename boost::mpl::if_c<
586  Tf_SupportsUniqueChanged<T>::Value &&
587  !boost::is_convertible<T*, TfSimpleRefBase*>::value,
588  Tf_RefPtr_UniqueChangedCounter,
589  Tf_RefPtr_Counter>::type _Counter;
590 
591 public:
593  typedef T DataType;
594 
595 
596  template <class U> struct Rebind {
597  typedef TfRefPtr<U> Type;
598  };
599 
605  TfRefPtr() : _refBase(nullptr) {
606  Tf_RefPtrTracker_New(this, _GetObjectForTracking());
607  }
608 
615  TfRefPtr(TfRefPtr<T>&& p) : _refBase(p._refBase) {
616  p._refBase = nullptr;
617  Tf_RefPtrTracker_New(this, _GetObjectForTracking());
618  Tf_RefPtrTracker_Assign(&p, p._GetObjectForTracking(),
619  _GetObjectForTracking());
620  }
621 
625  TfRefPtr(const TfRefPtr<T>& p) : _refBase(p._refBase) {
626  _AddRef();
627  Tf_RefPtrTracker_New(this, _GetObjectForTracking());
628  }
629 
633  template <template <class> class X, class U>
634  inline TfRefPtr(const TfWeakPtrFacade<X, U>& p,
635  typename boost::enable_if<
636  boost::is_convertible<U*, T*>
637  >::type *dummy = 0);
638 
671 #if defined(doxygen)
672  friend inline TfRefPtr TfCreateRefPtr(T*);
673 #else
674  template <class U>
675  friend inline TfRefPtr<U> TfCreateRefPtr(U*);
676 #endif
677 
684  template <class U>
685  explicit TfRefPtr(
686  U* ptr, typename std::enable_if<
687  std::is_convertible<U*, T*>::value>::type * = nullptr) :
688  _refBase(ptr)
689  {
690  _AddRef();
691  Tf_RefPtrTracker_New(this, _GetObjectForTracking());
692  }
693 
695  TfRefPtr(TfNullPtrType) : _refBase(nullptr)
696  {
697  Tf_RefPtrTracker_New(this, _GetObjectForTracking());
698  }
699 
701  TfRefPtr(std::nullptr_t) : _refBase(nullptr)
702  {
703  Tf_RefPtrTracker_New(this, _GetObjectForTracking());
704  }
705 
725  //
726  // It is quite possible for
727  // ptr = TfNullPtr;
728  // to delete the space that ptr actually lives in (this happens
729  // when you use a circular reference to keep an object alive).
730  // To avoid a crash, we have to ensure that deletion of the object
731  // is the last thing done in the assignment; so we use some
732  // local variables to help us out.
733  //
734 
735  Tf_RefPtrTracker_Assign(this, p._GetObjectForTracking(),
736  _GetObjectForTracking());
737 
738  const TfRefBase* tmp = _refBase;
739  _refBase = p._refBase;
740 
741  p._AddRef(); // first!
742  _RemoveRef(tmp); // second!
743  return *this;
744  }
745 
753  // See comment in assignment operator.
754  Tf_RefPtrTracker_Assign(this, p._GetObjectForTracking(),
755  _GetObjectForTracking());
756  Tf_RefPtrTracker_Assign(&p, nullptr,
757  p._GetObjectForTracking());
758 
759  const TfRefBase* tmp = _refBase;
760  _refBase = p._refBase;
761  p._refBase = nullptr;
762 
763  _RemoveRef(tmp);
764  return *this;
765  }
766 
772  Tf_RefPtrTracker_Delete(this, _GetObjectForTracking());
773  _RemoveRef(_refBase);
774  }
775 
776 private:
777 
778  // Compile error if a U* cannot be assigned to a T*.
779  template <class U>
780  static void _CheckTypeAssignability() {
781  T* unused = (U*)0;
782  if (unused) unused = 0;
783  }
784 
785  // Compile error if a T* and U* cannot be compared.
786  template <class U>
787  static void _CheckTypeComparability() {
788  bool unused = ((T*)0 == (U*)0);
789  if (unused) unused = false;
790  }
791 
792 public:
793 
802 #if !defined(doxygen)
803  template <class U>
804 #endif
805  TfRefPtr(const TfRefPtr<U>& p) : _refBase(p._refBase) {
806  if (!boost::is_same<T,U>::value) {
807  if (false)
808  _CheckTypeAssignability<U>();
809  }
810 
811  _AddRef();
812  Tf_RefPtrTracker_New(this, _GetObjectForTracking());
813  }
814 
825 #if !defined(doxygen)
826  template <class U>
827 #endif
828  TfRefPtr(TfRefPtr<U>&& p) : _refBase(p._refBase) {
829  if (!boost::is_same<T,U>::value) {
830  if (false)
831  _CheckTypeAssignability<U>();
832  }
833 
834  p._refBase = nullptr;
835  Tf_RefPtrTracker_New(this, _GetObjectForTracking());
836  Tf_RefPtrTracker_Assign(&p, p._GetObjectForTracking(),
837  _GetObjectForTracking());
838  }
839 
850 #if !defined(doxygen)
851  template <class U>
852 #endif
854  if (!boost::is_same<T,U>::value) {
855  if (false)
856  _CheckTypeAssignability<U>();
857  }
858 
859  Tf_RefPtrTracker_Assign(this,
860  reinterpret_cast<T*>(p._GetObjectForTracking()),
861  _GetObjectForTracking());
862  const TfRefBase* tmp = _refBase;
863  _refBase = p._GetData();
864  p._AddRef(); // first!
865  _RemoveRef(tmp); // second!
866  return *this;
867  }
868 
880 #if !defined(doxygen)
881  template <class U>
882 #endif
884  if (!boost::is_same<T,U>::value) {
885  if (false)
886  _CheckTypeAssignability<U>();
887  }
888 
889  Tf_RefPtrTracker_Assign(this,
890  reinterpret_cast<T*>(p._GetObjectForTracking()),
891  _GetObjectForTracking());
892  Tf_RefPtrTracker_Assign(&p,
893  nullptr,
894  reinterpret_cast<T*>(p._GetObjectForTracking()));
895  const TfRefBase* tmp = _refBase;
896  _refBase = p._GetData();
897  p._refBase = nullptr;
898  _RemoveRef(tmp);
899  return *this;
900  }
901 
906 #if !defined(doxygen)
907  template <class U>
908 #endif
909  bool operator== (const TfRefPtr<U>& p) const {
910  if (false)
911  _CheckTypeComparability<U>();
912 
913  return _refBase == p._refBase;
914  }
915 
920 #if !defined(doxygen)
921  template <class U>
922 #endif
923  bool operator< (const TfRefPtr<U>& p) const {
924  if (false)
925  _CheckTypeComparability<U>();
926 
927  return _refBase < p._refBase;
928  }
929 
930 #if !defined(doxygen)
931  template <class U>
932 #endif
933  bool operator> (const TfRefPtr<U>& p) const {
934  if (false)
935  _CheckTypeComparability<U>();
936 
937  return _refBase > p._refBase;
938  }
939 
940 #if !defined(doxygen)
941  template <class U>
942 #endif
943  bool operator<= (const TfRefPtr<U>& p) const {
944  if (false)
945  _CheckTypeComparability<U>();
946 
947  return _refBase <= p._refBase;
948  }
949 
950 #if !defined(doxygen)
951  template <class U>
952 #endif
953  bool operator>= (const TfRefPtr<U>& p) const {
954  if (false)
955  _CheckTypeComparability<U>();
956 
957  return _refBase >= p._refBase;
958  }
959 
963 #if !defined(doxygen)
964  template <class U>
965 #endif
966  bool operator!= (const TfRefPtr<U>& p) const {
967  if (false)
968  _CheckTypeComparability<U>();
969 
970  return _refBase != p._refBase;
971  }
972 
974  T* operator ->() const {
975  if (ARCH_LIKELY(_refBase)) {
976  return static_cast<T*>(const_cast<TfRefBase*>(_refBase));
977  }
978  static const TfCallContext ctx(TF_CALL_CONTEXT);
979  Tf_PostNullSmartPtrDereferenceFatalError(ctx, typeid(TfRefPtr));
980  }
981 
983  T& operator *() const {
984  return *operator->();
985  }
986 
987 #if !defined(doxygen)
988  using UnspecifiedBoolType = const TfRefBase * (TfRefPtr::*);
989 #endif
990 
992  operator UnspecifiedBoolType() const {
993  return _refBase ? &TfRefPtr::_refBase : nullptr;
994  }
995 
997  bool operator !() const {
998  return _refBase == nullptr;
999  }
1000 
1005  void swap(TfRefPtr &other) {
1006  Tf_RefPtrTracker_Assign(this, other._GetObjectForTracking(),
1007  _GetObjectForTracking());
1008  Tf_RefPtrTracker_Assign(&other, _GetObjectForTracking(),
1009  other._GetObjectForTracking());
1010  std::swap(_refBase, other._refBase);
1011  }
1012 
1015  void Reset() {
1016  *this = TfNullPtr;
1017  }
1018 
1019 private:
1020  const TfRefBase* _refBase;
1021 
1022  friend class TfHash;
1023  template <class U>
1024  friend inline size_t hash_value(const TfRefPtr<U>&);
1025 
1026  friend T *get_pointer(TfRefPtr const &p) {
1027  return static_cast<T *>(const_cast<TfRefBase *>(p._refBase));
1028  }
1029 
1030  // Used to distinguish construction in TfCreateRefPtr.
1031  class _CreateRefPtr { };
1032 
1033  // private constructor, used by TfCreateRefPtr()
1034  TfRefPtr(T* ptr, _CreateRefPtr /* unused */)
1035  : _refBase(ptr)
1036  {
1037  /* reference count is NOT bumped */
1038  Tf_RefPtrTracker_FirstRef(this, _GetObjectForTracking());
1039  Tf_RefPtrTracker_New(this, _GetObjectForTracking());
1040  }
1041 
1042  // Hide confusing internals of actual C++ definition (e.g. DataType)
1043  // for doxygen output:
1044 
1060 #if defined(doxygen)
1061  // Sanitized for documentation:
1062  template <class D>
1063  friend inline TfRef<D> TfDynamic_cast(const TfRefPtr<T>&);
1064 #else
1065  template <class D, class B>
1067  TfDynamic_cast(const TfRefPtr<B>&);
1068 
1069  template <class D, class B>
1072 #endif
1073 
1090 #if defined(doxygen)
1091  // Sanitized for documentation:
1092  template <class D>
1093  friend inline TfRefPtr<D> TfStatic_cast(const TfRefPtr<T>&);
1094 #else
1095  template <class D, class B>
1097  TfStatic_cast(const TfRefPtr<B>&);
1098 
1099 #endif
1100 
1112 #if defined(doxygen)
1113  // Sanitized for documentation:
1114  template <class D>
1115  friend inline TfRefPtr<D> TfConst_cast(const TfRefPtr<const D>&);
1116 #else
1117  template <class D>
1120 #endif
1121 
1122  T* _GetData() const {
1123  return static_cast<T*>(const_cast<TfRefBase*>(_refBase));
1124  }
1125 
1126  // This method is only used when calling the hook functions for
1127  // tracking. We reinterpret_cast instead of static_cast so that
1128  // we don't need the definition of T. However, if TfRefBase is
1129  // not the first base class of T then the resulting pointer may
1130  // not point to a T. Nevertheless, it should be consistent to
1131  // all calls to the tracking functions.
1132  T* _GetObjectForTracking() const {
1133  return reinterpret_cast<T*>(const_cast<TfRefBase*>(_refBase));
1134  }
1135 
1142 
1143  template <class U>
1144  friend const std::type_info& TfTypeid(const TfRefPtr<U>& ptr);
1145 
1146  void _AddRef() const {
1147  _Counter::AddRef(_refBase);
1148  }
1149 
1150  void _RemoveRef(const TfRefBase* ptr) const {
1151  if (_Counter::RemoveRef(ptr)) {
1152  Tf_RefPtrTracker_LastRef(this,
1153  reinterpret_cast<T*>(const_cast<TfRefBase*>(ptr)));
1154  delete ptr;
1155  }
1156  }
1157 
1158 #if ! defined(doxygen)
1159  // doxygen is very confused by this. It declares all TfRefPtrs
1160  // to be friends.
1161  template <class U> friend class TfRefPtr;
1162  template <class U> friend class TfWeakPtr;
1163  friend class Tf_Remnant;
1164 
1165  template <class U>
1167 #endif
1168  friend class TfWeakBase;
1169 };
1170 
1171 #if !defined(doxygen)
1172 
1173 //
1174 // nullptr comparisons
1175 //
1176 // These are provided to avoid ambiguous overloads due to
1177 // TfWeakPtrFacade::Derived comparisons with TfRefPtr.
1178 //
1179 
1180 template <class T>
1181 inline bool operator== (const TfRefPtr<T> &p, std::nullptr_t)
1182 {
1183  return !p;
1184 }
1185 template <class T>
1186 inline bool operator== (std::nullptr_t, const TfRefPtr<T> &p)
1187 {
1188  return !p;
1189 }
1190 
1191 template <class T>
1192 inline bool operator!= (const TfRefPtr<T> &p, std::nullptr_t)
1193 {
1194  return !(p == nullptr);
1195 }
1196 template <class T>
1197 inline bool operator!= (std::nullptr_t, const TfRefPtr<T> &p)
1198 {
1199  return !(nullptr == p);
1200 }
1201 
1202 template <class T>
1203 inline bool operator< (const TfRefPtr<T> &p, std::nullptr_t)
1204 {
1205  return std::less<const TfRefBase *>()(get_pointer(p), nullptr);
1206 }
1207 template <class T>
1208 inline bool operator< (std::nullptr_t, const TfRefPtr<T> &p)
1209 {
1210  return std::less<const TfRefBase *>()(nullptr, get_pointer(p));
1211 }
1212 
1213 template <class T>
1214 inline bool operator<= (const TfRefPtr<T> &p, std::nullptr_t)
1215 {
1216  return !(nullptr < p);
1217 }
1218 template <class T>
1219 inline bool operator<= (std::nullptr_t, const TfRefPtr<T> &p)
1220 {
1221  return !(p < nullptr);
1222 }
1223 
1224 template <class T>
1225 inline bool operator> (const TfRefPtr<T> &p, std::nullptr_t)
1226 {
1227  return nullptr < p;
1228 }
1229 template <class T>
1230 inline bool operator> (std::nullptr_t, const TfRefPtr<T> &p)
1231 {
1232  return p < nullptr;
1233 }
1234 
1235 template <class T>
1236 inline bool operator>= (const TfRefPtr<T> &p, std::nullptr_t)
1237 {
1238  return !(p < nullptr);
1239 }
1240 template <class T>
1241 inline bool operator>= (std::nullptr_t, const TfRefPtr<T> &p)
1242 {
1243  return !(nullptr < p);
1244 }
1245 
1246 
1247 template <typename T>
1248 inline TfRefPtr<T> TfCreateRefPtr(T* ptr) {
1249  return TfRefPtr<T>(ptr, typename TfRefPtr<T>::_CreateRefPtr());
1250 }
1251 
1252 template <class T>
1253 const std::type_info&
1254 TfTypeid(const TfRefPtr<T>& ptr)
1255 {
1256  if (ARCH_UNLIKELY(!ptr._refBase))
1257  TF_FATAL_ERROR("called TfTypeid on NULL TfRefPtr");
1258 
1259  return typeid(*ptr._GetData());
1260 }
1261 
1262 template <class D, class T>
1263 inline
1265 TfDynamic_cast(const TfRefPtr<T>& ptr)
1266 {
1267  typedef TfRefPtr<typename D::DataType> RefPtr;
1268  return RefPtr(dynamic_cast<typename D::DataType*>(ptr._GetData()));
1269 }
1270 
1271 template <class D, class T>
1272 inline
1274 TfSafeDynamic_cast(const TfRefPtr<T>& ptr)
1275 {
1276  typedef TfRefPtr<typename D::DataType> RefPtr;
1277  return RefPtr(TfSafeDynamic_cast<typename D::DataType*>(ptr._GetData()));
1278 }
1279 
1280 template <class D, class T>
1281 inline
1283 TfStatic_cast(const TfRefPtr<T>& ptr)
1284 {
1285  typedef TfRefPtr<typename D::DataType> RefPtr;
1286  return RefPtr(static_cast<typename D::DataType*>(ptr._GetData()));
1287 }
1288 
1289 template <class T>
1290 inline
1292 TfConst_cast(const TfRefPtr<const typename T::DataType>& ptr)
1293 {
1294  // this ugly cast allows TfConst_cast to work without requiring
1295  // a definition for T.
1296  typedef TfRefPtr<typename T::DataType> NonConstRefPtr;
1297  return *((NonConstRefPtr*)(&ptr));
1298 }
1299 
1300 // Specialization: prevent construction of a TfRefPtr<TfRefBase>.
1301 
1302 template <>
1303 class TfRefPtr<TfRefBase> {
1304 private:
1306  }
1307 };
1308 
1309 template <>
1310 class TfRefPtr<const TfRefBase> {
1311 private:
1313  }
1314 };
1315 
1316 template <class T>
1317 struct TfTypeFunctions<TfRefPtr<T> > {
1318  static T* GetRawPtr(const TfRefPtr<T>& t) {
1319  return t.operator-> ();
1320  }
1321 
1322  static TfRefPtr<T> ConstructFromRawPtr(T* ptr) {
1323  return TfRefPtr<T>(ptr);
1324  }
1325 
1326  static bool IsNull(const TfRefPtr<T>& t) {
1327  return !t;
1328  }
1329 
1330  static void Class_Object_MUST_Be_Passed_By_Address() { }
1331  static void Class_Object_MUST_Not_Be_Const() { }
1332 };
1333 
1334 template <class T>
1335 struct TfTypeFunctions<TfRefPtr<const T> > {
1336  static const T* GetRawPtr(const TfRefPtr<const T>& t) {
1337  return t.operator-> ();
1338  }
1339 
1340  static TfRefPtr<const T> ConstructFromRawPtr(T* ptr) {
1341  return TfRefPtr<const T>(ptr);
1342  }
1343 
1344  static bool IsNull(const TfRefPtr<const T>& t) {
1345  return !t;
1346  }
1347 
1348  static void Class_Object_MUST_Be_Passed_By_Address() { }
1349 };
1350 
1351 #endif
1352 
1353 #if !defined(doxygen)
1354 
1355 template <class T>
1356 inline void
1357 swap(TfRefPtr<T>& lhs, TfRefPtr<T>& rhs)
1358 {
1359  lhs.swap(rhs);
1360 }
1361 
1362 PXR_NAMESPACE_CLOSE_SCOPE
1363 
1364 namespace boost {
1365 
1366 template<typename T>
1367 T *
1368 get_pointer(PXR_NS::TfRefPtr<T> const& p)
1369 {
1370  return get_pointer(p);
1371 }
1372 
1373 } // end namespace boost
1374 
1375 PXR_NAMESPACE_OPEN_SCOPE
1376 
1377 // Extend boost::hash to support TfRefPtr.
1378 template <class T>
1379 inline size_t
1380 hash_value(const TfRefPtr<T>& ptr)
1381 {
1382  // Make the boost::hash type depend on T so that we don't have to always
1383  // include boost/functional/hash.hpp in this header for the definition of
1384  // boost::hash.
1385  auto refBase = ptr._refBase;
1386  return boost::hash<decltype(refBase)>()(refBase);
1387 }
1388 
1389 #endif // !doxygen
1390 
1391 #define TF_SUPPORTS_REFPTR(T) boost::is_base_of<TfRefBase, T >::value
1392 
1393 #if defined(ARCH_COMPILER_MSVC)
1394 // There is a bug in the compiler which means we have to provide this
1395 // implementation. See here for more information:
1396 // https://connect.microsoft.com/VisualStudio/Feedback/Details/2852624
1397 
1398 #define TF_REFPTR_CONST_VOLATILE_GET(x) \
1399  namespace boost \
1400  { \
1401  template<> \
1402  const volatile x* \
1403  get_pointer(const volatile x* p) \
1404  { \
1405  return p; \
1406  } \
1407  }
1408 #else
1409 #define TF_REFPTR_CONST_VOLATILE_GET(x)
1410 #endif
1411 
1412 PXR_NAMESPACE_CLOSE_SCOPE
1413 
1414 #endif // TF_REFPTR_H
void swap(ArAssetInfo &lhs, ArAssetInfo &rhs)
Definition: assetInfo.h:60
TfRefPtr(std::nullptr_t)
Implicit conversion from nullptr to TfRefPtr.
Definition: refPtr.h:701
TfRefPtr()
Initialize pointer to nullptr.
Definition: refPtr.h:605
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:883
bool operator!() const
True if the pointer points to NULL.
Definition: refPtr.h:997
TfRefPtr(TfRefPtr< T > &&p)
Moves the pointer managed by p to *this.
Definition: refPtr.h:615
TfRefPtr< T > TfCreateRefPtrFromProtectedWeakPtr(TfWeakPtr< T > const &p)
Thread-safe creation of a Tf ref pointer from a Tf weak pointer.
Definition: weakPtr.h:262
TO TfSafeDynamic_cast(FROM *ptr)
Safely perform a dynamic cast.
void Reset()
Set this pointer to point to no object.
Definition: refPtr.h:1015
TfRefPtr(TfRefPtr< U > &&p)
Moves the pointer managed by p to *this and leaves p pointing at the NULL object. ...
Definition: refPtr.h:828
friend TfRef< D > TfDynamic_cast(const TfRefPtr< T > &)
Allows dynamic casting of a TfRefPtr.
TfRefPtr< T > & operator=(const TfRefPtr< U > &p)
Assigns pointer to point at p&#39;s object, and increments reference count.
Definition: refPtr.h:853
SdfHandle< typename DST::SpecType > TfStatic_cast(const SdfHandle< SRC > &x)
Convert SdfHandle&lt;SRC&gt; x to an SdfHandle&lt;DST&gt;.
AR_API bool operator!=(const ArAssetInfo &lhs, const ArAssetInfo &rhs)
T DataType
Convenience type accessor to underlying type T for template code.
Definition: refPtr.h:593
void swap(TfRefPtr &other)
Swap this pointer with other.
Definition: refPtr.h:1005
bool operator==(const TfRefPtr< U > &p) const
Returns true if *this and p point to the same object (or if they both point to NULL).
Definition: refPtr.h:909
AR_API bool operator==(const ArAssetInfo &lhs, const ArAssetInfo &rhs)
Pointer storage with deletion detection.
Definition: hash.h:44
Provides hash function on STL string types and other types.
Definition: hash.h:86
Enable a concrete base class for use with TfRefPtr.
Definition: refBase.h:72
TfRefPtr(TfNullPtrType)
Implicit conversion from TfNullPtr to TfRefPtr.
Definition: refPtr.h:695
T * operator->() const
Accessor to T&#39;s public members.
Definition: refPtr.h:974
SdfHandle< typename DST::SpecType > TfDynamic_cast(const SdfHandle< SRC > &x)
Convert SdfHandle&lt;SRC&gt; x to an SdfHandle&lt;DST&gt;.
void swap(UsdStageLoadRules &l, UsdStageLoadRules &r)
Swap the contents of rules l and r.
bool operator!=(const TfRefPtr< U > &p) const
Returns true if *this and p do not point to the same object.
Definition: refPtr.h:966
TfRefPtr< T > & operator=(const TfRefPtr< T > &p)
Assigns pointer to point at p&#39;s object, and increments reference count.
Definition: refPtr.h:724
friend const std::type_info & TfTypeid(const TfRefPtr< U > &ptr)
Call typeid on the object pointed to by a TfRefPtr.
#define TF_FATAL_ERROR(fmt, args)
Issue a fatal error and end the program.
Definition: diagnostic.h:111
TfRefPtr(const TfRefPtr< U > &p)
Initializes to point at p&#39;s object, and increments reference count.
Definition: refPtr.h:805
~TfRefPtr()
Decrements reference count of object being pointed to.
Definition: refPtr.h:771
T & operator*() const
Dereferences the stored pointer.
Definition: refPtr.h:983
friend TfRefPtr TfCreateRefPtr(T *)
Transfer a raw pointer to a reference-counted pointer.
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:752
friend TfRefPtr< D > TfConst_cast(const TfRefPtr< const D > &)
Allows const casting of a TfRefPtr.
Implements assorted functions based on compile-time type information.
Definition: typeFunctions.h:54
friend TfRefPtr< D > TfStatic_cast(const TfRefPtr< T > &)
Allows static casting of a TfRefPtr.
Reference-counted smart pointer utility class.
Definition: hash.h:45
TfRefPtr(U *ptr, typename std::enable_if< std::is_convertible< U *, T * >::value >::type *=nullptr)
Initializes to point at *ptr.
Definition: refPtr.h:685
TfRefPtr(const TfRefPtr< T > &p)
Initializes *this to point at p&#39;s object.
Definition: refPtr.h:625
Enable a concrete base class for use with TfWeakPtr.
Definition: weakBase.h:142