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: CoinSmartPtr.hpp 1500 2011-11-04 00:01:44Z tkr $
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 
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 //#define IP_DEBUG_SMARTPTR
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_(); // Release any old pointer
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         // If lhs and rhs point to the same object with different interfaces
00480         // U1 and U2, we cannot guarantee that the value of the pointers will
00481         // be equivalent. We can guarantee this if we convert to void*.
00482         return static_cast<const void*>(lhs) == static_cast<const void*>(rhs);
00483     }
00484 
00485 } // namespace Coin
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

Generated on Fri Nov 4 03:05:25 2011 for CoinUtils by  doxygen 1.4.7