|
Teuchos - Trilinos Tools Package Version of the Day
|
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
1.7.4