Teuchos - Trilinos Tools Package Version of the Day
Teuchos_RCP.hpp
Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 //
00004 //                    Teuchos: Common Tools Package
00005 //                 Copyright (2004) Sandia Corporation
00006 //
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ***********************************************************************
00040 // @HEADER
00041 
00042 #ifndef TEUCHOS_RCP_HPP
00043 #define TEUCHOS_RCP_HPP
00044 
00045 
00058 #include "Teuchos_RCPDecl.hpp"
00059 #include "Teuchos_Ptr.hpp"
00060 #include "Teuchos_Assert.hpp"
00061 #include "Teuchos_Exceptions.hpp"
00062 #include "Teuchos_dyn_cast.hpp"
00063 #include "Teuchos_map.hpp"
00064 #include "Teuchos_TypeNameTraits.hpp"
00065 
00066 
00067 namespace Teuchos {
00068 
00069 
00070 // very bad public functions
00071 
00072 
00073 template<class T>
00074 inline
00075 RCPNode* RCP_createNewRCPNodeRawPtrNonowned( T* p )
00076 {
00077   return new RCPNodeTmpl<T,DeallocNull<T> >(p, DeallocNull<T>(), false);
00078 }
00079 
00080 
00081 template<class T>
00082 inline
00083 RCPNode* RCP_createNewRCPNodeRawPtrNonownedUndefined( T* p )
00084 {
00085   return new RCPNodeTmpl<T,DeallocNull<T> >(p, DeallocNull<T>(), false, null);
00086 }
00087 
00088 
00089 template<class T>
00090 inline
00091 RCPNode* RCP_createNewRCPNodeRawPtr( T* p, bool has_ownership_in )
00092 {
00093   return new RCPNodeTmpl<T,DeallocDelete<T> >(p, DeallocDelete<T>(), has_ownership_in);
00094 }
00095 
00096 
00097 template<class T, class Dealloc_T>
00098 inline
00099 RCPNode* RCP_createNewDeallocRCPNodeRawPtr(
00100   T* p, Dealloc_T dealloc, bool has_ownership_in
00101   )
00102 {
00103   return new RCPNodeTmpl<T,Dealloc_T>(p, dealloc, has_ownership_in);
00104 }
00105 
00106 
00107 template<class T, class Dealloc_T>
00108 inline
00109 RCPNode* RCP_createNewDeallocRCPNodeRawPtrUndefined(
00110   T* p, Dealloc_T dealloc, bool has_ownership_in
00111   )
00112 {
00113   return new RCPNodeTmpl<T,Dealloc_T>(p, dealloc, has_ownership_in, null);
00114 }
00115 
00116 
00117 template<class T>
00118 inline
00119 RCP<T>::RCP( T* p, const RCPNodeHandle& node)
00120   : ptr_(p), node_(node)
00121 {}
00122 
00123 
00124 template<class T>
00125 inline
00126 T* RCP<T>::access_private_ptr() const
00127 {  return ptr_; }
00128 
00129 
00130 template<class T>
00131 inline
00132 RCPNodeHandle& RCP<T>::nonconst_access_private_node()
00133 {  return node_; }
00134 
00135 
00136 template<class T>
00137 inline
00138 const RCPNodeHandle& RCP<T>::access_private_node() const
00139 {  return node_; }
00140 
00141 
00142 
00143 
00144 // Constructors/destructors/initializers
00145 
00146 
00147 template<class T>
00148 inline
00149 RCP<T>::RCP( ENull )
00150   : ptr_(NULL)
00151 {}
00152 
00153 
00154 template<class T>
00155 inline
00156 RCP<T>::RCP( T* p, ERCPWeakNoDealloc )
00157   : ptr_(p)
00158 #ifndef TEUCHOS_DEBUG
00159   , node_(RCP_createNewRCPNodeRawPtrNonowned(p))
00160 #endif // TEUCHOS_DEBUG
00161 {
00162 #ifdef TEUCHOS_DEBUG
00163   if (p) {
00164     RCPNode* existing_RCPNode = RCPNodeTracer::getExistingRCPNode(p);
00165     if (existing_RCPNode) {
00166       // Will not call add_new_RCPNode(...)
00167       node_ = RCPNodeHandle(existing_RCPNode, RCP_WEAK, false);
00168     }
00169     else {
00170       // Will call add_new_RCPNode(...)
00171       node_ = RCPNodeHandle(
00172         RCP_createNewRCPNodeRawPtrNonowned(p),
00173         p, typeName(*p), concreteTypeName(*p),
00174         false
00175         );
00176     }
00177   }
00178 #endif // TEUCHOS_DEBUG
00179 }
00180 
00181 
00182 template<class T>
00183 inline
00184 RCP<T>::RCP( T* p, ERCPUndefinedWeakNoDealloc )
00185   : ptr_(p),
00186     node_(RCP_createNewRCPNodeRawPtrNonownedUndefined(p))
00187 {}
00188 
00189 
00190 template<class T>
00191 inline
00192 RCP<T>::RCP( T* p, bool has_ownership_in )
00193   : ptr_(p)
00194 #ifndef TEUCHOS_DEBUG
00195   , node_(RCP_createNewRCPNodeRawPtr(p, has_ownership_in))
00196 #endif // TEUCHOS_DEBUG
00197 {
00198 #ifdef TEUCHOS_DEBUG
00199   if (p) {
00200     RCPNode* existing_RCPNode = 0;
00201     if (!has_ownership_in) {
00202       existing_RCPNode = RCPNodeTracer::getExistingRCPNode(p);
00203     }
00204     if (existing_RCPNode) {
00205       // Will not call add_new_RCPNode(...)
00206       node_ = RCPNodeHandle(existing_RCPNode, RCP_WEAK, false);
00207     }
00208     else {
00209       // Will call add_new_RCPNode(...)
00210       RCPNodeThrowDeleter nodeDeleter(RCP_createNewRCPNodeRawPtr(p, has_ownership_in));
00211       node_ = RCPNodeHandle(
00212         nodeDeleter.get(),
00213         p, typeName(*p), concreteTypeName(*p),
00214         has_ownership_in
00215         );
00216       nodeDeleter.release();
00217     }
00218   }
00219 #endif // TEUCHOS_DEBUG
00220 }
00221 
00222 
00223 template<class T>
00224 template<class Dealloc_T>
00225 inline
00226 RCP<T>::RCP( T* p, Dealloc_T dealloc, bool has_ownership_in )
00227   : ptr_(p)
00228 #ifndef TEUCHOS_DEBUG
00229   , node_(RCP_createNewDeallocRCPNodeRawPtr(p, dealloc, has_ownership_in))
00230 #endif // TEUCHOS_DEBUG
00231 {
00232 #ifdef TEUCHOS_DEBUG
00233   if (p) {
00234     // Here we are assuming that if the user passed in a custom deallocator
00235     // then they will want to have ownership (otherwise it will throw if it is
00236     // the same object).
00237     RCPNodeThrowDeleter nodeDeleter(RCP_createNewDeallocRCPNodeRawPtr(p, dealloc, has_ownership_in));
00238     node_ = RCPNodeHandle(
00239       nodeDeleter.get(),
00240       p, typeName(*p), concreteTypeName(*p),
00241       has_ownership_in
00242       );
00243     nodeDeleter.release();
00244   }
00245 #endif // TEUCHOS_DEBUG
00246 }
00247 
00248 
00249 template<class T>
00250 template<class Dealloc_T>
00251 inline
00252 RCP<T>::RCP( T* p, Dealloc_T dealloc, ERCPUndefinedWithDealloc, bool has_ownership_in )
00253   : ptr_(p)
00254 #ifndef TEUCHOS_DEBUG
00255   , node_(RCP_createNewDeallocRCPNodeRawPtrUndefined(p, dealloc, has_ownership_in))
00256 #endif // TEUCHOS_DEBUG
00257 {
00258 #ifdef TEUCHOS_DEBUG
00259   if (p) {
00260     // Here we are assuming that if the user passed in a custom deallocator
00261     // then they will want to have ownership (otherwise it will throw if it is
00262     // the same object).
00263     // Use auto_ptr to ensure we don't leak if a throw occurs
00264     RCPNodeThrowDeleter nodeDeleter(RCP_createNewDeallocRCPNodeRawPtrUndefined(
00265       p, dealloc, has_ownership_in));
00266     node_ = RCPNodeHandle(
00267       nodeDeleter.get(),
00268       p, typeName(*p), concreteTypeName(*p),
00269       has_ownership_in
00270       );
00271     nodeDeleter.release();
00272   }
00273 #endif // TEUCHOS_DEBUG
00274 }
00275 
00276 
00277 template<class T>
00278 inline
00279 RCP<T>::RCP(const RCP<T>& r_ptr)
00280   : ptr_(r_ptr.ptr_), node_(r_ptr.node_)
00281 {}
00282 
00283 
00284 template<class T>
00285 template<class T2>
00286 inline
00287 RCP<T>::RCP(const RCP<T2>& r_ptr)
00288   : ptr_(r_ptr.get()), // will not compile if T is not base class of T2
00289     node_(r_ptr.access_private_node())
00290 {}
00291 
00292 
00293 template<class T>
00294 inline
00295 RCP<T>::~RCP()
00296 {}
00297 
00298 
00299 template<class T>
00300 inline
00301 RCP<T>& RCP<T>::operator=(const RCP<T>& r_ptr)
00302 {
00303 #ifdef TEUCHOS_DEBUG
00304   if (this == &r_ptr)
00305     return *this;
00306   reset(); // Force delete first in debug mode!
00307 #endif
00308   RCP<T>(r_ptr).swap(*this);
00309   return *this;
00310 }
00311 
00312 
00313 template<class T>
00314 inline
00315 RCP<T>& RCP<T>::operator=(ENull)
00316 {
00317   reset();
00318   return *this;
00319 }
00320 
00321 
00322 template<class T>
00323 inline
00324 void RCP<T>::swap(RCP<T> &r_ptr)
00325 {
00326   std::swap(r_ptr.ptr_, ptr_);
00327   node_.swap(r_ptr.node_);
00328 }
00329 
00330 
00331 // Object query and access functions
00332 
00333 
00334 template<class T>
00335 inline
00336 bool RCP<T>::is_null() const
00337 {
00338   return ptr_ == 0;
00339 }
00340 
00341 
00342 template<class T>
00343 inline
00344 T* RCP<T>::operator->() const
00345 {
00346   debug_assert_not_null();
00347   debug_assert_valid_ptr();
00348   return ptr_;
00349 }
00350 
00351 
00352 template<class T>
00353 inline
00354 T& RCP<T>::operator*() const
00355 {
00356   debug_assert_not_null();
00357   debug_assert_valid_ptr();
00358   return *ptr_;
00359 }
00360 
00361 template<class T>
00362 inline
00363 T* RCP<T>::get() const
00364 {
00365   debug_assert_valid_ptr();
00366   return ptr_;
00367 }
00368 
00369 
00370 template<class T>
00371 inline
00372 T* RCP<T>::getRawPtr() const
00373 {
00374   return this->get();
00375 }
00376 
00377 
00378 template<class T>
00379 inline
00380 Ptr<T> RCP<T>::ptr() const
00381 {
00382 #ifdef TEUCHOS_DEBUG
00383   return Ptr<T>(this->create_weak());
00384 #else
00385   return Ptr<T>(getRawPtr());
00386 #endif
00387 }
00388 
00389 
00390 template<class T>
00391 inline
00392 Ptr<T> RCP<T>::operator()() const
00393 {
00394   return ptr();
00395 }
00396 
00397 
00398 template<class T>
00399 inline
00400 RCP<const T> RCP<T>::getConst() const
00401 {
00402   return rcp_implicit_cast<const T>(*this);
00403 }
00404 
00405 
00406 // Reference counting
00407 
00408 
00409 template<class T>
00410 inline
00411 ERCPStrength RCP<T>::strength() const
00412 {
00413   return node_.strength();
00414 }
00415 
00416 
00417 template<class T>
00418 inline
00419 bool RCP<T>::is_valid_ptr() const
00420 {
00421   if (ptr_)
00422     return node_.is_valid_ptr();
00423   return true;
00424 }
00425 
00426 
00427 template<class T>
00428 inline
00429 int RCP<T>::strong_count() const
00430 {
00431   return node_.strong_count();
00432 }
00433 
00434 
00435 template<class T>
00436 inline
00437 int RCP<T>::weak_count() const
00438 {
00439   return node_.weak_count();
00440 }
00441 
00442 
00443 template<class T>
00444 inline
00445 int RCP<T>::total_count() const
00446 {
00447   return node_.total_count();
00448 }
00449 
00450 
00451 template<class T>
00452 inline
00453 void RCP<T>::set_has_ownership()
00454 {
00455   node_.has_ownership(true);
00456 }
00457 
00458 
00459 template<class T>
00460 inline
00461 bool RCP<T>::has_ownership() const
00462 {
00463   return node_.has_ownership();
00464 }
00465 
00466 
00467 template<class T>
00468 inline
00469 Ptr<T> RCP<T>::release()
00470 {
00471   debug_assert_valid_ptr();
00472   node_.has_ownership(false);
00473   return Ptr<T>(ptr_);
00474 }
00475 
00476 
00477 template<class T>
00478 inline
00479 RCP<T> RCP<T>::create_weak() const
00480 {
00481   debug_assert_valid_ptr();
00482   return RCP<T>(ptr_, node_.create_weak());
00483 }
00484 
00485 
00486 template<class T>
00487 inline
00488 RCP<T> RCP<T>::create_strong() const
00489 {
00490   debug_assert_valid_ptr();
00491   return RCP<T>(ptr_, node_.create_strong());
00492 }
00493 
00494 
00495 template<class T>
00496 template <class T2>
00497 inline
00498 bool RCP<T>::shares_resource(const RCP<T2>& r_ptr) const
00499 {
00500   return node_.same_node(r_ptr.access_private_node());
00501   // Note: above, r_ptr is *not* the same class type as *this so we can not
00502   // access its node_ member directly!  This is an interesting detail to the
00503   // C++ protected/private protection mechanism!
00504 }
00505 
00506 
00507 // Assertions
00508 
00509 
00510 template<class T>
00511 inline
00512 const RCP<T>& RCP<T>::assert_not_null() const
00513 {
00514   if (!ptr_)
00515     throw_null_ptr_error(typeName(*this));
00516   return *this;
00517 }
00518 
00519 
00520 template<class T>
00521 inline
00522 const RCP<T>& RCP<T>::assert_valid_ptr() const
00523 {
00524   if (ptr_)
00525     node_.assert_valid_ptr(*this);
00526   return *this;
00527 }
00528 
00529 
00530 // boost::shared_ptr compatiblity funtions
00531 
00532 
00533 template<class T>
00534 inline
00535 void RCP<T>::reset()
00536 {
00537 #ifdef TEUCHOS_DEBUG
00538   node_ = RCPNodeHandle();
00539 #else
00540   RCPNodeHandle().swap(node_);
00541 #endif
00542   ptr_ = 0;
00543 }
00544 
00545 
00546 template<class T>
00547 template<class T2>
00548 inline
00549 void RCP<T>::reset(T2* p, bool has_ownership_in)
00550 {
00551   *this = rcp(p, has_ownership_in);
00552 }
00553 
00554 
00555 template<class T>
00556 inline
00557 int RCP<T>::count() const
00558 {
00559   return node_.count();
00560 }
00561 
00562 }  // end namespace Teuchos
00563 
00564 
00565 // /////////////////////////////////////////////////////////////////////////////////
00566 // Inline non-member functions for RCP
00567 
00568 
00569 template<class T>
00570 inline
00571 Teuchos::RCP<T>
00572 Teuchos::rcp( T* p, bool owns_mem )
00573 {
00574   return RCP<T>(p, owns_mem);
00575 }
00576 
00577 
00578 template<class T, class Dealloc_T>
00579 inline
00580 Teuchos::RCP<T>
00581 Teuchos::rcpWithDealloc( T* p, Dealloc_T dealloc, bool owns_mem )
00582 {
00583   return RCP<T>(p, dealloc, owns_mem);
00584 }
00585 
00586 
00587 template<class T, class Dealloc_T>
00588 inline
00589 Teuchos::RCP<T>
00590 Teuchos::rcpWithDeallocUndef( T* p, Dealloc_T dealloc, bool owns_mem )
00591 {
00592   return RCP<T>(p, dealloc, RCP_UNDEFINED_WITH_DEALLOC, owns_mem);
00593 }
00594 
00595 
00596 template<class T>
00597 Teuchos::RCP<T>
00598 Teuchos::rcpFromRef( T& r )
00599 {
00600   return RCP<T>(&r, RCP_WEAK_NO_DEALLOC);
00601 }
00602 
00603 
00604 template<class T>
00605 Teuchos::RCP<T>
00606 Teuchos::rcpFromUndefRef( T& r )
00607 {
00608   return RCP<T>(&r, RCP_UNDEFINED_WEAK_NO_DEALLOC);
00609 }
00610 
00611 
00612 template<class T, class Embedded>
00613 Teuchos::RCP<T>
00614 Teuchos::rcpWithEmbeddedObjPreDestroy(
00615   T* p, const Embedded &embedded, bool owns_mem
00616   )
00617 {
00618   return rcpWithDealloc(
00619     p, embeddedObjDeallocDelete<T>(embedded,PRE_DESTROY), owns_mem
00620     );
00621 }
00622 
00623 
00624 template<class T, class Embedded>
00625 Teuchos::RCP<T>
00626 Teuchos::rcpWithEmbeddedObjPostDestroy(
00627   T* p, const Embedded &embedded, bool owns_mem
00628   )
00629 {
00630   return rcpWithDealloc( p, embeddedObjDeallocDelete<T>(embedded,POST_DESTROY), owns_mem );
00631 }
00632 
00633 
00634 template<class T, class Embedded>
00635 Teuchos::RCP<T>
00636 Teuchos::rcpWithEmbeddedObj( T* p, const Embedded &embedded, bool owns_mem )
00637 {
00638   return rcpWithEmbeddedObjPostDestroy<T,Embedded>(p,embedded,owns_mem);
00639 }
00640 
00641 
00642 template<class T, class ParentT>
00643 Teuchos::RCP<T>
00644 Teuchos::rcpWithInvertedObjOwnership(const RCP<T> &child,
00645   const RCP<ParentT> &parent)
00646 {
00647   using std::make_pair;
00648   return rcpWithEmbeddedObj(child.getRawPtr(), make_pair(child, parent), false);
00649 }
00650 
00651 
00652 template<class T>
00653 Teuchos::RCP<T>
00654 Teuchos::rcpCloneNode(const RCP<T> &p)
00655 {
00656   if (is_null(p)) {
00657     return p;
00658   }
00659   return rcpWithEmbeddedObj(&*p, p, false);
00660 }
00661 
00662 
00663 template<class T>
00664 inline
00665 bool Teuchos::is_null( const RCP<T> &p )
00666 {
00667   return p.is_null();
00668 }
00669 
00670 
00671 template<class T>
00672 inline
00673 bool Teuchos::nonnull( const RCP<T> &p )
00674 {
00675   return !p.is_null();
00676 }
00677 
00678 
00679 template<class T>
00680 inline
00681 bool Teuchos::operator==( const RCP<T> &p, ENull )
00682 {
00683   return p.get() == NULL;
00684 }
00685 
00686 
00687 template<class T>
00688 inline
00689 bool Teuchos::operator!=( const RCP<T> &p, ENull )
00690 {
00691   return p.get() != NULL;
00692 }
00693 
00694 
00695 template<class T1, class T2>
00696 inline
00697 bool Teuchos::operator==( const RCP<T1> &p1, const RCP<T2> &p2 )
00698 {
00699   return p1.access_private_node().same_node(p2.access_private_node());
00700 }
00701 
00702 
00703 template<class T1, class T2>
00704 inline
00705 bool Teuchos::operator!=( const RCP<T1> &p1, const RCP<T2> &p2 )
00706 {
00707   return !p1.access_private_node().same_node(p2.access_private_node());
00708 }
00709 
00710 
00711 template<class T2, class T1>
00712 inline
00713 Teuchos::RCP<T2>
00714 Teuchos::rcp_implicit_cast(const RCP<T1>& p1)
00715 {
00716   // Make the compiler check if the conversion is legal
00717   T2 *check = p1.get();
00718   return RCP<T2>(check, p1.access_private_node());
00719 }
00720 
00721 
00722 template<class T2, class T1>
00723 inline
00724 Teuchos::RCP<T2>
00725 Teuchos::rcp_static_cast(const RCP<T1>& p1)
00726 {
00727   // Make the compiler check if the conversion is legal
00728   T2 *check = static_cast<T2*>(p1.get());
00729   return RCP<T2>(check, p1.access_private_node());
00730 }
00731 
00732 
00733 template<class T2, class T1>
00734 inline
00735 Teuchos::RCP<T2>
00736 Teuchos::rcp_const_cast(const RCP<T1>& p1)
00737 {
00738   // Make the compiler check if the conversion is legal
00739   T2 *check = const_cast<T2*>(p1.get());
00740   return RCP<T2>(check, p1.access_private_node());
00741 }
00742 
00743 
00744 template<class T2, class T1>
00745 inline
00746 Teuchos::RCP<T2>
00747 Teuchos::rcp_dynamic_cast(const RCP<T1>& p1, bool throw_on_fail)
00748 {
00749   if (!is_null(p1)) {
00750     T2 *p = NULL;
00751     if (throw_on_fail) {
00752       p = &dyn_cast<T2>(*p1);
00753     }
00754     else {
00755       // Make the compiler check if the conversion is legal
00756       p = dynamic_cast<T2*>(p1.get());
00757     }
00758     if (p) {
00759       return RCP<T2>(p, p1.access_private_node());
00760     }
00761   }
00762   return null;
00763 }
00764 
00765 
00766 template<class T1, class T2>
00767 inline
00768 void Teuchos::set_extra_data( const T1 &extra_data, const std::string& name,
00769   const Ptr<RCP<T2> > &p, EPrePostDestruction destroy_when, bool force_unique )
00770 {
00771   p->assert_not_null();
00772   p->nonconst_access_private_node().set_extra_data(
00773     any(extra_data), name, destroy_when,
00774     force_unique );
00775 }
00776 
00777 
00778 template<class T1, class T2>
00779 inline
00780 const T1& Teuchos::get_extra_data( const RCP<T2>& p, const std::string& name )
00781 {
00782   p.assert_not_null();
00783   return any_cast<T1>(
00784     p.access_private_node().get_extra_data(
00785       TypeNameTraits<T1>::name(), name
00786       )
00787     );
00788 }
00789 
00790 
00791 template<class T1, class T2>
00792 inline
00793 T1& Teuchos::get_nonconst_extra_data( RCP<T2>& p, const std::string& name )
00794 {
00795   p.assert_not_null();
00796   return any_cast<T1>(
00797     p.nonconst_access_private_node().get_extra_data(
00798       TypeNameTraits<T1>::name(), name
00799       )
00800     );
00801 }
00802 
00803 
00804 template<class T1, class T2>
00805 inline
00806 Teuchos::Ptr<const T1>
00807 Teuchos::get_optional_extra_data( const RCP<T2>& p, const std::string& name )
00808 {
00809   p.assert_not_null();
00810   const any *extra_data = p.access_private_node().get_optional_extra_data(
00811     TypeNameTraits<T1>::name(), name);
00812   if (extra_data)
00813     return Ptr<const T1>(&any_cast<T1>(*extra_data));
00814   return null;
00815 }
00816 
00817 
00818 template<class T1, class T2>
00819 inline
00820 Teuchos::Ptr<T1>
00821 Teuchos::get_optional_nonconst_extra_data( RCP<T2>& p, const std::string& name )
00822 {
00823   p.assert_not_null();
00824   any *extra_data = p.nonconst_access_private_node().get_optional_extra_data(
00825     TypeNameTraits<T1>::name(), name);
00826   if (extra_data)
00827     return Ptr<T1>(&any_cast<T1>(*extra_data));
00828   return null;
00829 }
00830 
00831 
00832 template<class Dealloc_T, class T>
00833 inline
00834 const Dealloc_T& Teuchos::get_dealloc( const RCP<T>& p )
00835 {
00836   return get_nonconst_dealloc<Dealloc_T>(const_cast<RCP<T>&>(p));
00837 }
00838 
00839 
00840 template<class Dealloc_T, class T>
00841 inline
00842 Dealloc_T& Teuchos::get_nonconst_dealloc( const RCP<T>& p )
00843 {
00844   typedef RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>  requested_type;
00845   p.assert_not_null();
00846   RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>
00847     *dnode = dynamic_cast<RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>*>(
00848       p.access_private_node().node_ptr());
00849   TEUCHOS_TEST_FOR_EXCEPTION(
00850     dnode==NULL, NullReferenceError
00851     ,"get_dealloc<" << TypeNameTraits<Dealloc_T>::name()
00852     << "," << TypeNameTraits<T>::name() << ">(p): "
00853     << "Error, requested type \'" << TypeNameTraits<requested_type>::name()
00854     << "\' does not match actual type of the node \'"
00855     << typeName(*p.access_private_node().node_ptr()) << "!"
00856     );
00857   return dnode->get_nonconst_dealloc();
00858 }
00859 
00860 
00861 template<class Dealloc_T, class T>
00862 inline
00863 Teuchos::Ptr<Dealloc_T>
00864 Teuchos::get_optional_nonconst_dealloc( const RCP<T>& p )
00865 {
00866   p.assert_not_null();
00867   typedef RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T> RCPNT;
00868   RCPNT *dnode = dynamic_cast<RCPNT*>(p.access_private_node().node_ptr());
00869   if(dnode)
00870     return ptr(&dnode->get_nonconst_dealloc());
00871   return null;
00872 }
00873 
00874 
00875 template<class Dealloc_T, class T>
00876 inline
00877 Teuchos::Ptr<const Dealloc_T>
00878 Teuchos::get_optional_dealloc( const RCP<T>& p )
00879 {
00880   return get_optional_nonconst_dealloc<Dealloc_T>(const_cast<RCP<T>&>(p));
00881 }
00882 
00883 
00884 template<class TOrig, class Embedded, class T>
00885 const Embedded& Teuchos::getEmbeddedObj( const RCP<T>& p )
00886 {
00887   typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
00888   return get_dealloc<Dealloc_t>(p).getObj();
00889 }
00890 
00891 
00892 template<class TOrig, class Embedded, class T>
00893 Embedded& Teuchos::getNonconstEmbeddedObj( const RCP<T>& p )
00894 {
00895   typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
00896   return get_nonconst_dealloc<Dealloc_t>(p).getNonconstObj();
00897 }
00898 
00899 
00900 template<class TOrig, class Embedded, class T>
00901 Teuchos::Ptr<const Embedded>
00902 Teuchos::getOptionalEmbeddedObj( const RCP<T>& p )
00903 {
00904   typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
00905   const Ptr<const Dealloc_t> dealloc = get_optional_dealloc<Dealloc_t>(p);
00906   if (!is_null(dealloc)) {
00907     return ptr(&dealloc->getObj());
00908   }
00909   return null;
00910 }
00911 
00912 
00913 template<class TOrig, class Embedded, class T>
00914 Teuchos::Ptr<Embedded>
00915 Teuchos::getOptionalNonconstEmbeddedObj( const RCP<T>& p )
00916 {
00917   typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
00918   const Ptr<Dealloc_t> dealloc = get_optional_nonconst_dealloc<Dealloc_t>(p);
00919   if (!is_null(dealloc)) {
00920     return ptr(&dealloc->getNonconstObj());
00921   }
00922   return null;
00923 }
00924 
00925 
00926 template<class ParentT, class T>
00927 Teuchos::RCP<ParentT>
00928 Teuchos::getInvertedObjOwnershipParent(const RCP<T> &invertedChild)
00929 {
00930   typedef std::pair<RCP<T>, RCP<ParentT> > Pair_t;
00931   Pair_t pair = getEmbeddedObj<T, Pair_t>(invertedChild);
00932   return pair.second;
00933 }
00934 
00935 
00936 template<class T>
00937 std::ostream& Teuchos::operator<<( std::ostream& out, const RCP<T>& p )
00938 {
00939   out
00940     << typeName(p) << "{"
00941     << "ptr="<<(const void*)(p.get()) // I can't find any alternative to this C cast :-(
00942     <<",node="<<p.access_private_node()
00943     <<",strong_count="<<p.strong_count()
00944     <<",weak_count="<<p.weak_count()
00945     <<"}";
00946   return out;
00947 }
00948 
00949 
00950 #endif // TEUCHOS_RCP_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines