A Discrete-Event Network Simulator
API
ptr.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2005,2006 INRIA
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18  */
19 
20 #ifndef PTR_H
21 #define PTR_H
22 
23 #include "assert.h"
24 #include "deprecated.h"
25 
26 #include <iostream>
27 #include <stdint.h>
28 
35 namespace ns3
36 {
37 
76 template <typename T>
77 class Ptr
78 {
79  private:
81  T* m_ptr;
82 
90  // Don't deprecate the class because the warning fires
91  // every time ptr.h is merely included, masking the real uses of Tester
92  // Leave the macro here so we can find this later to actually remove it.
93  class /* NS_DEPRECATED_3_37 ("see operator bool") */ Tester
94  {
95  public:
96  // Delete operator delete to avoid misuse
97  void operator delete(void*) = delete;
98  };
99 
101  friend class Ptr<const T>;
102 
114  template <typename U>
115  friend U* GetPointer(const Ptr<U>& p);
127  template <typename U>
128  friend U* PeekPointer(const Ptr<U>& p);
129 
131  inline void Acquire() const;
132 
133  public:
135  Ptr();
146  Ptr(T* ptr);
155  Ptr(T* ptr, bool ref);
161  Ptr(const Ptr& o);
168  template <typename U>
169  Ptr(const Ptr<U>& o);
171  ~Ptr();
178  Ptr<T>& operator=(const Ptr& o);
183  T* operator->() const;
193  T& operator*() const;
198  T& operator*();
199 
215  NS_DEPRECATED_3_37("see operator bool")
216  operator Tester*() const;
263  explicit operator bool() const;
264 };
265 
282 template <typename T, typename... Ts>
283 Ptr<T> Create(Ts&&... args);
284 
295 template <typename T>
296 std::ostream& operator<<(std::ostream& os, const Ptr<T>& p);
297 
319 template <typename T1, typename T2>
320 bool operator==(const Ptr<T1>& lhs, T2 const* rhs);
321 
322 template <typename T1, typename T2>
323 bool operator==(T1 const* lhs, Ptr<T2>& rhs);
324 
325 template <typename T1, typename T2>
326 bool operator==(const Ptr<T1>& lhs, const Ptr<T2>& rhs);
334 template <typename T1, typename T2>
335 typename std::enable_if<std::is_same<T2, std::nullptr_t>::value, bool>::type operator==(
336  const Ptr<T1>& lhs,
337  T2 rhs);
338 
360 template <typename T1, typename T2>
361 bool operator!=(const Ptr<T1>& lhs, T2 const* rhs);
362 
363 template <typename T1, typename T2>
364 bool operator!=(T1 const* lhs, Ptr<T2>& rhs);
365 
366 template <typename T1, typename T2>
367 bool operator!=(const Ptr<T1>& lhs, const Ptr<T2>& rhs);
375 template <typename T1, typename T2>
376 typename std::enable_if<std::is_same<T2, std::nullptr_t>::value, bool>::type operator!=(
377  const Ptr<T1>& lhs,
378  T2 rhs);
379 
390 template <typename T>
391 bool operator<(const Ptr<T>& lhs, const Ptr<T>& rhs);
392 template <typename T>
393 bool operator<(const Ptr<T>& lhs, const Ptr<const T>& rhs);
394 template <typename T>
395 bool operator<(const Ptr<const T>& lhs, const Ptr<T>& rhs);
396 template <typename T>
397 bool operator<=(const Ptr<T>& lhs, const Ptr<T>& rhs);
398 template <typename T>
399 bool operator>(const Ptr<T>& lhs, const Ptr<T>& rhs);
400 template <typename T>
401 bool operator>=(const Ptr<T>& lhs, const Ptr<T>& rhs);
413 template <typename T1, typename T2>
414 Ptr<T1> const_pointer_cast(const Ptr<T2>& p);
415 
416 // Duplicate of struct CallbackTraits<T> as defined in callback.h
417 template <typename T>
419 
430 template <typename T>
431 struct CallbackTraits<Ptr<T>>
432 {
437  static T& GetReference(const Ptr<T> p)
438  {
439  return *PeekPointer(p);
440  }
441 };
442 
443 // Duplicate of struct EventMemberImplObjTraits<T> as defined in make-event.h
444 // We repeat it here to declare a specialization on Ptr<T>
445 // without making this header dependent on make-event.h
446 template <typename T>
447 struct EventMemberImplObjTraits;
448 
457 template <typename T>
459 {
464  static T& GetReference(Ptr<T> p)
465  {
466  return *PeekPointer(p);
467  }
468 };
469 
470 } // namespace ns3
471 
472 namespace ns3
473 {
474 
475 /*************************************************
476  * friend non-member function implementations
477  ************************************************/
478 
479 template <typename T, typename... Ts>
480 Ptr<T>
481 Create(Ts&&... args)
482 {
483  return Ptr<T>(new T(std::forward<Ts>(args)...), false);
484 }
485 
486 template <typename U>
487 U*
489 {
490  return p.m_ptr;
491 }
492 
493 template <typename U>
494 U*
496 {
497  p.Acquire();
498  return p.m_ptr;
499 }
500 
501 template <typename T>
502 std::ostream&
503 operator<<(std::ostream& os, const Ptr<T>& p)
504 {
505  os << PeekPointer(p);
506  return os;
507 }
508 
509 template <typename T1, typename T2>
510 bool
511 operator==(const Ptr<T1>& lhs, T2 const* rhs)
512 {
513  return PeekPointer(lhs) == rhs;
514 }
515 
516 template <typename T1, typename T2>
517 bool
518 operator==(T1 const* lhs, Ptr<T2>& rhs)
519 {
520  return lhs == PeekPointer(rhs);
521 }
522 
523 template <typename T1, typename T2>
524 bool
525 operator!=(const Ptr<T1>& lhs, T2 const* rhs)
526 {
527  return PeekPointer(lhs) != rhs;
528 }
529 
530 template <typename T1, typename T2>
531 bool
532 operator!=(T1 const* lhs, Ptr<T2>& rhs)
533 {
534  return lhs != PeekPointer(rhs);
535 }
536 
537 template <typename T1, typename T2>
538 bool
539 operator==(const Ptr<T1>& lhs, const Ptr<T2>& rhs)
540 {
541  return PeekPointer(lhs) == PeekPointer(rhs);
542 }
543 
544 template <typename T1, typename T2>
545 bool
546 operator!=(const Ptr<T1>& lhs, const Ptr<T2>& rhs)
547 {
548  return PeekPointer(lhs) != PeekPointer(rhs);
549 }
550 
551 template <typename T1, typename T2>
553 operator==(const Ptr<T1>& lhs, T2 rhs)
554 {
555  return PeekPointer(lhs) == nullptr;
556 }
557 
558 template <typename T1, typename T2>
560 operator!=(const Ptr<T1>& lhs, T2 rhs)
561 {
562  return PeekPointer(lhs) != nullptr;
563 }
564 
565 template <typename T>
566 bool
567 operator<(const Ptr<T>& lhs, const Ptr<T>& rhs)
568 {
569  return PeekPointer<T>(lhs) < PeekPointer<T>(rhs);
570 }
571 
572 template <typename T>
573 bool
574 operator<(const Ptr<T>& lhs, const Ptr<const T>& rhs)
575 {
576  return PeekPointer<T>(lhs) < PeekPointer<const T>(rhs);
577 }
578 
579 template <typename T>
580 bool
581 operator<(const Ptr<const T>& lhs, const Ptr<T>& rhs)
582 {
583  return PeekPointer<const T>(lhs) < PeekPointer<T>(rhs);
584 }
585 
586 template <typename T>
587 bool
588 operator<=(const Ptr<T>& lhs, const Ptr<T>& rhs)
589 {
590  return PeekPointer<T>(lhs) <= PeekPointer<T>(rhs);
591 }
592 
593 template <typename T>
594 bool
595 operator>(const Ptr<T>& lhs, const Ptr<T>& rhs)
596 {
597  return PeekPointer<T>(lhs) > PeekPointer<T>(rhs);
598 }
599 
600 template <typename T>
601 bool
602 operator>=(const Ptr<T>& lhs, const Ptr<T>& rhs)
603 {
604  return PeekPointer<T>(lhs) >= PeekPointer<T>(rhs);
605 }
606 
616 template <typename T1, typename T2>
617 Ptr<T1>
619 {
620  return Ptr<T1>(const_cast<T1*>(PeekPointer(p)));
621 }
622 
623 template <typename T1, typename T2>
624 Ptr<T1>
626 {
627  return Ptr<T1>(dynamic_cast<T1*>(PeekPointer(p)));
628 }
629 
630 template <typename T1, typename T2>
631 Ptr<T1>
633 {
634  return Ptr<T1>(static_cast<T1*>(PeekPointer(p)));
635 }
636 
647 template <typename T>
648 Ptr<T>
649 Copy(Ptr<T> object)
650 {
651  Ptr<T> p = Ptr<T>(new T(*PeekPointer(object)), false);
652  return p;
653 }
654 
655 template <typename T>
656 Ptr<T>
657 Copy(Ptr<const T> object)
658 {
659  Ptr<T> p = Ptr<T>(new T(*PeekPointer(object)), false);
660  return p;
661 }
662 
665 /****************************************************
666  * Member method implementations.
667  ***************************************************/
668 
669 template <typename T>
670 void
672 {
673  if (m_ptr != nullptr)
674  {
675  m_ptr->Ref();
676  }
677 }
678 
679 template <typename T>
681  : m_ptr(nullptr)
682 {
683 }
684 
685 template <typename T>
686 Ptr<T>::Ptr(T* ptr)
687  : m_ptr(ptr)
688 {
689  Acquire();
690 }
691 
692 template <typename T>
693 Ptr<T>::Ptr(T* ptr, bool ref)
694  : m_ptr(ptr)
695 {
696  if (ref)
697  {
698  Acquire();
699  }
700 }
701 
702 template <typename T>
703 Ptr<T>::Ptr(const Ptr& o)
704  : m_ptr(nullptr)
705 {
706  T* ptr = PeekPointer(o);
707  if (ptr != nullptr)
708  {
709  m_ptr = ptr;
710  Acquire();
711  }
712 }
713 
714 template <typename T>
715 template <typename U>
717  : m_ptr(PeekPointer(o))
718 {
719  Acquire();
720 }
721 
722 template <typename T>
724 {
725  if (m_ptr != nullptr)
726  {
727  m_ptr->Unref();
728  }
729 }
730 
731 template <typename T>
732 Ptr<T>&
734 {
735  if (&o == this)
736  {
737  return *this;
738  }
739  if (m_ptr != nullptr)
740  {
741  m_ptr->Unref();
742  }
743  m_ptr = o.m_ptr;
744  Acquire();
745  return *this;
746 }
747 
748 template <typename T>
749 T*
751 {
752  NS_ASSERT_MSG(m_ptr, "Attempted to dereference zero pointer");
753  return m_ptr;
754 }
755 
756 template <typename T>
757 T*
759 {
760  NS_ASSERT_MSG(m_ptr, "Attempted to dereference zero pointer");
761  return m_ptr;
762 }
763 
764 template <typename T>
765 T&
767 {
768  NS_ASSERT_MSG(m_ptr, "Attempted to dereference zero pointer");
769  return *m_ptr;
770 }
771 
772 template <typename T>
773 T&
775 {
776  NS_ASSERT_MSG(m_ptr, "Attempted to dereference zero pointer");
777  return *m_ptr;
778 }
779 
780 template <typename T>
781 Ptr<T>::operator Tester*() const // NS_DEPRECATED_3_37
782 {
783  if (m_ptr == 0)
784  {
785  return 0;
786  }
787  static Tester test;
788  return &test;
789 }
790 
791 template <typename T>
792 Ptr<T>::operator bool() const
793 {
794  return m_ptr != nullptr;
795 }
796 
797 } // namespace ns3
798 
799 /****************************************************
800  * Global Functions (outside namespace ns3)
801  ***************************************************/
802 
816 template <class T>
817 struct std::hash<ns3::Ptr<T>>
818 {
824  std::size_t operator()(ns3::Ptr<T> p) const
825  {
826  return std::hash<const T*>()(ns3::PeekPointer(p));
827  }
828 };
829 
830 #endif /* PTR_H */
NS_ASSERT() and NS_ASSERT_MSG() macro definitions.
Helper to test for null pointer.
Definition: ptr.h:94
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
Ptr(T *ptr)
Create a smart pointer which points to the object pointed to by the input raw pointer ptr.
Definition: ptr.h:686
friend U * GetPointer(const Ptr< U > &p)
Get a permanent pointer to the underlying object.
Definition: ptr.h:495
Ptr(const Ptr &o)
Copy by referencing the same underlying object.
Definition: ptr.h:703
T & operator*()
A dereference.
Definition: ptr.h:774
Ptr()
Create an empty smart pointer.
Definition: ptr.h:680
void Acquire() const
Mark this as a a reference by incrementing the reference count.
Definition: ptr.h:671
Ptr(const Ptr< U > &o)
Copy, removing const qualifier.
Definition: ptr.h:716
T * operator->()
An lvalue member access.
Definition: ptr.h:750
friend U * PeekPointer(const Ptr< U > &p)
Get a temporary pointer to the underlying object.
Definition: ptr.h:488
T & operator*() const
A const dereference.
Definition: ptr.h:766
Ptr< T > & operator=(const Ptr &o)
Assignment operator by referencing the same underlying object.
Definition: ptr.h:733
Ptr(T *ptr, bool ref)
Create a smart pointer which points to the object pointed to by the input raw pointer ptr.
Definition: ptr.h:693
~Ptr()
Destructor.
Definition: ptr.h:723
T * m_ptr
The pointer.
Definition: ptr.h:81
T * operator->() const
An rvalue member access.
Definition: ptr.h:758
NS_DEPRECATED macro definition.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
#define NS_DEPRECATED_3_37(msg)
Tag for things deprecated in version ns-3.37.
Definition: deprecated.h:89
bool operator>=(const int64x64_t &lhs, const int64x64_t &rhs)
Greater or equal operator.
Definition: int64x64.h:174
bool operator<=(const int64x64_t &lhs, const int64x64_t &rhs)
Less or equal operator.
Definition: int64x64.h:161
bool operator>(const Length &left, const Length &right)
Check if left has a value greater than right.
Definition: length.cc:421
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition: ptr.h:481
Every class exported by the ns3 library is enclosed in the ns3 namespace.
bool operator!=(Callback< R, Args... > a, Callback< R, Args... > b)
Inequality test.
Definition: callback.h:681
bool operator==(const EventId &a, const EventId &b)
Definition: event-id.h:157
Ptr< T1 > StaticCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition: ptr.h:632
bool operator<(const EventId &a, const EventId &b)
Definition: event-id.h:170
Ptr< T1 > const_pointer_cast(const Ptr< T2 > &p)
Return a copy of p with its stored pointer const casted from T2 to T1.
Ptr< T1 > ConstCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition: ptr.h:618
U * GetPointer(const Ptr< U > &p)
Definition: ptr.h:495
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition: ptr.h:625
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:129
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:488
Ptr< T > Copy(Ptr< T > object)
Return a deep copy of a Ptr.
Definition: ptr.h:649
value
Definition: second.py:41
static T & GetReference(const Ptr< T > p)
Definition: ptr.h:437
static T & GetReference(Ptr< T > p)
Definition: ptr.h:464
Helper for the MakeEvent functions which take a class method.
Definition: make-event.h:370
std::size_t operator()(ns3::Ptr< T > p) const
The functor.
Definition: ptr.h:824