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

Generated on Thu Sep 18 12:30:29 2008 for Teuchos - Trilinos Tools Package by doxygen 1.3.9.1