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 #include <cstddef> 00015 #include <cstring> 00016 00017 namespace Coin { 00018 00019 //######################################################################### 00020 00157 class ReferencedObject { 00158 public: 00159 ReferencedObject() : reference_count_(0) {} 00160 virtual ~ReferencedObject() { assert(reference_count_ == 0); } 00161 inline int ReferenceCount() const { return reference_count_; } 00162 inline void AddRef() const { ++reference_count_; } 00163 inline void ReleaseRef() const { --reference_count_; } 00164 00165 private: 00166 mutable int reference_count_; 00167 }; 00168 00169 //######################################################################### 00170 00171 00172 //#define IP_DEBUG_SMARTPTR 00173 #if COIN_IPOPT_CHECKLEVEL > 2 00174 # define IP_DEBUG_SMARTPTR 00175 #endif 00176 #ifdef IP_DEBUG_SMARTPTR 00177 # include "IpDebug.hpp" 00178 #endif 00179 00318 template <class T> 00319 class SmartPtr { 00320 public: 00327 T* GetRawPtr() const { return ptr_; } 00328 00333 bool IsValid() const { return ptr_ != NULL; } 00334 00339 bool IsNull() const { return ptr_ == NULL; } 00340 00341 private: 00345 T* ptr_; 00346 00348 void ReleasePointer_() { 00349 if (ptr_) { 00350 ptr_->ReleaseRef(); 00351 if (ptr_->ReferenceCount() == 0) { 00352 delete ptr_; 00353 } 00354 ptr_ = NULL; 00355 } 00356 } 00357 00360 SmartPtr<T>& SetFromRawPtr_(T* rhs){ 00361 ReleasePointer_(); // Release any old pointer 00362 if (rhs != NULL) { 00363 rhs->AddRef(); 00364 ptr_ = rhs; 00365 } 00366 return *this; 00367 } 00368 00371 inline SmartPtr<T>& SetFromSmartPtr_(const SmartPtr<T>& rhs) { 00372 SetFromRawPtr_(rhs.GetRawPtr()); 00373 return (*this); 00374 } 00375 00377 00378 public: 00379 #define dbg_smartptr_verbosity 0 00380 00384 SmartPtr() : ptr_(NULL) {} 00385 00387 SmartPtr(const SmartPtr<T>& copy) : ptr_(NULL) { 00388 (void) SetFromSmartPtr_(copy); 00389 } 00390 00392 SmartPtr(T* ptr) : ptr_(NULL) { 00393 (void) SetFromRawPtr_(ptr); 00394 } 00395 00398 ~SmartPtr() { 00399 ReleasePointer_(); 00400 } 00402 00407 T* operator->() const { 00408 #if COIN_COINUTILS_CHECKLEVEL > 0 00409 assert(ptr_); 00410 #endif 00411 return ptr_; 00412 } 00413 00416 T& operator*() const { 00417 #if COIN_IPOPT_CHECKLEVEL > 0 00418 assert(ptr_); 00419 #endif 00420 return *ptr_; 00421 } 00422 00425 SmartPtr<T>& operator=(T* rhs) { 00426 return SetFromRawPtr_(rhs); 00427 } 00428 00432 SmartPtr<T>& operator=(const SmartPtr<T>& rhs) { 00433 return SetFromSmartPtr_(rhs); 00434 } 00435 00438 template <class U1, class U2> 00439 friend 00440 bool operator==(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs); 00441 00444 template <class U1, class U2> 00445 friend 00446 bool operator==(const SmartPtr<U1>& lhs, U2* raw_rhs); 00447 00450 template <class U1, class U2> 00451 friend 00452 bool operator==(U1* lhs, const SmartPtr<U2>& raw_rhs); 00453 00456 template <class U1, class U2> 00457 friend 00458 bool operator!=(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs); 00459 00462 template <class U1, class U2> 00463 friend 00464 bool operator!=(const SmartPtr<U1>& lhs, U2* raw_rhs); 00465 00468 template <class U1, class U2> 00469 friend 00470 bool operator!=(U1* lhs, const SmartPtr<U2>& raw_rhs); 00472 00473 }; 00474 00475 template <class U1, class U2> 00476 bool ComparePointers(const U1* lhs, const U2* rhs) { 00477 if (lhs == rhs) { 00478 return true; 00479 } 00480 // If lhs and rhs point to the same object with different interfaces 00481 // U1 and U2, we cannot guarantee that the value of the pointers will 00482 // be equivalent. We can guarantee this if we convert to void*. 00483 return static_cast<const void*>(lhs) == static_cast<const void*>(rhs); 00484 } 00485 00486 } // namespace Coin 00487 00488 //############################################################################# 00489 00493 template <class U1, class U2> 00494 bool operator==(const Coin::SmartPtr<U1>& lhs, const Coin::SmartPtr<U2>& rhs) { 00495 return Coin::ComparePointers(lhs.GetRawPtr(), rhs.GetRawPtr()); 00496 } 00497 00498 template <class U1, class U2> 00499 bool operator==(const Coin::SmartPtr<U1>& lhs, U2* raw_rhs) { 00500 return Coin::ComparePointers(lhs.GetRawPtr(), raw_rhs); 00501 } 00502 00503 template <class U1, class U2> 00504 bool operator==(U1* raw_lhs, const Coin::SmartPtr<U2>& rhs) { 00505 return Coin::ComparePointers(raw_lhs, rhs.GetRawPtr()); 00506 } 00507 00508 template <class U1, class U2> 00509 bool operator!=(const Coin::SmartPtr<U1>& lhs, const Coin::SmartPtr<U2>& rhs) { 00510 return ! operator==(lhs, rhs); 00511 } 00512 00513 template <class U1, class U2> 00514 bool operator!=(const Coin::SmartPtr<U1>& lhs, U2* raw_rhs) { 00515 return ! operator==(lhs, raw_rhs); 00516 } 00517 00518 template <class U1, class U2> 00519 bool operator!=(U1* raw_lhs, const Coin::SmartPtr<U2>& rhs) { 00520 return ! operator==(raw_lhs, rhs); 00521 } 00523 00524 #define CoinReferencedObject Coin::ReferencedObject 00525 #define CoinSmartPtr Coin::SmartPtr 00526 #define CoinComparePointers Coin::ComparePointers 00527 00528 #endif