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