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 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00048 #ifndef STLSOFT_INCL_STLSOFT_SMARTPTR_HPP_REF_PTR
00049 #define STLSOFT_INCL_STLSOFT_SMARTPTR_HPP_REF_PTR
00050 
00051 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00052 # define STLSOFT_VER_STLSOFT_SMARTPTR_HPP_REF_PTR_MAJOR      5
00053 # define STLSOFT_VER_STLSOFT_SMARTPTR_HPP_REF_PTR_MINOR      3
00054 # define STLSOFT_VER_STLSOFT_SMARTPTR_HPP_REF_PTR_REVISION   2
00055 # define STLSOFT_VER_STLSOFT_SMARTPTR_HPP_REF_PTR_EDIT       489
00056 #endif 
00057 
00058 
00059 
00060 
00061 
00062 #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
00063 # include <stlsoft/stlsoft.h>
00064 #endif 
00065 
00066 
00067 
00068 
00069 
00070 #ifndef _STLSOFT_NO_NAMESPACE
00071 namespace stlsoft
00072 {
00073 #endif 
00074 
00075 
00076 
00077 
00078 
00090 template<ss_typename_param_k I>
00091 inline void add_reference(I* pi)
00092 {
00093     STLSOFT_ASSERT(NULL != pi);
00094 
00095     pi->AddRef();
00096 }
00097 
00109 template<ss_typename_param_k I>
00110 inline void release_reference(I* pi)
00111 {
00112     STLSOFT_ASSERT(NULL != pi);
00113 
00114     pi->Release();
00115 }
00116 
00117 
00118 
00119 
00120 
00132 template<   ss_typename_param_k T
00133         ,   ss_typename_param_k I = T
00134         ,   ss_typename_param_k U = I
00135         >
00136 class ref_ptr
00137 {
00140 public:
00142     typedef bool_t              bool_type;
00144     typedef I                   interface_type;
00146     typedef T                   counted_type;
00148     typedef U                   upcast_type;
00150     typedef ref_ptr<T, I, U>    class_type;
00151 
00153     typedef I                   element_type;
00155     typedef counted_type*       resource_type;
00156     typedef counted_type const* const_resource_type;
00158 
00161 private:
00163     static counted_type* c_from_i(interface_type* i)
00164     {
00165         return static_cast<counted_type*>(static_cast<upcast_type*>(i));
00166     }
00168     static counted_type const* c_from_i(interface_type const* i)
00169     {
00170         return static_cast<counted_type const*>(static_cast<upcast_type const*>(i));
00171     }
00173     static interface_type* i_from_c(counted_type* c)
00174     {
00175         return static_cast<upcast_type*>(c);
00176     }
00177 
00178 #if defined(STLSOFT_COMPILER_IS_MSVC) && \
00179     _MSC_VER == 1300
00181     static interface_type* i_from_const_c(counted_type const* cc)
00182     {
00183         counted_type* c = const_cast<counted_type*>(cc);
00184 
00185         return i_from_c(c);
00186     }
00187 #endif 
00189 
00192 public:
00196     ref_ptr()
00197         : m_pi(NULL)
00198     {}
00211     ref_ptr(counted_type* c, bool_type bAddRef)
00212         : m_pi(i_from_c(c))
00213     {
00214         if( bAddRef &&
00215             NULL != m_pi)
00216         {
00217             add_reference(m_pi);
00218         }
00219     }
00220 
00225     ref_ptr(class_type const& rhs)
00226         : m_pi(rhs.m_pi)
00227     {
00228         if(NULL != m_pi)
00229         {
00230             add_reference(m_pi);
00231         }
00232     }
00233 
00234 #if !defined(STLSOFT_COMPILER_IS_MSVC) || \
00235     _MSC_VER > 1100
00241     template<   ss_typename_param_k T2
00242             ,   ss_typename_param_k I2
00243             ,   ss_typename_param_k U2
00244             >
00245 # if defined(STLSOFT_COMPILER_IS_MSVC) && \
00246      _MSC_VER == 1300
00247     ref_ptr(ref_ptr<T2, I2, U2> const& rhs)
00248 #  if 0
00249         
00250         
00251         : m_pi(rhs.m_pi)
00252 #  else 
00253         : m_pi(i_from_const_c(rhs.get()))
00254 #  endif 
00255     {
00256         if(NULL != m_pi)
00257         {
00258             add_reference(m_pi);
00259         }
00260     }
00261 # else 
00262     ref_ptr(ref_ptr<T2, I2, U2>& rhs)
00263 #  if 0
00264         
00265         
00266         : m_pi(rhs.m_pi)
00267 #  else 
00268         : m_pi(i_from_c(rhs.get()))
00269 #  endif 
00270     {
00271         if(NULL != m_pi)
00272         {
00273             add_reference(m_pi);
00274         }
00275     }
00276 # endif 
00277 #endif 
00278 
00279 #if !defined(STLSOFT_COMPILER_IS_INTEL) && \
00280     !defined(STLSOFT_COMPILER_IS_MWERKS) && \
00281     0
00282     template<   ss_typename_param_k I2
00283             ,   ss_typename_param_k U2
00284             >
00285     explicit ref_ptr(ref_ptr<T, I2, U2>& rhs)
00286         : m_pi(rhs.m_pi)
00287     {
00288         if(NULL != m_pi)
00289         {
00290             add_reference(m_pi);
00291         }
00292     }
00293 #endif 
00294 
00299     ~ref_ptr() stlsoft_throw_0()
00300     {
00301         if(NULL != m_pi)
00302         {
00303             release_reference(m_pi);
00304         }
00305     }
00306 
00312     class_type& operator =(class_type const& rhs)
00313     {
00314         class_type  t(rhs);
00315 
00316         t.swap(*this);
00317 
00318         return *this;
00319     }
00320 
00321 #if !defined(STLSOFT_COMPILER_IS_MSVC) || \
00322     (   _MSC_VER > 1100 && \
00323         _MSC_VER != 1300)
00333     template<   ss_typename_param_k T2
00334             ,   ss_typename_param_k U2
00335             >
00336     class_type& operator =(ref_ptr<T2, I, U2>& rhs)
00337     {
00338         class_type  t(rhs);
00339 
00340         t.swap(*this);
00341 
00342         return *this;
00343     }
00344 #endif 
00345 
00346 #if !defined(STLSOFT_COMPILER_IS_INTEL) && \
00347     !defined(STLSOFT_COMPILER_IS_MWERKS) && \
00348     0
00349     template<   ss_typename_param_k I2
00350             ,   ss_typename_param_k U2
00351             >
00352     class_type& operator =(ref_ptr<T, I2, U2>& rhs)
00353     {
00354         class_type  t(rhs);
00355 
00356         t.swap(*this);
00357 
00358         return *this;
00359     }
00360 #endif 
00362 
00365 public:
00369     void swap(class_type& rhs)
00370     {
00371         interface_type* t           =   rhs.m_pi;
00372                         rhs.m_pi    =   m_pi;
00373                         m_pi        =   t;
00374     }
00375 
00382     void set(counted_type* c, bool_type bAddRef)
00383     {
00384         class_type  t(c, bAddRef);
00385 
00386         t.swap(*this);
00387     }
00388 
00392     void close()
00393     {
00394         if(NULL != m_pi)
00395         {
00396             release_reference(m_pi);
00397             m_pi = NULL;
00398         }
00399     }
00400 
00403     counted_type* detach()
00404     {
00405         counted_type* r = class_type::c_from_i(m_pi);
00406 
00407         m_pi = NULL;
00408 
00409         return r;
00410     }
00412 
00415 public:
00417     bool_type equal(class_type const& rhs) const
00418     {
00419         return m_pi == rhs.m_pi;
00420     }
00422 
00425 public:
00427     bool_type empty() const
00428     {
00429         return NULL == m_pi;
00430     }
00431 
00433     bool_type operator !() const
00434     {
00435         return empty();
00436     }
00437 
00439     counted_type* get() const
00440     {
00441         return class_type::c_from_i(m_pi);
00442     }
00443 
00448     counted_type* operator ->()
00449     {
00450         STLSOFT_MESSAGE_ASSERT("Dereferencing a NULL pointer!", NULL != m_pi);
00451 
00452         return class_type::c_from_i(m_pi);
00453     }
00454 
00459     counted_type const* operator ->() const
00460     {
00461         STLSOFT_MESSAGE_ASSERT("Dereferencing a NULL pointer!", NULL != m_pi);
00462 
00463         return class_type::c_from_i(m_pi);
00464     }
00465 
00470     counted_type& operator *()
00471     {
00472         STLSOFT_MESSAGE_ASSERT("Dereferencing a NULL pointer!", NULL != m_pi);
00473 
00474         return *class_type::c_from_i(m_pi);
00475     }
00476 
00481     counted_type const& operator *() const
00482     {
00483         STLSOFT_MESSAGE_ASSERT("Dereferencing a NULL pointer!", NULL != m_pi);
00484 
00485         return *class_type::c_from_i(m_pi);
00486     }
00488 
00491 private:
00492     interface_type* m_pi;
00494 };
00495 
00496 
00497 
00498 
00499 
00500 template<   ss_typename_param_k T
00501         ,   ss_typename_param_k I
00502         ,   ss_typename_param_k U
00503         >
00504 inline ss_bool_t operator ==(ref_ptr<T, I, U> const& lhs, ref_ptr<T, I, U> const& rhs)
00505 {
00506     return lhs.equal(rhs);
00507 }
00508 
00509 template<   ss_typename_param_k T
00510         ,   ss_typename_param_k I
00511         ,   ss_typename_param_k U
00512         >
00513 inline ss_bool_t operator !=(ref_ptr<T, I, U> const& lhs, ref_ptr<T, I, U> const& rhs)
00514 {
00515     return !lhs.equal(rhs);
00516 }
00517 
00518 
00519 
00520 
00521 
00522 template<   ss_typename_param_k T
00523         ,   ss_typename_param_k I
00524         ,   ss_typename_param_k U
00525         >
00526 inline void swap(ref_ptr<T, I, U>& lhs, ref_ptr<T, I, U>& rhs)
00527 {
00528     lhs.swap(rhs);
00529 }
00530 
00531 
00532 
00533 
00534 
00539 template<   ss_typename_param_k T
00540         ,   ss_typename_param_k I 
00541         ,   ss_typename_param_k U 
00542         >
00543 inline ss_bool_t is_empty(ref_ptr<T, I, U> const& p)
00544 {
00545     return NULL == p.get();
00546 }
00547 
00552 template<   ss_typename_param_k T
00553         ,   ss_typename_param_k I 
00554         ,   ss_typename_param_k U 
00555         >
00556 inline T* get_ptr(ref_ptr<T, I, U> const& p)
00557 {
00558     return p.get();
00559 }
00560 
00565 template<   ss_typename_param_k S
00566         ,   ss_typename_param_k T
00567         ,   ss_typename_param_k I 
00568         ,   ss_typename_param_k U 
00569         >
00570 inline S& operator <<(S& s, ref_ptr<T, I, U> const& p)
00571 {
00572     return s << *p;
00573 }
00574 
00575 
00576 
00577 
00578 
00579 #ifdef STLSOFT_UNITTEST
00580 # include "./unittest/ref_ptr_unittest_.h"
00581 #endif 
00582 
00583 
00584 
00585 #ifndef _STLSOFT_NO_NAMESPACE
00586 } 
00587 #endif 
00588 
00589 
00590 
00591 
00592 #if defined(STLSOFT_CF_std_NAMESPACE)
00593 # if ( ( defined(STLSOFT_COMPILER_IS_INTEL) && \
00594          defined(_MSC_VER))) && \
00595      _MSC_VER < 1310
00596 namespace std
00597 {
00598     template<   ss_typename_param_k T
00599             ,   ss_typename_param_k I
00600             ,   ss_typename_param_k U
00601             >
00602     inline void swap(stlsoft_ns_qual(ref_ptr)<T, I, U>& lhs, stlsoft_ns_qual(ref_ptr)<T, I, U>& rhs)
00603     {
00604         lhs.swap(rhs);
00605     }
00606 } 
00607 # endif 
00608 #endif 
00609 
00610 
00611 
00612 #endif 
00613 
00614