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