- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# /home/coin/SVN-release/Ipopt-3.7.1/Ipopt/src/Common/IpSmartPtr.hpp

Go to the documentation of this file.

    00001 // Copyright (C) 2004, 2007 International Business Machines and others.
    00002 // All Rights Reserved.
    00003 // This code is published under the Common Public License.
    00004 //
    00005 // $Id: IpSmartPtr.hpp 1019 2007-06-24 03:52:34Z 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 #include "IpDebug.hpp"
    00015 #if COIN_IPOPT_CHECKLEVEL > 2
    00016 # define IP_DEBUG_SMARTPTR
    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
    00179     SmartPtr(T* ptr);
    00180
    00184     ~SmartPtr();
    00186
    00191     T* operator->() const;
    00192
    00195     T& operator*() const;
    00196
    00199     SmartPtr<T>& operator=(T* rhs);
    00200
    00204     SmartPtr<T>& operator=(const SmartPtr<T>& rhs);
    00205
    00208     template <class U1, class U2>
    00209     friend
    00210     bool operator==(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs);
    00211
    00214     template <class U1, class U2>
    00215     friend
    00216     bool operator==(const SmartPtr<U1>& lhs, U2* raw_rhs);
    00217
    00220     template <class U1, class U2>
    00221     friend
    00222     bool operator==(U1* lhs, const SmartPtr<U2>& raw_rhs);
    00223
    00226     template <class U1, class U2>
    00227     friend
    00228     bool operator!=(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs);
    00229
    00232     template <class U1, class U2>
    00233     friend
    00234     bool operator!=(const SmartPtr<U1>& lhs, U2* raw_rhs);
    00235
    00238     template <class U1, class U2>
    00239     friend
    00240     bool operator!=(U1* lhs, const SmartPtr<U2>& raw_rhs);
    00242
    00255     template <class U>
    00256     friend
    00257     U* GetRawPtr(const SmartPtr<U>& smart_ptr);
    00258
    00260     template <class U>
    00261     friend
    00262     SmartPtr<const U> ConstPtr(const SmartPtr<U>& smart_ptr);
    00263
    00268     template <class U>
    00269     friend
    00270     bool IsValid(const SmartPtr<U>& smart_ptr);
    00271
    00276     template <class U>
    00277     friend
    00278     bool IsNull(const SmartPtr<U>& smart_ptr);
    00280
    00281   private:
    00285     T* ptr_;
    00286
    00290     SmartPtr<T>& SetFromRawPtr_(T* rhs);
    00291
    00295     SmartPtr<T>& SetFromSmartPtr_(const SmartPtr<T>& rhs);
    00296
    00298     void ReleasePointer_();
    00300   };
    00301
    00304   template <class U>
    00305   U* GetRawPtr(const SmartPtr<U>& smart_ptr);
    00306
    00307   template <class U>
    00308   SmartPtr<const U> ConstPtr(const SmartPtr<U>& smart_ptr);
    00309
    00310   template <class U>
    00311   bool IsNull(const SmartPtr<U>& smart_ptr);
    00312
    00313   template <class U>
    00314   bool IsValid(const SmartPtr<U>& smart_ptr);
    00315
    00316   template <class U1, class U2>
    00317   bool operator==(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs);
    00318
    00319   template <class U1, class U2>
    00320   bool operator==(const SmartPtr<U1>& lhs, U2* raw_rhs);
    00321
    00322   template <class U1, class U2>
    00323   bool operator==(U1* lhs, const SmartPtr<U2>& raw_rhs);
    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
    00335
    00336
    00337   template <class T>
    00338   SmartPtr<T>::SmartPtr()
    00339       :
    00340       ptr_(NULL)
    00341   {
    00342 #ifdef IP_DEBUG_SMARTPTR
    00343     DBG_START_METH("SmartPtr<T>::SmartPtr()", dbg_smartptr_verbosity);
    00344 #endif
    00345
    00346 #ifdef CHECK_SMARTPTR
    00347
    00348     const ReferencedObject* trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_
    00349     = ptr_;
    00350     trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ = NULL;
    00351 #endif
    00352
    00353   }
    00354
    00355
    00356   template <class T>
    00357   SmartPtr<T>::SmartPtr(const SmartPtr<T>& copy)
    00358       :
    00359       ptr_(NULL)
    00360   {
    00361 #ifdef IP_DEBUG_SMARTPTR
    00362     DBG_START_METH("SmartPtr<T>::SmartPtr(const SmartPtr<T>& copy)", dbg_smartptr_verbosity);
    00363 #endif
    00364
    00365 #ifdef CHECK_SMARTPTR
    00366
    00367     const ReferencedObject* trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_
    00368     = ptr_;
    00369     trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ = NULL;
    00370 #endif
    00371
    00372     (void) SetFromSmartPtr_(copy);
    00373   }
    00374
    00375
    00376   template <class T>
    00377   SmartPtr<T>::SmartPtr(T* ptr)
    00378       :
    00379       ptr_(NULL)
    00380   {
    00381 #ifdef IP_DEBUG_SMARTPTR
    00382     DBG_START_METH("SmartPtr<T>::SmartPtr(T* ptr)", dbg_smartptr_verbosity);
    00383 #endif
    00384
    00385 #ifdef CHECK_SMARTPTR
    00386
    00387     const ReferencedObject* trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_
    00388     = ptr_;
    00389     trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ = NULL;
    00390 #endif
    00391
    00392     (void) SetFromRawPtr_(ptr);
    00393   }
    00394
    00395   template <class T>
    00396   SmartPtr<T>::~SmartPtr()
    00397   {
    00398 #ifdef IP_DEBUG_SMARTPTR
    00399     DBG_START_METH("SmartPtr<T>::~SmartPtr(T* ptr)", dbg_smartptr_verbosity);
    00400 #endif
    00401
    00402     ReleasePointer_();
    00403   }
    00404
    00405
    00406   template <class T>
    00407   T* SmartPtr<T>::operator->() const
    00408   {
    00409 #ifdef IP_DEBUG_SMARTPTR
    00410     DBG_START_METH("T* SmartPtr<T>::operator->()", dbg_smartptr_verbosity);
    00411 #endif
    00412
    00413     // cannot deref a null pointer
    00414 #if COIN_IPOPT_CHECKLEVEL > 0
    00415
    00416     assert(ptr_);
    00417 #endif
    00418
    00419     return ptr_;
    00420   }
    00421
    00422
    00423   template <class T>
    00424   T& SmartPtr<T>::operator*() const
    00425   {
    00426 #ifdef IP_DEBUG_SMARTPTR
    00427     DBG_START_METH("T& SmartPtr<T>::operator*()", dbg_smartptr_verbosity);
    00428 #endif
    00429
    00430     // cannot dereference a null pointer
    00431 #if COIN_IPOPT_CHECKLEVEL > 0
    00432
    00433     assert(ptr_);
    00434 #endif
    00435
    00436     return *ptr_;
    00437   }
    00438
    00439
    00440   template <class T>
    00441   SmartPtr<T>& SmartPtr<T>::operator=(T* rhs)
    00442   {
    00443 #ifdef IP_DEBUG_SMARTPTR
    00444     DBG_START_METH("SmartPtr<T>& SmartPtr<T>::operator=(T* rhs)", dbg_smartptr_verbosity);
    00445 #endif
    00446
    00447     return SetFromRawPtr_(rhs);
    00448   }
    00449
    00450
    00451   template <class T>
    00452   SmartPtr<T>& SmartPtr<T>::operator=(const SmartPtr<T>& rhs)
    00453   {
    00454 #ifdef IP_DEBUG_SMARTPTR
    00455     DBG_START_METH(
    00456       "SmartPtr<T>& SmartPtr<T>::operator=(const SmartPtr<T>& rhs)",
    00457       dbg_smartptr_verbosity);
    00458 #endif
    00459
    00460     return SetFromSmartPtr_(rhs);
    00461   }
    00462
    00463
    00464   template <class T>
    00465   SmartPtr<T>& SmartPtr<T>::SetFromRawPtr_(T* rhs)
    00466   {
    00467 #ifdef IP_DEBUG_SMARTPTR
    00468     DBG_START_METH(
    00469       "SmartPtr<T>& SmartPtr<T>::SetFromRawPtr_(T* rhs)", dbg_smartptr_verbosity);
    00470 #endif
    00471
    00472     // Release any old pointer
    00473     ReleasePointer_();
    00474
    00475     if (rhs != NULL) {
    00476       rhs->AddRef(this);
    00477       ptr_ = rhs;
    00478     }
    00479
    00480     return *this;
    00481   }
    00482
    00483   template <class T>
    00484   SmartPtr<T>& SmartPtr<T>::SetFromSmartPtr_(const SmartPtr<T>& rhs)
    00485   {
    00486 #ifdef IP_DEBUG_SMARTPTR
    00487     DBG_START_METH(
    00488       "SmartPtr<T>& SmartPtr<T>::SetFromSmartPtr_(const SmartPtr<T>& rhs)",
    00489       dbg_smartptr_verbosity);
    00490 #endif
    00491
    00492     T* ptr = GetRawPtr(rhs);
    00493     /* AW: I changed this so that NULL is correctly copied from the
    00494        right hand side */
    00495     //     if (ptr != NULL) {
    00496     //       SetFromRawPtr_(ptr);
    00497     //     }
    00498     SetFromRawPtr_(ptr);
    00499
    00500     return (*this);
    00501   }
    00502
    00503
    00504   template <class T>
    00505   void SmartPtr<T>::ReleasePointer_()
    00506   {
    00507 #ifdef IP_DEBUG_SMARTPTR
    00508     DBG_START_METH(
    00509       "void SmartPtr<T>::ReleasePointer()",
    00510       dbg_smartptr_verbosity);
    00511 #endif
    00512
    00513     if (ptr_) {
    00514       ptr_->ReleaseRef(this);
    00515       if (ptr_->ReferenceCount() == 0) {
    00516         delete ptr_;
    00517       }
    00518       ptr_ = NULL;
    00519     }
    00520   }
    00521
    00522
    00523   template <class U>
    00524   U* GetRawPtr(const SmartPtr<U>& smart_ptr)
    00525   {
    00526 #ifdef IP_DEBUG_SMARTPTR
    00527     DBG_START_FUN(
    00528       "T* GetRawPtr(const SmartPtr<T>& smart_ptr)",
    00529       0);
    00530 #endif
    00531
    00532     return smart_ptr.ptr_;
    00533   }
    00534
    00535   template <class U>
    00536   SmartPtr<const U> ConstPtr(const SmartPtr<U>& smart_ptr)
    00537   {
    00538     // compiler should implicitly cast
    00539     return GetRawPtr(smart_ptr);
    00540   }
    00541
    00542   template <class U>
    00543   bool IsValid(const SmartPtr<U>& smart_ptr)
    00544   {
    00545     return !IsNull(smart_ptr);
    00546   }
    00547
    00548   template <class U>
    00549   bool IsNull(const SmartPtr<U>& smart_ptr)
    00550   {
    00551 #ifdef IP_DEBUG_SMARTPTR
    00552     DBG_START_FUN(
    00553       "bool IsNull(const SmartPtr<T>& smart_ptr)",
    00554       0);
    00555 #endif
    00556
    00557     return (smart_ptr.ptr_ == NULL);
    00558   }
    00559
    00560
    00561   template <class U1, class U2>
    00562   bool ComparePointers(const U1* lhs, const U2* rhs)
    00563   {
    00564 #ifdef IP_DEBUG_SMARTPTR
    00565     DBG_START_FUN(
    00566       "bool ComparePtrs(const U1* lhs, const U2* rhs)",
    00567       dbg_smartptr_verbosity);
    00568 #endif
    00569
    00570     if (lhs == rhs) {
    00571       return true;
    00572     }
    00573
    00574     // Even if lhs and rhs point to the same object
    00575     // with different interfaces U1 and U2, we cannot guarantee that
    00576     // the value of the pointers will be equivalent. We can
    00577     // guarantee this if we convert to void*
    00578     const void* v_lhs = static_cast<const void*>(lhs);
    00579     const void* v_rhs = static_cast<const void*>(rhs);
    00580     if (v_lhs == v_rhs) {
    00581       return true;
    00582     }
    00583
    00584     // They must not be the same
    00585     return false;
    00586   }
    00587
    00588   template <class U1, class U2>
    00589   bool operator==(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs)
    00590   {
    00591 #ifdef IP_DEBUG_SMARTPTR
    00592     DBG_START_FUN(
    00593       "bool operator==(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs)",
    00594       dbg_smartptr_verbosity);
    00595 #endif
    00596
    00597     U1* raw_lhs = GetRawPtr(lhs);
    00598     U2* raw_rhs = GetRawPtr(rhs);
    00599     return ComparePointers(raw_lhs, raw_rhs);
    00600   }
    00601
    00602   template <class U1, class U2>
    00603   bool operator==(const SmartPtr<U1>& lhs, U2* raw_rhs)
    00604   {
    00605 #ifdef IP_DEBUG_SMARTPTR
    00606     DBG_START_FUN(
    00607       "bool operator==(SmartPtr<U1>& lhs, U2* rhs)",
    00608       dbg_smartptr_verbosity);
    00609 #endif
    00610
    00611     U1* raw_lhs = GetRawPtr(lhs);
    00612     return ComparePointers(raw_lhs, raw_rhs);
    00613   }
    00614
    00615   template <class U1, class U2>
    00616   bool operator==(U1* raw_lhs, const SmartPtr<U2>& rhs)
    00617   {
    00618 #ifdef IP_DEBUG_SMARTPTR
    00619     DBG_START_FUN(
    00620       "bool operator==(U1* raw_lhs, SmartPtr<U2>& rhs)",
    00621       dbg_smartptr_verbosity);
    00622 #endif
    00623
    00624     const U2* raw_rhs = GetRawPtr(rhs);
    00625     return ComparePointers(raw_lhs, raw_rhs);
    00626   }
    00627
    00628   template <class U1, class U2>
    00629   bool operator!=(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs)
    00630   {
    00631 #ifdef IP_DEBUG_SMARTPTR
    00632     DBG_START_FUN(
    00633       "bool operator!=(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs)",
    00634       dbg_smartptr_verbosity);
    00635 #endif
    00636
    00637     bool retValue = operator==(lhs, rhs);
    00638     return !retValue;
    00639   }
    00640
    00641   template <class U1, class U2>
    00642   bool operator!=(const SmartPtr<U1>& lhs, U2* raw_rhs)
    00643   {
    00644 #ifdef IP_DEBUG_SMARTPTR
    00645     DBG_START_FUN(
    00646       "bool operator!=(SmartPtr<U1>& lhs, U2* rhs)",
    00647       dbg_smartptr_verbosity);
    00648 #endif
    00649
    00650     bool retValue = operator==(lhs, raw_rhs);
    00651     return !retValue;
    00652   }
    00653
    00654   template <class U1, class U2>
    00655   bool operator!=(U1* raw_lhs, const SmartPtr<U2>& rhs)
    00656   {
    00657 #ifdef IP_DEBUG_SMARTPTR
    00658     DBG_START_FUN(
    00659       "bool operator!=(U1* raw_lhs, SmartPtr<U2>& rhs)",
    00660       dbg_smartptr_verbosity);
    00661 #endif
    00662
    00663     bool retValue = operator==(raw_lhs, rhs);
    00664     return !retValue;
    00665   }
    00666
    00667 } // namespace Ipopt
    00668
    00669 #endif
    00670