# 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 1520 2012-01-29 00:43:31Z 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 #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