/home/coin/SVN-release/CoinAll-1.1.0/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 

Generated on Sun Nov 14 14:06:35 2010 for Coin-All by  doxygen 1.4.7