00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef __IPSMARTPTR_HPP__
00010 #define __IPSMARTPTR_HPP__
00011
00012 #include "IpReferenced.hpp"
00013
00014
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
00183
00184
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
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
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
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
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
00505 ReleasePointer_();
00506
00507 if (rhs != NULL) {
00508 rhs->AddRef(this);
00509 ptr_ = rhs;
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
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
00537
00538
00539
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
00564
00565
00566
00567
00568
00569
00570
00571
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
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
00628
00629
00630
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
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 }
00721
00722 #endif
00723