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))
164 RCPNode* existing_RCPNode = RCPNodeTracer::getExistingRCPNode(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) {
202 existing_RCPNode = RCPNodeTracer::getExistingRCPNode(p);
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_)
289 node_(r_ptr.access_private_node())
326 std::swap(r_ptr.ptr_, ptr_);
327 node_.swap(r_ptr.node_);
346 debug_assert_not_null();
347 debug_assert_valid_ptr();
356 debug_assert_not_null();
357 debug_assert_valid_ptr();
365 debug_assert_valid_ptr();
383 return Ptr<T>(this->create_weak());
385 return Ptr<T>(getRawPtr());
402 return rcp_implicit_cast<const T>(*
this);
471 debug_assert_valid_ptr();
472 node_.has_ownership(
false);
481 debug_assert_valid_ptr();
482 return RCP<T>(ptr_, node_.create_weak());
490 debug_assert_valid_ptr();
491 return RCP<T>(ptr_, node_.create_strong());
494 #if defined(HAVE_TEUCHOSCORE_CXX11) && defined(HAVE_TEUCHOS_THREAD_SAFE)
499 if (strength() == RCP_STRONG) {
500 return create_strong();
505 RCPNodeHandle attemptStrong = node_.create_strong_lock();
506 return RCP<T>( attemptStrong.is_node_null() ? 0 : ptr_, attemptStrong);
516 return node_.same_node(r_ptr.access_private_node());
567 *
this =
rcp(p, has_ownership_in);
575 return node_.
count();
590 return RCP<T>(p, owns_mem);
594 template<
class T,
class Dealloc_T>
597 Teuchos::rcpWithDealloc( T* p, Dealloc_T dealloc,
bool owns_mem )
599 return RCP<T>(p, dealloc, owns_mem);
603 template<
class T,
class Dealloc_T>
606 Teuchos::rcpWithDeallocUndef( T* p, Dealloc_T dealloc,
bool owns_mem )
608 return RCP<T>(p, dealloc, RCP_UNDEFINED_WITH_DEALLOC, owns_mem);
614 Teuchos::rcpFromRef( T& r )
616 return RCP<T>(&r, RCP_WEAK_NO_DEALLOC);
622 Teuchos::rcpFromUndefRef( T& r )
624 return RCP<T>(&r, RCP_UNDEFINED_WEAK_NO_DEALLOC);
628 template<
class T,
class Embedded>
630 Teuchos::rcpWithEmbeddedObjPreDestroy(
631 T* p,
const Embedded &embedded,
bool owns_mem
635 p, embeddedObjDeallocDelete<T>(embedded,PRE_DESTROY), owns_mem
640 template<
class T,
class Embedded>
642 Teuchos::rcpWithEmbeddedObjPostDestroy(
643 T* p,
const Embedded &embedded,
bool owns_mem
646 return rcpWithDealloc( p, embeddedObjDeallocDelete<T>(embedded,POST_DESTROY), owns_mem );
650 template<
class T,
class Embedded>
652 Teuchos::rcpWithEmbeddedObj( T* p,
const Embedded &embedded,
bool owns_mem )
654 return rcpWithEmbeddedObjPostDestroy<T,Embedded>(p,embedded,owns_mem);
658 template<
class T,
class ParentT>
660 Teuchos::rcpWithInvertedObjOwnership(
const RCP<T> &child,
661 const RCP<ParentT> &parent)
663 using std::make_pair;
670 Teuchos::rcpCloneNode(
const RCP<T> &p)
697 bool Teuchos::operator==(
const RCP<T> &p,
ENull )
699 return p.get() == NULL;
705 bool Teuchos::operator!=(
const RCP<T> &p,
ENull )
707 return p.get() != NULL;
711 template<
class T1,
class T2>
713 bool Teuchos::operator==(
const RCP<T1> &p1,
const RCP<T2> &p2 )
715 return p1.access_private_node().same_node(p2.access_private_node());
719 template<
class T1,
class T2>
721 bool Teuchos::operator!=(
const RCP<T1> &p1,
const RCP<T2> &p2 )
723 return !p1.access_private_node().same_node(p2.access_private_node());
727 template<
class T2,
class T1>
730 Teuchos::rcp_implicit_cast(
const RCP<T1>& p1)
733 T2 *check = p1.
get();
734 return RCP<T2>(check, p1.access_private_node());
738 template<
class T2,
class T1>
741 Teuchos::rcp_static_cast(
const RCP<T1>& p1)
744 T2 *check = static_cast<T2*>(p1.get());
745 return RCP<T2>(check, p1.access_private_node());
749 template<
class T2,
class T1>
752 Teuchos::rcp_const_cast(
const RCP<T1>& p1)
755 T2 *check = const_cast<T2*>(p1.get());
756 return RCP<T2>(check, p1.access_private_node());
760 template<
class T2,
class T1>
763 Teuchos::rcp_dynamic_cast(
const RCP<T1>& p1,
bool throw_on_fail)
768 p = &dyn_cast<T2>(*p1);
772 p = dynamic_cast<T2*>(p1.get());
775 return RCP<T2>(p, p1.access_private_node());
782 template<
class T1,
class T2>
784 void Teuchos::set_extra_data(
const T1 &extra_data,
const std::string& name,
787 p->assert_not_null();
788 p->nonconst_access_private_node().set_extra_data(
789 any(extra_data), name, destroy_when,
794 template<
class T1,
class T2>
796 const T1& Teuchos::get_extra_data(
const RCP<T2>& p,
const std::string& name )
800 p.access_private_node().get_extra_data(
801 TypeNameTraits<T1>::name(), name
807 template<
class T1,
class T2>
809 T1& Teuchos::get_nonconst_extra_data( RCP<T2>& p,
const std::string& name )
813 p.nonconst_access_private_node().get_extra_data(
814 TypeNameTraits<T1>::name(), name
820 template<
class T1,
class T2>
823 Teuchos::get_optional_extra_data(
const RCP<T2>& p,
const std::string& name )
826 const any *extra_data = p.access_private_node().get_optional_extra_data(
827 TypeNameTraits<T1>::name(), name);
829 return Ptr<const T1>(&any_cast<T1>(*extra_data));
834 template<
class T1,
class T2>
837 Teuchos::get_optional_nonconst_extra_data( RCP<T2>& p,
const std::string& name )
840 any *extra_data = p.nonconst_access_private_node().get_optional_extra_data(
841 TypeNameTraits<T1>::name(), name);
843 return Ptr<T1>(&any_cast<T1>(*extra_data));
848 template<
class Dealloc_T,
class T>
850 const Dealloc_T& Teuchos::get_dealloc(
const RCP<T>& p )
852 return get_nonconst_dealloc<Dealloc_T>(
const_cast<RCP<T>&
>(p));
856 template<
class Dealloc_T,
class T>
858 Dealloc_T& Teuchos::get_nonconst_dealloc(
const RCP<T>& p )
860 typedef RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T> requested_type;
862 RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>
863 *dnode =
dynamic_cast<RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>*
>(
864 p.access_private_node().node_ptr());
866 dnode==NULL, NullReferenceError
867 ,
"get_dealloc<" << TypeNameTraits<Dealloc_T>::name()
868 <<
"," << TypeNameTraits<T>::name() <<
">(p): "
869 <<
"Error, requested type \'" << TypeNameTraits<requested_type>::name()
870 <<
"\' does not match actual type of the node \'"
871 <<
typeName(*p.access_private_node().node_ptr()) <<
"!"
873 return dnode->get_nonconst_dealloc();
877 template<
class Dealloc_T,
class T>
880 Teuchos::get_optional_nonconst_dealloc(
const RCP<T>& p )
883 typedef RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T> RCPNT;
884 RCPNT *dnode = dynamic_cast<RCPNT*>(p.access_private_node().node_ptr());
886 return ptr(&dnode->get_nonconst_dealloc());
891 template<
class Dealloc_T,
class T>
894 Teuchos::get_optional_dealloc(
const RCP<T>& p )
896 return get_optional_nonconst_dealloc<Dealloc_T>(
const_cast<RCP<T>&
>(p));
900 template<
class TOrig,
class Embedded,
class T>
901 const Embedded& Teuchos::getEmbeddedObj(
const RCP<T>& p )
903 typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
904 return get_dealloc<Dealloc_t>(p).getObj();
908 template<
class TOrig,
class Embedded,
class T>
909 Embedded& Teuchos::getNonconstEmbeddedObj(
const RCP<T>& p )
911 typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
912 return get_nonconst_dealloc<Dealloc_t>(p).getNonconstObj();
916 template<
class TOrig,
class Embedded,
class T>
918 Teuchos::getOptionalEmbeddedObj(
const RCP<T>& p )
920 typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
921 const Ptr<const Dealloc_t> dealloc = get_optional_dealloc<Dealloc_t>(p);
923 return ptr(&dealloc->getObj());
929 template<
class TOrig,
class Embedded,
class T>
931 Teuchos::getOptionalNonconstEmbeddedObj(
const RCP<T>& p )
933 typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
934 const Ptr<Dealloc_t> dealloc = get_optional_nonconst_dealloc<Dealloc_t>(p);
936 return ptr(&dealloc->getNonconstObj());
942 template<
class ParentT,
class T>
946 typedef std::pair<RCP<T>, RCP<ParentT> > Pair_t;
947 Pair_t pair = getEmbeddedObj<T, Pair_t>(invertedChild);
953 std::ostream& Teuchos::operator<<( std::ostream& out,
const RCP<T>& p )
957 <<
"ptr="<<(
const void*)(p.get())
958 <<
",node="<<p.access_private_node()
959 <<
",strong_count="<<p.strong_count()
960 <<
",weak_count="<<p.weak_count()
966 #endif // TEUCHOS_RCP_HPP