Teuchos Package Browser (Single Doxygen Collection) 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_TestForException.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 rcp(
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 rcp( 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   typedef std::pair<RCP<T>, RCP<ParentT> > Pair_t;
00649   return rcpWithEmbeddedObj(child.getRawPtr(), make_pair(child, parent), false);
00650 }
00651 
00652 
00653 template<class T>
00654 Teuchos::RCP<T>
00655 Teuchos::rcpCloneNode(const RCP<T> &p)
00656 {
00657   if (is_null(p)) {
00658     return p;
00659   }
00660   return rcpWithEmbeddedObj(&*p, p, false);
00661 }
00662 
00663 
00664 template<class T>
00665 inline
00666 bool Teuchos::is_null( const RCP<T> &p )
00667 {
00668   return p.is_null();
00669 }
00670 
00671 
00672 template<class T>
00673 inline
00674 bool Teuchos::nonnull( const RCP<T> &p )
00675 {
00676   return !p.is_null();
00677 }
00678 
00679 
00680 template<class T>
00681 inline
00682 bool Teuchos::operator==( const RCP<T> &p, ENull )
00683 {
00684   return p.get() == NULL;
00685 }
00686 
00687 
00688 template<class T>
00689 inline
00690 bool Teuchos::operator!=( const RCP<T> &p, ENull )
00691 {
00692   return p.get() != NULL;
00693 }
00694 
00695 
00696 template<class T1, class T2>
00697 inline
00698 bool Teuchos::operator==( const RCP<T1> &p1, const RCP<T2> &p2 )
00699 {
00700   return p1.access_private_node().same_node(p2.access_private_node());
00701 }
00702 
00703 
00704 template<class T1, class T2>
00705 inline
00706 bool Teuchos::operator!=( const RCP<T1> &p1, const RCP<T2> &p2 )
00707 {
00708   return !p1.access_private_node().same_node(p2.access_private_node());
00709 }
00710 
00711 
00712 template<class T2, class T1>
00713 inline
00714 Teuchos::RCP<T2>
00715 Teuchos::rcp_implicit_cast(const RCP<T1>& p1)
00716 {
00717   // Make the compiler check if the conversion is legal
00718   T2 *check = p1.get();
00719   return RCP<T2>(check, p1.access_private_node());
00720 }
00721 
00722 
00723 template<class T2, class T1>
00724 inline
00725 Teuchos::RCP<T2>
00726 Teuchos::rcp_static_cast(const RCP<T1>& p1)
00727 {
00728   // Make the compiler check if the conversion is legal
00729   T2 *check = static_cast<T2*>(p1.get());
00730   return RCP<T2>(check, p1.access_private_node());
00731 }
00732 
00733 
00734 template<class T2, class T1>
00735 inline
00736 Teuchos::RCP<T2>
00737 Teuchos::rcp_const_cast(const RCP<T1>& p1)
00738 {
00739   // Make the compiler check if the conversion is legal
00740   T2 *check = const_cast<T2*>(p1.get());
00741   return RCP<T2>(check, p1.access_private_node());
00742 }
00743 
00744 
00745 template<class T2, class T1>
00746 inline
00747 Teuchos::RCP<T2>
00748 Teuchos::rcp_dynamic_cast(const RCP<T1>& p1, bool throw_on_fail)
00749 {
00750   if (!is_null(p1)) {
00751     T2 *p = NULL;
00752     if (throw_on_fail) {
00753       p = &dyn_cast<T2>(*p1);
00754     }
00755     else {
00756       // Make the compiler check if the conversion is legal
00757       p = dynamic_cast<T2*>(p1.get());
00758     }
00759     if (p) {
00760       return RCP<T2>(p, p1.access_private_node());
00761     }
00762   }
00763   return null;
00764 }
00765 
00766 
00767 template<class T1, class T2>
00768 inline
00769 void Teuchos::set_extra_data( const T1 &extra_data, const std::string& name,
00770   const Ptr<RCP<T2> > &p, EPrePostDestruction destroy_when, bool force_unique )
00771 {
00772   p->assert_not_null();
00773   p->nonconst_access_private_node().set_extra_data(
00774     any(extra_data), name, destroy_when,
00775     force_unique );
00776 }
00777 
00778 
00779 template<class T1, class T2>
00780 inline
00781 const T1& Teuchos::get_extra_data( const RCP<T2>& p, const std::string& name )
00782 {
00783   p.assert_not_null();
00784   return any_cast<T1>(
00785     p.access_private_node().get_extra_data(
00786       TypeNameTraits<T1>::name(), name
00787       )
00788     );
00789 }
00790 
00791 
00792 template<class T1, class T2>
00793 inline
00794 T1& Teuchos::get_nonconst_extra_data( RCP<T2>& p, const std::string& name )
00795 {
00796   p.assert_not_null();
00797   return any_cast<T1>(
00798     p.nonconst_access_private_node().get_extra_data(
00799       TypeNameTraits<T1>::name(), name
00800       )
00801     );
00802 }
00803 
00804 
00805 template<class T1, class T2>
00806 inline
00807 Teuchos::Ptr<const T1>
00808 Teuchos::get_optional_extra_data( const RCP<T2>& p, const std::string& name )
00809 {
00810   p.assert_not_null();
00811   const any *extra_data = p.access_private_node().get_optional_extra_data(
00812     TypeNameTraits<T1>::name(), name);
00813   if (extra_data)
00814     return Ptr<const T1>(&any_cast<T1>(*extra_data));
00815   return null;
00816 }
00817 
00818 
00819 template<class T1, class T2>
00820 inline
00821 Teuchos::Ptr<T1>
00822 Teuchos::get_optional_nonconst_extra_data( RCP<T2>& p, const std::string& name )
00823 {
00824   p.assert_not_null();
00825   any *extra_data = p.nonconst_access_private_node().get_optional_extra_data(
00826     TypeNameTraits<T1>::name(), name);
00827   if (extra_data)
00828     return Ptr<T1>(&any_cast<T1>(*extra_data));
00829   return null;
00830 }
00831 
00832 
00833 template<class Dealloc_T, class T>
00834 inline
00835 const Dealloc_T& Teuchos::get_dealloc( const RCP<T>& p )
00836 {
00837   return get_nonconst_dealloc<Dealloc_T>(const_cast<RCP<T>&>(p));
00838 }
00839 
00840 
00841 template<class Dealloc_T, class T>
00842 inline
00843 Dealloc_T& Teuchos::get_nonconst_dealloc( const RCP<T>& p )
00844 {
00845   typedef RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>  requested_type;
00846   p.assert_not_null();
00847   RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>
00848     *dnode = dynamic_cast<RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>*>(
00849       p.access_private_node().node_ptr());
00850   TEST_FOR_EXCEPTION(
00851     dnode==NULL, NullReferenceError
00852     ,"get_dealloc<" << TypeNameTraits<Dealloc_T>::name()
00853     << "," << TypeNameTraits<T>::name() << ">(p): "
00854     << "Error, requested type \'" << TypeNameTraits<requested_type>::name()
00855     << "\' does not match actual type of the node \'"
00856     << typeName(*p.access_private_node().node_ptr()) << "!"
00857     );
00858   return dnode->get_nonconst_dealloc();
00859 }
00860 
00861 
00862 template<class Dealloc_T, class T>
00863 inline
00864 Teuchos::Ptr<Dealloc_T>
00865 Teuchos::get_optional_nonconst_dealloc( const RCP<T>& p )
00866 {
00867   p.assert_not_null();
00868   typedef RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T> RCPNT;
00869   RCPNT *dnode = dynamic_cast<RCPNT*>(p.access_private_node().node_ptr());
00870   if(dnode)
00871     return ptr(&dnode->get_nonconst_dealloc());
00872   return null;
00873 }
00874 
00875 
00876 template<class Dealloc_T, class T>
00877 inline
00878 Teuchos::Ptr<const Dealloc_T>
00879 Teuchos::get_optional_dealloc( const RCP<T>& p )
00880 {
00881   return get_optional_nonconst_dealloc<Dealloc_T>(const_cast<RCP<T>&>(p));
00882 }
00883 
00884 
00885 template<class TOrig, class Embedded, class T>
00886 const Embedded& Teuchos::getEmbeddedObj( const RCP<T>& p )
00887 {
00888   typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
00889   return get_dealloc<Dealloc_t>(p).getObj();
00890 }
00891 
00892 
00893 template<class TOrig, class Embedded, class T>
00894 Embedded& Teuchos::getNonconstEmbeddedObj( const RCP<T>& p )
00895 {
00896   typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
00897   return get_nonconst_dealloc<Dealloc_t>(p).getNonconstObj();
00898 }
00899 
00900 
00901 template<class TOrig, class Embedded, class T>
00902 Teuchos::Ptr<const Embedded>
00903 Teuchos::getOptionalEmbeddedObj( const RCP<T>& p )
00904 {
00905   typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
00906   const Ptr<const Dealloc_t> dealloc = get_optional_dealloc<Dealloc_t>(p);
00907   if (!is_null(dealloc)) {
00908     return ptr(&dealloc->getObj());
00909   }
00910   return null;
00911 }
00912 
00913 
00914 template<class TOrig, class Embedded, class T>
00915 Teuchos::Ptr<Embedded>
00916 Teuchos::getOptionalNonconstEmbeddedObj( const RCP<T>& p )
00917 {
00918   typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
00919   const Ptr<Dealloc_t> dealloc = get_optional_nonconst_dealloc<Dealloc_t>(p);
00920   if (!is_null(dealloc)) {
00921     return ptr(&dealloc->getNonconstObj());
00922   }
00923   return null;
00924 }
00925 
00926 
00927 template<class ParentT, class T>
00928 Teuchos::RCP<ParentT>
00929 Teuchos::getInvertedObjOwnershipParent(const RCP<T> &invertedChild)
00930 {
00931   typedef std::pair<RCP<T>, RCP<ParentT> > Pair_t;
00932   Pair_t pair = getEmbeddedObj<T, Pair_t>(invertedChild);
00933   return pair.second;
00934 }
00935 
00936 
00937 template<class T>
00938 std::ostream& Teuchos::operator<<( std::ostream& out, const RCP<T>& p )
00939 {
00940   out
00941     << typeName(p) << "{"
00942     << "ptr="<<(const void*)(p.get()) // I can't find any alternative to this C cast :-(
00943     <<",node="<<p.access_private_node()
00944     <<",count="<<p.count()
00945     <<"}";
00946   return out;
00947 }
00948 
00949 
00950 #endif // TEUCHOS_RCP_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines