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