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