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(int __getbuffer__(PyObject *self, Py_buffer *view, int flags));
121  EXTENSION(void __releasebuffer__(PyObject *self, Py_buffer *view) const);
122 #endif
123 
124 #else // CPPPARSER
125  // This is the actual, complete interface.
126  typedef typename PointerToArrayBase<Element>::To To;
127  typedef typename pvector<Element>::value_type value_type;
128  typedef typename pvector<Element>::reference reference;
129  typedef typename pvector<Element>::const_reference const_reference;
130  typedef typename pvector<Element>::iterator iterator;
131  typedef typename pvector<Element>::const_iterator const_iterator;
132  typedef typename pvector<Element>::reverse_iterator reverse_iterator;
133  typedef typename pvector<Element>::const_reverse_iterator const_reverse_iterator;
134  typedef typename pvector<Element>::difference_type difference_type;
135  typedef typename pvector<Element>::size_type size_type;
136 
137 public:
138  INLINE PointerToArray(TypeHandle type_handle = get_type_handle(Element));
139  INLINE static PointerToArray<Element> empty_array(size_type n, TypeHandle type_handle = get_type_handle(Element));
140  INLINE PointerToArray(size_type n, const Element &value, TypeHandle type_handle = get_type_handle(Element));
141  INLINE PointerToArray(const Element *begin, const Element *end, TypeHandle type_handle = get_type_handle(Element));
142  INLINE PointerToArray(const PointerToArray<Element> &copy);
143  INLINE PointerToArray(PointerToArray<Element> &&from) noexcept;
144  INLINE explicit PointerToArray(pvector<Element> &&from, TypeHandle type_handle = get_type_handle(Element));
145 
146 public:
147  // Duplicating the interface of vector. The following member functions are
148  // all const, because they do not reassign the pointer--they operate only
149  // within the vector itself, which is non-const in this class.
150 
151  INLINE iterator begin() const;
152  INLINE iterator end() const;
153  INLINE typename PointerToArray<Element>::reverse_iterator rbegin() const;
154  INLINE typename PointerToArray<Element>::reverse_iterator rend() const;
155 
156  // Equality and comparison operators are pointerwise for PointerToArrays,
157  // not elementwise as in vector.
158  INLINE size_type size() const;
159  INLINE size_type max_size() const;
160  INLINE bool empty() const;
161 
162  INLINE void clear();
163 
164  // Functions specific to vectors.
165  INLINE void reserve(size_type n);
166  INLINE void resize(size_type n);
167  INLINE size_type capacity() const;
168  INLINE reference front() const;
169  INLINE reference back() const;
170  INLINE iterator insert(iterator position, const Element &x);
171  INLINE void insert(iterator position, size_type n, const Element &x);
172 
173  // We don't define the insert() method that accepts a pair of iterators to
174  // copy from. That's problematic because of the whole member template
175  // thing. If you really need this, use pta.v().insert(...); if you're doing
176  // this on a vector that has to be exported from the DLL, you should use
177  // insert_into_vector(pta.v(), ...).
178 
179  INLINE void erase(iterator position);
180  INLINE void erase(iterator first, iterator last);
181 
182 #if !defined(WIN32_VC) && !defined (WIN64_VC)
183  INLINE reference operator [](size_type n) const;
184  INLINE reference operator [](int n) const;
185 #endif
186 
187  INLINE void push_back(const Element &x);
188  INLINE void pop_back();
189  INLINE void make_empty();
190 
191  INLINE operator Element *() const;
192  INLINE Element *p() const;
193  INLINE pvector<Element> &v() const;
194  INLINE ReferenceCountedVector<Element> *v0() const;
195 
196  // Methods to help out Python and other high-level languages.
197  INLINE const Element &get_element(size_type n) const;
198  INLINE void set_element(size_type n, const Element &value);
199  INLINE std::string get_data() const;
200  INLINE void set_data(const std::string &data);
201  INLINE std::string get_subdata(size_type n, size_type count) const;
202  INLINE void set_subdata(size_type n, size_type count, const std::string &data);
203 
204  // These functions are only to be used in Reading through BamReader. They
205  // are designed to work in pairs, so that you register what is returned by
206  // get_void_ptr with BamReader and when you are setting another PTA with
207  // what is returned by BamReader, you set it with set_void_ptr. If you used
208  // the provided macro of READ_PTA, this is done for you. So you should
209  // never call these functions directly
210  INLINE void *get_void_ptr() const;
211  INLINE void set_void_ptr(void* p);
212 
213  INLINE int get_ref_count() const;
214  INLINE void ref() const;
215  INLINE bool unref() const;
216 
217  INLINE int get_node_ref_count() const;
218  INLINE void node_ref() const;
219  INLINE bool node_unref() const;
220 
221  INLINE size_t count(const Element &) const;
222 
223 #endif // CPPPARSER
224 
225 public:
226  // Reassignment is by pointer, not memberwise as with a vector.
227  INLINE PointerToArray<Element> &
228  operator = (ReferenceCountedVector<Element> *ptr);
229  INLINE PointerToArray<Element> &
230  operator = (const PointerToArray<Element> &copy);
231  INLINE PointerToArray<Element> &
232  operator = (PointerToArray<Element> &&from) noexcept;
233 
234 private:
235  TypeHandle _type_handle;
236 
237  // This static empty array is kept around just so we can return something
238  // meaningful when begin() or end() is called and we have a NULL pointer.
239  // It might not be shared properly between different .so's, since it's a
240  // static member of a template class, but we don't really care.
241  static pvector<Element> _empty_array;
242 
243  friend class ConstPointerToArray<Element>;
244 };
245 
246 /**
247  * Similar to PointerToArray, except that its contents may not be modified.
248  */
249 template <class Element>
250 class ConstPointerToArray : public PointerToArrayBase<Element> {
251 public:
252  INLINE ConstPointerToArray(TypeHandle type_handle = get_type_handle(Element));
253 
254  // By hiding this template from interrogate, we would improve compile-time
255  // speed and memory utilization. However, we do want to export a minimal
256  // subset of this class. So we define just the exportable interface here.
257 #ifdef CPPPARSER
258 PUBLISHED:
259  INLINE ConstPointerToArray(const PointerToArray<Element> &copy);
261 
262  INLINE void clear();
263 
264  typedef typename pvector<Element>::size_type size_type;
265  INLINE size_type size() const;
266  INLINE const Element &get_element(size_type n) const;
267  EXTENSION(const Element &__getitem__(size_type n) const);
268  EXTENSION(PyObject *get_data() const);
269  EXTENSION(PyObject *get_subdata(size_type n, size_type count) const);
270  INLINE int get_ref_count() const;
271  INLINE int get_node_ref_count() const;
272 
273  INLINE size_t count(const Element &) const;
274 
275 #ifdef HAVE_PYTHON
276  EXTENSION(int __getbuffer__(PyObject *self, Py_buffer *view, int flags) const);
277  EXTENSION(void __releasebuffer__(PyObject *self, Py_buffer *view) const);
278 #endif
279 
280 #else // CPPPARSER
281  // This is the actual, complete interface.
282  typedef typename PointerToArrayBase<Element>::To To;
283  typedef typename pvector<Element>::value_type value_type;
284  typedef typename pvector<Element>::const_reference reference;
285  typedef typename pvector<Element>::const_reference const_reference;
286  typedef typename pvector<Element>::const_iterator iterator;
287  typedef typename pvector<Element>::const_iterator const_iterator;
288 #if defined(WIN32_VC) || defined(WIN64_VC)
289  // VC++ seems to break the const_reverse_iterator definition somehow.
290  typedef typename pvector<Element>::reverse_iterator reverse_iterator;
291 #else
292  typedef typename pvector<Element>::const_reverse_iterator reverse_iterator;
293 #endif
294  typedef typename pvector<Element>::const_reverse_iterator const_reverse_iterator;
295  typedef typename pvector<Element>::difference_type difference_type;
296  typedef typename pvector<Element>::size_type size_type;
297 
298  INLINE ConstPointerToArray(const Element *begin, const Element *end, TypeHandle type_handle = get_type_handle(Element));
299  INLINE ConstPointerToArray(const PointerToArray<Element> &copy);
301  INLINE ConstPointerToArray(PointerToArray<Element> &&from) noexcept;
302  INLINE ConstPointerToArray(ConstPointerToArray<Element> &&from) noexcept;
303  INLINE explicit ConstPointerToArray(pvector<Element> &&from, TypeHandle type_handle = get_type_handle(Element));
304 
305  // Duplicating the interface of vector.
306 
307  INLINE iterator begin() const;
308  INLINE iterator end() const;
309  INLINE typename ConstPointerToArray<Element>::reverse_iterator rbegin() const;
310  INLINE typename ConstPointerToArray<Element>::reverse_iterator rend() const;
311 
312  // Equality and comparison operators are pointerwise for PointerToArrays,
313  // not elementwise as in vector.
314 
315  INLINE size_type size() const;
316  INLINE size_type max_size() const;
317  INLINE bool empty() const;
318 
319  INLINE void clear();
320 
321  // Functions specific to vectors.
322  INLINE size_type capacity() const;
323  INLINE reference front() const;
324  INLINE reference back() const;
325 
326 #if !defined(WIN32_VC) && !defined(WIN64_VC)
327  INLINE reference operator [](size_type n) const;
328  INLINE reference operator [](int n) const;
329 #endif
330 
331  INLINE operator const Element *() const;
332  INLINE const Element *p() const;
333  INLINE const pvector<Element> &v() const;
334  INLINE const ReferenceCountedVector<Element> *v0() const;
336 
337  // Methods to help out Python and other high-level languages.
338  INLINE const Element &get_element(size_type n) const;
339  INLINE std::string get_data() const;
340  INLINE std::string get_subdata(size_type n, size_type count) const;
341 
342  INLINE int get_ref_count() const;
343  INLINE void ref() const;
344  INLINE bool unref() const;
345 
346  INLINE int get_node_ref_count() const;
347  INLINE void node_ref() const;
348  INLINE bool node_unref() const;
349 
350  INLINE size_t count(const Element &) const;
351 
352 #endif // CPPPARSER
353 
354 public:
355  // Reassignment is by pointer, not memberwise as with a vector.
357  operator = (ReferenceCountedVector<Element> *ptr);
359  operator = (const PointerToArray<Element> &copy);
361  operator = (const ConstPointerToArray<Element> &copy);
363  operator = (PointerToArray<Element> &&from) noexcept;
365  operator = (ConstPointerToArray<Element> &&from) noexcept;
366 
367 private:
368  TypeHandle _type_handle;
369 
370  // This static empty array is kept around just so we can return something
371  // meangful when begin() or end() is called and we have a NULL pointer. It
372  // might not be shared properly between different .so's, since it's a static
373  // member of a template class, but we don't really care.
374  static pvector<Element> _empty_array;
375 
376  friend class PointerToArray<Element>;
377 };
378 
379 // And the brevity macros.
380 #define PTA(type) PointerToArray< type >
381 #define CPTA(type) ConstPointerToArray< type >
382 
383 #include "pointerToArray.I"
384 
385 #endif // HAVE_POINTERTOARRAY_H
Element * p() const
Function p() is similar to the function from PointerTo.
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...
int get_node_ref_count() const
Returns the node_ref of the underlying vector.
void clear()
To empty the PTA, use the clear() method, since assignment to NULL is problematic (given the ambiguit...
void node_ref() const
Increments the node_ref of the underlying vector.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void * get_void_ptr() const
Returns the reference to memory where the vector is stored.
int get_ref_count() const
Returns 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 ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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 ...
bool node_unref() const
Decrements the node_ref of the underlying vector.
A special kind of PointerTo that stores an array of the indicated element type, instead of a single e...
static PointerToArray< Element > empty_array(size_type n, TypeHandle type_handle=get_type_handle(Element))
Return an empty array of size n.
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...
ReferenceCountedVector< Element > * v0() const
To access the internal ReferenceCountedVector object, for very low-level fiddling.
This is our own Panda specialization on the default STL vector.
Definition: pvector.h:42
void make_empty()
Empties the array pointed to.
void set_void_ptr(void *p)
Sets this PTA to point to the pointer passed in.
void ref() const
Increments the reference count of the underlying vector.
PointerToArray< Element > cast_non_const() const
Casts away the constness of the CPTA(Element), and returns an equivalent PTA(Element).
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...
const pvector< Element > & v() const
To access the vector itself, for more direct fiddling with some of the vector's esoteric functionalit...
const Element * p() const
Function p() is similar to the function from ConstPointerTo.
pvector< Element > & v() const
To access the vector itself, for more direct fiddling with some of the vector's esoteric functionalit...
void node_ref() const
Increments the node_ref of the underlying vector.
bool unref() const
Decrements the reference count of the underlying vector.
This is the base class for PointerToArray and ConstPointerToArray.
void clear()
To empty the PTA, use the clear() method, since assignment to NULL is problematic (given the ambiguit...
int get_ref_count() const
Returns the reference count of the underlying vector.
int get_node_ref_count() const
Returns the node_ref of the underlying vector.
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.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
size_t count(const Element &) const
Counts the frequency at which the given element occurs in the vector.
This defines the object that is actually stored and reference-counted internally by a PointerToArray.
size_t count(const Element &) const
Counts the frequency at which the given element occurs in the vector.
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...
void ref() const
Increments the reference count of the underlying vector.
Similar to PointerToArray, except that its contents may not be modified.
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 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...
bool node_unref() const
Decrements the node_ref of the underlying vector.
bool unref() const
Decrements the reference count of the underlying vector.