Panda3D
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  */
68 template <class T>
69 class PointerTo : public PointerToBase<T> {
70 public:
71  typedef typename PointerToBase<T>::To To;
72 PUBLISHED:
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 
78 public:
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 
102 PUBLISHED:
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  */
143 template <class T>
144 class ConstPointerTo : public PointerToBase<T> {
145 public:
146  typedef typename PointerToBase<T>::To To;
147 PUBLISHED:
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 
154 public:
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 
187 PUBLISHED:
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!
207 template <class T>
208 void swap(PointerTo<T> &one, PointerTo<T> &two) noexcept {
209  one.swap(two);
210 }
211 
212 template <class T>
213 void swap(ConstPointerTo<T> &one, ConstPointerTo<T> &two) noexcept {
214  one.swap(two);
215 }
216 
217 
218 // Define owner_less specializations, for completeness' sake.
219 namespace 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 
247 template<class T>
248 INLINE TypeHandle _get_type_handle(const PointerTo<T> *) {
249  return T::get_class_type();
250 }
251 
252 template<class T>
253 INLINE 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.
Definition: pointerToBase.h:29
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.
Definition: pointerToVoid.I:27
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
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.