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