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