- Main Page
- Namespaces
- Classes
- Files
- Directories

- Search for |

- File List
- File Members

# 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 1368 2010-12-30 22:00:41Z mjs $
    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