10#ifndef TEUCHOS_RCP_HPP
11#define TEUCHOS_RCP_HPP
27#include "Teuchos_Ptr.hpp"
28#include "Teuchos_Assert.hpp"
29#include "Teuchos_Exceptions.hpp"
30#include "Teuchos_dyn_cast.hpp"
43RCPNode* RCP_createNewRCPNodeRawPtrNonowned( T* p )
51RCPNode* RCP_createNewRCPNodeRawPtrNonownedUndefined( T* p )
59RCPNode* RCP_createNewRCPNodeRawPtr( T* p,
bool has_ownership_in )
65template<
class T,
class Dealloc_T>
67RCPNode* RCP_createNewDeallocRCPNodeRawPtr(
68 T* p, Dealloc_T dealloc,
bool has_ownership_in
75template<
class T,
class Dealloc_T>
77RCPNode* RCP_createNewDeallocRCPNodeRawPtrUndefined(
78 T* p, Dealloc_T dealloc,
bool has_ownership_in
88 : ptr_(p), node_(node)
94T* RCP<T>::access_private_ptr()
const
100RCPNodeHandle& RCP<T>::nonconst_access_private_node()
106const RCPNodeHandle& RCP<T>::access_private_node()
const
127 , node_(RCP_createNewRCPNodeRawPtrNonowned(p))
133 if (existing_RCPNode) {
140 RCP_createNewRCPNodeRawPtrNonowned(p),
154 node_(RCP_createNewRCPNodeRawPtrNonownedUndefined(p))
163 , node_(RCP_createNewRCPNodeRawPtr(p, has_ownership_in))
169 if (!has_ownership_in) {
172 if (existing_RCPNode) {
192template<
class Dealloc_T>
197 , node_(RCP_createNewDeallocRCPNodeRawPtr(p, dealloc, has_ownership_in))
205 RCPNodeThrowDeleter nodeDeleter(RCP_createNewDeallocRCPNodeRawPtr(p, dealloc, has_ownership_in));
218template<
class Dealloc_T>
220RCP<T>::RCP( T* p, Dealloc_T dealloc, ERCPUndefinedWithDealloc,
bool has_ownership_in )
223 , node_(RCP_createNewDeallocRCPNodeRawPtrUndefined(p, dealloc, has_ownership_in))
233 p, dealloc, has_ownership_in));
248 : ptr_(r_ptr.ptr_), node_(r_ptr.node_)
255 : ptr_(r_ptr.ptr_), node_(std::move(r_ptr.node_))
266 node_(r_ptr.access_private_node())
275 node_(r_ptr.access_private_node())
294 RCP<T>(r_ptr).swap(*
this);
309 node_ = std::move(r_ptr.node_);
328 std::swap(r_ptr.ptr_, ptr_);
329 node_.swap(r_ptr.node_);
423 return node_.strength();
432 return node_.is_valid_ptr();
441 return node_.strong_count();
449 return node_.weak_count();
457 return node_.total_count();
465 node_.has_ownership(
true);
473 return node_.has_ownership();
482 node_.has_ownership(
false);
492 return RCP<T>(ptr_, node_.create_weak());
501 return RCP<T>(ptr_, node_.create_strong());
504#if defined(HAVE_TEUCHOSCORE_CXX11) && defined(HAVE_TEUCHOS_THREAD_SAFE)
509 if (strength() == RCP_STRONG) {
510 return create_strong();
515 RCPNodeHandle attemptStrong = node_.create_strong_lock();
516 return RCP<T>( attemptStrong.is_node_null() ? 0 : ptr_, attemptStrong);
526 return node_.same_node(r_ptr.access_private_node());
551 node_.assert_valid_ptr(*
this);
577 *
this =
rcp(p, has_ownership_in);
592 return RCP<T>(p, owns_mem);
596template<
class T,
class Dealloc_T>
601 return RCP<T>(p, dealloc, owns_mem);
605template<
class T,
class Dealloc_T>
610 return RCP<T>(p, dealloc, RCP_UNDEFINED_WITH_DEALLOC, owns_mem);
618 return RCP<T>(&r, RCP_WEAK_NO_DEALLOC);
626 return RCP<T>(&r, RCP_UNDEFINED_WEAK_NO_DEALLOC);
630template<
class T,
class Embedded>
633 T* p,
const Embedded &embedded,
bool owns_mem
642template<
class T,
class Embedded>
645 T* p,
const Embedded &embedded,
bool owns_mem
652template<
class T,
class Embedded>
660template<
class T,
class ParentT>
665 using std::make_pair;
699bool Teuchos::operator==(
const RCP<T> &p, ENull )
701 return p.get() == NULL;
709 return p.
get() != NULL;
713template<
class T1,
class T2>
715bool Teuchos::operator==(
const RCP<T1> &p1,
const RCP<T2> &p2 )
717 return p1.access_private_node().same_node(p2.access_private_node());
721template<
class T1,
class T2>
725 return !p1.access_private_node().same_node(p2.access_private_node());
729template<
class T2,
class T1>
735 T2 *check = p1.
get();
736 return RCP<T2>(check, p1.access_private_node());
740template<
class T2,
class T1>
746 T2 *check =
static_cast<T2*
>(p1.get());
747 return RCP<T2>(check, p1.access_private_node());
751template<
class T2,
class T1>
757 T2 *check =
const_cast<T2*
>(p1.
get());
758 return RCP<T2>(check, p1.access_private_node());
762template<
class T2,
class T1>
774 p =
dynamic_cast<T2*
>(p1.
get());
777 return RCP<T2>(p, p1.access_private_node());
784template<
class T1,
class T2>
790 p->nonconst_access_private_node().set_extra_data(
791 any(extra_data), name, destroy_when,
796template<
class T1,
class T2>
809template<
class T1,
class T2>
822template<
class T1,
class T2>
836template<
class T1,
class T2>
842 any *extra_data = p.nonconst_access_private_node().get_optional_extra_data(
843 TypeNameTraits<T1>::name(), name);
850template<
class Dealloc_T,
class T>
858template<
class Dealloc_T,
class T>
862 typedef RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T> requested_type;
864 RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>
865 *dnode =
dynamic_cast<RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>*
>(
866 p.access_private_node().node_ptr());
868 dnode==NULL, NullReferenceError
869 ,
"get_dealloc<" << TypeNameTraits<Dealloc_T>::name()
870 <<
"," << TypeNameTraits<T>::name() <<
">(p): "
871 <<
"Error, requested type \'" << TypeNameTraits<requested_type>::name()
872 <<
"\' does not match actual type of the node \'"
873 << typeName(*p.access_private_node().node_ptr()) <<
"!"
875 return dnode->get_nonconst_dealloc();
879template<
class Dealloc_T,
class T>
885 typedef RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T> RCPNT;
886 RCPNT *dnode =
dynamic_cast<RCPNT*
>(p.access_private_node().node_ptr());
888 return ptr(&dnode->get_nonconst_dealloc());
893template<
class Dealloc_T,
class T>
898 return get_optional_nonconst_dealloc<Dealloc_T>(
const_cast<RCP<T>&
>(p));
902template<
class TOrig,
class Embedded,
class T>
905 typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
906 return get_dealloc<Dealloc_t>(p).getObj();
910template<
class TOrig,
class Embedded,
class T>
913 typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
914 return get_nonconst_dealloc<Dealloc_t>(p).getNonconstObj();
918template<
class TOrig,
class Embedded,
class T>
922 typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
923 const Ptr<const Dealloc_t> dealloc = get_optional_dealloc<Dealloc_t>(p);
925 return ptr(&dealloc->getObj());
931template<
class TOrig,
class Embedded,
class T>
935 typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
936 const Ptr<Dealloc_t> dealloc = get_optional_nonconst_dealloc<Dealloc_t>(p);
938 return ptr(&dealloc->getNonconstObj());
944template<
class ParentT,
class T>
948 typedef std::pair<RCP<T>, RCP<ParentT> > Pair_t;
949 Pair_t pair = getEmbeddedObj<T, Pair_t>(invertedChild);
955std::ostream& Teuchos::operator<<( std::ostream& out,
const RCP<T>& p )
959 <<
"ptr="<<(
const void*)(p.get())
960 <<
",node="<<p.access_private_node()
961 <<
",strong_count="<<p.strong_count()
962 <<
",weak_count="<<p.weak_count()
Reference-counted pointer class and non-member templated function implementations.
Defines basic traits returning the name of a type in a portable and readable way.
Provides std::map class for deficient platforms.
T1 * get_optional_extra_data(ArrayRCP< T2 > &p, const std::string &name)
Get a pointer to non-const extra data (if it exists) associated with a ArrayRCP object.
Embedded & getNonconstEmbeddedObj(const ArrayRCP< T > &p)
Get a const reference to an embedded object that was set by calling arcpWithEmbeddedObjPreDestroy(),...
T1 & get_extra_data(ArrayRCP< T2 > &p, const std::string &name)
Get a non-const reference to extra data associated with a ArrayRCP object.
const Dealloc_T * get_optional_dealloc(const ArrayRCP< T > &p)
Return a pointer to the underlying non-const deallocator object if it exists.
void set_extra_data(const T1 &extra_data, const std::string &name, const Ptr< ArrayRCP< T2 > > &p, EPrePostDestruction destroy_when=POST_DESTROY, bool force_unique=true)
Set extra data associated with a ArrayRCP object.
const Dealloc_T & get_dealloc(const ArrayRCP< T > &p)
Return a const reference to the underlying deallocator object.
Dealloc_T * get_optional_nonconst_dealloc(const ArrayRCP< T > &p)
Return a pointer to the underlying const deallocator object if it exists.
Dealloc_T & get_nonconst_dealloc(const ArrayRCP< T > &p)
Return a non-const reference to the underlying deallocator object.
const Embedded & getEmbeddedObj(const ArrayRCP< T > &p)
Get a const reference to an embedded object that was set by calling arcpWithEmbeddedObjPreDestroy(),...
Policy class for deallocator that uses delete to delete a pointer which is used by RCP.
Policy class for deallocator for non-owned RCPs.
EmbeddedObjDealloc< T, Embedded, DeallocDelete< T > > embeddedObjDeallocDelete(const Embedded &embedded, EPrePostDestruction prePostDestroy)
Create a dealocator with an embedded object using delete.
T & get(ParameterList &l, const std::string &name)
A shorter name for getParameter().
Simple wrapper class for raw pointers to single objects where no persisting relationship exists.
const Ptr< T > & assert_not_null() const
Throws std::logic_error if this->get()==NULL, otherwise returns reference to *this.
Ptr< T > ptr(T *p)
Create a pointer to an object from a raw pointer.
Handle class that manages the RCPNode's reference counting.
void swap(RCPNodeHandle &node_ref)
Swap the contents of node_ref with *this.
Deletes a (non-owning) RCPNode but not it's underlying object in case of a throw.
void release()
Releaes the RCPNode pointer before the destructor is called.
Templated implementation class of RCPNode that has the responsibility for deleting the reference-coun...
static RCPNode * getExistingRCPNode(T *p)
Return a raw pointer to an existing owning RCPNode given the address to the underlying object if it e...
Node class to keep track of address and the reference count for a reference-counted utility class and...
TEUCHOSCORE_LIB_DLL_EXPORT void throw_null_ptr_error(const std::string &type_name)
Throw that a pointer passed into an RCP object is null.
Smart reference counting pointer class for automatic garbage collection.
RCP< const T > getConst() const
Return an RCP<const T> version of *this.
RCP< T > rcpWithEmbeddedObjPreDestroy(T *p, const Embedded &embedded, bool owns_mem=true)
Create an RCP with and also put in an embedded object.
RCP< T > create_weak() const
Create a new weak RCP object from another (strong) RCP object.
RCP< T > rcpWithDealloc(T *p, Dealloc_T dealloc, bool owns_mem=true)
Initialize from a raw pointer with a deallocation policy.
bool is_null(const RCP< const FileNameValidator > &p)
RCP< T2 > rcp_dynamic_cast(const RCP< T1 > &p1, bool throw_on_fail=false)
Dynamic cast of underlying RCP type from T1* to T2*.
RCP< T2 > rcp_static_cast(const RCP< T1 > &p1)
Static cast of underlying RCP type from T1* to T2*.
Ptr< Embedded > getOptionalNonconstEmbeddedObj(const RCP< T > &p)
Get an optional Ptr to a non-const embedded object if it was set by calling rcpWithEmbeddedObjPreDest...
Ptr< T > release()
Release the ownership of the underlying dynamically allocated object.
void reset()
Reset to null.
void set_has_ownership()
Give this and other RCP<> objects ownership of the referenced object this->get().
~RCP()
Removes a reference to a dynamically allocated object and possibly deletes the object if owned.
const RCP< T > & assert_valid_ptr() const
If the object pointer is non-null, assert that it is still valid.
bool shares_resource(const RCP< T2 > &r_ptr) const
Returns true if the smart pointers share the same underlying reference-counted object.
RCP< T > rcpWithEmbeddedObj(T *p, const Embedded &embedded, bool owns_mem=true)
Create an RCP with and also put in an embedded object.
RCP< T2 > rcp_implicit_cast(const RCP< T1 > &p1)
Implicit cast of underlying RCP type from T1* to T2*.
void swap(RCP< T > &r_ptr)
Swap the contents with some other RCP object.
RCP< T2 > rcp_const_cast(const RCP< T1 > &p1)
Constant cast of underlying RCP type from T1* to T2*.
RCP< T > rcpWithDeallocUndef(T *p, Dealloc_T dealloc, bool owns_mem=true)
Initialize from a raw pointer with a deallocation policy for an undefined type.
RCP< T > rcpFromRef(T &r)
Return a non-owning weak RCP object from a raw object reference for a defined type.
RCP(ENull null_arg=null)
Initialize RCP<T> to NULL.
Ptr< T1 > get_optional_nonconst_extra_data(RCP< T2 > &p, const std::string &name)
Get a pointer to non-const extra data (if it exists) associated with a RCP object.
bool is_null() const
Returns true if the underlying pointer is null.
RCP< T > rcpFromUndefRef(T &r)
Return a non-owning weak RCP object from a raw object reference for an undefined type.
RCP< T > rcpWithEmbeddedObjPostDestroy(T *p, const Embedded &embedded, bool owns_mem=true)
Create an RCP with and also put in an embedded object.
T * getRawPtr() const
Get the raw C++ pointer to the underlying object.
Ptr< T > ptr() const
Get a safer wrapper raw C++ pointer to the underlying object.
T1 & get_nonconst_extra_data(RCP< T2 > &p, const std::string &name)
Get a non-const reference to extra data associated with a RCP object.
const RCP< T > & assert_not_null() const
Throws NullReferenceError if this->get()==NULL, otherwise returns reference to *this.
const RCP< T > & debug_assert_valid_ptr() const
Calls assert_valid_ptr() in a debug build.
Ptr< const T1 > get_optional_extra_data(const RCP< T2 > &p, const std::string &name)
Get a pointer to const extra data (if it exists) associated with a RCP object.
T * operator->() const
Pointer (->) access to members of underlying object.
bool is_valid_ptr() const
Return if the underlying object pointer is still valid or not.
const T1 & get_extra_data(const RCP< T2 > &p, const std::string &name)
Get a const reference to extra data associated with a RCP object.
RCP< T > create_strong() const
Create a new strong RCP object from another (weak) RCP object.
RCP< T > rcpWithInvertedObjOwnership(const RCP< T > &child, const RCP< ParentT > &parent)
Create a new RCP that inverts the ownership of parent and child.
bool has_ownership() const
Returns true if this has ownership of object pointed to by this->get() in order to delete it.
T * get() const
Get the raw C++ pointer to the underlying object.
ERCPStrength strength() const
Strength of the pointer.
RCP< T > rcpCloneNode(const RCP< T > &p)
Allocate a new RCP object with a new RCPNode with memory pointing to the initial node.
Ptr< const Embedded > getOptionalEmbeddedObj(const RCP< T > &p)
Get an optional Ptr to a const embedded object if it was set by calling rcpWithEmbeddedObjPreDestroy(...
int weak_count() const
Return the number of active RCP<> objects that have a "weak" reference to the underlying reference-co...
ENull
Used to initialize a RCP object to NULL using an implicit conversion!
const RCP< T > & debug_assert_not_null() const
Calls assert_not_null() in a debug build.
RCP< T > & operator=(const RCP< T > &r_ptr)
Copy the pointer to the referenced object and increment the reference count.
int total_count() const
Total count (strong_count() + weak_count()).
int strong_count() const
Return the number of active RCP<> objects that have a "strong" reference to the underlying reference-...
Ptr< T > operator()() const
Shorthand for ptr().
T & operator*() const
Dereference the underlying object.
static std::string name()
Modified boost::any class, which is a container for a templated value.
bool operator!=(const any &a, const any &b)
Returns true if two any objects do not have the same value.
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.
bool is_null(const boost::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.
bool nonnull(const std::shared_ptr< T > &p)
Returns true if p.get()!=NULL.
std::string typeName(const T &t)
Template function for returning the concrete type name of a passed-in object.
std::string concreteTypeName(const T &t)
Template function for returning the type name of the actual concrete name of a passed-in object.
T_To & dyn_cast(T_From &from)
Dynamic casting utility function meant to replace dynamic_cast<T&> by throwing a better documented er...
ERCPStrength
Used to specify if the pointer is weak or strong.
EPrePostDestruction
Used to specify a pre or post destruction of extra data.
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos,...
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.
RCP< ParentT > getInvertedObjOwnershipParent(const RCP< T > &invertedChild)
Get the parent back from an inverted ownership RCP.