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
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
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
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
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
00494
00495
00496
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
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
00575
00576
00577
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
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 }
00668
00669 #endif
00670