CoinUtils  trunk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
CoinSmartPtr.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines