Ipopt Documentation  
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
IpSmartPtr.hpp
Go to the documentation of this file.
1 // Copyright (C) 2004, 2011 International Business Machines and others.
2 // All Rights Reserved.
3 // This code is published under the Eclipse Public License.
4 //
5 // Authors: Carl Laird, Andreas Waechter IBM 2004-08-13
6 
7 #ifndef __IPSMARTPTR_HPP__
8 #define __IPSMARTPTR_HPP__
9 
10 #include "IpReferenced.hpp"
11 
12 #include "IpDebug.hpp"
13 #if IPOPT_CHECKLEVEL > 2
14 # define IP_DEBUG_SMARTPTR
15 #endif
16 #ifndef IPOPT_UNUSED
17 # if defined(__GNUC__)
18 # define IPOPT_UNUSED __attribute__((unused))
19 # else
20 # define IPOPT_UNUSED
21 # endif
22 #endif
23 
24 namespace Ipopt
25 {
26 
170 template<class T>
171 class SmartPtr: public Referencer
172 {
173 public:
174 #define ipopt_dbg_smartptr_verbosity 0
175 
177 
179  SmartPtr();
180 
182  SmartPtr(
183  const SmartPtr<T>& copy
184  );
185 
187  template<class U>
188  SmartPtr(
189  const SmartPtr<U>& copy
190  );
191 
193  SmartPtr(
194  T* ptr
195  );
196 
201  ~SmartPtr();
203 
205 
209  T* operator->() const;
210 
214  T& operator*() const;
215 
219  SmartPtr<T>& operator=(
220  T* rhs
221  );
222 
227  SmartPtr<T>& operator=(
228  const SmartPtr<T>& rhs
229  );
230 
235  template<class U>
236  SmartPtr<T>& operator=(
237  const SmartPtr<U>& rhs);
238 
242  template<class U1, class U2>
243  friend
244  bool operator==(
245  const SmartPtr<U1>& lhs,
246  const SmartPtr<U2>& rhs
247  );
248 
252  template<class U1, class U2>
253  friend
254  bool operator==(
255  const SmartPtr<U1>& lhs,
256  U2* raw_rhs
257  );
258 
262  template<class U1, class U2>
263  friend
264  bool operator==(
265  U1* lhs,
266  const SmartPtr<U2>& raw_rhs
267  );
268 
272  template<class U1, class U2>
273  friend
274  bool operator!=(
275  const SmartPtr<U1>& lhs,
276  const SmartPtr<U2>& rhs
277  );
278 
282  template<class U1, class U2>
283  friend
284  bool operator!=(
285  const SmartPtr<U1>& lhs,
286  U2* raw_rhs
287  );
288 
292  template<class U1, class U2>
293  friend
294  bool operator!=(
295  U1* lhs,
296  const SmartPtr<U2>& raw_rhs
297  );
298 
302  template<class U>
303  friend
304  bool operator<(
305  const SmartPtr<U>& lhs,
306  const SmartPtr<U>& rhs
307  );
309 
311 
323  template<class U>
324  friend U* GetRawPtr(
325  const SmartPtr<U>& smart_ptr
326  );
327 
329  template<class U>
330  friend SmartPtr<const U> ConstPtr(
331  const SmartPtr<U>& smart_ptr
332  );
333 
339  template<class U>
340  friend
341  bool IsValid(
342  const SmartPtr<U>& smart_ptr
343  );
344 
350  template<class U>
351  friend
352  bool IsNull(
353  const SmartPtr<U>& smart_ptr
354  );
356 
357 private:
359 
361  T* ptr_;
362 
368  T* rhs
369  );
370 
376  const SmartPtr<T>& rhs
377  );
378 
380  void ReleasePointer_();
382 };
383 
385 template<class U>
387 U* GetRawPtr(
388  const SmartPtr<U>& smart_ptr
389 );
390 
391 template<class U>
393  const SmartPtr<U>& smart_ptr
394 );
395 
396 template<class U>
397 bool IsNull(
398  const SmartPtr<U>& smart_ptr
399 );
400 
401 template<class U>
402 bool IsValid(
403  const SmartPtr<U>& smart_ptr
404 );
405 
406 template<class U1, class U2>
407 bool operator==(
408  const SmartPtr<U1>& lhs,
409  const SmartPtr<U2>& rhs
410 );
411 
412 template<class U1, class U2>
413 bool operator==(
414  const SmartPtr<U1>& lhs,
415  U2* raw_rhs
416 );
417 
418 template<class U1, class U2>
419 bool operator==(
420  U1* lhs,
421  const SmartPtr<U2>& raw_rhs
422 );
423 
424 template<class U1, class U2>
425 bool operator!=(
426  const SmartPtr<U1>& lhs,
427  const SmartPtr<U2>& rhs);
428 
429 template<class U1, class U2>
430 bool operator!=(
431  const SmartPtr<U1>& lhs,
432  U2* raw_rhs
433 );
434 
435 template<class U1, class U2>
436 bool operator!=(
437  U1* lhs,
438  const SmartPtr<U2>& raw_rhs
439 );
440 
442 
443 template<class T>
445  : ptr_(0)
446 {
447 #ifdef IP_DEBUG_SMARTPTR
448  DBG_START_METH("SmartPtr<T>::SmartPtr()", ipopt_dbg_smartptr_verbosity);
449 #endif
450 
451 #ifndef NDEBUG
452  const ReferencedObject* IPOPT_UNUSED trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ = ptr_;
453 #endif
454 }
455 
456 template<class T>
458  const SmartPtr<T>& copy
459 )
460  : ptr_(0)
461 {
462 #ifdef IP_DEBUG_SMARTPTR
463  DBG_START_METH("SmartPtr<T>::SmartPtr(const SmartPtr<T>& copy)", ipopt_dbg_smartptr_verbosity);
464 #endif
465 
466 #ifndef NDEBUG
467  const ReferencedObject* IPOPT_UNUSED trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ =
468  ptr_;
469 #endif
470 
471  (void) SetFromSmartPtr_(copy);
472 }
473 
474 template<class T>
475 template<class U>
477  const SmartPtr<U>& copy
478 )
479  : ptr_(0)
480 {
481 #ifdef IP_DEBUG_SMARTPTR
482  DBG_START_METH("SmartPtr<T>::SmartPtr(const SmartPtr<U>& copy)", ipopt_dbg_smartptr_verbosity);
483 #endif
484 
485 #ifndef NDEBUG
486  const ReferencedObject* IPOPT_UNUSED trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ =
487  ptr_;
488 #endif
489 
490  (void) SetFromSmartPtr_(GetRawPtr(copy));
491 }
492 
493 template<class T>
495  T* ptr
496 )
497  : ptr_(0)
498 {
499 #ifdef IP_DEBUG_SMARTPTR
500  DBG_START_METH("SmartPtr<T>::SmartPtr(T* ptr)", ipopt_dbg_smartptr_verbosity);
501 #endif
502 
503 #ifndef NDEBUG
504  const ReferencedObject* IPOPT_UNUSED trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ =
505  ptr_;
506 #endif
507 
508  (void) SetFromRawPtr_(ptr);
509 }
510 
511 template<class T>
513 {
514 #ifdef IP_DEBUG_SMARTPTR
515  DBG_START_METH("SmartPtr<T>::~SmartPtr(T* ptr)", ipopt_dbg_smartptr_verbosity);
516 #endif
517 
518  ReleasePointer_();
519 }
520 
521 template<class T>
523 {
524 #ifdef IP_DEBUG_SMARTPTR
525  DBG_START_METH("T* SmartPtr<T>::operator->()", ipopt_dbg_smartptr_verbosity);
526 #endif
527 
528  // cannot deref a null pointer
529 #if IPOPT_CHECKLEVEL > 0
530  assert(ptr_);
531 #endif
532 
533  return ptr_;
534 }
535 
536 template<class T>
538 {
539 #ifdef IP_DEBUG_SMARTPTR
540  DBG_START_METH("T& SmartPtr<T>::operator*()", ipopt_dbg_smartptr_verbosity);
541 #endif
542 
543  // cannot dereference a null pointer
544 #if IPOPT_CHECKLEVEL > 0
545  assert(ptr_);
546 #endif
547 
548  return *ptr_;
549 }
550 
551 template<class T>
553  T* rhs
554 )
555 {
556 #ifdef IP_DEBUG_SMARTPTR
557  DBG_START_METH("SmartPtr<T>& SmartPtr<T>::operator=(T* rhs)", ipopt_dbg_smartptr_verbosity);
558 #endif
559 
560  return SetFromRawPtr_(rhs);
561 }
562 
563 template<class T>
565  const SmartPtr<T>& rhs
566 )
567 {
568 #ifdef IP_DEBUG_SMARTPTR
570  "SmartPtr<T>& SmartPtr<T>::operator=(const SmartPtr<T>& rhs)",
572 #endif
573 
574  return SetFromSmartPtr_(rhs);
575 }
576 
577 template<class T>
578 template<class U>
580  const SmartPtr<U>& rhs
581 )
582 {
583 #ifdef IP_DEBUG_SMARTPTR
585  "SmartPtr<T>& SmartPtr<T>::operator=(const SmartPtr<U>& rhs)",
587 #endif
588 
589  return SetFromSmartPtr_(GetRawPtr(rhs));
590 }
591 
592 template<class T>
594  T* rhs
595 )
596 {
597 #ifdef IP_DEBUG_SMARTPTR
599  "SmartPtr<T>& SmartPtr<T>::SetFromRawPtr_(T* rhs)", ipopt_dbg_smartptr_verbosity);
600 #endif
601 
602  if( rhs != 0 )
603  {
604  rhs->AddRef(this);
605  }
606 
607  // Release any old pointer
608  ReleasePointer_();
609 
610  ptr_ = rhs;
611 
612  return *this;
613 }
614 
615 template<class T>
617  const SmartPtr<T>& rhs
618 )
619 {
620 #ifdef IP_DEBUG_SMARTPTR
622  "SmartPtr<T>& SmartPtr<T>::SetFromSmartPtr_(const SmartPtr<T>& rhs)",
624 #endif
625 
626  SetFromRawPtr_(GetRawPtr(rhs));
627 
628  return (*this);
629 }
630 
631 template<class T>
633 {
634 #ifdef IP_DEBUG_SMARTPTR
636  "void SmartPtr<T>::ReleasePointer()",
638 #endif
639 
640  if( ptr_ )
641  {
642  ptr_->ReleaseRef(this);
643  if( ptr_->ReferenceCount() == 0 )
644  {
645  delete ptr_;
646  }
647  }
648 }
649 
650 template<class U>
652  const SmartPtr<U>& smart_ptr
653 )
654 {
655 #ifdef IP_DEBUG_SMARTPTR
657  "T* GetRawPtr(const SmartPtr<T>& smart_ptr)",
658  0);
659 #endif
660 
661  return smart_ptr.ptr_;
662 }
663 
664 template<class U>
666  const SmartPtr<U>& smart_ptr
667 )
668 {
669  // compiler should implicitly cast
670  return GetRawPtr(smart_ptr);
671 }
672 
673 template<class U>
674 bool IsValid(
675  const SmartPtr<U>& smart_ptr
676 )
677 {
678  return !IsNull(smart_ptr);
679 }
680 
681 template<class U>
682 bool IsNull(
683  const SmartPtr<U>& smart_ptr
684 )
685 {
686 #ifdef IP_DEBUG_SMARTPTR
688  "bool IsNull(const SmartPtr<T>& smart_ptr)",
689  0);
690 #endif
691 
692  return (smart_ptr.ptr_ == 0);
693 }
694 
695 template<class U1, class U2>
697  const U1* lhs,
698  const U2* rhs
699 )
700 {
701 #ifdef IP_DEBUG_SMARTPTR
703  "bool ComparePtrs(const U1* lhs, const U2* rhs)",
705 #endif
706 
707  // Even if lhs and rhs point to the same object
708  // with different interfaces U1 and U2, we cannot guarantee that
709  // the value of the pointers will be equivalent. We can
710  // guarantee this if we convert to ReferencedObject* (see also #162)
711  const ReferencedObject* v_lhs = lhs;
712  const ReferencedObject* v_rhs = rhs;
713 
714  return v_lhs == v_rhs;
715 }
716 
717 template<class U1, class U2>
719  const SmartPtr<U1>& lhs,
720  const SmartPtr<U2>& rhs
721 )
722 {
723 #ifdef IP_DEBUG_SMARTPTR
725  "bool operator==(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs)",
727 #endif
728 
729  U1* raw_lhs = GetRawPtr(lhs);
730  U2* raw_rhs = GetRawPtr(rhs);
731  return ComparePointers(raw_lhs, raw_rhs);
732 }
733 
734 template<class U1, class U2>
736  const SmartPtr<U1>& lhs,
737  U2* raw_rhs
738 )
739 {
740 #ifdef IP_DEBUG_SMARTPTR
742  "bool operator==(SmartPtr<U1>& lhs, U2* rhs)",
744 #endif
745 
746  U1* raw_lhs = GetRawPtr(lhs);
747  return ComparePointers(raw_lhs, raw_rhs);
748 }
749 
750 template<class U1, class U2>
752  U1* raw_lhs,
753  const SmartPtr<U2>& rhs
754 )
755 {
756 #ifdef IP_DEBUG_SMARTPTR
758  "bool operator==(U1* raw_lhs, SmartPtr<U2>& rhs)",
760 #endif
761 
762  const U2* raw_rhs = GetRawPtr(rhs);
763  return ComparePointers(raw_lhs, raw_rhs);
764 }
765 
766 template<class U1, class U2>
768  const SmartPtr<U1>& lhs,
769  const SmartPtr<U2>& rhs
770 )
771 {
772 #ifdef IP_DEBUG_SMARTPTR
774  "bool operator!=(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs)",
776 #endif
777 
778  bool retValue = operator==(lhs, rhs);
779  return !retValue;
780 }
781 
782 template<class U1, class U2>
784  const SmartPtr<U1>& lhs,
785  U2* raw_rhs
786 )
787 {
788 #ifdef IP_DEBUG_SMARTPTR
790  "bool operator!=(SmartPtr<U1>& lhs, U2* rhs)",
792 #endif
793 
794  bool retValue = operator==(lhs, raw_rhs);
795  return !retValue;
796 }
797 
798 template<class U1, class U2>
800  U1* raw_lhs,
801  const SmartPtr<U2>& rhs
802 )
803 {
804 #ifdef IP_DEBUG_SMARTPTR
806  "bool operator!=(U1* raw_lhs, SmartPtr<U2>& rhs)",
808 #endif
809 
810  bool retValue = operator==(raw_lhs, rhs);
811  return !retValue;
812 }
813 
814 template<class T>
815 void swap(
816  SmartPtr<T>& a,
817  SmartPtr<T>& b
818 )
819 {
820 #ifdef IP_DEBUG_REFERENCED
821  SmartPtr<T> tmp(a);
822  a = b;
823  b = tmp;
824 #else
825  std::swap(a.prt_, b.ptr_);
826 #endif
827 }
828 
829 template<class T>
831  const SmartPtr<T>& lhs,
832  const SmartPtr<T>& rhs
833 )
834 {
835  return lhs.ptr_ < rhs.ptr_;
836 }
837 
838 template<class T>
840  const SmartPtr<T>& lhs,
841  const SmartPtr<T>& rhs
842 )
843 {
844  return rhs < lhs;
845 }
846 
847 template<class T> bool operator<=(
848  const SmartPtr<T>& lhs,
849  const SmartPtr<T>& rhs
850 )
851 {
852  return !(rhs < lhs);
853 }
854 
855 template<class T> bool operator>=(
856  const SmartPtr<T>& lhs,
857  const SmartPtr<T>& rhs
858 )
859 {
860  return !(lhs < rhs);
861 }
862 
863 } // namespace Ipopt
864 
865 #undef ipopt_dbg_smartptr_verbosity
866 
867 #endif
~SmartPtr()
Destructor, automatically decrements the reference count and deletes the object if necessary...
Definition: IpSmartPtr.hpp:512
bool IsValid(const SmartPtr< U > &smart_ptr)
Definition: IpSmartPtr.hpp:674
SmartPtr< T > & operator=(T *rhs)
Overloaded equals operator, allows the user to set the value of the SmartPtr from a raw pointer...
Definition: IpSmartPtr.hpp:552
bool operator<(const SmartPtr< T > &lhs, const SmartPtr< T > &rhs)
Definition: IpSmartPtr.hpp:830
SmartPtr< T > & SetFromRawPtr_(T *rhs)
Set the value of the internal raw pointer from another raw pointer, releasing the previously referenc...
Definition: IpSmartPtr.hpp:593
#define DBG_START_METH(__func_name, __verbose_level)
Definition: IpDebug.hpp:38
bool IsNull(const SmartPtr< U > &smart_ptr)
Definition: IpSmartPtr.hpp:682
bool operator>(const SmartPtr< T > &lhs, const SmartPtr< T > &rhs)
Definition: IpSmartPtr.hpp:839
bool operator>=(const SmartPtr< T > &lhs, const SmartPtr< T > &rhs)
Definition: IpSmartPtr.hpp:855
bool ComparePointers(const U1 *lhs, const U2 *rhs)
Definition: IpSmartPtr.hpp:696
friend bool operator<(const SmartPtr< U > &lhs, const SmartPtr< U > &rhs)
Overloaded less-than comparison operator, allows the user to compare the value of two SmartPtrs...
Template class for Smart Pointers.
Definition: IpSmartPtr.hpp:171
Storing the reference count of all the smart pointers that currently reference it.
bool operator!=(const SmartPtr< U1 > &lhs, const SmartPtr< U2 > &rhs)
Definition: IpSmartPtr.hpp:767
U * GetRawPtr(const SmartPtr< U > &smart_ptr)
Definition: IpSmartPtr.hpp:651
T * ptr_
Actual raw pointer to the object.
Definition: IpSmartPtr.hpp:361
Pseudo-class, from which everything has to inherit that wants to use be registered as a Referencer fo...
#define ipopt_dbg_smartptr_verbosity
Definition: IpSmartPtr.hpp:174
#define DBG_START_FUN(__func_name, __verbose_level)
Definition: IpDebug.hpp:37
bool operator<=(const SmartPtr< T > &lhs, const SmartPtr< T > &rhs)
Definition: IpSmartPtr.hpp:847
friend bool IsNull(const SmartPtr< U > &smart_ptr)
Returns true if the SmartPtr is NULL.
friend bool operator!=(const SmartPtr< U1 > &lhs, const SmartPtr< U2 > &rhs)
Overloaded in-equality comparison operator, allows the user to compare the value of two SmartPtrs...
friend U * GetRawPtr(const SmartPtr< U > &smart_ptr)
Returns the raw pointer contained.
SmartPtr< const U > ConstPtr(const SmartPtr< U > &smart_ptr)
Definition: IpSmartPtr.hpp:665
SmartPtr()
Default constructor, initialized to NULL.
Definition: IpSmartPtr.hpp:444
void ReleasePointer_()
Release the currently referenced object.
Definition: IpSmartPtr.hpp:632
SmartPtr< T > & SetFromSmartPtr_(const SmartPtr< T > &rhs)
Set the value of the internal raw pointer from a SmartPtr, releasing the previously referenced object...
Definition: IpSmartPtr.hpp:616
friend bool IsValid(const SmartPtr< U > &smart_ptr)
Returns true if the SmartPtr is NOT NULL.
friend bool operator==(const SmartPtr< U1 > &lhs, const SmartPtr< U2 > &rhs)
Overloaded equality comparison operator, allows the user to compare the value of two SmartPtrs...
friend SmartPtr< const U > ConstPtr(const SmartPtr< U > &smart_ptr)
Returns a const pointer.
T & operator*() const
Overloaded dereference operator, allows the user to dereference the contained pointer.
Definition: IpSmartPtr.hpp:537
T * operator->() const
Overloaded arrow operator, allows the user to call methods using the contained pointer.
Definition: IpSmartPtr.hpp:522
#define IPOPT_UNUSED
Definition: IpSmartPtr.hpp:20
bool operator==(const SmartPtr< U1 > &lhs, const SmartPtr< U2 > &rhs)
Definition: IpSmartPtr.hpp:718
void swap(SmartPtr< T > &a, SmartPtr< T > &b)
Definition: IpSmartPtr.hpp:815