Teuchos - Trilinos Tools Package  Version of the Day
Teuchos_RCPDecl.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Teuchos: Common Tools Package
5 // Copyright (2004) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #ifndef TEUCHOS_RCP_DECL_HPP
43 #define TEUCHOS_RCP_DECL_HPP
44 
45 
51 #include "Teuchos_RCPNode.hpp"
52 #include "Teuchos_ENull.hpp"
53 #include "Teuchos_NullIteratorTraits.hpp"
54 
55 
56 #ifdef REFCOUNTPTR_INLINE_FUNCS
57 # define REFCOUNTPTR_INLINE inline
58 #else
59 # define REFCOUNTPTR_INLINE
60 #endif
61 
62 
63 #ifdef TEUCHOS_DEBUG
64 # define TEUCHOS_REFCOUNTPTR_ASSERT_NONNULL
65 #endif
66 
67 
68 namespace Teuchos {
69 
70 
72 template<class T> class Ptr;
73 
74 
75 enum ERCPWeakNoDealloc { RCP_WEAK_NO_DEALLOC };
76 enum ERCPUndefinedWeakNoDealloc { RCP_UNDEFINED_WEAK_NO_DEALLOC };
77 enum ERCPUndefinedWithDealloc { RCP_UNDEFINED_WITH_DEALLOC };
78 
79 
428 template<class T>
429 class RCP {
430 public:
431 
433  typedef T element_type;
434 
437 
459  inline RCP(ENull null_arg = null);
460 
481  inline explicit RCP( T* p, bool has_ownership = true );
482 
502  template<class Dealloc_T>
503  inline RCP(T* p, Dealloc_T dealloc, bool has_ownership);
504 
522  inline RCP(const RCP<T>& r_ptr);
523 
537  template<class T2>
538  inline RCP(const RCP<T2>& r_ptr);
539 
551  inline ~RCP();
552 
572  inline RCP<T>& operator=(const 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 RCP<const T> getConst() const;
635 
637 
640 
652  inline ERCPStrength strength() const;
653 
663  inline bool is_valid_ptr() const;
664 
670  inline int strong_count() const;
671 
677  inline int weak_count() const;
678 
680  inline int total_count() const;
681 
700  inline void set_has_ownership();
701 
712  inline bool has_ownership() const;
713 
745  inline Ptr<T> release();
746 
763  inline RCP<T> create_weak() const;
764 
781  inline RCP<T> create_strong() const;
782 
783 #if defined(HAVE_TEUCHOSCORE_CXX11) && defined(HAVE_TEUCHOS_THREAD_SAFE)
784 
785  inline RCP<T> create_strong_thread_safe() const; // this format to be determined
786 #endif
787 
795  template<class T2>
796  inline bool shares_resource(const RCP<T2>& r_ptr) const;
797 
799 
802 
806  inline const RCP<T>& assert_not_null() const;
807 
817  inline const RCP<T>& assert_valid_ptr() const;
818 
820  inline const RCP<T>& debug_assert_not_null() const
821  {
822 #ifdef TEUCHOS_REFCOUNTPTR_ASSERT_NONNULL
823  assert_not_null();
824 #endif
825  return *this;
826  }
827 
829  inline const RCP<T>& debug_assert_valid_ptr() const
830  {
831 #ifdef TEUCHOS_DEBUG
833 #endif
834  return *this;
835  }
836 
838 
841 
843  inline void reset();
844 
855  template<class T2>
856  inline void reset(T2* p, bool has_ownership = true);
857 
859  TEUCHOS_DEPRECATED inline int count() const;
860 
862 
863 private:
864 
865  // //////////////////////////////////////////////////////////////
866  // Private data members
867 
868  T *ptr_; // NULL if this pointer is null
869  RCPNodeHandle node_; // NULL if this pointer is null
870 
871 public: // Bad bad bad
872 
873  // These constructors are put here because we don't want to confuse users
874  // who would otherwise see them.
875 
887  inline explicit RCP(T* p, ERCPWeakNoDealloc);
888 
899  inline explicit RCP(T* p, ERCPUndefinedWeakNoDealloc);
900 
907  template<class Dealloc_T>
908  inline RCP(T* p, Dealloc_T dealloc, ERCPUndefinedWithDealloc,
909  bool has_ownership = true);
910 
911 #ifndef DOXYGEN_COMPILE
912 
913  // WARNING: A general user should *never* call these functions!
914  inline RCP(T* p, const RCPNodeHandle &node);
915  inline T* access_private_ptr() const; // Does not throw
916  inline RCPNodeHandle& nonconst_access_private_node(); // Does not thorw
917  inline const RCPNodeHandle& access_private_node() const; // Does not thorw
918 
919 #endif
920 
921 };
922 
925 struct RCPComp {
927  template<class T1, class T2> inline
928  bool operator() (const RCP<T1> p1, const RCP<T2> p2) const{
929  return p1.get() < p2.get();
930  }
931 };
932 
935 struct RCPConstComp {
937  template<class T1, class T2> inline
938  bool operator() (const RCP<const T1> p1, const RCP<const T2> p2) const{
939  return p1.get() < p2.get();
940  }
941 };
942 
943 
944 
945 // 2008/09/22: rabartl: NOTE: I removed the TypeNameTraits<RCP<T> >
946 // specialization since I want to be able to print the type name of an RCP
947 // that does not have the type T fully defined!
948 
949 
954 template<typename T>
956 public:
957  static RCP<T> getNull() { return null; }
958 };
959 
960 
965 template<class T>
967 {
968 public:
970  typedef T ptr_t;
972  void free( T* ptr ) {
973  (void) ptr; // silence "unused parameter" compiler warning
974  }
975 };
976 
977 
983 template<class T>
985 {
986 public:
988  typedef T ptr_t;
990  void free( T* ptr ) { if(ptr) delete ptr; }
991 };
992 
993 
999 template<class T>
1001 {
1002 public:
1004  typedef T ptr_t;
1006  void free( T* ptr ) { if(ptr) delete [] ptr; }
1007 };
1008 
1009 
1022 template<class T, class DeleteFunctor>
1024 {
1025 public:
1026  DeallocFunctorDelete( DeleteFunctor deleteFunctor ) : deleteFunctor_(deleteFunctor) {}
1027  typedef T ptr_t;
1028  void free( T* ptr ) { if(ptr) deleteFunctor_(ptr); }
1029 private:
1030  DeleteFunctor deleteFunctor_;
1031  DeallocFunctorDelete(); // Not defined and not to be called!
1032 };
1033 
1034 
1039 template<class T, class DeleteFunctor>
1041 deallocFunctorDelete( DeleteFunctor deleteFunctor )
1042 {
1043  return DeallocFunctorDelete<T,DeleteFunctor>(deleteFunctor);
1044 }
1045 
1046 
1060 template<class T, class DeleteHandleFunctor>
1062 {
1063 public:
1064  DeallocFunctorHandleDelete( DeleteHandleFunctor deleteHandleFunctor )
1065  : deleteHandleFunctor_(deleteHandleFunctor) {}
1066  typedef T ptr_t;
1067  void free( T* ptr ) { if(ptr) { T **hdl = &ptr; deleteHandleFunctor_(hdl); } }
1068 private:
1069  DeleteHandleFunctor deleteHandleFunctor_;
1070  DeallocFunctorHandleDelete(); // Not defined and not to be called!
1071 };
1072 
1073 
1078 template<class T, class DeleteHandleFunctor>
1080 deallocFunctorHandleDelete( DeleteHandleFunctor deleteHandleFunctor )
1081 {
1082  return DeallocFunctorHandleDelete<T,DeleteHandleFunctor>(deleteHandleFunctor);
1083 }
1084 
1085 
1094 template<class T, class Embedded, class Dealloc>
1096 {
1097 public:
1098  typedef typename Dealloc::ptr_t ptr_t;
1100  const Embedded &embedded, EPrePostDestruction prePostDestroy,
1101  Dealloc dealloc
1102  ) : embedded_(embedded), prePostDestroy_(prePostDestroy), dealloc_(dealloc)
1103  {}
1104  void setObj( const Embedded &embedded ) { embedded_ = embedded; }
1105  const Embedded& getObj() const { return embedded_; }
1106  Embedded& getNonconstObj() { return embedded_; }
1107  void free( T* ptr )
1108  {
1109  if (prePostDestroy_ == PRE_DESTROY)
1110  embedded_ = Embedded();
1111  dealloc_.free(ptr);
1112  if (prePostDestroy_ == POST_DESTROY)
1113  embedded_ = Embedded();
1114  }
1115 private:
1116  Embedded embedded_;
1117  EPrePostDestruction prePostDestroy_;
1118  Dealloc dealloc_;
1119  EmbeddedObjDealloc(); // Not defined and not to be called!
1120 };
1121 
1122 
1127 template<class T, class Embedded >
1129 embeddedObjDeallocDelete(const Embedded &embedded, EPrePostDestruction prePostDestroy)
1130 {
1132  embedded, prePostDestroy,DeallocDelete<T>());
1133 }
1134 
1135 
1140 template<class T, class Embedded >
1142 embeddedObjDeallocArrayDelete(const Embedded &embedded, EPrePostDestruction prePostDestroy)
1143 {
1145  embedded, prePostDestroy,DeallocArrayDelete<T>());
1146 }
1147 
1148 
1171 template<class T> inline
1172 RCP<T> rcp(T* p, bool owns_mem = true);
1173 
1174 
1218 template<class T, class Dealloc_T> inline
1219 RCP<T> rcpWithDealloc(T* p, Dealloc_T dealloc, bool owns_mem=true);
1220 
1221 
1223 template<class T, class Dealloc_T> inline
1224 TEUCHOS_DEPRECATED RCP<T> rcp( T* p, Dealloc_T dealloc, bool owns_mem )
1225 {
1226  return rcpWithDealloc(p, dealloc, owns_mem);
1227 }
1228 
1229 
1241 template<class T, class Dealloc_T> inline
1242 RCP<T> rcpWithDeallocUndef(T* p, Dealloc_T dealloc, bool owns_mem=true);
1243 
1244 
1254 template<class T> inline
1255 RCP<T> rcpFromRef(T& r);
1256 
1257 
1267 template<class T> inline
1268 RCP<T> rcpFromUndefRef(T& r);
1269 
1270 
1281 template<class T, class Embedded> inline
1282 RCP<T>
1283 rcpWithEmbeddedObjPreDestroy( T* p, const Embedded &embedded, bool owns_mem = true );
1284 
1285 
1296 template<class T, class Embedded> inline
1297 RCP<T>
1298 rcpWithEmbeddedObjPostDestroy( T* p, const Embedded &embedded, bool owns_mem = true );
1299 
1300 
1312 template<class T, class Embedded> inline
1313 RCP<T>
1314 rcpWithEmbeddedObj( T* p, const Embedded &embedded, bool owns_mem = true );
1315 
1316 
1317 // 2007/10/25: rabartl: ToDo: put in versions of
1318 // rcpWithEmbedded[Pre,Post]DestoryWithDealloc(...) that also accept a general
1319 // deallocator!
1320 
1321 
1331 template<class T, class ParentT>
1332 RCP<T> rcpWithInvertedObjOwnership(const RCP<T> &child, const RCP<ParentT> &parent);
1333 
1334 
1348 template<class T>
1349 RCP<T> rcpCloneNode(const RCP<T> &p);
1350 
1351 
1356 template<class T> inline
1357 bool is_null( const RCP<T> &p );
1358 
1359 
1364 template<class T> inline
1365 bool nonnull( const RCP<T> &p );
1366 
1367 
1372 template<class T> inline
1373 bool operator==( const RCP<T> &p, ENull );
1374 
1375 
1380 template<class T> inline
1381 bool operator!=( const RCP<T> &p, ENull );
1382 
1383 
1389 template<class T1, class T2> inline
1390 bool operator==( const RCP<T1> &p1, const RCP<T2> &p2 );
1391 
1392 
1398 template<class T1, class T2> inline
1399 bool operator!=( const RCP<T1> &p1, const RCP<T2> &p2 );
1400 
1401 
1411 template<class T2, class T1> inline
1412 RCP<T2> rcp_implicit_cast(const RCP<T1>& p1);
1413 
1414 
1425 template<class T2, class T1> inline
1426 RCP<T2> rcp_static_cast(const RCP<T1>& p1);
1427 
1428 
1435 template<class T2, class T1> inline
1436 RCP<T2> rcp_const_cast(const RCP<T1>& p1);
1437 
1438 
1462 template<class T2, class T1> inline
1463 RCP<T2> rcp_dynamic_cast(
1464  const RCP<T1>& p1, bool throw_on_fail = false
1465  );
1466 
1467 
1526 template<class T1, class T2>
1527 void set_extra_data( const T1 &extra_data, const std::string& name,
1528  const Ptr<RCP<T2> > &p, EPrePostDestruction destroy_when = POST_DESTROY,
1529  bool force_unique = true);
1530 
1550 template<class T1, class T2>
1551 const T1& get_extra_data( const RCP<T2>& p, const std::string& name );
1552 
1553 
1573 template<class T1, class T2>
1574 T1& get_nonconst_extra_data( RCP<T2>& p, const std::string& name );
1575 
1576 
1601 template<class T1, class T2>
1602 Ptr<const T1> get_optional_extra_data( const RCP<T2>& p, const std::string& name );
1603 
1604 
1629 template<class T1, class T2>
1630 Ptr<T1> get_optional_nonconst_extra_data( RCP<T2>& p, const std::string& name );
1631 
1632 
1644 template<class Dealloc_T, class T>
1645 const Dealloc_T& get_dealloc( const RCP<T>& p );
1646 
1647 
1659 template<class Dealloc_T, class T>
1660 Dealloc_T& get_nonconst_dealloc( const RCP<T>& p );
1661 
1662 
1677 template<class Dealloc_T, class T>
1678 Ptr<const Dealloc_T> get_optional_dealloc( const RCP<T>& p );
1679 
1680 
1695 template<class Dealloc_T, class T>
1696 Ptr<Dealloc_T> get_optional_nonconst_dealloc( const RCP<T>& p );
1697 
1698 
1705 template<class TOrig, class Embedded, class T>
1706 const Embedded& getEmbeddedObj( const RCP<T>& p );
1707 
1708 
1715 template<class TOrig, class Embedded, class T>
1716 Embedded& getNonconstEmbeddedObj( const RCP<T>& p );
1717 
1718 
1725 template<class TOrig, class Embedded, class T>
1726 Ptr<const Embedded> getOptionalEmbeddedObj( const RCP<T>& p );
1727 
1728 
1735 template<class TOrig, class Embedded, class T>
1736 Ptr<Embedded> getOptionalNonconstEmbeddedObj( const RCP<T>& p );
1737 
1738 
1744 template<class ParentT, class T>
1745 RCP<ParentT> getInvertedObjOwnershipParent(const RCP<T> &invertedChild);
1746 
1747 
1755 template<class T>
1756 std::ostream& operator<<( std::ostream& out, const RCP<T>& p );
1757 
1758 
1759 } // end namespace Teuchos
1760 
1761 
1762 #endif // TEUCHOS_RCP_DECL_HPP
const RCP< T > & assert_valid_ptr() const
If the object pointer is non-null, assert that it is still valid.
~RCP()
Removes a reference to a dynamically allocated object and possibly deletes the object if owned...
RCP(ENull null_arg=null)
Initialize RCP<T> to NULL.
int strong_count() const
Return the number of active RCP<> objects that have a "strong" reference to the underlying reference-...
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).
T ptr_t
Gives the type (required)
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.
int total_count() const
Total count (strong_count() + weak_count()).
const RCP< T > & debug_assert_not_null() const
Calls assert_not_null() in a debug build.
RCP< T > create_strong() const
Create a new strong RCP object from another (weak) RCP object.
TEUCHOS_DEPRECATED int count() const
Returns strong_count() [deprecated].
int weak_count() const
Return the number of active RCP<> objects that have a "weak" reference to the underlying reference-co...
void swap(RCP< T > &r_ptr)
Swap the contents with some other RCP object.
ERCPStrength strength() const
Strength of the pointer.
bool is_valid_ptr() const
Return if the underlying object pointer is still valid or not.
T & operator*() const
Dereference the underlying object.
ENull
Used to initialize a RCP object to NULL using an implicit conversion!
A deallocator class that wraps a simple value object and delegates to another deallocator object...
bool operator()(const RCP< T1 > p1, const RCP< T2 > p2) const
T * get() const
Get the raw C++ pointer to the 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).
bool shares_resource(const RCP< T2 > &r_ptr) const
Returns true if the smart pointers share the same underlying reference-counted object.
bool is_null() const
Returns true if the underlying pointer is null.
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 * operator->() const
Pointer (->) access to members of underlying object.
const RCP< T > & debug_assert_valid_ptr() const
Calls assert_valid_ptr() in a debug build.
Deallocator class that uses delete [] to delete memory allocated uisng new []
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.
void set_has_ownership()
Give this and other RCP<> objects ownership of the referenced object this->get(). ...
void reset()
Reset to null.
T ptr_t
Gives the type (required)
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.
RCP< T > create_weak() const
Create a new weak RCP object from another (strong) RCP object.
Base traits class for getting a properly initialized null pointer.
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.
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos, as well as a number of utility routines.
bool has_ownership() const
Returns true if this has ownership of object pointed to by this->get() in order to delete it...
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.
T * getRawPtr() const
Get the raw C++ pointer to the underlying object.
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.
Ptr< T > operator()() const
Shorthand for ptr().
const RCP< T > & assert_not_null() const
Throws NullReferenceError if this->get()==NULL, otherwise returns reference to *this.
RCP< const T > getConst() const
Return an RCP<const T> version of *this.
Reference-counted pointer node classes.
void free(T *ptr)
Deallocates a pointer ptr using delete [] ptr (required).
Ptr< T > ptr() const
Get a safer wrapper raw C++ pointer to the underlying object.
Simple wrapper class for raw pointers to single objects where no persisting relationship exists...
bool operator()(const RCP< const T1 > p1, const RCP< const T2 > p2) const