42#ifndef TEUCHOS_RCP_HPP
43#define TEUCHOS_RCP_HPP
97template<
class T,
class Dealloc_T>
100 T* p, Dealloc_T dealloc,
bool has_ownership_in
107template<
class T,
class Dealloc_T>
110 T* p, Dealloc_T dealloc,
bool has_ownership_in
120 : ptr_(p), node_(node)
132RCPNodeHandle& RCP<T>::nonconst_access_private_node()
138const RCPNodeHandle& RCP<T>::access_private_node()
const
165 if (existing_RCPNode) {
201 if (!has_ownership_in) {
204 if (existing_RCPNode) {
224template<
class Dealloc_T>
250template<
class Dealloc_T>
265 p, dealloc, has_ownership_in));
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())
307 node_(r_ptr.access_private_node())
341 node_ = std::move(r_ptr.node_);
360 std::swap(r_ptr.
ptr_, ptr_);
361 node_.swap(r_ptr.
node_);
380 debug_assert_not_null();
381 debug_assert_valid_ptr();
390 debug_assert_not_null();
391 debug_assert_valid_ptr();
399 debug_assert_valid_ptr();
417 return Ptr<T>(this->create_weak());
436 return rcp_implicit_cast<const T>(*
this);
455 return node_.strength();
464 return node_.is_valid_ptr();
473 return node_.strong_count();
481 return node_.weak_count();
489 return node_.total_count();
497 node_.has_ownership(
true);
505 return node_.has_ownership();
513 debug_assert_valid_ptr();
514 node_.has_ownership(
false);
523 debug_assert_valid_ptr();
524 return RCP<T>(ptr_, node_.create_weak());
532 debug_assert_valid_ptr();
533 return RCP<T>(ptr_, node_.create_strong());
536#if defined(HAVE_TEUCHOSCORE_CXX11) && defined(HAVE_TEUCHOS_THREAD_SAFE)
542 return create_strong();
558 return node_.same_node(r_ptr.access_private_node());
573 throw_null_ptr_error(
typeName(*
this));
583 node_.assert_valid_ptr(*
this);
609 *
this =
rcp(p, has_ownership_in);
624 return RCP<T>(p, owns_mem);
628template<
class T,
class Dealloc_T>
631Teuchos::rcpWithDealloc( T* p, Dealloc_T dealloc,
bool owns_mem )
633 return RCP<T>(p, dealloc, owns_mem);
637template<
class T,
class Dealloc_T>
640Teuchos::rcpWithDeallocUndef( T* p, Dealloc_T dealloc,
bool owns_mem )
648Teuchos::rcpFromRef( T& r )
656Teuchos::rcpFromUndefRef( T& r )
662template<
class T,
class Embedded>
664Teuchos::rcpWithEmbeddedObjPreDestroy(
665 T* p,
const Embedded &embedded,
bool owns_mem
668 return rcpWithDealloc(
669 p, embeddedObjDeallocDelete<T>(embedded,PRE_DESTROY), owns_mem
674template<
class T,
class Embedded>
676Teuchos::rcpWithEmbeddedObjPostDestroy(
677 T* p,
const Embedded &embedded,
bool owns_mem
680 return rcpWithDealloc( p, embeddedObjDeallocDelete<T>(embedded,POST_DESTROY), owns_mem );
684template<
class T,
class Embedded>
686Teuchos::rcpWithEmbeddedObj( T* p,
const Embedded &embedded,
bool owns_mem )
688 return rcpWithEmbeddedObjPostDestroy<T,Embedded>(p,embedded,owns_mem);
692template<
class T,
class ParentT>
694Teuchos::rcpWithInvertedObjOwnership(
const RCP<T> &child,
697 using std::make_pair;
698 return rcpWithEmbeddedObj(child.
getRawPtr(), make_pair(child, parent),
false);
704Teuchos::rcpCloneNode(
const RCP<T> &p)
709 return rcpWithEmbeddedObj(&*p, p,
false);
733 return p.get() == NULL;
739bool Teuchos::operator!=(
const RCP<T> &p, ENull )
741 return p.
get() != NULL;
745template<
class T1,
class T2>
749 return p1.access_private_node().same_node(p2.access_private_node());
753template<
class T1,
class T2>
757 return !p1.access_private_node().same_node(p2.access_private_node());
761template<
class T2,
class T1>
764Teuchos::rcp_implicit_cast(
const RCP<T1>& p1)
767 T2 *check = p1.
get();
768 return RCP<T2>(check, p1.access_private_node());
772template<
class T2,
class T1>
775Teuchos::rcp_static_cast(
const RCP<T1>& p1)
778 T2 *check =
static_cast<T2*
>(p1.get());
779 return RCP<T2>(check, p1.access_private_node());
783template<
class T2,
class T1>
786Teuchos::rcp_const_cast(
const RCP<T1>& p1)
789 T2 *check =
const_cast<T2*
>(p1.
get());
790 return RCP<T2>(check, p1.access_private_node());
794template<
class T2,
class T1>
797Teuchos::rcp_dynamic_cast(
const RCP<T1>& p1,
bool throw_on_fail)
802 p = &dyn_cast<T2>(*p1);
806 p =
dynamic_cast<T2*
>(p1.
get());
809 return RCP<T2>(p, p1.access_private_node());
816template<
class T1,
class T2>
818void Teuchos::set_extra_data(
const T1 &extra_data,
const std::string& name,
821 p->assert_not_null();
822 p->nonconst_access_private_node().set_extra_data(
823 any(extra_data), name, destroy_when,
828template<
class T1,
class T2>
830const T1& Teuchos::get_extra_data(
const RCP<T2>& p,
const std::string& name )
841template<
class T1,
class T2>
843T1& Teuchos::get_nonconst_extra_data(
RCP<T2>& p,
const std::string& name )
854template<
class T1,
class T2>
857Teuchos::get_optional_extra_data(
const RCP<T2>& p,
const std::string& name )
868template<
class T1,
class T2>
871Teuchos::get_optional_nonconst_extra_data( RCP<T2>& p,
const std::string& name )
874 any *extra_data = p.nonconst_access_private_node().get_optional_extra_data(
875 TypeNameTraits<T1>::name(), name);
877 return Ptr<T1>(&any_cast<T1>(*extra_data));
882template<
class Dealloc_T,
class T>
884const Dealloc_T& Teuchos::get_dealloc(
const RCP<T>& p )
886 return get_nonconst_dealloc<Dealloc_T>(
const_cast<RCP<T>&
>(p));
890template<
class Dealloc_T,
class T>
892Dealloc_T& Teuchos::get_nonconst_dealloc(
const RCP<T>& p )
898 p.access_private_node().node_ptr());
904 <<
"\' does not match actual type of the node \'"
905 <<
typeName(*p.access_private_node().node_ptr()) <<
"!"
911template<
class Dealloc_T,
class T>
914Teuchos::get_optional_nonconst_dealloc(
const RCP<T>& p )
918 RCPNT *dnode =
dynamic_cast<RCPNT*
>(p.access_private_node().node_ptr());
920 return ptr(&dnode->get_nonconst_dealloc());
925template<
class Dealloc_T,
class T>
928Teuchos::get_optional_dealloc(
const RCP<T>& p )
930 return get_optional_nonconst_dealloc<Dealloc_T>(
const_cast<RCP<T>&
>(p));
934template<
class TOrig,
class Embedded,
class T>
935const Embedded& Teuchos::getEmbeddedObj(
const RCP<T>& p )
938 return get_dealloc<Dealloc_t>(p).
getObj();
942template<
class TOrig,
class Embedded,
class T>
943Embedded& Teuchos::getNonconstEmbeddedObj(
const RCP<T>& p )
950template<
class TOrig,
class Embedded,
class T>
952Teuchos::getOptionalEmbeddedObj(
const RCP<T>& p )
954 typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
955 const Ptr<const Dealloc_t> dealloc = get_optional_dealloc<Dealloc_t>(p);
956 if (!is_null(dealloc)) {
957 return ptr(&dealloc->getObj());
963template<
class TOrig,
class Embedded,
class T>
965Teuchos::getOptionalNonconstEmbeddedObj(
const RCP<T>& p )
967 typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
968 const Ptr<Dealloc_t> dealloc = get_optional_nonconst_dealloc<Dealloc_t>(p);
970 return ptr(&dealloc->getNonconstObj());
976template<
class ParentT,
class T>
980 typedef std::pair<RCP<T>, RCP<ParentT> > Pair_t;
981 Pair_t pair = getEmbeddedObj<T, Pair_t>(invertedChild);
991 <<
"ptr="<<(
const void*)(p.get())
992 <<
",node="<<p.access_private_node()
993 <<
",strong_count="<<p.strong_count()
994 <<
",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.
Policy class for deallocator that uses delete to delete a pointer which is used by RCP.
Policy class for deallocator for non-owned RCPs.
A deallocator class that wraps a simple value object and delegates to another deallocator object.
Embedded & getNonconstObj()
const Embedded & getObj() const
Null reference error exception class.
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.
Handle class that manages the RCPNode's reference counting.
RCPNodeHandle create_strong_lock() const
Return a strong handle if possible using thread safe atomics.
bool is_node_null() const
Whether the underlying RCPNode is NULL.
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...
Dealloc_T & get_nonconst_dealloc()
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...
Smart reference counting pointer class for automatic garbage collection.
RCP< const T > getConst() const
Return an RCP<const T> version of *this.
RCP< T > create_weak() const
Create a new weak RCP object from another (strong) RCP object.
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.
void swap(RCP< T > &r_ptr)
Swap the contents with some other RCP object.
RCP(ENull null_arg=null)
Initialize RCP<T> to NULL.
bool is_null() const
Returns true if the underlying pointer is null.
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.
const RCP< T > & assert_not_null() const
Throws NullReferenceError if this->get()==NULL, otherwise returns reference to *this.
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.
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.
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!
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.
Default traits class that just returns typeid(T).name().
Modified boost::any class, which is a container for a templated value.
#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.
ERCPStrength
Used to specify if the pointer is weak or strong.
std::string typeName(const T &t)
Template function for returning the concrete type name of a passed-in object.
RCPNode * RCP_createNewRCPNodeRawPtr(T *p, bool has_ownership_in)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.
std::string concreteTypeName(const T &t)
Template function for returning the type name of the actual concrete name of a passed-in object.
std::ostream & operator<<(std::ostream &os, BigUInt< n > a)
RCPNode * RCP_createNewDeallocRCPNodeRawPtrUndefined(T *p, Dealloc_T dealloc, bool has_ownership_in)
RawPointerConversionTraits< Container >::Ptr_t getRawPtr(const Container &c)
ERCPUndefinedWeakNoDealloc
@ RCP_UNDEFINED_WEAK_NO_DEALLOC
RCPNode * RCP_createNewDeallocRCPNodeRawPtr(T *p, Dealloc_T dealloc, bool has_ownership_in)
RCPNode * RCP_createNewRCPNodeRawPtrNonownedUndefined(T *p)
EPrePostDestruction
Used to specify a pre or post destruction of extra data.
RCPNode * RCP_createNewRCPNodeRawPtrNonowned(T *p)
@ RCP_UNDEFINED_WITH_DEALLOC
bool operator==(BigUInt< n > const &a, BigUInt< n > const &b)
RCP< ParentT > getInvertedObjOwnershipParent(const RCP< T > &invertedChild)
Get the parent back from an inverted ownership RCP.