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 
25 #include <iostream>
26 #include <stdint.h>
27 
34 namespace ns3
35 {
36 
75 template <typename T>
76 class Ptr
77 {
78  private:
80  T* m_ptr;
81 
83  friend class Ptr<const T>;
84 
96  template <typename U>
97  friend U* GetPointer(const Ptr<U>& p);
109  template <typename U>
110  friend U* PeekPointer(const Ptr<U>& p);
111 
113  inline void Acquire() const;
114 
115  public:
117  Ptr();
128  Ptr(T* ptr);
137  Ptr(T* ptr, bool ref);
143  Ptr(const Ptr& o);
150  template <typename U>
151  Ptr(const Ptr<U>& o);
153  ~Ptr();
160  Ptr<T>& operator=(const Ptr& o);
165  T* operator->() const;
175  T& operator*() const;
180  T& operator*();
181 
228  explicit operator bool() const;
229 };
230 
247 template <typename T, typename... Ts>
248 Ptr<T> Create(Ts&&... args);
249 
260 template <typename T>
261 std::ostream& operator<<(std::ostream& os, const Ptr<T>& p);
262 
284 template <typename T1, typename T2>
285 bool operator==(const Ptr<T1>& lhs, T2 const* rhs);
286 
287 template <typename T1, typename T2>
288 bool operator==(T1 const* lhs, Ptr<T2>& rhs);
289 
290 template <typename T1, typename T2>
291 bool operator==(const Ptr<T1>& lhs, const Ptr<T2>& rhs);
299 template <typename T1, typename T2>
300 std::enable_if_t<std::is_same_v<T2, std::nullptr_t>, bool> operator==(const Ptr<T1>& lhs, T2 rhs);
301 
323 template <typename T1, typename T2>
324 bool operator!=(const Ptr<T1>& lhs, T2 const* rhs);
325 
326 template <typename T1, typename T2>
327 bool operator!=(T1 const* lhs, Ptr<T2>& rhs);
328 
329 template <typename T1, typename T2>
330 bool operator!=(const Ptr<T1>& lhs, const Ptr<T2>& rhs);
338 template <typename T1, typename T2>
339 std::enable_if_t<std::is_same_v<T2, std::nullptr_t>, bool> operator!=(const Ptr<T1>& lhs, T2 rhs);
340 
351 template <typename T>
352 bool operator<(const Ptr<T>& lhs, const Ptr<T>& rhs);
353 template <typename T>
354 bool operator<(const Ptr<T>& lhs, const Ptr<const T>& rhs);
355 template <typename T>
356 bool operator<(const Ptr<const T>& lhs, const Ptr<T>& rhs);
357 template <typename T>
358 bool operator<=(const Ptr<T>& lhs, const Ptr<T>& rhs);
359 template <typename T>
360 bool operator>(const Ptr<T>& lhs, const Ptr<T>& rhs);
361 template <typename T>
362 bool operator>=(const Ptr<T>& lhs, const Ptr<T>& rhs);
374 template <typename T1, typename T2>
376 
377 // Duplicate of struct CallbackTraits<T> as defined in callback.h
378 template <typename T>
380 
391 template <typename T>
392 struct CallbackTraits<Ptr<T>>
393 {
398  static T& GetReference(const Ptr<T> p)
399  {
400  return *PeekPointer(p);
401  }
402 };
403 
404 // Duplicate of struct EventMemberImplObjTraits<T> as defined in make-event.h
405 // We repeat it here to declare a specialization on Ptr<T>
406 // without making this header dependent on make-event.h
407 template <typename T>
408 struct EventMemberImplObjTraits;
409 
418 template <typename T>
420 {
425  static T& GetReference(Ptr<T> p)
426  {
427  return *PeekPointer(p);
428  }
429 };
430 
431 } // namespace ns3
432 
433 namespace ns3
434 {
435 
436 /*************************************************
437  * friend non-member function implementations
438  ************************************************/
439 
440 template <typename T, typename... Ts>
441 Ptr<T>
442 Create(Ts&&... args)
443 {
444  return Ptr<T>(new T(std::forward<Ts>(args)...), false);
445 }
446 
447 template <typename U>
448 U*
450 {
451  return p.m_ptr;
452 }
453 
454 template <typename U>
455 U*
457 {
458  p.Acquire();
459  return p.m_ptr;
460 }
461 
462 template <typename T>
463 std::ostream&
464 operator<<(std::ostream& os, const Ptr<T>& p)
465 {
466  os << PeekPointer(p);
467  return os;
468 }
469 
470 template <typename T1, typename T2>
471 bool
472 operator==(const Ptr<T1>& lhs, T2 const* rhs)
473 {
474  return PeekPointer(lhs) == rhs;
475 }
476 
477 template <typename T1, typename T2>
478 bool
479 operator==(T1 const* lhs, Ptr<T2>& rhs)
480 {
481  return lhs == PeekPointer(rhs);
482 }
483 
484 template <typename T1, typename T2>
485 bool
486 operator!=(const Ptr<T1>& lhs, T2 const* rhs)
487 {
488  return PeekPointer(lhs) != rhs;
489 }
490 
491 template <typename T1, typename T2>
492 bool
493 operator!=(T1 const* lhs, Ptr<T2>& rhs)
494 {
495  return lhs != PeekPointer(rhs);
496 }
497 
498 template <typename T1, typename T2>
499 bool
500 operator==(const Ptr<T1>& lhs, const Ptr<T2>& rhs)
501 {
502  return PeekPointer(lhs) == PeekPointer(rhs);
503 }
504 
505 template <typename T1, typename T2>
506 bool
507 operator!=(const Ptr<T1>& lhs, const Ptr<T2>& rhs)
508 {
509  return PeekPointer(lhs) != PeekPointer(rhs);
510 }
511 
512 template <typename T1, typename T2>
513 std::enable_if_t<std::is_same_v<T2, std::nullptr_t>, bool>
514 operator==(const Ptr<T1>& lhs, T2 rhs)
515 {
516  return PeekPointer(lhs) == nullptr;
517 }
518 
519 template <typename T1, typename T2>
520 std::enable_if_t<std::is_same_v<T2, std::nullptr_t>, bool>
521 operator!=(const Ptr<T1>& lhs, T2 rhs)
522 {
523  return PeekPointer(lhs) != nullptr;
524 }
525 
526 template <typename T>
527 bool
528 operator<(const Ptr<T>& lhs, const Ptr<T>& rhs)
529 {
530  return PeekPointer<T>(lhs) < PeekPointer<T>(rhs);
531 }
532 
533 template <typename T>
534 bool
535 operator<(const Ptr<T>& lhs, const Ptr<const T>& rhs)
536 {
537  return PeekPointer<T>(lhs) < PeekPointer<const T>(rhs);
538 }
539 
540 template <typename T>
541 bool
542 operator<(const Ptr<const T>& lhs, const Ptr<T>& rhs)
543 {
544  return PeekPointer<const T>(lhs) < PeekPointer<T>(rhs);
545 }
546 
547 template <typename T>
548 bool
549 operator<=(const Ptr<T>& lhs, const Ptr<T>& rhs)
550 {
551  return PeekPointer<T>(lhs) <= PeekPointer<T>(rhs);
552 }
553 
554 template <typename T>
555 bool
556 operator>(const Ptr<T>& lhs, const Ptr<T>& rhs)
557 {
558  return PeekPointer<T>(lhs) > PeekPointer<T>(rhs);
559 }
560 
561 template <typename T>
562 bool
563 operator>=(const Ptr<T>& lhs, const Ptr<T>& rhs)
564 {
565  return PeekPointer<T>(lhs) >= PeekPointer<T>(rhs);
566 }
567 
577 template <typename T1, typename T2>
578 Ptr<T1>
580 {
581  return Ptr<T1>(const_cast<T1*>(PeekPointer(p)));
582 }
583 
584 template <typename T1, typename T2>
585 Ptr<T1>
587 {
588  return Ptr<T1>(dynamic_cast<T1*>(PeekPointer(p)));
589 }
590 
591 template <typename T1, typename T2>
592 Ptr<T1>
594 {
595  return Ptr<T1>(static_cast<T1*>(PeekPointer(p)));
596 }
597 
608 template <typename T>
609 Ptr<T>
610 Copy(Ptr<T> object)
611 {
612  Ptr<T> p = Ptr<T>(new T(*PeekPointer(object)), false);
613  return p;
614 }
615 
616 template <typename T>
617 Ptr<T>
618 Copy(Ptr<const T> object)
619 {
620  Ptr<T> p = Ptr<T>(new T(*PeekPointer(object)), false);
621  return p;
622 }
623 
626 /****************************************************
627  * Member method implementations.
628  ***************************************************/
629 
630 template <typename T>
631 void
633 {
634  if (m_ptr != nullptr)
635  {
636  m_ptr->Ref();
637  }
638 }
639 
640 template <typename T>
642  : m_ptr(nullptr)
643 {
644 }
645 
646 template <typename T>
647 Ptr<T>::Ptr(T* ptr)
648  : m_ptr(ptr)
649 {
650  Acquire();
651 }
652 
653 template <typename T>
654 Ptr<T>::Ptr(T* ptr, bool ref)
655  : m_ptr(ptr)
656 {
657  if (ref)
658  {
659  Acquire();
660  }
661 }
662 
663 template <typename T>
664 Ptr<T>::Ptr(const Ptr& o)
665  : m_ptr(nullptr)
666 {
667  T* ptr = PeekPointer(o);
668  if (ptr != nullptr)
669  {
670  m_ptr = ptr;
671  Acquire();
672  }
673 }
674 
675 template <typename T>
676 template <typename U>
678  : m_ptr(PeekPointer(o))
679 {
680  Acquire();
681 }
682 
683 template <typename T>
685 {
686  if (m_ptr != nullptr)
687  {
688  m_ptr->Unref();
689  }
690 }
691 
692 template <typename T>
693 Ptr<T>&
695 {
696  if (&o == this)
697  {
698  return *this;
699  }
700  if (m_ptr != nullptr)
701  {
702  m_ptr->Unref();
703  }
704  m_ptr = o.m_ptr;
705  Acquire();
706  return *this;
707 }
708 
709 template <typename T>
710 T*
712 {
713  NS_ASSERT_MSG(m_ptr, "Attempted to dereference zero pointer");
714  return m_ptr;
715 }
716 
717 template <typename T>
718 T*
720 {
721  NS_ASSERT_MSG(m_ptr, "Attempted to dereference zero pointer");
722  return m_ptr;
723 }
724 
725 template <typename T>
726 T&
728 {
729  NS_ASSERT_MSG(m_ptr, "Attempted to dereference zero pointer");
730  return *m_ptr;
731 }
732 
733 template <typename T>
734 T&
736 {
737  NS_ASSERT_MSG(m_ptr, "Attempted to dereference zero pointer");
738  return *m_ptr;
739 }
740 
741 template <typename T>
742 Ptr<T>::operator bool() const
743 {
744  return m_ptr != nullptr;
745 }
746 
747 } // namespace ns3
748 
749 /****************************************************
750  * Global Functions (outside namespace ns3)
751  ***************************************************/
752 
766 template <class T>
767 struct std::hash<ns3::Ptr<T>>
768 {
774  std::size_t operator()(ns3::Ptr<T> p) const
775  {
776  return std::hash<const T*>()(ns3::PeekPointer(p));
777  }
778 };
779 
780 #endif /* PTR_H */
NS_ASSERT() and NS_ASSERT_MSG() macro definitions.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
Ptr(T *ptr)
Create a smart pointer which points to the object pointed to by the input raw pointer ptr.
Definition: ptr.h:647
friend U * GetPointer(const Ptr< U > &p)
Get a permanent pointer to the underlying object.
Definition: ptr.h:456
Ptr(const Ptr &o)
Copy by referencing the same underlying object.
Definition: ptr.h:664
T & operator*()
A dereference.
Definition: ptr.h:735
Ptr()
Create an empty smart pointer.
Definition: ptr.h:641
void Acquire() const
Mark this as a a reference by incrementing the reference count.
Definition: ptr.h:632
Ptr(const Ptr< U > &o)
Copy, removing const qualifier.
Definition: ptr.h:677
T * operator->()
An lvalue member access.
Definition: ptr.h:711
friend U * PeekPointer(const Ptr< U > &p)
Get a temporary pointer to the underlying object.
Definition: ptr.h:449
T & operator*() const
A const dereference.
Definition: ptr.h:727
Ptr< T > & operator=(const Ptr &o)
Assignment operator by referencing the same underlying object.
Definition: ptr.h:694
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:654
~Ptr()
Destructor.
Definition: ptr.h:684
T * m_ptr
The pointer.
Definition: ptr.h:80
T * operator->() const
An rvalue member access.
Definition: ptr.h:719
#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
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:442
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition: json.h:4680
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:678
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:593
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:579
U * GetPointer(const Ptr< U > &p)
Definition: ptr.h:456
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition: ptr.h:586
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:159
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:449
Ptr< T > Copy(Ptr< T > object)
Return a deep copy of a Ptr.
Definition: ptr.h:610
static T & GetReference(const Ptr< T > p)
Definition: ptr.h:398
static T & GetReference(Ptr< T > p)
Definition: ptr.h:425
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:774