00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef CoinSmartPtr_hpp
00010 #define CoinSmartPtr_hpp
00011
00012 #include <list>
00013 #include <cassert>
00014 #include <cstddef>
00015
00016 namespace Coin {
00017
00018
00019
00156 class ReferencedObject {
00157 public:
00158 ReferencedObject() : reference_count_(0) {}
00159 virtual ~ReferencedObject() { assert(reference_count_ == 0); }
00160 inline int ReferenceCount() const { return reference_count_; }
00161 inline void AddRef() const { ++reference_count_; }
00162 inline void ReleaseRef() const { --reference_count_; }
00163
00164 private:
00165 mutable int reference_count_;
00166 };
00167
00168
00169
00170
00171
00172 #if COIN_IPOPT_CHECKLEVEL > 2
00173 # define IP_DEBUG_SMARTPTR
00174 #endif
00175 #ifdef IP_DEBUG_SMARTPTR
00176 # include "IpDebug.hpp"
00177 #endif
00178
00317 template <class T>
00318 class SmartPtr {
00319 public:
00326 T* GetRawPtr() const { return ptr_; }
00327
00332 bool IsValid() const { return ptr_ != NULL; }
00333
00338 bool IsNull() const { return ptr_ == NULL; }
00339
00340 private:
00344 T* ptr_;
00345
00347 void ReleasePointer_() {
00348 if (ptr_) {
00349 ptr_->ReleaseRef();
00350 if (ptr_->ReferenceCount() == 0) {
00351 delete ptr_;
00352 }
00353 ptr_ = NULL;
00354 }
00355 }
00356
00359 SmartPtr<T>& SetFromRawPtr_(T* rhs){
00360 ReleasePointer_();
00361 if (rhs != NULL) {
00362 rhs->AddRef();
00363 ptr_ = rhs;
00364 }
00365 return *this;
00366 }
00367
00370 inline SmartPtr<T>& SetFromSmartPtr_(const SmartPtr<T>& rhs) {
00371 SetFromRawPtr_(rhs.GetRawPtr());
00372 return (*this);
00373 }
00374
00376
00377 public:
00378 #define dbg_smartptr_verbosity 0
00379
00383 SmartPtr() : ptr_(NULL) {}
00384
00386 SmartPtr(const SmartPtr<T>& copy) : ptr_(NULL) {
00387 (void) SetFromSmartPtr_(copy);
00388 }
00389
00391 SmartPtr(T* ptr) : ptr_(NULL) {
00392 (void) SetFromRawPtr_(ptr);
00393 }
00394
00397 ~SmartPtr() {
00398 ReleasePointer_();
00399 }
00401
00406 T* operator->() const {
00407 #if COIN_COINUTILS_CHECKLEVEL > 0
00408 assert(ptr_);
00409 #endif
00410 return ptr_;
00411 }
00412
00415 T& operator*() const {
00416 #if COIN_IPOPT_CHECKLEVEL > 0
00417 assert(ptr_);
00418 #endif
00419 return *ptr_;
00420 }
00421
00424 SmartPtr<T>& operator=(T* rhs) {
00425 return SetFromRawPtr_(rhs);
00426 }
00427
00431 SmartPtr<T>& operator=(const SmartPtr<T>& rhs) {
00432 return SetFromSmartPtr_(rhs);
00433 }
00434
00437 template <class U1, class U2>
00438 friend
00439 bool operator==(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs);
00440
00443 template <class U1, class U2>
00444 friend
00445 bool operator==(const SmartPtr<U1>& lhs, U2* raw_rhs);
00446
00449 template <class U1, class U2>
00450 friend
00451 bool operator==(U1* lhs, const SmartPtr<U2>& raw_rhs);
00452
00455 template <class U1, class U2>
00456 friend
00457 bool operator!=(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs);
00458
00461 template <class U1, class U2>
00462 friend
00463 bool operator!=(const SmartPtr<U1>& lhs, U2* raw_rhs);
00464
00467 template <class U1, class U2>
00468 friend
00469 bool operator!=(U1* lhs, const SmartPtr<U2>& raw_rhs);
00471
00472 };
00473
00474 template <class U1, class U2>
00475 bool ComparePointers(const U1* lhs, const U2* rhs) {
00476 if (lhs == rhs) {
00477 return true;
00478 }
00479
00480
00481
00482 return static_cast<const void*>(lhs) == static_cast<const void*>(rhs);
00483 }
00484
00485 }
00486
00487
00488
00492 template <class U1, class U2>
00493 bool operator==(const Coin::SmartPtr<U1>& lhs, const Coin::SmartPtr<U2>& rhs) {
00494 return Coin::ComparePointers(lhs.GetRawPtr(), rhs.GetRawPtr());
00495 }
00496
00497 template <class U1, class U2>
00498 bool operator==(const Coin::SmartPtr<U1>& lhs, U2* raw_rhs) {
00499 return Coin::ComparePointers(lhs.GetRawPtr(), raw_rhs);
00500 }
00501
00502 template <class U1, class U2>
00503 bool operator==(U1* raw_lhs, const Coin::SmartPtr<U2>& rhs) {
00504 return Coin::ComparePointers(raw_lhs, rhs.GetRawPtr());
00505 }
00506
00507 template <class U1, class U2>
00508 bool operator!=(const Coin::SmartPtr<U1>& lhs, const Coin::SmartPtr<U2>& rhs) {
00509 return ! operator==(lhs, rhs);
00510 }
00511
00512 template <class U1, class U2>
00513 bool operator!=(const Coin::SmartPtr<U1>& lhs, U2* raw_rhs) {
00514 return ! operator==(lhs, raw_rhs);
00515 }
00516
00517 template <class U1, class U2>
00518 bool operator!=(U1* raw_lhs, const Coin::SmartPtr<U2>& rhs) {
00519 return ! operator==(raw_lhs, rhs);
00520 }
00522
00523 #define CoinReferencedObject Coin::ReferencedObject
00524 #define CoinSmartPtr Coin::SmartPtr
00525 #define CoinComparePointers Coin::ComparePointers
00526
00527 #endif