Teuchos Package Browser (Single Doxygen Collection) Version of the Day
Teuchos_RCPDecl.hpp
Go to the documentation of this file.
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 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ***********************************************************************
00040 // @HEADER
00041 
00042 #ifndef TEUCHOS_RCP_DECL_HPP
00043 #define TEUCHOS_RCP_DECL_HPP
00044 
00045 
00051 #include "Teuchos_RCPNode.hpp"
00052 #include "Teuchos_ENull.hpp"
00053 #include "Teuchos_NullIteratorTraits.hpp"
00054 
00055 
00056 #ifdef REFCOUNTPTR_INLINE_FUNCS
00057 #  define REFCOUNTPTR_INLINE inline
00058 #else
00059 #  define REFCOUNTPTR_INLINE
00060 #endif
00061 
00062 
00063 #ifdef TEUCHOS_DEBUG
00064 #  define TEUCHOS_REFCOUNTPTR_ASSERT_NONNULL
00065 #endif
00066 
00067 
00068 namespace Teuchos {
00069 
00070 
00072 template<class T> class Ptr;
00073 
00074 
00075 enum ERCPWeakNoDealloc { RCP_WEAK_NO_DEALLOC };
00076 enum ERCPUndefinedWeakNoDealloc { RCP_UNDEFINED_WEAK_NO_DEALLOC };
00077 enum ERCPUndefinedWithDealloc { RCP_UNDEFINED_WITH_DEALLOC };
00078 
00079 
00428 template<class T>
00429 class RCP {
00430 public:
00431 
00433   typedef T  element_type;
00434 
00437 
00459   inline RCP(ENull null_arg = null);
00460 
00481   inline explicit RCP( T* p, bool has_ownership = true );
00482 
00502   template<class Dealloc_T>
00503   inline RCP(T* p, Dealloc_T dealloc, bool has_ownership);
00504 
00522   inline RCP(const RCP<T>& r_ptr);
00523 
00537   template<class T2>
00538   inline RCP(const RCP<T2>& r_ptr);
00539 
00551   inline ~RCP();
00552 
00572   inline RCP<T>& operator=(const RCP<T>& r_ptr);
00573 
00586   inline RCP<T>& operator=(ENull);
00587 
00589   inline void swap(RCP<T> &r_ptr);
00590 
00592 
00595 
00597   inline bool is_null() const;
00598 
00605   inline T* operator->() const;
00606 
00613   inline T& operator*() const;
00614 
00619   inline T* get() const;
00620 
00625   inline T* getRawPtr() const;
00626 
00628   inline Ptr<T> ptr() const;
00629 
00631   inline Ptr<T> operator()() const;
00632 
00634   inline RCP<const T> getConst() const;
00635 
00637 
00640 
00652   inline ERCPStrength strength() const;
00653 
00663   inline bool is_valid_ptr() const;
00664 
00670   inline int strong_count() const;
00671 
00677   inline int weak_count() const;
00678 
00680   inline int total_count() const;
00681 
00700   inline void set_has_ownership();
00701 
00712   inline bool has_ownership() const;
00713 
00745   inline Ptr<T> release();
00746 
00763   inline RCP<T> create_weak() const;
00764 
00781   inline RCP<T> create_strong() const;
00782 
00790   template<class T2>
00791   inline bool shares_resource(const RCP<T2>& r_ptr) const;
00792 
00794 
00797 
00801   inline const RCP<T>& assert_not_null() const;
00802 
00812   inline const RCP<T>& assert_valid_ptr() const;
00813 
00815   inline const RCP<T>& debug_assert_not_null() const
00816     {
00817 #ifdef TEUCHOS_REFCOUNTPTR_ASSERT_NONNULL
00818       assert_not_null();
00819 #endif
00820       return *this;
00821     }
00822 
00824   inline const RCP<T>& debug_assert_valid_ptr() const
00825     {
00826 #ifdef TEUCHOS_DEBUG
00827       assert_valid_ptr();
00828 #endif
00829       return *this;
00830     }
00831 
00833 
00836 
00838   inline void reset();
00839 
00850   template<class T2>
00851   inline void reset(T2* p, bool has_ownership = true);
00852 
00854   TEUCHOS_DEPRECATED inline int count() const;
00855 
00857 
00858 private:
00859 
00860   // //////////////////////////////////////////////////////////////
00861   // Private data members
00862 
00863   T *ptr_; // NULL if this pointer is null
00864   RCPNodeHandle node_; // NULL if this pointer is null
00865 
00866 public: // Bad bad bad
00867 
00868   // These constructors are put here because we don't want to confuse users
00869   // who would otherwise see them.
00870 
00882   inline explicit RCP(T* p, ERCPWeakNoDealloc);
00883 
00894   inline explicit RCP(T* p, ERCPUndefinedWeakNoDealloc);
00895 
00902   template<class Dealloc_T>
00903   inline RCP(T* p, Dealloc_T dealloc, ERCPUndefinedWithDealloc,
00904     bool has_ownership = true);
00905 
00906 #ifndef DOXYGEN_COMPILE
00907 
00908   // WARNING: A general user should *never* call these functions!
00909   inline RCP(T* p, const RCPNodeHandle &node);
00910   inline T* access_private_ptr() const; // Does not throw
00911   inline RCPNodeHandle& nonconst_access_private_node(); // Does not thorw
00912   inline const RCPNodeHandle& access_private_node() const; // Does not thorw
00913 
00914 #endif
00915 
00916 };
00917 
00920 struct RCPComp {
00922   template<class T1, class T2> inline
00923   bool operator() (const RCP<T1> p1, const RCP<T2> p2) const{
00924     return p1.get() < p2.get();
00925   }
00926 };
00927 
00930 struct RCPConstComp {
00932   template<class T1, class T2> inline
00933   bool operator() (const RCP<const T1> p1, const RCP<const T2> p2) const{
00934     return p1.get() < p2.get();
00935   }
00936 };
00937 
00938 
00939 
00940 // 2008/09/22: rabartl: NOTE: I removed the TypeNameTraits<RCP<T> >
00941 // specialization since I want to be able to print the type name of an RCP
00942 // that does not have the type T fully defined!
00943 
00944 
00949 template<typename T>
00950 class NullIteratorTraits<RCP<T> > {
00951 public:
00952   static RCP<T> getNull() { return null; }
00953 };
00954 
00955 
00960 template<class T>
00961 class DeallocNull
00962 {
00963 public:
00965   typedef T ptr_t;
00967   void free( T* ptr ) { 
00968     (void) ptr; // silence "unused parameter" compiler warning
00969   }
00970 };
00971 
00972 
00978 template<class T>
00979 class DeallocDelete
00980 {
00981 public:
00983   typedef T ptr_t;
00985   void free( T* ptr ) { if(ptr) delete ptr; }
00986 };
00987 
00988 
00994 template<class T>
00995 class DeallocArrayDelete
00996 {
00997 public:
00999   typedef T ptr_t;
01001   void free( T* ptr ) { if(ptr) delete [] ptr; }
01002 };
01003 
01004 
01017 template<class T, class DeleteFunctor>
01018 class DeallocFunctorDelete
01019 {
01020 public:
01021   DeallocFunctorDelete( DeleteFunctor deleteFunctor ) : deleteFunctor_(deleteFunctor) {}
01022   typedef T ptr_t;
01023   void free( T* ptr ) { if(ptr) deleteFunctor_(ptr); }
01024 private:
01025   DeleteFunctor deleteFunctor_;
01026   DeallocFunctorDelete(); // Not defined and not to be called!
01027 };
01028 
01029 
01034 template<class T, class DeleteFunctor>
01035 DeallocFunctorDelete<T,DeleteFunctor>
01036 deallocFunctorDelete( DeleteFunctor deleteFunctor )
01037 {
01038   return DeallocFunctorDelete<T,DeleteFunctor>(deleteFunctor);
01039 }
01040 
01041 
01055 template<class T, class DeleteHandleFunctor>
01056 class DeallocFunctorHandleDelete
01057 {
01058 public:
01059   DeallocFunctorHandleDelete( DeleteHandleFunctor deleteHandleFunctor )
01060     : deleteHandleFunctor_(deleteHandleFunctor) {}
01061   typedef T ptr_t;
01062   void free( T* ptr ) { if(ptr) { T **hdl = &ptr; deleteHandleFunctor_(hdl); } }
01063 private:
01064   DeleteHandleFunctor deleteHandleFunctor_;
01065   DeallocFunctorHandleDelete(); // Not defined and not to be called!
01066 };
01067 
01068 
01073 template<class T, class DeleteHandleFunctor>
01074 DeallocFunctorHandleDelete<T,DeleteHandleFunctor>
01075 deallocFunctorHandleDelete( DeleteHandleFunctor deleteHandleFunctor )
01076 {
01077   return DeallocFunctorHandleDelete<T,DeleteHandleFunctor>(deleteHandleFunctor);
01078 }
01079 
01080 
01089 template<class T, class Embedded, class Dealloc>
01090 class EmbeddedObjDealloc
01091 {
01092 public:
01093   typedef typename Dealloc::ptr_t ptr_t;
01094   EmbeddedObjDealloc(
01095     const Embedded &embedded, EPrePostDestruction prePostDestroy,
01096     Dealloc dealloc
01097     ) : embedded_(embedded), prePostDestroy_(prePostDestroy), dealloc_(dealloc)
01098     {}
01099   void setObj( const Embedded &embedded ) { embedded_ = embedded; }
01100   const Embedded& getObj() const { return embedded_; }
01101   Embedded& getNonconstObj() { return embedded_; }
01102   void free( T* ptr )
01103     {
01104       if (prePostDestroy_ == PRE_DESTROY)
01105         embedded_ = Embedded();
01106       dealloc_.free(ptr);
01107       if (prePostDestroy_ == POST_DESTROY)
01108         embedded_ = Embedded();
01109     }
01110 private:
01111   Embedded embedded_;
01112   EPrePostDestruction prePostDestroy_;
01113   Dealloc dealloc_;
01114   EmbeddedObjDealloc(); // Not defined and not to be called!
01115 };
01116 
01117 
01122 template<class T, class Embedded >
01123 EmbeddedObjDealloc<T,Embedded,DeallocDelete<T> >
01124 embeddedObjDeallocDelete(const Embedded &embedded, EPrePostDestruction prePostDestroy)
01125 {
01126   return EmbeddedObjDealloc<T,Embedded,DeallocDelete<T> >(
01127     embedded, prePostDestroy,DeallocDelete<T>());
01128 }
01129 
01130 
01135 template<class T, class Embedded >
01136 EmbeddedObjDealloc<T,Embedded,DeallocArrayDelete<T> >
01137 embeddedObjDeallocArrayDelete(const Embedded &embedded, EPrePostDestruction prePostDestroy)
01138 {
01139   return EmbeddedObjDealloc<T,Embedded,DeallocArrayDelete<T> >(
01140     embedded, prePostDestroy,DeallocArrayDelete<T>());
01141 }
01142 
01143 
01166 template<class T> inline
01167 RCP<T> rcp(T* p, bool owns_mem = true);
01168 
01169 
01213 template<class T, class Dealloc_T> inline
01214 RCP<T> rcpWithDealloc(T* p, Dealloc_T dealloc, bool owns_mem=true);
01215 
01216 
01218 template<class T, class Dealloc_T> inline
01219 TEUCHOS_DEPRECATED RCP<T> rcp( T* p, Dealloc_T dealloc, bool owns_mem )
01220 {
01221   return rcpWithDealloc(p, dealloc, owns_mem);
01222 }
01223 
01224 
01236 template<class T, class Dealloc_T> inline
01237 RCP<T> rcpWithDeallocUndef(T* p, Dealloc_T dealloc, bool owns_mem=true);
01238 
01239 
01249 template<class T> inline
01250 RCP<T> rcpFromRef(T& r);
01251 
01252 
01262 template<class T> inline
01263 RCP<T> rcpFromUndefRef(T& r);
01264 
01265 
01276 template<class T, class Embedded> inline
01277 RCP<T>
01278 rcpWithEmbeddedObjPreDestroy( T* p, const Embedded &embedded, bool owns_mem = true );
01279 
01280 
01291 template<class T, class Embedded> inline
01292 RCP<T>
01293 rcpWithEmbeddedObjPostDestroy( T* p, const Embedded &embedded, bool owns_mem = true );
01294 
01295 
01307 template<class T, class Embedded> inline
01308 RCP<T>
01309 rcpWithEmbeddedObj( T* p, const Embedded &embedded, bool owns_mem = true );
01310 
01311 
01312 // 2007/10/25: rabartl: ToDo: put in versions of
01313 // rcpWithEmbedded[Pre,Post]DestoryWithDealloc(...) that also accept a general
01314 // deallocator!
01315 
01316 
01326 template<class T, class ParentT>
01327 RCP<T> rcpWithInvertedObjOwnership(const RCP<T> &child, const RCP<ParentT> &parent);
01328 
01329 
01343 template<class T>
01344 RCP<T> rcpCloneNode(const RCP<T> &p);
01345 
01346 
01351 template<class T> inline
01352 bool is_null( const RCP<T> &p );
01353 
01354 
01359 template<class T> inline
01360 bool nonnull( const RCP<T> &p );
01361 
01362 
01367 template<class T> inline
01368 bool operator==( const RCP<T> &p, ENull );
01369 
01370 
01375 template<class T> inline
01376 bool operator!=( const RCP<T> &p, ENull );
01377 
01378 
01384 template<class T1, class T2> inline
01385 bool operator==( const RCP<T1> &p1, const RCP<T2> &p2 );
01386 
01387 
01393 template<class T1, class T2> inline
01394 bool operator!=( const RCP<T1> &p1, const RCP<T2> &p2 );
01395 
01396 
01406 template<class T2, class T1> inline
01407 RCP<T2> rcp_implicit_cast(const RCP<T1>& p1);
01408 
01409 
01420 template<class T2, class T1> inline
01421 RCP<T2> rcp_static_cast(const RCP<T1>& p1);
01422 
01423 
01430 template<class T2, class T1> inline
01431 RCP<T2> rcp_const_cast(const RCP<T1>& p1);
01432 
01433 
01457 template<class T2, class T1> inline
01458 RCP<T2> rcp_dynamic_cast(
01459   const RCP<T1>& p1, bool throw_on_fail = false
01460   );
01461 
01462 
01521 template<class T1, class T2>
01522 void set_extra_data( const T1 &extra_data, const std::string& name,
01523   const Ptr<RCP<T2> > &p, EPrePostDestruction destroy_when = POST_DESTROY,
01524   bool force_unique = true);
01525 
01545 template<class T1, class T2>
01546 const T1& get_extra_data( const RCP<T2>& p, const std::string& name );
01547 
01548 
01568 template<class T1, class T2>
01569 T1& get_nonconst_extra_data( RCP<T2>& p, const std::string& name );
01570 
01571 
01596 template<class T1, class T2>
01597 Ptr<const T1> get_optional_extra_data( const RCP<T2>& p, const std::string& name );
01598 
01599 
01624 template<class T1, class T2>
01625 Ptr<T1> get_optional_nonconst_extra_data( RCP<T2>& p, const std::string& name );
01626 
01627 
01639 template<class Dealloc_T, class T>
01640 const Dealloc_T& get_dealloc( const RCP<T>& p );
01641 
01642 
01654 template<class Dealloc_T, class T>
01655 Dealloc_T& get_nonconst_dealloc( const RCP<T>& p );
01656 
01657 
01672 template<class Dealloc_T, class T>
01673 Ptr<const Dealloc_T> get_optional_dealloc( const RCP<T>& p );
01674 
01675 
01690 template<class Dealloc_T, class T>
01691 Ptr<Dealloc_T> get_optional_nonconst_dealloc( const RCP<T>& p );
01692 
01693 
01700 template<class TOrig, class Embedded, class T>
01701 const Embedded& getEmbeddedObj( const RCP<T>& p );
01702 
01703 
01710 template<class TOrig, class Embedded, class T>
01711 Embedded& getNonconstEmbeddedObj( const RCP<T>& p );
01712 
01713 
01720 template<class TOrig, class Embedded, class T>
01721 Ptr<const Embedded> getOptionalEmbeddedObj( const RCP<T>& p );
01722 
01723 
01730 template<class TOrig, class Embedded, class T>
01731 Ptr<Embedded> getOptionalNonconstEmbeddedObj( const RCP<T>& p );
01732 
01733 
01739 template<class ParentT, class T>
01740 RCP<ParentT> getInvertedObjOwnershipParent(const RCP<T> &invertedChild);
01741 
01742 
01750 template<class T>
01751 std::ostream& operator<<( std::ostream& out, const RCP<T>& p );
01752 
01753 
01754 } // end namespace Teuchos
01755 
01756 
01757 #endif  // TEUCHOS_RCP_DECL_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines