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_SHARED_PTR
00049 #define STLSOFT_INCL_STLSOFT_SMARTPTR_HPP_SHARED_PTR
00050
00051 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00052 # define STLSOFT_VER_STLSOFT_SMARTPTR_HPP_SHARED_PTR_MAJOR 3
00053 # define STLSOFT_VER_STLSOFT_SMARTPTR_HPP_SHARED_PTR_MINOR 2
00054 # define STLSOFT_VER_STLSOFT_SMARTPTR_HPP_SHARED_PTR_REVISION 3
00055 # define STLSOFT_VER_STLSOFT_SMARTPTR_HPP_SHARED_PTR_EDIT 37
00056 #endif
00057
00058
00059
00060
00061
00062 #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
00063 # include <stlsoft/stlsoft.h>
00064 #endif
00065 #ifndef STLSOFT_INCL_STLSOFT_UTIL_HPP_STD_SWAP
00066 # include <stlsoft/util/std_swap.hpp>
00067 #endif
00068
00069
00070
00071
00072
00073 #ifndef _STLSOFT_NO_NAMESPACE
00074 namespace stlsoft
00075 {
00076 #endif
00077
00078
00079
00080
00081
00092 template <ss_typename_param_k T>
00093 class shared_ptr
00094 {
00097 public:
00098 typedef T value_type;
00099 typedef value_type* pointer;
00100 typedef value_type const* const_pointer;
00101 typedef value_type& reference;
00102 typedef value_type const& const_reference;
00103 typedef shared_ptr<T> class_type;
00104
00105 typedef pointer resource_type;
00106 typedef const_pointer const_resource_type;
00108
00111 public:
00112 shared_ptr()
00113 : m_p(NULL)
00114 , m_pc(NULL)
00115 {
00116 STLSOFT_ASSERT(is_valid());
00117 }
00128 explicit shared_ptr(T* p)
00129 : m_p(p)
00130 , m_pc(NULL)
00131 {
00132
00133
00134
00135
00136
00137
00138 if(NULL != p)
00139 {
00140 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00141 try
00142 {
00143 #endif
00144
00145 m_pc = new long(1);
00146
00147 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00148 }
00149 catch(std::bad_alloc&)
00150 #else
00151 if(NULL == m_pc)
00152 #endif
00153 {
00154 delete m_p;
00155
00156 m_p = NULL;
00157
00158 throw;
00159 }
00160 }
00161
00162 STLSOFT_ASSERT(is_valid());
00163 }
00164
00165 shared_ptr(class_type const& rhs)
00166 : m_p(rhs.m_p)
00167 , m_pc(rhs.m_pc)
00168 {
00169 STLSOFT_ASSERT(rhs.is_valid());
00170
00171 if(NULL != m_pc)
00172 {
00173 ++*m_pc;
00174 }
00175
00176 STLSOFT_ASSERT(is_valid());
00177 }
00178
00179 #if defined(STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT) && \
00180 ( !defined(STLSOFT_COMPILER_IS_MSVC) || \
00181 _MSC_VER > 1200)
00182 template <ss_typename_param_k T2>
00183 shared_ptr(shared_ptr<T2> const& rhs)
00184 : m_p(rhs.m_p)
00185 , m_pc(rhs.m_pc)
00186 {
00187 STLSOFT_ASSERT(rhs.is_valid());
00188
00189 STLSOFT_ASSERT((NULL == m_p) == (NULL == m_pc));
00190
00191 if(NULL != m_pc)
00192 {
00193 ++*m_pc;
00194 }
00195
00196 STLSOFT_ASSERT(is_valid());
00197 }
00198 #endif
00199
00200 ~shared_ptr() stlsoft_throw_0()
00201 {
00202 STLSOFT_ASSERT(is_valid());
00203
00204 STLSOFT_ASSERT((NULL == m_p) == (NULL == m_pc));
00205 STLSOFT_ASSERT((NULL == m_pc) || (0 < *m_pc));
00206
00207 if( NULL != m_pc &&
00208 0 == --*m_pc)
00209 {
00210 delete m_p;
00211 delete m_pc;
00212 }
00213 }
00214
00215 class_type& operator =(class_type const& rhs)
00216 {
00217 STLSOFT_ASSERT(is_valid());
00218
00219 class_type this_(rhs);
00220
00221 this_.swap(*this);
00222
00223 STLSOFT_ASSERT(is_valid());
00224
00225 return *this;
00226 }
00227
00228 #if defined(STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT) && \
00229 ( !defined(STLSOFT_COMPILER_IS_MSVC) || \
00230 _MSC_VER > 1200)
00231 template <ss_typename_param_k T2>
00232 class_type& operator =(shared_ptr<T2> const& rhs)
00233 {
00234 STLSOFT_ASSERT(rhs.is_valid());
00235
00236 STLSOFT_ASSERT(is_valid());
00237
00238 class_type this_(rhs);
00239
00240 this_.swap(*this);
00241
00242 STLSOFT_ASSERT(is_valid());
00243
00244 return *this;
00245 }
00246 #endif
00248
00251 public:
00252 void close()
00253 {
00254 STLSOFT_ASSERT((NULL == m_p) == (NULL == m_pc));
00255 STLSOFT_ASSERT((NULL == m_pc) || (0 < *m_pc));
00256
00257 STLSOFT_ASSERT(is_valid());
00258
00259 if(NULL != m_pc)
00260 {
00261 pointer p = m_p;
00262 long *pc = m_pc;
00263
00264
00265
00266
00267
00268
00269 m_p = NULL;
00270 m_pc = NULL;
00271
00272 if(0 == --*pc)
00273 {
00274 delete p;
00275 delete pc;
00276 }
00277 }
00278
00279 STLSOFT_ASSERT(is_valid());
00280 }
00281
00282 #if 0 && !defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00283 void reset()
00284 {
00285 close();
00286 }
00287 #endif
00288
00289 pointer detach()
00290 {
00291 STLSOFT_ASSERT((NULL == m_p) == (NULL == m_pc));
00292 STLSOFT_ASSERT((NULL == m_pc) || (0 < *m_pc));
00293
00294 STLSOFT_ASSERT(is_valid());
00295
00296 pointer p = NULL;
00297
00298 if(NULL != m_pc)
00299 {
00300 if(0 == --*m_pc)
00301 {
00302 delete m_pc;
00303
00304 m_pc = NULL;
00305 }
00306
00307 std_swap(p, m_p);
00308 }
00309
00310 STLSOFT_ASSERT(is_valid());
00311
00312 return p;
00313 }
00314
00315 void swap(class_type& rhs)
00316 {
00317 STLSOFT_ASSERT(rhs.is_valid());
00318
00319 STLSOFT_ASSERT(is_valid());
00320
00321 std_swap(m_p, rhs.m_p);
00322 std_swap(m_pc, rhs.m_pc);
00323
00324 STLSOFT_ASSERT(is_valid());
00325 }
00327
00330 public:
00331 const_pointer operator ->() const
00332 {
00333 STLSOFT_ASSERT(NULL != m_p);
00334 STLSOFT_ASSERT(is_valid());
00335
00336 return m_p;
00337 }
00338 pointer operator ->()
00339 {
00340 STLSOFT_ASSERT(NULL != m_p);
00341 STLSOFT_ASSERT(is_valid());
00342
00343 return m_p;
00344 }
00345
00346 pointer get() const
00347 {
00348 STLSOFT_ASSERT(is_valid());
00349
00350 return m_p;
00351 }
00352
00353 const_reference operator *() const
00354 {
00355 STLSOFT_ASSERT(NULL != m_p);
00356 STLSOFT_ASSERT(is_valid());
00357
00358 return *m_p;
00359 }
00360 reference operator *()
00361 {
00362 STLSOFT_ASSERT(NULL != m_p);
00363 STLSOFT_ASSERT(is_valid());
00364
00365 return *m_p;
00366 }
00368
00371 public:
00372 long count() const
00373 {
00374 STLSOFT_ASSERT(is_valid());
00375
00376 return (NULL == m_pc) ? 0 : *m_pc;
00377 }
00379 long use_count() const
00380 {
00381 STLSOFT_ASSERT(is_valid());
00382
00383 return this->count();
00384 }
00386
00389 private:
00390 ss_bool_t is_valid() const
00391 {
00392 if((NULL == m_p) != (NULL == m_pc))
00393 {
00394 #ifdef STLSOFT_UNITTEST
00395 fprintf(err, "Managed object's pointer and shared count pointer must both be NULL, or both non-NULL!\n");
00396 #endif
00397
00398 return false;
00399 }
00400
00401 if( NULL != m_pc &&
00402 *m_pc < 1)
00403 {
00404 #ifdef STLSOFT_UNITTEST
00405 fprintf(err, "Shared count cannot be less than 1!\n");
00406 #endif
00407
00408 return false;
00409 }
00410
00411 return true;
00412 }
00414
00417 private:
00418 pointer m_p;
00419 long *m_pc;
00421 };
00422
00423
00424
00425
00426
00427 template <ss_typename_param_k T>
00428 void swap(shared_ptr<T>& lhs, shared_ptr<T>& rhs)
00429 {
00430 lhs.swap(rhs);
00431 }
00432
00433
00434
00435
00436
00437 #if !defined(STLSOFT_COMPILER_IS_WATCOM)
00438
00443 template<ss_typename_param_k T>
00444 inline T* get_ptr(shared_ptr<T> const& p)
00445 {
00446 return p.get();
00447 }
00448
00453 template< ss_typename_param_k S
00454 , ss_typename_param_k T
00455 >
00456 inline S& operator <<(S& s, shared_ptr<T> const& p)
00457 {
00458 return s << *p;
00459 }
00460
00461 #endif
00462
00463
00464
00465 #ifndef _STLSOFT_NO_NAMESPACE
00466 }
00467 #endif
00468
00469
00470
00471
00472 #if defined(STLSOFT_CF_std_NAMESPACE)
00473 # if ( ( defined(STLSOFT_COMPILER_IS_INTEL) && \
00474 defined(_MSC_VER))) && \
00475 _MSC_VER < 1310
00476 namespace std
00477 {
00478 template< ss_typename_param_k T
00479 >
00480 inline void swap(stlsoft_ns_qual(shared_ptr)<T>& lhs, stlsoft_ns_qual(shared_ptr)<T>& rhs)
00481 {
00482 lhs.swap(rhs);
00483 }
00484 }
00485 # endif
00486 #endif
00487
00488
00489
00490 #endif
00491
00492