|
Teuchos Package Browser (Single Doxygen Collection) 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_ARRAY_RCP_HPP 00030 #define TEUCHOS_ARRAY_RCP_HPP 00031 00032 00033 #include "Teuchos_ArrayRCPDecl.hpp" 00034 #include "Teuchos_ArrayView.hpp" 00035 #include "Teuchos_TestForException.hpp" 00036 #include "Teuchos_dyn_cast.hpp" 00037 #include "Teuchos_as.hpp" 00038 00039 00040 namespace Teuchos { 00041 00042 00043 // Helper code (not for general clients) 00044 00045 00046 template<class T> inline 00047 RCPNode* ArrayRCP_createNewRCPNodeRawPtr( T* p, bool has_ownership_in ) 00048 { 00049 return new RCPNodeTmpl<T,DeallocArrayDelete<T> >( 00050 p, DeallocArrayDelete<T>(), has_ownership_in 00051 ); 00052 } 00053 00054 00055 template<class T, class Dealloc_T> 00056 inline 00057 RCPNode* ArrayRCP_createNewDeallocRCPNodeRawPtr( 00058 T* p, Dealloc_T dealloc, bool has_ownership_in 00059 ) 00060 { 00061 return new RCPNodeTmpl<T,Dealloc_T>(p, dealloc, has_ownership_in); 00062 } 00063 00064 00065 template<class T2, class T1> 00066 class ArcpReinterpretCastEmbeddedObj 00067 { 00068 public: 00069 typedef T2 ptr_t; 00070 ArcpReinterpretCastEmbeddedObj() 00071 : arcp_pod_(null) 00072 {} 00073 ArcpReinterpretCastEmbeddedObj(const ArrayRCP<T1> &arcp_pod) 00074 : arcp_pod_(arcpCloneNode(arcp_pod)) // Unique reference count! 00075 {} 00076 // NOTE: The default copy constructor is allowed and does the right thing 00077 ~ArcpReinterpretCastEmbeddedObj() 00078 { freeMemory(); } 00079 ArcpReinterpretCastEmbeddedObj& 00080 operator=(const ArcpReinterpretCastEmbeddedObj& arceo) 00081 { 00082 assert(is_null(arceo.arcp_pod_)); // Can only be a catestrophic programming error! 00083 freeMemory(); 00084 return *this; 00085 } 00086 private: 00087 ArrayRCP<T1> arcp_pod_; 00088 void freeMemory() 00089 { 00090 typedef typename ArrayRCP<T2>::iterator itr_t; 00091 if (arcp_pod_.strong_count() == 1) { 00092 ArrayRCP<T2> arcp2 = arcp_reinterpret_cast<T2>(arcp_pod_); 00093 for (itr_t itr = arcp2.begin(); itr != arcp2.end(); ++itr) { 00094 itr->~T2(); 00095 } 00096 arcp_pod_ = null; 00097 } 00098 } 00099 }; 00100 00101 00102 // Constructors/Destructors/Initializers 00103 00104 template<class T> inline 00105 ArrayRCP<T>::ArrayRCP( ENull ) 00106 : ptr_(NULL), lowerOffset_(0), upperOffset_(-1) 00107 {} 00108 00109 00110 template<class T> inline 00111 ArrayRCP<T>::ArrayRCP(size_type n, const T& val) 00112 : ptr_(0), lowerOffset_(0), upperOffset_(-1) 00113 { 00114 *this = arcp<T>(n); 00115 std::fill_n(begin(), n, val); 00116 } 00117 00118 00119 template<class T> inline 00120 ArrayRCP<T>::ArrayRCP( 00121 T* p, size_type lowerOffset_in, size_type size_in, 00122 bool has_ownership_in, const ERCPNodeLookup rcpNodeLookup 00123 ) 00124 : ptr_(p), 00125 #ifndef TEUCHOS_DEBUG 00126 node_(ArrayRCP_createNewRCPNodeRawPtr(p, has_ownership_in)), 00127 #endif // TEUCHOS_DEBUG 00128 lowerOffset_(lowerOffset_in), 00129 upperOffset_(size_in + lowerOffset_in - 1) 00130 { 00131 #ifdef TEUCHOS_DEBUG 00132 if (p) { 00133 RCPNode* existing_RCPNode = 0; 00134 if (!has_ownership_in && rcpNodeLookup==RCP_ENABLE_NODE_LOOKUP) { 00135 existing_RCPNode = RCPNodeTracer::getExistingRCPNode(p); 00136 } 00137 if (existing_RCPNode) { 00138 // Will not call add_new_RCPNode(...) 00139 node_ = RCPNodeHandle(existing_RCPNode, RCP_WEAK, false); 00140 } 00141 else { 00142 // Will call add_new_RCPNode(...) 00143 RCPNodeThrowDeleter nodeDeleter(ArrayRCP_createNewRCPNodeRawPtr(p, has_ownership_in)); 00144 node_ = RCPNodeHandle( 00145 nodeDeleter.get(), 00146 p, typeName(*p), concreteTypeName(*p), 00147 has_ownership_in 00148 ); 00149 nodeDeleter.release(); 00150 } 00151 } 00152 #endif // TEUCHOS_DEBUG 00153 } 00154 00155 00156 template<class T> 00157 template<class Dealloc_T> 00158 inline 00159 ArrayRCP<T>::ArrayRCP( 00160 T* p, size_type lowerOffset_in, size_type size_in, 00161 Dealloc_T dealloc, bool has_ownership_in 00162 ) 00163 : ptr_(p), 00164 #ifndef TEUCHOS_DEBUG 00165 node_(ArrayRCP_createNewDeallocRCPNodeRawPtr(p, dealloc, has_ownership_in)), 00166 #endif // TEUCHOS_DEBUG 00167 lowerOffset_(lowerOffset_in), 00168 upperOffset_(size_in + lowerOffset_in - 1) 00169 { 00170 #ifdef TEUCHOS_DEBUG 00171 if (p) { 00172 node_ = RCPNodeHandle( 00173 ArrayRCP_createNewDeallocRCPNodeRawPtr(p, dealloc, has_ownership_in), 00174 p, typeName(*p), concreteTypeName(*p), 00175 has_ownership_in 00176 //, RCP_STRONG, false 00177 ); 00178 } 00179 #endif // TEUCHOS_DEBUG 00180 } 00181 00182 00183 template<class T> inline 00184 ArrayRCP<T>::ArrayRCP(const ArrayRCP<T>& r_ptr) 00185 :ptr_(r_ptr.ptr_), 00186 node_(r_ptr.node_), 00187 lowerOffset_(r_ptr.lowerOffset_), 00188 upperOffset_(r_ptr.upperOffset_) 00189 {} 00190 00191 00192 template<class T> inline 00193 ArrayRCP<T>::~ArrayRCP() 00194 {} 00195 00196 00197 template<class T> inline 00198 ArrayRCP<T>& ArrayRCP<T>::operator=(const ArrayRCP<T>& r_ptr) 00199 { 00200 if( this == &r_ptr ) 00201 return *this; // Assignment to self 00202 node_ = r_ptr.access_private_node(); // May throw in debug mode! 00203 ptr_ = r_ptr.ptr_; 00204 lowerOffset_ = r_ptr.lowerOffset_; 00205 upperOffset_ = r_ptr.upperOffset_; 00206 return *this; 00207 // NOTE: It is critical that the assignment of ptr_ come *after* the 00208 // assignment of node_ since node_ might throw an exception! 00209 } 00210 00211 00212 // Object/Pointer Access Functions 00213 00214 00215 template<class T> inline 00216 bool ArrayRCP<T>::is_null() const 00217 { 00218 return ptr_ == 0; 00219 } 00220 00221 00222 template<class T> inline 00223 T* ArrayRCP<T>::operator->() const 00224 { 00225 debug_assert_valid_ptr(); 00226 debug_assert_in_range(0,1); 00227 return ptr_; 00228 } 00229 00230 00231 template<class T> inline 00232 T& ArrayRCP<T>::operator*() const 00233 { 00234 debug_assert_valid_ptr(); 00235 debug_assert_in_range(0,1); 00236 return *ptr_; 00237 } 00238 00239 00240 template<class T> inline 00241 T* ArrayRCP<T>::get() const 00242 { 00243 if(ptr_) { 00244 debug_assert_valid_ptr(); 00245 debug_assert_in_range(0,1); 00246 } 00247 return ptr_; 00248 } 00249 00250 00251 template<class T> inline 00252 T* ArrayRCP<T>::getRawPtr() const 00253 { 00254 return this->get(); 00255 } 00256 00257 00258 template<class T> inline 00259 T& ArrayRCP<T>::operator[](size_type offset) const 00260 { 00261 debug_assert_valid_ptr(); 00262 debug_assert_in_range(offset,1); 00263 return ptr_[offset]; 00264 } 00265 00266 00267 // Pointer Arithmetic Functions 00268 00269 00270 template<class T> inline 00271 ArrayRCP<T>& ArrayRCP<T>::operator++() 00272 { 00273 debug_assert_valid_ptr(); 00274 ++ptr_; 00275 --lowerOffset_; 00276 --upperOffset_; 00277 return *this; 00278 } 00279 00280 00281 template<class T> inline 00282 ArrayRCP<T> ArrayRCP<T>::operator++(int) 00283 { 00284 debug_assert_valid_ptr(); 00285 ArrayRCP<T> r_ptr = *this; 00286 ++(*this); 00287 return r_ptr; 00288 } 00289 00290 00291 template<class T> inline 00292 ArrayRCP<T>& ArrayRCP<T>::operator--() 00293 { 00294 debug_assert_valid_ptr(); 00295 --ptr_; 00296 ++lowerOffset_; 00297 ++upperOffset_; 00298 return *this; 00299 } 00300 00301 00302 template<class T> inline 00303 ArrayRCP<T> ArrayRCP<T>::operator--(int) 00304 { 00305 debug_assert_valid_ptr(); 00306 ArrayRCP<T> r_ptr = *this; 00307 --(*this); 00308 return r_ptr; 00309 } 00310 00311 00312 template<class T> inline 00313 ArrayRCP<T>& ArrayRCP<T>::operator+=(size_type offset) 00314 { 00315 debug_assert_valid_ptr(); 00316 ptr_ += offset; 00317 lowerOffset_ -= offset; 00318 upperOffset_ -= offset; 00319 return *this; 00320 } 00321 00322 00323 template<class T> inline 00324 ArrayRCP<T>& ArrayRCP<T>::operator-=(size_type offset) 00325 { 00326 debug_assert_valid_ptr(); 00327 ptr_ -= offset; 00328 lowerOffset_ += offset; 00329 upperOffset_ += offset; 00330 return *this; 00331 } 00332 00333 00334 template<class T> inline 00335 ArrayRCP<T> ArrayRCP<T>::operator+(size_type offset) const 00336 { 00337 ArrayRCP<T> r_ptr = *this; 00338 r_ptr+=(offset); 00339 return r_ptr; 00340 } 00341 00342 00343 template<class T> inline 00344 ArrayRCP<T> ArrayRCP<T>::operator-(size_type offset) const 00345 { 00346 ArrayRCP<T> r_ptr = *this; 00347 r_ptr-=offset; 00348 return r_ptr; 00349 } 00350 00351 00352 // Standard Container-Like Functions 00353 00354 00355 template<class T> inline 00356 typename ArrayRCP<T>::iterator ArrayRCP<T>::begin() const 00357 { 00358 debug_assert_valid_ptr(); 00359 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00360 return *this; 00361 #else 00362 return ptr_; 00363 #endif 00364 } 00365 00366 00367 template<class T> inline 00368 typename ArrayRCP<T>::iterator ArrayRCP<T>::end() const 00369 { 00370 debug_assert_valid_ptr(); 00371 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00372 return *this + (upperOffset_ + 1); 00373 #else 00374 return ptr_ + (upperOffset_ + 1); 00375 #endif 00376 } 00377 00378 00379 // ArrayRCP Views 00380 00381 00382 template<class T> inline 00383 ArrayRCP<const T> ArrayRCP<T>::getConst() const 00384 { 00385 if (ptr_) { 00386 debug_assert_valid_ptr(); 00387 const T *cptr = ptr_; // Will not compile if not legal! 00388 return ArrayRCP<const T>(cptr, lowerOffset_, size(), node_); 00389 } 00390 return null; 00391 } 00392 00393 00394 template<class T> inline 00395 ArrayRCP<T> 00396 ArrayRCP<T>::persistingView( size_type lowerOffset_in, size_type size_in ) const 00397 { 00398 debug_assert_valid_ptr(); 00399 debug_assert_in_range(lowerOffset_in, size_in); 00400 ArrayRCP<T> ptr = *this; 00401 ptr.ptr_ = ptr.ptr_ + lowerOffset_in; 00402 ptr.lowerOffset_ = 0; 00403 ptr.upperOffset_ = size_in - 1; 00404 return ptr; 00405 } 00406 00407 00408 // Size and extent query functions 00409 00410 00411 template<class T> inline 00412 typename ArrayRCP<T>::size_type 00413 ArrayRCP<T>::lowerOffset() const 00414 { 00415 debug_assert_valid_ptr(); 00416 return lowerOffset_; 00417 } 00418 00419 00420 template<class T> inline 00421 typename ArrayRCP<T>::size_type 00422 ArrayRCP<T>::upperOffset() const 00423 { 00424 debug_assert_valid_ptr(); 00425 return upperOffset_; 00426 } 00427 00428 00429 template<class T> inline 00430 typename ArrayRCP<T>::size_type 00431 ArrayRCP<T>::size() const 00432 { 00433 debug_assert_valid_ptr(); 00434 return upperOffset_ - lowerOffset_ + 1; 00435 } 00436 00437 00438 // ArrayView views 00439 00440 00441 template<class T> inline 00442 ArrayView<T> ArrayRCP<T>::view( size_type lowerOffset_in, size_type size_in ) const 00443 { 00444 debug_assert_valid_ptr(); 00445 debug_assert_in_range(lowerOffset_in,size_in); 00446 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00447 return ArrayView<T>(persistingView(lowerOffset_in, size_in).create_weak()); 00448 #else 00449 return arrayView(ptr_ + lowerOffset_in, size_in); 00450 #endif 00451 // ToDo: Implement checks for dangling references! 00452 } 00453 00454 00455 template<class T> inline 00456 ArrayView<T> ArrayRCP<T>::operator()( size_type lowerOffset_in, size_type size_in ) const 00457 { 00458 return view(lowerOffset_in, size_in); 00459 } 00460 00461 00462 template<class T> inline 00463 ArrayView<T> ArrayRCP<T>::operator()() const 00464 { 00465 if (size()) { 00466 return view(lowerOffset_, size()); 00467 } 00468 return null; 00469 } 00470 00471 00472 // Implicit conversions 00473 00474 00475 template<class T> inline 00476 ArrayRCP<T>::operator ArrayView<T>() const 00477 { 00478 return this->operator()(); 00479 } 00480 00481 00482 template<class T> inline 00483 ArrayRCP<T>::operator ArrayRCP<const T>() const 00484 { 00485 if (size()) { 00486 return ArrayRCP<const T>(ptr_, lowerOffset_, size(), node_); 00487 } 00488 return null; 00489 } 00490 00491 00492 // std::vector like functions 00493 00494 00495 template<class T> inline 00496 void ArrayRCP<T>::assign(size_type n, const T &val) 00497 { 00498 *this = arcp<T>(n); 00499 std::fill_n(this->begin(), n, val); 00500 } 00501 00502 00503 template<class T> 00504 template<class Iter> 00505 inline 00506 void ArrayRCP<T>::assign(Iter first, Iter last) 00507 { 00508 const size_type new_n = std::distance(first, last); 00509 if (new_n != size()) 00510 *this = arcp<T>(new_n); 00511 std::copy( first, last, begin() ); 00512 } 00513 00514 00515 template<class T> inline 00516 void ArrayRCP<T>::resize(const size_type n, const T &val) 00517 { 00518 #ifdef TEUCHOS_DEBUG 00519 TEUCHOS_ASSERT_EQUALITY(lowerOffset(), 0); 00520 #endif 00521 if (n == 0) { 00522 clear(); 00523 return; 00524 } 00525 const size_type orig_n = size(); 00526 if (n != orig_n) { 00527 ArrayRCP<T> tmp = *this; 00528 *this = arcp<T>(n); 00529 const size_type small_n = std::min(n, orig_n); 00530 for (size_type i = 0; i < small_n; ++i) 00531 (*this)[i] = tmp[i]; 00532 for (size_type i = orig_n; i < n; ++i) 00533 (*this)[i] = val; 00534 upperOffset_ = n-1; 00535 } 00536 } 00537 00538 00539 template<class T> inline 00540 void ArrayRCP<T>::clear() 00541 { 00542 *this = null; 00543 } 00544 00545 00546 // Misc functions 00547 00548 template<class T> inline 00549 void ArrayRCP<T>::deepCopy(const ArrayView<const T>& av) 00550 { 00551 if (av.size() == 0) { 00552 *this = null; 00553 return; 00554 } 00555 assign(av.begin(), av.end()); 00556 } 00557 00558 00559 // Reference counting 00560 00561 00562 template<class T> inline 00563 ERCPStrength ArrayRCP<T>::strength() const 00564 { 00565 return node_.strength(); 00566 } 00567 00568 00569 template<class T> inline 00570 bool ArrayRCP<T>::is_valid_ptr() const 00571 { 00572 if (ptr_) 00573 return node_.is_valid_ptr(); 00574 return true; 00575 } 00576 00577 00578 template<class T> inline 00579 int ArrayRCP<T>::strong_count() const 00580 { 00581 return node_.strong_count(); 00582 } 00583 00584 00585 template<class T> inline 00586 int ArrayRCP<T>::weak_count() const 00587 { 00588 return node_.weak_count(); 00589 } 00590 00591 00592 template<class T> inline 00593 int ArrayRCP<T>::total_count() const 00594 { 00595 return node_.total_count(); 00596 } 00597 00598 00599 template<class T> inline 00600 void ArrayRCP<T>::set_has_ownership() 00601 { 00602 node_.has_ownership(true); 00603 } 00604 00605 00606 template<class T> inline 00607 bool ArrayRCP<T>::has_ownership() const 00608 { 00609 return node_.has_ownership(); 00610 } 00611 00612 00613 template<class T> inline 00614 T* ArrayRCP<T>::release() 00615 { 00616 debug_assert_valid_ptr(); 00617 node_.has_ownership(false); 00618 return ptr_; 00619 } 00620 00621 00622 template<class T> inline 00623 ArrayRCP<T> ArrayRCP<T>::create_weak() const 00624 { 00625 debug_assert_valid_ptr(); 00626 return ArrayRCP<T>(ptr_, lowerOffset_, size(), node_.create_weak()); 00627 } 00628 00629 00630 template<class T> inline 00631 ArrayRCP<T> ArrayRCP<T>::create_strong() const 00632 { 00633 debug_assert_valid_ptr(); 00634 return ArrayRCP<T>(ptr_, lowerOffset_, size(), node_.create_strong()); 00635 } 00636 00637 00638 template<class T> 00639 template <class T2> 00640 inline 00641 bool ArrayRCP<T>::shares_resource(const ArrayRCP<T2>& r_ptr) const 00642 { 00643 return node_.same_node(r_ptr.access_private_node()); 00644 // Note: above, r_ptr is *not* the same class type as *this so we can not 00645 // access its node_ member directly! This is an interesting detail to the 00646 // C++ protected/private protection mechanism! 00647 } 00648 00649 00650 // Assertion Functions 00651 00652 00653 template<class T> inline 00654 const ArrayRCP<T>& 00655 ArrayRCP<T>::assert_not_null() const 00656 { 00657 if(!ptr_) 00658 throw_null_ptr_error(typeName(*this)); 00659 return *this; 00660 } 00661 00662 00663 template<class T> inline 00664 const ArrayRCP<T>& ArrayRCP<T>::assert_valid_ptr() const 00665 { 00666 if (ptr_) 00667 node_.assert_valid_ptr(*this); 00668 return *this; 00669 } 00670 00671 00672 template<class T> inline 00673 const ArrayRCP<T>& 00674 ArrayRCP<T>::assert_in_range( size_type lowerOffset_in, size_type size_in ) const 00675 { 00676 assert_not_null(); 00677 TEST_FOR_EXCEPTION( 00678 !( 00679 (lowerOffset_ <= lowerOffset_in && lowerOffset_in+size_in-1 <= upperOffset_) 00680 && 00681 size_in >= 0 00682 ), 00683 Teuchos::RangeError, 00684 typeName(*this)<<"::assert_in_range:" 00685 " Error, [lowerOffset,lowerOffset+size-1] = [" 00686 <<lowerOffset_in<<","<<(lowerOffset_in+size_in-1)<<"] does not lie in the" 00687 " range ["<<lowerOffset_<<","<<upperOffset_<<"]!" 00688 ); 00689 return *this; 00690 } 00691 00692 00693 // Deprecated 00694 00695 00696 template<class T> inline 00697 int ArrayRCP<T>::count() const { 00698 return node_.count(); 00699 } 00700 00701 00702 // very bad public functions 00703 00704 00705 template<class T> inline 00706 ArrayRCP<T>::ArrayRCP( 00707 T* p, size_type lowerOffset_in, size_type size_in, 00708 const RCPNodeHandle& node 00709 ) 00710 :ptr_(p), 00711 node_(node), 00712 lowerOffset_(lowerOffset_in), 00713 upperOffset_(size_in + lowerOffset_in - 1) 00714 {} 00715 00716 00717 template<class T> inline 00718 T* ArrayRCP<T>::access_private_ptr() const 00719 { 00720 return ptr_; 00721 } 00722 00723 00724 template<class T> inline 00725 RCPNodeHandle& ArrayRCP<T>::nonconst_access_private_node() 00726 { 00727 return node_; 00728 } 00729 00730 00731 template<class T> inline 00732 const RCPNodeHandle& ArrayRCP<T>::access_private_node() const 00733 { 00734 return node_; 00735 } 00736 00737 // Array<void> and Array<const void> specializations 00738 00739 00740 ArrayRCP<void>::ArrayRCP() 00741 { 00742 TEST_FOR_EXCEPT(true); 00743 } 00744 00745 00746 ArrayRCP<const void>::ArrayRCP() 00747 { 00748 TEST_FOR_EXCEPT(true); 00749 } 00750 00751 00752 } // end namespace Teuchos 00753 00754 00755 // /////////////////////////////////////////// 00756 // Non-member functions for ArrayRCP 00757 00758 00759 namespace Teuchos { 00760 namespace Utilities { 00761 template<class T1, class T2> 00762 inline void assert_shares_resource( 00763 const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 00764 ) 00765 { 00766 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00767 TEST_FOR_EXCEPTION( 00768 !p1.shares_resource(p2), IncompatibleIteratorsError, 00769 "Error, these iterators are *not* pointing to the same valid memory!" 00770 ); 00771 #endif 00772 } 00773 } // namespace Utilities 00774 } // namespace Teuchos 00775 00776 00777 template<class T> inline 00778 Teuchos::ArrayRCP<T> 00779 Teuchos::arcp( 00780 T* p, typename ArrayRCP<T>::size_type lowerOffset 00781 ,typename ArrayRCP<T>::size_type size_in 00782 ,bool owns_mem 00783 ) 00784 { 00785 return ArrayRCP<T>(p, lowerOffset, size_in, owns_mem); 00786 } 00787 00788 00789 template<class T, class Dealloc_T> 00790 inline 00791 Teuchos::ArrayRCP<T> 00792 Teuchos::arcp( 00793 T* p, typename ArrayRCP<T>::size_type lowerOffset 00794 ,typename ArrayRCP<T>::size_type size_in 00795 ,Dealloc_T dealloc, bool owns_mem 00796 ) 00797 { 00798 return ArrayRCP<T>(p, lowerOffset, size_in, dealloc, owns_mem); 00799 } 00800 00801 00802 template<class T> inline 00803 Teuchos::ArrayRCP<T> 00804 Teuchos::arcp( typename ArrayRCP<T>::size_type size ) 00805 { 00806 #ifdef TEUCHOS_DEBUG 00807 TEUCHOS_ASSERT_INEQUALITY( size, >=, 0 ); 00808 #endif 00809 if (size == 0) { 00810 return null; 00811 } 00812 return ArrayRCP<T>(new T[size], 0, size, true); 00813 } 00814 00815 00816 template<class T> inline 00817 Teuchos::ArrayRCP<T> 00818 Teuchos::arcpCloneNode(const ArrayRCP<T> &a) 00819 { 00820 if (is_null(a)) { 00821 return null; 00822 } 00823 return arcpWithEmbeddedObj(a.getRawPtr(), a.lowerOffset(), a.size(), 00824 a, false); 00825 } 00826 00827 00828 template<class T> inline 00829 Teuchos::ArrayRCP<T> 00830 Teuchos::arcpClone( const ArrayView<const T> &v ) 00831 { 00832 const ArrayRCP<T> new_arcp = arcp<T>(v.size()); 00833 std::copy( v.begin(), v.end(), new_arcp.begin() ); 00834 return new_arcp; 00835 } 00836 00837 00838 template<class T, class Embedded> 00839 Teuchos::ArrayRCP<T> 00840 Teuchos::arcpWithEmbeddedObjPreDestroy( 00841 T* p, 00842 typename ArrayRCP<T>::size_type lowerOffset, 00843 typename ArrayRCP<T>::size_type size, 00844 const Embedded &embedded, 00845 bool owns_mem 00846 ) 00847 { 00848 return arcp( 00849 p, lowerOffset, size, 00850 embeddedObjDeallocArrayDelete<T>(embedded, PRE_DESTROY), 00851 owns_mem 00852 ); 00853 } 00854 00855 00856 template<class T, class Embedded> 00857 Teuchos::ArrayRCP<T> 00858 Teuchos::arcpWithEmbeddedObjPostDestroy( 00859 T* p, 00860 typename ArrayRCP<T>::size_type lowerOffset, 00861 typename ArrayRCP<T>::size_type size, 00862 const Embedded &embedded, 00863 bool owns_mem 00864 ) 00865 { 00866 return arcp( 00867 p, lowerOffset, size, 00868 embeddedObjDeallocArrayDelete<T>(embedded, POST_DESTROY), 00869 owns_mem 00870 ); 00871 } 00872 00873 00874 template<class T, class Embedded> 00875 Teuchos::ArrayRCP<T> 00876 Teuchos::arcpWithEmbeddedObj( 00877 T* p, 00878 typename ArrayRCP<T>::size_type lowerOffset, 00879 typename ArrayRCP<T>::size_type size, 00880 const Embedded &embedded, 00881 bool owns_mem 00882 ) 00883 { 00884 return arcpWithEmbeddedObjPostDestroy<T,Embedded>( 00885 p, lowerOffset, size, embedded, owns_mem ); 00886 } 00887 00888 00889 template<class T> inline 00890 Teuchos::ArrayRCP<T> 00891 Teuchos::arcp( const RCP<std::vector<T> > &v ) 00892 { 00893 if ( is_null(v) || !v->size() ) 00894 return null; 00895 return arcpWithEmbeddedObjPostDestroy<T,RCP<std::vector<T> > >( 00896 &(*v)[0], 0, v->size(), 00897 v, false 00898 ); 00899 } 00900 00901 00902 template<class T> inline 00903 Teuchos::ArrayRCP<const T> 00904 Teuchos::arcp( const RCP<const std::vector<T> > &v ) 00905 { 00906 if ( is_null(v) || !v->size() ) 00907 return null; 00908 return arcpWithEmbeddedObjPostDestroy<const T,RCP<const std::vector<T> > >( 00909 &(*v)[0], 0, v->size(), 00910 v, false 00911 ); 00912 } 00913 00914 00915 template<class T> inline 00916 Teuchos::ArrayRCP<T> 00917 Teuchos::arcpFromArrayView(const ArrayView<T> &av) 00918 { 00919 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00920 return av.access_private_arcp(); 00921 #else 00922 return arcp(av.getRawPtr(), 0, av.size(), false); 00923 #endif 00924 } 00925 00926 00927 template<class T> inline 00928 Teuchos::RCP<std::vector<T> > 00929 Teuchos::get_std_vector( const ArrayRCP<T> &ptr ) 00930 { 00931 return getEmbeddedObj<T, RCP<std::vector<T> > >(ptr); 00932 } 00933 00934 00935 template<class T> inline 00936 Teuchos::RCP<const std::vector<T> > 00937 Teuchos::get_std_vector( const ArrayRCP<const T> &ptr ) 00938 { 00939 return getEmbeddedObj<const T, RCP<const std::vector<T> > >(ptr); 00940 } 00941 00942 00943 template<class T> inline 00944 bool Teuchos::is_null( const ArrayRCP<T> &p ) 00945 { 00946 return p.is_null(); 00947 } 00948 00949 00950 template<class T> inline 00951 bool Teuchos::nonnull( const ArrayRCP<T> &p ) 00952 { 00953 return !p.is_null(); 00954 } 00955 00956 00957 template<class T> inline 00958 bool Teuchos::operator==( const ArrayRCP<T> &p, ENull ) 00959 { 00960 return p.is_null(); 00961 } 00962 00963 00964 template<class T> inline 00965 bool Teuchos::operator!=( const ArrayRCP<T> &p, ENull ) 00966 { 00967 return !p.is_null(); 00968 } 00969 00970 00971 template<class T1, class T2> 00972 inline 00973 bool Teuchos::operator==( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 ) 00974 { 00975 return p1.access_private_ptr() == p2.access_private_ptr(); 00976 } 00977 00978 00979 template<class T1, class T2> 00980 inline 00981 bool Teuchos::operator!=( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 ) 00982 { 00983 return p1.access_private_ptr() != p2.access_private_ptr(); 00984 } 00985 00986 00987 template<class T1, class T2> 00988 inline 00989 bool Teuchos::operator<( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 ) 00990 { 00991 return p1.access_private_ptr() < p2.access_private_ptr(); 00992 } 00993 00994 00995 template<class T1, class T2> 00996 inline 00997 bool Teuchos::operator<=( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 ) 00998 { 00999 Utilities::assert_shares_resource(p1,p2); 01000 return p1.access_private_ptr() <= p2.access_private_ptr(); 01001 } 01002 01003 01004 template<class T1, class T2> 01005 inline 01006 bool Teuchos::operator>( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 ) 01007 { 01008 Utilities::assert_shares_resource(p1,p2); 01009 return p1.access_private_ptr() > p2.access_private_ptr(); 01010 } 01011 01012 01013 template<class T1, class T2> 01014 inline 01015 bool Teuchos::operator>=( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 ) 01016 { 01017 Utilities::assert_shares_resource(p1,p2); 01018 return p1.access_private_ptr() >= p2.access_private_ptr(); 01019 } 01020 01021 01022 template<class T> 01023 typename Teuchos::ArrayRCP<T>::difference_type 01024 Teuchos::operator-( const ArrayRCP<T> &p1, const ArrayRCP<T> &p2 ) 01025 { 01026 Utilities::assert_shares_resource(p1,p2); 01027 return p1.access_private_ptr() - p2.access_private_ptr(); 01028 } 01029 01030 01031 template<class T2, class T1> 01032 inline 01033 Teuchos::ArrayRCP<T2> 01034 Teuchos::arcp_reinterpret_cast(const ArrayRCP<T1>& p1) 01035 { 01036 typedef typename ArrayRCP<T1>::size_type size_type; 01037 const int sizeOfT1 = sizeof(T1); 01038 const int sizeOfT2 = sizeof(T2); 01039 size_type lowerOffset2 = (p1.lowerOffset()*sizeOfT1) / sizeOfT2; 01040 size_type upperOffset2 = ((p1.upperOffset()+1)*sizeOfT1) / sizeOfT2 - 1; 01041 T2 *ptr2 = reinterpret_cast<T2*>(p1.get()); 01042 return ArrayRCP<T2>( 01043 ptr2, lowerOffset2, upperOffset2 - lowerOffset2 + 1, 01044 p1.access_private_node() 01045 ); 01046 // Note: Above is just fine even if p1.get()==NULL! 01047 } 01048 01049 01050 template<class T2, class T1> 01051 Teuchos::ArrayRCP<T2> 01052 Teuchos::arcp_reinterpret_cast_nonpod(const ArrayRCP<T1>& p1, const T2& val) 01053 { 01054 typedef typename ArrayRCP<T2>::iterator itr_t; 01055 ArrayRCP<T2> arcp2 = arcp_reinterpret_cast<T2>(p1); 01056 for (itr_t itr = arcp2.begin(); itr != arcp2.end(); ++itr) { 01057 new (&*itr) T2(val); 01058 } 01059 return arcpWithEmbeddedObj( 01060 arcp2.getRawPtr(), 0, arcp2.size(), 01061 ArcpReinterpretCastEmbeddedObj<T2, T1>(p1), 01062 false); 01063 // Above, the ownership of the memory is totally owned by the embedded 01064 // object and the default deallocator policy object does not do anything. 01065 // This is just fine. 01066 } 01067 01068 01069 template<class T2, class T1> 01070 inline 01071 Teuchos::ArrayRCP<T2> 01072 Teuchos::arcp_const_cast(const ArrayRCP<T1>& p1) 01073 { 01074 typedef typename ArrayRCP<T1>::size_type size_type; 01075 T2 *ptr2 = const_cast<T2*>(p1.get()); 01076 return ArrayRCP<T2>( 01077 ptr2, p1.lowerOffset(), p1.size(), 01078 p1.access_private_node() 01079 ); 01080 // Note: Above is just fine even if p1.get()==NULL! 01081 } 01082 01083 01084 template<class T2, class T1> 01085 inline 01086 Teuchos::ArrayRCP<T2> 01087 Teuchos::arcp_implicit_cast(const ArrayRCP<T1>& p1) 01088 { 01089 typedef typename ArrayRCP<T1>::size_type size_type; 01090 T2 * raw_ptr2 = p1.get(); 01091 return ArrayRCP<T2>( 01092 raw_ptr2, p1.lowerOffset(), p1.size(), 01093 p1.access_private_node() 01094 ); 01095 // Note: Above is just fine even if p1.get()==NULL! 01096 } 01097 01098 01099 template<class T1, class T2> 01100 inline 01101 void Teuchos::set_extra_data( 01102 const T1 &extra_data, const std::string& name, 01103 const Ptr<ArrayRCP<T2> > &p, EPrePostDestruction destroy_when, 01104 bool force_unique 01105 ) 01106 { 01107 p->assert_not_null(); 01108 p->nonconst_access_private_node().set_extra_data( any(extra_data), name, destroy_when, 01109 force_unique ); 01110 } 01111 01112 01113 template<class T1, class T2> 01114 inline 01115 T1& Teuchos::get_extra_data( ArrayRCP<T2>& p, const std::string& name ) 01116 { 01117 p.assert_not_null(); 01118 return any_cast<T1>( 01119 p.nonconst_access_private_node().get_extra_data( 01120 TypeNameTraits<T1>::name(), name 01121 ) 01122 ); 01123 } 01124 01125 01126 template<class T1, class T2> 01127 inline 01128 const T1& Teuchos::get_extra_data( const ArrayRCP<T2>& p, const std::string& name ) 01129 { 01130 p.assert_not_null(); 01131 return any_cast<T1>( 01132 p.access_private_node().get_extra_data( 01133 TypeNameTraits<T1>::name() ,name 01134 ) 01135 ); 01136 } 01137 01138 01139 template<class T1, class T2> 01140 inline 01141 T1* Teuchos::get_optional_extra_data( ArrayRCP<T2>& p, const std::string& name ) 01142 { 01143 p.assert_not_null(); 01144 any *extra_data = p.nonconst_access_private_node().get_optional_extra_data( 01145 TypeNameTraits<T1>::name(), name); 01146 if( extra_data ) return &any_cast<T1>(*extra_data); 01147 return NULL; 01148 } 01149 01150 01151 template<class T1, class T2> 01152 inline 01153 const T1* Teuchos::get_optional_extra_data( const ArrayRCP<T2>& p, const std::string& name ) 01154 { 01155 p.assert_not_null(); 01156 any *extra_data = p.access_private_node().get_optional_extra_data( 01157 TypeNameTraits<T1>::name(), name); 01158 if( extra_data ) return &any_cast<T1>(*extra_data); 01159 return NULL; 01160 } 01161 01162 01163 template<class Dealloc_T, class T> 01164 inline 01165 const Dealloc_T& 01166 Teuchos::get_dealloc( const ArrayRCP<T>& p ) 01167 { 01168 return get_nonconst_dealloc<Dealloc_T>(p); 01169 } 01170 01171 01172 template<class Dealloc_T, class T> 01173 inline 01174 Dealloc_T& 01175 Teuchos::get_nonconst_dealloc( const Teuchos::ArrayRCP<T>& p ) 01176 { 01177 typedef RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T> requested_type; 01178 p.assert_not_null(); 01179 RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T> 01180 *dnode = dynamic_cast<RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>*>( 01181 p.access_private_node().node_ptr()); 01182 TEST_FOR_EXCEPTION( 01183 dnode==NULL, NullReferenceError 01184 ,"get_dealloc<" << TypeNameTraits<Dealloc_T>::name() 01185 << "," << TypeNameTraits<T>::name() << ">(p): " 01186 << "Error, requested type \'" << TypeNameTraits<requested_type>::name() 01187 << "\' does not match actual type of the node \'" 01188 << typeName(*p.access_private_node().node_ptr()) << "!" 01189 ); 01190 return dnode->get_nonconst_dealloc(); 01191 } 01192 01193 01194 template<class Dealloc_T, class T> 01195 inline 01196 const Dealloc_T* 01197 Teuchos::get_optional_dealloc( const ArrayRCP<T>& p ) 01198 { 01199 return get_optional_dealloc<Dealloc_T>(p); 01200 } 01201 01202 01203 template<class Dealloc_T, class T> 01204 inline 01205 Dealloc_T* 01206 Teuchos::get_optional_nonconst_dealloc( const Teuchos::ArrayRCP<T>& p ) 01207 { 01208 p.assert_not_null(); 01209 typedef RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T> 01210 RCPNT; 01211 RCPNT *dnode = dynamic_cast<RCPNT*>(p.access_private_node().node_ptr()); 01212 if (dnode) 01213 return &dnode->get_nonconst_dealloc(); 01214 return 0; 01215 } 01216 01217 01218 template<class TOrig, class Embedded, class T> 01219 const Embedded& Teuchos::getEmbeddedObj( const ArrayRCP<T>& p ) 01220 { 01221 typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocArrayDelete<TOrig> > Dealloc_t; 01222 return get_dealloc<Dealloc_t>(p).getObj(); 01223 } 01224 01225 01226 template<class TOrig, class Embedded, class T> 01227 Embedded& Teuchos::getNonconstEmbeddedObj( const ArrayRCP<T>& p ) 01228 { 01229 typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocArrayDelete<TOrig> > Dealloc_t; 01230 return get_nonconst_dealloc<Dealloc_t>(p).getNonconstObj(); 01231 } 01232 01233 01234 template<class T> 01235 std::ostream& Teuchos::operator<<( std::ostream& out, const ArrayRCP<T>& p ) 01236 { 01237 out 01238 << TypeNameTraits<ArrayRCP<T> >::name() << "{" 01239 << "ptr="<<(const void*)(p.get()) // I can't find any alternative to this C cast :-( 01240 <<",lowerOffset="<<p.lowerOffset() 01241 <<",upperOffset="<<p.upperOffset() 01242 <<",size="<<p.size() 01243 <<",node="<<p.access_private_node() 01244 <<",count="<<p.count() 01245 <<"}"; 01246 return out; 01247 } 01248 01249 01250 #endif // TEUCHOS_ARRAY_RCP_HPP
1.7.4