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_map.hpp"
00038
00039
00040 namespace Teuchos {
00041
00042
00043
00044
00045
00046 template<class T>
00047 inline
00048 ArrayRCP<T>::ArrayRCP( ENull )
00049 : ptr_(NULL)
00050 , node_(NULL)
00051 , lowerOffset_(0)
00052 , upperOffset_(-1)
00053 {}
00054
00055
00056 template<class T>
00057 REFCOUNTPTR_INLINE
00058 ArrayRCP<T>::ArrayRCP(const ArrayRCP<T>& r_ptr)
00059 :ptr_(r_ptr.ptr_), node_(r_ptr.node_),
00060 lowerOffset_(r_ptr.lowerOffset_),
00061 upperOffset_(r_ptr.upperOffset_)
00062 {
00063 if(node_) node_->incr_count();
00064 }
00065
00066
00067 template<class T>
00068 REFCOUNTPTR_INLINE
00069 ArrayRCP<T>::~ArrayRCP()
00070 {
00071 if(node_ && node_->deincr_count() == 0 ) {
00072 #ifdef TEUCHOS_DEBUG
00073 local_printActiveRCPNodes.foo();
00074 remove_RCPNode(node_);
00075 #endif
00076 delete node_;
00077 }
00078 }
00079
00080
00081 template<class T>
00082 REFCOUNTPTR_INLINE
00083 ArrayRCP<T>& ArrayRCP<T>::operator=(const ArrayRCP<T>& r_ptr)
00084 {
00085 if( this == &r_ptr )
00086 return *this;
00087 if( node_ && !node_->deincr_count() ) {
00088 #ifdef TEUCHOS_DEBUG
00089 remove_RCPNode(node_);
00090 #endif
00091 delete node_;
00092 }
00093 ptr_ = r_ptr.ptr_;
00094 node_ = r_ptr.node_;
00095 lowerOffset_ = r_ptr.lowerOffset_;
00096 upperOffset_ = r_ptr.upperOffset_;
00097 if(node_) node_->incr_count();
00098 return *this;
00099 }
00100
00101
00102
00103
00104
00105 template<class T>
00106 inline
00107 T* ArrayRCP<T>::operator->() const
00108 {
00109 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00110 assert_in_range(0,1);
00111 #endif
00112 return ptr_;
00113 }
00114
00115
00116 template<class T>
00117 inline
00118 T& ArrayRCP<T>::operator*() const
00119 {
00120 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00121 assert_in_range(0,1);
00122 #endif
00123 return *ptr_;
00124 }
00125
00126
00127 template<class T>
00128 inline
00129 T* ArrayRCP<T>::get() const
00130 {
00131 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00132 if(ptr_) {
00133 assert_in_range(0,1);
00134 }
00135 #endif
00136 return ptr_;
00137 }
00138
00139
00140 template<class T>
00141 inline
00142 T* ArrayRCP<T>::getRawPtr() const
00143 {
00144 return this->get();
00145 }
00146
00147
00148 template<class T>
00149 REFCOUNTPTR_INLINE
00150 T& ArrayRCP<T>::operator[](Ordinal offset) const
00151 {
00152 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00153 assert_in_range(offset,1);
00154 #endif
00155 return ptr_[offset];
00156 }
00157
00158
00159
00160
00161
00162 template<class T>
00163 REFCOUNTPTR_INLINE
00164 ArrayRCP<T>& ArrayRCP<T>::operator++()
00165 {
00166 if(ptr_) {
00167 ++ptr_;
00168 --lowerOffset_;
00169 --upperOffset_;
00170 }
00171 return *this;
00172 }
00173
00174
00175 template<class T>
00176 REFCOUNTPTR_INLINE
00177 ArrayRCP<T> ArrayRCP<T>::operator++(int)
00178 {
00179 ArrayRCP<T> r_ptr = *this;
00180 ++(*this);
00181 return r_ptr;
00182 }
00183
00184
00185 template<class T>
00186 REFCOUNTPTR_INLINE
00187 ArrayRCP<T>& ArrayRCP<T>::operator--()
00188 {
00189 if(ptr_) {
00190 --ptr_;
00191 ++lowerOffset_;
00192 ++upperOffset_;
00193 }
00194 return *this;
00195 }
00196
00197
00198 template<class T>
00199 REFCOUNTPTR_INLINE
00200 ArrayRCP<T> ArrayRCP<T>::operator--(int)
00201 {
00202 ArrayRCP<T> r_ptr = *this;
00203 --(*this);
00204 return r_ptr;
00205 }
00206
00207
00208 template<class T>
00209 REFCOUNTPTR_INLINE
00210 ArrayRCP<T>& ArrayRCP<T>::operator+=(Ordinal offset)
00211 {
00212 if(ptr_) {
00213 ptr_ += offset;
00214 lowerOffset_ -= offset;
00215 upperOffset_ -= offset;
00216 }
00217 return *this;
00218 }
00219
00220
00221 template<class T>
00222 REFCOUNTPTR_INLINE
00223 ArrayRCP<T>& ArrayRCP<T>::operator-=(Ordinal offset)
00224 {
00225 if(ptr_) {
00226 ptr_ -= offset;
00227 lowerOffset_ += offset;
00228 upperOffset_ += offset;
00229 }
00230 return *this;
00231 }
00232
00233
00234 template<class T>
00235 REFCOUNTPTR_INLINE
00236 ArrayRCP<T> ArrayRCP<T>::operator+(Ordinal offset) const
00237 {
00238 ArrayRCP<T> r_ptr = *this;
00239 r_ptr+=(offset);
00240 return r_ptr;
00241 }
00242
00243
00244 template<class T>
00245 REFCOUNTPTR_INLINE
00246 ArrayRCP<T> ArrayRCP<T>::operator-(Ordinal offset) const
00247 {
00248 ArrayRCP<T> r_ptr = *this;
00249 r_ptr-=offset;
00250 return r_ptr;
00251 }
00252
00253
00254
00255
00256
00257 template<class T>
00258 REFCOUNTPTR_INLINE
00259 ArrayRCP<const T> ArrayRCP<T>::getConst() const
00260 {
00261 const T *cptr = ptr_;
00262 return ArrayRCP<const T>(cptr,lowerOffset_,upperOffset_,node_);
00263 }
00264
00265
00266 template<class T>
00267 REFCOUNTPTR_INLINE
00268 ArrayRCP<T>
00269 ArrayRCP<T>::persistingView( Ordinal lowerOffset_in, Ordinal size_in ) const
00270 {
00271 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00272 assert_in_range(lowerOffset_in,size_in);
00273 #endif
00274 ArrayRCP<T> ptr = *this;
00275 ptr.ptr_ = ptr.ptr_ + lowerOffset_in;
00276 ptr.lowerOffset_ = 0;
00277 ptr.upperOffset_ = size_in-1;
00278 return ptr;
00279 }
00280
00281
00282
00283
00284
00285 template<class T>
00286 REFCOUNTPTR_INLINE
00287 int ArrayRCP<T>::count() const {
00288 if(node_)
00289 return node_->count();
00290 return 0;
00291 }
00292
00293
00294 template<class T>
00295 REFCOUNTPTR_INLINE
00296 template <class T2>
00297 bool ArrayRCP<T>::shares_resource(const ArrayRCP<T2>& r_ptr) const
00298 {
00299 return node_ == r_ptr.access_node();
00300
00301
00302
00303 }
00304
00305
00306 template<class T>
00307 REFCOUNTPTR_INLINE
00308 typename ArrayRCP<T>::Ordinal
00309 ArrayRCP<T>::lowerOffset() const
00310 {
00311 return lowerOffset_;
00312 }
00313
00314
00315 template<class T>
00316 REFCOUNTPTR_INLINE
00317 typename ArrayRCP<T>::Ordinal
00318 ArrayRCP<T>::upperOffset() const
00319 {
00320 return upperOffset_;
00321 }
00322
00323
00324 template<class T>
00325 REFCOUNTPTR_INLINE
00326 typename ArrayRCP<T>::Ordinal
00327 ArrayRCP<T>::size() const
00328 {
00329 return upperOffset_-lowerOffset_+1;
00330 }
00331
00332
00333
00334
00335
00336 template<class T>
00337 REFCOUNTPTR_INLINE
00338 typename ArrayRCP<T>::const_iterator ArrayRCP<T>::begin() const
00339 {
00340 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00341 return *this;
00342 #else
00343 return ptr_;
00344 #endif
00345 }
00346
00347
00348 template<class T>
00349 REFCOUNTPTR_INLINE
00350 typename ArrayRCP<T>::const_iterator
00351 ArrayRCP<T>::end() const
00352 {
00353 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00354 return *this + (upperOffset_ + 1);
00355 #else
00356 return ptr_ + (upperOffset_ + 1);
00357 #endif
00358 }
00359
00360
00361
00362
00363
00364 template<class T> inline
00365 ArrayView<T> ArrayRCP<T>::view( Ordinal lowerOffset_in, Ordinal size_in ) const
00366 {
00367 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00368 assert_in_range(lowerOffset_in,size_in);
00369 #endif
00370 return arrayView(ptr_ + lowerOffset_in, size_in );
00371 }
00372
00373
00374 template<class T> inline
00375 ArrayView<T> ArrayRCP<T>::operator()( Ordinal lowerOffset_in, Ordinal size_in ) const
00376 {
00377 return view(lowerOffset_in,size_in);
00378 }
00379
00380
00381 template<class T> inline
00382 ArrayView<T> ArrayRCP<T>::operator()() const
00383 {
00384 if (!size())
00385 return null;
00386 return arrayView(ptr_ + lowerOffset_, size() );
00387 }
00388
00389
00390 template<class T> inline
00391 ArrayRCP<T>::operator ArrayView<T>() const
00392 {
00393 return this->operator()();
00394 }
00395
00396
00397 template<class T> inline
00398 ArrayRCP<T>::operator ArrayRCP<const T>() const
00399 {
00400 return ArrayRCP<const T>(ptr_,lowerOffset_,upperOffset_,node_);
00401 }
00402
00403
00404
00405
00406
00407 template<class T>
00408 REFCOUNTPTR_INLINE
00409 T* ArrayRCP<T>::release()
00410 {
00411 if(node_)
00412 node_->has_ownership(false);
00413 return ptr_;
00414 }
00415
00416
00417 template<class T>
00418 REFCOUNTPTR_INLINE
00419 void ArrayRCP<T>::set_has_ownership()
00420 {
00421 if(node_)
00422 node_->has_ownership(true);
00423 }
00424
00425
00426 template<class T>
00427 REFCOUNTPTR_INLINE
00428 bool ArrayRCP<T>::has_ownership() const
00429 {
00430 if(node_)
00431 return node_->has_ownership();
00432 return false;
00433 }
00434
00435
00436
00437
00438
00439 template<class T>
00440 inline
00441 const ArrayRCP<T>&
00442 ArrayRCP<T>::assert_not_null() const
00443 {
00444 if(!ptr_)
00445 throw_null_ptr_error(typeName(*this));
00446 return *this;
00447 }
00448
00449
00450 template<class T>
00451 inline
00452 const ArrayRCP<T>&
00453 ArrayRCP<T>::assert_in_range( Ordinal lowerOffset_in, Ordinal size_in ) const
00454 {
00455 assert_not_null();
00456 TEST_FOR_EXCEPTION(
00457 !( lowerOffset_ <= lowerOffset_in && lowerOffset_in+size_in-1 <= upperOffset_ ),
00458 Teuchos::RangeError,
00459 typeName(*this)<<"::assert_in_range:"
00460 " Error, [lowerOffset,lowerOffset+size-1] = ["
00461 <<lowerOffset_in<<","<<(lowerOffset_in+size_in-1)<<"] does not lie in the"
00462 " range ["<<lowerOffset_<<","<<upperOffset_<<"]!"
00463 );
00464 return *this;
00465 }
00466
00467
00468
00469
00470
00471 template<class T>
00472 inline
00473 ArrayRCP<T>::ArrayRCP(
00474 T* p, Ordinal lowerOffset_in, Ordinal upperOffset_in, bool has_ownership_in
00475 )
00476 : ptr_(p)
00477 , node_(
00478 p
00479 ? new RCPNodeTmpl<T,DeallocArrayDelete<T> >(
00480 p,DeallocArrayDelete<T>(),has_ownership_in
00481 )
00482 : NULL
00483 )
00484 ,lowerOffset_(lowerOffset_in)
00485 ,upperOffset_(upperOffset_in)
00486 {
00487 #ifdef TEUCHOS_DEBUG
00488 if(node_ && isTracingActiveRCPNodes()) {
00489 std::ostringstream os;
00490 os << "{T=\'"<<TypeNameTraits<T>::name()<<"\',Concrete T=\'"
00491 <<TypeNameTraits<T>::concreteName(*p)<<"\',p="<<p
00492 <<",has_ownership="<<has_ownership_in<<"}";
00493 add_new_RCPNode(node_,os.str());
00494 }
00495 #endif
00496 }
00497
00498
00499 template<class T>
00500 REFCOUNTPTR_INLINE
00501 template<class Dealloc_T>
00502 ArrayRCP<T>::ArrayRCP(
00503 T* p, Ordinal lowerOffset_in, Ordinal upperOffset_in,
00504 Dealloc_T dealloc, bool has_ownership_in
00505 )
00506 : ptr_(p)
00507 , node_( p
00508 ? new RCPNodeTmpl<T,Dealloc_T>(p,dealloc,has_ownership_in)
00509 : NULL )
00510 ,lowerOffset_(lowerOffset_in)
00511 ,upperOffset_(upperOffset_in)
00512 {
00513 #ifdef TEUCHOS_DEBUG
00514 if(node_ && isTracingActiveRCPNodes()) {
00515 std::ostringstream os;
00516 os << "{T=\'"<<TypeNameTraits<T>::name()<<"\',Concrete T=\'"
00517 <<typeName(*p)<<"\',p="<<p<<",has_ownership="<<has_ownership_in<<"}";
00518 add_new_RCPNode(node_,os.str());
00519 }
00520 #endif
00521 }
00522
00523
00524 template<class T>
00525 inline
00526 ArrayRCP<T>::ArrayRCP(
00527 T* p, Ordinal lowerOffset_in, Ordinal upperOffset_in, RCPNode* node
00528 )
00529 :ptr_(p),
00530 node_(node),
00531 lowerOffset_(lowerOffset_in),
00532 upperOffset_(upperOffset_in)
00533 {
00534 if(node_)
00535 node_->incr_count();
00536 }
00537
00538
00539 template<class T>
00540 inline
00541 T*& ArrayRCP<T>::access_ptr()
00542 {
00543 return ptr_;
00544 }
00545
00546
00547 template<class T>
00548 inline
00549 T* ArrayRCP<T>::access_ptr() const
00550 {
00551 return ptr_;
00552 }
00553
00554
00555 template<class T>
00556 inline
00557 RCPNode*& ArrayRCP<T>::access_node()
00558 {
00559 return node_;
00560 }
00561
00562
00563 template<class T>
00564 inline
00565 RCPNode* ArrayRCP<T>::access_node() const
00566 {
00567 return node_;
00568 }
00569
00570
00571 }
00572
00573
00574
00575
00576
00577
00578 namespace Teuchos {
00579 namespace Utilities {
00580 template<class T1, class T2>
00581 inline void assert_shares_resource(
00582 const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2
00583 )
00584 {
00585 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00586 TEST_FOR_EXCEPTION(
00587 !p1.shares_resource(p2), IncompatibleIteratorsError,
00588 "Error, these iterators are *not* pointing to the same valid memory!"
00589 );
00590 #endif
00591 }
00592 }
00593 }
00594
00595
00596 template<class T>
00597 inline
00598 Teuchos::ArrayRCP<T>
00599 Teuchos::arcp(
00600 T* p, typename ArrayRCP<T>::Ordinal lowerOffset
00601 ,typename ArrayRCP<T>::Ordinal size_in
00602 ,bool owns_mem
00603 )
00604 {
00605 return ArrayRCP<T>(p,lowerOffset,lowerOffset+size_in-1,owns_mem);
00606 }
00607
00608
00609 template<class T, class Dealloc_T>
00610 inline
00611 Teuchos::ArrayRCP<T>
00612 Teuchos::arcp(
00613 T* p, typename ArrayRCP<T>::Ordinal lowerOffset
00614 ,typename ArrayRCP<T>::Ordinal size_in
00615 ,Dealloc_T dealloc, bool owns_mem
00616 )
00617 {
00618 return ArrayRCP<T>(p,lowerOffset,lowerOffset+size_in-1,dealloc,owns_mem);
00619 }
00620
00621
00622 template<class T>
00623 inline
00624 Teuchos::ArrayRCP<T>
00625 Teuchos::arcp( typename ArrayRCP<T>::Ordinal size )
00626 {
00627 return ArrayRCP<T>(new T[size],0,size-1,true);
00628 }
00629
00630
00631 template<class T>
00632 inline
00633 Teuchos::ArrayRCP<T>
00634 Teuchos::arcpClone( const ArrayView<const T> &v )
00635 {
00636 const ArrayRCP<T> new_arcp = arcp<T>(v.size());
00637 std::copy( v.begin(), v.end(), new_arcp.begin() );
00638 return new_arcp;
00639 }
00640
00641
00642 template<class T, class Embedded>
00643 Teuchos::ArrayRCP<T>
00644 Teuchos::arcpWithEmbeddedObjPreDestroy(
00645 T* p,
00646 typename ArrayRCP<T>::Ordinal lowerOffset,
00647 typename ArrayRCP<T>::Ordinal size,
00648 const Embedded &embedded,
00649 bool owns_mem
00650 )
00651 {
00652 return arcp(
00653 p, lowerOffset, size,
00654 embeddedObjDeallocDelete<T>(embedded,PRE_DESTROY),
00655 owns_mem
00656 );
00657 }
00658
00659
00660 template<class T, class Embedded>
00661 Teuchos::ArrayRCP<T>
00662 Teuchos::arcpWithEmbeddedObjPostDestroy(
00663 T* p,
00664 typename ArrayRCP<T>::Ordinal lowerOffset,
00665 typename ArrayRCP<T>::Ordinal size,
00666 const Embedded &embedded,
00667 bool owns_mem
00668 )
00669 {
00670 return arcp(
00671 p, lowerOffset, size,
00672 embeddedObjDeallocDelete<T>(embedded,POST_DESTROY),
00673 owns_mem
00674 );
00675 }
00676
00677
00678 template<class T, class Embedded>
00679 Teuchos::ArrayRCP<T>
00680 Teuchos::arcpWithEmbeddedObj(
00681 T* p,
00682 typename ArrayRCP<T>::Ordinal lowerOffset,
00683 typename ArrayRCP<T>::Ordinal size,
00684 const Embedded &embedded,
00685 bool owns_mem
00686 )
00687 {
00688 return arcpWithEmbeddedObjPostDestroy<T,Embedded>(
00689 p, lowerOffset, size, embedded, owns_mem );
00690 }
00691
00692
00693 template<class T>
00694 REFCOUNTPTR_INLINE
00695 Teuchos::ArrayRCP<T>
00696 Teuchos::arcp( const RCP<std::vector<T> > &v )
00697 {
00698 if ( is_null(v) || !v->size() )
00699 return null;
00700 return arcpWithEmbeddedObjPostDestroy<T,RCP<std::vector<T> > >(
00701 &(*v)[0], 0, v->size(),
00702 v, false
00703 );
00704 }
00705
00706
00707 template<class T>
00708 REFCOUNTPTR_INLINE
00709 Teuchos::ArrayRCP<const T>
00710 Teuchos::arcp( const RCP<const std::vector<T> > &v )
00711 {
00712 if ( is_null(v) || !v->size() )
00713 return null;
00714 return arcpWithEmbeddedObjPostDestroy<const T,RCP<const std::vector<T> > >(
00715 &(*v)[0], 0, v->size(),
00716 v, false
00717 );
00718 }
00719
00720
00721 template<class T>
00722 REFCOUNTPTR_INLINE
00723 Teuchos::RCP<std::vector<T> >
00724 Teuchos::get_std_vector( const ArrayRCP<T> &ptr )
00725 {
00726 return getEmbeddedObj<T,RCP<std::vector<T> > >(ptr);
00727 }
00728
00729
00730 template<class T>
00731 REFCOUNTPTR_INLINE
00732 Teuchos::RCP<const std::vector<T> >
00733 Teuchos::get_std_vector( const ArrayRCP<const T> &ptr )
00734 {
00735 return getEmbeddedObj<const T,RCP<const std::vector<T> > >(ptr);
00736 }
00737
00738
00739 template<class T>
00740 REFCOUNTPTR_INLINE
00741 bool Teuchos::is_null( const ArrayRCP<T> &p )
00742 {
00743 return p.access_ptr() == NULL;
00744 }
00745
00746
00747 template<class T>
00748 REFCOUNTPTR_INLINE
00749 bool Teuchos::operator==( const ArrayRCP<T> &p, ENull )
00750 {
00751 return p.access_ptr() == NULL;
00752 }
00753
00754
00755 template<class T>
00756 REFCOUNTPTR_INLINE
00757 bool Teuchos::operator!=( const ArrayRCP<T> &p, ENull )
00758 {
00759 return p.access_ptr() != NULL;
00760 }
00761
00762
00763 template<class T1, class T2>
00764 REFCOUNTPTR_INLINE
00765 bool Teuchos::operator==( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 )
00766 {
00767 return p1.access_ptr() == p2.access_ptr();
00768 }
00769
00770
00771 template<class T1, class T2>
00772 REFCOUNTPTR_INLINE
00773 bool Teuchos::operator!=( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 )
00774 {
00775 return p1.access_ptr() != p2.access_ptr();
00776 }
00777
00778
00779 template<class T1, class T2>
00780 REFCOUNTPTR_INLINE
00781 bool Teuchos::operator<( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 )
00782 {
00783 return p1.access_ptr() < p2.access_ptr();
00784 }
00785
00786
00787 template<class T1, class T2>
00788 REFCOUNTPTR_INLINE
00789 bool Teuchos::operator<=( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 )
00790 {
00791 Utilities::assert_shares_resource(p1,p2);
00792 return p1.access_ptr() <= p2.access_ptr();
00793 }
00794
00795
00796 template<class T1, class T2>
00797 REFCOUNTPTR_INLINE
00798 bool Teuchos::operator>( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 )
00799 {
00800 Utilities::assert_shares_resource(p1,p2);
00801 return p1.access_ptr() > p2.access_ptr();
00802 }
00803
00804
00805 template<class T1, class T2>
00806 REFCOUNTPTR_INLINE
00807 bool Teuchos::operator>=( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 )
00808 {
00809 Utilities::assert_shares_resource(p1,p2);
00810 return p1.access_ptr() >= p2.access_ptr();
00811 }
00812
00813
00814 template<class T>
00815 typename Teuchos::ArrayRCP<T>::difference_type
00816 Teuchos::operator-( const ArrayRCP<T> &p1, const ArrayRCP<T> &p2 )
00817 {
00818 Utilities::assert_shares_resource(p1,p2);
00819 return p1.access_ptr() - p2.access_ptr();
00820 }
00821
00822
00823 template<class T2, class T1>
00824 REFCOUNTPTR_INLINE
00825 Teuchos::ArrayRCP<T2>
00826 Teuchos::arcp_reinterpret_cast(const ArrayRCP<T1>& p1)
00827 {
00828 typedef typename ArrayRCP<T1>::Ordinal Ordinal;
00829 const int sizeOfT2ToT1 = sizeof(T2)/sizeof(T1);
00830 Ordinal lowerOffset2 = p1.lowerOffset() / sizeOfT2ToT1;
00831 Ordinal upperOffset2 = (p1.upperOffset()+1) / sizeOfT2ToT1 -1;
00832 T2 *ptr2 = reinterpret_cast<T2*>(p1.get());
00833 return ArrayRCP<T2>(
00834 ptr2, lowerOffset2, upperOffset2,
00835 p1.access_node()
00836 );
00837
00838 }
00839
00840
00841 template<class T2, class T1>
00842 REFCOUNTPTR_INLINE
00843 Teuchos::ArrayRCP<T2>
00844 Teuchos::arcp_const_cast(const ArrayRCP<T1>& p1)
00845 {
00846 typedef typename ArrayRCP<T1>::Ordinal Ordinal;
00847 T2 *ptr2 = const_cast<T2*>(p1.get());
00848 return ArrayRCP<T2>(
00849 ptr2, p1.lowerOffset(), p1.upperOffset(),
00850 p1.access_node()
00851 );
00852
00853 }
00854
00855
00856 template<class T2, class T1>
00857 REFCOUNTPTR_INLINE
00858 Teuchos::ArrayRCP<T2>
00859 Teuchos::arcp_implicit_cast(const ArrayRCP<T1>& p1)
00860 {
00861 typedef typename ArrayRCP<T1>::Ordinal Ordinal;
00862 T2 * raw_ptr2 = p1.get();
00863 return ArrayRCP<T2>(
00864 raw_ptr2,p1.lowerOffset(),p1.upperOffset()
00865 ,p1.access_node()
00866 );
00867
00868 }
00869
00870
00871 template<class T1, class T2>
00872 REFCOUNTPTR_INLINE
00873 void Teuchos::set_extra_data(
00874 const T1 &extra_data, const std::string& name, Teuchos::ArrayRCP<T2> *p
00875 ,EPrePostDestruction destroy_when, bool force_unique
00876 )
00877 {
00878 p->assert_not_null();
00879 p->access_node()->set_extra_data( any(extra_data), name, destroy_when, force_unique );
00880 }
00881
00882
00883 template<class T1, class T2>
00884 REFCOUNTPTR_INLINE
00885 T1& Teuchos::get_extra_data( ArrayRCP<T2>& p, const std::string& name )
00886 {
00887 p.assert_not_null();
00888 return any_cast<T1>(p.access_node()->get_extra_data(TypeNameTraits<T1>::name(),name));
00889 }
00890
00891
00892 template<class T1, class T2>
00893 REFCOUNTPTR_INLINE
00894 const T1& Teuchos::get_extra_data( const ArrayRCP<T2>& p, const std::string& name )
00895 {
00896 p.assert_not_null();
00897 return any_cast<T1>(p.access_node()->get_extra_data(TypeNameTraits<T1>::name(),name));
00898 }
00899
00900
00901 template<class T1, class T2>
00902 REFCOUNTPTR_INLINE
00903 T1* Teuchos::get_optional_extra_data( ArrayRCP<T2>& p, const std::string& name )
00904 {
00905 p.assert_not_null();
00906 any *extra_data = p.access_node()->get_optional_extra_data(TypeNameTraits<T1>::name(),name);
00907 if( extra_data ) return &any_cast<T1>(*extra_data);
00908 return NULL;
00909 }
00910
00911
00912 template<class T1, class T2>
00913 REFCOUNTPTR_INLINE
00914 const T1* Teuchos::get_optional_extra_data( const ArrayRCP<T2>& p, const std::string& name )
00915 {
00916 p.assert_not_null();
00917 any *extra_data = p.access_node()->get_optional_extra_data(TypeNameTraits<T1>::name(),name);
00918 if( extra_data ) return &any_cast<T1>(*extra_data);
00919 return NULL;
00920 }
00921
00922
00923 template<class Dealloc_T, class T>
00924 REFCOUNTPTR_INLINE
00925 const Dealloc_T&
00926 Teuchos::get_dealloc( const ArrayRCP<T>& p )
00927 {
00928 return get_nonconst_dealloc<Dealloc_T>(p);
00929 }
00930
00931
00932 template<class Dealloc_T, class T>
00933 inline
00934 Dealloc_T&
00935 Teuchos::get_nonconst_dealloc( const Teuchos::ArrayRCP<T>& p )
00936 {
00937 typedef RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T> requested_type;
00938 p.assert_not_null();
00939 RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>
00940 *dnode = dynamic_cast<RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>*>(
00941 p.access_node());
00942 TEST_FOR_EXCEPTION(
00943 dnode==NULL, NullReferenceError
00944 ,"get_dealloc<" << TypeNameTraits<Dealloc_T>::name()
00945 << "," << TypeNameTraits<T>::name() << ">(p): "
00946 << "Error, requested type \'" << TypeNameTraits<requested_type>::name()
00947 << "\' does not match actual type of the node \'" << typeName(*p.access_node()) << "!"
00948 );
00949 return dnode->get_nonconst_dealloc();
00950 }
00951
00952
00953 template<class Dealloc_T, class T>
00954 REFCOUNTPTR_INLINE
00955 const Dealloc_T*
00956 Teuchos::get_optional_dealloc( const ArrayRCP<T>& p )
00957 {
00958 return get_optional_dealloc<Dealloc_T>(p);
00959 }
00960
00961
00962 template<class Dealloc_T, class T>
00963 inline
00964 Dealloc_T*
00965 Teuchos::get_optional_nonconst_dealloc( const Teuchos::ArrayRCP<T>& p )
00966 {
00967 p.assert_not_null();
00968 typedef RCPNodeTmpl<typename Dealloc_T::ptr_t,Dealloc_T>
00969 RCPNT;
00970 RCPNT *dnode = dynamic_cast<RCPNT*>(p.access_node());
00971 if(dnode)
00972 return &dnode->get_nonconst_dealloc();
00973 return 0;
00974 }
00975
00976
00977 template<class TOrig, class Embedded, class T>
00978 const Embedded& Teuchos::getEmbeddedObj( const ArrayRCP<T>& p )
00979 {
00980 typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
00981 return get_dealloc<Dealloc_t>(p).getObj();
00982 }
00983
00984
00985 template<class TOrig, class Embedded, class T>
00986 Embedded& Teuchos::getNonconstEmbeddedObj( const ArrayRCP<T>& p )
00987 {
00988 typedef EmbeddedObjDealloc<TOrig,Embedded,DeallocDelete<TOrig> > Dealloc_t;
00989 return get_nonconst_dealloc<Dealloc_t>(p).getNonconstObj();
00990 }
00991
00992
00993 template<class T>
00994 std::ostream& Teuchos::operator<<( std::ostream& out, const ArrayRCP<T>& p )
00995 {
00996 out
00997 << TypeNameTraits<ArrayRCP<T> >::name() << "{"
00998 << "ptr="<<(const void*)(p.get())
00999 <<",lowerOffset="<<p.lowerOffset()
01000 <<",upperOffset="<<p.upperOffset()
01001 <<",size="<<p.size()
01002 <<",node="<<p.access_node()
01003 <<",count="<<p.count()
01004 <<"}";
01005 return out;
01006 }
01007
01008
01009 #endif // TEUCHOS_ARRAY_RCP_HPP