- Main Page
- Classes
- Files

- File List
- File Members

# src/Common/IpSmartPtr.hpp

Go to the documentation of this file.

    00001 // Copyright (C) 2004, 2011 International Business Machines and others.
    00002 // All Rights Reserved.
    00003 // This code is published under the Eclipse Public License.
    00004 //
    00005 // $Id: IpSmartPtr.hpp 2182 2013-03-30 20:02:18Z stefan $
    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 #ifndef IPOPT_UNUSED
    00019 # if defined(__GNUC__)
    00020 #   define IPOPT_UNUSED __attribute__((unused))
    00021 # else
    00022 #   define IPOPT_UNUSED
    00023 # endif
    00024 #endif
    00025
    00026 namespace Ipopt
    00027 {
    00028
    00171   template<class T>
    00172   class SmartPtr : public Referencer
    00173   {
    00174   public:
    00175 #define ipopt_dbg_smartptr_verbosity 0
    00176
    00180     SmartPtr();
    00181
    00183     SmartPtr(const SmartPtr<T>& copy);
    00184
    00186     template <class U>
    00187     SmartPtr(const SmartPtr<U>& copy);
    00188
    00190     SmartPtr(T* ptr);
    00191
    00195     ~SmartPtr();
    00197
    00202     T* operator->() const;
    00203
    00206     T& operator*() const;
    00207
    00210     SmartPtr<T>& operator=(T* rhs);
    00211
    00215     SmartPtr<T>& operator=(const SmartPtr<T>& rhs);
    00216
    00220     template <class U>
    00221     SmartPtr<T>& operator=(const SmartPtr<U>& rhs);
    00222
    00225     template <class U1, class U2>
    00226     friend
    00227     bool operator==(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs);
    00228
    00231     template <class U1, class U2>
    00232     friend
    00233     bool operator==(const SmartPtr<U1>& lhs, U2* raw_rhs);
    00234
    00237     template <class U1, class U2>
    00238     friend
    00239     bool operator==(U1* lhs, const SmartPtr<U2>& raw_rhs);
    00240
    00243     template <class U1, class U2>
    00244     friend
    00245     bool operator!=(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs);
    00246
    00249     template <class U1, class U2>
    00250     friend
    00251     bool operator!=(const SmartPtr<U1>& lhs, U2* raw_rhs);
    00252
    00255     template <class U1, class U2>
    00256     friend
    00257     bool operator!=(U1* lhs, const SmartPtr<U2>& raw_rhs);
    00258
    00261     template <class U>
    00262     friend
    00263     bool operator<(const SmartPtr<U>& lhs, const SmartPtr<U>& rhs);
    00265
    00278     template <class U>
    00279     friend
    00280     U* GetRawPtr(const SmartPtr<U>& smart_ptr);
    00281
    00283     template <class U>
    00284     friend
    00285     SmartPtr<const U> ConstPtr(const SmartPtr<U>& smart_ptr);
    00286
    00291     template <class U>
    00292     friend
    00293     bool IsValid(const SmartPtr<U>& smart_ptr);
    00294
    00299     template <class U>
    00300     friend
    00301     bool IsNull(const SmartPtr<U>& smart_ptr);
    00303
    00304   private:
    00308     T* ptr_;
    00309
    00313     SmartPtr<T>& SetFromRawPtr_(T* rhs);
    00314
    00318     SmartPtr<T>& SetFromSmartPtr_(const SmartPtr<T>& rhs);
    00319
    00321     void ReleasePointer_();
    00323   };
    00324
    00327   template <class U>
    00328   U* GetRawPtr(const SmartPtr<U>& smart_ptr);
    00329
    00330   template <class U>
    00331   SmartPtr<const U> ConstPtr(const SmartPtr<U>& smart_ptr);
    00332
    00333   template <class U>
    00334   bool IsNull(const SmartPtr<U>& smart_ptr);
    00335
    00336   template <class U>
    00337   bool IsValid(const SmartPtr<U>& smart_ptr);
    00338
    00339   template <class U1, class U2>
    00340   bool operator==(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs);
    00341
    00342   template <class U1, class U2>
    00343   bool operator==(const SmartPtr<U1>& lhs, U2* raw_rhs);
    00344
    00345   template <class U1, class U2>
    00346   bool operator==(U1* lhs, const SmartPtr<U2>& raw_rhs);
    00347
    00348   template <class U1, class U2>
    00349   bool operator!=(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs);
    00350
    00351   template <class U1, class U2>
    00352   bool operator!=(const SmartPtr<U1>& lhs, U2* raw_rhs);
    00353
    00354   template <class U1, class U2>
    00355   bool operator!=(U1* lhs, const SmartPtr<U2>& raw_rhs);
    00356
    00358
    00359
    00360   template <class T>
    00361   SmartPtr<T>::SmartPtr()
    00362       :
    00363       ptr_(0)
    00364   {
    00365 #ifdef IP_DEBUG_SMARTPTR
    00366     DBG_START_METH("SmartPtr<T>::SmartPtr()", ipopt_dbg_smartptr_verbosity);
    00367 #endif
    00368
    00369 #ifndef NDEBUG
    00370     const ReferencedObject* IPOPT_UNUSED trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ = ptr_;
    00371 #endif
    00372
    00373   }
    00374
    00375
    00376   template <class T>
    00377   SmartPtr<T>::SmartPtr(const SmartPtr<T>& copy)
    00378       :
    00379       ptr_(0)
    00380   {
    00381 #ifdef IP_DEBUG_SMARTPTR
    00382     DBG_START_METH("SmartPtr<T>::SmartPtr(const SmartPtr<T>& copy)", ipopt_dbg_smartptr_verbosity);
    00383 #endif
    00384
    00385 #ifndef NDEBUG
    00386     const ReferencedObject* IPOPT_UNUSED trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ = ptr_;
    00387 #endif
    00388
    00389     (void) SetFromSmartPtr_(copy);
    00390   }
    00391
    00392
    00393   template <class T>
    00394   template <class U>
    00395   SmartPtr<T>::SmartPtr(const SmartPtr<U>& copy)
    00396       :
    00397       ptr_(0)
    00398   {
    00399 #ifdef IP_DEBUG_SMARTPTR
    00400     DBG_START_METH("SmartPtr<T>::SmartPtr(const SmartPtr<U>& copy)", ipopt_dbg_smartptr_verbosity);
    00401 #endif
    00402
    00403 #ifndef NDEBUG
    00404     const ReferencedObject* IPOPT_UNUSED trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ = ptr_;
    00405 #endif
    00406
    00407     (void) SetFromSmartPtr_(GetRawPtr(copy));
    00408   }
    00409
    00410
    00411   template <class T>
    00412   SmartPtr<T>::SmartPtr(T* ptr)
    00413       :
    00414       ptr_(0)
    00415   {
    00416 #ifdef IP_DEBUG_SMARTPTR
    00417     DBG_START_METH("SmartPtr<T>::SmartPtr(T* ptr)", ipopt_dbg_smartptr_verbosity);
    00418 #endif
    00419
    00420 #ifndef NDEBUG
    00421     const ReferencedObject* IPOPT_UNUSED trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ = ptr_;
    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)", ipopt_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->()", ipopt_dbg_smartptr_verbosity);
    00443 #endif
    00444
    00445     // cannot deref a null pointer
    00446 #if COIN_IPOPT_CHECKLEVEL > 0
    00447     assert(ptr_);
    00448 #endif
    00449
    00450     return ptr_;
    00451   }
    00452
    00453
    00454   template <class T>
    00455   T& SmartPtr<T>::operator*() const
    00456   {
    00457 #ifdef IP_DEBUG_SMARTPTR
    00458     DBG_START_METH("T& SmartPtr<T>::operator*()", ipopt_dbg_smartptr_verbosity);
    00459 #endif
    00460
    00461     // cannot dereference a null pointer
    00462 #if COIN_IPOPT_CHECKLEVEL > 0
    00463     assert(ptr_);
    00464 #endif
    00465
    00466     return *ptr_;
    00467   }
    00468
    00469
    00470   template <class T>
    00471   SmartPtr<T>& SmartPtr<T>::operator=(T* rhs)
    00472   {
    00473 #ifdef IP_DEBUG_SMARTPTR
    00474     DBG_START_METH("SmartPtr<T>& SmartPtr<T>::operator=(T* rhs)", ipopt_dbg_smartptr_verbosity);
    00475 #endif
    00476
    00477     return SetFromRawPtr_(rhs);
    00478   }
    00479
    00480
    00481   template <class T>
    00482   SmartPtr<T>& SmartPtr<T>::operator=(const SmartPtr<T>& rhs)
    00483   {
    00484 #ifdef IP_DEBUG_SMARTPTR
    00485     DBG_START_METH(
    00486       "SmartPtr<T>& SmartPtr<T>::operator=(const SmartPtr<T>& rhs)",
    00487       ipopt_dbg_smartptr_verbosity);
    00488 #endif
    00489
    00490     return SetFromSmartPtr_(rhs);
    00491   }
    00492
    00493
    00494   template <class T>
    00495   template <class U>
    00496   SmartPtr<T>& SmartPtr<T>::operator=(const SmartPtr<U>& rhs)
    00497   {
    00498 #ifdef IP_DEBUG_SMARTPTR
    00499     DBG_START_METH(
    00500       "SmartPtr<T>& SmartPtr<T>::operator=(const SmartPtr<U>& rhs)",
    00501       ipopt_dbg_smartptr_verbosity);
    00502 #endif
    00503
    00504     return SetFromSmartPtr_(GetRawPtr(rhs));
    00505   }
    00506
    00507
    00508   template <class T>
    00509   SmartPtr<T>& SmartPtr<T>::SetFromRawPtr_(T* rhs)
    00510   {
    00511 #ifdef IP_DEBUG_SMARTPTR
    00512     DBG_START_METH(
    00513       "SmartPtr<T>& SmartPtr<T>::SetFromRawPtr_(T* rhs)", ipopt_dbg_smartptr_verbosity);
    00514 #endif
    00515
    00516     if (rhs != 0)
    00517       rhs->AddRef(this);
    00518
    00519     // Release any old pointer
    00520     ReleasePointer_();
    00521
    00522     ptr_ = rhs;
    00523
    00524     return *this;
    00525   }
    00526
    00527   template <class T>
    00528   SmartPtr<T>& SmartPtr<T>::SetFromSmartPtr_(const SmartPtr<T>& rhs)
    00529   {
    00530 #ifdef IP_DEBUG_SMARTPTR
    00531     DBG_START_METH(
    00532       "SmartPtr<T>& SmartPtr<T>::SetFromSmartPtr_(const SmartPtr<T>& rhs)",
    00533       ipopt_dbg_smartptr_verbosity);
    00534 #endif
    00535
    00536     SetFromRawPtr_(GetRawPtr(rhs));
    00537
    00538     return (*this);
    00539   }
    00540
    00541
    00542   template <class T>
    00543   void SmartPtr<T>::ReleasePointer_()
    00544   {
    00545 #ifdef IP_DEBUG_SMARTPTR
    00546     DBG_START_METH(
    00547       "void SmartPtr<T>::ReleasePointer()",
    00548       ipopt_dbg_smartptr_verbosity);
    00549 #endif
    00550
    00551     if (ptr_) {
    00552       ptr_->ReleaseRef(this);
    00553       if (ptr_->ReferenceCount() == 0)
    00554         delete ptr_;
    00555     }
    00556   }
    00557
    00558
    00559   template <class U>
    00560   U* GetRawPtr(const SmartPtr<U>& smart_ptr)
    00561   {
    00562 #ifdef IP_DEBUG_SMARTPTR
    00563     DBG_START_FUN(
    00564       "T* GetRawPtr(const SmartPtr<T>& smart_ptr)",
    00565       0);
    00566 #endif
    00567
    00568     return smart_ptr.ptr_;
    00569   }
    00570
    00571   template <class U>
    00572   SmartPtr<const U> ConstPtr(const SmartPtr<U>& smart_ptr)
    00573   {
    00574     // compiler should implicitly cast
    00575     return GetRawPtr(smart_ptr);
    00576   }
    00577
    00578   template <class U>
    00579   bool IsValid(const SmartPtr<U>& smart_ptr)
    00580   {
    00581     return !IsNull(smart_ptr);
    00582   }
    00583
    00584   template <class U>
    00585   bool IsNull(const SmartPtr<U>& smart_ptr)
    00586   {
    00587 #ifdef IP_DEBUG_SMARTPTR
    00588     DBG_START_FUN(
    00589       "bool IsNull(const SmartPtr<T>& smart_ptr)",
    00590       0);
    00591 #endif
    00592
    00593     return (smart_ptr.ptr_ == 0);
    00594   }
    00595
    00596
    00597   template <class U1, class U2>
    00598   bool ComparePointers(const U1* lhs, const U2* rhs)
    00599   {
    00600 #ifdef IP_DEBUG_SMARTPTR
    00601     DBG_START_FUN(
    00602       "bool ComparePtrs(const U1* lhs, const U2* rhs)",
    00603       ipopt_dbg_smartptr_verbosity);
    00604 #endif
    00605
    00606     // Even if lhs and rhs point to the same object
    00607     // with different interfaces U1 and U2, we cannot guarantee that
    00608     // the value of the pointers will be equivalent. We can
    00609     // guarantee this if we convert to ReferencedObject* (see also #162)
    00610     const ReferencedObject* v_lhs = lhs;
    00611     const ReferencedObject* v_rhs = rhs;
    00612
    00613     return v_lhs == v_rhs;
    00614   }
    00615
    00616   template <class U1, class U2>
    00617   bool operator==(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs)
    00618   {
    00619 #ifdef IP_DEBUG_SMARTPTR
    00620     DBG_START_FUN(
    00621       "bool operator==(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs)",
    00622       ipopt_dbg_smartptr_verbosity);
    00623 #endif
    00624
    00625     U1* raw_lhs = GetRawPtr(lhs);
    00626     U2* raw_rhs = GetRawPtr(rhs);
    00627     return ComparePointers(raw_lhs, raw_rhs);
    00628   }
    00629
    00630   template <class U1, class U2>
    00631   bool operator==(const SmartPtr<U1>& lhs, U2* raw_rhs)
    00632   {
    00633 #ifdef IP_DEBUG_SMARTPTR
    00634     DBG_START_FUN(
    00635       "bool operator==(SmartPtr<U1>& lhs, U2* rhs)",
    00636       ipopt_dbg_smartptr_verbosity);
    00637 #endif
    00638
    00639     U1* raw_lhs = GetRawPtr(lhs);
    00640     return ComparePointers(raw_lhs, raw_rhs);
    00641   }
    00642
    00643   template <class U1, class U2>
    00644   bool operator==(U1* raw_lhs, const SmartPtr<U2>& rhs)
    00645   {
    00646 #ifdef IP_DEBUG_SMARTPTR
    00647     DBG_START_FUN(
    00648       "bool operator==(U1* raw_lhs, SmartPtr<U2>& rhs)",
    00649       ipopt_dbg_smartptr_verbosity);
    00650 #endif
    00651
    00652     const U2* raw_rhs = GetRawPtr(rhs);
    00653     return ComparePointers(raw_lhs, raw_rhs);
    00654   }
    00655
    00656   template <class U1, class U2>
    00657   bool operator!=(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs)
    00658   {
    00659 #ifdef IP_DEBUG_SMARTPTR
    00660     DBG_START_FUN(
    00661       "bool operator!=(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs)",
    00662       ipopt_dbg_smartptr_verbosity);
    00663 #endif
    00664
    00665     bool retValue = operator==(lhs, rhs);
    00666     return !retValue;
    00667   }
    00668
    00669   template <class U1, class U2>
    00670   bool operator!=(const SmartPtr<U1>& lhs, U2* raw_rhs)
    00671   {
    00672 #ifdef IP_DEBUG_SMARTPTR
    00673     DBG_START_FUN(
    00674       "bool operator!=(SmartPtr<U1>& lhs, U2* rhs)",
    00675       ipopt_dbg_smartptr_verbosity);
    00676 #endif
    00677
    00678     bool retValue = operator==(lhs, raw_rhs);
    00679     return !retValue;
    00680   }
    00681
    00682   template <class U1, class U2>
    00683   bool operator!=(U1* raw_lhs, const SmartPtr<U2>& rhs)
    00684   {
    00685 #ifdef IP_DEBUG_SMARTPTR
    00686     DBG_START_FUN(
    00687       "bool operator!=(U1* raw_lhs, SmartPtr<U2>& rhs)",
    00688       ipopt_dbg_smartptr_verbosity);
    00689 #endif
    00690
    00691     bool retValue = operator==(raw_lhs, rhs);
    00692     return !retValue;
    00693   }
    00694
    00695   template <class T>
    00696   void swap(SmartPtr<T>& a, SmartPtr<T>& b)
    00697   {
    00698 #ifdef IP_DEBUG_REFERENCED
    00699     SmartPtr<T> tmp(a);
    00700     a = b;
    00701     b = tmp;
    00702 #else
    00703     std::swap(a.prt_, b.ptr_);
    00704 #endif
    00705   }
    00706
    00707   template <class T>
    00708   bool operator<(const SmartPtr<T>& lhs, const SmartPtr<T>& rhs)
    00709   {
    00710     return lhs.ptr_ < rhs.ptr_;
    00711   }
    00712
    00713   template <class T>
    00714   bool operator> (const SmartPtr<T>& lhs, const SmartPtr<T>& rhs)
    00715   {
    00716     return rhs < lhs;
    00717   }
    00718
    00719   template <class T> bool
    00720   operator<=(const SmartPtr<T>& lhs, const SmartPtr<T>& rhs)
    00721   {
    00722     return !( rhs < lhs );
    00723   }
    00724
    00725   template <class T> bool
    00726   operator>=(const SmartPtr<T>& lhs, const SmartPtr<T>& rhs)
    00727   {
    00728     return !( lhs < rhs );
    00729   }
    00730 } // namespace Ipopt
    00731
    00732 #undef ipopt_dbg_smartptr_verbosity
    00733
    00734 #endif

All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines