CoinUtils trunk
|
00001 // Copyright (C) 2004, 2006 International Business Machines and others. 00002 // All Rights Reserved. 00003 // This code is published under the Eclipse Public License. 00004 // 00005 // $Id$ 00006 // 00007 // Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 00008 // Removed lots of debugging stuff and reformatted: Laszlo Ladanyi, IBM 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 //#define IP_DEBUG_SMARTPTR 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_(); // Release any old pointer 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 // If lhs and rhs point to the same object with different interfaces 00479 // U1 and U2, we cannot guarantee that the value of the pointers will 00480 // be equivalent. We can guarantee this if we convert to void*. 00481 return static_cast<const void*>(lhs) == static_cast<const void*>(rhs); 00482 } 00483 00484 } // namespace Coin 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