00001
00002
00003
00004
00005
00006
00007
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
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
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
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
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
00607
00608
00609
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 }
00731
00732 #undef ipopt_dbg_smartptr_verbosity
00733
00734 #endif