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 
70 template <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  */
86 template <class Element>
87 class PointerToArray : public PointerToArrayBase<Element> {
88 public:
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
93 PUBLISHED:
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 
139 public:
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 
148 public:
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 
227 public:
228  // Reassignment is by pointer, not memberwise as with a vector.
229  INLINE PointerToArray<Element> &
230  operator = (ReferenceCountedVector<Element> *ptr);
231  INLINE PointerToArray<Element> &
232  operator = (const PointerToArray<Element> &copy);
233  INLINE PointerToArray<Element> &
234  operator = (PointerToArray<Element> &&from) noexcept;
235 
236 private:
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  */
251 template <class Element>
252 class ConstPointerToArray : public PointerToArrayBase<Element> {
253 public:
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
260 PUBLISHED:
261  INLINE ConstPointerToArray(const PointerToArray<Element> &copy);
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));
303  INLINE ConstPointerToArray(const PointerToArray<Element> &copy);
305  INLINE ConstPointerToArray(PointerToArray<Element> &&from) noexcept;
306  INLINE ConstPointerToArray(ConstPointerToArray<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 
358 public:
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 
371 private:
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.