Panda3D
Loading...
Searching...
No Matches
pointerTo.h
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file pointerTo.h
10 * @author drose
11 * @date 1998-10-23
12 */
13
14#ifndef POINTERTO_H
15#define POINTERTO_H
16
17/**
18 * This file defines the classes PointerTo and ConstPointerTo (and their
19 * abbreviations, PT and CPT). These should be used in place of traditional
20 * C-style pointers wherever implicit reference counting is desired.
21 *
22 * The syntax is: instead of:
23 *
24 * PointerTo<MyClass> p; MyClass *p;
25 * PT(MyClass) p;
26 *
27 * ConstPointerTo<MyClass> p; const MyClass *p;
28 * CPT(MyClass) p;
29 *
30 * PointerTo and ConstPointerTo will automatically increment the object's
31 * reference count while the pointer is kept. When the PointerTo object is
32 * reassigned or goes out of scope, the reference count is automatically
33 * decremented. If the reference count reaches zero, the object is freed.
34 *
35 * Note that const PointerTo<MyClass> is different from
36 * ConstPointerTo<MyClass>. A const PointerTo may not reassign its pointer,
37 * but it may still modify the contents at that address. On the other hand, a
38 * ConstPointerTo may reassign its pointer at will, but may not modify the
39 * contents. It is like the difference between (MyClass * const) and
40 * (const MyClass *).
41 *
42 * In order to use PointerTo, it is necessary that the thing pointed to
43 * --MyClass in the above example--either inherits from ReferenceCount, or is
44 * a proxy built with RefCountProxy or RefCountObj (see referenceCount.h).
45 * However, also see PointerToArray, which does not have this restriction.
46 *
47 * It is crucial that the PointerTo object is only used to refer to objects
48 * allocated from the free store, for which delete is a sensible thing to do.
49 * If you assign a PointerTo to an automatic variable (allocated from the
50 * stack, for instance), bad things will certainly happen when the reference
51 * count reaches zero and it tries to delete it.
52 *
53 * It's also important to remember that, as always, a virtual destructor is
54 * required if you plan to support polymorphism. That is, if you define a
55 * PointerTo to some base type, and assign to it instances of a class derived
56 * from that base class, the base class must have a virtual destructor in
57 * order to properly destruct the derived object when it is deleted.
58 */
59
60#include "pandabase.h"
61#include "pointerToBase.h"
62#include "register_type.h"
63
64/**
65 * PointerTo is a template class which implements a smart pointer to an object
66 * derived from ReferenceCount.
67 */
68template <class T>
69class PointerTo : public PointerToBase<T> {
70public:
71 typedef typename PointerToBase<T>::To To;
72PUBLISHED:
73 ALWAYS_INLINE constexpr PointerTo() noexcept = default;
74 ALWAYS_INLINE explicit constexpr PointerTo(std::nullptr_t) noexcept {}
75 ALWAYS_INLINE PointerTo(To *ptr) noexcept;
76 INLINE PointerTo(const PointerTo<T> &copy);
77
78public:
79 INLINE PointerTo(PointerTo<T> &&from) noexcept;
80
81 template<class Y>
82 ALWAYS_INLINE explicit PointerTo(Y *ptr) noexcept;
83 template<class Y>
84 ALWAYS_INLINE PointerTo(const PointerTo<Y> &r) noexcept;
85 template<class Y>
86 ALWAYS_INLINE PointerTo(PointerTo<Y> &&r) noexcept;
87
88 INLINE PointerTo<T> &operator = (PointerTo<T> &&from) noexcept;
89
90 template<class Y>
91 ALWAYS_INLINE PointerTo<T> &operator = (const PointerTo<Y> &r) noexcept;
92 template<class Y>
93 ALWAYS_INLINE PointerTo<T> &operator = (PointerTo<Y> &&r) noexcept;
94
95 constexpr To &operator *() const noexcept;
96 constexpr To *operator -> () const noexcept;
97 // MSVC.NET 2005 insists that we use T *, and not To *, here.
98 constexpr operator T *() const noexcept;
99
100 INLINE T *&cheat();
101
102PUBLISHED:
103 // When downcasting to a derived class from a PointerTo<BaseClass>, C++
104 // would normally require you to cast twice: once to an actual BaseClass
105 // pointer, and then again to your desired pointer. You can use the handy
106 // function p() to avoid this first cast and make your code look a bit
107 // cleaner.
108
109 // e.g. instead of (MyType *)(BaseClass *)ptr, use (MyType *)ptr.p()
110
111 // If your base class is a derivative of TypedObject, you might want to use
112 // the DCAST macro defined in typedObject.h instead, e.g. DCAST(MyType,
113 // ptr). This provides a clean downcast that doesn't require .p() or any
114 // double-casting, and it can be run-time checked for correctness.
115 constexpr To *p() const noexcept;
116
117 INLINE PointerTo<T> &operator = (To *ptr);
118 INLINE PointerTo<T> &operator = (const PointerTo<T> &copy);
119
120 // These functions normally wouldn't need to be redefined here, but we do so
121 // anyway just to help out interrogate (which doesn't seem to want to
122 // automatically export the PointerToBase class). When this works again in
123 // interrogate, we can remove these.
124#ifdef CPPPARSER
125 INLINE bool is_null() const;
126 INLINE void clear();
127#endif
128};
129
130
131/**
132 * A ConstPointerTo is similar to a PointerTo, except it keeps a const pointer
133 * to the thing.
134 *
135 * (Actually, it keeps a non-const pointer, because it must be allowed to
136 * adjust the reference counts, and it must be able to delete it when the
137 * reference count goes to zero. But it presents only a const pointer to the
138 * outside world.)
139 *
140 * Notice that a PointerTo may be assigned to a ConstPointerTo, but a
141 * ConstPointerTo may not be assigned to a PointerTo.
142 */
143template <class T>
144class ConstPointerTo : public PointerToBase<T> {
145public:
146 typedef typename PointerToBase<T>::To To;
147PUBLISHED:
148 ALWAYS_INLINE constexpr ConstPointerTo() noexcept = default;
149 ALWAYS_INLINE explicit constexpr ConstPointerTo(std::nullptr_t) noexcept {}
150 ALWAYS_INLINE ConstPointerTo(const To *ptr) noexcept;
151 INLINE ConstPointerTo(const PointerTo<T> &copy);
152 INLINE ConstPointerTo(const ConstPointerTo<T> &copy);
153
154public:
155 INLINE ConstPointerTo(PointerTo<T> &&from) noexcept;
156 INLINE ConstPointerTo(ConstPointerTo<T> &&from) noexcept;
157
158 template<class Y>
159 ALWAYS_INLINE explicit ConstPointerTo(const Y *ptr) noexcept;
160 template<class Y>
161 ALWAYS_INLINE ConstPointerTo(const PointerTo<Y> &r) noexcept;
162 template<class Y>
163 ALWAYS_INLINE ConstPointerTo(const ConstPointerTo<Y> &r) noexcept;
164 template<class Y>
165 ALWAYS_INLINE ConstPointerTo(PointerTo<Y> &&r) noexcept;
166 template<class Y>
167 ALWAYS_INLINE ConstPointerTo(ConstPointerTo<Y> &&r) noexcept;
168
169 INLINE ConstPointerTo<T> &operator = (PointerTo<T> &&from) noexcept;
170 INLINE ConstPointerTo<T> &operator = (ConstPointerTo<T> &&from) noexcept;
171
172 template<class Y>
173 ALWAYS_INLINE ConstPointerTo<T> &operator = (const PointerTo<Y> &r) noexcept;
174 template<class Y>
175 ALWAYS_INLINE ConstPointerTo<T> &operator = (const ConstPointerTo<Y> &r) noexcept;
176 template<class Y>
177 ALWAYS_INLINE ConstPointerTo<T> &operator = (PointerTo<Y> &&r) noexcept;
178 template<class Y>
179 ALWAYS_INLINE ConstPointerTo<T> &operator = (ConstPointerTo<Y> &&r) noexcept;
180
181 constexpr const To &operator *() const noexcept;
182 constexpr const To *operator -> () const noexcept;
183 constexpr operator const T *() const noexcept;
184
185 INLINE const T *&cheat();
186
187PUBLISHED:
188 constexpr const To *p() const noexcept;
189
190 INLINE ConstPointerTo<T> &operator = (const To *ptr);
191 INLINE ConstPointerTo<T> &operator = (const PointerTo<T> &copy);
192 INLINE ConstPointerTo<T> &operator = (const ConstPointerTo<T> &copy);
193
194 // This functions normally wouldn't need to be redefined here, but we do so
195 // anyway just to help out interrogate (which doesn't seem to want to
196 // automatically export the PointerToBase class). When this works again in
197 // interrogate, we can remove this.
198#ifdef CPPPARSER
199 INLINE void clear();
200#endif
201};
202
203
204// The existence of these functions makes it possible to sort vectors of
205// PointerTo objects without incurring the cost of unnecessary reference count
206// changes. The performance difference is dramatic!
207template <class T>
208void swap(PointerTo<T> &one, PointerTo<T> &two) noexcept {
209 one.swap(two);
210}
211
212template <class T>
213void swap(ConstPointerTo<T> &one, ConstPointerTo<T> &two) noexcept {
214 one.swap(two);
215}
216
217
218// Define owner_less specializations, for completeness' sake.
219namespace std {
220 template<class T>
221 struct owner_less<PointerTo<T> > {
222 bool operator () (const PointerTo<T> &lhs,
223 const PointerTo<T> &rhs) const noexcept {
224 return lhs < rhs;
225 }
226 };
227
228 template<class T>
229 struct owner_less<ConstPointerTo<T> > {
230 bool operator () (const ConstPointerTo<T> &lhs,
231 const ConstPointerTo<T> &rhs) const noexcept {
232 return lhs < rhs;
233 }
234 };
235}
236
237
238// Finally, we'll define a couple of handy abbreviations to save on all that
239// wasted typing time.
240
241#define PT(type) PointerTo< type >
242#define CPT(type) ConstPointerTo< type >
243
244// Now that we have defined PointerTo, we can define what it means to take the
245// TypeHandle of a PointerTo object.
246
247template<class T>
248INLINE TypeHandle _get_type_handle(const PointerTo<T> *) {
249 return T::get_class_type();
250}
251
252template<class T>
253INLINE TypeHandle _get_type_handle(const ConstPointerTo<T> *) {
254 return T::get_class_type();
255}
256
257
258#include "pointerTo.I"
259
260#endif
A ConstPointerTo is similar to a PointerTo, except it keeps a const pointer to the thing.
Definition pointerTo.h:144
constexpr const To * p() const noexcept
Returns an ordinary pointer instead of a ConstPointerTo.
Definition pointerTo.I:406
const T *& cheat()
Returns a reference to the underlying pointer.
Definition pointerTo.I:396
This is the base class for PointerTo and ConstPointerTo.
void clear()
A convenient way to set the PointerTo object to NULL.
constexpr bool is_null() const
Returns true if the PointerTo is a NULL pointer, false otherwise.
This file defines the classes PointerTo and ConstPointerTo (and their abbreviations,...
Definition pointerTo.h:69
T *& cheat()
Returns a reference to the underlying pointer.
Definition pointerTo.I:150
constexpr To * p() const noexcept
Returns an ordinary pointer instead of a PointerTo.
Definition pointerTo.I:160
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
STL namespace.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.