42 #ifndef TEUCHOS_RCP_HPP
43 #define TEUCHOS_RCP_HPP
59 #include "Teuchos_Ptr.hpp"
60 #include "Teuchos_Assert.hpp"
61 #include "Teuchos_Exceptions.hpp"
62 #include "Teuchos_dyn_cast.hpp"
75 RCPNode* RCP_createNewRCPNodeRawPtrNonowned( T* p )
77 return new RCPNodeTmpl<T,DeallocNull<T> >(p, DeallocNull<T>(),
false);
83 RCPNode* RCP_createNewRCPNodeRawPtrNonownedUndefined( T* p )
85 return new RCPNodeTmpl<T,DeallocNull<T> >(p, DeallocNull<T>(),
false, null);
91 RCPNode* RCP_createNewRCPNodeRawPtr( T* p,
bool has_ownership_in )
93 return new RCPNodeTmpl<T,DeallocDelete<T> >(p, DeallocDelete<T>(), has_ownership_in);
97 template<
class T,
class Dealloc_T>
99 RCPNode* RCP_createNewDeallocRCPNodeRawPtr(
100 T* p, Dealloc_T dealloc,
bool has_ownership_in
103 return new RCPNodeTmpl<T,Dealloc_T>(p, dealloc, has_ownership_in);
107 template<
class T,
class Dealloc_T>
109 RCPNode* RCP_createNewDeallocRCPNodeRawPtrUndefined(
110 T* p, Dealloc_T dealloc,
bool has_ownership_in
113 return new RCPNodeTmpl<T,Dealloc_T>(p, dealloc, has_ownership_in, null);
120 : ptr_(p), node_(node)
126 T* RCP<T>::access_private_ptr()
const
132 RCPNodeHandle& RCP<T>::nonconst_access_private_node()
138 const RCPNodeHandle& RCP<T>::access_private_node()
const
158 #ifndef TEUCHOS_DEBUG
159 , node_(RCP_createNewRCPNodeRawPtrNonowned(p))
165 if (existing_RCPNode) {
172 RCP_createNewRCPNodeRawPtrNonowned(p),
178 #endif // TEUCHOS_DEBUG
186 node_(RCP_createNewRCPNodeRawPtrNonownedUndefined(p))
194 #ifndef TEUCHOS_DEBUG
195 , node_(RCP_createNewRCPNodeRawPtr(p, has_ownership_in))
201 if (!has_ownership_in) {
204 if (existing_RCPNode) {
219 #endif // TEUCHOS_DEBUG
224 template<
class Dealloc_T>
228 #ifndef TEUCHOS_DEBUG
229 , node_(RCP_createNewDeallocRCPNodeRawPtr(p, dealloc, has_ownership_in))
237 RCPNodeThrowDeleter nodeDeleter(RCP_createNewDeallocRCPNodeRawPtr(p, dealloc, has_ownership_in));
245 #endif // TEUCHOS_DEBUG
250 template<
class Dealloc_T>
252 RCP<T>::RCP( T* p, Dealloc_T dealloc, ERCPUndefinedWithDealloc,
bool has_ownership_in )
254 #ifndef TEUCHOS_DEBUG
255 , node_(RCP_createNewDeallocRCPNodeRawPtrUndefined(p, dealloc, has_ownership_in))
265 p, dealloc, has_ownership_in));
273 #endif // TEUCHOS_DEBUG
280 : ptr_(r_ptr.ptr_), node_(r_ptr.node_)
287 : ptr_(r_ptr.ptr_), node_(std::move(r_ptr.node_))
298 node_(r_ptr.access_private_node())
317 RCP<T>(r_ptr).swap(*
this);
332 node_ = std::move(r_ptr.node_);
351 std::swap(r_ptr.ptr_, ptr_);
352 node_.swap(r_ptr.node_);
371 debug_assert_not_null();
372 debug_assert_valid_ptr();
381 debug_assert_not_null();
382 debug_assert_valid_ptr();
390 debug_assert_valid_ptr();
408 return Ptr<T>(this->create_weak());
410 return Ptr<T>(getRawPtr());
427 return rcp_implicit_cast<
const T>(*this);
446 return node_.strength();
455 return node_.is_valid_ptr();
464 return node_.strong_count();
472 return node_.weak_count();
480 return node_.total_count();
488 node_.has_ownership(
true);
496 return node_.has_ownership();
504 debug_assert_valid_ptr();
505 node_.has_ownership(
false);
514 debug_assert_valid_ptr();
515 return RCP<T>(ptr_, node_.create_weak());
523 debug_assert_valid_ptr();
524 return RCP<T>(ptr_, node_.create_strong());
527 #if defined(HAVE_TEUCHOSCORE_CXX11) && defined(HAVE_TEUCHOS_THREAD_SAFE)
532 if (strength() == RCP_STRONG) {
533 return create_strong();
538 RCPNodeHandle attemptStrong = node_.create_strong_lock();
539 return RCP<T>( attemptStrong.is_node_null() ? 0 : ptr_, attemptStrong);
549 return node_.same_node(r_ptr.access_private_node());
564 throw_null_ptr_error(
typeName(*
this));
574 node_.assert_valid_ptr(*
this);
600 *
this =
rcp(p, has_ownership_in);
615 return RCP<T>(p, owns_mem);
619 template<
class T,
class Dealloc_T>
622 Teuchos::rcpWithDealloc( T* p, Dealloc_T dealloc,
bool owns_mem )
624 return RCP<T>(p, dealloc, owns_mem);
628 template<
class T,
class Dealloc_T>
631 Teuchos::rcpWithDeallocUndef( T* p, Dealloc_T dealloc,
bool owns_mem )
633 return RCP<T>(p, dealloc, RCP_UNDEFINED_WITH_DEALLOC, owns_mem);
639 Teuchos::rcpFromRef( T& r )
641 return RCP<T>(&r, RCP_WEAK_NO_DEALLOC);
647 Teuchos::rcpFromUndefRef( T& r )
649 return RCP<T>(&r, RCP_UNDEFINED_WEAK_NO_DEALLOC);
653 template<
class T,
class Embedded>
655 Teuchos::rcpWithEmbeddedObjPreDestroy(
656 T* p,
const Embedded &embedded,
bool owns_mem
660 p, embeddedObjDeallocDelete<T>(embedded,PRE_DESTROY), owns_mem
665 template<
class T,
class Embedded>
667 Teuchos::rcpWithEmbeddedObjPostDestroy(
668 T* p,
const Embedded &embedded,
bool owns_mem
671 return rcpWithDealloc( p, embeddedObjDeallocDelete<T>(embedded,POST_DESTROY), owns_mem );
675 template<
class T,
class Embedded>
677 Teuchos::rcpWithEmbeddedObj( T* p,
const Embedded &embedded,
bool owns_mem )
679 return rcpWithEmbeddedObjPostDestroy<T,Embedded>(p,embedded,owns_mem);
683 template<
class T,
class ParentT>
685 Teuchos::rcpWithInvertedObjOwnership(
const RCP<T> &child,
686 const RCP<ParentT> &parent)
688 using std::make_pair;
695 Teuchos::rcpCloneNode(
const RCP<T> &p)
722 bool Teuchos::operator==(
const RCP<T> &p,
ENull )
724 return p.get() == NULL;
730 bool Teuchos::operator!=(
const RCP<T> &p,
ENull )
732 return p.get() != NULL;
736 template<
class T1,
class T2>
738 bool Teuchos::operator==(
const RCP<T1> &p1,
const RCP<T2> &p2 )
740 return p1.access_private_node().same_node(p2.access_private_node());
744 template<
class T1,
class T2>
746 bool Teuchos::operator!=(
const RCP<T1> &p1,
const RCP<T2> &p2 )
748 return !p1.access_private_node().same_node(p2.access_private_node());
752 template<
class T2,
class T1>
755 Teuchos::rcp_implicit_cast(
const RCP<T1>& p1)
758 T2 *check = p1.
get();
759 return RCP<T2>(check, p1.access_private_node());
763 template<
class T2,
class T1>
766 Teuchos::rcp_static_cast(
const RCP<T1>& p1)
769 T2 *check =
static_cast<T2*
>(p1.get());
770 return RCP<T2>(check, p1.access_private_node());
774 template<
class T2,
class T1>
777 Teuchos::rcp_const_cast(
const RCP<T1>& p1)
780 T2 *check =
const_cast<T2*
>(p1.get());
781 return RCP<T2>(check, p1.access_private_node());
785 template<
class T2,
class T1>
788 Teuchos::rcp_dynamic_cast(
const RCP<T1>& p1,
bool throw_on_fail)
797 p =
dynamic_cast<T2*
>(p1.get());
800 return RCP<T2>(p, p1.access_private_node());
807 template<
class T1,
class T2>
809 void Teuchos::set_extra_data(
const T1 &extra_data,
const std::string& name,
812 p->assert_not_null();
813 p->nonconst_access_private_node().set_extra_data(
814 any(extra_data), name, destroy_when,
819 template<
class T1,
class T2>
821 const T1& Teuchos::get_extra_data(
const RCP<T2>& p,
const std::string& name )
825 p.access_private_node().get_extra_data(
826 TypeNameTraits<T1>::name(), name
832 template<
class T1,
class T2>
834 T1& Teuchos::get_nonconst_extra_data( RCP<T2>& p,
const std::string& name )
838 p.nonconst_access_private_node().get_extra_data(
839 TypeNameTraits<T1>::name(), name
845 template<
class T1,
class T2>
848 Teuchos::get_optional_extra_data(
const RCP<T2>& p,
const std::string& name )
851 const any *extra_data = p.access_private_node().get_optional_extra_data(
852 TypeNameTraits<T1>::name(), name);
854 return Ptr<const T1>(&
any_cast<T1>(*extra_data));
859 template<
class T1,
class T2>
862 Teuchos::get_optional_nonconst_extra_data( RCP<T2>& p,
const std::string& name )
865 any *extra_data = p.nonconst_access_private_node().get_optional_extra_data(
866 TypeNameTraits<T1>::name(), name);
868 return Ptr<T1>(&
any_cast<T1>(*extra_data));
873 template<
class Dealloc_T,
class T>
875 const Dealloc_T& Teuchos::get_dealloc(
const RCP<T>& p )
877 return get_nonconst_dealloc<Dealloc_T>(
const_cast<RCP<T>&
>(p));
881 template<
class Dealloc_T,
class T>
883 Dealloc_T& Teuchos::get_nonconst_dealloc(
const RCP<T>& p )
885 typedef RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T> requested_type;
887 RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>
888 *dnode =
dynamic_cast<RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>*
>(
889 p.access_private_node().node_ptr());
891 dnode==NULL, NullReferenceError
892 ,
"get_dealloc<" << TypeNameTraits<Dealloc_T>::name()
893 <<
"," << TypeNameTraits<T>::name() <<
">(p): "
894 <<
"Error, requested type \'" << TypeNameTraits<requested_type>::name()
895 <<
"\' does not match actual type of the node \'"
896 <<
typeName(*p.access_private_node().node_ptr()) <<
"!"
898 return dnode->get_nonconst_dealloc();
902 template<
class Dealloc_T,
class T>
905 Teuchos::get_optional_nonconst_dealloc(
const RCP<T>& p )
908 typedef RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T> RCPNT;
909 RCPNT *dnode =
dynamic_cast<RCPNT*
>(p.access_private_node().node_ptr());
911 return ptr(&dnode->get_nonconst_dealloc());
916 template<
class Dealloc_T,
class T>
919 Teuchos::get_optional_dealloc(
const RCP<T>& p )
921 return get_optional_nonconst_dealloc<Dealloc_T>(
const_cast<RCP<T>&
>(p));
925 template<
class TOrig,
class Embedded,
class T>
926 const Embedded& Teuchos::getEmbeddedObj(
const RCP<T>& p )
928 typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
929 return get_dealloc<Dealloc_t>(p).getObj();
933 template<
class TOrig,
class Embedded,
class T>
934 Embedded& Teuchos::getNonconstEmbeddedObj(
const RCP<T>& p )
936 typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
937 return get_nonconst_dealloc<Dealloc_t>(p).getNonconstObj();
941 template<
class TOrig,
class Embedded,
class T>
943 Teuchos::getOptionalEmbeddedObj(
const RCP<T>& p )
945 typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
946 const Ptr<const Dealloc_t> dealloc = get_optional_dealloc<Dealloc_t>(p);
948 return ptr(&dealloc->getObj());
954 template<
class TOrig,
class Embedded,
class T>
956 Teuchos::getOptionalNonconstEmbeddedObj(
const RCP<T>& p )
958 typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
959 const Ptr<Dealloc_t> dealloc = get_optional_nonconst_dealloc<Dealloc_t>(p);
961 return ptr(&dealloc->getNonconstObj());
967 template<
class ParentT,
class T>
971 typedef std::pair<RCP<T>, RCP<ParentT> > Pair_t;
972 Pair_t pair = getEmbeddedObj<T, Pair_t>(invertedChild);
978 std::ostream& Teuchos::operator<<( std::ostream& out, const RCP<T>& p )
982 <<
"ptr="<<(
const void*)(p.get())
983 <<
",node="<<p.access_private_node()
984 <<
",strong_count="<<p.strong_count()
985 <<
",weak_count="<<p.weak_count()
991 #endif // TEUCHOS_RCP_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<const T> version of *this.
RCP(ENull null_arg=null)
Initialize RCP<T> to NULL.
RCP< T > create_weak() const
Create a new weak RCP object from another (strong) RCP object.
bool has_ownership() const
Returns true if this has ownership of object pointed to by this->get() in order to delete it...
bool nonnull(const std::shared_ptr< T > &p)
Returns true if p.get()!=NULL.
bool is_null(const std::shared_ptr< T > &p)
Returns true if p.get()==NULL.
ValueType & any_cast(any &operand)
Used to extract the templated value held in Teuchos::any to a given value type.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
T_To & dyn_cast(T_From &from)
Dynamic casting utility function meant to replace dynamic_cast<T&> by throwing a better documented er...
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.
void release()
Releaes the RCPNode pointer before the destructor is called.
ENull
Used to initialize a RCP object to NULL using an implicit conversion!
ERCPStrength strength() const
Strength of the pointer.
std::string concreteTypeName(const T &t)
Template function for returning the type name of the actual concrete name of a passed-in object...
bool is_null(const ArrayRCP< T > &p)
Returns true if p.get()==NULL.
T * operator->() const
Pointer (->) access to members of underlying object.
RCP< T > rcpWithEmbeddedObj(T *p, const Embedded &embedded, bool owns_mem=true)
Create an RCP with and also put in an embedded object.
Node class to keep track of address and the reference count for a reference-counted utility class and...
T * getRawPtr() const
Get the raw C++ pointer to the underlying object.
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<> objects ownership of the referenced object this->get(). ...
void reset()
Reset to null.
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 & 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.
const Ptr< T > & assert_not_null() const
Throws std::logic_error if this->get()==NULL, otherwise returns reference to *this.
const RCP< T > & assert_not_null() const
Throws NullReferenceError if this->get()==NULL, otherwise returns reference to *this.
static RCPNode * getExistingRCPNode(T *p)
Return a raw pointer to an existing owning RCPNode given the address to the underlying object if it e...
Ptr< T > release()
Release the ownership of the underlying dynamically allocated object.
Ptr< T > ptr(T *p)
Create a pointer to an object from a raw pointer.
Provides std::map class for deficient platforms.
bool is_valid_ptr() const
Return if the underlying object pointer is still valid or not.
Handle class that manages the RCPNode'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.
Reference-counted pointer class and non-member templated function implementations.
Smart reference counting pointer class for automatic garbage collection.
Deletes a (non-owning) RCPNode but not it's underlying object in case of a throw. ...
RCP< T > rcpWithDealloc(T *p, Dealloc_T dealloc, bool owns_mem=true)
Initialize from a raw pointer with a deallocation policy.
Defines basic traits returning the name of a type in a portable and readable way. ...
int strong_count() const
Return the number of active RCP<> objects that have a "strong" reference to the underlying reference-...
void swap(RCPNodeHandle &node_ref)
Swap the contents of node_ref with *this.
int weak_count() const
Return the number of active RCP<> objects that have a "weak" 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...
std::string typeName(const T &t)
Template function for returning the concrete type name of a passed-in object.
bool is_null() const
Returns true if the underlying pointer is null.