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