Teuchos - Trilinos Tools Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Teuchos_RCPDecl.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Teuchos: Common Tools Package
4 //
5 // Copyright 2004 NTESS and the Teuchos contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef TEUCHOS_RCP_DECL_HPP
11 #define TEUCHOS_RCP_DECL_HPP
12 
13 
19 #include "Teuchos_RCPNode.hpp"
20 #include "Teuchos_ENull.hpp"
21 #include "Teuchos_NullIteratorTraits.hpp"
22 
23 
24 #ifdef REFCOUNTPTR_INLINE_FUNCS
25 # define REFCOUNTPTR_INLINE inline
26 #else
27 # define REFCOUNTPTR_INLINE
28 #endif
29 
30 
31 #ifdef TEUCHOS_DEBUG
32 # define TEUCHOS_REFCOUNTPTR_ASSERT_NONNULL
33 #endif
34 
35 
36 namespace Teuchos {
37 
38 
40 template<class T> class Ptr;
41 
42 
43 enum ERCPWeakNoDealloc { RCP_WEAK_NO_DEALLOC };
44 enum ERCPUndefinedWeakNoDealloc { RCP_UNDEFINED_WEAK_NO_DEALLOC };
45 enum ERCPUndefinedWithDealloc { RCP_UNDEFINED_WITH_DEALLOC };
46 
47 
396 template<class T>
397 class RCP {
398 public:
399 
401  typedef T element_type;
402 
405 
427  inline RCP(ENull null_arg = null);
428 
449  inline explicit RCP( T* p, bool has_ownership = true );
450 
470  template<class Dealloc_T>
471  inline RCP(T* p, Dealloc_T dealloc, bool has_ownership);
472 
490  inline RCP(const RCP<T>& r_ptr);
491 
499  inline RCP(RCP<T>&& r_ptr);
500 
514  template<class T2>
515  inline RCP(const RCP<T2>& r_ptr);
516 
526  template<class T2>
527  inline RCP(const RCP<T2>& r_ptr, T* ptr);
528 
540  inline ~RCP();
541 
561  inline RCP<T>& operator=(const RCP<T>& r_ptr);
562 
572  inline RCP<T>& operator=(RCP<T>&& r_ptr);
573 
586  inline RCP<T>& operator=(ENull);
587 
589  inline void swap(RCP<T> &r_ptr);
590 
592 
595 
597  inline bool is_null() const;
598 
605  inline T* operator->() const;
606 
613  inline T& operator*() const;
614 
619  inline T* get() const;
620 
625  inline T* getRawPtr() const;
626 
628  inline Ptr<T> ptr() const;
629 
631  inline Ptr<T> operator()() const;
632 
634  inline explicit operator bool() const;
635 
637  inline RCP<const T> getConst() const;
638 
640 
643 
653  inline ERCPStrength strength() const;
654 
664  inline bool is_valid_ptr() const;
665 
671  inline int strong_count() const;
672 
678  inline int weak_count() const;
679 
681  inline int total_count() const;
682 
701  inline void set_has_ownership();
702 
713  inline bool has_ownership() const;
714 
746  inline Ptr<T> release();
747 
764  inline RCP<T> create_weak() const;
765 
782  inline RCP<T> create_strong() const;
783 
784 #if defined(HAVE_TEUCHOSCORE_CXX11) && defined(HAVE_TEUCHOS_THREAD_SAFE)
785 
786  inline RCP<T> create_strong_thread_safe() const; // this format to be determined
787 #endif
788 
796  template<class T2>
797  inline bool shares_resource(const RCP<T2>& r_ptr) const;
798 
800 
803 
807  inline const RCP<T>& assert_not_null() const;
808 
818  inline const RCP<T>& assert_valid_ptr() const;
819 
821  inline const RCP<T>& debug_assert_not_null() const
822  {
823 #ifdef TEUCHOS_REFCOUNTPTR_ASSERT_NONNULL
824  assert_not_null();
825 #endif
826  return *this;
827  }
828 
830  inline const RCP<T>& debug_assert_valid_ptr() const
831  {
832 #ifdef TEUCHOS_DEBUG
834 #endif
835  return *this;
836  }
837 
839 
842 
844  inline void reset();
845 
856  template<class T2>
857  inline void reset(T2* p, bool has_ownership = true);
858 
860 
861 private:
862 
863  // //////////////////////////////////////////////////////////////
864  // Private data members
865 
866  T *ptr_; // NULL if this pointer is null
867  RCPNodeHandle node_; // NULL if this pointer is null
868 
869 public: // Bad bad bad
870 
871  // These constructors are put here because we don't want to confuse users
872  // who would otherwise see them.
873 
885  inline explicit RCP(T* p, ERCPWeakNoDealloc);
886 
897  inline explicit RCP(T* p, ERCPUndefinedWeakNoDealloc);
898 
905  template<class Dealloc_T>
906  inline RCP(T* p, Dealloc_T dealloc, ERCPUndefinedWithDealloc,
907  bool has_ownership = true);
908 
909 #ifndef DOXYGEN_COMPILE
910 
911  // WARNING: A general user should *never* call these functions!
912  inline RCP(T* p, const RCPNodeHandle &node);
913  inline T* access_private_ptr() const; // Does not throw
914  inline RCPNodeHandle& nonconst_access_private_node(); // Does not thorw
915  inline const RCPNodeHandle& access_private_node() const; // Does not thorw
916 
917 #endif
918 
919 };
920 
923 struct RCPComp {
925  template<class T1, class T2> inline
926  bool operator() (const RCP<T1> p1, const RCP<T2> p2) const{
927  return p1.get() < p2.get();
928  }
929 };
930 
933 struct RCPConstComp {
935  template<class T1, class T2> inline
936  bool operator() (const RCP<const T1> p1, const RCP<const T2> p2) const{
937  return p1.get() < p2.get();
938  }
939 };
940 
941 
942 
943 // 2008/09/22: rabartl: NOTE: I removed the TypeNameTraits<RCP<T> >
944 // specialization since I want to be able to print the type name of an RCP
945 // that does not have the type T fully defined!
946 
947 
952 template<typename T>
954 public:
955  static RCP<T> getNull() { return null; }
956 };
957 
958 
963 template<class T>
965 {
966 public:
968  typedef T ptr_t;
970  void free( T* ptr ) {
971  (void) ptr; // silence "unused parameter" compiler warning
972  }
973 };
974 
975 
981 template<class T>
983 {
984 public:
986  typedef T ptr_t;
988  void free( T* ptr ) { if(ptr) delete ptr; }
989 };
990 
991 
997 template<class T>
999 {
1000 public:
1002  typedef T ptr_t;
1004  void free( T* ptr ) { if(ptr) delete [] ptr; }
1005 };
1006 
1007 
1020 template<class T, class DeleteFunctor>
1022 {
1023 public:
1024  DeallocFunctorDelete( DeleteFunctor deleteFunctor ) : deleteFunctor_(deleteFunctor) {}
1025  typedef T ptr_t;
1026  void free( T* ptr ) { if(ptr) deleteFunctor_(ptr); }
1027 private:
1028  DeleteFunctor deleteFunctor_;
1029  DeallocFunctorDelete(); // Not defined and not to be called!
1030 };
1031 
1032 
1037 template<class T, class DeleteFunctor>
1039 deallocFunctorDelete( DeleteFunctor deleteFunctor )
1040 {
1041  return DeallocFunctorDelete<T,DeleteFunctor>(deleteFunctor);
1042 }
1043 
1044 
1058 template<class T, class DeleteHandleFunctor>
1060 {
1061 public:
1062  DeallocFunctorHandleDelete( DeleteHandleFunctor deleteHandleFunctor )
1063  : deleteHandleFunctor_(deleteHandleFunctor) {}
1064  typedef T ptr_t;
1065  void free( T* ptr ) { if(ptr) { T **hdl = &ptr; deleteHandleFunctor_(hdl); } }
1066 private:
1067  DeleteHandleFunctor deleteHandleFunctor_;
1068  DeallocFunctorHandleDelete(); // Not defined and not to be called!
1069 };
1070 
1071 
1076 template<class T, class DeleteHandleFunctor>
1078 deallocFunctorHandleDelete( DeleteHandleFunctor deleteHandleFunctor )
1079 {
1080  return DeallocFunctorHandleDelete<T,DeleteHandleFunctor>(deleteHandleFunctor);
1081 }
1082 
1083 
1092 template<class T, class Embedded, class Dealloc>
1094 {
1095 public:
1096  typedef typename Dealloc::ptr_t ptr_t;
1098  const Embedded &embedded, EPrePostDestruction prePostDestroy,
1099  Dealloc dealloc
1100  ) : embedded_(embedded), prePostDestroy_(prePostDestroy), dealloc_(dealloc)
1101  {}
1102  void setObj( const Embedded &embedded ) { embedded_ = embedded; }
1103  const Embedded& getObj() const { return embedded_; }
1104  Embedded& getNonconstObj() { return embedded_; }
1105  void free( T* ptr )
1106  {
1107  if (prePostDestroy_ == PRE_DESTROY)
1108  embedded_ = Embedded();
1109  dealloc_.free(ptr);
1110  if (prePostDestroy_ == POST_DESTROY)
1111  embedded_ = Embedded();
1112  }
1113 private:
1114  Embedded embedded_;
1115  EPrePostDestruction prePostDestroy_;
1116  Dealloc dealloc_;
1117  EmbeddedObjDealloc(); // Not defined and not to be called!
1118 };
1119 
1120 
1125 template<class T, class Embedded >
1127 embeddedObjDeallocDelete(const Embedded &embedded, EPrePostDestruction prePostDestroy)
1128 {
1130  embedded, prePostDestroy,DeallocDelete<T>());
1131 }
1132 
1133 
1138 template<class T, class Embedded >
1140 embeddedObjDeallocArrayDelete(const Embedded &embedded, EPrePostDestruction prePostDestroy)
1141 {
1143  embedded, prePostDestroy,DeallocArrayDelete<T>());
1144 }
1145 
1146 
1169 template<class T> inline
1170 RCP<T> rcp(T* p, bool owns_mem = true);
1171 
1177 template <typename T, typename ... Args>
1178 inline auto make_rcp(Args&& ... args)
1179 {
1180  return Teuchos::rcp(
1181  new T(std::forward<Args>(args)...)
1182  );
1183 }
1184 
1228 template<class T, class Dealloc_T> inline
1229 RCP<T> rcpWithDealloc(T* p, Dealloc_T dealloc, bool owns_mem=true);
1230 
1231 
1233 template<class T, class Dealloc_T> inline
1234 TEUCHOS_DEPRECATED RCP<T> rcp( T* p, Dealloc_T dealloc, bool owns_mem )
1235 {
1236  return rcpWithDealloc(p, dealloc, owns_mem);
1237 }
1238 
1239 
1251 template<class T, class Dealloc_T> inline
1252 RCP<T> rcpWithDeallocUndef(T* p, Dealloc_T dealloc, bool owns_mem=true);
1253 
1254 
1264 template<class T> inline
1265 RCP<T> rcpFromRef(T& r);
1266 
1267 
1277 template<class T> inline
1278 RCP<T> rcpFromUndefRef(T& r);
1279 
1280 
1291 template<class T, class Embedded> inline
1292 RCP<T>
1293 rcpWithEmbeddedObjPreDestroy( T* p, const Embedded &embedded, bool owns_mem = true );
1294 
1295 
1306 template<class T, class Embedded> inline
1307 RCP<T>
1308 rcpWithEmbeddedObjPostDestroy( T* p, const Embedded &embedded, bool owns_mem = true );
1309 
1310 
1322 template<class T, class Embedded> inline
1323 RCP<T>
1324 rcpWithEmbeddedObj( T* p, const Embedded &embedded, bool owns_mem = true );
1325 
1326 
1327 // 2007/10/25: rabartl: ToDo: put in versions of
1328 // rcpWithEmbedded[Pre,Post]DestoryWithDealloc(...) that also accept a general
1329 // deallocator!
1330 
1331 
1341 template<class T, class ParentT>
1342 RCP<T> rcpWithInvertedObjOwnership(const RCP<T> &child, const RCP<ParentT> &parent);
1343 
1344 
1358 template<class T>
1359 RCP<T> rcpCloneNode(const RCP<T> &p);
1360 
1361 
1366 template<class T> inline
1367 bool is_null( const RCP<T> &p );
1368 
1369 
1374 template<class T> inline
1375 bool nonnull( const RCP<T> &p );
1376 
1377 
1382 template<class T> inline
1383 bool operator==( const RCP<T> &p, ENull );
1384 
1385 
1390 template<class T> inline
1391 bool operator!=( const RCP<T> &p, ENull );
1392 
1393 
1399 template<class T1, class T2> inline
1400 bool operator==( const RCP<T1> &p1, const RCP<T2> &p2 );
1401 
1402 
1408 template<class T1, class T2> inline
1409 bool operator!=( const RCP<T1> &p1, const RCP<T2> &p2 );
1410 
1411 
1421 template<class T2, class T1> inline
1422 RCP<T2> rcp_implicit_cast(const RCP<T1>& p1);
1423 
1424 
1435 template<class T2, class T1> inline
1436 RCP<T2> rcp_static_cast(const RCP<T1>& p1);
1437 
1438 
1445 template<class T2, class T1> inline
1446 RCP<T2> rcp_const_cast(const RCP<T1>& p1);
1447 
1448 
1472 template<class T2, class T1> inline
1473 RCP<T2> rcp_dynamic_cast(
1474  const RCP<T1>& p1, bool throw_on_fail = false
1475  );
1476 
1477 
1536 template<class T1, class T2>
1537 void set_extra_data( const T1 &extra_data, const std::string& name,
1538  const Ptr<RCP<T2> > &p, EPrePostDestruction destroy_when = POST_DESTROY,
1539  bool force_unique = true);
1540 
1560 template<class T1, class T2>
1561 const T1& get_extra_data( const RCP<T2>& p, const std::string& name );
1562 
1563 
1583 template<class T1, class T2>
1584 T1& get_nonconst_extra_data( RCP<T2>& p, const std::string& name );
1585 
1586 
1611 template<class T1, class T2>
1612 Ptr<const T1> get_optional_extra_data( const RCP<T2>& p, const std::string& name );
1613 
1614 
1639 template<class T1, class T2>
1640 Ptr<T1> get_optional_nonconst_extra_data( RCP<T2>& p, const std::string& name );
1641 
1642 
1654 template<class Dealloc_T, class T>
1655 const Dealloc_T& get_dealloc( const RCP<T>& p );
1656 
1657 
1669 template<class Dealloc_T, class T>
1670 Dealloc_T& get_nonconst_dealloc( const RCP<T>& p );
1671 
1672 
1687 template<class Dealloc_T, class T>
1688 Ptr<const Dealloc_T> get_optional_dealloc( const RCP<T>& p );
1689 
1690 
1705 template<class Dealloc_T, class T>
1706 Ptr<Dealloc_T> get_optional_nonconst_dealloc( const RCP<T>& p );
1707 
1708 
1715 template<class TOrig, class Embedded, class T>
1716 const Embedded& getEmbeddedObj( const RCP<T>& p );
1717 
1718 
1725 template<class TOrig, class Embedded, class T>
1726 Embedded& getNonconstEmbeddedObj( const RCP<T>& p );
1727 
1728 
1735 template<class TOrig, class Embedded, class T>
1736 Ptr<const Embedded> getOptionalEmbeddedObj( const RCP<T>& p );
1737 
1738 
1745 template<class TOrig, class Embedded, class T>
1746 Ptr<Embedded> getOptionalNonconstEmbeddedObj( const RCP<T>& p );
1747 
1748 
1754 template<class ParentT, class T>
1755 RCP<ParentT> getInvertedObjOwnershipParent(const RCP<T> &invertedChild);
1756 
1757 
1765 template<class T>
1766 std::ostream& operator<<( std::ostream& out, const RCP<T>& p );
1767 
1768 
1769 } // end namespace Teuchos
1770 
1771 
1772 #endif // TEUCHOS_RCP_DECL_HPP
~RCP()
Removes a reference to a dynamically allocated object and possibly deletes the object if owned...
RCP< const T > getConst() const
Return an RCP&lt;const T&gt; version of *this.
RCP(ENull null_arg=null)
Initialize RCP&lt;T&gt; to NULL.
DeallocFunctorHandleDelete< T, DeleteHandleFunctor > deallocFunctorHandleDelete(DeleteHandleFunctor deleteHandleFunctor)
A simple function used to create a functor deallocator object.
void free(T *ptr)
Deallocates a pointer ptr using delete ptr (required).
bool operator()(const RCP< T1 > p1, const RCP< T2 > p2) const
const RCP< T > & debug_assert_not_null() const
Calls assert_not_null() in a debug build.
RCP< T > create_weak() const
Create a new weak RCP object from another (strong) RCP object.
T ptr_t
Gives the type (required)
bool operator()(const RCP< const T1 > p1, const RCP< const T2 > p2) const
bool has_ownership() const
Returns true if this has ownership of object pointed to by this-&gt;get() in order to delete it...
bool nonnull(const std::shared_ptr< T > &p)
Returns true if p.get()!=NULL.
Deallocator subclass that Allows any functor object (including a function pointer) to be used to free...
bool is_null(const std::shared_ptr< T > &p)
Returns true if p.get()==NULL.
void swap(RCP< T > &r_ptr)
Swap the contents with some other RCP object.
RCP< T > create_strong() const
Create a new strong RCP object from another (weak) RCP object.
T * get() const
Get the raw C++ pointer to the underlying object.
ENull
Used to initialize a RCP object to NULL using an implicit conversion!
ERCPStrength strength() const
Strength of the pointer.
A deallocator class that wraps a simple value object and delegates to another deallocator object...
T * operator->() const
Pointer (-&gt;) access to members of underlying object.
Struct for comparing two RCPs. Simply compares the raw pointers contained within the RCPs...
void free(T *ptr)
Deallocates a pointer ptr using delete ptr (required).
Struct for comparing two RCPs. Simply compares the raw pointers contained within the RCPs...
Policy class for deallocator that uses delete to delete a pointer which is used by RCP...
EmbeddedObjDealloc< T, Embedded, DeallocArrayDelete< T > > embeddedObjDeallocArrayDelete(const Embedded &embedded, EPrePostDestruction prePostDestroy)
Create a dealocator with an embedded object using delete [].
T * getRawPtr() const
Get the raw C++ pointer to the underlying object.
Deallocator class that uses delete [] to delete memory allocated uisng new []
const RCP< T > & assert_valid_ptr() const
If the object pointer is non-null, assert that it is still valid.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.
void set_has_ownership()
Give this and other RCP&lt;&gt; objects ownership of the referenced object this-&gt;get(). ...
void reset()
Reset to null.
const RCP< T > & debug_assert_valid_ptr() const
Calls assert_valid_ptr() in a debug build.
Ptr< T > ptr() const
Get a safer wrapper raw C++ pointer to the underlying object.
Ptr< T > operator()() const
Shorthand for ptr().
bool shares_resource(const RCP< T2 > &r_ptr) const
Returns true if the smart pointers share the same underlying reference-counted object.
T ptr_t
Gives the type (required)
T & operator*() const
Dereference the underlying object.
ERCPStrength
Used to specify if the pointer is weak or strong.
RCP< T > & operator=(const RCP< T > &r_ptr)
Copy the pointer to the referenced object and increment the reference count.
Base traits class for getting a properly initialized null pointer.
const RCP< T > & assert_not_null() const
Throws NullReferenceError if this-&gt;get()==NULL, otherwise returns reference to *this.
Ptr< T > release()
Release the ownership of the underlying dynamically allocated object.
T ptr_t
Gives the type (required)
EmbeddedObjDealloc< T, Embedded, DeallocDelete< T > > embeddedObjDeallocDelete(const Embedded &embedded, EPrePostDestruction prePostDestroy)
Create a dealocator with an embedded object using delete.
bool is_valid_ptr() const
Return if the underlying object pointer is still valid or not.
Handle class that manages the RCPNode&#39;s reference counting.
RCP< ParentT > getInvertedObjOwnershipParent(const RCP< T > &invertedChild)
Get the parent back from an inverted ownership RCP.
EPrePostDestruction
Used to specify a pre or post destruction of extra data.
Policy class for deallocator for non-owned RCPs.
Deallocator subclass that Allows any functor object (including a function pointer) to be used to free...
DeallocFunctorDelete< T, DeleteFunctor > deallocFunctorDelete(DeleteFunctor deleteFunctor)
A simple function used to create a functor deallocator object.
Smart reference counting pointer class for automatic garbage collection.
Reference-counted pointer node classes.
void free(T *ptr)
Deallocates a pointer ptr using delete [] ptr (required).
int strong_count() const
Return the number of active RCP&lt;&gt; objects that have a &quot;strong&quot; reference to the underlying reference-...
int weak_count() const
Return the number of active RCP&lt;&gt; objects that have a &quot;weak&quot; reference to the underlying reference-co...
int total_count() const
Total count (strong_count() + weak_count()).
Simple wrapper class for raw pointers to single objects where no persisting relationship exists...
auto make_rcp(Args &&...args)
bool is_null() const
Returns true if the underlying pointer is null.