00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef OSSMARTPTR_HPP
00013 #define OSSMARTPTR_HPP
00014
00015 #include "OSReferenced.hpp"
00016
00155 template<class T>
00156 class OSSmartPtr : public OSReferencer
00157 {
00158 public:
00159
00163 OSSmartPtr();
00164
00166 OSSmartPtr(const OSSmartPtr<T>& copy);
00167
00169 OSSmartPtr(T* ptr);
00170
00174 ~OSSmartPtr();
00176
00181 T* operator->() const;
00182
00185 T& operator*() const;
00186
00189 OSSmartPtr<T>& operator=(T* rhs);
00190
00194 OSSmartPtr<T>& operator=(const OSSmartPtr<T>& rhs);
00195
00198 template <class U1, class U2>
00199 friend
00200 bool operator==(const OSSmartPtr<U1>& lhs, const OSSmartPtr<U2>& rhs);
00201
00204 template <class U1, class U2>
00205 friend
00206 bool operator==(const OSSmartPtr<U1>& lhs, U2* raw_rhs);
00207
00210 template <class U1, class U2>
00211 friend
00212 bool operator==(U1* lhs, const OSSmartPtr<U2>& raw_rhs);
00213
00216 template <class U1, class U2>
00217 friend
00218 bool operator!=(const OSSmartPtr<U1>& lhs, const OSSmartPtr<U2>& rhs);
00219
00222 template <class U1, class U2>
00223 friend
00224 bool operator!=(const OSSmartPtr<U1>& lhs, U2* raw_rhs);
00225
00228 template <class U1, class U2>
00229 friend
00230 bool operator!=(U1* lhs, const OSSmartPtr<U2>& raw_rhs);
00232
00245 template <class U>
00246 friend
00247 U* GetRawPtr(const OSSmartPtr<U>& smart_ptr);
00248
00250 template <class U>
00251 friend
00252 OSSmartPtr<const U> ConstPtr(const OSSmartPtr<U>& smart_ptr);
00253
00258 template <class U>
00259 friend
00260 bool IsValid(const OSSmartPtr<U>& smart_ptr);
00261
00266 template <class U>
00267 friend
00268 bool IsNull(const OSSmartPtr<U>& smart_ptr);
00270
00271 private:
00275 T* ptr_;
00276
00280 OSSmartPtr<T>& SetFromRawPtr_(T* rhs);
00281
00285 OSSmartPtr<T>& SetFromSmartPtr_(const OSSmartPtr<T>& rhs);
00286
00288 void ReleasePointer_();
00290 };
00291
00294 template <class U>
00295 U* GetRawPtr(const OSSmartPtr<U>& smart_ptr);
00296
00297 template <class U>
00298 OSSmartPtr<const U> ConstPtr(const OSSmartPtr<U>& smart_ptr);
00299
00300 template <class U>
00301 bool IsNull(const OSSmartPtr<U>& smart_ptr);
00302
00303 template <class U>
00304 bool IsValid(const OSSmartPtr<U>& smart_ptr);
00305
00306 template <class U1, class U2>
00307 bool operator==(const OSSmartPtr<U1>& lhs, const OSSmartPtr<U2>& rhs);
00308
00309 template <class U1, class U2>
00310 bool operator==(const OSSmartPtr<U1>& lhs, U2* raw_rhs);
00311
00312 template <class U1, class U2>
00313 bool operator==(U1* lhs, const OSSmartPtr<U2>& raw_rhs);
00314
00315 template <class U1, class U2>
00316 bool operator!=(const OSSmartPtr<U1>& lhs, const OSSmartPtr<U2>& rhs);
00317
00318 template <class U1, class U2>
00319 bool operator!=(const OSSmartPtr<U1>& lhs, U2* raw_rhs);
00320
00321 template <class U1, class U2>
00322 bool operator!=(U1* lhs, const OSSmartPtr<U2>& raw_rhs);
00323
00325
00326
00327 template <class T>
00328 OSSmartPtr<T>::OSSmartPtr()
00329 :
00330 ptr_(0)
00331 {
00332
00333 #ifdef CHECK_SMARTPTR
00334
00335 const OSReferencedObject* trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_
00336 = ptr_;
00337 trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ = 0;
00338 #endif
00339
00340 }
00341
00342
00343 template <class T>
00344 OSSmartPtr<T>::OSSmartPtr(const OSSmartPtr<T>& copy)
00345 :
00346 ptr_(0)
00347 {
00348
00349 #ifdef CHECK_SMARTPTR
00350
00351 const ReferencedObject* trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_
00352 = ptr_;
00353 trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ = 0;
00354 #endif
00355
00356 (void) SetFromSmartPtr_(copy);
00357 }
00358
00359
00360 template <class T>
00361 OSSmartPtr<T>::OSSmartPtr(T* ptr)
00362 :
00363 ptr_(0)
00364 {
00365 #ifdef CHECK_SMARTPTR
00366
00367 const ReferencedObject* trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_
00368 = ptr_;
00369 trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ = 0;
00370 #endif
00371
00372 (void) SetFromRawPtr_(ptr);
00373 }
00374
00375 template <class T>
00376 OSSmartPtr<T>::~OSSmartPtr()
00377 {
00378 ReleasePointer_();
00379 }
00380
00381 template <class T>
00382 T* OSSmartPtr<T>::operator->() const
00383 {
00384 return ptr_;
00385 }
00386
00387
00388 template <class T>
00389 T& OSSmartPtr<T>::operator*() const
00390 {
00391 return *ptr_;
00392 }
00393
00394
00395 template <class T>
00396 OSSmartPtr<T>& OSSmartPtr<T>::operator=(T* rhs)
00397 {
00398 return SetFromRawPtr_(rhs);
00399 }
00400
00401
00402 template <class T>
00403 OSSmartPtr<T>& OSSmartPtr<T>::operator=(const OSSmartPtr<T>& rhs)
00404 {
00405 return SetFromSmartPtr_(rhs);
00406 }
00407
00408
00409 template <class T>
00410 OSSmartPtr<T>& OSSmartPtr<T>::SetFromRawPtr_(T* rhs)
00411 {
00412
00413 ReleasePointer_();
00414
00415 if (rhs != 0) {
00416 rhs->AddRef(this);
00417 ptr_ = rhs;
00418 }
00419
00420 return *this;
00421 }
00422
00423 template <class T>
00424 OSSmartPtr<T>& OSSmartPtr<T>::SetFromSmartPtr_(const OSSmartPtr<T>& rhs)
00425 {
00426 T* ptr = GetRawPtr(rhs);
00427
00428
00429
00430
00431
00432 SetFromRawPtr_(ptr);
00433
00434 return (*this);
00435 }
00436
00437
00438 template <class T>
00439 void OSSmartPtr<T>::ReleasePointer_()
00440 {
00441 if (ptr_) {
00442 ptr_->ReleaseRef(this);
00443 if (ptr_->ReferenceCount() == 0) {
00444 delete ptr_;
00445 }
00446 ptr_ = 0;
00447 }
00448 }
00449
00450
00451 template <class U>
00452 U* GetRawPtr(const OSSmartPtr<U>& smart_ptr)
00453 {
00454 return smart_ptr.ptr_;
00455 }
00456
00457 template <class U>
00458 OSSmartPtr<const U> ConstPtr(const OSSmartPtr<U>& smart_ptr)
00459 {
00460
00461 return GetRawPtr(smart_ptr);
00462 }
00463
00464 template <class U>
00465 bool IsValid(const OSSmartPtr<U>& smart_ptr)
00466 {
00467 return !IsNull(smart_ptr);
00468 }
00469
00470 template <class U>
00471 bool IsNull(const OSSmartPtr<U>& smart_ptr)
00472 {
00473 return (smart_ptr.ptr_ == 0);
00474 }
00475
00476
00477 template <class U1, class U2>
00478 bool ComparePointers(const U1* lhs, const U2* rhs)
00479 {
00480 if (lhs == rhs) {
00481 return true;
00482 }
00483
00484
00485
00486
00487
00488 const void* v_lhs = static_cast<const void*>(lhs);
00489 const void* v_rhs = static_cast<const void*>(rhs);
00490 if (v_lhs == v_rhs) {
00491 return true;
00492 }
00493
00494
00495 return false;
00496 }
00497
00498 template <class U1, class U2>
00499 bool operator==(const OSSmartPtr<U1>& lhs, const OSSmartPtr<U2>& rhs)
00500 {
00501 U1* raw_lhs = GetRawPtr(lhs);
00502 U2* raw_rhs = GetRawPtr(rhs);
00503 return ComparePointers(raw_lhs, raw_rhs);
00504 }
00505
00506 template <class U1, class U2>
00507 bool operator==(const OSSmartPtr<U1>& lhs, U2* raw_rhs)
00508 {
00509 U1* raw_lhs = GetRawPtr(lhs);
00510 return ComparePointers(raw_lhs, raw_rhs);
00511 }
00512
00513 template <class U1, class U2>
00514 bool operator==(U1* raw_lhs, const OSSmartPtr<U2>& rhs)
00515 {
00516 const U2* raw_rhs = GetRawPtr(rhs);
00517 return ComparePointers(raw_lhs, raw_rhs);
00518 }
00519
00520 template <class U1, class U2>
00521 bool operator!=(const OSSmartPtr<U1>& lhs, const OSSmartPtr<U2>& rhs)
00522 {
00523 bool retValue = operator==(lhs, rhs);
00524 return !retValue;
00525 }
00526
00527 template <class U1, class U2>
00528 bool operator!=(const OSSmartPtr<U1>& lhs, U2* raw_rhs)
00529 {
00530 bool retValue = operator==(lhs, raw_rhs);
00531 return !retValue;
00532 }
00533
00534 template <class U1, class U2>
00535 bool operator!=(U1* raw_lhs, const OSSmartPtr<U2>& rhs)
00536 {
00537 bool retValue = operator==(raw_lhs, rhs);
00538 return !retValue;
00539 }
00540
00541 #endif
00542