- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# /home/coin/SVN-release/Ipopt-3.2.1/Ipopt/src/Common/IpSmartPtr.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 Common Public License.
    00004 //
    00005 // $Id: IpSmartPtr.hpp 759 2006-07-07 03:07:08Z andreasw $
    00006 //
    00007 // Authors:  Carl Laird, Andreas Waechter     IBM    2004-08-13
    00008
    00009 #ifndef __IPSMARTPTR_HPP__
    00010 #define __IPSMARTPTR_HPP__
    00011
    00012 #include "IpReferenced.hpp"
    00013
    00014 //#define IP_DEBUG_SMARTPTR
    00015 #ifdef IP_DEBUG_SMARTPTR
    00016 # include "IpDebug.hpp"
    00017 #endif
    00018
    00019 namespace Ipopt
    00020 {
    00021
    00164   template<class T>
    00165   class SmartPtr : public Referencer
    00166   {
    00167   public:
    00168 #define dbg_smartptr_verbosity 0
    00169
    00173     SmartPtr();
    00174
    00176     SmartPtr(const SmartPtr<T>& copy);
    00177
    00182     /* Don't support this, use dynamic_cast(GetRawPtr(copy))
    00183     template <class U>
    00184     SmartPtr(const SmartPtr<U> &copy);
    00185     */
    00186
    00188     SmartPtr(T* ptr);
    00189
    00193     ~SmartPtr();
    00195
    00200     T* operator->() const;
    00201
    00204     T& operator*() const;
    00205
    00208     SmartPtr<T>& operator=(T* rhs);
    00209
    00213     SmartPtr<T>& operator=(const SmartPtr<T>& rhs);
    00214
    00217     template <class U1, class U2>
    00218     friend
    00219     bool operator==(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs);
    00220
    00223     template <class U1, class U2>
    00224     friend
    00225     bool operator==(const SmartPtr<U1>& lhs, U2* raw_rhs);
    00226
    00229     template <class U1, class U2>
    00230     friend
    00231     bool operator==(U1* lhs, const SmartPtr<U2>& raw_rhs);
    00232
    00235     template <class U1, class U2>
    00236     friend
    00237     bool operator!=(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs);
    00238
    00241     template <class U1, class U2>
    00242     friend
    00243     bool operator!=(const SmartPtr<U1>& lhs, U2* raw_rhs);
    00244
    00247     template <class U1, class U2>
    00248     friend
    00249     bool operator!=(U1* lhs, const SmartPtr<U2>& raw_rhs);
    00251
    00264     template <class U>
    00265     friend
    00266     U* GetRawPtr(const SmartPtr<U>& smart_ptr);
    00267
    00269     template <class U>
    00270     friend
    00271     SmartPtr<const U> ConstPtr(const SmartPtr<U>& smart_ptr);
    00272
    00277     template <class U>
    00278     friend
    00279     bool IsValid(const SmartPtr<U>& smart_ptr);
    00280
    00285     template <class U>
    00286     friend
    00287     bool IsNull(const SmartPtr<U>& smart_ptr);
    00289
    00290   private:
    00294     T* ptr_;
    00295
    00299     SmartPtr<T>& SetFromRawPtr_(T* rhs);
    00300
    00304     SmartPtr<T>& SetFromSmartPtr_(const SmartPtr<T>& rhs);
    00305
    00307     void ReleasePointer_();
    00309   };
    00310
    00313   template <class U>
    00314   U* GetRawPtr(const SmartPtr<U>& smart_ptr);
    00315
    00316   template <class U>
    00317   SmartPtr<const U> ConstPtr(const SmartPtr<U>& smart_ptr);
    00318
    00319   template <class U>
    00320   bool IsNull(const SmartPtr<U>& smart_ptr);
    00321
    00322   template <class U>
    00323   bool IsValid(const SmartPtr<U>& smart_ptr);
    00324
    00325   template <class U1, class U2>
    00326   bool operator==(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs);
    00327
    00328   template <class U1, class U2>
    00329   bool operator==(const SmartPtr<U1>& lhs, U2* raw_rhs);
    00330
    00331   template <class U1, class U2>
    00332   bool operator==(U1* lhs, const SmartPtr<U2>& raw_rhs);
    00333
    00334   template <class U1, class U2>
    00335   bool operator!=(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs);
    00336
    00337   template <class U1, class U2>
    00338   bool operator!=(const SmartPtr<U1>& lhs, U2* raw_rhs);
    00339
    00340   template <class U1, class U2>
    00341   bool operator!=(U1* lhs, const SmartPtr<U2>& raw_rhs);
    00342
    00344
    00345
    00346   template <class T>
    00347   SmartPtr<T>::SmartPtr()
    00348       :
    00349       ptr_(NULL)
    00350   {
    00351 #ifdef IP_DEBUG_SMARTPTR
    00352     DBG_START_METH("SmartPtr<T>::SmartPtr()", dbg_smartptr_verbosity);
    00353 #endif
    00354
    00355 #ifdef CHECK_SMARTPTR
    00356
    00357     const ReferencedObject* trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_
    00358     = ptr_;
    00359     trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ = NULL;
    00360 #endif
    00361
    00362   }
    00363
    00364
    00365   template <class T>
    00366   SmartPtr<T>::SmartPtr(const SmartPtr<T>& copy)
    00367       :
    00368       ptr_(NULL)
    00369   {
    00370 #ifdef IP_DEBUG_SMARTPTR
    00371     DBG_START_METH("SmartPtr<T>::SmartPtr(const SmartPtr<T>& copy)", dbg_smartptr_verbosity);
    00372 #endif
    00373
    00374 #ifdef CHECK_SMARTPTR
    00375
    00376     const ReferencedObject* trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_
    00377     = ptr_;
    00378     trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ = NULL;
    00379 #endif
    00380
    00381     (void) SetFromSmartPtr_(copy);
    00382   }
    00383
    00384
    00385   /* Don't support this, use dynamic_cast(GetRawPtr(copy))
    00386   template <class T>
    00387   template <class U> SmartPtr<T>::SmartPtr(const SmartPtr<U>& copy)
    00388    :
    00389    ptr_(NULL)
    00390    {
    00391      DBG_START_METH("SmartPtr<T>::SmartPtr(const SmartPtr<U>& copy)", dbg_smartptr_verbosity);
    00392
    00393      U* raw_U_ptr = GetRawPtr(copy);
    00394
    00395      // try to cast to type T
    00396      T* raw_T_ptr = dynamic_cast<T*>(raw_U_ptr);
    00397
    00398      // Don't try to point to type U with a
    00399      // type T SmartPtr if the types U & T
    00400      // are not related
    00401      DBG_ASSERT(raw_T_ptr);
    00402
    00403      (void) SetFromRawPtr_(raw_T_ptr);
    00404    }
    00405    */
    00406
    00407
    00408   template <class T>
    00409   SmartPtr<T>::SmartPtr(T* ptr)
    00410       :
    00411       ptr_(NULL)
    00412   {
    00413 #ifdef IP_DEBUG_SMARTPTR
    00414     DBG_START_METH("SmartPtr<T>::SmartPtr(T* ptr)", dbg_smartptr_verbosity);
    00415 #endif
    00416
    00417 #ifdef CHECK_SMARTPTR
    00418
    00419     const ReferencedObject* trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_
    00420     = ptr_;
    00421     trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ = NULL;
    00422 #endif
    00423
    00424     (void) SetFromRawPtr_(ptr);
    00425   }
    00426
    00427   template <class T>
    00428   SmartPtr<T>::~SmartPtr()
    00429   {
    00430 #ifdef IP_DEBUG_SMARTPTR
    00431     DBG_START_METH("SmartPtr<T>::~SmartPtr(T* ptr)", dbg_smartptr_verbosity);
    00432 #endif
    00433
    00434     ReleasePointer_();
    00435   }
    00436
    00437
    00438   template <class T>
    00439   T* SmartPtr<T>::operator->() const
    00440   {
    00441 #ifdef IP_DEBUG_SMARTPTR
    00442     DBG_START_METH("T* SmartPtr<T>::operator->()", dbg_smartptr_verbosity);
    00443 #endif
    00444
    00445     // cannot deref a null pointer
    00446 #ifdef IP_DEBUG
    00447
    00448     assert(ptr_);
    00449 #endif
    00450
    00451     return ptr_;
    00452   }
    00453
    00454
    00455   template <class T>
    00456   T& SmartPtr<T>::operator*() const
    00457   {
    00458 #ifdef IP_DEBUG_SMARTPTR
    00459     DBG_START_METH("T& SmartPtr<T>::operator*()", dbg_smartptr_verbosity);
    00460 #endif
    00461
    00462     // cannot dereference a null pointer
    00463 #ifdef IP_DEBUG
    00464
    00465     assert(ptr_);
    00466 #endif
    00467
    00468     return *ptr_;
    00469   }
    00470
    00471
    00472   template <class T>
    00473   SmartPtr<T>& SmartPtr<T>::operator=(T* rhs)
    00474   {
    00475 #ifdef IP_DEBUG_SMARTPTR
    00476     DBG_START_METH("SmartPtr<T>& SmartPtr<T>::operator=(T* rhs)", dbg_smartptr_verbosity);
    00477 #endif
    00478
    00479     return SetFromRawPtr_(rhs);
    00480   }
    00481
    00482
    00483   template <class T>
    00484   SmartPtr<T>& SmartPtr<T>::operator=(const SmartPtr<T>& rhs)
    00485   {
    00486 #ifdef IP_DEBUG_SMARTPTR
    00487     DBG_START_METH(
    00488       "SmartPtr<T>& SmartPtr<T>::operator=(const SmartPtr<T>& rhs)",
    00489       dbg_smartptr_verbosity);
    00490 #endif
    00491
    00492     return SetFromSmartPtr_(rhs);
    00493   }
    00494
    00495
    00496   template <class T>
    00497   SmartPtr<T>& SmartPtr<T>::SetFromRawPtr_(T* rhs)
    00498   {
    00499 #ifdef IP_DEBUG_SMARTPTR
    00500     DBG_START_METH(
    00501       "SmartPtr<T>& SmartPtr<T>::SetFromRawPtr_(T* rhs)", dbg_smartptr_verbosity);
    00502 #endif
    00503
    00504     // Release any old pointer
    00505     ReleasePointer_();
    00506
    00507     if (rhs != NULL) {
    00508       rhs->AddRef(this);
    00509       ptr_ = rhs;
    00510       //       const ReferencedObject* r_ptr =
    00511       //         dynamic_cast<const ReferencedObject*>(rhs);
    00512
    00513       //       // All objects pointed to by a SmartPtr MUST
    00514       //       // inherit off of ReferencedObject
    00515       //       DBG_ASSERT(r_ptr && "This is not inherited from ReferencedObject");
    00516
    00517       //       if (r_ptr) {
    00518       //         r_ptr->AddRef(this);
    00519       //         ptr_ = rhs;
    00520       //       }
    00521     }
    00522
    00523     return *this;
    00524   }
    00525
    00526   template <class T>
    00527   SmartPtr<T>& SmartPtr<T>::SetFromSmartPtr_(const SmartPtr<T>& rhs)
    00528   {
    00529 #ifdef IP_DEBUG_SMARTPTR
    00530     DBG_START_METH(
    00531       "SmartPtr<T>& SmartPtr<T>::SetFromSmartPtr_(const SmartPtr<T>& rhs)",
    00532       dbg_smartptr_verbosity);
    00533 #endif
    00534
    00535     T* ptr = GetRawPtr(rhs);
    00536     /* AW: I changed this so that NULL is correctly copied from the
    00537        right hand side */
    00538     //     if (ptr != NULL) {
    00539     //       SetFromRawPtr_(ptr);
    00540     //     }
    00541     SetFromRawPtr_(ptr);
    00542
    00543     return (*this);
    00544   }
    00545
    00546
    00547   template <class T>
    00548   void SmartPtr<T>::ReleasePointer_()
    00549   {
    00550 #ifdef IP_DEBUG_SMARTPTR
    00551     DBG_START_METH(
    00552       "void SmartPtr<T>::ReleasePointer()",
    00553       dbg_smartptr_verbosity);
    00554 #endif
    00555
    00556     if (ptr_) {
    00557       ptr_->ReleaseRef(this);
    00558       if (ptr_->ReferenceCount() == 0) {
    00559         delete ptr_;
    00560       }
    00561       ptr_ = NULL;
    00562     }
    00563     //     if (ptr_ != NULL) {
    00564     //       const ReferencedObject* r_ptr =
    00565     //         dynamic_cast<const ReferencedObject*>(ptr_);
    00566
    00567     //       r_ptr->ReleaseRef(this);
    00568     //       if (r_ptr->ReferenceCount() == 0) {
    00569     //         delete ptr_;
    00570     //       }
    00571     //       ptr_ = NULL;
    00572     //     }
    00573   }
    00574
    00575
    00576   template <class U>
    00577   U* GetRawPtr(const SmartPtr<U>& smart_ptr)
    00578   {
    00579 #ifdef IP_DEBUG_SMARTPTR
    00580     DBG_START_FUN(
    00581       "T* GetRawPtr(const SmartPtr<T>& smart_ptr)",
    00582       0);
    00583 #endif
    00584
    00585     return smart_ptr.ptr_;
    00586   }
    00587
    00588   template <class U>
    00589   SmartPtr<const U> ConstPtr(const SmartPtr<U>& smart_ptr)
    00590   {
    00591     // compiler should implicitly cast
    00592     return GetRawPtr(smart_ptr);
    00593   }
    00594
    00595   template <class U>
    00596   bool IsValid(const SmartPtr<U>& smart_ptr)
    00597   {
    00598     return !IsNull(smart_ptr);
    00599   }
    00600
    00601   template <class U>
    00602   bool IsNull(const SmartPtr<U>& smart_ptr)
    00603   {
    00604 #ifdef IP_DEBUG_SMARTPTR
    00605     DBG_START_FUN(
    00606       "bool IsNull(const SmartPtr<T>& smart_ptr)",
    00607       0);
    00608 #endif
    00609
    00610     return (smart_ptr.ptr_ == NULL);
    00611   }
    00612
    00613
    00614   template <class U1, class U2>
    00615   bool ComparePointers(const U1* lhs, const U2* rhs)
    00616   {
    00617 #ifdef IP_DEBUG_SMARTPTR
    00618     DBG_START_FUN(
    00619       "bool ComparePtrs(const U1* lhs, const U2* rhs)",
    00620       dbg_smartptr_verbosity);
    00621 #endif
    00622
    00623     if (lhs == rhs) {
    00624       return true;
    00625     }
    00626
    00627     // Even if lhs and rhs point to the same object
    00628     // with different interfaces U1 and U2, we cannot guarantee that
    00629     // the value of the pointers will be equivalent. We can
    00630     // guarantee this if we convert to void*
    00631     const void* v_lhs = dynamic_cast<const void*>(lhs);
    00632     const void* v_rhs = dynamic_cast<const void*>(rhs);
    00633     if (v_lhs == v_rhs) {
    00634       return true;
    00635     }
    00636
    00637     // They must not be the same
    00638     return false;
    00639   }
    00640
    00641   template <class U1, class U2>
    00642   bool operator==(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs)
    00643   {
    00644 #ifdef IP_DEBUG_SMARTPTR
    00645     DBG_START_FUN(
    00646       "bool operator==(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs)",
    00647       dbg_smartptr_verbosity);
    00648 #endif
    00649
    00650     U1* raw_lhs = GetRawPtr(lhs);
    00651     U2* raw_rhs = GetRawPtr(rhs);
    00652     return ComparePointers(raw_lhs, raw_rhs);
    00653   }
    00654
    00655   template <class U1, class U2>
    00656   bool operator==(const SmartPtr<U1>& lhs, U2* raw_rhs)
    00657   {
    00658 #ifdef IP_DEBUG_SMARTPTR
    00659     DBG_START_FUN(
    00660       "bool operator==(SmartPtr<U1>& lhs, U2* rhs)",
    00661       dbg_smartptr_verbosity);
    00662 #endif
    00663
    00664     U1* raw_lhs = GetRawPtr(lhs);
    00665     return ComparePointers(raw_lhs, raw_rhs);
    00666   }
    00667
    00668   template <class U1, class U2>
    00669   bool operator==(U1* raw_lhs, const SmartPtr<U2>& rhs)
    00670   {
    00671 #ifdef IP_DEBUG_SMARTPTR
    00672     DBG_START_FUN(
    00673       "bool operator==(U1* raw_lhs, SmartPtr<U2>& rhs)",
    00674       dbg_smartptr_verbosity);
    00675 #endif
    00676
    00677     const U2* raw_rhs = GetRawPtr(rhs);
    00678     return ComparePointers(raw_lhs, raw_rhs);
    00679   }
    00680
    00681   template <class U1, class U2>
    00682   bool operator!=(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs)
    00683   {
    00684 #ifdef IP_DEBUG_SMARTPTR
    00685     DBG_START_FUN(
    00686       "bool operator!=(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs)",
    00687       dbg_smartptr_verbosity);
    00688 #endif
    00689
    00690     bool retValue = operator==(lhs, rhs);
    00691     return !retValue;
    00692   }
    00693
    00694   template <class U1, class U2>
    00695   bool operator!=(const SmartPtr<U1>& lhs, U2* raw_rhs)
    00696   {
    00697 #ifdef IP_DEBUG_SMARTPTR
    00698     DBG_START_FUN(
    00699       "bool operator!=(SmartPtr<U1>& lhs, U2* rhs)",
    00700       dbg_smartptr_verbosity);
    00701 #endif
    00702
    00703     bool retValue = operator==(lhs, raw_rhs);
    00704     return !retValue;
    00705   }
    00706
    00707   template <class U1, class U2>
    00708   bool operator!=(U1* raw_lhs, const SmartPtr<U2>& rhs)
    00709   {
    00710 #ifdef IP_DEBUG_SMARTPTR
    00711     DBG_START_FUN(
    00712       "bool operator!=(U1* raw_lhs, SmartPtr<U2>& rhs)",
    00713       dbg_smartptr_verbosity);
    00714 #endif
    00715
    00716     bool retValue = operator==(raw_lhs, rhs);
    00717     return !retValue;
    00718   }
    00719
    00720 } // namespace Ipopt
    00721
    00722 #endif
    00723