00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef __IPSMARTPTR_HPP__
00010 #define __IPSMARTPTR_HPP__
00011
00012 #ifdef HAVE_CSTDDEF
00013 # include <cstddef>
00014 #else
00015 # ifdef HAVE_STDDEF_H
00016 # include <stddef.h>
00017 # else
00018 # error "don't have header file for stddef"
00019 # endif
00020 #endif
00021
00022 #include "IpReferenced.hpp"
00023
00024 #include "IpDebug.hpp"
00025 #if COIN_IPOPT_CHECKLEVEL > 2
00026 # define IP_DEBUG_SMARTPTR
00027 #endif
00028
00029 namespace Ipopt
00030 {
00031
00174 template<class T>
00175 class SmartPtr : public Referencer
00176 {
00177 public:
00178 #define dbg_smartptr_verbosity 0
00179
00183 SmartPtr();
00184
00186 SmartPtr(const SmartPtr<T>& copy);
00187
00189 SmartPtr(T* ptr);
00190
00194 ~SmartPtr();
00196
00201 T* operator->() const;
00202
00205 T& operator*() const;
00206
00209 SmartPtr<T>& operator=(T* rhs);
00210
00214 SmartPtr<T>& operator=(const SmartPtr<T>& rhs);
00215
00218 template <class U1, class U2>
00219 friend
00220 bool operator==(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs);
00221
00224 template <class U1, class U2>
00225 friend
00226 bool operator==(const SmartPtr<U1>& lhs, U2* raw_rhs);
00227
00230 template <class U1, class U2>
00231 friend
00232 bool operator==(U1* lhs, const SmartPtr<U2>& raw_rhs);
00233
00236 template <class U1, class U2>
00237 friend
00238 bool operator!=(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs);
00239
00242 template <class U1, class U2>
00243 friend
00244 bool operator!=(const SmartPtr<U1>& lhs, U2* raw_rhs);
00245
00248 template <class U1, class U2>
00249 friend
00250 bool operator!=(U1* lhs, const SmartPtr<U2>& raw_rhs);
00252
00265 template <class U>
00266 friend
00267 U* GetRawPtr(const SmartPtr<U>& smart_ptr);
00268
00270 template <class U>
00271 friend
00272 SmartPtr<const U> ConstPtr(const SmartPtr<U>& smart_ptr);
00273
00278 template <class U>
00279 friend
00280 bool IsValid(const SmartPtr<U>& smart_ptr);
00281
00286 template <class U>
00287 friend
00288 bool IsNull(const SmartPtr<U>& smart_ptr);
00290
00291 private:
00295 T* ptr_;
00296
00300 SmartPtr<T>& SetFromRawPtr_(T* rhs);
00301
00305 SmartPtr<T>& SetFromSmartPtr_(const SmartPtr<T>& rhs);
00306
00308 void ReleasePointer_();
00310 };
00311
00314 template <class U>
00315 U* GetRawPtr(const SmartPtr<U>& smart_ptr);
00316
00317 template <class U>
00318 SmartPtr<const U> ConstPtr(const SmartPtr<U>& smart_ptr);
00319
00320 template <class U>
00321 bool IsNull(const SmartPtr<U>& smart_ptr);
00322
00323 template <class U>
00324 bool IsValid(const SmartPtr<U>& smart_ptr);
00325
00326 template <class U1, class U2>
00327 bool operator==(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs);
00328
00329 template <class U1, class U2>
00330 bool operator==(const SmartPtr<U1>& lhs, U2* raw_rhs);
00331
00332 template <class U1, class U2>
00333 bool operator==(U1* lhs, const SmartPtr<U2>& raw_rhs);
00334
00335 template <class U1, class U2>
00336 bool operator!=(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs);
00337
00338 template <class U1, class U2>
00339 bool operator!=(const SmartPtr<U1>& lhs, U2* raw_rhs);
00340
00341 template <class U1, class U2>
00342 bool operator!=(U1* lhs, const SmartPtr<U2>& raw_rhs);
00343
00345
00346
00347 template <class T>
00348 SmartPtr<T>::SmartPtr()
00349 :
00350 ptr_(0)
00351 {
00352 #ifdef IP_DEBUG_SMARTPTR
00353 DBG_START_METH("SmartPtr<T>::SmartPtr()", dbg_smartptr_verbosity);
00354 #endif
00355
00356 #ifdef CHECK_SMARTPTR
00357
00358 const ReferencedObject* trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_
00359 = ptr_;
00360 trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ = 0;
00361 #endif
00362
00363 }
00364
00365
00366 template <class T>
00367 SmartPtr<T>::SmartPtr(const SmartPtr<T>& copy)
00368 :
00369 ptr_(0)
00370 {
00371 #ifdef IP_DEBUG_SMARTPTR
00372 DBG_START_METH("SmartPtr<T>::SmartPtr(const SmartPtr<T>& copy)", dbg_smartptr_verbosity);
00373 #endif
00374
00375 #ifdef CHECK_SMARTPTR
00376
00377 const ReferencedObject* trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_
00378 = ptr_;
00379 trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ = 0;
00380 #endif
00381
00382 (void) SetFromSmartPtr_(copy);
00383 }
00384
00385
00386 template <class T>
00387 SmartPtr<T>::SmartPtr(T* ptr)
00388 :
00389 ptr_(0)
00390 {
00391 #ifdef IP_DEBUG_SMARTPTR
00392 DBG_START_METH("SmartPtr<T>::SmartPtr(T* ptr)", dbg_smartptr_verbosity);
00393 #endif
00394
00395 #ifdef CHECK_SMARTPTR
00396
00397 const ReferencedObject* trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_
00398 = ptr_;
00399 trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ = 0;
00400 #endif
00401
00402 (void) SetFromRawPtr_(ptr);
00403 }
00404
00405 template <class T>
00406 SmartPtr<T>::~SmartPtr()
00407 {
00408 #ifdef IP_DEBUG_SMARTPTR
00409 DBG_START_METH("SmartPtr<T>::~SmartPtr(T* ptr)", dbg_smartptr_verbosity);
00410 #endif
00411
00412 ReleasePointer_();
00413 }
00414
00415
00416 template <class T>
00417 T* SmartPtr<T>::operator->() const
00418 {
00419 #ifdef IP_DEBUG_SMARTPTR
00420 DBG_START_METH("T* SmartPtr<T>::operator->()", dbg_smartptr_verbosity);
00421 #endif
00422
00423
00424 #if COIN_IPOPT_CHECKLEVEL > 0
00425
00426 assert(ptr_);
00427 #endif
00428
00429 return ptr_;
00430 }
00431
00432
00433 template <class T>
00434 T& SmartPtr<T>::operator*() const
00435 {
00436 #ifdef IP_DEBUG_SMARTPTR
00437 DBG_START_METH("T& SmartPtr<T>::operator*()", dbg_smartptr_verbosity);
00438 #endif
00439
00440
00441 #if COIN_IPOPT_CHECKLEVEL > 0
00442
00443 assert(ptr_);
00444 #endif
00445
00446 return *ptr_;
00447 }
00448
00449
00450 template <class T>
00451 SmartPtr<T>& SmartPtr<T>::operator=(T* rhs)
00452 {
00453 #ifdef IP_DEBUG_SMARTPTR
00454 DBG_START_METH("SmartPtr<T>& SmartPtr<T>::operator=(T* rhs)", dbg_smartptr_verbosity);
00455 #endif
00456
00457 return SetFromRawPtr_(rhs);
00458 }
00459
00460
00461 template <class T>
00462 SmartPtr<T>& SmartPtr<T>::operator=(const SmartPtr<T>& rhs)
00463 {
00464 #ifdef IP_DEBUG_SMARTPTR
00465 DBG_START_METH(
00466 "SmartPtr<T>& SmartPtr<T>::operator=(const SmartPtr<T>& rhs)",
00467 dbg_smartptr_verbosity);
00468 #endif
00469
00470 return SetFromSmartPtr_(rhs);
00471 }
00472
00473
00474 template <class T>
00475 SmartPtr<T>& SmartPtr<T>::SetFromRawPtr_(T* rhs)
00476 {
00477 #ifdef IP_DEBUG_SMARTPTR
00478 DBG_START_METH(
00479 "SmartPtr<T>& SmartPtr<T>::SetFromRawPtr_(T* rhs)", dbg_smartptr_verbosity);
00480 #endif
00481
00482
00483 ReleasePointer_();
00484
00485 if (rhs != 0) {
00486 rhs->AddRef(this);
00487 ptr_ = rhs;
00488 }
00489
00490 return *this;
00491 }
00492
00493 template <class T>
00494 SmartPtr<T>& SmartPtr<T>::SetFromSmartPtr_(const SmartPtr<T>& rhs)
00495 {
00496 #ifdef IP_DEBUG_SMARTPTR
00497 DBG_START_METH(
00498 "SmartPtr<T>& SmartPtr<T>::SetFromSmartPtr_(const SmartPtr<T>& rhs)",
00499 dbg_smartptr_verbosity);
00500 #endif
00501
00502 T* ptr = GetRawPtr(rhs);
00503
00504
00505
00506
00507
00508 SetFromRawPtr_(ptr);
00509
00510 return (*this);
00511 }
00512
00513
00514 template <class T>
00515 void SmartPtr<T>::ReleasePointer_()
00516 {
00517 #ifdef IP_DEBUG_SMARTPTR
00518 DBG_START_METH(
00519 "void SmartPtr<T>::ReleasePointer()",
00520 dbg_smartptr_verbosity);
00521 #endif
00522
00523 if (ptr_) {
00524 ptr_->ReleaseRef(this);
00525 if (ptr_->ReferenceCount() == 0) {
00526 delete ptr_;
00527 }
00528 ptr_ = 0;
00529 }
00530 }
00531
00532
00533 template <class U>
00534 U* GetRawPtr(const SmartPtr<U>& smart_ptr)
00535 {
00536 #ifdef IP_DEBUG_SMARTPTR
00537 DBG_START_FUN(
00538 "T* GetRawPtr(const SmartPtr<T>& smart_ptr)",
00539 0);
00540 #endif
00541
00542 return smart_ptr.ptr_;
00543 }
00544
00545 template <class U>
00546 SmartPtr<const U> ConstPtr(const SmartPtr<U>& smart_ptr)
00547 {
00548
00549 return GetRawPtr(smart_ptr);
00550 }
00551
00552 template <class U>
00553 bool IsValid(const SmartPtr<U>& smart_ptr)
00554 {
00555 return !IsNull(smart_ptr);
00556 }
00557
00558 template <class U>
00559 bool IsNull(const SmartPtr<U>& smart_ptr)
00560 {
00561 #ifdef IP_DEBUG_SMARTPTR
00562 DBG_START_FUN(
00563 "bool IsNull(const SmartPtr<T>& smart_ptr)",
00564 0);
00565 #endif
00566
00567 return (smart_ptr.ptr_ == 0);
00568 }
00569
00570
00571 template <class U1, class U2>
00572 bool ComparePointers(const U1* lhs, const U2* rhs)
00573 {
00574 #ifdef IP_DEBUG_SMARTPTR
00575 DBG_START_FUN(
00576 "bool ComparePtrs(const U1* lhs, const U2* rhs)",
00577 dbg_smartptr_verbosity);
00578 #endif
00579
00580 if (lhs == rhs) {
00581 return true;
00582 }
00583
00584
00585
00586
00587
00588 const void* v_lhs = static_cast<const void*>(lhs);
00589 const void* v_rhs = static_cast<const void*>(rhs);
00590 if (v_lhs == v_rhs) {
00591 return true;
00592 }
00593
00594
00595 return false;
00596 }
00597
00598 template <class U1, class U2>
00599 bool operator==(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs)
00600 {
00601 #ifdef IP_DEBUG_SMARTPTR
00602 DBG_START_FUN(
00603 "bool operator==(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs)",
00604 dbg_smartptr_verbosity);
00605 #endif
00606
00607 U1* raw_lhs = GetRawPtr(lhs);
00608 U2* raw_rhs = GetRawPtr(rhs);
00609 return ComparePointers(raw_lhs, raw_rhs);
00610 }
00611
00612 template <class U1, class U2>
00613 bool operator==(const SmartPtr<U1>& lhs, U2* raw_rhs)
00614 {
00615 #ifdef IP_DEBUG_SMARTPTR
00616 DBG_START_FUN(
00617 "bool operator==(SmartPtr<U1>& lhs, U2* rhs)",
00618 dbg_smartptr_verbosity);
00619 #endif
00620
00621 U1* raw_lhs = GetRawPtr(lhs);
00622 return ComparePointers(raw_lhs, raw_rhs);
00623 }
00624
00625 template <class U1, class U2>
00626 bool operator==(U1* raw_lhs, const SmartPtr<U2>& rhs)
00627 {
00628 #ifdef IP_DEBUG_SMARTPTR
00629 DBG_START_FUN(
00630 "bool operator==(U1* raw_lhs, SmartPtr<U2>& rhs)",
00631 dbg_smartptr_verbosity);
00632 #endif
00633
00634 const U2* raw_rhs = GetRawPtr(rhs);
00635 return ComparePointers(raw_lhs, raw_rhs);
00636 }
00637
00638 template <class U1, class U2>
00639 bool operator!=(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs)
00640 {
00641 #ifdef IP_DEBUG_SMARTPTR
00642 DBG_START_FUN(
00643 "bool operator!=(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs)",
00644 dbg_smartptr_verbosity);
00645 #endif
00646
00647 bool retValue = operator==(lhs, rhs);
00648 return !retValue;
00649 }
00650
00651 template <class U1, class U2>
00652 bool operator!=(const SmartPtr<U1>& lhs, U2* raw_rhs)
00653 {
00654 #ifdef IP_DEBUG_SMARTPTR
00655 DBG_START_FUN(
00656 "bool operator!=(SmartPtr<U1>& lhs, U2* rhs)",
00657 dbg_smartptr_verbosity);
00658 #endif
00659
00660 bool retValue = operator==(lhs, raw_rhs);
00661 return !retValue;
00662 }
00663
00664 template <class U1, class U2>
00665 bool operator!=(U1* raw_lhs, const SmartPtr<U2>& rhs)
00666 {
00667 #ifdef IP_DEBUG_SMARTPTR
00668 DBG_START_FUN(
00669 "bool operator!=(U1* raw_lhs, SmartPtr<U2>& rhs)",
00670 dbg_smartptr_verbosity);
00671 #endif
00672
00673 bool retValue = operator==(raw_lhs, rhs);
00674 return !retValue;
00675 }
00676
00677 }
00678
00679 #endif
00680