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 #include "Teuchos_ArrayRCPDecl.hpp"
00033 #include "Teuchos_TestForException.hpp"
00034 #include "Teuchos_dyn_cast.hpp"
00035 #include "Teuchos_map.hpp"
00036 
00037 namespace Teuchos {
00038 
00039 // Constructors/Initializers
00040 
00041 template<class T>
00042 inline
00043 ArrayRCP<T>::ArrayRCP( ENull )
00044   : ptr_(NULL)
00045   , node_(NULL)
00046   , lowerOffset_(0)
00047   , upperOffset_(-1)
00048 {}
00049 
00050 template<class T>
00051 REFCOUNTPTR_INLINE
00052 ArrayRCP<T>::ArrayRCP(const ArrayRCP<T>& r_ptr)
00053   : ptr_(r_ptr.ptr_), node_(r_ptr.node_)
00054   , lowerOffset_(r_ptr.lowerOffset_)
00055   , upperOffset_(r_ptr.upperOffset_)
00056 {
00057   if(node_) node_->incr_count();
00058 }
00059 
00060 template<class T>
00061 REFCOUNTPTR_INLINE
00062 ArrayRCP<T>::~ArrayRCP()
00063 {
00064   if(node_ && node_->deincr_count() == 0 ) {
00065 #ifdef TEUCHOS_SHOW_ACTIVE_REFCOUNTPTR_NODES
00066     printActiveRCPNodes.foo(); // Make sure this object is used!
00067     remove_RCP_node(node_);
00068 #endif
00069     delete node_;
00070   }
00071 }
00072 
00073 template<class T>
00074 REFCOUNTPTR_INLINE
00075 ArrayRCP<T>& ArrayRCP<T>::operator=(const ArrayRCP<T>& r_ptr)
00076 {
00077   if( this == &r_ptr )
00078     return *this; // Assignment to self
00079   if( node_ && !node_->deincr_count() ) {
00080 #ifdef TEUCHOS_SHOW_ACTIVE_REFCOUNTPTR_NODES
00081     remove_RCP_node(node_);
00082 #endif
00083     delete node_;
00084   }
00085   ptr_   = r_ptr.ptr_;
00086   node_  = r_ptr.node_;
00087   lowerOffset_ = r_ptr.lowerOffset_;
00088   upperOffset_ = r_ptr.upperOffset_;
00089   if(node_) node_->incr_count();
00090   return *this;
00091 }
00092 
00093 // Object/Pointer Access Functions
00094 
00095 template<class T>
00096 inline
00097 T* ArrayRCP<T>::operator->() const
00098 {
00099 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00100   assert_in_range(0,1);
00101 #endif
00102   return ptr_;
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 template<class T>
00116 inline
00117 T* ArrayRCP<T>::get() const
00118 {
00119 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00120   if(ptr_) {
00121     assert_in_range(0,1);
00122   }
00123 #endif
00124   return ptr_;
00125 }
00126 
00127 template<class T>
00128 REFCOUNTPTR_INLINE
00129 T& ArrayRCP<T>::operator[](Ordinal offset) const
00130 {
00131 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00132   assert_in_range(offset,1);
00133 #endif
00134   return ptr_[offset];
00135 }
00136 
00137 // Pointer Arithmetic Functions
00138 
00139 template<class T>
00140 REFCOUNTPTR_INLINE
00141 ArrayRCP<T>& ArrayRCP<T>::operator++()
00142 {
00143   if(ptr_) {
00144     ++ptr_;
00145     --lowerOffset_;
00146     --upperOffset_;
00147   }
00148   return *this;
00149 }
00150 
00151 template<class T>
00152 REFCOUNTPTR_INLINE
00153 ArrayRCP<T> ArrayRCP<T>::operator++(int)
00154 {
00155   ArrayRCP<T> r_ptr = *this;
00156   ++(*this);
00157   return r_ptr;
00158 }
00159 
00160 template<class T>
00161 REFCOUNTPTR_INLINE
00162 ArrayRCP<T>& ArrayRCP<T>::operator--()
00163 {
00164   if(ptr_) {
00165     --ptr_;
00166     ++lowerOffset_;
00167     ++upperOffset_;
00168   }
00169   return *this;
00170 }
00171 
00172 template<class T>
00173 REFCOUNTPTR_INLINE
00174 ArrayRCP<T> ArrayRCP<T>::operator--(int)
00175 {
00176   ArrayRCP<T> r_ptr = *this;
00177   --(*this);
00178   return r_ptr;
00179 }
00180 
00181 template<class T>
00182 REFCOUNTPTR_INLINE
00183 ArrayRCP<T>& ArrayRCP<T>::operator+=(Ordinal offset)
00184 {
00185   if(ptr_) {
00186     ptr_ += offset;
00187     lowerOffset_ -= offset;
00188     upperOffset_ -= offset;
00189   }
00190   return *this;
00191 }
00192 
00193 template<class T>
00194 REFCOUNTPTR_INLINE
00195 ArrayRCP<T>& ArrayRCP<T>::operator-=(Ordinal offset)
00196 {
00197   if(ptr_) {
00198     ptr_ -= offset;
00199     lowerOffset_ += offset;
00200     upperOffset_ += offset;
00201   }
00202   return *this;
00203 }
00204 
00205 template<class T>
00206 REFCOUNTPTR_INLINE
00207 ArrayRCP<T> ArrayRCP<T>::operator+(Ordinal offset) const
00208 {
00209   ArrayRCP<T> r_ptr = *this;
00210   r_ptr+=(offset);
00211   return r_ptr;
00212 }
00213 
00214 template<class T>
00215 REFCOUNTPTR_INLINE
00216 ArrayRCP<T> ArrayRCP<T>::operator-(Ordinal offset) const
00217 {
00218   ArrayRCP<T> r_ptr = *this;
00219   r_ptr-=offset;
00220   return r_ptr;
00221 }
00222 
00223 // Views
00224 
00225 template<class T>
00226 REFCOUNTPTR_INLINE
00227 ArrayRCP<const T> ArrayRCP<T>::getConst() const
00228 {
00229   const T *cptr = ptr_; // Will not compile if not legal!
00230   return ArrayRCP<const T>(cptr,lowerOffset_,upperOffset_,node_);
00231 }
00232 
00233 template<class T>
00234 REFCOUNTPTR_INLINE
00235 ArrayRCP<T>
00236 ArrayRCP<T>::subview( Ordinal lowerOffset, Ordinal size ) const
00237 {
00238 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00239   assert_in_range(lowerOffset,size);
00240 #endif
00241   ArrayRCP<T> ptr = *this;
00242   ptr.ptr_ = ptr.ptr_ + lowerOffset;
00243   ptr.lowerOffset_ = 0;
00244   ptr.upperOffset_ = size-1;
00245   return ptr;
00246 }
00247 
00248 // General query functions
00249 
00250 template<class T>
00251 REFCOUNTPTR_INLINE
00252 int ArrayRCP<T>::count() const {
00253   if(node_)
00254     return node_->count();
00255   return 0;
00256 }
00257 
00258 template<class T>
00259 REFCOUNTPTR_INLINE
00260 template <class T2>
00261 bool ArrayRCP<T>::shares_resource(const ArrayRCP<T2>& r_ptr) const
00262 {
00263   return node_ == r_ptr.access_node();
00264   // Note: above, r_ptr is *not* the same class type as *this so we can not
00265   // access its node_ member directly!  This is an interesting detail to the
00266   // C++ protected/private protection mechanism!
00267 }
00268 
00269 template<class T>
00270 REFCOUNTPTR_INLINE
00271 typename ArrayRCP<T>::Ordinal
00272 ArrayRCP<T>::lowerOffset() const
00273 {
00274   return lowerOffset_;
00275 }
00276 
00277 template<class T>
00278 REFCOUNTPTR_INLINE
00279 typename ArrayRCP<T>::Ordinal
00280 ArrayRCP<T>::upperOffset() const
00281 {
00282   return upperOffset_;
00283 }
00284 
00285 template<class T>
00286 REFCOUNTPTR_INLINE
00287 typename ArrayRCP<T>::Ordinal
00288 ArrayRCP<T>::size() const
00289 {
00290   return upperOffset_-lowerOffset_+1;
00291 }
00292 
00293 // Standard Container-Like Functions
00294 
00295 template<class T>
00296 REFCOUNTPTR_INLINE
00297 typename ArrayRCP<T>::const_iterator ArrayRCP<T>::begin() const
00298 {
00299 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00300   return *this;
00301 #else
00302   return ptr_;
00303 #endif
00304 }
00305 
00306 template<class T>
00307 REFCOUNTPTR_INLINE
00308 typename ArrayRCP<T>::const_iterator
00309 ArrayRCP<T>::end() const
00310 {
00311 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
00312   return *this + (upperOffset_ + 1);
00313 #else
00314   return ptr_ + (upperOffset_ + 1);
00315 #endif
00316 }
00317 
00318 // Ownership
00319 
00320 template<class T>
00321 REFCOUNTPTR_INLINE
00322 T* ArrayRCP<T>::release()
00323 {
00324   if(node_)
00325     node_->has_ownership(false);
00326   return ptr_;
00327 }
00328 
00329 template<class T>
00330 REFCOUNTPTR_INLINE
00331 void ArrayRCP<T>::set_has_ownership()
00332 {
00333   if(node_)
00334     node_->has_ownership(true);
00335 }
00336 
00337 template<class T>
00338 REFCOUNTPTR_INLINE
00339 bool ArrayRCP<T>::has_ownership() const
00340 {
00341   if(node_)
00342     return node_->has_ownership();
00343   return false;
00344 }
00345 
00346 // Assertion Functions.
00347 
00348 template<class T>
00349 inline
00350 const ArrayRCP<T>&
00351 ArrayRCP<T>::assert_not_null() const
00352 {
00353   if(!ptr_) PrivateUtilityPack::throw_null(TypeNameTraits<T>::name());
00354   return *this;
00355 }
00356 
00357 template<class T>
00358 inline
00359 const ArrayRCP<T>&
00360 ArrayRCP<T>::assert_in_range( Ordinal lowerOffset, Ordinal size ) const
00361 {
00362   assert_not_null();
00363   TEST_FOR_EXCEPTION(
00364     !( lowerOffset_ <= lowerOffset && lowerOffset+size-1 <= upperOffset_ ), std::logic_error
00365     ,"Teuchos::ArrayRCP<"<<TypeNameTraits<T>::name()<<">::assert_in_range:"
00366     " Error, [lowerOffset,lowerOffset+size-1] = ["<<lowerOffset<<","<<(lowerOffset+size-1)<<"] does not lie in the"
00367     " range ["<<lowerOffset_<<","<<upperOffset_<<"]!"
00368     );
00369   return *this;
00370 }
00371 
00372 // very bad public functions
00373 
00374 template<class T>
00375 inline
00376 ArrayRCP<T>::ArrayRCP(
00377   T* p, Ordinal lowerOffset, Ordinal upperOffset, bool has_ownership
00378   )
00379   : ptr_(p)
00380   , node_(
00381     p
00382     ? new PrivateUtilityPack::RCP_node_tmpl<T,DeallocArrayDelete<T> >(
00383       p,DeallocArrayDelete<T>(),has_ownership
00384       )
00385     : NULL
00386     )
00387   ,lowerOffset_(lowerOffset)
00388   ,upperOffset_(upperOffset)
00389 {
00390 #ifdef TEUCHOS_SHOW_ACTIVE_REFCOUNTPTR_NODES
00391   if(node_) {
00392     std::ostringstream os;
00393     os << "{T=\'"<<TypeNameTraits<T>::name()<<"\',Concrete T=\'"<<typeName(*p)<<"\',p="<<p<<",has_ownership="<<has_ownership<<"}";
00394     add_new_RCP_node(node_,os.str());
00395   }
00396 #endif
00397 }
00398 
00399 template<class T>
00400 REFCOUNTPTR_INLINE
00401 template<class Dealloc_T>
00402 ArrayRCP<T>::ArrayRCP(
00403   T* p, Ordinal lowerOffset, Ordinal upperOffset, Dealloc_T dealloc, bool has_ownership
00404   )
00405   : ptr_(p)
00406   , node_( p ? new PrivateUtilityPack::RCP_node_tmpl<T,Dealloc_T>(p,dealloc,has_ownership) : NULL )
00407   ,lowerOffset_(lowerOffset)
00408   ,upperOffset_(upperOffset)
00409 {
00410 #ifdef TEUCHOS_SHOW_ACTIVE_REFCOUNTPTR_NODES
00411   if(node_) {
00412     std::ostringstream os;
00413     os << "{T=\'"<<TypeNameTraits<T>::name()<<"\',Concrete T=\'"<<typeName(*p)<<"\',p="<<p<<",has_ownership="<<has_ownership<<"}";
00414     add_new_ArrayRCP_node(node_,os.str());
00415   }
00416 #endif
00417 }
00418 
00419 template<class T>
00420 inline
00421 ArrayRCP<T>::ArrayRCP(
00422   T* p, Ordinal lowerOffset, Ordinal upperOffset, node_t* node
00423   )
00424   : ptr_(p)
00425   , node_(node)
00426   ,lowerOffset_(lowerOffset)
00427   ,upperOffset_(upperOffset)
00428 {
00429   if(node_) node_->incr_count();
00430 }
00431 
00432 template<class T>
00433 inline
00434 T*& ArrayRCP<T>::access_ptr()
00435 {  return ptr_; }
00436 
00437 template<class T>
00438 inline
00439 T* ArrayRCP<T>::access_ptr() const
00440 {  return ptr_; }
00441 
00442 template<class T>
00443 inline
00444 typename ArrayRCP<T>::node_t*& ArrayRCP<T>::access_node()
00445 {  return node_; }
00446 
00447 template<class T>
00448 inline
00449 typename ArrayRCP<T>::node_t* ArrayRCP<T>::access_node() const
00450 {  return node_; }
00451 
00452 }  // end namespace Teuchos
00453 
00454 // ///////////////////////////////////////////
00455 // Non-member functions for ArrayRCP
00456 
00457 namespace Teuchos {
00458 namespace Utilities {
00459 template<class T1, class T2>
00460 inline void assert_shares_resource(
00461   const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2
00462   )
00463 {
00464 #ifdef TEUCHOS_DEBUG
00465   TEST_FOR_EXCEPT(!p1.shares_resource(p2));
00466 #endif
00467 }
00468 } // namespace Utilities
00469 } // namespace Teuchos
00470 
00471 template<class T>
00472 inline
00473 Teuchos::ArrayRCP<T>
00474 Teuchos::arcp(
00475 T* p, typename ArrayRCP<T>::Ordinal lowerOffset
00476   ,typename ArrayRCP<T>::Ordinal size
00477   ,bool owns_mem
00478   )
00479 {
00480   return ArrayRCP<T>(p,lowerOffset,lowerOffset+size-1,owns_mem);
00481 }
00482 
00483 template<class T, class Dealloc_T>
00484 inline
00485 Teuchos::ArrayRCP<T>
00486 Teuchos::arcp(
00487 T* p, typename ArrayRCP<T>::Ordinal lowerOffset
00488   ,typename ArrayRCP<T>::Ordinal size
00489   ,Dealloc_T dealloc, bool owns_mem
00490   )
00491 {
00492   return ArrayRCP<T>(p,lowerOffset,lowerOffset+size-1,dealloc,owns_mem);
00493 }
00494 
00495 template<class T>
00496 inline
00497 Teuchos::ArrayRCP<T>
00498 Teuchos::arcp( typename ArrayRCP<T>::Ordinal size )
00499 {
00500   return ArrayRCP<T>(new T[size],0,size-1,true);
00501 }
00502 
00503 template<class T>
00504 REFCOUNTPTR_INLINE
00505 Teuchos::ArrayRCP<T>
00506 Teuchos::arcp( const RCP<std::vector<T> > &v )
00507 {
00508   Teuchos::ArrayRCP<T> ptr = arcp(&(*v)[0],0,v->size(),false);
00509   set_extra_data( v, "std::vector", &ptr );
00510   return ptr;
00511 }
00512 
00513 template<class T>
00514 REFCOUNTPTR_INLINE
00515 Teuchos::RCP<std::vector<T> >
00516 Teuchos::get_std_vector( const ArrayRCP<T> &ptr )
00517 {
00518   return get_extra_data<RCP<std::vector<T> > >(ptr,"std::vector");
00519 }
00520 
00521 template<class T>
00522 REFCOUNTPTR_INLINE
00523 Teuchos::ArrayRCP<const T>
00524 Teuchos::arcp( const RCP<const std::vector<T> > &v )
00525 {
00526   Teuchos::ArrayRCP<const T> ptr = arcp(&(*v)[0],0,v->size(),false);
00527   set_extra_data( v, "std::vector", &ptr );
00528   return ptr;
00529 }
00530 
00531 template<class T>
00532 REFCOUNTPTR_INLINE
00533 Teuchos::RCP<const std::vector<T> >
00534 Teuchos::get_std_vector( const ArrayRCP<const T> &ptr )
00535 {
00536   return get_extra_data<RCP<const std::vector<T> > >(ptr,"std::vector");
00537 }
00538 
00539 template<class T>
00540 REFCOUNTPTR_INLINE
00541 bool Teuchos::is_null( const ArrayRCP<T> &p )
00542 {
00543   return p.access_ptr() == NULL;
00544 }
00545 
00546 template<class T>
00547 REFCOUNTPTR_INLINE
00548 bool Teuchos::operator==( const ArrayRCP<T> &p, ENull )
00549 {
00550   return p.access_ptr() == NULL;
00551 }
00552 
00553 template<class T>
00554 REFCOUNTPTR_INLINE
00555 bool Teuchos::operator!=( const ArrayRCP<T> &p, ENull )
00556 {
00557   return p.access_ptr() != NULL;
00558 }
00559 
00560 template<class T1, class T2>
00561 REFCOUNTPTR_INLINE
00562 bool Teuchos::operator==( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 )
00563 {
00564   return p1.access_ptr() == p2.access_ptr();
00565 }
00566 
00567 template<class T1, class T2>
00568 REFCOUNTPTR_INLINE
00569 bool Teuchos::operator!=( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 )
00570 {
00571   return p1.access_ptr() != p2.access_ptr();
00572 }
00573 
00574 template<class T1, class T2>
00575 REFCOUNTPTR_INLINE
00576 bool Teuchos::operator<( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 )
00577 {
00578   return p1.access_ptr() < p2.access_ptr();
00579 }
00580 
00581 template<class T1, class T2>
00582 REFCOUNTPTR_INLINE
00583 bool Teuchos::operator<=( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 )
00584 {
00585   Utilities::assert_shares_resource(p1,p2);
00586   return p1.access_ptr() <= p2.access_ptr();
00587 }
00588 
00589 template<class T1, class T2>
00590 REFCOUNTPTR_INLINE
00591 bool Teuchos::operator>( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 )
00592 {
00593   Utilities::assert_shares_resource(p1,p2);
00594   return p1.access_ptr() > p2.access_ptr();
00595 }
00596 
00597 template<class T1, class T2>
00598 REFCOUNTPTR_INLINE
00599 bool Teuchos::operator>=( const ArrayRCP<T1> &p1, const ArrayRCP<T2> &p2 )
00600 {
00601   Utilities::assert_shares_resource(p1,p2);
00602   return p1.access_ptr() >= p2.access_ptr();
00603 }
00604 
00605 template<class T2, class T1>
00606 REFCOUNTPTR_INLINE
00607 Teuchos::ArrayRCP<T2>
00608 Teuchos::arcp_reinterpret_cast(const ArrayRCP<T1>& p1)
00609 {
00610   typedef typename ArrayRCP<T1>::Ordinal Ordinal;
00611   const int sizeOfT2ToT1 = sizeof(T2)/sizeof(T1);
00612   Ordinal lowerOffset2 = p1.lowerOffset() / sizeOfT2ToT1;
00613   Ordinal upperOffset2 = (p1.upperOffset()+1) / sizeOfT2ToT1 -1;
00614   T2 *ptr2 = reinterpret_cast<T2*>(p1.get());
00615   return ArrayRCP<T2>(
00616     ptr2,lowerOffset2,upperOffset2
00617     ,p1.access_node()
00618     );
00619   // Note: Above is just fine even if p1.get()==NULL!
00620 }
00621 
00622 template<class T2, class T1>
00623 REFCOUNTPTR_INLINE
00624 Teuchos::ArrayRCP<T2>
00625 Teuchos::arcp_implicit_cast(const ArrayRCP<T1>& p1)
00626 {
00627   typedef typename ArrayRCP<T1>::Ordinal Ordinal;
00628   T2 * raw_ptr2 = p1.get();
00629   return ArrayRCP<T2>(
00630     raw_ptr2,p1.lowerOffset(),p1.upperOffset()
00631     ,p1.access_node()
00632     );
00633   // Note: Above is just fine even if p1.get()==NULL!
00634 }
00635 
00636 template<class T1, class T2>
00637 REFCOUNTPTR_INLINE
00638 void Teuchos::set_extra_data(
00639   const T1 &extra_data, const std::string& name, Teuchos::ArrayRCP<T2> *p
00640   ,EPrePostDestruction destroy_when, bool force_unique
00641   )
00642 {
00643   p->assert_not_null();
00644   p->access_node()->set_extra_data( any(extra_data), name, destroy_when, force_unique );
00645 }
00646 
00647 template<class T1, class T2>
00648 REFCOUNTPTR_INLINE
00649 T1& Teuchos::get_extra_data( ArrayRCP<T2>& p, const std::string& name )
00650 {
00651   p.assert_not_null();
00652   return any_cast<T1>(p.access_node()->get_extra_data(TypeNameTraits<T1>::name(),name));
00653 }
00654 
00655 template<class T1, class T2>
00656 REFCOUNTPTR_INLINE
00657 const T1& Teuchos::get_extra_data( const ArrayRCP<T2>& p, const std::string& name )
00658 {
00659   p.assert_not_null();
00660   return any_cast<T1>(p.access_node()->get_extra_data(TypeNameTraits<T1>::name(),name));
00661 }
00662 
00663 template<class T1, class T2>
00664 REFCOUNTPTR_INLINE
00665 T1* Teuchos::get_optional_extra_data( ArrayRCP<T2>& p, const std::string& name )
00666 {
00667   p.assert_not_null();
00668   any *extra_data = p.access_node()->get_optional_extra_data(TypeNameTraits<T1>::name(),name);
00669   if( extra_data ) return &any_cast<T1>(*extra_data);
00670   return NULL;
00671 }
00672 
00673 template<class T1, class T2>
00674 REFCOUNTPTR_INLINE
00675 const T1* Teuchos::get_optional_extra_data( const ArrayRCP<T2>& p, const std::string& name )
00676 {
00677   p.assert_not_null();
00678   any *extra_data = p.access_node()->get_optional_extra_data(TypeNameTraits<T1>::name(),name);
00679   if( extra_data ) return &any_cast<T1>(*extra_data);
00680   return NULL;
00681 }
00682 
00683 template<class Dealloc_T, class T>
00684 REFCOUNTPTR_INLINE
00685 Dealloc_T&
00686 Teuchos::get_dealloc( ArrayRCP<T>& p )
00687 {
00688   typedef PrivateUtilityPack::RCP_node_tmpl<typename Dealloc_T::ptr_t,Dealloc_T>  requested_type;
00689   p.assert_not_null();
00690   PrivateUtilityPack::RCP_node_tmpl<typename Dealloc_T::ptr_t,Dealloc_T>
00691     *dnode = dynamic_cast<PrivateUtilityPack::RCP_node_tmpl<typename Dealloc_T::ptr_t,Dealloc_T>*>(p.access_node());
00692   TEST_FOR_EXCEPTION(
00693     dnode==NULL, std::logic_error
00694     ,"get_dealloc<" << TypeNameTraits<Dealloc_T>::name() << "," << TypeNameTraits<T>::name() << ">(p): "
00695     << "Error, requested type \'" << TypeNameTraits<requested_type>::name()
00696     << "\' does not match actual type of the node \'" << typeName(*p.access_node()) << "!"
00697     );
00698   return dnode->get_dealloc();
00699 }
00700 
00701 template<class Dealloc_T, class T>
00702 inline
00703 const Dealloc_T& 
00704 Teuchos::get_dealloc( const Teuchos::ArrayRCP<T>& p )
00705 {
00706   return get_dealloc<Dealloc_T>(const_cast<ArrayRCP<T>&>(p));
00707 }
00708 
00709 template<class Dealloc_T, class T>
00710 REFCOUNTPTR_INLINE
00711 Dealloc_T*
00712 Teuchos::get_optional_dealloc( ArrayRCP<T>& p )
00713 {
00714   p.assert_not_null();
00715   typedef PrivateUtilityPack::RCP_node_tmpl<typename Dealloc_T::ptr_t,Dealloc_T>
00716     RCPNT;
00717   RCPNT *dnode = dynamic_cast<RCPNT*>(p.access_node());
00718   if(dnode)
00719     return &dnode->get_dealloc();
00720   return NULL;
00721 }
00722 
00723 template<class Dealloc_T, class T>
00724 inline
00725 const Dealloc_T*
00726 Teuchos::get_optional_dealloc( const Teuchos::ArrayRCP<T>& p )
00727 {
00728   return get_optional_dealloc<Dealloc_T>(const_cast<ArrayRCP<T>&>(p));
00729 }
00730 
00731 template<class T>
00732 std::ostream& Teuchos::operator<<( std::ostream& out, const ArrayRCP<T>& p )
00733 {
00734   out
00735     << TypeNameTraits<ArrayRCP<T> >::name() << "{"
00736     << "ptr="<<(const void*)(p.get()) // I can't find any alternative to this C cast :-(
00737     <<",lowerOffset="<<p.lowerOffset()
00738     <<",upperOffset="<<p.upperOffset()
00739     <<",size="<<p.size()
00740     <<",node="<<p.access_node()
00741     <<",count="<<p.count()
00742     <<"}";
00743   return out;
00744 }
00745 
00746 #endif // TEUCHOS_ARRAY_RCP_HPP

Generated on Tue Oct 20 12:45:25 2009 for Teuchos - Trilinos Tools Package by doxygen 1.4.7