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