A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
ptr.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2005,2006 INRIA
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
7 */
8
9#ifndef PTR_H
10#define PTR_H
11
12#include "assert.h"
13
14#include <iostream>
15#include <stdint.h>
16#include <type_traits>
17
18/**
19 * @file
20 * @ingroup ptr
21 * ns3::Ptr smart pointer declaration and implementation.
22 */
23
24namespace ns3
25{
26
27/**
28 * @ingroup core
29 * @defgroup ptr Smart Pointer
30 * @brief Heap memory management.
31 *
32 * See \ref ns3::Ptr for implementation details.
33 *
34 * See \ref main-ptr.cc for example usage.
35 */
36/**
37 * @ingroup ptr
38 *
39 * @brief Smart pointer class similar to \c boost::intrusive_ptr.
40 *
41 * This smart-pointer class assumes that the underlying
42 * type provides a pair of \c Ref() and \c Unref() methods which are
43 * expected to increment and decrement the internal reference count
44 * of the object instance. You can add \c Ref() and \c Unref()
45 * to a class simply by inheriting from ns3::SimpleRefCount<>
46 * using the CRTP (`class Foo : public SimpleRefCount<Foo>`)
47 *
48 * This implementation allows you to manipulate the smart pointer
49 * as if it was a normal pointer: you can test if it is non-null,
50 * compare it to other pointers of the same type, etc.
51 *
52 * It is possible to extract the raw pointer from this
53 * smart pointer with the GetPointer() and PeekPointer() methods.
54 *
55 * If you want to store a `new Object()` into a smart pointer,
56 * we recommend you to use the CreateObject<>() template function
57 * to create the Object and store it in a smart pointer to avoid
58 * memory leaks. These functions are really small convenience
59 * functions and their goal is just is save you a small
60 * bit of typing. If the Object does not inherit from Object
61 * (or ObjectBase) there is also a convenience wrapper Create<>()
62 *
63 * @tparam T \explicit The type of the underlying object.
64 */
65template <typename T>
66class Ptr
67{
68 private:
69 /** The pointer. */
71
72 /** Interoperate with const instances. */
73 friend class Ptr<const T>;
74
75 /**
76 * Get a permanent pointer to the underlying object.
77 *
78 * The underlying refcount is incremented prior
79 * to returning to the caller so the caller is
80 * responsible for calling Unref himself.
81 *
82 * @tparam U \deduced The actual type of the argument and return pointer.
83 * @param [in] p Smart pointer
84 * @return The pointer managed by this smart pointer.
85 */
86 template <typename U>
87 friend U* GetPointer(const Ptr<U>& p);
88 /**
89 * Get a temporary pointer to the underlying object.
90 *
91 * The underlying refcount is not incremented prior
92 * to returning to the caller so the caller is not
93 * responsible for calling Unref himself.
94 *
95 * @tparam U \deduced The actual type of the argument and return pointer.
96 * @param [in] p Smart pointer
97 * @return The pointer managed by this smart pointer.
98 */
99 template <typename U>
100 friend U* PeekPointer(const Ptr<U>& p);
101
102 /** Mark this as a a reference by incrementing the reference count. */
103 inline void Acquire() const;
104
105 public:
106 /** Create an empty smart pointer */
108 /**
109 * Create a smart pointer which points to the object pointed to by
110 * the input raw pointer ptr. This method creates its own reference
111 * to the pointed object. The caller is responsible for Unref()'ing
112 * its own reference, and the smart pointer will eventually do the
113 * same, so that object is deleted if no more references to it
114 * remain.
115 *
116 * @param [in] ptr Raw pointer to manage
117 */
118 Ptr(T* ptr);
119 /**
120 * Create a smart pointer which points to the object pointed to by
121 * the input raw pointer ptr.
122 *
123 * @param [in] ptr Raw pointer to manage
124 * @param [in] ref if set to true, this method calls Ref, otherwise,
125 * it does not call Ref.
126 */
127 Ptr(T* ptr, bool ref);
128 /**
129 * Copy by referencing the same underlying object.
130 *
131 * @param [in] o The other Ptr instance.
132 */
133 Ptr(const Ptr& o);
134 /**
135 * Copy, removing \c const qualifier.
136 *
137 * @tparam U \deduced The type underlying the Ptr being copied.
138 * @param [in] o The Ptr to copy.
139 */
140 template <typename U>
141 Ptr(const Ptr<U>& o);
142 /** Destructor. */
144 /**
145 * Assignment operator by referencing the same underlying object.
146 *
147 * @param [in] o The other Ptr instance.
148 * @return A reference to self.
149 */
150 Ptr<T>& operator=(const Ptr& o);
151 /**
152 * An rvalue member access.
153 * @returns A pointer to the underlying object.
154 */
155 T* operator->() const;
156 /**
157 * An lvalue member access.
158 * @returns A pointer to the underlying object.
159 */
161 /**
162 * A \c const dereference.
163 * @returns A pointer to the underlying object.
164 */
165 T& operator*() const;
166 /**
167 * A dereference.
168 * @returns A pointer to the underlying object.
169 */
171
172 /**
173 * Test for non-NULL pointer.
174 *
175 * This enables simple pointer checks like
176 * @code
177 * Ptr<...> p = ...;
178 * if (p) ...
179 * if (!p) ...
180 * @endcode
181 *
182 * The same construct works in the NS_ASSERT... and NS_ABORT... macros.
183 *
184 * @note Explicit tests against `0`, `NULL` or `nullptr` are not supported.
185 * All these cases will fail to compile:
186 * @code
187 * if (p != nullptr {...} // Should be `if (p)`
188 * if (p != NULL) {...}
189 * if (p != 0) {...}
190 *
191 * if (p == nullptr {...} // Should be `if (!p)`
192 * if (p == NULL) {...}
193 * if (p == 0) {...}
194 * @endcode
195 * Just use `if (p)` or `if (!p)` as indicated.
196 *
197 * @note NS_TEST... invocations should be written as follows:
198 * @code
199 * // p should be non-NULL
200 * NS_TEST...NE... (p, nullptr, ...);
201 * // p should be NULL
202 * NS_TEST...EQ... (p, nullptr, ...);
203 * @endcode
204 *
205 * @note Unfortunately return values are not
206 * "contextual conversion expression" contexts,
207 * so you need to explicitly cast return values to bool:
208 * @code
209 * bool f (...)
210 * {
211 * Ptr<...> p = ...;
212 * return (bool)(p);
213 * }
214 * @endcode
215 *
216 * @returns \c true if the underlying pointer is non-NULL.
217 */
218 explicit operator bool() const;
219};
220
221/**
222 * @ingroup ptr
223 * Create class instances by constructors with varying numbers
224 * of arguments and return them by Ptr.
225 *
226 * This template work for any class \c T derived from ns3::SimpleRefCount
227 *
228 * @see CreateObject for methods to create derivatives of ns3::Object
229 */
230/** @{ */
231/**
232 * @tparam T \explicit The type of class object to create.
233 * @tparam Ts \deduced Types of the constructor arguments.
234 * @param [in] args Constructor arguments.
235 * @return A Ptr to the newly created \c T.
236 */
237template <typename T, typename... Ts>
238Ptr<T> Create(Ts&&... args);
239
240/** @}*/
241
242/**
243 * @ingroup ptr
244 * Output streamer.
245 * @tparam T \deduced The type of the underlying Object.
246 * @param [in,out] os The output stream.
247 * @param [in] p The Ptr.
248 * @returns The stream.
249 */
250template <typename T>
251std::ostream& operator<<(std::ostream& os, const Ptr<T>& p);
252
253/**
254 * @ingroup ptr
255 * Equality operator.
256 *
257 * This enables code such as
258 * @code
259 * Ptr<...> p = ...;
260 * Ptr<...> q = ...;
261 * if (p == q) ...
262 * @endcode
263 *
264 * Note that either \c p or \c q could also be ordinary pointers
265 * to the underlying object.
266 *
267 * @tparam T1 \deduced Type of the object on the lhs.
268 * @tparam T2 \deduced Type of the object on the rhs.
269 * @param [in] lhs The left operand.
270 * @param [in] rhs The right operand.
271 * @return \c true if the operands point to the same underlying object.
272 */
273/** @{ */
274template <typename T1, typename T2>
275bool operator==(const Ptr<T1>& lhs, T2 const* rhs);
276
277template <typename T1, typename T2>
278bool operator==(T1 const* lhs, Ptr<T2>& rhs);
279
280template <typename T1, typename T2>
281bool operator==(const Ptr<T1>& lhs, const Ptr<T2>& rhs);
282/**@}*/
283
284/**
285 * @ingroup ptr
286 * Specialization for comparison to \c nullptr
287 * @copydoc operator==(Ptr<T1>const&,Ptr<T2>const&)
288 */
289template <typename T1, typename T2>
290std::enable_if_t<std::is_same_v<T2, std::nullptr_t>, bool> operator==(const Ptr<T1>& lhs, T2 rhs);
291
292/**
293 * @ingroup ptr
294 * Inequality operator.
295 *
296 * This enables code such as
297 * @code
298 * Ptr<...> p = ...;
299 * Ptr<...> q = ...;
300 * if (p != q) ...
301 * @endcode
302 *
303 * Note that either \c p or \c q could also be ordinary pointers
304 * to the underlying object.
305 *
306 * @tparam T1 \deduced Type of the object on the lhs.
307 * @tparam T2 \deduced Type of the object on the rhs.
308 * @param [in] lhs The left operand.
309 * @param [in] rhs The right operand.
310 * @return \c true if the operands point to the same underlying object.
311 */
312/** @{ */
313template <typename T1, typename T2>
314bool operator!=(const Ptr<T1>& lhs, T2 const* rhs);
315
316template <typename T1, typename T2>
317bool operator!=(T1 const* lhs, Ptr<T2>& rhs);
318
319template <typename T1, typename T2>
320bool operator!=(const Ptr<T1>& lhs, const Ptr<T2>& rhs);
321/**@}*/
322
323/**
324 * @ingroup ptr
325 * Specialization for comparison to \c nullptr
326 * @copydoc operator==(Ptr<T1>const&,Ptr<T2>const&)
327 */
328template <typename T1, typename T2>
329std::enable_if_t<std::is_same_v<T2, std::nullptr_t>, bool> operator!=(const Ptr<T1>& lhs, T2 rhs);
330
331/**
332 * @ingroup ptr
333 * Comparison operator applied to the underlying pointers.
334 *
335 * @tparam T \deduced The type of the operands.
336 * @param [in] lhs The left operand.
337 * @param [in] rhs The right operand.
338 * @return The comparison on the underlying pointers.
339 */
340/** @{ */
341template <typename T>
342bool operator<(const Ptr<T>& lhs, const Ptr<T>& rhs);
343template <typename T>
344bool operator<(const Ptr<T>& lhs, const Ptr<const T>& rhs);
345template <typename T>
346bool operator<(const Ptr<const T>& lhs, const Ptr<T>& rhs);
347template <typename T>
348bool operator<=(const Ptr<T>& lhs, const Ptr<T>& rhs);
349template <typename T>
350bool operator>(const Ptr<T>& lhs, const Ptr<T>& rhs);
351template <typename T>
352bool operator>=(const Ptr<T>& lhs, const Ptr<T>& rhs);
353/** @} */
354
355/**
356 * Return a copy of \c p with its stored pointer const casted from
357 * \c T2 to \c T1.
358 *
359 * @tparam T1 \deduced The type to return in a Ptr.
360 * @tparam T2 \deduced The type of the underlying object.
361 * @param [in] p The original \c const Ptr.
362 * @return A non-const Ptr.
363 */
364template <typename T1, typename T2>
366
367// Duplicate of struct CallbackTraits<T> as defined in callback.h
368template <typename T>
370
371/**
372 * @ingroup callbackimpl
373 *
374 * Trait class to convert a pointer into a reference,
375 * used by MemPtrCallBackImpl.
376 *
377 * This is the specialization for Ptr types.
378 *
379 * @tparam T \deduced The type of the underlying object.
380 */
381template <typename T>
383{
384 /**
385 * @param [in] p Object pointer
386 * @return A reference to the object pointed to by p
387 */
388 static T& GetReference(const Ptr<T> p)
389 {
390 return *PeekPointer(p);
391 }
392};
393
394namespace internal
395{
396
397// Duplicate of struct EventMemberImplObjTraits<T> as defined in make-event.h
398// We repeat it here to declare a specialization on Ptr<T>
399// without making this header dependent on make-event.h
400template <typename T>
402
403/**
404 * @ingroup makeeventmemptr
405 * Helper for the MakeEvent functions which take a class method.
406 *
407 * This is the specialization for Ptr types.
408 *
409 * @tparam T \deduced The type of the underlying object.
410 */
411template <typename T>
413{
414 /**
415 * @param [in] p Object pointer
416 * @return A reference to the object pointed to by p
417 */
418 static T& GetReference(Ptr<T> p)
419 {
420 return *PeekPointer(p);
421 }
422};
423
424} // namespace internal
425
426} // namespace ns3
427
428namespace ns3
429{
430
431class Object;
432
433/*************************************************
434 * friend non-member function implementations
435 ************************************************/
436
437template <typename T, typename... Ts>
438Ptr<T>
439Create(Ts&&... args)
440{
441 static_assert(!std::is_base_of_v<Object, T>,
442 "Use CreateObject() instead of Create() for Object subclasses");
443 return Ptr<T>(new T(std::forward<Ts>(args)...), false);
444}
445
446template <typename U>
447U*
449{
450 return p.m_ptr;
451}
452
453template <typename U>
454U*
456{
457 p.Acquire();
458 return p.m_ptr;
459}
460
461template <typename T>
462std::ostream&
463operator<<(std::ostream& os, const Ptr<T>& p)
464{
465 os << PeekPointer(p);
466 return os;
467}
468
469template <typename T1, typename T2>
470bool
471operator==(const Ptr<T1>& lhs, T2 const* rhs)
472{
473 return PeekPointer(lhs) == rhs;
474}
475
476template <typename T1, typename T2>
477bool
478operator==(T1 const* lhs, Ptr<T2>& rhs)
479{
480 return lhs == PeekPointer(rhs);
481}
482
483template <typename T1, typename T2>
484bool
485operator!=(const Ptr<T1>& lhs, T2 const* rhs)
486{
487 return PeekPointer(lhs) != rhs;
488}
489
490template <typename T1, typename T2>
491bool
492operator!=(T1 const* lhs, Ptr<T2>& rhs)
493{
494 return lhs != PeekPointer(rhs);
495}
496
497template <typename T1, typename T2>
498bool
499operator==(const Ptr<T1>& lhs, const Ptr<T2>& rhs)
500{
501 return PeekPointer(lhs) == PeekPointer(rhs);
502}
503
504template <typename T1, typename T2>
505bool
506operator!=(const Ptr<T1>& lhs, const Ptr<T2>& rhs)
507{
508 return PeekPointer(lhs) != PeekPointer(rhs);
509}
510
511template <typename T1, typename T2>
512std::enable_if_t<std::is_same_v<T2, std::nullptr_t>, bool>
513operator==(const Ptr<T1>& lhs, T2 rhs)
514{
515 return PeekPointer(lhs) == nullptr;
516}
517
518template <typename T1, typename T2>
519std::enable_if_t<std::is_same_v<T2, std::nullptr_t>, bool>
520operator!=(const Ptr<T1>& lhs, T2 rhs)
521{
522 return PeekPointer(lhs) != nullptr;
523}
524
525template <typename T>
526bool
527operator<(const Ptr<T>& lhs, const Ptr<T>& rhs)
528{
529 return PeekPointer<T>(lhs) < PeekPointer<T>(rhs);
530}
531
532template <typename T>
533bool
534operator<(const Ptr<T>& lhs, const Ptr<const T>& rhs)
535{
536 return PeekPointer<T>(lhs) < PeekPointer<const T>(rhs);
537}
538
539template <typename T>
540bool
541operator<(const Ptr<const T>& lhs, const Ptr<T>& rhs)
542{
543 return PeekPointer<const T>(lhs) < PeekPointer<T>(rhs);
544}
545
546template <typename T>
547bool
548operator<=(const Ptr<T>& lhs, const Ptr<T>& rhs)
549{
550 return PeekPointer<T>(lhs) <= PeekPointer<T>(rhs);
551}
552
553template <typename T>
554bool
555operator>(const Ptr<T>& lhs, const Ptr<T>& rhs)
556{
557 return PeekPointer<T>(lhs) > PeekPointer<T>(rhs);
558}
559
560template <typename T>
561bool
562operator>=(const Ptr<T>& lhs, const Ptr<T>& rhs)
563{
564 return PeekPointer<T>(lhs) >= PeekPointer<T>(rhs);
565}
566
567/**
568 * Cast a Ptr.
569 *
570 * @tparam T1 \deduced The desired type to cast to.
571 * @tparam T2 \deduced The type of the original Ptr.
572 * @param [in] p The original Ptr.
573 * @return The result of the cast.
574 */
575/** @{ */
576template <typename T1, typename T2>
577Ptr<T1>
579{
580 return Ptr<T1>(const_cast<T1*>(PeekPointer(p)));
581}
582
583template <typename T1, typename T2>
584Ptr<T1>
586{
587 return Ptr<T1>(dynamic_cast<T1*>(PeekPointer(p)));
588}
589
590template <typename T1, typename T2>
591Ptr<T1>
593{
594 return Ptr<T1>(static_cast<T1*>(PeekPointer(p)));
595}
596
597/** @} */
598
599/**
600 * Return a deep copy of a Ptr.
601 *
602 * @tparam T \deduced The type of the underlying object.
603 * @param [in] object The object Ptr to copy.
604 * @returns The copy.
605 */
606/** @{ */
607template <typename T>
608Ptr<T>
610{
611 Ptr<T> p = Ptr<T>(new T(*PeekPointer(object)), false);
612 return p;
613}
614
615template <typename T>
616Ptr<T>
617Copy(Ptr<const T> object)
618{
619 Ptr<T> p = Ptr<T>(new T(*PeekPointer(object)), false);
620 return p;
621}
622
623/** @} */
624
625/****************************************************
626 * Member method implementations.
627 ***************************************************/
628
629template <typename T>
630void
632{
633 if (m_ptr != nullptr)
634 {
635 m_ptr->Ref();
636 }
637}
638
639template <typename T>
641 : m_ptr(nullptr)
642{
643}
644
645template <typename T>
647 : m_ptr(ptr)
648{
649 Acquire();
650}
651
652template <typename T>
653Ptr<T>::Ptr(T* ptr, bool ref)
654 : m_ptr(ptr)
655{
656 if (ref)
657 {
658 Acquire();
659 }
660}
661
662template <typename T>
664 : m_ptr(nullptr)
665{
666 T* ptr = PeekPointer(o);
667 if (ptr != nullptr)
668 {
669 m_ptr = ptr;
670 Acquire();
671 }
672}
673
674template <typename T>
675template <typename U>
677 : m_ptr(PeekPointer(o))
678{
679 Acquire();
680}
681
682template <typename T>
684{
685 if (m_ptr != nullptr)
686 {
687 m_ptr->Unref();
688 }
689}
690
691template <typename T>
692Ptr<T>&
694{
695 if (&o == this)
696 {
697 return *this;
698 }
699 if (m_ptr != nullptr)
700 {
701 m_ptr->Unref();
702 }
703 m_ptr = o.m_ptr;
704 Acquire();
705 return *this;
706}
707
708template <typename T>
709T*
711{
712 NS_ASSERT_MSG(m_ptr, "Attempted to dereference zero pointer");
713 return m_ptr;
714}
715
716template <typename T>
717T*
719{
720 NS_ASSERT_MSG(m_ptr, "Attempted to dereference zero pointer");
721 return m_ptr;
722}
723
724template <typename T>
725T&
727{
728 NS_ASSERT_MSG(m_ptr, "Attempted to dereference zero pointer");
729 return *m_ptr;
730}
731
732template <typename T>
733T&
735{
736 NS_ASSERT_MSG(m_ptr, "Attempted to dereference zero pointer");
737 return *m_ptr;
738}
739
740template <typename T>
742{
743 return m_ptr != nullptr;
744}
745
746} // namespace ns3
747
748/****************************************************
749 * Global Functions (outside namespace ns3)
750 ***************************************************/
751
752/**
753 * @ingroup ptr
754 * Hashing functor taking a `Ptr` and returning a @c std::size_t.
755 * For use with `unordered_map` and `unordered_set`.
756 *
757 * @note When a `Ptr` is used in a container the lifetime of the underlying
758 * object is at least as long as the container. In other words,
759 * you need to remove the object from the container when you are done with
760 * it, otherwise the object will persist until the container itself is
761 * deleted.
762 *
763 * @tparam T \deduced The type held by the `Ptr`
764 */
765template <class T>
766struct std::hash<ns3::Ptr<T>>
767{
768 /**
769 * The functor.
770 * @param p The `Ptr` value to hash.
771 * @return the hash
772 */
773 std::size_t operator()(ns3::Ptr<T> p) const
774 {
775 return std::hash<const T*>()(ns3::PeekPointer(p));
776 }
777};
778
779#endif /* PTR_H */
NS_ASSERT() and NS_ASSERT_MSG() macro definitions.
Smart pointer class similar to boost::intrusive_ptr.
Ptr(T *ptr)
Create a smart pointer which points to the object pointed to by the input raw pointer ptr.
Definition ptr.h:646
Ptr(const Ptr &o)
Copy by referencing the same underlying object.
Definition ptr.h:663
T & operator*()
A dereference.
Definition ptr.h:734
Ptr()
Create an empty smart pointer.
Definition ptr.h:640
void Acquire() const
Mark this as a a reference by incrementing the reference count.
Definition ptr.h:631
friend U * PeekPointer(const Ptr< U > &p)
Get a temporary pointer to the underlying object.
Definition ptr.h:448
Ptr(const Ptr< U > &o)
Copy, removing const qualifier.
Definition ptr.h:676
T * operator->()
An lvalue member access.
Definition ptr.h:710
T & operator*() const
A const dereference.
Definition ptr.h:726
friend U * GetPointer(const Ptr< U > &p)
Get a permanent pointer to the underlying object.
Definition ptr.h:455
Ptr< T > & operator=(const Ptr &o)
Assignment operator by referencing the same underlying object.
Definition ptr.h:693
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:653
~Ptr()
Destructor.
Definition ptr.h:683
T * m_ptr
The pointer.
Definition ptr.h:70
T * operator->() const
An rvalue member access.
Definition ptr.h:718
#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:75
bool operator>=(const int64x64_t &lhs, const int64x64_t &rhs)
Greater or equal operator.
Definition int64x64.h:162
bool operator<=(const int64x64_t &lhs, const int64x64_t &rhs)
Less or equal operator.
Definition int64x64.h:149
bool operator>(const Length &left, const Length &right)
Check if left has a value greater than right.
Definition length.cc:410
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:439
Every class exported by the ns3 library is enclosed in the ns3 namespace.
U * PeekPointer(const Ptr< U > &p)
Definition ptr.h:448
bool operator!=(Callback< R, Args... > a, Callback< R, Args... > b)
Inequality test.
Definition callback.h:658
bool operator==(const EventId &a, const EventId &b)
Definition event-id.h:155
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition angles.cc:148
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 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:585
bool operator<(const EventId &a, const EventId &b)
Definition event-id.h:168
Ptr< T > Copy(Ptr< T > object)
Return a deep copy of a Ptr.
Definition ptr.h:609
Ptr< T1 > StaticCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:592
U * GetPointer(const Ptr< U > &p)
Definition ptr.h:455
Ptr< T1 > ConstCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:578
static T & GetReference(const Ptr< T > p)
Definition ptr.h:388
Helper for the MakeEvent functions which take a class method.
Definition ptr.h:401
std::size_t operator()(ns3::Ptr< T > p) const
The functor.
Definition ptr.h:773