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