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