Teuchos_ArrayRCP.hpp

00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 //                    Teuchos: Common Tools Package
00005 //                 Copyright (2004) Sandia Corporation
00006 // 
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 // 
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //  
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //  
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00025 // 
00026 // ***********************************************************************
00027 // @HEADER
00028 
00029 #ifndef TEUCHOS_ARRAY_RCP_HPP
00030 #define TEUCHOS_ARRAY_RCP_HPP
00031 
00032 
00033 #include "Teuchos_ArrayRCPDecl.hpp"
00034 #include "Teuchos_ArrayView.hpp"
00035 #include "Teuchos_TestForException.hpp"
00036 #include "Teuchos_dyn_cast.hpp"
00037 #include "Teuchos_map.hpp"
00038 
00039 
00040 namespace Teuchos {
00041 
00042 
00043 // Constructors/Initializers
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(); // Make sure this object is used!
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; // Assignment to self
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 // Object/Pointer Access Functions
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 // Pointer Arithmetic Functions
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 // ArrayView views
00255 
00256 
00257 template<class T>
00258 REFCOUNTPTR_INLINE
00259 ArrayRCP<const T> ArrayRCP<T>::getConst() const
00260 {
00261   const T *cptr = ptr_; // Will not compile if not legal!
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 // General query functions
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   // Note: above, r_ptr is *not* the same class type as *this so we can not
00301   // access its node_ member directly!  This is an interesting detail to the
00302   // C++ protected/private protection mechanism!
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 // Standard Container-Like Functions
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 // Views 
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 // Ownership
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 // Assertion Functions.
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 // very bad public functions
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 }  // end namespace Teuchos
00572 
00573 
00574 // ///////////////////////////////////////////
00575 // Non-member functions for ArrayRCP
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 } // namespace Utilities
00593 } // namespace Teuchos
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   // Note: Above is just fine even if p1.get()==NULL!
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   // Note: Above is just fine even if p1.get()==NULL!
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   // Note: Above is just fine even if p1.get()==NULL!
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()) // I can't find any alternative to this C cast :-(
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

Generated on Wed May 12 21:40:31 2010 for Teuchos - Trilinos Tools Package by  doxygen 1.4.7