|
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_ARRAY_RCP_HPP 00043 #define TEUCHOS_ARRAY_RCP_HPP 00044 00045 00046 #include "Teuchos_ArrayRCPDecl.hpp" 00047 #include "Teuchos_ArrayView.hpp" 00048 #include "Teuchos_Assert.hpp" 00049 #include "Teuchos_dyn_cast.hpp" 00050 #include "Teuchos_as.hpp" 00051 00052 00053 namespace Teuchos { 00054 00055 00056 // Helper code (not for general clients) 00057 00058 00059 template<class T> inline 00060 RCPNode* ArrayRCP_createNewRCPNodeRawPtr( T* p, bool has_ownership_in ) 00061 { 00062 return new RCPNodeTmpl<T,DeallocArrayDelete<T> >( 00063 p, DeallocArrayDelete<T>(), has_ownership_in 00064 ); 00065 } 00066 00067 00068 template<class T, class Dealloc_T> 00069 inline 00070 RCPNode* ArrayRCP_createNewDeallocRCPNodeRawPtr( 00071 T* p, Dealloc_T dealloc, bool has_ownership_in 00072 ) 00073 { 00074 return new RCPNodeTmpl<T,Dealloc_T>(p, dealloc, has_ownership_in); 00075 } 00076 00077 00078 template<class T2, class T1> 00079 class ArcpReinterpretCastEmbeddedObj 00080 { 00081 public: 00082 typedef T2 ptr_t; 00083 ArcpReinterpretCastEmbeddedObj() 00084 : arcp_pod_(null) 00085 {} 00086 ArcpReinterpretCastEmbeddedObj(const ArrayRCP<T1> &arcp_pod) 00087 : arcp_pod_(arcpCloneNode(arcp_pod)) // Unique reference count! 00088 {} 00089 // NOTE: The default copy constructor is allowed and does the right thing 00090 ~ArcpReinterpretCastEmbeddedObj() 00091 { freeMemory(); } 00092 ArcpReinterpretCastEmbeddedObj& 00093 operator=(const ArcpReinterpretCastEmbeddedObj& arceo) 00094 { 00095 assert(is_null(arceo.arcp_pod_)); // Can only be a catestrophic programming error! 00096 freeMemory(); 00097 return *this; 00098 } 00099 private: 00100 ArrayRCP<T1> arcp_pod_; 00101 void freeMemory() 00102 { 00103 typedef typename ArrayRCP<T2>::iterator itr_t; 00104 if (arcp_pod_.strong_count() == 1) { 00105 ArrayRCP<T2> arcp2 = arcp_reinterpret_cast<T2>(arcp_pod_); 00106 for (itr_t itr = arcp2.begin(); itr != arcp2.end(); ++itr) { 00107 itr->~T2(); 00108 } 00109 arcp_pod_ = null; 00110 } 00111 } 00112 }; 00113 00114 00115 // Constructors/Destructors/Initializers 00116 00117 template<class T> inline 00118 ArrayRCP<T>::ArrayRCP( ENull ) 00119 : ptr_(NULL), lowerOffset_(0), upperOffset_(-1) 00120 {} 00121 00122 template<class T> inline 00123 ArrayRCP<const T>::ArrayRCP( ENull ) 00124 : ptr_(NULL), lowerOffset_(0), upperOffset_(-1) 00125 {} 00126 00127 00128 template<class T> inline 00129 ArrayRCP<T>::ArrayRCP(size_type n, const T& val) 00130 : ptr_(0), lowerOffset_(0), upperOffset_(-1) 00131 { 00132 *this = arcp<T>(n); 00133 std::fill_n(begin(), n, val); 00134 } 00135 00136 template<class T> inline 00137 ArrayRCP<const T>::ArrayRCP (size_type n, const T& val) 00138 : ptr_(0), lowerOffset_(0), upperOffset_(-1) 00139 { 00140 // We can't call std::fill_n on a const T*, so we have to create a 00141 // nonconst array first, fill it, and then convert to const. 00142 ArrayRCP<T> nonconstArray (n, val); 00143 *this = arcp_const_cast<const T> (nonconstArray); 00144 } 00145 00146 00147 template<class T> inline 00148 ArrayRCP<T>::ArrayRCP( 00149 T* p, size_type lowerOffset_in, size_type size_in, 00150 bool has_ownership_in, const ERCPNodeLookup rcpNodeLookup 00151 ) 00152 : ptr_(p), 00153 #ifndef TEUCHOS_DEBUG 00154 node_(ArrayRCP_createNewRCPNodeRawPtr(p, has_ownership_in)), 00155 #endif // TEUCHOS_DEBUG 00156 lowerOffset_(lowerOffset_in), 00157 upperOffset_(size_in + lowerOffset_in - 1) 00158 { 00159 #ifdef TEUCHOS_DEBUG 00160 if (p) { 00161 RCPNode* existing_RCPNode = 0; 00162 if (!has_ownership_in && rcpNodeLookup==RCP_ENABLE_NODE_LOOKUP) { 00163 existing_RCPNode = RCPNodeTracer::getExistingRCPNode(p); 00164 } 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 RCPNodeThrowDeleter nodeDeleter(ArrayRCP_createNewRCPNodeRawPtr(p, has_ownership_in)); 00172 node_ = RCPNodeHandle( 00173 nodeDeleter.get(), 00174 p, typeName(*p), concreteTypeName(*p), 00175 has_ownership_in 00176 ); 00177 nodeDeleter.release(); 00178 } 00179 } 00180 #else // NOT TEUCHOS_DEBUG 00181 (void) rcpNodeLookup; // Silence "unused variable" compiler warning. 00182 #endif // TEUCHOS_DEBUG 00183 } 00184 00185 template<class T> inline 00186 ArrayRCP<const T>:: 00187 ArrayRCP (const T* p, size_type lowerOffset_in, size_type size_in, 00188 bool has_ownership_in, const ERCPNodeLookup rcpNodeLookup) 00189 : ptr_(p), 00190 #ifndef TEUCHOS_DEBUG 00191 node_(ArrayRCP_createNewRCPNodeRawPtr(p, has_ownership_in)), 00192 #endif // TEUCHOS_DEBUG 00193 lowerOffset_(lowerOffset_in), 00194 upperOffset_(size_in + lowerOffset_in - 1) 00195 { 00196 #ifdef TEUCHOS_DEBUG 00197 if (p) { 00198 RCPNode* existing_RCPNode = 0; 00199 if (! has_ownership_in && rcpNodeLookup == RCP_ENABLE_NODE_LOOKUP) { 00200 existing_RCPNode = RCPNodeTracer::getExistingRCPNode (p); 00201 } 00202 if (existing_RCPNode) { 00203 // Will not call add_new_RCPNode(...) 00204 node_ = RCPNodeHandle(existing_RCPNode, RCP_WEAK, false); 00205 } 00206 else { 00207 // Will call add_new_RCPNode(...) 00208 RCPNodeThrowDeleter nodeDeleter (ArrayRCP_createNewRCPNodeRawPtr (p, has_ownership_in)); 00209 node_ = RCPNodeHandle( 00210 nodeDeleter.get (), 00211 p, typeName (*p), concreteTypeName (*p), 00212 has_ownership_in 00213 ); 00214 nodeDeleter.release (); 00215 } 00216 } 00217 #else // NOT TEUCHOS_DEBUG 00218 (void) rcpNodeLookup; // Silence "unused variable" compiler warning. 00219 #endif // TEUCHOS_DEBUG 00220 } 00221 00222 00223 template<class T> 00224 template<class Dealloc_T> 00225 inline 00226 ArrayRCP<T>::ArrayRCP( 00227 T* p, size_type lowerOffset_in, size_type size_in, 00228 Dealloc_T dealloc, bool has_ownership_in 00229 ) 00230 : ptr_(p), 00231 #ifndef TEUCHOS_DEBUG 00232 node_(ArrayRCP_createNewDeallocRCPNodeRawPtr(p, dealloc, has_ownership_in)), 00233 #endif // TEUCHOS_DEBUG 00234 lowerOffset_(lowerOffset_in), 00235 upperOffset_(size_in + lowerOffset_in - 1) 00236 { 00237 #ifdef TEUCHOS_DEBUG 00238 if (p) { 00239 node_ = RCPNodeHandle( 00240 ArrayRCP_createNewDeallocRCPNodeRawPtr(p, dealloc, has_ownership_in), 00241 p, typeName(*p), concreteTypeName(*p), 00242 has_ownership_in 00243 //, RCP_STRONG, false 00244 ); 00245 } 00246 #endif // TEUCHOS_DEBUG 00247 } 00248 00249 template<class T> 00250 template<class Dealloc_T> 00251 inline 00252 ArrayRCP<const T>::ArrayRCP( 00253 const T* p, size_type lowerOffset_in, size_type size_in, 00254 Dealloc_T dealloc, bool has_ownership_in 00255 ) 00256 : ptr_(p), 00257 #ifndef TEUCHOS_DEBUG 00258 node_(ArrayRCP_createNewDeallocRCPNodeRawPtr(p, dealloc, has_ownership_in)), 00259 #endif // TEUCHOS_DEBUG 00260 lowerOffset_(lowerOffset_in), 00261 upperOffset_(size_in + lowerOffset_in - 1) 00262 { 00263 #ifdef TEUCHOS_DEBUG 00264 if (p) { 00265 node_ = RCPNodeHandle( 00266 ArrayRCP_createNewDeallocRCPNodeRawPtr(p, dealloc, has_ownership_in), 00267 p, typeName(*p), concreteTypeName(*p), 00268 has_ownership_in 00269 //, RCP_STRONG, false 00270 ); 00271 } 00272 #endif // TEUCHOS_DEBUG 00273 } 00274 00275 00276 template<class T> inline 00277 ArrayRCP<T>::ArrayRCP(const ArrayRCP<T>& r_ptr) 00278 :ptr_(r_ptr.ptr_), 00279 node_(r_ptr.node_), 00280 lowerOffset_(r_ptr.lowerOffset_), 00281 upperOffset_(r_ptr.upperOffset_) 00282 {} 00283 00284 template<class T> inline 00285 ArrayRCP<const T>::ArrayRCP (const ArrayRCP<const T>& r_ptr) 00286 :ptr_(r_ptr.ptr_), 00287 node_(r_ptr.node_), 00288 lowerOffset_(r_ptr.lowerOffset_), 00289 upperOffset_(r_ptr.upperOffset_) 00290 {} 00291 00292 00293 template<class T> inline 00294 ArrayRCP<T>::~ArrayRCP() {} 00295 00296 template<class T> inline 00297 ArrayRCP<const T>::~ArrayRCP() {} 00298 00299 00300 template<class T> inline 00301 ArrayRCP<T>& ArrayRCP<T>::operator=(const ArrayRCP<T>& r_ptr) 00302 { 00303 if( this == &r_ptr ) 00304 return *this; // Assignment to self 00305 node_ = r_ptr.access_private_node(); // May throw in debug mode! 00306 ptr_ = r_ptr.ptr_; 00307 lowerOffset_ = r_ptr.lowerOffset_; 00308 upperOffset_ = r_ptr.upperOffset_; 00309 return *this; 00310 // NOTE: It is critical that the assignment of ptr_ come *after* the 00311 // assignment of node_ since node_ might throw an exception! 00312 } 00313 00314 template<class T> inline 00315 ArrayRCP<const T>& 00316 ArrayRCP<const T>::operator= (const ArrayRCP<const T>& r_ptr) 00317 { 00318 if (this == &r_ptr) { 00319 return *this; // Assignment to self 00320 } 00321 node_ = r_ptr.access_private_node (); // May throw in debug mode! 00322 ptr_ = r_ptr.ptr_; 00323 lowerOffset_ = r_ptr.lowerOffset_; 00324 upperOffset_ = r_ptr.upperOffset_; 00325 return *this; 00326 // NOTE: The assignment of ptr_ MUST come after the assignment of 00327 // node_, since that line of code might throw an exception! 00328 } 00329 00330 00331 // Object/Pointer Access Functions 00332 00333 00334 template<class T> inline 00335 bool ArrayRCP<T>::is_null() const { 00336 return ptr_ == 0; 00337 } 00338 00339 template<class T> inline 00340 bool ArrayRCP<const T>::is_null() const { 00341 return ptr_ == 0; 00342 } 00343 00344 00345 template<class T> inline 00346 T* ArrayRCP<T>::operator->() const 00347 { 00348 debug_assert_valid_ptr(); 00349 debug_assert_in_range(0,1); 00350 return ptr_; 00351 } 00352 00353 template<class T> inline 00354 const T* ArrayRCP<const T>::operator->() const 00355 { 00356 debug_assert_valid_ptr(); 00357 debug_assert_in_range(0,1); 00358 return ptr_; 00359 } 00360 00361 00362 template<class T> inline 00363 T& ArrayRCP<T>::operator*() const 00364 { 00365 debug_assert_valid_ptr(); 00366 debug_assert_in_range(0,1); 00367 return *ptr_; 00368 } 00369 00370 template<class T> inline 00371 const T& ArrayRCP<const T>::operator*() const 00372 { 00373 debug_assert_valid_ptr(); 00374 debug_assert_in_range(0,1); 00375 return *ptr_; 00376 } 00377 00378 00379 template<class T> inline 00380 T* ArrayRCP<T>::get() const 00381 { 00382 if (ptr_) { 00383 debug_assert_valid_ptr(); 00384 debug_assert_in_range(0,1); 00385 } 00386 return ptr_; 00387 } 00388 00389 template<class T> inline 00390 const T* ArrayRCP<const T>::get() const 00391 { 00392 if (ptr_) { 00393 debug_assert_valid_ptr(); 00394 debug_assert_in_range(0,1); 00395 } 00396 return ptr_; 00397 } 00398 00399 00400 template<class T> inline 00401 T* ArrayRCP<T>::getRawPtr() const { 00402 return this->get(); 00403 } 00404 00405 template<class T> inline 00406 const T* ArrayRCP<const T>::getRawPtr() const { 00407 return this->get(); 00408 } 00409 00410 00411 template<class T> inline 00412 T& ArrayRCP<T>::operator[](size_type offset) const 00413 { 00414 debug_assert_valid_ptr(); 00415 debug_assert_in_range(offset,1); 00416 return ptr_[offset]; 00417 } 00418 00419 template<class T> inline 00420 const T& ArrayRCP<const T>::operator[] (size_type offset) const 00421 { 00422 debug_assert_valid_ptr(); 00423 debug_assert_in_range(offset,1); 00424 return ptr_[offset]; 00425 } 00426 00427 00428 // Pointer Arithmetic Functions 00429 00430 00431 template<class T> inline 00432 ArrayRCP<T>& ArrayRCP<T>::operator++() 00433 { 00434 debug_assert_valid_ptr(); 00435 ++ptr_; 00436 --lowerOffset_; 00437 --upperOffset_; 00438 return *this; 00439 } 00440 00441 template<class T> inline 00442 ArrayRCP<const T>& ArrayRCP<const T>::operator++() 00443 { 00444 debug_assert_valid_ptr(); 00445 ++ptr_; 00446 --lowerOffset_; 00447 --upperOffset_; 00448 return *this; 00449 } 00450 00451 00452 template<class T> inline 00453 ArrayRCP<T> ArrayRCP<T>::operator++(int) 00454 { 00455 debug_assert_valid_ptr(); 00456 ArrayRCP<T> r_ptr = *this; 00457 ++(*this); 00458 return r_ptr; 00459 } 00460 00461 template<class T> inline 00462 ArrayRCP<const T> ArrayRCP<const T>::operator++(int) 00463 { 00464 debug_assert_valid_ptr(); 00465 ArrayRCP<const T> r_ptr = *this; 00466 ++(*this); 00467 return r_ptr; 00468 } 00469 00470 00471 template<class T> inline 00472 ArrayRCP<T>& ArrayRCP<T>::operator--() 00473 { 00474 debug_assert_valid_ptr(); 00475 --ptr_; 00476 ++lowerOffset_; 00477 ++upperOffset_; 00478 return *this; 00479 } 00480 00481 template<class T> inline 00482 ArrayRCP<const T>& ArrayRCP<const T>::operator--() 00483 { 00484 debug_assert_valid_ptr(); 00485 --ptr_; 00486 ++lowerOffset_; 00487 ++upperOffset_; 00488 return *this; 00489 } 00490 00491 00492 template<class T> inline 00493 ArrayRCP<T> ArrayRCP<T>::operator--(int) 00494 { 00495 debug_assert_valid_ptr(); 00496 ArrayRCP<T> r_ptr = *this; 00497 --(*this); 00498 return r_ptr; 00499 } 00500 00501 template<class T> inline 00502 ArrayRCP<const T> ArrayRCP<const T>::operator--(int) 00503 { 00504 debug_assert_valid_ptr(); 00505 ArrayRCP<const T> r_ptr = *this; 00506 --(*this); 00507 return r_ptr; 00508 } 00509 00510 00511 template<class T> inline 00512 ArrayRCP<T>& ArrayRCP<T>::operator+=(size_type offset) 00513 { 00514 debug_assert_valid_ptr(); 00515 ptr_ += offset; 00516 lowerOffset_ -= offset; 00517 upperOffset_ -= offset; 00518 return *this; 00519 } 00520 00521 template<class T> inline 00522 ArrayRCP<const T>& ArrayRCP<const T>::operator+=(size_type offset) 00523 { 00524 debug_assert_valid_ptr(); 00525 ptr_ += offset; 00526 lowerOffset_ -= offset; 00527 upperOffset_ -= offset; 00528 return *this; 00529 } 00530 00531 00532 template<class T> inline 00533 ArrayRCP<T>& ArrayRCP<T>::operator-=(size_type offset) 00534 { 00535 debug_assert_valid_ptr(); 00536 ptr_ -= offset; 00537 lowerOffset_ += offset; 00538 upperOffset_ += offset; 00539 return *this; 00540 } 00541 00542 template<class T> inline 00543 ArrayRCP<const T>& ArrayRCP<const T>::operator-=(size_type offset) 00544 { 00545 debug_assert_valid_ptr(); 00546 ptr_ -= offset; 00547 lowerOffset_ += offset; 00548 upperOffset_ += offset; 00549 return *this; 00550 } 00551 00552 00553 template<class T> inline 00554 ArrayRCP<T> ArrayRCP<T>::operator+(size_type offset) const 00555 { 00556 ArrayRCP<T> r_ptr = *this; 00557 r_ptr+=(offset); 00558 return r_ptr; 00559 } 00560 00561 template<class T> inline 00562 ArrayRCP<const T> ArrayRCP<const T>::operator+(size_type offset) const 00563 { 00564 ArrayRCP<const T> r_ptr = *this; 00565 r_ptr+=(offset); 00566 return r_ptr; 00567 } 00568 00569 00570 template<class T> inline 00571 ArrayRCP<T> ArrayRCP<T>::operator-(size_type offset) const 00572 { 00573 ArrayRCP<T> r_ptr = *this; 00574 r_ptr-=offset; 00575 return r_ptr; 00576 } 00577 00578 template<class T> inline 00579 ArrayRCP<const T> ArrayRCP<const T>::operator-(size_type offset) const 00580 { 00581 ArrayRCP<const T> r_ptr = *this; 00582 r_ptr-=offset; 00583 return r_ptr; 00584 } 00585 00586 00587 // Standard Container-Like Functions 00588 00589 00590 template<class T> inline 00591 typename ArrayRCP<T>::iterator ArrayRCP<T>::begin() const 00592 { 00593 debug_assert_valid_ptr(); 00594 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00595 return *this; 00596 #else 00597 return ptr_; 00598 #endif 00599 } 00600 00601 template<class T> inline 00602 typename ArrayRCP<const T>::iterator ArrayRCP<const T>::begin() const 00603 { 00604 debug_assert_valid_ptr(); 00605 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00606 return *this; 00607 #else 00608 return ptr_; 00609 #endif 00610 } 00611 00612 00613 template<class T> inline 00614 typename ArrayRCP<T>::iterator ArrayRCP<T>::end() const 00615 { 00616 debug_assert_valid_ptr(); 00617 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00618 return *this + (upperOffset_ + 1); 00619 #else 00620 return ptr_ + (upperOffset_ + 1); 00621 #endif 00622 } 00623 00624 template<class T> inline 00625 typename ArrayRCP<const T>::iterator ArrayRCP<const T>::end() const 00626 { 00627 debug_assert_valid_ptr(); 00628 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00629 return *this + (upperOffset_ + 1); 00630 #else 00631 return ptr_ + (upperOffset_ + 1); 00632 #endif 00633 } 00634 00635 00636 // ArrayRCP Views 00637 00638 00639 template<class T> inline 00640 ArrayRCP<const T> ArrayRCP<T>::getConst() const 00641 { 00642 if (ptr_) { 00643 debug_assert_valid_ptr(); 00644 const T *cptr = ptr_; // Will not compile if not legal! 00645 return ArrayRCP<const T>(cptr, lowerOffset_, size(), node_); 00646 } 00647 return null; 00648 } 00649 00650 template<class T> inline 00651 ArrayRCP<const T> ArrayRCP<const T>::getConst() const { 00652 // Trivial implementation, since no need for conversion. 00653 return *this; 00654 } 00655 00656 00657 template<class T> inline 00658 ArrayRCP<T> 00659 ArrayRCP<T>::persistingView( size_type lowerOffset_in, size_type size_in ) const 00660 { 00661 if (size_in == 0) { 00662 return null; 00663 } 00664 debug_assert_valid_ptr(); 00665 debug_assert_in_range(lowerOffset_in, size_in); 00666 ArrayRCP<T> ptr = *this; 00667 ptr.ptr_ = ptr.ptr_ + lowerOffset_in; 00668 ptr.lowerOffset_ = 0; 00669 ptr.upperOffset_ = size_in - 1; 00670 return ptr; 00671 } 00672 00673 template<class T> inline 00674 ArrayRCP<const T> 00675 ArrayRCP<const T>::persistingView (size_type lowerOffset_in, size_type size_in) const 00676 { 00677 if (size_in == 0) { 00678 return null; 00679 } 00680 debug_assert_valid_ptr(); 00681 debug_assert_in_range(lowerOffset_in, size_in); 00682 ArrayRCP<const T> ptr = *this; 00683 ptr.ptr_ = ptr.ptr_ + lowerOffset_in; 00684 ptr.lowerOffset_ = 0; 00685 ptr.upperOffset_ = size_in - 1; 00686 return ptr; 00687 } 00688 00689 00690 // Size and extent query functions 00691 00692 00693 template<class T> inline 00694 typename ArrayRCP<T>::size_type 00695 ArrayRCP<T>::lowerOffset() const 00696 { 00697 debug_assert_valid_ptr(); 00698 return lowerOffset_; 00699 } 00700 00701 template<class T> inline 00702 typename ArrayRCP<const T>::size_type 00703 ArrayRCP<const T>::lowerOffset() const 00704 { 00705 debug_assert_valid_ptr(); 00706 return lowerOffset_; 00707 } 00708 00709 00710 template<class T> inline 00711 typename ArrayRCP<T>::size_type 00712 ArrayRCP<T>::upperOffset() const 00713 { 00714 debug_assert_valid_ptr(); 00715 return upperOffset_; 00716 } 00717 00718 template<class T> inline 00719 typename ArrayRCP<const T>::size_type 00720 ArrayRCP<const T>::upperOffset() const 00721 { 00722 debug_assert_valid_ptr(); 00723 return upperOffset_; 00724 } 00725 00726 00727 template<class T> inline 00728 typename ArrayRCP<T>::size_type 00729 ArrayRCP<T>::size() const 00730 { 00731 debug_assert_valid_ptr(); 00732 return upperOffset_ - lowerOffset_ + 1; 00733 } 00734 00735 template<class T> inline 00736 typename ArrayRCP<const T>::size_type 00737 ArrayRCP<const T>::size() const 00738 { 00739 debug_assert_valid_ptr(); 00740 return upperOffset_ - lowerOffset_ + 1; 00741 } 00742 00743 00744 // ArrayView views 00745 00746 00747 template<class T> inline 00748 ArrayView<T> ArrayRCP<T>::view( size_type lowerOffset_in, size_type size_in ) const 00749 { 00750 if (size_in == 0) { 00751 return null; 00752 } 00753 debug_assert_valid_ptr(); 00754 debug_assert_in_range(lowerOffset_in,size_in); 00755 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00756 return ArrayView<T>(persistingView(lowerOffset_in, size_in).create_weak()); 00757 #else 00758 return arrayView(ptr_ + lowerOffset_in, size_in); 00759 #endif 00760 // ToDo: Implement checks for dangling references! 00761 } 00762 00763 template<class T> inline 00764 ArrayView<const T> 00765 ArrayRCP<const T>::view (size_type lowerOffset_in, size_type size_in) const 00766 { 00767 if (size_in == 0) { 00768 return null; 00769 } 00770 debug_assert_valid_ptr(); 00771 debug_assert_in_range(lowerOffset_in,size_in); 00772 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 00773 return ArrayView<const T> (persistingView (lowerOffset_in, size_in).create_weak ()); 00774 #else 00775 return arrayView (ptr_ + lowerOffset_in, size_in); 00776 #endif 00777 // ToDo: Implement checks for dangling references! 00778 } 00779 00780 00781 template<class T> inline 00782 ArrayView<T> ArrayRCP<T>::operator()( size_type lowerOffset_in, size_type size_in ) const 00783 { 00784 return view(lowerOffset_in, size_in); 00785 } 00786 00787 template<class T> inline 00788 ArrayView<const T> 00789 ArrayRCP<const T>::operator() (size_type lowerOffset_in, size_type size_in) const 00790 { 00791 return view (lowerOffset_in, size_in); 00792 } 00793 00794 00795 template<class T> inline 00796 ArrayView<T> ArrayRCP<T>::operator()() const 00797 { 00798 if (size()) { 00799 return view(lowerOffset_, size()); 00800 } 00801 return null; 00802 } 00803 00804 template<class T> inline 00805 ArrayView<const T> ArrayRCP<const T>::operator()() const 00806 { 00807 if (size()) { 00808 return view (lowerOffset_, size ()); 00809 } 00810 return null; 00811 } 00812 00813 00814 // Implicit conversions 00815 00816 00817 template<class T> inline 00818 ArrayRCP<T>::operator ArrayRCP<const T>() const 00819 { 00820 if (size()) { 00821 return ArrayRCP<const T>(ptr_, lowerOffset_, size(), node_); 00822 } 00823 return null; 00824 } 00825 // The above operator does not exist in the partial specialization for 00826 // const T, because it doesn't make sense in that case. (Many 00827 // compilers warn if one tries to implement that operator, because 00828 // that code would never get called.) 00829 00830 00831 // std::vector like functions 00832 // 00833 // Assignment (deep copy) doesn't make sense for the "const T" partial 00834 // specialization, so the assignment methods (assign() and deepCopy()) 00835 // are omitted in that case. 00836 00837 00838 template<class T> inline 00839 void ArrayRCP<T>::assign (size_type n, const T &val) { 00840 *this = arcp<T> (n); 00841 std::fill_n (this->begin (), n, val); 00842 } 00843 00844 00845 template<class T> 00846 template<class Iter> 00847 inline 00848 void ArrayRCP<T>::assign (Iter first, Iter last) { 00849 const size_type new_n = std::distance (first, last); 00850 if (new_n != size ()) { 00851 *this = arcp<T> (new_n); 00852 } 00853 std::copy (first, last, begin ()); 00854 } 00855 00856 00857 template<class T> inline 00858 void ArrayRCP<T>::resize(const size_type n, const T &val) 00859 { 00860 #ifdef TEUCHOS_DEBUG 00861 TEUCHOS_ASSERT_EQUALITY(lowerOffset(), 0); 00862 #endif 00863 if (n == 0) { 00864 clear(); 00865 return; 00866 } 00867 const size_type orig_n = size(); 00868 if (n != orig_n) { 00869 ArrayRCP<T> tmp = *this; 00870 *this = arcp<T>(n); 00871 const size_type small_n = std::min(n, orig_n); 00872 for (size_type i = 0; i < small_n; ++i) 00873 (*this)[i] = tmp[i]; 00874 for (size_type i = orig_n; i < n; ++i) 00875 (*this)[i] = val; 00876 upperOffset_ = n-1; 00877 } 00878 } 00879 00880 template<class T> inline 00881 void ArrayRCP<const T>::resize (const size_type n, const T& val) 00882 { 00883 #ifdef TEUCHOS_DEBUG 00884 TEUCHOS_ASSERT_EQUALITY(lowerOffset(), 0); 00885 #endif 00886 if (n == 0) { 00887 clear (); 00888 return; 00889 } 00890 const size_type orig_n = size (); 00891 if (n != orig_n) { 00892 ArrayRCP<const T> tmp = *this; 00893 // It's not allowed to assign to the result of operator[] for a 00894 // const right-hand side, so we have to assign to a temporary 00895 // nonconst ArrayRCP (nonconstThis) first. 00896 ArrayRCP<T> nonconstThis = arcp<T> (n); 00897 const size_type small_n = std::min (n, orig_n); 00898 for (size_type i = 0; i < small_n; ++i) { 00899 nonconstThis[i] = tmp[i]; 00900 } 00901 for (size_type i = orig_n; i < n; ++i) { 00902 nonconstThis[i] = val; 00903 } 00904 *this = arcp_const_cast<const T> (nonconstThis); 00905 upperOffset_ = n-1; 00906 } 00907 } 00908 00909 00910 template<class T> inline 00911 void ArrayRCP<T>::clear() { 00912 *this = null; 00913 } 00914 00915 template<class T> inline 00916 void ArrayRCP<const T>::clear() { 00917 *this = null; 00918 } 00919 00920 00921 // Misc functions 00922 00923 00924 template<class T> inline 00925 void ArrayRCP<T>::deepCopy(const ArrayView<const T>& av) 00926 { 00927 if (av.size() == 0) { 00928 *this = null; 00929 return; 00930 } 00931 assign(av.begin(), av.end()); 00932 } 00933 00934 00935 // Reference counting 00936 00937 00938 template<class T> inline 00939 ERCPStrength ArrayRCP<T>::strength() const { 00940 return node_.strength(); 00941 } 00942 00943 template<class T> inline 00944 ERCPStrength ArrayRCP<const T>::strength() const { 00945 return node_.strength(); 00946 } 00947 00948 00949 template<class T> inline 00950 bool ArrayRCP<T>::is_valid_ptr() const 00951 { 00952 if (ptr_) 00953 return node_.is_valid_ptr(); 00954 return true; 00955 } 00956 00957 template<class T> inline 00958 bool ArrayRCP<const T>::is_valid_ptr() const 00959 { 00960 if (ptr_) 00961 return node_.is_valid_ptr(); 00962 return true; 00963 } 00964 00965 00966 template<class T> inline 00967 int ArrayRCP<T>::strong_count() const 00968 { 00969 return node_.strong_count(); 00970 } 00971 00972 template<class T> inline 00973 int ArrayRCP<const T>::strong_count() const 00974 { 00975 return node_.strong_count(); 00976 } 00977 00978 00979 template<class T> inline 00980 int ArrayRCP<T>::weak_count() const 00981 { 00982 return node_.weak_count(); 00983 } 00984 00985 template<class T> inline 00986 int ArrayRCP<const T>::weak_count() const 00987 { 00988 return node_.weak_count(); 00989 } 00990 00991 00992 template<class T> inline 00993 int ArrayRCP<T>::total_count() const 00994 { 00995 return node_.total_count(); 00996 } 00997 00998 template<class T> inline 00999 int ArrayRCP<const T>::total_count() const 01000 { 01001 return node_.total_count(); 01002 } 01003 01004 01005 template<class T> inline 01006 void ArrayRCP<T>::set_has_ownership() 01007 { 01008 node_.has_ownership(true); 01009 } 01010 01011 template<class T> inline 01012 void ArrayRCP<const T>::set_has_ownership() 01013 { 01014 node_.has_ownership(true); 01015 } 01016 01017 01018 template<class T> inline 01019 bool ArrayRCP<T>::has_ownership() const 01020 { 01021 return node_.has_ownership(); 01022 } 01023 01024 template<class T> inline 01025 bool ArrayRCP<const T>::has_ownership() const 01026 { 01027 return node_.has_ownership(); 01028 } 01029 01030 01031 template<class T> inline 01032 T* ArrayRCP<T>::release() 01033 { 01034 debug_assert_valid_ptr(); 01035 node_.has_ownership(false); 01036 return ptr_; 01037 } 01038 01039 template<class T> inline 01040 const T* ArrayRCP<const T>::release() 01041 { 01042 debug_assert_valid_ptr(); 01043 node_.has_ownership(false); 01044 return ptr_; 01045 } 01046 01047 01048 template<class T> inline 01049 ArrayRCP<T> ArrayRCP<T>::create_weak () const { 01050 debug_assert_valid_ptr (); 01051 return ArrayRCP<T> (ptr_, lowerOffset_, size (), node_.create_weak ()); 01052 } 01053 01054 template<class T> inline 01055 ArrayRCP<const T> ArrayRCP<const T>::create_weak() const { 01056 debug_assert_valid_ptr (); 01057 return ArrayRCP<const T> (ptr_, lowerOffset_, size (), node_.create_weak ()); 01058 } 01059 01060 01061 template<class T> inline 01062 ArrayRCP<T> ArrayRCP<T>::create_strong () const { 01063 debug_assert_valid_ptr (); 01064 return ArrayRCP<T> (ptr_, lowerOffset_, size (), node_.create_strong ()); 01065 } 01066 01067 template<class T> inline 01068 ArrayRCP<const T> ArrayRCP<const T>::create_strong () const { 01069 debug_assert_valid_ptr (); 01070 return ArrayRCP<const T> (ptr_, lowerOffset_, size (), node_.create_strong ()); 01071 } 01072 01073 01074 template<class T> 01075 template <class T2> 01076 inline 01077 bool ArrayRCP<T>::shares_resource (const ArrayRCP<T2>& r_ptr) const 01078 { 01079 return node_.same_node (r_ptr.access_private_node ()); 01080 // Note: above, r_ptr is *not* the same class type as *this so we can not 01081 // access its node_ member directly! This is an interesting detail to the 01082 // C++ protected/private protection mechanism! 01083 } 01084 01085 template<class T> 01086 template <class T2> 01087 inline 01088 bool ArrayRCP<const T>::shares_resource (const ArrayRCP<T2>& r_ptr) const 01089 { 01090 return node_.same_node (r_ptr.access_private_node ()); 01091 // Note: above, r_ptr is *not* the same class type as *this so we can not 01092 // access its node_ member directly! This is an interesting detail to the 01093 // C++ protected/private protection mechanism! 01094 } 01095 01096 01097 // Assertion Functions 01098 01099 01100 template<class T> inline 01101 const ArrayRCP<T>& 01102 ArrayRCP<T>::assert_not_null() const 01103 { 01104 if(!ptr_) 01105 throw_null_ptr_error(typeName(*this)); 01106 return *this; 01107 } 01108 01109 template<class T> inline 01110 const ArrayRCP<const T>& 01111 ArrayRCP<const T>::assert_not_null() const 01112 { 01113 if (! ptr_) { 01114 throw_null_ptr_error (typeName (*this)); 01115 } 01116 return *this; 01117 } 01118 01119 01120 template<class T> inline 01121 const ArrayRCP<T>& ArrayRCP<T>::assert_valid_ptr() const 01122 { 01123 if (ptr_) { 01124 node_.assert_valid_ptr (*this); 01125 } 01126 return *this; 01127 } 01128 01129 template<class T> inline 01130 const ArrayRCP<const T>& ArrayRCP<const T>::assert_valid_ptr () const 01131 { 01132 if (ptr_) { 01133 node_.assert_valid_ptr (*this); 01134 } 01135 return *this; 01136 } 01137 01138 01139 template<class T> inline 01140 const ArrayRCP<T>& 01141 ArrayRCP<T>::assert_in_range( size_type lowerOffset_in, size_type size_in ) const 01142 { 01143 assert_not_null(); 01144 TEUCHOS_TEST_FOR_EXCEPTION( 01145 !( 01146 (lowerOffset_ <= lowerOffset_in && lowerOffset_in+size_in-1 <= upperOffset_) 01147 && 01148 size_in >= 0 01149 ), 01150 Teuchos::RangeError, 01151 typeName(*this)<<"::assert_in_range:" 01152 " Error, [lowerOffset,lowerOffset+size-1] = [" 01153 <<lowerOffset_in<<","<<(lowerOffset_in+size_in-1)<<"] does not lie in the" 01154 " range ["<<lowerOffset_<<","<<upperOffset_<<"]!" 01155 ); 01156 return *this; 01157 } 01158 01159 template<class T> inline 01160 const ArrayRCP<const T>& 01161 ArrayRCP<const T>:: 01162 assert_in_range (size_type lowerOffset_in, size_type size_in) const 01163 { 01164 assert_not_null (); 01165 TEUCHOS_TEST_FOR_EXCEPTION( 01166 !( 01167 (lowerOffset_ <= lowerOffset_in && lowerOffset_in+size_in-1 <= upperOffset_) 01168 && 01169 size_in >= 0 01170 ), 01171 Teuchos::RangeError, 01172 typeName (*this) << "::assert_in_range:" 01173 " Error, [lowerOffset,lowerOffset+size-1] = [" 01174 <<lowerOffset_in<<","<<(lowerOffset_in+size_in-1)<<"] does not lie in the" 01175 " range ["<<lowerOffset_<<","<<upperOffset_<<"]!" 01176 ); 01177 return *this; 01178 } 01179 01180 01181 // Deprecated 01182 01183 01184 template<class T> inline 01185 int ArrayRCP<T>::count() const { 01186 return node_.count(); 01187 } 01188 01189 template<class T> inline 01190 int ArrayRCP<const T>::count() const { 01191 return node_.count(); 01192 } 01193 01194 01195 // very bad public functions 01196 01197 01198 template<class T> inline 01199 ArrayRCP<T>::ArrayRCP( 01200 T* p, size_type lowerOffset_in, size_type size_in, 01201 const RCPNodeHandle& node 01202 ) 01203 :ptr_(p), 01204 node_(node), 01205 lowerOffset_(lowerOffset_in), 01206 upperOffset_(size_in + lowerOffset_in - 1) 01207 {} 01208 01209 template<class T> inline 01210 ArrayRCP<const T>::ArrayRCP( 01211 const T* p, size_type lowerOffset_in, size_type size_in, 01212 const RCPNodeHandle& node 01213 ) 01214 :ptr_(p), 01215 node_(node), 01216 lowerOffset_(lowerOffset_in), 01217 upperOffset_(size_in + lowerOffset_in - 1) 01218 {} 01219 01220 01221 template<class T> inline 01222 T* ArrayRCP<T>::access_private_ptr() const 01223 { 01224 return ptr_; 01225 } 01226 01227 template<class T> inline 01228 const T* ArrayRCP<const T>::access_private_ptr () const 01229 { 01230 return ptr_; 01231 } 01232 01233 01234 template<class T> inline 01235 RCPNodeHandle& ArrayRCP<T>::nonconst_access_private_node() 01236 { 01237 return node_; 01238 } 01239 01240 template<class T> inline 01241 RCPNodeHandle& ArrayRCP<const T>::nonconst_access_private_node() 01242 { 01243 return node_; 01244 } 01245 01246 01247 template<class T> inline 01248 const RCPNodeHandle& ArrayRCP<T>::access_private_node() const 01249 { 01250 return node_; 01251 } 01252 01253 template<class T> inline 01254 const RCPNodeHandle& ArrayRCP<const T>::access_private_node() const 01255 { 01256 return node_; 01257 } 01258 01259 01260 // Array<void> and Array<const void> specializations 01261 01262 01263 ArrayRCP<void>::ArrayRCP() 01264 { 01265 TEUCHOS_TEST_FOR_EXCEPT(true); 01266 } 01267 01268 01269 ArrayRCP<const void>::ArrayRCP() 01270 { 01271 TEUCHOS_TEST_FOR_EXCEPT(true); 01272 } 01273 01274 01275 } // end namespace Teuchos 01276 01277 01278 // /////////////////////////////////////////// 01279 // Non-member functions for ArrayRCP 01280 01281 01282 namespace Teuchos { 01283 namespace Utilities { 01284 template<class T1, class T2> 01285 inline void assert_shares_resource( 01286 const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 01287 ) 01288 { 01289 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 01290 TEUCHOS_TEST_FOR_EXCEPTION( 01291 !p1.shares_resource(p2), IncompatibleIteratorsError, 01292 "Error, these iterators are *not* pointing to the same valid memory!" 01293 ); 01294 #endif 01295 } 01296 } // namespace Utilities 01297 } // namespace Teuchos 01298 01299 01300 template<class T> inline 01301 Teuchos::ArrayRCP<T> 01302 Teuchos::arcp( 01303 T* p, typename ArrayRCP<T>::size_type lowerOffset 01304 ,typename ArrayRCP<T>::size_type size_in 01305 ,bool owns_mem 01306 ) 01307 { 01308 return ArrayRCP<T>(p, lowerOffset, size_in, owns_mem); 01309 } 01310 01311 01312 template<class T, class Dealloc_T> 01313 inline 01314 Teuchos::ArrayRCP<T> 01315 Teuchos::arcp( 01316 T* p, typename ArrayRCP<T>::size_type lowerOffset 01317 ,typename ArrayRCP<T>::size_type size_in 01318 ,Dealloc_T dealloc, bool owns_mem 01319 ) 01320 { 01321 return ArrayRCP<T>(p, lowerOffset, size_in, dealloc, owns_mem); 01322 } 01323 01324 01325 template<class T> inline 01326 Teuchos::ArrayRCP<T> 01327 Teuchos::arcp( typename ArrayRCP<T>::size_type size ) 01328 { 01329 #ifdef TEUCHOS_DEBUG 01330 TEUCHOS_ASSERT_INEQUALITY( size, >=, 0 ); 01331 #endif 01332 if (size == 0) { 01333 return null; 01334 } 01335 return ArrayRCP<T>(new T[size], 0, size, true); 01336 } 01337 01338 01339 template<class T> inline 01340 Teuchos::ArrayRCP<T> 01341 Teuchos::arcpCloneNode(const ArrayRCP<T> &a) 01342 { 01343 if (is_null(a)) { 01344 return null; 01345 } 01346 return arcpWithEmbeddedObj(a.getRawPtr(), a.lowerOffset(), a.size(), 01347 a, false); 01348 } 01349 01350 01351 template<class T> inline 01352 Teuchos::ArrayRCP<T> 01353 Teuchos::arcpClone( const ArrayView<const T> &v ) 01354 { 01355 const ArrayRCP<T> new_arcp = arcp<T>(v.size()); 01356 std::copy( v.begin(), v.end(), new_arcp.begin() ); 01357 return new_arcp; 01358 } 01359 01360 01361 template<class T, class Embedded> 01362 Teuchos::ArrayRCP<T> 01363 Teuchos::arcpWithEmbeddedObjPreDestroy( 01364 T* p, 01365 typename ArrayRCP<T>::size_type lowerOffset, 01366 typename ArrayRCP<T>::size_type size, 01367 const Embedded &embedded, 01368 bool owns_mem 01369 ) 01370 { 01371 return arcp( 01372 p, lowerOffset, size, 01373 embeddedObjDeallocArrayDelete<T>(embedded, PRE_DESTROY), 01374 owns_mem 01375 ); 01376 } 01377 01378 01379 template<class T, class Embedded> 01380 Teuchos::ArrayRCP<T> 01381 Teuchos::arcpWithEmbeddedObjPostDestroy( 01382 T* p, 01383 typename ArrayRCP<T>::size_type lowerOffset, 01384 typename ArrayRCP<T>::size_type size, 01385 const Embedded &embedded, 01386 bool owns_mem 01387 ) 01388 { 01389 return arcp( 01390 p, lowerOffset, size, 01391 embeddedObjDeallocArrayDelete<T>(embedded, POST_DESTROY), 01392 owns_mem 01393 ); 01394 } 01395 01396 01397 template<class T, class Embedded> 01398 Teuchos::ArrayRCP<T> 01399 Teuchos::arcpWithEmbeddedObj( 01400 T* p, 01401 typename ArrayRCP<T>::size_type lowerOffset, 01402 typename ArrayRCP<T>::size_type size, 01403 const Embedded &embedded, 01404 bool owns_mem 01405 ) 01406 { 01407 return arcpWithEmbeddedObjPostDestroy<T,Embedded>( 01408 p, lowerOffset, size, embedded, owns_mem ); 01409 } 01410 01411 01412 template<class T> inline 01413 Teuchos::ArrayRCP<T> 01414 Teuchos::arcp( const RCP<std::vector<T> > &v ) 01415 { 01416 if ( is_null(v) || !v->size() ) 01417 return null; 01418 return arcpWithEmbeddedObjPostDestroy<T,RCP<std::vector<T> > >( 01419 &(*v)[0], 0, v->size(), 01420 v, false 01421 ); 01422 } 01423 01424 01425 template<class T> inline 01426 Teuchos::ArrayRCP<const T> 01427 Teuchos::arcp( const RCP<const std::vector<T> > &v ) 01428 { 01429 if ( is_null(v) || !v->size() ) 01430 return null; 01431 return arcpWithEmbeddedObjPostDestroy<const T,RCP<const std::vector<T> > >( 01432 &(*v)[0], 0, v->size(), 01433 v, false 01434 ); 01435 } 01436 01437 01438 template<class T> inline 01439 Teuchos::ArrayRCP<T> 01440 Teuchos::arcpFromArrayView(const ArrayView<T> &av) 01441 { 01442 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK 01443 return av.access_private_arcp(); 01444 #else 01445 return arcp(av.getRawPtr(), 0, av.size(), false); 01446 #endif 01447 } 01448 01449 01450 template<class T> inline 01451 Teuchos::RCP<std::vector<T> > 01452 Teuchos::get_std_vector( const ArrayRCP<T> &ptr ) 01453 { 01454 return getEmbeddedObj<T, RCP<std::vector<T> > >(ptr); 01455 } 01456 01457 01458 template<class T> inline 01459 Teuchos::RCP<const std::vector<T> > 01460 Teuchos::get_std_vector( const ArrayRCP<const T> &ptr ) 01461 { 01462 return getEmbeddedObj<const T, RCP<const std::vector<T> > >(ptr); 01463 } 01464 01465 01466 template<class T> inline 01467 bool Teuchos::is_null( const ArrayRCP<T> &p ) 01468 { 01469 return p.is_null(); 01470 } 01471 01472 01473 template<class T> inline 01474 bool Teuchos::nonnull( const ArrayRCP<T> &p ) 01475 { 01476 return !p.is_null(); 01477 } 01478 01479 01480 template<class T> inline 01481 bool Teuchos::operator==( const ArrayRCP<T> &p, ENull ) 01482 { 01483 return p.is_null(); 01484 } 01485 01486 01487 template<class T> inline 01488 bool Teuchos::operator!=( const ArrayRCP<T> &p, ENull ) 01489 { 01490 return !p.is_null(); 01491 } 01492 01493 01494 template<class T1, class T2> 01495 inline 01496 bool Teuchos::operator==( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 ) 01497 { 01498 return p1.access_private_ptr() == p2.access_private_ptr(); 01499 } 01500 01501 01502 template<class T1, class T2> 01503 inline 01504 bool Teuchos::operator!=( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 ) 01505 { 01506 return p1.access_private_ptr() != p2.access_private_ptr(); 01507 } 01508 01509 01510 template<class T1, class T2> 01511 inline 01512 bool Teuchos::operator<( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 ) 01513 { 01514 return p1.access_private_ptr() < p2.access_private_ptr(); 01515 } 01516 01517 01518 template<class T1, class T2> 01519 inline 01520 bool Teuchos::operator<=( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 ) 01521 { 01522 Utilities::assert_shares_resource(p1,p2); 01523 return p1.access_private_ptr() <= p2.access_private_ptr(); 01524 } 01525 01526 01527 template<class T1, class T2> 01528 inline 01529 bool Teuchos::operator>( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 ) 01530 { 01531 Utilities::assert_shares_resource(p1,p2); 01532 return p1.access_private_ptr() > p2.access_private_ptr(); 01533 } 01534 01535 01536 template<class T1, class T2> 01537 inline 01538 bool Teuchos::operator>=( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 ) 01539 { 01540 Utilities::assert_shares_resource(p1,p2); 01541 return p1.access_private_ptr() >= p2.access_private_ptr(); 01542 } 01543 01544 01545 template<class T> 01546 typename Teuchos::ArrayRCP<T>::difference_type 01547 Teuchos::operator-( const ArrayRCP<T> &p1, const ArrayRCP<T> &p2 ) 01548 { 01549 Utilities::assert_shares_resource(p1,p2); 01550 return p1.access_private_ptr() - p2.access_private_ptr(); 01551 } 01552 01553 01554 template<class T2, class T1> 01555 inline 01556 Teuchos::ArrayRCP<T2> 01557 Teuchos::arcp_reinterpret_cast(const ArrayRCP<T1>& p1) 01558 { 01559 typedef typename ArrayRCP<T1>::size_type size_type; 01560 const int sizeOfT1 = sizeof(T1); 01561 const int sizeOfT2 = sizeof(T2); 01562 size_type lowerOffset2 = (p1.lowerOffset()*sizeOfT1) / sizeOfT2; 01563 size_type upperOffset2 = ((p1.upperOffset()+1)*sizeOfT1) / sizeOfT2 - 1; 01564 T2 *ptr2 = reinterpret_cast<T2*>(p1.get()); 01565 return ArrayRCP<T2>( 01566 ptr2, lowerOffset2, upperOffset2 - lowerOffset2 + 1, 01567 p1.access_private_node() 01568 ); 01569 // Note: Above is just fine even if p1.get()==NULL! 01570 } 01571 01572 01573 template<class T2, class T1> 01574 Teuchos::ArrayRCP<T2> 01575 Teuchos::arcp_reinterpret_cast_nonpod(const ArrayRCP<T1>& p1, const T2& val) 01576 { 01577 typedef typename ArrayRCP<T2>::iterator itr_t; 01578 ArrayRCP<T2> arcp2 = arcp_reinterpret_cast<T2>(p1); 01579 for (itr_t itr = arcp2.begin(); itr != arcp2.end(); ++itr) { 01580 new (&*itr) T2(val); 01581 } 01582 return arcpWithEmbeddedObj( 01583 arcp2.getRawPtr(), 0, arcp2.size(), 01584 ArcpReinterpretCastEmbeddedObj<T2, T1>(p1), 01585 false); 01586 // Above, the ownership of the memory is totally owned by the embedded 01587 // object and the default deallocator policy object does not do anything. 01588 // This is just fine. 01589 } 01590 01591 01592 template<class T2, class T1> 01593 inline 01594 Teuchos::ArrayRCP<T2> 01595 Teuchos::arcp_const_cast(const ArrayRCP<T1>& p1) 01596 { 01597 T2 *ptr2 = const_cast<T2*>(p1.get()); 01598 return ArrayRCP<T2>( 01599 ptr2, p1.lowerOffset(), p1.size(), 01600 p1.access_private_node() 01601 ); 01602 // Note: Above is just fine even if p1.get()==NULL! 01603 } 01604 01605 01606 template<class T2, class T1> 01607 inline 01608 Teuchos::ArrayRCP<T2> 01609 Teuchos::arcp_implicit_cast(const ArrayRCP<T1>& p1) 01610 { 01611 T2 * raw_ptr2 = p1.get(); 01612 return ArrayRCP<T2>( 01613 raw_ptr2, p1.lowerOffset(), p1.size(), 01614 p1.access_private_node() 01615 ); 01616 // Note: Above is just fine even if p1.get()==NULL! 01617 } 01618 01619 01620 template<class T1, class T2> 01621 inline 01622 void Teuchos::set_extra_data( 01623 const T1 &extra_data, const std::string& name, 01624 const Ptr<ArrayRCP<T2> > &p, EPrePostDestruction destroy_when, 01625 bool force_unique 01626 ) 01627 { 01628 p->assert_not_null(); 01629 p->nonconst_access_private_node().set_extra_data( any(extra_data), name, destroy_when, 01630 force_unique ); 01631 } 01632 01633 01634 template<class T1, class T2> 01635 inline 01636 T1& Teuchos::get_extra_data( ArrayRCP<T2>& p, const std::string& name ) 01637 { 01638 p.assert_not_null(); 01639 return any_cast<T1>( 01640 p.nonconst_access_private_node().get_extra_data( 01641 TypeNameTraits<T1>::name(), name 01642 ) 01643 ); 01644 } 01645 01646 01647 template<class T1, class T2> 01648 inline 01649 const T1& Teuchos::get_extra_data( const ArrayRCP<T2>& p, const std::string& name ) 01650 { 01651 p.assert_not_null(); 01652 return any_cast<T1>( 01653 p.access_private_node().get_extra_data( 01654 TypeNameTraits<T1>::name() ,name 01655 ) 01656 ); 01657 } 01658 01659 01660 template<class T1, class T2> 01661 inline 01662 T1* Teuchos::get_optional_extra_data( ArrayRCP<T2>& p, const std::string& name ) 01663 { 01664 p.assert_not_null(); 01665 any *extra_data = p.nonconst_access_private_node().get_optional_extra_data( 01666 TypeNameTraits<T1>::name(), name); 01667 if( extra_data ) return &any_cast<T1>(*extra_data); 01668 return NULL; 01669 } 01670 01671 01672 template<class T1, class T2> 01673 inline 01674 const T1* Teuchos::get_optional_extra_data( const ArrayRCP<T2>& p, const std::string& name ) 01675 { 01676 p.assert_not_null(); 01677 any *extra_data = p.access_private_node().get_optional_extra_data( 01678 TypeNameTraits<T1>::name(), name); 01679 if( extra_data ) return &any_cast<T1>(*extra_data); 01680 return NULL; 01681 } 01682 01683 01684 template<class Dealloc_T, class T> 01685 inline 01686 const Dealloc_T& 01687 Teuchos::get_dealloc( const ArrayRCP<T>& p ) 01688 { 01689 return get_nonconst_dealloc<Dealloc_T>(p); 01690 } 01691 01692 01693 template<class Dealloc_T, class T> 01694 inline 01695 Dealloc_T& 01696 Teuchos::get_nonconst_dealloc( const Teuchos::ArrayRCP<T>& p ) 01697 { 01698 typedef RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T> requested_type; 01699 p.assert_not_null(); 01700 RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T> 01701 *dnode = dynamic_cast<RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>*>( 01702 p.access_private_node().node_ptr()); 01703 TEUCHOS_TEST_FOR_EXCEPTION( 01704 dnode==NULL, NullReferenceError 01705 ,"get_dealloc<" << TypeNameTraits<Dealloc_T>::name() 01706 << "," << TypeNameTraits<T>::name() << ">(p): " 01707 << "Error, requested type \'" << TypeNameTraits<requested_type>::name() 01708 << "\' does not match actual type of the node \'" 01709 << typeName(*p.access_private_node().node_ptr()) << "!" 01710 ); 01711 return dnode->get_nonconst_dealloc(); 01712 } 01713 01714 01715 template<class Dealloc_T, class T> 01716 inline 01717 const Dealloc_T* 01718 Teuchos::get_optional_dealloc( const ArrayRCP<T>& p ) 01719 { 01720 return get_optional_dealloc<Dealloc_T>(p); 01721 } 01722 01723 01724 template<class Dealloc_T, class T> 01725 inline 01726 Dealloc_T* 01727 Teuchos::get_optional_nonconst_dealloc( const Teuchos::ArrayRCP<T>& p ) 01728 { 01729 p.assert_not_null(); 01730 typedef RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T> 01731 RCPNT; 01732 RCPNT *dnode = dynamic_cast<RCPNT*>(p.access_private_node().node_ptr()); 01733 if (dnode) 01734 return &dnode->get_nonconst_dealloc(); 01735 return 0; 01736 } 01737 01738 01739 template<class TOrig, class Embedded, class T> 01740 const Embedded& Teuchos::getEmbeddedObj( const ArrayRCP<T>& p ) 01741 { 01742 typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocArrayDelete<TOrig> > Dealloc_t; 01743 return get_dealloc<Dealloc_t>(p).getObj(); 01744 } 01745 01746 01747 template<class TOrig, class Embedded, class T> 01748 Embedded& Teuchos::getNonconstEmbeddedObj( const ArrayRCP<T>& p ) 01749 { 01750 typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocArrayDelete<TOrig> > Dealloc_t; 01751 return get_nonconst_dealloc<Dealloc_t>(p).getNonconstObj(); 01752 } 01753 01754 01755 template<class T> 01756 std::ostream& Teuchos::operator<<( std::ostream& out, const ArrayRCP<T>& p ) 01757 { 01758 out 01759 << TypeNameTraits<ArrayRCP<T> >::name() << "{" 01760 << "ptr="<<(const void*)(p.access_private_ptr()) 01761 <<",lowerOffset="<<p.lowerOffset() 01762 <<",upperOffset="<<p.upperOffset() 01763 <<",size="<<p.size() 01764 <<",node="<<p.access_private_node() 01765 <<",strong_count="<<p.strong_count() 01766 <<",weak_count="<<p.weak_count() 01767 <<"}"; 01768 return out; 01769 // NOTES: 01770 // * I can't find any alternative to this C cast (problems with char data) 01771 // * Don't range check the pointer since this code does not dereference it. 01772 // This is needed to allow printing the end() or past end() for debugging. 01773 } 01774 01775 01776 #endif // TEUCHOS_ARRAY_RCP_HPP
1.7.6.1