Panda3D
pointerToArray.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 pointerToArray.h
10 * @author drose
11 * @date 1999-01-14
12 */
13
14#ifndef POINTERTOARRAY_H
15#define POINTERTOARRAY_H
16
17/*
18 * This file defines the classes PointerToArray and ConstPointerToArray (and
19 * their abbreviations, PTA and CPTA), which are extensions to the PointerTo
20 * class that support reference-counted arrays.
21 *
22 * You may think of a PointerToArray as the same thing as a traditional
23 * C-style array. However, it actually stores a pointer to an STL vector,
24 * which is then reference-counted. Thus, most vector operations may be
25 * applied directly to a PointerToArray object, including dynamic resizing via
26 * push_back() and pop_back().
27 *
28 * Unlike the PointerTo class, the PointerToArray may store pointers to any
29 * kind of object, not just those derived from ReferenceCount.
30 *
31 * Like PointerTo and ConstPointerTo, the macro abbreviations PTA and CPTA are
32 * defined for convenience.
33 *
34 * Some examples of syntax: instead of:
35 *
36 * PTA(int) array(10); int *array = new int[10];
37 * memset(array, 0, sizeof(int) * 10); memset(array, 0, sizeof(int) * 10);
38 * array[i] = array[i+1]; array[i] = array[i+1];
39 * num_elements = array.size(); (no equivalent)
40 *
41 * PTA(int) copy = array; int *copy = array;
42 *
43 * Note that in the above example, unlike an STL vector (but like a C-style
44 * array), assigning a PointerToArray object from another simply copies the
45 * pointer, and does not copy individual elements. (Of course, reference
46 * counts are adjusted appropriately.) If you actually wanted an
47 * element-by-element copy of the array, you would do this:
48 *
49 * PTA(int) copy(0); // Create a pointer to an empty vector.
50 * copy.v() = array.v(); // v() is the STL vector itself.
51 *
52 * The (0) parameter to the constructor in the above example is crucial. When
53 * a numeric length parameter, such as zero, is given to the constructor, it
54 * means to define a new STL vector with that number of elements initially in
55 * it. If no parameter is given, on the other hand, it means the
56 * PointerToArray should point to nothing--no STL vector is created. This is
57 * equivalent to a C array that points to NULL.
58 */
59
60#include "pandabase.h"
61
62#include "pointerToArrayBase.h"
63
64#if (defined(WIN32_VC) || defined(WIN64_VC)) && !defined(__INTEL_COMPILER)
65// disable mysterious MSVC warning for static inline PTA::empty_array method
66// need to chk if vc 7.0 still has this problem, would like to keep it enabled
67#pragma warning (disable : 4506)
68#endif
69
70template <class Element>
72
73/**
74 * A special kind of PointerTo that stores an array of the indicated element
75 * type, instead of a single element. This is actually implemented as an STL
76 * vector, using the RefCountObj class to wrap it up with a reference count.
77 *
78 * We actually inherit from NodeRefCountObj these days, which adds node_ref()
79 * and node_unref() to the standard ref() and unref(). This is particularly
80 * useful for GeomVertexArrayData; other classes may or may not find this
81 * additional counter useful, but since it adds relatively little overhead
82 * (compared with what is presumably a largish array), we go ahead and add it
83 * here, even though it is inherited by many different parts of the system
84 * that may not use it.
85 */
86template <class Element>
87class PointerToArray : public PointerToArrayBase<Element> {
88public:
89 // By hiding this template from interrogate, we would improve compile-time
90 // speed and memory utilization. However, we do want to export a minimal
91 // subset of this class. So we define just the exportable interface here.
92#ifdef CPPPARSER
93PUBLISHED:
94 typedef typename pvector<Element>::size_type size_type;
95 INLINE PointerToArray(TypeHandle type_handle = get_type_handle(Element));
96 INLINE static PointerToArray<Element> empty_array(size_type n, TypeHandle type_handle = get_type_handle(Element));
97 INLINE PointerToArray(const PointerToArray<Element> &copy);
98
99 EXTENSION(PointerToArray(PyObject *self, PyObject *source));
100
101 INLINE void clear();
102
103 INLINE size_type size() const;
104 INLINE void push_back(const Element &x);
105 INLINE void pop_back();
106 INLINE const Element &get_element(size_type n) const;
107 INLINE void set_element(size_type n, const Element &value);
108 EXTENSION(const Element &__getitem__(size_type n) const);
109 EXTENSION(void __setitem__(size_type n, const Element &value));
110 EXTENSION(PyObject *get_data() const);
111 EXTENSION(void set_data(PyObject *data));
112 EXTENSION(PyObject *get_subdata(size_type n, size_type count) const);
113 INLINE void set_subdata(size_type n, size_type count, const std::string &data);
114 INLINE int get_ref_count() const;
115 INLINE int get_node_ref_count() const;
116
117 INLINE size_t count(const Element &) const;
118
119#ifdef HAVE_PYTHON
120 EXTENSION(PyObject *__reduce__(PyObject *self) const);
121
122 EXTENSION(int __getbuffer__(PyObject *self, Py_buffer *view, int flags));
123 EXTENSION(void __releasebuffer__(PyObject *self, Py_buffer *view) const);
124#endif
125
126#else // CPPPARSER
127 // This is the actual, complete interface.
128 typedef typename PointerToArrayBase<Element>::To To;
129 typedef typename pvector<Element>::value_type value_type;
130 typedef typename pvector<Element>::reference reference;
131 typedef typename pvector<Element>::const_reference const_reference;
132 typedef typename pvector<Element>::iterator iterator;
133 typedef typename pvector<Element>::const_iterator const_iterator;
134 typedef typename pvector<Element>::reverse_iterator reverse_iterator;
135 typedef typename pvector<Element>::const_reverse_iterator const_reverse_iterator;
136 typedef typename pvector<Element>::difference_type difference_type;
137 typedef typename pvector<Element>::size_type size_type;
138
139public:
140 INLINE PointerToArray(TypeHandle type_handle = get_type_handle(Element));
141 INLINE static PointerToArray<Element> empty_array(size_type n, TypeHandle type_handle = get_type_handle(Element));
142 INLINE PointerToArray(size_type n, const Element &value, TypeHandle type_handle = get_type_handle(Element));
143 INLINE PointerToArray(const Element *begin, const Element *end, TypeHandle type_handle = get_type_handle(Element));
144 INLINE PointerToArray(const PointerToArray<Element> &copy);
145 INLINE PointerToArray(PointerToArray<Element> &&from) noexcept;
146 INLINE explicit PointerToArray(pvector<Element> &&from, TypeHandle type_handle = get_type_handle(Element));
147
148public:
149 // Duplicating the interface of vector. The following member functions are
150 // all const, because they do not reassign the pointer--they operate only
151 // within the vector itself, which is non-const in this class.
152
153 INLINE iterator begin() const;
154 INLINE iterator end() const;
155 INLINE typename PointerToArray<Element>::reverse_iterator rbegin() const;
156 INLINE typename PointerToArray<Element>::reverse_iterator rend() const;
157
158 // Equality and comparison operators are pointerwise for PointerToArrays,
159 // not elementwise as in vector.
160 INLINE size_type size() const;
161 INLINE size_type max_size() const;
162 INLINE bool empty() const;
163
164 INLINE void clear();
165
166 // Functions specific to vectors.
167 INLINE void reserve(size_type n);
168 INLINE void resize(size_type n);
169 INLINE size_type capacity() const;
170 INLINE reference front() const;
171 INLINE reference back() const;
172 INLINE iterator insert(iterator position, const Element &x);
173 INLINE void insert(iterator position, size_type n, const Element &x);
174
175 // We don't define the insert() method that accepts a pair of iterators to
176 // copy from. That's problematic because of the whole member template
177 // thing. If you really need this, use pta.v().insert(...); if you're doing
178 // this on a vector that has to be exported from the DLL, you should use
179 // insert_into_vector(pta.v(), ...).
180
181 INLINE void erase(iterator position);
182 INLINE void erase(iterator first, iterator last);
183
184#if !defined(WIN32_VC) && !defined (WIN64_VC)
185 INLINE reference operator [](size_type n) const;
186 INLINE reference operator [](int n) const;
187#endif
188
189 INLINE void push_back(const Element &x);
190 INLINE void pop_back();
191 INLINE void make_empty();
192
193 INLINE operator Element *() const;
194 INLINE Element *p() const;
195 INLINE pvector<Element> &v() const;
196 INLINE ReferenceCountedVector<Element> *v0() const;
197
198 // Methods to help out Python and other high-level languages.
199 INLINE const Element &get_element(size_type n) const;
200 INLINE void set_element(size_type n, const Element &value);
201 INLINE std::string get_data() const;
202 INLINE void set_data(const std::string &data);
203 INLINE std::string get_subdata(size_type n, size_type count) const;
204 INLINE void set_subdata(size_type n, size_type count, const std::string &data);
205
206 // These functions are only to be used in Reading through BamReader. They
207 // are designed to work in pairs, so that you register what is returned by
208 // get_void_ptr with BamReader and when you are setting another PTA with
209 // what is returned by BamReader, you set it with set_void_ptr. If you used
210 // the provided macro of READ_PTA, this is done for you. So you should
211 // never call these functions directly
212 INLINE void *get_void_ptr() const;
213 INLINE void set_void_ptr(void* p);
214
215 INLINE int get_ref_count() const;
216 INLINE void ref() const;
217 INLINE bool unref() const;
218
219 INLINE int get_node_ref_count() const;
220 INLINE void node_ref() const;
221 INLINE bool node_unref() const;
222
223 INLINE size_t count(const Element &) const;
224
225#endif // CPPPARSER
226
227public:
228 // Reassignment is by pointer, not memberwise as with a vector.
230 operator = (ReferenceCountedVector<Element> *ptr);
232 operator = (const PointerToArray<Element> &copy);
234 operator = (PointerToArray<Element> &&from) noexcept;
235
236private:
237 TypeHandle _type_handle;
238
239 // This static empty array is kept around just so we can return something
240 // meaningful when begin() or end() is called and we have a NULL pointer.
241 // It might not be shared properly between different .so's, since it's a
242 // static member of a template class, but we don't really care.
243 static pvector<Element> _empty_array;
244
245 friend class ConstPointerToArray<Element>;
246};
247
248/**
249 * Similar to PointerToArray, except that its contents may not be modified.
250 */
251template <class Element>
253public:
254 INLINE ConstPointerToArray(TypeHandle type_handle = get_type_handle(Element));
255
256 // By hiding this template from interrogate, we would improve compile-time
257 // speed and memory utilization. However, we do want to export a minimal
258 // subset of this class. So we define just the exportable interface here.
259#ifdef CPPPARSER
260PUBLISHED:
263
264 INLINE void clear();
265
266 typedef typename pvector<Element>::size_type size_type;
267 INLINE size_type size() const;
268 INLINE const Element &get_element(size_type n) const;
269 EXTENSION(const Element &__getitem__(size_type n) const);
270 EXTENSION(PyObject *get_data() const);
271 EXTENSION(PyObject *get_subdata(size_type n, size_type count) const);
272 INLINE int get_ref_count() const;
273 INLINE int get_node_ref_count() const;
274
275 INLINE size_t count(const Element &) const;
276
277#ifdef HAVE_PYTHON
278 EXTENSION(PyObject *__reduce__(PyObject *self) const);
279
280 EXTENSION(int __getbuffer__(PyObject *self, Py_buffer *view, int flags) const);
281 EXTENSION(void __releasebuffer__(PyObject *self, Py_buffer *view) const);
282#endif
283
284#else // CPPPARSER
285 // This is the actual, complete interface.
286 typedef typename PointerToArrayBase<Element>::To To;
287 typedef typename pvector<Element>::value_type value_type;
288 typedef typename pvector<Element>::const_reference reference;
289 typedef typename pvector<Element>::const_reference const_reference;
290 typedef typename pvector<Element>::const_iterator iterator;
291 typedef typename pvector<Element>::const_iterator const_iterator;
292#if defined(WIN32_VC) || defined(WIN64_VC)
293 // VC++ seems to break the const_reverse_iterator definition somehow.
294 typedef typename pvector<Element>::reverse_iterator reverse_iterator;
295#else
296 typedef typename pvector<Element>::const_reverse_iterator reverse_iterator;
297#endif
298 typedef typename pvector<Element>::const_reverse_iterator const_reverse_iterator;
299 typedef typename pvector<Element>::difference_type difference_type;
300 typedef typename pvector<Element>::size_type size_type;
301
302 INLINE ConstPointerToArray(const Element *begin, const Element *end, TypeHandle type_handle = get_type_handle(Element));
305 INLINE ConstPointerToArray(PointerToArray<Element> &&from) noexcept;
307 INLINE explicit ConstPointerToArray(pvector<Element> &&from, TypeHandle type_handle = get_type_handle(Element));
308
309 // Duplicating the interface of vector.
310
311 INLINE iterator begin() const;
312 INLINE iterator end() const;
313 INLINE typename ConstPointerToArray<Element>::reverse_iterator rbegin() const;
314 INLINE typename ConstPointerToArray<Element>::reverse_iterator rend() const;
315
316 // Equality and comparison operators are pointerwise for PointerToArrays,
317 // not elementwise as in vector.
318
319 INLINE size_type size() const;
320 INLINE size_type max_size() const;
321 INLINE bool empty() const;
322
323 INLINE void clear();
324
325 // Functions specific to vectors.
326 INLINE size_type capacity() const;
327 INLINE reference front() const;
328 INLINE reference back() const;
329
330#if !defined(WIN32_VC) && !defined(WIN64_VC)
331 INLINE reference operator [](size_type n) const;
332 INLINE reference operator [](int n) const;
333#endif
334
335 INLINE operator const Element *() const;
336 INLINE const Element *p() const;
337 INLINE const pvector<Element> &v() const;
338 INLINE const ReferenceCountedVector<Element> *v0() const;
340
341 // Methods to help out Python and other high-level languages.
342 INLINE const Element &get_element(size_type n) const;
343 INLINE std::string get_data() const;
344 INLINE std::string get_subdata(size_type n, size_type count) const;
345
346 INLINE int get_ref_count() const;
347 INLINE void ref() const;
348 INLINE bool unref() const;
349
350 INLINE int get_node_ref_count() const;
351 INLINE void node_ref() const;
352 INLINE bool node_unref() const;
353
354 INLINE size_t count(const Element &) const;
355
356#endif // CPPPARSER
357
358public:
359 // Reassignment is by pointer, not memberwise as with a vector.
361 operator = (ReferenceCountedVector<Element> *ptr);
363 operator = (const PointerToArray<Element> &copy);
365 operator = (const ConstPointerToArray<Element> &copy);
367 operator = (PointerToArray<Element> &&from) noexcept;
369 operator = (ConstPointerToArray<Element> &&from) noexcept;
370
371private:
372 TypeHandle _type_handle;
373
374 // This static empty array is kept around just so we can return something
375 // meangful when begin() or end() is called and we have a NULL pointer. It
376 // might not be shared properly between different .so's, since it's a static
377 // member of a template class, but we don't really care.
378 static pvector<Element> _empty_array;
379
380 friend class PointerToArray<Element>;
381};
382
383// And the brevity macros.
384#define PTA(type) PointerToArray< type >
385#define CPTA(type) ConstPointerToArray< type >
386
387#include "pointerToArray.I"
388
389#endif // HAVE_POINTERTOARRAY_H
Similar to PointerToArray, except that its contents may not be modified.
int get_ref_count() const
Returns the reference count of the underlying vector.
std::string get_data() const
This method exists mainly to access the data of the array easily from a high-level language such as P...
bool node_unref() const
Decrements the node_ref of the underlying vector.
const Element * p() const
Function p() is similar to the function from ConstPointerTo.
void clear()
To empty the PTA, use the clear() method, since assignment to NULL is problematic (given the ambiguit...
std::string get_subdata(size_type n, size_type count) const
This method exists mainly to access the data of the array easily from a high-level language such as P...
const ReferenceCountedVector< Element > * v0() const
To access the internal ReferenceCountedVector object, for very low-level fiddling.
size_t count(const Element &) const
Counts the frequency at which the given element occurs in the vector.
void node_ref() const
Increments the node_ref of the underlying vector.
int get_node_ref_count() const
Returns the node_ref of the underlying vector.
const pvector< Element > & v() const
To access the vector itself, for more direct fiddling with some of the vector's esoteric functionalit...
bool unref() const
Decrements the reference count of the underlying vector.
const Element & get_element(size_type n) const
This method exists mainly to access the elements of the array easily from a high-level language such ...
PointerToArray< Element > cast_non_const() const
Casts away the constness of the CPTA(Element), and returns an equivalent PTA(Element).
void ref() const
Increments the reference count of the underlying vector.
This is the base class for PointerToArray and ConstPointerToArray.
A special kind of PointerTo that stores an array of the indicated element type, instead of a single e...
void set_data(const std::string &data)
This method exists mainly to access the data of the array easily from a high-level language such as P...
size_t count(const Element &) const
Counts the frequency at which the given element occurs in the vector.
pvector< Element > & v() const
To access the vector itself, for more direct fiddling with some of the vector's esoteric functionalit...
void set_void_ptr(void *p)
Sets this PTA to point to the pointer passed in.
std::string get_subdata(size_type n, size_type count) const
This method exists mainly to access the data of the array easily from a high-level language such as P...
int get_ref_count() const
Returns the reference count of the underlying vector.
static PointerToArray< Element > empty_array(size_type n, TypeHandle type_handle=get_type_handle(Element))
Return an empty array of size n.
void set_subdata(size_type n, size_type count, const std::string &data)
This method exists mainly to access the data of the array easily from a high-level language such as P...
ReferenceCountedVector< Element > * v0() const
To access the internal ReferenceCountedVector object, for very low-level fiddling.
int get_node_ref_count() const
Returns the node_ref of the underlying vector.
const Element & get_element(size_type n) const
This method exists mainly to access the elements of the array easily from a high-level language such ...
void clear()
To empty the PTA, use the clear() method, since assignment to NULL is problematic (given the ambiguit...
void set_element(size_type n, const Element &value)
This method exists mainly to access the elements of the array easily from a high-level language such ...
void * get_void_ptr() const
Returns the reference to memory where the vector is stored.
void ref() const
Increments the reference count of the underlying vector.
void make_empty()
Empties the array pointed to.
bool unref() const
Decrements the reference count of the underlying vector.
Element * p() const
Function p() is similar to the function from PointerTo.
bool node_unref() const
Decrements the node_ref of the underlying vector.
void node_ref() const
Increments the node_ref of the underlying vector.
std::string get_data() const
This method exists mainly to access the data of the array easily from a high-level language such as P...
This defines the object that is actually stored and reference-counted internally by a PointerToArray.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
This is our own Panda specialization on the default STL vector.
Definition: pvector.h:42
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.